summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorsemenu <semenu@FreeBSD.org>2000-04-12 06:51:43 +0000
committersemenu <semenu@FreeBSD.org>2000-04-12 06:51:43 +0000
commitfea3e0ecac004c02502dcdcbf96af20a3a4bc864 (patch)
tree1bc77cb304b695502e35eef83160c588aa165a4e /sys
parentba68a82065f9f9389d80893245d4b41bcd22a765 (diff)
downloadFreeBSD-src-fea3e0ecac004c02502dcdcbf96af20a3a4bc864.zip
FreeBSD-src-fea3e0ecac004c02502dcdcbf96af20a3a4bc864.tar.gz
Driver is now using miibus, and newbus.
PR: kern/17601
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/tx/if_tx.c1360
-rw-r--r--sys/dev/tx/if_txreg.h211
-rw-r--r--sys/dev/tx/if_txvar.h211
-rw-r--r--sys/pci/if_tx.c1360
-rw-r--r--sys/pci/if_txvar.h211
5 files changed, 1286 insertions, 2067 deletions
diff --git a/sys/dev/tx/if_tx.c b/sys/dev/tx/if_tx.c
index 288edbd..fa03716 100644
--- a/sys/dev/tx/if_tx.c
+++ b/sys/dev/tx/if_tx.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_tx.c,v 1.3 1998/10/10 04:30:09 jason Exp $ */
+/* $OpenBSD: if_tx.c,v 1.9.2.1 2000/02/21 22:29:13 niklas Exp $ */
/* $FreeBSD$ */
/*-
@@ -25,8 +25,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- *
*/
/*
@@ -37,60 +35,72 @@
*
* todo:
* Implement FULL IFF_MULTICAST support.
- * Test, test and test again:-(
*
*/
/* We should define compile time options before if_txvar.h included */
-/*#define EPIC_NOIFMEDIA 1*/
-/*#define EPIC_USEIOSPACE 1*/
#define EARLY_RX 1
/*#define EPIC_DEBUG 1*/
-#if defined(EPIC_DEBUG)
-#define dprintf(a) printf a
-#else
-#define dprintf(a)
-#endif
-
-/* Macro to get either mbuf cluster or nothing */
-#define EPIC_MGETCLUSTER(m) \
- { MGETHDR((m),M_DONTWAIT,MT_DATA); \
- if (m) { \
- MCLGET((m),M_DONTWAIT); \
- if( 0 == ((m)->m_flags & M_EXT) ){ \
- m_freem(m); \
- (m) = NULL; \
- } \
- } \
- }
-
-#include "bpf.h"
-#include "opt_bdg.h"
-
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/sockio.h>
#include <sys/mbuf.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/socket.h>
-#include <sys/sockio.h>
+#include <sys/queue.h>
+
+#if defined(__FreeBSD__)
+#include "opt_bdg.h"
+#define NBPFILTER 1
+
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/ethernet.h>
+#include <net/if_media.h>
+
+#include <net/bpf.h>
+
+#ifdef BRIDGE
+#include <net/bridge.h>
+#endif
+
+#include <vm/vm.h> /* for vtophys */
+#include <vm/pmap.h> /* for vtophys */
+#include <machine/clock.h> /* for DELAY */
+#include <machine/bus_memio.h>
+#include <machine/bus_pio.h>
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+
+#include <pci/pcireg.h>
+#include <pci/pcivar.h>
+
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+
+#include "miibus_if.h"
+
+#include <pci/if_txvar.h>
+#else /* __OpenBSD__ */
+#include "bpfilter.h"
+
+#include <sys/device.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_types.h>
-
-#if !defined(SIOCSIFMEDIA) || defined(EPIC_NOIFMEDIA)
-#define EPIC_NOIFMEDIA 1
-#else
#include <net/if_media.h>
-#endif
#ifdef INET
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/in_var.h>
#include <netinet/ip.h>
+#include <netinet/if_ether.h>
#endif
#ifdef IPX
@@ -103,64 +113,38 @@
#include <netns/ns_if.h>
#endif
-#if NBPF > 0
+#if NBPFILTER > 0
#include <net/bpf.h>
-#include <net/bpfdesc.h>
#endif
-#if defined(__OpenBSD__)
-#include <sys/ioctl.h>
-#include <sys/errno.h>
-#include <sys/device.h>
-
-#include <netinet/if_ether.h>
-
#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcidevs.h>
#include <dev/pci/if_txvar.h>
-#else /* __FreeBSD__ */
-#include <sys/eventhandler.h>
-#include <net/if_mib.h>
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-#include <vm/vm.h>
-#include <vm/pmap.h>
-#include <machine/clock.h>
-
-#include <pci/pcivar.h>
-#include <pci/if_txvar.h>
-
-#ifdef BRIDGE
-#include <net/bridge.h>
-#endif
-
#endif
#if defined(__FreeBSD__)
-#if __FreeBSD_version >= 300000
-#define EPIC_IFIOCTL_CMD_TYPE u_long
-#else
-#define EPIC_IFIOCTL_CMD_TYPE int
-#endif
#define EPIC_INTR_RET_TYPE void
#else /* __OpenBSD__ */
-#define EPIC_IFIOCTL_CMD_TYPE u_long
#define EPIC_INTR_RET_TYPE int
#endif
-static int epic_ifioctl __P((register struct ifnet *, EPIC_IFIOCTL_CMD_TYPE, caddr_t));
+static int epic_ifioctl __P((register struct ifnet *, u_long, caddr_t));
static EPIC_INTR_RET_TYPE epic_intr __P((void *));
static int epic_common_attach __P((epic_softc_t *));
-static void epic_ifstart __P((struct ifnet * const));
+static void epic_ifstart __P((struct ifnet *));
static void epic_ifwatchdog __P((struct ifnet *));
static int epic_init __P((epic_softc_t *));
static void epic_stop __P((epic_softc_t *));
-static __inline void epic_rx_done __P((epic_softc_t *));
-static __inline void epic_tx_done __P((epic_softc_t *));
+static void epic_rx_done __P((epic_softc_t *));
+static void epic_tx_done __P((epic_softc_t *));
static int epic_init_rings __P((epic_softc_t *));
static void epic_free_rings __P((epic_softc_t *));
static void epic_stop_activity __P((epic_softc_t *));
@@ -168,39 +152,22 @@ static void epic_start_activity __P((epic_softc_t *));
static void epic_set_rx_mode __P((epic_softc_t *));
static void epic_set_tx_mode __P((epic_softc_t *));
static void epic_set_mc_table __P((epic_softc_t *));
-static void epic_set_media_speed __P((epic_softc_t *));
-static void epic_init_phy __P((epic_softc_t *));
-static void epic_dump_state __P((epic_softc_t *));
-static int epic_autoneg __P((epic_softc_t *));
static int epic_read_eeprom __P((epic_softc_t *,u_int16_t));
static void epic_output_eepromw __P((epic_softc_t *, u_int16_t));
static u_int16_t epic_input_eepromw __P((epic_softc_t *));
static u_int8_t epic_eeprom_clock __P((epic_softc_t *,u_int8_t));
static void epic_write_eepromreg __P((epic_softc_t *,u_int8_t));
static u_int8_t epic_read_eepromreg __P((epic_softc_t *));
-static u_int16_t epic_read_phy_register __P((epic_softc_t *, u_int16_t));
-static void epic_write_phy_register __P((epic_softc_t *, u_int16_t, u_int16_t));
-#if !defined(EPIC_NOIFMEDIA)
-static int epic_ifmedia_change __P((struct ifnet *));
-static void epic_ifmedia_status __P((struct ifnet *, struct ifmediareq *));
-#endif
+static int epic_read_phy_reg __P((epic_softc_t *, int, int));
+static void epic_write_phy_reg __P((epic_softc_t *, int, int, int));
-int epic_mtypes [] = {
- IFM_ETHER | IFM_10_T,
- IFM_ETHER | IFM_10_T | IFM_FDX,
- IFM_ETHER | IFM_100_TX,
- IFM_ETHER | IFM_100_TX | IFM_FDX,
- IFM_ETHER | IFM_10_T | IFM_LOOP,
- IFM_ETHER | IFM_10_T | IFM_FDX | IFM_LOOP,
- IFM_ETHER | IFM_10_T | IFM_LOOP | IFM_FLAG1,
- IFM_ETHER | IFM_100_TX | IFM_LOOP,
- IFM_ETHER | IFM_100_TX | IFM_LOOP | IFM_FLAG1,
- IFM_ETHER | IFM_100_TX | IFM_FDX | IFM_LOOP,
- IFM_ETHER | IFM_AUTO
-};
-#define EPIC_MTYPESNUM (sizeof(epic_mtypes) / sizeof(epic_mtypes[0]))
+static int epic_miibus_readreg __P((device_t, int, int));
+static int epic_miibus_writereg __P((device_t, int, int, int));
+static void epic_miibus_statchg __P((device_t));
+static int epic_ifmedia_upd __P((struct ifnet *));
+static void epic_ifmedia_sts __P((struct ifnet *, struct ifmediareq *));
/* -------------------------------------------------------------------------
OS-specific part
@@ -209,9 +176,9 @@ int epic_mtypes [] = {
#if defined(__OpenBSD__)
/* -----------------------------OpenBSD------------------------------------- */
-static int epic_openbsd_probe __P((struct device *,void *,void *));
-static void epic_openbsd_attach __P((struct device *, struct device *, void *));
-static void epic_shutdown __P((void *));
+int epic_openbsd_probe __P((struct device *,void *,void *));
+void epic_openbsd_attach __P((struct device *, struct device *, void *));
+void epic_openbsd_shutdown __P((void *));
struct cfattach tx_ca = {
sizeof(epic_softc_t), epic_openbsd_probe, epic_openbsd_attach
@@ -221,7 +188,7 @@ struct cfdriver tx_cd = {
};
/* Synopsis: Check if device id corresponds with SMC83C170 id. */
-static int
+int
epic_openbsd_probe(
struct device *parent,
void *match,
@@ -231,13 +198,13 @@ epic_openbsd_probe(
if( PCI_VENDOR(pa->pa_id) != SMC_VENDORID )
return 0;
- if( PCI_PRODUCT(pa->pa_id) == CHIPID_83C170 )
+ if( PCI_PRODUCT(pa->pa_id) == SMC_DEVICEID_83C170 )
return 1;
return 0;
}
-static void
+void
epic_openbsd_attach(
struct device *parent,
struct device *self,
@@ -249,23 +216,46 @@ epic_openbsd_attach(
pci_intr_handle_t ih;
const char *intrstr = NULL;
struct ifnet *ifp;
- bus_space_tag_t iot = pa->pa_iot;
bus_addr_t iobase;
bus_size_t iosize;
int i;
-#if !defined(EPIC_NOIFMEDIA)
- int tmp;
-#endif
+ u_int32_t command;
+
+ command = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
+ command |= PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE |
+ PCI_COMMAND_MASTER_ENABLE;
+ pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, command);
+ command = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
- if( pci_io_find(pc, pa->pa_tag, PCI_CBIO, &iobase, &iosize)) {
+#ifdef EPIC_USEIOSPACE
+ if (!(command & PCI_COMMAND_IO_ENABLE)) {
+ printf(": failed to enable I/O ports\n");
+ return;
+ }
+ if( pci_io_find(pc, pa->pa_tag, PCI_BASEIO, &iobase, &iosize)) {
printf(": can't find i/o space\n");
return;
}
- if( bus_space_map(iot, iobase, iosize, 0, &sc->sc_sh)) {
+ if( bus_space_map(pa->pa_iot, iobase, iosize, 0, &sc->sc_sh)) {
printf(": can't map i/o space\n");
return;
}
- sc->sc_st = iot;
+ sc->sc_st = pa->pa_iot;
+#else
+ if (!(command & PCI_COMMAND_MEM_ENABLE)) {
+ printf(": failed to enable memory mapping\n");
+ return;
+ }
+ if( pci_mem_find(pc, pa->pa_tag, PCI_BASEMEM, &iobase, &iosize, NULL)) {
+ printf(": can't find mem space\n");
+ return;
+ }
+ if( bus_space_map(pa->pa_memt, iobase, iosize, 0, &sc->sc_sh)) {
+ printf(": can't map i/o space\n");
+ return;
+ }
+ sc->sc_st = pa->pa_memt;
+#endif
ifp = &sc->sc_if;
bcopy(sc->sc_dev.dv_xname, ifp->if_xname,IFNAMSIZ);
@@ -298,75 +288,37 @@ epic_openbsd_attach(
/* Display some info */
printf(" address %s",ether_sprintf(sc->sc_macaddr));
- /* Read current media config and display it too */
- i = PHY_READ_2( sc, DP83840_BMCR );
-#if !defined(EPIC_NOIFMEDIA)
- tmp = IFM_ETHER;
-#endif
- if( i & BMCR_AUTONEGOTIATION ){
- printf(", Auto-Neg ");
-
- /* To avoid bug in QS6612 read LPAR enstead of BMSR */
- i = PHY_READ_2( sc, DP83840_LPAR );
- if( i & (ANAR_100_TX|ANAR_100_TX_FD) ) printf("100Mbps");
- else printf("10Mbps");
- if( i & (ANAR_10_FD|ANAR_100_TX_FD) ) printf(" FD");
-#if !defined(EPIC_NOIFMEDIA)
- tmp |= IFM_AUTO;
-#endif
- } else {
-#if defined(EPIC_NOIFMEDIA)
- ifp->if_flags |= IFF_LINK0;
-#endif
- if( i & BMCR_100MBPS ) {
- printf(", 100Mbps");
-#if !defined(EPIC_NOIFMEDIA)
- tmp |= IFM_100_TX;
-#else
- ifp->if_flags |= IFF_LINK2;
-#endif
- } else {
- printf(", 10Mbps");
-#if !defined(EPIC_NOIFMEDIA)
- tmp |= IFM_10_T;
-#endif
- }
- if( i & BMCR_FULL_DUPLEX ) {
- printf(" FD");
-#if !defined(EPIC_NOIFMEDIA)
- tmp |= IFM_FDX;
-#else
- ifp->if_flags |= IFF_LINK1;
-#endif
- }
- }
/* Init ifmedia interface */
-#if !defined(EPIC_NOIFMEDIA)
- ifmedia_init(&sc->ifmedia,0,epic_ifmedia_change,epic_ifmedia_status);
-
- for (i=0; i<EPIC_MTYPESNUM; i++)
- ifmedia_add(&sc->ifmedia,epic_mtypes[i],0,NULL);
-
- ifmedia_set(&sc->ifmedia, tmp);
-#endif
+ ifmedia_init(&sc->sc_mii.mii_media, 0,
+ epic_ifmedia_upd, epic_ifmedia_sts);
+ sc->sc_mii.mii_ifp = ifp;
+ sc->sc_mii.mii_readreg = epic_miibus_readreg;
+ sc->sc_mii.mii_writereg = epic_miibus_writereg;
+ sc->sc_mii.mii_statchg = epic_miibus_statchg;
+ mii_phy_probe(self, &sc->sc_mii, 0xffffffff);
+ if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
+ ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE,0,NULL);
+ ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE);
+ } else
+ ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
/* Attach os interface and bpf */
if_attach(ifp);
ether_ifattach(ifp);
-#if NBPF > 0
+#if NBPFILTER > 0
bpfattach(&sc->sc_if.if_bpf, ifp, DLT_EN10MB,
sizeof(struct ether_header));
#endif
/* Set shutdown routine to stop DMA process */
- shutdownhook_establish(epic_shutdown, sc);
+ shutdownhook_establish(epic_openbsd_shutdown, sc);
printf("\n");
}
/* Simple call epic_stop() */
-static void
-epic_shutdown(
+void
+epic_openbsd_shutdown(
void *sc)
{
epic_stop(sc);
@@ -375,62 +327,108 @@ epic_shutdown(
#else /* __FreeBSD__ */
/* -----------------------------FreeBSD------------------------------------- */
-static const char* epic_freebsd_probe __P((pcici_t, pcidi_t));
-static void epic_freebsd_attach __P((pcici_t, int));
-static void epic_shutdown __P((void *, int));
-
-/* Global variables */
-static u_long epic_pci_count;
-static struct pci_device txdevice = {
- "tx",
- epic_freebsd_probe,
- epic_freebsd_attach,
- &epic_pci_count,
- NULL
+static int epic_freebsd_probe __P((device_t));
+static int epic_freebsd_attach __P((device_t));
+static void epic_freebsd_shutdown __P((device_t));
+static int epic_freebsd_detach __P((device_t));
+static struct epic_type *epic_devtype __P((device_t));
+
+static device_method_t epic_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, epic_freebsd_probe),
+ DEVMETHOD(device_attach, epic_freebsd_attach),
+ DEVMETHOD(device_detach, epic_freebsd_detach),
+ DEVMETHOD(device_shutdown, epic_freebsd_shutdown),
+
+ /* bus interface */
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+ DEVMETHOD(bus_driver_added, bus_generic_driver_added),
+
+ /* MII interface */
+ DEVMETHOD(miibus_readreg, epic_miibus_readreg),
+ DEVMETHOD(miibus_writereg, epic_miibus_writereg),
+ DEVMETHOD(miibus_statchg, epic_miibus_statchg),
+
+ { 0, 0 }
+};
+
+static driver_t epic_driver = {
+ "tx",
+ epic_methods,
+ sizeof(epic_softc_t)
};
-/* Append this driver to pci drivers list */
-COMPAT_PCI_DRIVER (tx, txdevice);
+static devclass_t epic_devclass;
+
+DRIVER_MODULE(if_tx, pci, epic_driver, epic_devclass, 0, 0);
+DRIVER_MODULE(miibus, tx, miibus_driver, miibus_devclass, 0, 0);
+
+static struct epic_type epic_devs[] = {
+ { SMC_VENDORID, SMC_DEVICEID_83C170,
+ "SMC EtherPower II 10/100BaseTX" },
+ { 0, 0, NULL }
+};
-/* Synopsis: Check if device id corresponds with SMC83C170 id. */
-static const char*
-epic_freebsd_probe(
- pcici_t config_id,
- pcidi_t device_id)
+static int
+epic_freebsd_probe(dev)
+ device_t dev;
{
- if( PCI_VENDORID(device_id) != SMC_VENDORID )
- return NULL;
+ struct epic_type *t;
+
+ t = epic_devtype(dev);
- if( PCI_CHIPID(device_id) == CHIPID_83C170 )
- return "SMC 83c170";
+ if (t != NULL) {
+ device_set_desc(dev, t->name);
+ return(0);
+ }
- return NULL;
+ return(ENXIO);
}
+static struct epic_type *
+epic_devtype(dev)
+ device_t dev;
+{
+ struct epic_type *t;
+
+ t = epic_devs;
+
+ while(t->name != NULL) {
+ if ((pci_get_vendor(dev) == t->ven_id) &&
+ (pci_get_device(dev) == t->dev_id)) {
+ return(t);
+ }
+ t++;
+ }
+ return (NULL);
+}
+
+#if defined(EPIC_USEIOSPACE)
+#define EPIC_RES SYS_RES_IOPORT
+#define EPIC_RID PCIR_BASEIO
+#else
+#define EPIC_RES SYS_RES_MEMORY
+#define EPIC_RID PCIR_BASEMEM
+#endif
+
/*
* Do FreeBSD-specific attach routine, like map registers, alloc softc
* structure and etc.
*/
-static void
-epic_freebsd_attach(
- pcici_t config_id,
- int unit)
+static int
+epic_freebsd_attach(dev)
+ device_t dev;
{
struct ifnet *ifp;
epic_softc_t *sc;
-#if defined(EPIC_USEIOSPACE)
- u_int32_t iobase;
-#else
- caddr_t pmembase;
-#endif
u_int32_t command;
- int i,s,tmp;
+ int unit, error;
+ int i, s, rid, tmp;
- printf("tx%d",unit);
+ s = splimp ();
- /* Allocate memory for softc, hardware descriptors and frag lists */
- sc = (epic_softc_t *) malloc( sizeof(epic_softc_t), M_DEVBUF, M_NOWAIT);
- if (sc == NULL) return;
+ sc = device_get_softc(dev);
+ unit = device_get_unit(dev);
/* Preinitialize softc structure */
bzero(sc, sizeof(epic_softc_t));
@@ -443,62 +441,101 @@ epic_freebsd_attach(
ifp->if_softc = sc;
ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST;
ifp->if_ioctl = epic_ifioctl;
+ ifp->if_output = ether_output;
ifp->if_start = epic_ifstart;
ifp->if_watchdog = epic_ifwatchdog;
ifp->if_init = (if_init_f_t*)epic_init;
ifp->if_timer = 0;
- ifp->if_output = ether_output;
- ifp->if_snd.ifq_maxlen = TX_RING_SIZE;
+ ifp->if_baudrate = 10000000;
+ ifp->if_snd.ifq_maxlen = TX_RING_SIZE - 1;
+
+ /* Enable ports, memory and busmastering */
+ command = pci_read_config(dev, PCIR_COMMAND, 4);
+ command |= PCIM_CMD_PORTEN | PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN;
+ pci_write_config(dev, PCIR_COMMAND, command, 4);
+ command = pci_read_config(dev, PCIR_COMMAND, 4);
- /* Get iobase or membase */
#if defined(EPIC_USEIOSPACE)
- command = PCI_CONF_READ(PCI_CFCS);
- command |= PCI_CFCS_IOEN;
- PCI_CONF_WRITE(PCI_CFCS, command);
- command = PCI_CONF_READ(PCI_CFCS);
-
- if (!(command & PCI_CFCS_IOEN)) {
- printf(": failed to enable memory mapping!\n");
- free(sc, M_DEVBUF);
- return;
+ if (!(command & PCIM_CMD_PORTEN)) {
+ device_printf(dev, "failed to enable I/O mapping!\n");
+ error = ENXIO;
+ goto fail;
}
+#else
+ if (!(command & PCIM_CMD_MEMEN)) {
+ device_printf(dev, "failed to enable memory mapping!\n");
+ error = ENXIO;
+ goto fail;
+ }
+#endif
- if (!pci_map_port(config_id, PCI_CBIO,(u_short *) &(sc->iobase))) {
- printf(": cannot map port\n");
- free(sc, M_DEVBUF);
- return;
+ rid = EPIC_RID;
+ sc->res = bus_alloc_resource(dev, EPIC_RES, &rid, 0, ~0, 1,
+ RF_ACTIVE);
+
+ if (sc->res == NULL) {
+ device_printf(dev, "couldn't map ports/memory\n");
+ error = ENXIO;
+ goto fail;
}
-#else
- command = PCI_CONF_READ(PCI_CFCS);
- command |= PCI_CFCS_MAEN;
- PCI_CONF_WRITE(PCI_CFCS, command);
- command = PCI_CONF_READ(PCI_CFCS);
-
- if (!(command & PCI_CFCS_MAEN)) {
- printf(": failed to enable memory mapping!\n");
- free(sc, M_DEVBUF);
- return;
+
+ sc->sc_st = rman_get_bustag(sc->res);
+ sc->sc_sh = rman_get_bushandle(sc->res);
+
+ /* Allocate interrupt */
+ rid = 0;
+ sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
+ RF_SHAREABLE | RF_ACTIVE);
+
+ if (sc->irq == NULL) {
+ device_printf(dev, "couldn't map interrupt\n");
+ bus_release_resource(dev, EPIC_RES, EPIC_RID, sc->res);
+ error = ENXIO;
+ goto fail;
}
- if (!pci_map_mem(config_id, PCI_CBMA,(vm_offset_t *) &(sc->csr),(vm_offset_t *) &pmembase)) {
- printf(": cannot map memory\n");
- free(sc, M_DEVBUF);
- return;
+ error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET,
+ epic_intr, sc, &sc->sc_ih);
+
+ if (error) {
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
+ bus_release_resource(dev, EPIC_RES, EPIC_RID, sc->res);
+ device_printf(dev, "couldn't set up irq\n");
+ goto fail;
}
-#endif
- /* Do OS independent part, including chip wakeup and reset */
- if( epic_common_attach(sc) ) return;
+ /* Bring the chip out of low-power mode and reset it. */
+ CSR_WRITE_4( sc, GENCTL, GENCTL_SOFT_RESET );
+ DELAY(500);
+
+ /* Workaround for Application Note 7-15 */
+ for (i=0; i<16; i++) CSR_WRITE_4(sc, TEST1, TEST1_CLOCK_TEST);
+
+ /*
+ * Do ifmedia setup.
+ */
+ if (mii_phy_probe(dev, &sc->miibus,
+ epic_ifmedia_upd, epic_ifmedia_sts)) {
+ device_printf(dev, "MII without any PHY!?\n");
+ bus_teardown_intr(dev, sc->irq, sc->sc_ih);
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
+ bus_release_resource(dev, EPIC_RES, EPIC_RID, sc->res);
+ error = ENXIO;
+ goto fail;
+ }
- /* Enable BusMaster'ing */
- command = PCI_CONF_READ(PCI_CFCS);
- command |= PCI_CFCS_BMEN;
- PCI_CONF_WRITE(PCI_CFCS, command);
+ /* Do OS independent part, including chip wakeup and reset */
+ if (epic_common_attach(sc)) {
+ device_printf(dev, "memory distribution error\n");
+ bus_teardown_intr(dev, sc->irq, sc->sc_ih);
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
+ bus_release_resource(dev, EPIC_RES, EPIC_RID, sc->res);
+ error = ENXIO;
+ goto fail;
+ }
/* Display ethernet address ,... */
- printf(": address %02x:%02x:%02x:%02x:%02x:%02x,",
- sc->sc_macaddr[0],sc->sc_macaddr[1],sc->sc_macaddr[2],
- sc->sc_macaddr[3],sc->sc_macaddr[4],sc->sc_macaddr[5]);
+ device_printf(dev, "address %6D,", sc->sc_macaddr, ":");
/* board type and ... */
printf(" type ");
@@ -510,96 +547,75 @@ epic_freebsd_attach(
if( ' ' == (u_int8_t)tmp ) break;
printf("%c",(u_int8_t)tmp);
}
+ printf ("\n");
- /* Read current media config and display it too */
- i = PHY_READ_2( sc, DP83840_BMCR );
-#if !defined(EPIC_NOIFMEDIA)
- tmp = IFM_ETHER;
-#endif
- if( i & BMCR_AUTONEGOTIATION ){
- printf(", Auto-Neg ");
-
- /* To avoid bug in QS6612 read LPAR enstead of BMSR */
- i = PHY_READ_2( sc, DP83840_LPAR );
- if( i & (ANAR_100_TX|ANAR_100_TX_FD) ) printf("100Mbps ");
- else printf("10Mbps ");
- if( i & (ANAR_10_FD|ANAR_100_TX_FD) ) printf("FD");
-#if !defined(EPIC_NOIFMEDIA)
- tmp |= IFM_AUTO;
-#endif
- } else {
-#if defined(EPIC_NOIFMEDIA)
- ifp->if_flags |= IFF_LINK0;
-#endif
- if( i & BMCR_100MBPS ) {
- printf(", 100Mbps ");
-#if !defined(EPIC_NOIFMEDIA)
- tmp |= IFM_100_TX;
-#else
- ifp->if_flags |= IFF_LINK2;
-#endif
- } else {
- printf(", 10Mbps ");
-#if !defined(EPIC_NOIFMEDIA)
- tmp |= IFM_10_T;
-#endif
- }
- if( i & BMCR_FULL_DUPLEX ) {
- printf("FD");
-#if !defined(EPIC_NOIFMEDIA)
- tmp |= IFM_FDX;
-#else
- ifp->if_flags |= IFF_LINK1;
-#endif
- }
- }
+ /* Attach to OS's managers */
+ if_attach(ifp);
+ ether_ifattach(ifp);
+ callout_handle_init(&sc->stat_ch);
- /* Init ifmedia interface */
-#if !defined(EPIC_NOIFMEDIA)
- ifmedia_init(&sc->ifmedia,0,epic_ifmedia_change,epic_ifmedia_status);
+ bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
- for (i=0; i<EPIC_MTYPESNUM; i++)
- ifmedia_add(&sc->ifmedia,epic_mtypes[i],0,NULL);
+fail:
+ splx(s);
- ifmedia_set(&sc->ifmedia, tmp);
-#endif
+ return(error);
+}
+
+/*
+ * Detach driver and free resources
+ */
+static int
+epic_freebsd_detach(dev)
+ device_t dev;
+{
+ struct ifnet *ifp;
+ epic_softc_t *sc;
+ int s;
s = splimp();
- /* Map interrupt */
- if( !pci_map_int(config_id, epic_intr, (void*)sc, &net_imask) ) {
- printf(": couldn't map interrupt\n");
- free(sc, M_DEVBUF);
- return;
- }
+ sc = device_get_softc(dev);
+ ifp = &sc->arpcom.ac_if;
- /* Set shut down routine to stop DMA processes on reboot */
- EVENTHANDLER_REGISTER(shutdown_post_sync, epic_shutdown, sc,
- SHUTDOWN_PRI_DEFAULT);
+ bpfdetach(ifp);
+ if_detach(ifp);
- /* Attach to if manager */
- if_attach(ifp);
- ether_ifattach(ifp);
+ epic_stop(sc);
-#if NBPF > 0
- bpfattach(ifp,DLT_EN10MB, sizeof(struct ether_header));
-#endif
+ bus_generic_detach(dev);
+ device_delete_child(dev, sc->miibus);
- splx(s);
+ bus_teardown_intr(dev, sc->irq, sc->sc_ih);
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
+ bus_release_resource(dev, EPIC_RES, EPIC_RID, sc->res);
- printf("\n");
+ free(sc->pool, M_DEVBUF);
- return;
+ splx(s);
+
+ return(0);
}
+#undef EPIC_RES
+#undef EPIC_RID
+
+/*
+ * Stop all chip I/O so that the kernel's probe routines don't
+ * get confused by errant DMAs when rebooting.
+ */
static void
-epic_shutdown(
- void *sc,
- int howto)
+epic_freebsd_shutdown(dev)
+ device_t dev;
{
+ epic_softc_t *sc;
+
+ sc = device_get_softc(dev);
+
epic_stop(sc);
-}
+ return;
+}
#endif /* __OpenBSD__ */
/* ------------------------------------------------------------------------
@@ -610,12 +626,14 @@ epic_shutdown(
* This is if_ioctl handler.
*/
static int
-epic_ifioctl __P((
- register struct ifnet * ifp,
- EPIC_IFIOCTL_CMD_TYPE command,
- caddr_t data))
+epic_ifioctl(ifp, command, data)
+ struct ifnet *ifp;
+ u_long command;
+ caddr_t data;
{
epic_softc_t *sc = ifp->if_softc;
+ struct mii_data *mii;
+ struct ifreq *ifr = (struct ifreq *) data;
int x, error = 0;
x = splimp();
@@ -639,7 +657,7 @@ epic_ifioctl __P((
epic_init(sc);
arp_ifinit(&sc->arpcom,ifa);
break;
-#endif /* __FreeBSD__ */
+#endif
#if NS
case AF_NS: {
register struct ns_addr * ina = &IA_SNS(ifa)->sns_addr;
@@ -662,7 +680,7 @@ epic_ifioctl __P((
break;
}
}
-#endif
+#endif /* __FreeBSD__ */
case SIOCSIFFLAGS:
/*
@@ -681,15 +699,9 @@ epic_ifioctl __P((
}
}
- epic_stop_activity(sc);
-
/* Handle IFF_PROMISC flag */
+ epic_stop_activity(sc);
epic_set_rx_mode(sc);
-
-#if defined(EPIC_NOIFMEDIA)
- /* Handle IFF_LINKx flags */
- epic_set_media_speed(sc);
-#endif
epic_start_activity(sc);
break;
@@ -711,13 +723,11 @@ epic_ifioctl __P((
#endif
break;
-#if !defined(EPIC_NOIFMEDIA)
case SIOCSIFMEDIA:
case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, (struct ifreq *)data,
- &sc->ifmedia, command);
+ mii = device_get_softc(sc->miibus);
+ error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
break;
-#endif
default:
error = EINVAL;
@@ -733,8 +743,8 @@ epic_ifioctl __P((
* Return -1 on failure.
*/
static int
-epic_common_attach(
- epic_softc_t *sc)
+epic_common_attach(sc)
+ epic_softc_t *sc;
{
int i;
caddr_t pool;
@@ -761,8 +771,8 @@ epic_common_attach(
pool += sizeof(struct epic_rx_desc)*RX_RING_SIZE;
sc->tx_desc = (void *)pool;
- /* Bring the chip out of low-power mode and reset it. */
- CSR_WRITE_4( sc, GENCTL, GENCTL_SOFT_RESET );
+ /* Bring the chip out of low-power mode. */
+ CSR_WRITE_4( sc, GENCTL, GENCTL_SOFT_RESET);
/* Workaround for Application Note 7-15 */
for (i=0; i<16; i++) CSR_WRITE_4(sc, TEST1, TEST1_CLOCK_TEST);
@@ -771,12 +781,7 @@ epic_common_attach(
for (i = 0; i < ETHER_ADDR_LEN / sizeof(u_int16_t); i++)
((u_int16_t *)sc->sc_macaddr)[i] = epic_read_eeprom(sc,i);
- /* Identify PHY */
- sc->phyid = PHY_READ_2(sc, DP83840_PHYIDR1 )<<6;
- sc->phyid|= (PHY_READ_2( sc, DP83840_PHYIDR2 )>>10)&0x3F;
- if( QS6612_OUI != sc->phyid )
- printf(": WARNING! PHY unknown (0x%x)",sc->phyid);
-
+ /* Set defaults */
sc->tx_threshold = TRANSMIT_THRESHOLD;
sc->txcon = TXCON_DEFAULT;
@@ -789,7 +794,9 @@ epic_common_attach(
* or quque become empty.
*/
static void
-epic_ifstart(struct ifnet * const ifp){
+epic_ifstart(ifp)
+ struct ifnet * ifp;
+{
epic_softc_t *sc = ifp->if_softc;
struct epic_tx_buffer *buf;
struct epic_tx_desc *desc;
@@ -798,20 +805,6 @@ epic_ifstart(struct ifnet * const ifp){
register struct mbuf *m;
register int i;
-#if 0
- /* If no link is established, simply free all mbufs in queue */
- PHY_READ_2( sc, DP83840_BMSR );
- if( !(BMSR_LINK_STATUS & PHY_READ_2( sc, DP83840_BMSR )) ){
- IF_DEQUEUE( &ifp->if_snd, m0 );
- while( m0 ) {
- m_freem(m0);
- IF_DEQUEUE( &ifp->if_snd, m0 );
- }
- return;
- }
-#endif
-
- /* Link is OK, queue packets to NIC */
while( sc->pending_txs < TX_RING_SIZE ){
buf = sc->tx_buffer + sc->cur_tx;
desc = sc->tx_desc + sc->cur_tx;
@@ -823,17 +816,6 @@ epic_ifstart(struct ifnet * const ifp){
/* If nothing to send, return */
if( NULL == m0 ) return;
- /* If descriptor is busy, set IFF_OACTIVE and exit */
- if( desc->status & 0x8000 ) {
- dprintf((EPIC_FORMAT ": desc is busy in ifstart, up and down interface please\n",EPIC_ARGS(sc)));
- break;
- }
-
- if( buf->mbuf ) {
- dprintf((EPIC_FORMAT ": mbuf not freed in ifstart, up and down interface please\n",EPIC_ARGS(sc)));
- break;
- }
-
/* Fill fragments list */
for( m=m0, i=0;
(NULL != m) && (i < EPIC_MAX_FRAGS);
@@ -877,13 +859,9 @@ epic_ifstart(struct ifnet * const ifp){
/* Set watchdog timer */
ifp->if_timer = 8;
-#if NBPF > 0
+#if NBPFILTER > 0
if( ifp->if_bpf )
-#if defined(__FreeBSD__)
- bpf_mtap( ifp, m0 );
-#else /* __OpenBSD__ */
- bpf_mtap( ifp->if_bpf, m0 );
-#endif /* __FreeBSD__ */
+ bpf_mtap( EPIC_BPFTAP_ARG(ifp), m0 );
#endif
}
@@ -894,12 +872,11 @@ epic_ifstart(struct ifnet * const ifp){
}
/*
- *
- * splimp() invoked before epic_intr_normal()
+ * Synopsis: Finish all received frames.
*/
-static __inline void
-epic_rx_done __P((
- epic_softc_t *sc ))
+static void
+epic_rx_done(sc)
+ epic_softc_t *sc;
{
u_int16_t len;
struct epic_rx_buffer *buf;
@@ -947,15 +924,11 @@ epic_rx_done __P((
m->m_pkthdr.rcvif = &(sc->sc_if);
m->m_pkthdr.len = m->m_len = len;
-#if NBPF > 0
- /* Give mbuf to BPF */
+#if NBPFILTER > 0
+ /* Give mbuf to BPFILTER */
if( sc->sc_if.if_bpf )
-#if defined(__FreeBSD__)
- bpf_mtap( &sc->sc_if, m );
-#else /* __OpenBSD__ */
- bpf_mtap( sc->sc_if.if_bpf, m );
-#endif /* __FreeBSD__ */
-#endif /* NBPF */
+ bpf_mtap( EPIC_BPFTAP_ARG(&sc->sc_if), m );
+#endif /* NBPFILTER > 0 */
#ifdef BRIDGE
if (do_bridge) {
@@ -978,8 +951,7 @@ epic_rx_done __P((
}
#endif
-#if NBPF > 0
-#ifdef BRIDGE
+#if defined (__FreeBSD__)
/*
* This deserves explanation
* If the bridge is _on_, then the following check
@@ -989,11 +961,14 @@ epic_rx_done __P((
*
* But if the bridge is off, then we have to drop
* stuff that came in just via bpf.
+ *
+ * In OpenBSD such filter stands in ether_input. (?)
*/
- if (!do_bridge)
-#endif
/* Accept only our packets, broadcasts and multicasts */
- if( (eh->ether_dhost[0] & 1) == 0 &&
+#ifdef BRIDGE
+ if (do_bridge)
+#endif
+ if ((eh->ether_dhost[0] & 1) == 0 &&
bcmp(eh->ether_dhost,sc->sc_macaddr,ETHER_ADDR_LEN)){
m_freem(m);
continue;
@@ -1020,9 +995,9 @@ epic_rx_done __P((
* packet, switch to next descriptor and repeat until no packets
* are pending or descriptor is not transmitted yet.
*/
-static __inline void
-epic_tx_done __P((
- register epic_softc_t *sc ))
+static void
+epic_tx_done(sc)
+ epic_softc_t *sc;
{
struct epic_tx_buffer *buf;
struct epic_tx_desc *desc;
@@ -1060,12 +1035,10 @@ epic_tx_done __P((
/*
* Interrupt function
- *
- * splimp() assumed to be done
*/
static EPIC_INTR_RET_TYPE
-epic_intr (
- void *arg)
+epic_intr(arg)
+ void *arg;
{
epic_softc_t * sc = (epic_softc_t *) arg;
int status,i=4;
@@ -1073,7 +1046,6 @@ epic_intr (
int claimed = 0;
#endif
-
while( i-- && ((status = CSR_READ_4(sc, INTSTAT)) & INTSTAT_INT_ACTV) ){
#if defined(__OpenBSD__)
claimed = 1;
@@ -1088,8 +1060,6 @@ epic_intr (
printf(EPIC_FORMAT ": RX buffer overflow\n",EPIC_ARGS(sc));
if( status & INTSTAT_RQE )
printf(EPIC_FORMAT ": RX FIFO overflow\n",EPIC_ARGS(sc));
- if( sc->sc_if.if_flags & IFF_DEBUG )
- epic_dump_state(sc);
#endif
if( !(CSR_READ_4( sc, COMMAND ) & COMMAND_RXQUEUED) )
CSR_WRITE_4( sc, COMMAND, COMMAND_RXQUEUED );
@@ -1104,46 +1074,6 @@ epic_intr (
epic_ifstart( &sc->sc_if );
}
- if( (status & INTSTAT_GP2) && (QS6612_OUI == sc->phyid) ) {
- u_int32_t phystatus = PHY_READ_2( sc, QS6612_INTSTAT );
-
- if( phystatus & INTSTAT_AN_COMPLETE ) {
- u_int32_t bmcr;
- if( epic_autoneg(sc) == EPIC_FULL_DUPLEX ) {
- dprintf((EPIC_FORMAT ": going fullduplex\n",EPIC_ARGS(sc)));
- bmcr = BMCR_FULL_DUPLEX | PHY_READ_2( sc, DP83840_BMCR );
- sc->txcon |= TXCON_FULL_DUPLEX;
- } else {
- /* Default to half-duplex */
- dprintf((EPIC_FORMAT ": going halfduplex\n",EPIC_ARGS(sc)));
- bmcr = ~BMCR_FULL_DUPLEX & PHY_READ_2( sc, DP83840_BMCR );
- sc->txcon &= ~TXCON_FULL_DUPLEX;
- }
-
- /* There is apparently QS6612 chip bug: */
- /* BMCR_FULL_DUPLEX flag is not updated by */
- /* autonegotiation process, so update it by hands */
- /* so we can rely on it in epic_ifmedia_status() */
- PHY_WRITE_2( sc, DP83840_BMCR, bmcr );
-
- epic_stop_activity(sc);
- epic_set_tx_mode(sc);
- epic_start_activity(sc);
- }
-
- PHY_READ_2(sc, DP83840_BMSR);
- if( !(PHY_READ_2(sc, DP83840_BMSR) & BMSR_LINK_STATUS) ) {
- dprintf((EPIC_FORMAT ": WARNING! link down\n",EPIC_ARGS(sc)));
- sc->flags |= EPIC_LINK_DOWN;
- } else {
- dprintf((EPIC_FORMAT ": link up\n",EPIC_ARGS(sc)));
- sc->flags &= ~EPIC_LINK_DOWN;
- }
-
- /* We should clear GP2 int again after we clear it on PHY */
- CSR_WRITE_4( sc, INTSTAT, INTSTAT_GP2 );
- }
-
/* Check for errors */
if( status & (INTSTAT_FATAL|INTSTAT_PMA|INTSTAT_PTA|
INTSTAT_APE|INTSTAT_DPE|INTSTAT_TXU|INTSTAT_RXE) ){
@@ -1157,8 +1087,6 @@ epic_intr (
(status&INTSTAT_DPE)?" DPE":""
);
- epic_dump_state(sc);
-
epic_stop(sc);
epic_init(sc);
@@ -1202,12 +1130,10 @@ epic_intr (
* Synopsis: This one is called if packets wasn't transmitted
* during timeout. Try to deallocate transmitted packets, and
* if success continue to work.
- *
- * splimp() invoked here
*/
static void
-epic_ifwatchdog __P((
- struct ifnet *ifp))
+epic_ifwatchdog(ifp)
+ struct ifnet *ifp;
{
epic_softc_t *sc = ifp->if_softc;
int x;
@@ -1222,9 +1148,7 @@ epic_ifwatchdog __P((
/* If not successful */
if( sc->pending_txs > 0 ){
-#if defined(EPIC_DEBUG)
- if( ifp->if_flags & IFF_DEBUG ) epic_dump_state(sc);
-#endif
+
ifp->if_oerrors+=sc->pending_txs;
/* Reinitialize board */
@@ -1241,77 +1165,99 @@ epic_ifwatchdog __P((
splx(x);
}
-#if defined(SIOCSIFMEDIA) && !defined(EPIC_NOIFMEDIA)
+/*
+ * Set media options.
+ */
static int
-epic_ifmedia_change __P((
- struct ifnet * ifp))
+epic_ifmedia_upd(ifp)
+ struct ifnet *ifp;
{
- epic_softc_t *sc = (epic_softc_t *)(ifp->if_softc);
+ epic_softc_t *sc;
+ struct mii_data *mii;
- if (IFM_TYPE(sc->ifmedia.ifm_media) != IFM_ETHER)
- return (EINVAL);
+ sc = ifp->if_softc;
+ mii = device_get_softc(sc->miibus);
+ mii_mediachg(mii);
- if (!(ifp->if_flags & IFF_UP))
- return (0);
+ return(0);
+}
- epic_stop_activity(sc);
- epic_set_media_speed(sc);
- epic_start_activity(sc);
+/*
+ * Report current media status.
+ */
+static void
+epic_ifmedia_sts(ifp, ifmr)
+ struct ifnet *ifp;
+ struct ifmediareq *ifmr;
+{
+ epic_softc_t *sc;
+ struct mii_data *mii;
+
+ sc = ifp->if_softc;
+ mii = device_get_softc(sc->miibus);
+ if (ifp->if_flags & IFF_UP) {
+ mii_pollstat(mii);
+ ifmr->ifm_active = mii->mii_media_active;
+ ifmr->ifm_status = mii->mii_media_status;
+ } else {
+ ifmr->ifm_active = IFM_NONE;
+ ifmr->ifm_status = 0;
+ }
- return 0;
+ return;
}
+/*
+ * Callback routine, called on media change.
+ */
static void
-epic_ifmedia_status __P((
- struct ifnet * ifp,
- struct ifmediareq *ifmr))
+epic_miibus_statchg(dev)
+ device_t dev;
{
- epic_softc_t *sc = ifp->if_softc;
- u_int32_t bmcr;
- u_int32_t bmsr;
-
- if (!(ifp->if_flags & IFF_UP))
- return;
+ epic_softc_t *sc;
+ struct mii_data *mii;
- bmcr = PHY_READ_2( sc, DP83840_BMCR );
+ sc = device_get_softc(dev);
+ mii = device_get_softc(sc->miibus);
- PHY_READ_2( sc, DP83840_BMSR );
- bmsr = PHY_READ_2( sc, DP83840_BMSR );
+ sc->txcon &= ~(TXCON_LOOPBACK_MODE | TXCON_FULL_DUPLEX);
- ifmr->ifm_active = IFM_ETHER;
- ifmr->ifm_status = IFM_AVALID;
+ /*
+ * If we are in full-duplex mode or loopback operation,
+ * we need to decouple receiver and transmitter.
+ */
+ if (mii->mii_media_active & (IFM_FDX | IFM_LOOP))
+ sc->txcon |= TXCON_FULL_DUPLEX;
- if( !(bmsr & BMSR_LINK_STATUS) ) {
- ifmr->ifm_active |=
- (bmcr&BMCR_AUTONEGOTIATION)?IFM_AUTO:IFM_NONE;
- return;
- }
+ if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX)
+ sc->sc_if.if_baudrate = 100000000;
+ else
+ sc->sc_if.if_baudrate = 10000000;
- ifmr->ifm_status |= IFM_ACTIVE;
- ifmr->ifm_active |= (bmcr & BMCR_100MBPS) ? IFM_100_TX : IFM_10_T;
- ifmr->ifm_active |= (bmcr & BMCR_FULL_DUPLEX) ? IFM_FDX : 0;
- if ((sc->txcon & TXCON_LOOPBACK_MODE) == TXCON_LOOPBACK_MODE_INT)
- ifmr->ifm_active |= (IFM_LOOP | IFM_FLAG1);
- else if ((sc->txcon & TXCON_LOOPBACK_MODE) == TXCON_LOOPBACK_MODE_PHY)
- ifmr->ifm_active |= IFM_LOOP;
+ epic_set_tx_mode(sc);
+ return;
}
-#endif
/*
- * Reset chip, PHY, allocate rings
- *
- * splimp() invoked here
+ * Reset chip, allocate rings, and call miibus mediachg.
*/
-static int
-epic_init __P((
- epic_softc_t * sc))
+static int
+epic_init(sc)
+ epic_softc_t *sc;
{
struct ifnet *ifp = &sc->sc_if;
+ struct mii_data *mii;
int s,i;
s = splimp();
+ /* If interface is already running, then we need not do anything */
+ if (ifp->if_flags & IFF_RUNNING) {
+ splx(s);
+ return 0;
+ }
+
/* Soft reset the chip (we have to power up card before) */
CSR_WRITE_4( sc, GENCTL, 0 );
CSR_WRITE_4( sc, GENCTL, GENCTL_SOFT_RESET );
@@ -1357,17 +1303,13 @@ epic_init __P((
CSR_WRITE_4( sc, INTMASK,
INTSTAT_RCC | INTSTAT_RQE | INTSTAT_OVW | INTSTAT_RXE |
INTSTAT_TXC | INTSTAT_TCC | INTSTAT_TQE | INTSTAT_TXU |
- INTSTAT_FATAL |
- ((QS6612_OUI == sc->phyid)?INTSTAT_GP2:0) );
+ INTSTAT_FATAL);
/* Enable interrupts, set for PCI read multiple and etc */
CSR_WRITE_4( sc, GENCTL,
GENCTL_ENABLE_INTERRUPT | GENCTL_MEMORY_READ_MULTIPLE |
GENCTL_ONECOPY | GENCTL_RECEIVE_FIFO_THRESHOLD64 );
- /* Set media speed mode */
- epic_set_media_speed( sc );
-
/* Mark interface running ... */
if( ifp->if_flags & IFF_UP ) ifp->if_flags |= IFF_RUNNING;
else ifp->if_flags &= ~IFF_RUNNING;
@@ -1378,7 +1320,21 @@ epic_init __P((
/* Start Rx process */
epic_start_activity(sc);
+ /* Reset all PHYs */
+ mii = device_get_softc(sc->miibus);
+ if (mii->mii_instance) {
+ struct mii_softc *miisc;
+ for (miisc = LIST_FIRST(&mii->mii_phys); miisc != NULL;
+ miisc = LIST_NEXT(miisc, mii_list))
+ mii_phy_reset(miisc);
+ }
+
+ /* Fetch info from MII */
+ mii_mediachg(mii);
+ mii_pollstat(mii);
+
splx(s);
+
return 0;
}
@@ -1387,264 +1343,31 @@ epic_init __P((
* access RXCON.
*/
static void
-epic_set_rx_mode(
- epic_softc_t * sc)
+epic_set_rx_mode(sc)
+ epic_softc_t *sc;
{
- u_int32_t flags = sc->sc_if.if_flags;
- u_int32_t rxcon = RXCON_DEFAULT | RXCON_RECEIVE_MULTICAST_FRAMES | RXCON_RECEIVE_BROADCAST_FRAMES;
+ u_int32_t flags = sc->sc_if.if_flags;
+ u_int32_t rxcon = RXCON_DEFAULT;
- rxcon |= (flags & IFF_PROMISC)?RXCON_PROMISCUOUS_MODE:0;
+ rxcon |= (flags & IFF_PROMISC) ? RXCON_PROMISCUOUS_MODE : 0;
CSR_WRITE_4( sc, RXCON, rxcon );
return;
}
-#if 0
-void
-dump_phy_regs(epic_softc_t *sc)
-{
-
- printf("BMCR: 0x%04x\n", PHY_READ_2(sc, DP83840_BMCR));
- printf("BMSR: 0x%04x\n", PHY_READ_2(sc, DP83840_BMSR));
- printf("ANAR: 0x%04x\n", PHY_READ_2(sc, DP83840_ANAR));
- printf("LPAR: 0x%04x\n", PHY_READ_2(sc, DP83840_LPAR));
- printf("ANER: 0x%04x\n", PHY_READ_2(sc, DP83840_ANER));
- printf("MCTL: 0x%04x\n", PHY_READ_2(sc, QS6612_MCTL));
- printf("INTSTAT: 0x%04x\n", PHY_READ_2(sc, QS6612_INTSTAT));
- printf("INTMASK: 0x%04x\n", PHY_READ_2(sc, QS6612_INTMASK));
- printf("BPCR: 0x%04x\n", PHY_READ_2(sc, QS6612_BPCR));
-}
-#endif
-
/*
- * Synopsis: Reset PHY and do PHY-special initialization:
+ * Synopsis: Set transmit control register. Chip must be in idle state to
+ * access TXCON.
*/
static void
-epic_init_phy __P((
- epic_softc_t * sc))
-{
- u_int32_t i;
-
- /* Reset PHY (We have to take the delay from manual XXX) */
- PHY_WRITE_2(sc, DP83840_BMCR, BMCR_RESET);
- DELAY(10);
- for(i=0;i<0x1000;i++) {
- if( !(PHY_READ_2(sc, DP83840_BMCR) & BMCR_RESET) )
- break;
- DELAY(1);
- }
-
- if( PHY_READ_2(sc, DP83840_BMCR) & BMCR_RESET )
- printf(EPIC_FORMAT ": WARNING! cant reset PHY\n",EPIC_ARGS(sc));
-
- PHY_WRITE_2(sc, DP83840_BMCR, 0 );
- PHY_WRITE_2(sc, DP83840_BMCR, BMCR_LOOPBACK | BMCR_ISOLATE );
-
- switch( sc->phyid ){
- case QS6612_OUI: {
- /* Init QS6612 and EPIC to generate interrupt */
- CSR_WRITE_4(sc, NVCTL, NVCTL_GP1_OUTPUT_ENABLE | NVCTL_GP1);
-
- /* Mask interrupts sources */
- PHY_WRITE_2(sc, QS6612_INTMASK,
- PHY_READ_2(sc, QS6612_INTSTAT) |
- INTMASK_THUNDERLAN | INTSTAT_AN_COMPLETE |
- INTSTAT_LINK_STATUS );
-
- /* Enable QS6612 extended cable length capabilites */
- /* PHY_WRITE_2(sc, QS6612_MCTL, */
- /* PHY_READ_2(sc, QS6612_MCTL) | MCTL_BTEXT); */
-
- break;
- }
- default:
- break;
- }
-}
-
-/*
- * Synopsis: Set PHY to media type specified by IFF_LINK* flags or
- * ifmedia structure. Chip must be in idle state to access TXCON.
- */
-static void
-epic_set_media_speed __P((
- epic_softc_t * sc))
-{
- u_int16_t media;
-#if !defined(EPIC_NOIFMEDIA)
- u_int32_t tgtmedia = sc->ifmedia.ifm_cur->ifm_media;
-#endif
-
- epic_init_phy(sc);
-
-#if !defined(EPIC_NOIFMEDIA)
- if( IFM_SUBTYPE(tgtmedia) != IFM_AUTO ){
- /* Clean previous values */
- sc->txcon &= ~(TXCON_LOOPBACK_MODE | TXCON_FULL_DUPLEX);
- media = 0;
-
- /* Set mode */
- media |= (IFM_SUBTYPE(tgtmedia)==IFM_100_TX) ? BMCR_100MBPS : 0;
- if (tgtmedia & IFM_FDX) {
- media |= BMCR_FULL_DUPLEX;
- sc->txcon |= TXCON_FULL_DUPLEX;
- }
- if (tgtmedia & IFM_LOOP) {
- if (tgtmedia & IFM_FLAG1)
- sc->txcon |= TXCON_LOOPBACK_MODE_INT;
- else {
- media |= BMCR_LOOPBACK | BMCR_ISOLATE;
- sc->txcon |= TXCON_LOOPBACK_MODE_PHY;
- }
- }
-
- sc->sc_if.if_baudrate =
- (IFM_SUBTYPE(tgtmedia)==IFM_100_TX)?100000000:10000000;
-
- PHY_WRITE_2( sc, DP83840_BMCR, media );
- }
-#else /* EPIC_NOIFMEDIA */
- struct ifnet *ifp = &sc->sc_if;
-
- if( ifp->if_flags & IFF_LINK0 ) {
- /* Set mode */
- media = 0;
- media|= (ifp->if_flags & IFF_LINK2) ? BMCR_100MBPS : 0;
- media|= (ifp->if_flags & IFF_LINK1) ? BMCR_FULL_DUPLEX : 0;
-
- sc->sc_if.if_baudrate =
- (ifp->if_flags & IFF_LINK2)?100000000:10000000;
-
- PHY_WRITE_2( sc, DP83840_BMCR, media );
-
- if( ifp->if_flags & IFF_LINK2 ) sc->txcon |= TXCON_FULL_DUPLEX;
- else sc->txcon &= ~TXCON_FULL_DUPLEX;
-
- CSR_WRITE_4( sc, TXCON, sc->txcon );
- }
-#endif /* !EPIC_NOIFMEDIA */
- else {
- sc->sc_if.if_baudrate = 100000000;
-
- sc->txcon &= ~TXCON_FULL_DUPLEX;
- CSR_WRITE_4(sc, TXCON, sc->txcon);
-
- /* Set and restart autoneg */
- PHY_WRITE_2(sc, DP83840_BMCR, BMCR_AUTONEGOTIATION );
- PHY_WRITE_2(sc, DP83840_BMCR,
- BMCR_AUTONEGOTIATION | BMCR_RESTART_AUTONEG);
-
- /* If it is not QS6612 PHY, try to get result of autoneg. */
- if( QS6612_OUI != sc->phyid ) {
- /* Wait 3 seconds for the autoneg to finish
- * This is the recommended time from the DP83840A data
- * sheet Section 7.1
- */
- DELAY(3000000);
-
- if( epic_autoneg(sc) == EPIC_FULL_DUPLEX ) {
- sc->txcon |= TXCON_FULL_DUPLEX;
- CSR_WRITE_4(sc, TXCON, sc->txcon);
- }
- }
- /* Else it will be done when GP2 int occured */
- }
-
- epic_set_tx_mode(sc);
-
- return;
-}
-
-/*
- * This functions get results of the autoneg processes of the phy
- * It implements the workaround that is described in section 7.2 & 7.3 of the
- * DP83840A data sheet
- * http://www.national.com/ds/DP/DP83840A.pdf
- */
-static int
-epic_autoneg(
- epic_softc_t * sc)
-{
- u_int16_t media;
- u_int16_t i;
-
- /* BMSR must be read twice to update the link status bit
- * since that bit is a latch bit
- */
- PHY_READ_2( sc, DP83840_BMSR);
- i = PHY_READ_2( sc, DP83840_BMSR);
-
- if ((i & BMSR_LINK_STATUS) && (i & BMSR_AUTONEG_COMPLETE)){
- i = PHY_READ_2( sc, DP83840_LPAR );
-
- if ( i & (ANAR_100_TX_FD|ANAR_10_FD) )
- return EPIC_FULL_DUPLEX;
- else
- return EPIC_HALF_DUPLEX;
- } else {
- /*Auto-negotiation or link status is not 1
- Thus the auto-negotiation failed and one
- must take other means to fix it.
- */
-
- /* ANER must be read twice to get the correct reading for the
- * Multiple link fault bit -- it is a latched bit
- */
- PHY_READ_2( sc, DP83840_ANER );
- i = PHY_READ_2( sc, DP83840_ANER );
-
- if ( i & ANER_MULTIPLE_LINK_FAULT ) {
- /* it can be forced to 100Mb/s Half-Duplex */
- media = PHY_READ_2( sc, DP83840_BMCR );
- media &= ~(BMCR_AUTONEGOTIATION | BMCR_FULL_DUPLEX);
- media |= BMCR_100MBPS;
- PHY_WRITE_2( sc, DP83840_BMCR, media );
-
- /* read BMSR again to determine link status */
- PHY_READ_2( sc, DP83840_BMSR );
- i=PHY_READ_2( sc, DP83840_BMSR );
-
- if (i & BMSR_LINK_STATUS){
- /* port is linked to the non Auto-Negotiation
- * 100Mbs partner.
- */
- return EPIC_HALF_DUPLEX;
- }
- else {
- media = PHY_READ_2( sc, DP83840_BMCR);
- media &= ~(BMCR_AUTONEGOTIATION | BMCR_FULL_DUPLEX | BMCR_100MBPS);
- PHY_WRITE_2( sc, DP83840_BMCR, media);
- PHY_READ_2( sc, DP83840_BMSR );
- i = PHY_READ_2( sc, DP83840_BMSR );
-
- if (i & BMSR_LINK_STATUS) {
- /*port is linked to the non
- * Auto-Negotiation10Mbs partner
- */
- return EPIC_HALF_DUPLEX;
- }
- }
- }
- /* If we get here we are most likely not connected
- * so lets default it to half duplex
- */
- return EPIC_HALF_DUPLEX;
- }
-
-}
-
-/*
- */
-static void
-epic_set_tx_mode (
- epic_softc_t *sc )
+epic_set_tx_mode(sc)
+ epic_softc_t *sc;
{
+ if (sc->txcon & TXCON_EARLY_TRANSMIT_ENABLE)
+ CSR_WRITE_4 (sc, ETXTHR, sc->tx_threshold);
- if( sc->txcon & TXCON_EARLY_TRANSMIT_ENABLE )
- CSR_WRITE_4( sc, ETXTHR, sc->tx_threshold );
-
- CSR_WRITE_4( sc, TXCON, sc->txcon );
+ CSR_WRITE_4 (sc, TXCON, sc->txcon);
}
/*
@@ -1656,8 +1379,8 @@ epic_set_tx_mode (
* epic_start_activity() should help to do this.
*/
static void
-epic_set_mc_table (
- epic_softc_t * sc)
+epic_set_mc_table(sc)
+ epic_softc_t *sc;
{
struct ifnet *ifp = &sc->sc_if;
@@ -1676,14 +1399,14 @@ epic_set_mc_table (
* Synopsis: Start receive process and transmit one, if they need.
*/
static void
-epic_start_activity __P((
- epic_softc_t * sc))
+epic_start_activity(sc)
+ epic_softc_t *sc;
{
- /* Start rx process */
- CSR_WRITE_4(sc, COMMAND,
- COMMAND_RXQUEUED | COMMAND_START_RX |
- (sc->pending_txs?COMMAND_TXQUEUED:0));
- dprintf((EPIC_FORMAT ": activity started\n",EPIC_ARGS(sc)));
+ /* Start rx process */
+ CSR_WRITE_4(sc, COMMAND,
+ COMMAND_RXQUEUED | COMMAND_START_RX |
+ (sc->pending_txs?COMMAND_TXQUEUED:0));
+ dprintf((EPIC_FORMAT ": activity started\n",EPIC_ARGS(sc)));
}
/*
@@ -1691,8 +1414,8 @@ epic_start_activity __P((
* packet needs to be queued to stop Tx DMA.
*/
static void
-epic_stop_activity __P((
- epic_softc_t * sc))
+epic_stop_activity(sc)
+ epic_softc_t *sc;
{
int i;
@@ -1784,12 +1507,10 @@ epic_stop_activity __P((
/*
* Synopsis: Shut down board and deallocates rings.
- *
- * splimp() invoked here
*/
static void
-epic_stop __P((
- epic_softc_t * sc))
+epic_stop(sc)
+ epic_softc_t *sc;
{
int s;
@@ -1825,8 +1546,8 @@ epic_stop __P((
* Synopsis: This function should free all memory allocated for rings.
*/
static void
-epic_free_rings __P((
- epic_softc_t * sc))
+epic_free_rings(sc)
+ epic_softc_t *sc;
{
int i;
@@ -1861,7 +1582,9 @@ epic_free_rings __P((
* are bounded and aligned properly.
*/
static int
-epic_init_rings(epic_softc_t * sc){
+epic_init_rings(sc)
+ epic_softc_t *sc;
+{
int i;
sc->cur_rx = sc->cur_tx = sc->dirty_tx = sc->pending_txs = 0;
@@ -1910,9 +1633,10 @@ epic_init_rings(epic_softc_t * sc){
/*
* EEPROM operation functions
*/
-static void epic_write_eepromreg __P((
- epic_softc_t *sc,
- u_int8_t val))
+static void
+epic_write_eepromreg(sc, val)
+ epic_softc_t *sc;
+ u_int8_t val;
{
u_int16_t i;
@@ -1925,16 +1649,16 @@ static void epic_write_eepromreg __P((
}
static u_int8_t
-epic_read_eepromreg __P((
- epic_softc_t *sc))
+epic_read_eepromreg(sc)
+ epic_softc_t *sc;
{
- return CSR_READ_1( sc,EECTL );
+ return CSR_READ_1(sc, EECTL);
}
static u_int8_t
-epic_eeprom_clock __P((
- epic_softc_t *sc,
- u_int8_t val))
+epic_eeprom_clock(sc, val)
+ epic_softc_t *sc;
+ u_int8_t val;
{
epic_write_eepromreg( sc, val );
epic_write_eepromreg( sc, (val | 0x4) );
@@ -1944,9 +1668,9 @@ epic_eeprom_clock __P((
}
static void
-epic_output_eepromw __P((
- epic_softc_t * sc,
- u_int16_t val))
+epic_output_eepromw(sc, val)
+ epic_softc_t *sc;
+ u_int16_t val;
{
int i;
for( i = 0xF; i >= 0; i--){
@@ -1956,8 +1680,8 @@ epic_output_eepromw __P((
}
static u_int16_t
-epic_input_eepromw __P((
- epic_softc_t *sc))
+epic_input_eepromw(sc)
+ epic_softc_t *sc;
{
int i;
int tmp;
@@ -1973,9 +1697,9 @@ epic_input_eepromw __P((
}
static int
-epic_read_eeprom __P((
- epic_softc_t *sc,
- u_int16_t loc))
+epic_read_eeprom(sc, loc)
+ epic_softc_t *sc;
+ u_int16_t loc;
{
u_int16_t dataval;
u_int16_t read_cmd;
@@ -1996,74 +1720,66 @@ epic_read_eeprom __P((
return dataval;
}
-static u_int16_t
-epic_read_phy_register __P((
- epic_softc_t *sc,
- u_int16_t loc))
+/*
+ * Here goes MII read/write routines
+ */
+static int
+epic_read_phy_reg(sc, phy, reg)
+ epic_softc_t *sc;
+ int phy, reg;
{
int i;
- CSR_WRITE_4( sc, MIICTL, ((loc << 4) | 0x0601) );
+ CSR_WRITE_4 (sc, MIICTL, ((reg << 4) | (phy << 9) | 0x01));
for (i=0;i<0x100;i++) {
- if( !(CSR_READ_4( sc, MIICTL )&1) ) break;
+ if( !(CSR_READ_4(sc, MIICTL) & 0x01) ) break;
DELAY(1);
}
- return CSR_READ_4( sc, MIIDATA );
+ return (CSR_READ_4 (sc, MIIDATA));
}
static void
-epic_write_phy_register __P((
- epic_softc_t * sc,
- u_int16_t loc,
- u_int16_t val))
+epic_write_phy_reg(sc, phy, reg, val)
+ epic_softc_t *sc;
+ int phy, reg, val;
{
int i;
- CSR_WRITE_4( sc, MIIDATA, val );
- CSR_WRITE_4( sc, MIICTL, ((loc << 4) | 0x0602) );
+ CSR_WRITE_4 (sc, MIIDATA, val);
+ CSR_WRITE_4 (sc, MIICTL, ((reg << 4) | (phy << 9) | 0x02));
- for( i=0;i<0x100;i++) {
- if( !(CSR_READ_4( sc, MIICTL )&2) ) break;
+ for(i=0;i<0x100;i++) {
+ if( !(CSR_READ_4(sc, MIICTL) & 0x02) ) break;
DELAY(1);
}
return;
}
-static void
-epic_dump_state __P((
- epic_softc_t * sc))
+static int
+epic_miibus_readreg(dev, phy, reg)
+ device_t dev;
+ int phy, reg;
{
- int j;
- struct epic_tx_desc *tdesc;
- struct epic_rx_desc *rdesc;
- printf(EPIC_FORMAT ": cur_rx: %d, pending_txs: %d, dirty_tx: %d, cur_tx: %d\n", EPIC_ARGS(sc),sc->cur_rx,sc->pending_txs,sc->dirty_tx,sc->cur_tx);
- printf(EPIC_FORMAT ": COMMAND: 0x%08x, INTSTAT: 0x%08x\n",EPIC_ARGS(sc),CSR_READ_4(sc,COMMAND),CSR_READ_4(sc,INTSTAT));
- printf(EPIC_FORMAT ": PRCDAR: 0x%08x, PTCDAR: 0x%08x\n",EPIC_ARGS(sc),CSR_READ_4(sc,PRCDAR),CSR_READ_4(sc,PTCDAR));
- printf(EPIC_FORMAT ": dumping rx descriptors\n",EPIC_ARGS(sc));
- for(j=0;j<RX_RING_SIZE;j++){
- rdesc = sc->rx_desc + j;
- printf("desc%d: %4d 0x%04x, 0x%08x, %4d, 0x%08x\n",
- j,
- rdesc->rxlength,rdesc->status,
- rdesc->bufaddr,
- rdesc->buflength,
- rdesc->next
- );
- }
- printf(EPIC_FORMAT ": dumping tx descriptors\n",EPIC_ARGS(sc));
- for(j=0;j<TX_RING_SIZE;j++){
- tdesc = sc->tx_desc + j;
- printf(
- "desc%d: %4d 0x%04x, 0x%08lx, 0x%04x %4u, 0x%08lx, mbuf: %p\n",
- j,
- tdesc->txlength,tdesc->status,
- (u_long)tdesc->bufaddr,
- tdesc->control,tdesc->buflength,
- (u_long)tdesc->next,
- (void *)sc->tx_buffer[j].mbuf
- );
- }
+ epic_softc_t *sc;
+
+ sc = device_get_softc(dev);
+
+ return (PHY_READ_2(sc, phy, reg));
+}
+
+static int
+epic_miibus_writereg(dev, phy, reg, data)
+ device_t dev;
+ int phy, reg, data;
+{
+ epic_softc_t *sc;
+
+ sc = device_get_softc(dev);
+
+ PHY_WRITE_2(sc, phy, reg, data);
+
+ return (0);
}
diff --git a/sys/dev/tx/if_txreg.h b/sys/dev/tx/if_txreg.h
index 49a3941..35685af 100644
--- a/sys/dev/tx/if_txreg.h
+++ b/sys/dev/tx/if_txreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_txvar.h,v 1.3 1998/10/10 04:30:09 jason Exp $ */
+/* $OpenBSD: if_txvar.h,v 1.7 1999/11/17 05:21:19 jason Exp $ */
/* $FreeBSD$ */
/*-
@@ -25,13 +25,15 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- *
*/
/*
* Configuration
*/
+/*#define EPIC_DEBUG 1*/
+/*#define EPIC_USEIOSPACE 1*/
+#define EARLY_RX 1
+
#ifndef ETHER_MAX_LEN
#define ETHER_MAX_LEN 1518
#endif
@@ -46,33 +48,20 @@
/* confuse RX(TX)_RING_MASK */
#define TX_RING_MASK (TX_RING_SIZE - 1)
#define RX_RING_MASK (RX_RING_SIZE - 1)
-#define EPIC_FULL_DUPLEX 1
-#define EPIC_HALF_DUPLEX 0
#define ETHER_MAX_FRAME_LEN (ETHER_MAX_LEN + ETHER_CRC_LEN)
-#define EPIC_LINK_DOWN 0x00000001
+
+/* PCI aux configuration registers */
+#if defined(__FreeBSD__)
+#define PCIR_BASEIO (PCIR_MAPS + 0x0) /* Base IO Address */
+#define PCIR_BASEMEM (PCIR_MAPS + 0x4) /* Base Memory Address */
+#else /* __OpenBSD__ */
+#define PCI_BASEIO (PCI_MAPS + 0x0) /* Base IO Address */
+#define PCI_BASEMEM (PCI_MAPS + 0x4) /* Base Memory Address */
+#endif /* __FreeBSD__ */
/* PCI identification */
#define SMC_VENDORID 0x10B8
-#define CHIPID_83C170 0x0005
-#define PCI_VENDORID(x) ((x) & 0xFFFF)
-#define PCI_CHIPID(x) (((x) >> 16) & 0xFFFF)
-
-/* PCI configuration */
-#define PCI_CFID 0x00 /* Configuration ID */
-#define PCI_CFCS 0x04 /* Configurtion Command/Status */
-#define PCI_CFRV 0x08 /* Configuration Revision */
-#define PCI_CFLT 0x0c /* Configuration Latency Timer */
-#define PCI_CBIO 0x10 /* Configuration Base IO Address */
-#define PCI_CBMA 0x14 /* Configuration Base Memory Address */
-#define PCI_CFIT 0x3c /* Configuration Interrupt */
-#define PCI_CFDA 0x40 /* Configuration Driver Area */
-
-#define PCI_CFCS_IOEN 0x0001 /* IO Sapce Enable */
-#define PCI_CFCS_MAEN 0x0002 /* Memory Space Enable */
-#define PCI_CFCS_BMEN 0x0004 /* Bus Master Enable */
-
-#define PCI_CONF_WRITE(r, v) pci_conf_write(config_id, (r), (v))
-#define PCI_CONF_READ(r) pci_conf_read(config_id, (r))
+#define SMC_DEVICEID_83C170 0x0005
/* EPIC's registers */
#define COMMAND 0x0000
@@ -115,9 +104,6 @@
#define COMMAND_STOP_RDMA 0x40
#define COMMAND_TXUGO 0x80
-/* Tx threshold */
-#define TX_FIFO_THRESH 0x80 /* 0x40 or 0x10 */
-
/* Interrupt register bits */
#define INTSTAT_RCC 0x00000001
#define INTSTAT_HCC 0x00000002
@@ -200,80 +186,22 @@
#define TEST1_CLOCK_TEST 0x00000008
+/*
+ * Some default values
+ */
#define TXCON_DEFAULT (TXCON_SLOT_TIME | TXCON_EARLY_TRANSMIT_ENABLE)
-#define TRANSMIT_THRESHOLD 0x80
+#define TRANSMIT_THRESHOLD 0x300
#if defined(EARLY_RX)
- #define RXCON_DEFAULT (RXCON_EARLY_RECEIVE_ENABLE | RXCON_SAVE_ERRORED_PACKETS)
+#define RXCON_EARLY (RXCON_EARLY_RECEIVE_ENABLE | \
+ RXCON_SAVE_ERRORED_PACKETS)
#else
- #define RXCON_DEFAULT (0)
+#define RXCON_EARLY (0)
#endif
-/*
- * National Semiconductor's DP83840A Registers and bits
- */
-#define DP83840_OUI 0x080017
-#define DP83840_BMCR 0x00 /* Control register */
-#define DP83840_BMSR 0x01 /* Status rgister */
-#define DP83840_ANAR 0x04 /* Autonegotiation advertising register */
-#define DP83840_LPAR 0x05 /* Link Partner Ability register */
-#define DP83840_ANER 0x06 /* Auto-Negotiation Expansion Register */
-#define DP83840_PAR 0x19 /* PHY Address Register */
-#define DP83840_PHYIDR1 0x02
-#define DP83840_PHYIDR2 0x03
-
-#define BMCR_RESET 0x8000
-#define BMCR_LOOPBACK 0x4000
-#define BMCR_100MBPS 0x2000 /* 10/100 Mbps */
-#define BMCR_AUTONEGOTIATION 0x1000 /* ON/OFF */
-#define BMCR_POWERDOWN 0x0800
-#define BMCR_ISOLATE 0x0400
-#define BMCR_RESTART_AUTONEG 0x0200
-#define BMCR_FULL_DUPLEX 0x0100
-#define BMCR_COL_TEST 0x0080
-
-#define BMSR_100BASE_T4 0x8000
-#define BMSR_100BASE_TX_FD 0x4000
-#define BMSR_100BASE_TX 0x2000
-#define BMSR_10BASE_T_FD 0x1000
-#define BMSR_10BASE_T 0x0800
-#define BMSR_AUTONEG_COMPLETE 0x0020
-#define BMSR_AUTONEG_ABLE 0x0008
-#define BMSR_LINK_STATUS 0x0004
-
-#define PAR_FULL_DUPLEX 0x0400
-
-#define ANER_MULTIPLE_LINK_FAULT 0x10
-
-/* ANAR and LPAR have the same bits, define them only once */
-#define ANAR_10 0x0020
-#define ANAR_10_FD 0x0040
-#define ANAR_100_TX 0x0080
-#define ANAR_100_TX_FD 0x0100
-#define ANAR_100_T4 0x0200
-/*
- * Quality Semiconductor's QS6612 registers and bits
- */
-#define QS6612_OUI 0x006051
-#define QS6612_MCTL 17
-#define QS6612_INTSTAT 29
-#define QS6612_INTMASK 30
-#define QS6612_BPCR 31
-
-#define MCTL_T4_PRESENT 0x1000 /* External T4 Enabled, ignored */
- /* if AutoNeg is enabled */
-#define MCTL_BTEXT 0x0800 /* Reduces 10baset squelch level */
- /* for extended cable length */
-
-#define INTSTAT_AN_COMPLETE 0x40 /* Autonegotiation complete */
-#define INTSTAT_RF_DETECTED 0x20 /* Remote Fault detected */
-#define INTSTAT_LINK_STATUS 0x10 /* Link status changed */
-#define INTSTAT_AN_LP_ACK 0x08 /* Autoneg. LP Acknoledge */
-#define INTSTAT_PD_FAULT 0x04 /* Parallel Detection Fault */
-#define INTSTAT_AN_PAGE 0x04 /* Autoneg. Page Received */
-#define INTSTAT_RE_CNT_FULL 0x01 /* Receive Error Counter Full */
-
-#define INTMASK_THUNDERLAN 0x8000 /* Enable interrupts */
+#define RXCON_DEFAULT (RXCON_EARLY | \
+ RXCON_RECEIVE_MULTICAST_FRAMES | \
+ RXCON_RECEIVE_BROADCAST_FRAMES)
/*
* Structures definition and Functions prototypes
@@ -330,20 +258,20 @@ typedef struct {
struct arpcom arpcom;
#if defined(__OpenBSD__)
struct device sc_dev;
+ mii_data_t sc_mii;
+#else /* __FreeBSD__ */
+ struct resource *res;
+ struct resource *irq;
+
+ device_t miibus;
+ struct callout_handle stat_ch;
+
+ u_int32_t unit;
+#endif
void *sc_ih;
bus_space_tag_t sc_st;
bus_space_handle_t sc_sh;
-#else /* __FreeBSD__ */
-#if defined(EPIC_USEIOSPACE)
- u_int32_t iobase;
-#else
- caddr_t csr;
-#endif
-#endif
-#if !defined(EPIC_NOIFMEDIA)
- struct ifmedia ifmedia;
-#endif
- u_int32_t unit;
+
struct epic_rx_buffer rx_buffer[RX_RING_SIZE];
struct epic_tx_buffer tx_buffer[TX_RING_SIZE];
@@ -363,43 +291,31 @@ typedef struct {
void *pool;
} epic_softc_t;
+struct epic_type {
+ u_int16_t ven_id;
+ u_int16_t dev_id;
+ char *name;
+};
+
+#if defined(EPIC_DEBUG)
+#define dprintf(a) printf a
+#else
+#define dprintf(a)
+#endif
+
#if defined(__FreeBSD__)
#define EPIC_FORMAT "tx%d"
#define EPIC_ARGS(sc) (sc->unit)
-#define sc_if arpcom.ac_if
-#define sc_macaddr arpcom.ac_enaddr
-#if defined(EPIC_USEIOSPACE)
-#define CSR_WRITE_4(sc,reg,val) \
- outl( (sc)->iobase + (u_int32_t)(reg), (val) )
-#define CSR_WRITE_2(sc,reg,val) \
- outw( (sc)->iobase + (u_int32_t)(reg), (val) )
-#define CSR_WRITE_1(sc,reg,val) \
- outb( (sc)->iobase + (u_int32_t)(reg), (val) )
-#define CSR_READ_4(sc,reg) \
- inl( (sc)->iobase + (u_int32_t)(reg) )
-#define CSR_READ_2(sc,reg) \
- inw( (sc)->iobase + (u_int32_t)(reg) )
-#define CSR_READ_1(sc,reg) \
- inb( (sc)->iobase + (u_int32_t)(reg) )
-#else
-#define CSR_WRITE_1(sc,reg,val) \
- ((*(volatile u_int8_t*)((sc)->csr + (u_int32_t)(reg))) = (u_int8_t)(val))
-#define CSR_WRITE_2(sc,reg,val) \
- ((*(volatile u_int16_t*)((sc)->csr + (u_int32_t)(reg))) = (u_int16_t)(val))
-#define CSR_WRITE_4(sc,reg,val) \
- ((*(volatile u_int32_t*)((sc)->csr + (u_int32_t)(reg))) = (u_int32_t)(val))
-#define CSR_READ_1(sc,reg) \
- (*(volatile u_int8_t*)((sc)->csr + (u_int32_t)(reg)))
-#define CSR_READ_2(sc,reg) \
- (*(volatile u_int16_t*)((sc)->csr + (u_int32_t)(reg)))
-#define CSR_READ_4(sc,reg) \
- (*(volatile u_int32_t*)((sc)->csr + (u_int32_t)(reg)))
-#endif
+#define EPIC_BPFTAP_ARG(ifp) ifp
#else /* __OpenBSD__ */
#define EPIC_FORMAT "%s"
#define EPIC_ARGS(sc) (sc->sc_dev.dv_xname)
-#define sc_if arpcom.ac_if
+#define EPIC_BPFTAP_ARG(ifp) (ifp)->if_bpf
+#endif
+
+#define sc_if arpcom.ac_if
#define sc_macaddr arpcom.ac_enaddr
+
#define CSR_WRITE_4(sc,reg,val) \
bus_space_write_4( (sc)->sc_st, (sc)->sc_sh, (reg), (val) )
#define CSR_WRITE_2(sc,reg,val) \
@@ -412,8 +328,21 @@ typedef struct {
bus_space_read_2( (sc)->sc_st, (sc)->sc_sh, (reg) )
#define CSR_READ_1(sc,reg) \
bus_space_read_1( (sc)->sc_st, (sc)->sc_sh, (reg) )
-#endif
-#define PHY_READ_2(sc,reg) epic_read_phy_register(sc,reg)
-#define PHY_WRITE_2(sc,reg,val) epic_write_phy_register(sc,reg,val)
+#define PHY_READ_2(sc,phy,reg) \
+ epic_read_phy_reg((sc),(phy),(reg))
+#define PHY_WRITE_2(sc,phy,reg,val) \
+ epic_write_phy_reg((sc),(phy),(reg),(val))
+
+/* Macro to get either mbuf cluster or nothing */
+#define EPIC_MGETCLUSTER(m) \
+ { MGETHDR((m),M_DONTWAIT,MT_DATA); \
+ if (m) { \
+ MCLGET((m),M_DONTWAIT); \
+ if( 0 == ((m)->m_flags & M_EXT) ) { \
+ m_freem(m); \
+ (m) = NULL; \
+ } \
+ } \
+ }
diff --git a/sys/dev/tx/if_txvar.h b/sys/dev/tx/if_txvar.h
index 49a3941..35685af 100644
--- a/sys/dev/tx/if_txvar.h
+++ b/sys/dev/tx/if_txvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_txvar.h,v 1.3 1998/10/10 04:30:09 jason Exp $ */
+/* $OpenBSD: if_txvar.h,v 1.7 1999/11/17 05:21:19 jason Exp $ */
/* $FreeBSD$ */
/*-
@@ -25,13 +25,15 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- *
*/
/*
* Configuration
*/
+/*#define EPIC_DEBUG 1*/
+/*#define EPIC_USEIOSPACE 1*/
+#define EARLY_RX 1
+
#ifndef ETHER_MAX_LEN
#define ETHER_MAX_LEN 1518
#endif
@@ -46,33 +48,20 @@
/* confuse RX(TX)_RING_MASK */
#define TX_RING_MASK (TX_RING_SIZE - 1)
#define RX_RING_MASK (RX_RING_SIZE - 1)
-#define EPIC_FULL_DUPLEX 1
-#define EPIC_HALF_DUPLEX 0
#define ETHER_MAX_FRAME_LEN (ETHER_MAX_LEN + ETHER_CRC_LEN)
-#define EPIC_LINK_DOWN 0x00000001
+
+/* PCI aux configuration registers */
+#if defined(__FreeBSD__)
+#define PCIR_BASEIO (PCIR_MAPS + 0x0) /* Base IO Address */
+#define PCIR_BASEMEM (PCIR_MAPS + 0x4) /* Base Memory Address */
+#else /* __OpenBSD__ */
+#define PCI_BASEIO (PCI_MAPS + 0x0) /* Base IO Address */
+#define PCI_BASEMEM (PCI_MAPS + 0x4) /* Base Memory Address */
+#endif /* __FreeBSD__ */
/* PCI identification */
#define SMC_VENDORID 0x10B8
-#define CHIPID_83C170 0x0005
-#define PCI_VENDORID(x) ((x) & 0xFFFF)
-#define PCI_CHIPID(x) (((x) >> 16) & 0xFFFF)
-
-/* PCI configuration */
-#define PCI_CFID 0x00 /* Configuration ID */
-#define PCI_CFCS 0x04 /* Configurtion Command/Status */
-#define PCI_CFRV 0x08 /* Configuration Revision */
-#define PCI_CFLT 0x0c /* Configuration Latency Timer */
-#define PCI_CBIO 0x10 /* Configuration Base IO Address */
-#define PCI_CBMA 0x14 /* Configuration Base Memory Address */
-#define PCI_CFIT 0x3c /* Configuration Interrupt */
-#define PCI_CFDA 0x40 /* Configuration Driver Area */
-
-#define PCI_CFCS_IOEN 0x0001 /* IO Sapce Enable */
-#define PCI_CFCS_MAEN 0x0002 /* Memory Space Enable */
-#define PCI_CFCS_BMEN 0x0004 /* Bus Master Enable */
-
-#define PCI_CONF_WRITE(r, v) pci_conf_write(config_id, (r), (v))
-#define PCI_CONF_READ(r) pci_conf_read(config_id, (r))
+#define SMC_DEVICEID_83C170 0x0005
/* EPIC's registers */
#define COMMAND 0x0000
@@ -115,9 +104,6 @@
#define COMMAND_STOP_RDMA 0x40
#define COMMAND_TXUGO 0x80
-/* Tx threshold */
-#define TX_FIFO_THRESH 0x80 /* 0x40 or 0x10 */
-
/* Interrupt register bits */
#define INTSTAT_RCC 0x00000001
#define INTSTAT_HCC 0x00000002
@@ -200,80 +186,22 @@
#define TEST1_CLOCK_TEST 0x00000008
+/*
+ * Some default values
+ */
#define TXCON_DEFAULT (TXCON_SLOT_TIME | TXCON_EARLY_TRANSMIT_ENABLE)
-#define TRANSMIT_THRESHOLD 0x80
+#define TRANSMIT_THRESHOLD 0x300
#if defined(EARLY_RX)
- #define RXCON_DEFAULT (RXCON_EARLY_RECEIVE_ENABLE | RXCON_SAVE_ERRORED_PACKETS)
+#define RXCON_EARLY (RXCON_EARLY_RECEIVE_ENABLE | \
+ RXCON_SAVE_ERRORED_PACKETS)
#else
- #define RXCON_DEFAULT (0)
+#define RXCON_EARLY (0)
#endif
-/*
- * National Semiconductor's DP83840A Registers and bits
- */
-#define DP83840_OUI 0x080017
-#define DP83840_BMCR 0x00 /* Control register */
-#define DP83840_BMSR 0x01 /* Status rgister */
-#define DP83840_ANAR 0x04 /* Autonegotiation advertising register */
-#define DP83840_LPAR 0x05 /* Link Partner Ability register */
-#define DP83840_ANER 0x06 /* Auto-Negotiation Expansion Register */
-#define DP83840_PAR 0x19 /* PHY Address Register */
-#define DP83840_PHYIDR1 0x02
-#define DP83840_PHYIDR2 0x03
-
-#define BMCR_RESET 0x8000
-#define BMCR_LOOPBACK 0x4000
-#define BMCR_100MBPS 0x2000 /* 10/100 Mbps */
-#define BMCR_AUTONEGOTIATION 0x1000 /* ON/OFF */
-#define BMCR_POWERDOWN 0x0800
-#define BMCR_ISOLATE 0x0400
-#define BMCR_RESTART_AUTONEG 0x0200
-#define BMCR_FULL_DUPLEX 0x0100
-#define BMCR_COL_TEST 0x0080
-
-#define BMSR_100BASE_T4 0x8000
-#define BMSR_100BASE_TX_FD 0x4000
-#define BMSR_100BASE_TX 0x2000
-#define BMSR_10BASE_T_FD 0x1000
-#define BMSR_10BASE_T 0x0800
-#define BMSR_AUTONEG_COMPLETE 0x0020
-#define BMSR_AUTONEG_ABLE 0x0008
-#define BMSR_LINK_STATUS 0x0004
-
-#define PAR_FULL_DUPLEX 0x0400
-
-#define ANER_MULTIPLE_LINK_FAULT 0x10
-
-/* ANAR and LPAR have the same bits, define them only once */
-#define ANAR_10 0x0020
-#define ANAR_10_FD 0x0040
-#define ANAR_100_TX 0x0080
-#define ANAR_100_TX_FD 0x0100
-#define ANAR_100_T4 0x0200
-/*
- * Quality Semiconductor's QS6612 registers and bits
- */
-#define QS6612_OUI 0x006051
-#define QS6612_MCTL 17
-#define QS6612_INTSTAT 29
-#define QS6612_INTMASK 30
-#define QS6612_BPCR 31
-
-#define MCTL_T4_PRESENT 0x1000 /* External T4 Enabled, ignored */
- /* if AutoNeg is enabled */
-#define MCTL_BTEXT 0x0800 /* Reduces 10baset squelch level */
- /* for extended cable length */
-
-#define INTSTAT_AN_COMPLETE 0x40 /* Autonegotiation complete */
-#define INTSTAT_RF_DETECTED 0x20 /* Remote Fault detected */
-#define INTSTAT_LINK_STATUS 0x10 /* Link status changed */
-#define INTSTAT_AN_LP_ACK 0x08 /* Autoneg. LP Acknoledge */
-#define INTSTAT_PD_FAULT 0x04 /* Parallel Detection Fault */
-#define INTSTAT_AN_PAGE 0x04 /* Autoneg. Page Received */
-#define INTSTAT_RE_CNT_FULL 0x01 /* Receive Error Counter Full */
-
-#define INTMASK_THUNDERLAN 0x8000 /* Enable interrupts */
+#define RXCON_DEFAULT (RXCON_EARLY | \
+ RXCON_RECEIVE_MULTICAST_FRAMES | \
+ RXCON_RECEIVE_BROADCAST_FRAMES)
/*
* Structures definition and Functions prototypes
@@ -330,20 +258,20 @@ typedef struct {
struct arpcom arpcom;
#if defined(__OpenBSD__)
struct device sc_dev;
+ mii_data_t sc_mii;
+#else /* __FreeBSD__ */
+ struct resource *res;
+ struct resource *irq;
+
+ device_t miibus;
+ struct callout_handle stat_ch;
+
+ u_int32_t unit;
+#endif
void *sc_ih;
bus_space_tag_t sc_st;
bus_space_handle_t sc_sh;
-#else /* __FreeBSD__ */
-#if defined(EPIC_USEIOSPACE)
- u_int32_t iobase;
-#else
- caddr_t csr;
-#endif
-#endif
-#if !defined(EPIC_NOIFMEDIA)
- struct ifmedia ifmedia;
-#endif
- u_int32_t unit;
+
struct epic_rx_buffer rx_buffer[RX_RING_SIZE];
struct epic_tx_buffer tx_buffer[TX_RING_SIZE];
@@ -363,43 +291,31 @@ typedef struct {
void *pool;
} epic_softc_t;
+struct epic_type {
+ u_int16_t ven_id;
+ u_int16_t dev_id;
+ char *name;
+};
+
+#if defined(EPIC_DEBUG)
+#define dprintf(a) printf a
+#else
+#define dprintf(a)
+#endif
+
#if defined(__FreeBSD__)
#define EPIC_FORMAT "tx%d"
#define EPIC_ARGS(sc) (sc->unit)
-#define sc_if arpcom.ac_if
-#define sc_macaddr arpcom.ac_enaddr
-#if defined(EPIC_USEIOSPACE)
-#define CSR_WRITE_4(sc,reg,val) \
- outl( (sc)->iobase + (u_int32_t)(reg), (val) )
-#define CSR_WRITE_2(sc,reg,val) \
- outw( (sc)->iobase + (u_int32_t)(reg), (val) )
-#define CSR_WRITE_1(sc,reg,val) \
- outb( (sc)->iobase + (u_int32_t)(reg), (val) )
-#define CSR_READ_4(sc,reg) \
- inl( (sc)->iobase + (u_int32_t)(reg) )
-#define CSR_READ_2(sc,reg) \
- inw( (sc)->iobase + (u_int32_t)(reg) )
-#define CSR_READ_1(sc,reg) \
- inb( (sc)->iobase + (u_int32_t)(reg) )
-#else
-#define CSR_WRITE_1(sc,reg,val) \
- ((*(volatile u_int8_t*)((sc)->csr + (u_int32_t)(reg))) = (u_int8_t)(val))
-#define CSR_WRITE_2(sc,reg,val) \
- ((*(volatile u_int16_t*)((sc)->csr + (u_int32_t)(reg))) = (u_int16_t)(val))
-#define CSR_WRITE_4(sc,reg,val) \
- ((*(volatile u_int32_t*)((sc)->csr + (u_int32_t)(reg))) = (u_int32_t)(val))
-#define CSR_READ_1(sc,reg) \
- (*(volatile u_int8_t*)((sc)->csr + (u_int32_t)(reg)))
-#define CSR_READ_2(sc,reg) \
- (*(volatile u_int16_t*)((sc)->csr + (u_int32_t)(reg)))
-#define CSR_READ_4(sc,reg) \
- (*(volatile u_int32_t*)((sc)->csr + (u_int32_t)(reg)))
-#endif
+#define EPIC_BPFTAP_ARG(ifp) ifp
#else /* __OpenBSD__ */
#define EPIC_FORMAT "%s"
#define EPIC_ARGS(sc) (sc->sc_dev.dv_xname)
-#define sc_if arpcom.ac_if
+#define EPIC_BPFTAP_ARG(ifp) (ifp)->if_bpf
+#endif
+
+#define sc_if arpcom.ac_if
#define sc_macaddr arpcom.ac_enaddr
+
#define CSR_WRITE_4(sc,reg,val) \
bus_space_write_4( (sc)->sc_st, (sc)->sc_sh, (reg), (val) )
#define CSR_WRITE_2(sc,reg,val) \
@@ -412,8 +328,21 @@ typedef struct {
bus_space_read_2( (sc)->sc_st, (sc)->sc_sh, (reg) )
#define CSR_READ_1(sc,reg) \
bus_space_read_1( (sc)->sc_st, (sc)->sc_sh, (reg) )
-#endif
-#define PHY_READ_2(sc,reg) epic_read_phy_register(sc,reg)
-#define PHY_WRITE_2(sc,reg,val) epic_write_phy_register(sc,reg,val)
+#define PHY_READ_2(sc,phy,reg) \
+ epic_read_phy_reg((sc),(phy),(reg))
+#define PHY_WRITE_2(sc,phy,reg,val) \
+ epic_write_phy_reg((sc),(phy),(reg),(val))
+
+/* Macro to get either mbuf cluster or nothing */
+#define EPIC_MGETCLUSTER(m) \
+ { MGETHDR((m),M_DONTWAIT,MT_DATA); \
+ if (m) { \
+ MCLGET((m),M_DONTWAIT); \
+ if( 0 == ((m)->m_flags & M_EXT) ) { \
+ m_freem(m); \
+ (m) = NULL; \
+ } \
+ } \
+ }
diff --git a/sys/pci/if_tx.c b/sys/pci/if_tx.c
index 288edbd..fa03716 100644
--- a/sys/pci/if_tx.c
+++ b/sys/pci/if_tx.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_tx.c,v 1.3 1998/10/10 04:30:09 jason Exp $ */
+/* $OpenBSD: if_tx.c,v 1.9.2.1 2000/02/21 22:29:13 niklas Exp $ */
/* $FreeBSD$ */
/*-
@@ -25,8 +25,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- *
*/
/*
@@ -37,60 +35,72 @@
*
* todo:
* Implement FULL IFF_MULTICAST support.
- * Test, test and test again:-(
*
*/
/* We should define compile time options before if_txvar.h included */
-/*#define EPIC_NOIFMEDIA 1*/
-/*#define EPIC_USEIOSPACE 1*/
#define EARLY_RX 1
/*#define EPIC_DEBUG 1*/
-#if defined(EPIC_DEBUG)
-#define dprintf(a) printf a
-#else
-#define dprintf(a)
-#endif
-
-/* Macro to get either mbuf cluster or nothing */
-#define EPIC_MGETCLUSTER(m) \
- { MGETHDR((m),M_DONTWAIT,MT_DATA); \
- if (m) { \
- MCLGET((m),M_DONTWAIT); \
- if( 0 == ((m)->m_flags & M_EXT) ){ \
- m_freem(m); \
- (m) = NULL; \
- } \
- } \
- }
-
-#include "bpf.h"
-#include "opt_bdg.h"
-
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/sockio.h>
#include <sys/mbuf.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/socket.h>
-#include <sys/sockio.h>
+#include <sys/queue.h>
+
+#if defined(__FreeBSD__)
+#include "opt_bdg.h"
+#define NBPFILTER 1
+
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/ethernet.h>
+#include <net/if_media.h>
+
+#include <net/bpf.h>
+
+#ifdef BRIDGE
+#include <net/bridge.h>
+#endif
+
+#include <vm/vm.h> /* for vtophys */
+#include <vm/pmap.h> /* for vtophys */
+#include <machine/clock.h> /* for DELAY */
+#include <machine/bus_memio.h>
+#include <machine/bus_pio.h>
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+
+#include <pci/pcireg.h>
+#include <pci/pcivar.h>
+
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+
+#include "miibus_if.h"
+
+#include <pci/if_txvar.h>
+#else /* __OpenBSD__ */
+#include "bpfilter.h"
+
+#include <sys/device.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_types.h>
-
-#if !defined(SIOCSIFMEDIA) || defined(EPIC_NOIFMEDIA)
-#define EPIC_NOIFMEDIA 1
-#else
#include <net/if_media.h>
-#endif
#ifdef INET
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/in_var.h>
#include <netinet/ip.h>
+#include <netinet/if_ether.h>
#endif
#ifdef IPX
@@ -103,64 +113,38 @@
#include <netns/ns_if.h>
#endif
-#if NBPF > 0
+#if NBPFILTER > 0
#include <net/bpf.h>
-#include <net/bpfdesc.h>
#endif
-#if defined(__OpenBSD__)
-#include <sys/ioctl.h>
-#include <sys/errno.h>
-#include <sys/device.h>
-
-#include <netinet/if_ether.h>
-
#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcidevs.h>
#include <dev/pci/if_txvar.h>
-#else /* __FreeBSD__ */
-#include <sys/eventhandler.h>
-#include <net/if_mib.h>
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-#include <vm/vm.h>
-#include <vm/pmap.h>
-#include <machine/clock.h>
-
-#include <pci/pcivar.h>
-#include <pci/if_txvar.h>
-
-#ifdef BRIDGE
-#include <net/bridge.h>
-#endif
-
#endif
#if defined(__FreeBSD__)
-#if __FreeBSD_version >= 300000
-#define EPIC_IFIOCTL_CMD_TYPE u_long
-#else
-#define EPIC_IFIOCTL_CMD_TYPE int
-#endif
#define EPIC_INTR_RET_TYPE void
#else /* __OpenBSD__ */
-#define EPIC_IFIOCTL_CMD_TYPE u_long
#define EPIC_INTR_RET_TYPE int
#endif
-static int epic_ifioctl __P((register struct ifnet *, EPIC_IFIOCTL_CMD_TYPE, caddr_t));
+static int epic_ifioctl __P((register struct ifnet *, u_long, caddr_t));
static EPIC_INTR_RET_TYPE epic_intr __P((void *));
static int epic_common_attach __P((epic_softc_t *));
-static void epic_ifstart __P((struct ifnet * const));
+static void epic_ifstart __P((struct ifnet *));
static void epic_ifwatchdog __P((struct ifnet *));
static int epic_init __P((epic_softc_t *));
static void epic_stop __P((epic_softc_t *));
-static __inline void epic_rx_done __P((epic_softc_t *));
-static __inline void epic_tx_done __P((epic_softc_t *));
+static void epic_rx_done __P((epic_softc_t *));
+static void epic_tx_done __P((epic_softc_t *));
static int epic_init_rings __P((epic_softc_t *));
static void epic_free_rings __P((epic_softc_t *));
static void epic_stop_activity __P((epic_softc_t *));
@@ -168,39 +152,22 @@ static void epic_start_activity __P((epic_softc_t *));
static void epic_set_rx_mode __P((epic_softc_t *));
static void epic_set_tx_mode __P((epic_softc_t *));
static void epic_set_mc_table __P((epic_softc_t *));
-static void epic_set_media_speed __P((epic_softc_t *));
-static void epic_init_phy __P((epic_softc_t *));
-static void epic_dump_state __P((epic_softc_t *));
-static int epic_autoneg __P((epic_softc_t *));
static int epic_read_eeprom __P((epic_softc_t *,u_int16_t));
static void epic_output_eepromw __P((epic_softc_t *, u_int16_t));
static u_int16_t epic_input_eepromw __P((epic_softc_t *));
static u_int8_t epic_eeprom_clock __P((epic_softc_t *,u_int8_t));
static void epic_write_eepromreg __P((epic_softc_t *,u_int8_t));
static u_int8_t epic_read_eepromreg __P((epic_softc_t *));
-static u_int16_t epic_read_phy_register __P((epic_softc_t *, u_int16_t));
-static void epic_write_phy_register __P((epic_softc_t *, u_int16_t, u_int16_t));
-#if !defined(EPIC_NOIFMEDIA)
-static int epic_ifmedia_change __P((struct ifnet *));
-static void epic_ifmedia_status __P((struct ifnet *, struct ifmediareq *));
-#endif
+static int epic_read_phy_reg __P((epic_softc_t *, int, int));
+static void epic_write_phy_reg __P((epic_softc_t *, int, int, int));
-int epic_mtypes [] = {
- IFM_ETHER | IFM_10_T,
- IFM_ETHER | IFM_10_T | IFM_FDX,
- IFM_ETHER | IFM_100_TX,
- IFM_ETHER | IFM_100_TX | IFM_FDX,
- IFM_ETHER | IFM_10_T | IFM_LOOP,
- IFM_ETHER | IFM_10_T | IFM_FDX | IFM_LOOP,
- IFM_ETHER | IFM_10_T | IFM_LOOP | IFM_FLAG1,
- IFM_ETHER | IFM_100_TX | IFM_LOOP,
- IFM_ETHER | IFM_100_TX | IFM_LOOP | IFM_FLAG1,
- IFM_ETHER | IFM_100_TX | IFM_FDX | IFM_LOOP,
- IFM_ETHER | IFM_AUTO
-};
-#define EPIC_MTYPESNUM (sizeof(epic_mtypes) / sizeof(epic_mtypes[0]))
+static int epic_miibus_readreg __P((device_t, int, int));
+static int epic_miibus_writereg __P((device_t, int, int, int));
+static void epic_miibus_statchg __P((device_t));
+static int epic_ifmedia_upd __P((struct ifnet *));
+static void epic_ifmedia_sts __P((struct ifnet *, struct ifmediareq *));
/* -------------------------------------------------------------------------
OS-specific part
@@ -209,9 +176,9 @@ int epic_mtypes [] = {
#if defined(__OpenBSD__)
/* -----------------------------OpenBSD------------------------------------- */
-static int epic_openbsd_probe __P((struct device *,void *,void *));
-static void epic_openbsd_attach __P((struct device *, struct device *, void *));
-static void epic_shutdown __P((void *));
+int epic_openbsd_probe __P((struct device *,void *,void *));
+void epic_openbsd_attach __P((struct device *, struct device *, void *));
+void epic_openbsd_shutdown __P((void *));
struct cfattach tx_ca = {
sizeof(epic_softc_t), epic_openbsd_probe, epic_openbsd_attach
@@ -221,7 +188,7 @@ struct cfdriver tx_cd = {
};
/* Synopsis: Check if device id corresponds with SMC83C170 id. */
-static int
+int
epic_openbsd_probe(
struct device *parent,
void *match,
@@ -231,13 +198,13 @@ epic_openbsd_probe(
if( PCI_VENDOR(pa->pa_id) != SMC_VENDORID )
return 0;
- if( PCI_PRODUCT(pa->pa_id) == CHIPID_83C170 )
+ if( PCI_PRODUCT(pa->pa_id) == SMC_DEVICEID_83C170 )
return 1;
return 0;
}
-static void
+void
epic_openbsd_attach(
struct device *parent,
struct device *self,
@@ -249,23 +216,46 @@ epic_openbsd_attach(
pci_intr_handle_t ih;
const char *intrstr = NULL;
struct ifnet *ifp;
- bus_space_tag_t iot = pa->pa_iot;
bus_addr_t iobase;
bus_size_t iosize;
int i;
-#if !defined(EPIC_NOIFMEDIA)
- int tmp;
-#endif
+ u_int32_t command;
+
+ command = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
+ command |= PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE |
+ PCI_COMMAND_MASTER_ENABLE;
+ pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, command);
+ command = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
- if( pci_io_find(pc, pa->pa_tag, PCI_CBIO, &iobase, &iosize)) {
+#ifdef EPIC_USEIOSPACE
+ if (!(command & PCI_COMMAND_IO_ENABLE)) {
+ printf(": failed to enable I/O ports\n");
+ return;
+ }
+ if( pci_io_find(pc, pa->pa_tag, PCI_BASEIO, &iobase, &iosize)) {
printf(": can't find i/o space\n");
return;
}
- if( bus_space_map(iot, iobase, iosize, 0, &sc->sc_sh)) {
+ if( bus_space_map(pa->pa_iot, iobase, iosize, 0, &sc->sc_sh)) {
printf(": can't map i/o space\n");
return;
}
- sc->sc_st = iot;
+ sc->sc_st = pa->pa_iot;
+#else
+ if (!(command & PCI_COMMAND_MEM_ENABLE)) {
+ printf(": failed to enable memory mapping\n");
+ return;
+ }
+ if( pci_mem_find(pc, pa->pa_tag, PCI_BASEMEM, &iobase, &iosize, NULL)) {
+ printf(": can't find mem space\n");
+ return;
+ }
+ if( bus_space_map(pa->pa_memt, iobase, iosize, 0, &sc->sc_sh)) {
+ printf(": can't map i/o space\n");
+ return;
+ }
+ sc->sc_st = pa->pa_memt;
+#endif
ifp = &sc->sc_if;
bcopy(sc->sc_dev.dv_xname, ifp->if_xname,IFNAMSIZ);
@@ -298,75 +288,37 @@ epic_openbsd_attach(
/* Display some info */
printf(" address %s",ether_sprintf(sc->sc_macaddr));
- /* Read current media config and display it too */
- i = PHY_READ_2( sc, DP83840_BMCR );
-#if !defined(EPIC_NOIFMEDIA)
- tmp = IFM_ETHER;
-#endif
- if( i & BMCR_AUTONEGOTIATION ){
- printf(", Auto-Neg ");
-
- /* To avoid bug in QS6612 read LPAR enstead of BMSR */
- i = PHY_READ_2( sc, DP83840_LPAR );
- if( i & (ANAR_100_TX|ANAR_100_TX_FD) ) printf("100Mbps");
- else printf("10Mbps");
- if( i & (ANAR_10_FD|ANAR_100_TX_FD) ) printf(" FD");
-#if !defined(EPIC_NOIFMEDIA)
- tmp |= IFM_AUTO;
-#endif
- } else {
-#if defined(EPIC_NOIFMEDIA)
- ifp->if_flags |= IFF_LINK0;
-#endif
- if( i & BMCR_100MBPS ) {
- printf(", 100Mbps");
-#if !defined(EPIC_NOIFMEDIA)
- tmp |= IFM_100_TX;
-#else
- ifp->if_flags |= IFF_LINK2;
-#endif
- } else {
- printf(", 10Mbps");
-#if !defined(EPIC_NOIFMEDIA)
- tmp |= IFM_10_T;
-#endif
- }
- if( i & BMCR_FULL_DUPLEX ) {
- printf(" FD");
-#if !defined(EPIC_NOIFMEDIA)
- tmp |= IFM_FDX;
-#else
- ifp->if_flags |= IFF_LINK1;
-#endif
- }
- }
/* Init ifmedia interface */
-#if !defined(EPIC_NOIFMEDIA)
- ifmedia_init(&sc->ifmedia,0,epic_ifmedia_change,epic_ifmedia_status);
-
- for (i=0; i<EPIC_MTYPESNUM; i++)
- ifmedia_add(&sc->ifmedia,epic_mtypes[i],0,NULL);
-
- ifmedia_set(&sc->ifmedia, tmp);
-#endif
+ ifmedia_init(&sc->sc_mii.mii_media, 0,
+ epic_ifmedia_upd, epic_ifmedia_sts);
+ sc->sc_mii.mii_ifp = ifp;
+ sc->sc_mii.mii_readreg = epic_miibus_readreg;
+ sc->sc_mii.mii_writereg = epic_miibus_writereg;
+ sc->sc_mii.mii_statchg = epic_miibus_statchg;
+ mii_phy_probe(self, &sc->sc_mii, 0xffffffff);
+ if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
+ ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE,0,NULL);
+ ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE);
+ } else
+ ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
/* Attach os interface and bpf */
if_attach(ifp);
ether_ifattach(ifp);
-#if NBPF > 0
+#if NBPFILTER > 0
bpfattach(&sc->sc_if.if_bpf, ifp, DLT_EN10MB,
sizeof(struct ether_header));
#endif
/* Set shutdown routine to stop DMA process */
- shutdownhook_establish(epic_shutdown, sc);
+ shutdownhook_establish(epic_openbsd_shutdown, sc);
printf("\n");
}
/* Simple call epic_stop() */
-static void
-epic_shutdown(
+void
+epic_openbsd_shutdown(
void *sc)
{
epic_stop(sc);
@@ -375,62 +327,108 @@ epic_shutdown(
#else /* __FreeBSD__ */
/* -----------------------------FreeBSD------------------------------------- */
-static const char* epic_freebsd_probe __P((pcici_t, pcidi_t));
-static void epic_freebsd_attach __P((pcici_t, int));
-static void epic_shutdown __P((void *, int));
-
-/* Global variables */
-static u_long epic_pci_count;
-static struct pci_device txdevice = {
- "tx",
- epic_freebsd_probe,
- epic_freebsd_attach,
- &epic_pci_count,
- NULL
+static int epic_freebsd_probe __P((device_t));
+static int epic_freebsd_attach __P((device_t));
+static void epic_freebsd_shutdown __P((device_t));
+static int epic_freebsd_detach __P((device_t));
+static struct epic_type *epic_devtype __P((device_t));
+
+static device_method_t epic_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, epic_freebsd_probe),
+ DEVMETHOD(device_attach, epic_freebsd_attach),
+ DEVMETHOD(device_detach, epic_freebsd_detach),
+ DEVMETHOD(device_shutdown, epic_freebsd_shutdown),
+
+ /* bus interface */
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+ DEVMETHOD(bus_driver_added, bus_generic_driver_added),
+
+ /* MII interface */
+ DEVMETHOD(miibus_readreg, epic_miibus_readreg),
+ DEVMETHOD(miibus_writereg, epic_miibus_writereg),
+ DEVMETHOD(miibus_statchg, epic_miibus_statchg),
+
+ { 0, 0 }
+};
+
+static driver_t epic_driver = {
+ "tx",
+ epic_methods,
+ sizeof(epic_softc_t)
};
-/* Append this driver to pci drivers list */
-COMPAT_PCI_DRIVER (tx, txdevice);
+static devclass_t epic_devclass;
+
+DRIVER_MODULE(if_tx, pci, epic_driver, epic_devclass, 0, 0);
+DRIVER_MODULE(miibus, tx, miibus_driver, miibus_devclass, 0, 0);
+
+static struct epic_type epic_devs[] = {
+ { SMC_VENDORID, SMC_DEVICEID_83C170,
+ "SMC EtherPower II 10/100BaseTX" },
+ { 0, 0, NULL }
+};
-/* Synopsis: Check if device id corresponds with SMC83C170 id. */
-static const char*
-epic_freebsd_probe(
- pcici_t config_id,
- pcidi_t device_id)
+static int
+epic_freebsd_probe(dev)
+ device_t dev;
{
- if( PCI_VENDORID(device_id) != SMC_VENDORID )
- return NULL;
+ struct epic_type *t;
+
+ t = epic_devtype(dev);
- if( PCI_CHIPID(device_id) == CHIPID_83C170 )
- return "SMC 83c170";
+ if (t != NULL) {
+ device_set_desc(dev, t->name);
+ return(0);
+ }
- return NULL;
+ return(ENXIO);
}
+static struct epic_type *
+epic_devtype(dev)
+ device_t dev;
+{
+ struct epic_type *t;
+
+ t = epic_devs;
+
+ while(t->name != NULL) {
+ if ((pci_get_vendor(dev) == t->ven_id) &&
+ (pci_get_device(dev) == t->dev_id)) {
+ return(t);
+ }
+ t++;
+ }
+ return (NULL);
+}
+
+#if defined(EPIC_USEIOSPACE)
+#define EPIC_RES SYS_RES_IOPORT
+#define EPIC_RID PCIR_BASEIO
+#else
+#define EPIC_RES SYS_RES_MEMORY
+#define EPIC_RID PCIR_BASEMEM
+#endif
+
/*
* Do FreeBSD-specific attach routine, like map registers, alloc softc
* structure and etc.
*/
-static void
-epic_freebsd_attach(
- pcici_t config_id,
- int unit)
+static int
+epic_freebsd_attach(dev)
+ device_t dev;
{
struct ifnet *ifp;
epic_softc_t *sc;
-#if defined(EPIC_USEIOSPACE)
- u_int32_t iobase;
-#else
- caddr_t pmembase;
-#endif
u_int32_t command;
- int i,s,tmp;
+ int unit, error;
+ int i, s, rid, tmp;
- printf("tx%d",unit);
+ s = splimp ();
- /* Allocate memory for softc, hardware descriptors and frag lists */
- sc = (epic_softc_t *) malloc( sizeof(epic_softc_t), M_DEVBUF, M_NOWAIT);
- if (sc == NULL) return;
+ sc = device_get_softc(dev);
+ unit = device_get_unit(dev);
/* Preinitialize softc structure */
bzero(sc, sizeof(epic_softc_t));
@@ -443,62 +441,101 @@ epic_freebsd_attach(
ifp->if_softc = sc;
ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST;
ifp->if_ioctl = epic_ifioctl;
+ ifp->if_output = ether_output;
ifp->if_start = epic_ifstart;
ifp->if_watchdog = epic_ifwatchdog;
ifp->if_init = (if_init_f_t*)epic_init;
ifp->if_timer = 0;
- ifp->if_output = ether_output;
- ifp->if_snd.ifq_maxlen = TX_RING_SIZE;
+ ifp->if_baudrate = 10000000;
+ ifp->if_snd.ifq_maxlen = TX_RING_SIZE - 1;
+
+ /* Enable ports, memory and busmastering */
+ command = pci_read_config(dev, PCIR_COMMAND, 4);
+ command |= PCIM_CMD_PORTEN | PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN;
+ pci_write_config(dev, PCIR_COMMAND, command, 4);
+ command = pci_read_config(dev, PCIR_COMMAND, 4);
- /* Get iobase or membase */
#if defined(EPIC_USEIOSPACE)
- command = PCI_CONF_READ(PCI_CFCS);
- command |= PCI_CFCS_IOEN;
- PCI_CONF_WRITE(PCI_CFCS, command);
- command = PCI_CONF_READ(PCI_CFCS);
-
- if (!(command & PCI_CFCS_IOEN)) {
- printf(": failed to enable memory mapping!\n");
- free(sc, M_DEVBUF);
- return;
+ if (!(command & PCIM_CMD_PORTEN)) {
+ device_printf(dev, "failed to enable I/O mapping!\n");
+ error = ENXIO;
+ goto fail;
}
+#else
+ if (!(command & PCIM_CMD_MEMEN)) {
+ device_printf(dev, "failed to enable memory mapping!\n");
+ error = ENXIO;
+ goto fail;
+ }
+#endif
- if (!pci_map_port(config_id, PCI_CBIO,(u_short *) &(sc->iobase))) {
- printf(": cannot map port\n");
- free(sc, M_DEVBUF);
- return;
+ rid = EPIC_RID;
+ sc->res = bus_alloc_resource(dev, EPIC_RES, &rid, 0, ~0, 1,
+ RF_ACTIVE);
+
+ if (sc->res == NULL) {
+ device_printf(dev, "couldn't map ports/memory\n");
+ error = ENXIO;
+ goto fail;
}
-#else
- command = PCI_CONF_READ(PCI_CFCS);
- command |= PCI_CFCS_MAEN;
- PCI_CONF_WRITE(PCI_CFCS, command);
- command = PCI_CONF_READ(PCI_CFCS);
-
- if (!(command & PCI_CFCS_MAEN)) {
- printf(": failed to enable memory mapping!\n");
- free(sc, M_DEVBUF);
- return;
+
+ sc->sc_st = rman_get_bustag(sc->res);
+ sc->sc_sh = rman_get_bushandle(sc->res);
+
+ /* Allocate interrupt */
+ rid = 0;
+ sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
+ RF_SHAREABLE | RF_ACTIVE);
+
+ if (sc->irq == NULL) {
+ device_printf(dev, "couldn't map interrupt\n");
+ bus_release_resource(dev, EPIC_RES, EPIC_RID, sc->res);
+ error = ENXIO;
+ goto fail;
}
- if (!pci_map_mem(config_id, PCI_CBMA,(vm_offset_t *) &(sc->csr),(vm_offset_t *) &pmembase)) {
- printf(": cannot map memory\n");
- free(sc, M_DEVBUF);
- return;
+ error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET,
+ epic_intr, sc, &sc->sc_ih);
+
+ if (error) {
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
+ bus_release_resource(dev, EPIC_RES, EPIC_RID, sc->res);
+ device_printf(dev, "couldn't set up irq\n");
+ goto fail;
}
-#endif
- /* Do OS independent part, including chip wakeup and reset */
- if( epic_common_attach(sc) ) return;
+ /* Bring the chip out of low-power mode and reset it. */
+ CSR_WRITE_4( sc, GENCTL, GENCTL_SOFT_RESET );
+ DELAY(500);
+
+ /* Workaround for Application Note 7-15 */
+ for (i=0; i<16; i++) CSR_WRITE_4(sc, TEST1, TEST1_CLOCK_TEST);
+
+ /*
+ * Do ifmedia setup.
+ */
+ if (mii_phy_probe(dev, &sc->miibus,
+ epic_ifmedia_upd, epic_ifmedia_sts)) {
+ device_printf(dev, "MII without any PHY!?\n");
+ bus_teardown_intr(dev, sc->irq, sc->sc_ih);
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
+ bus_release_resource(dev, EPIC_RES, EPIC_RID, sc->res);
+ error = ENXIO;
+ goto fail;
+ }
- /* Enable BusMaster'ing */
- command = PCI_CONF_READ(PCI_CFCS);
- command |= PCI_CFCS_BMEN;
- PCI_CONF_WRITE(PCI_CFCS, command);
+ /* Do OS independent part, including chip wakeup and reset */
+ if (epic_common_attach(sc)) {
+ device_printf(dev, "memory distribution error\n");
+ bus_teardown_intr(dev, sc->irq, sc->sc_ih);
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
+ bus_release_resource(dev, EPIC_RES, EPIC_RID, sc->res);
+ error = ENXIO;
+ goto fail;
+ }
/* Display ethernet address ,... */
- printf(": address %02x:%02x:%02x:%02x:%02x:%02x,",
- sc->sc_macaddr[0],sc->sc_macaddr[1],sc->sc_macaddr[2],
- sc->sc_macaddr[3],sc->sc_macaddr[4],sc->sc_macaddr[5]);
+ device_printf(dev, "address %6D,", sc->sc_macaddr, ":");
/* board type and ... */
printf(" type ");
@@ -510,96 +547,75 @@ epic_freebsd_attach(
if( ' ' == (u_int8_t)tmp ) break;
printf("%c",(u_int8_t)tmp);
}
+ printf ("\n");
- /* Read current media config and display it too */
- i = PHY_READ_2( sc, DP83840_BMCR );
-#if !defined(EPIC_NOIFMEDIA)
- tmp = IFM_ETHER;
-#endif
- if( i & BMCR_AUTONEGOTIATION ){
- printf(", Auto-Neg ");
-
- /* To avoid bug in QS6612 read LPAR enstead of BMSR */
- i = PHY_READ_2( sc, DP83840_LPAR );
- if( i & (ANAR_100_TX|ANAR_100_TX_FD) ) printf("100Mbps ");
- else printf("10Mbps ");
- if( i & (ANAR_10_FD|ANAR_100_TX_FD) ) printf("FD");
-#if !defined(EPIC_NOIFMEDIA)
- tmp |= IFM_AUTO;
-#endif
- } else {
-#if defined(EPIC_NOIFMEDIA)
- ifp->if_flags |= IFF_LINK0;
-#endif
- if( i & BMCR_100MBPS ) {
- printf(", 100Mbps ");
-#if !defined(EPIC_NOIFMEDIA)
- tmp |= IFM_100_TX;
-#else
- ifp->if_flags |= IFF_LINK2;
-#endif
- } else {
- printf(", 10Mbps ");
-#if !defined(EPIC_NOIFMEDIA)
- tmp |= IFM_10_T;
-#endif
- }
- if( i & BMCR_FULL_DUPLEX ) {
- printf("FD");
-#if !defined(EPIC_NOIFMEDIA)
- tmp |= IFM_FDX;
-#else
- ifp->if_flags |= IFF_LINK1;
-#endif
- }
- }
+ /* Attach to OS's managers */
+ if_attach(ifp);
+ ether_ifattach(ifp);
+ callout_handle_init(&sc->stat_ch);
- /* Init ifmedia interface */
-#if !defined(EPIC_NOIFMEDIA)
- ifmedia_init(&sc->ifmedia,0,epic_ifmedia_change,epic_ifmedia_status);
+ bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
- for (i=0; i<EPIC_MTYPESNUM; i++)
- ifmedia_add(&sc->ifmedia,epic_mtypes[i],0,NULL);
+fail:
+ splx(s);
- ifmedia_set(&sc->ifmedia, tmp);
-#endif
+ return(error);
+}
+
+/*
+ * Detach driver and free resources
+ */
+static int
+epic_freebsd_detach(dev)
+ device_t dev;
+{
+ struct ifnet *ifp;
+ epic_softc_t *sc;
+ int s;
s = splimp();
- /* Map interrupt */
- if( !pci_map_int(config_id, epic_intr, (void*)sc, &net_imask) ) {
- printf(": couldn't map interrupt\n");
- free(sc, M_DEVBUF);
- return;
- }
+ sc = device_get_softc(dev);
+ ifp = &sc->arpcom.ac_if;
- /* Set shut down routine to stop DMA processes on reboot */
- EVENTHANDLER_REGISTER(shutdown_post_sync, epic_shutdown, sc,
- SHUTDOWN_PRI_DEFAULT);
+ bpfdetach(ifp);
+ if_detach(ifp);
- /* Attach to if manager */
- if_attach(ifp);
- ether_ifattach(ifp);
+ epic_stop(sc);
-#if NBPF > 0
- bpfattach(ifp,DLT_EN10MB, sizeof(struct ether_header));
-#endif
+ bus_generic_detach(dev);
+ device_delete_child(dev, sc->miibus);
- splx(s);
+ bus_teardown_intr(dev, sc->irq, sc->sc_ih);
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
+ bus_release_resource(dev, EPIC_RES, EPIC_RID, sc->res);
- printf("\n");
+ free(sc->pool, M_DEVBUF);
- return;
+ splx(s);
+
+ return(0);
}
+#undef EPIC_RES
+#undef EPIC_RID
+
+/*
+ * Stop all chip I/O so that the kernel's probe routines don't
+ * get confused by errant DMAs when rebooting.
+ */
static void
-epic_shutdown(
- void *sc,
- int howto)
+epic_freebsd_shutdown(dev)
+ device_t dev;
{
+ epic_softc_t *sc;
+
+ sc = device_get_softc(dev);
+
epic_stop(sc);
-}
+ return;
+}
#endif /* __OpenBSD__ */
/* ------------------------------------------------------------------------
@@ -610,12 +626,14 @@ epic_shutdown(
* This is if_ioctl handler.
*/
static int
-epic_ifioctl __P((
- register struct ifnet * ifp,
- EPIC_IFIOCTL_CMD_TYPE command,
- caddr_t data))
+epic_ifioctl(ifp, command, data)
+ struct ifnet *ifp;
+ u_long command;
+ caddr_t data;
{
epic_softc_t *sc = ifp->if_softc;
+ struct mii_data *mii;
+ struct ifreq *ifr = (struct ifreq *) data;
int x, error = 0;
x = splimp();
@@ -639,7 +657,7 @@ epic_ifioctl __P((
epic_init(sc);
arp_ifinit(&sc->arpcom,ifa);
break;
-#endif /* __FreeBSD__ */
+#endif
#if NS
case AF_NS: {
register struct ns_addr * ina = &IA_SNS(ifa)->sns_addr;
@@ -662,7 +680,7 @@ epic_ifioctl __P((
break;
}
}
-#endif
+#endif /* __FreeBSD__ */
case SIOCSIFFLAGS:
/*
@@ -681,15 +699,9 @@ epic_ifioctl __P((
}
}
- epic_stop_activity(sc);
-
/* Handle IFF_PROMISC flag */
+ epic_stop_activity(sc);
epic_set_rx_mode(sc);
-
-#if defined(EPIC_NOIFMEDIA)
- /* Handle IFF_LINKx flags */
- epic_set_media_speed(sc);
-#endif
epic_start_activity(sc);
break;
@@ -711,13 +723,11 @@ epic_ifioctl __P((
#endif
break;
-#if !defined(EPIC_NOIFMEDIA)
case SIOCSIFMEDIA:
case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, (struct ifreq *)data,
- &sc->ifmedia, command);
+ mii = device_get_softc(sc->miibus);
+ error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
break;
-#endif
default:
error = EINVAL;
@@ -733,8 +743,8 @@ epic_ifioctl __P((
* Return -1 on failure.
*/
static int
-epic_common_attach(
- epic_softc_t *sc)
+epic_common_attach(sc)
+ epic_softc_t *sc;
{
int i;
caddr_t pool;
@@ -761,8 +771,8 @@ epic_common_attach(
pool += sizeof(struct epic_rx_desc)*RX_RING_SIZE;
sc->tx_desc = (void *)pool;
- /* Bring the chip out of low-power mode and reset it. */
- CSR_WRITE_4( sc, GENCTL, GENCTL_SOFT_RESET );
+ /* Bring the chip out of low-power mode. */
+ CSR_WRITE_4( sc, GENCTL, GENCTL_SOFT_RESET);
/* Workaround for Application Note 7-15 */
for (i=0; i<16; i++) CSR_WRITE_4(sc, TEST1, TEST1_CLOCK_TEST);
@@ -771,12 +781,7 @@ epic_common_attach(
for (i = 0; i < ETHER_ADDR_LEN / sizeof(u_int16_t); i++)
((u_int16_t *)sc->sc_macaddr)[i] = epic_read_eeprom(sc,i);
- /* Identify PHY */
- sc->phyid = PHY_READ_2(sc, DP83840_PHYIDR1 )<<6;
- sc->phyid|= (PHY_READ_2( sc, DP83840_PHYIDR2 )>>10)&0x3F;
- if( QS6612_OUI != sc->phyid )
- printf(": WARNING! PHY unknown (0x%x)",sc->phyid);
-
+ /* Set defaults */
sc->tx_threshold = TRANSMIT_THRESHOLD;
sc->txcon = TXCON_DEFAULT;
@@ -789,7 +794,9 @@ epic_common_attach(
* or quque become empty.
*/
static void
-epic_ifstart(struct ifnet * const ifp){
+epic_ifstart(ifp)
+ struct ifnet * ifp;
+{
epic_softc_t *sc = ifp->if_softc;
struct epic_tx_buffer *buf;
struct epic_tx_desc *desc;
@@ -798,20 +805,6 @@ epic_ifstart(struct ifnet * const ifp){
register struct mbuf *m;
register int i;
-#if 0
- /* If no link is established, simply free all mbufs in queue */
- PHY_READ_2( sc, DP83840_BMSR );
- if( !(BMSR_LINK_STATUS & PHY_READ_2( sc, DP83840_BMSR )) ){
- IF_DEQUEUE( &ifp->if_snd, m0 );
- while( m0 ) {
- m_freem(m0);
- IF_DEQUEUE( &ifp->if_snd, m0 );
- }
- return;
- }
-#endif
-
- /* Link is OK, queue packets to NIC */
while( sc->pending_txs < TX_RING_SIZE ){
buf = sc->tx_buffer + sc->cur_tx;
desc = sc->tx_desc + sc->cur_tx;
@@ -823,17 +816,6 @@ epic_ifstart(struct ifnet * const ifp){
/* If nothing to send, return */
if( NULL == m0 ) return;
- /* If descriptor is busy, set IFF_OACTIVE and exit */
- if( desc->status & 0x8000 ) {
- dprintf((EPIC_FORMAT ": desc is busy in ifstart, up and down interface please\n",EPIC_ARGS(sc)));
- break;
- }
-
- if( buf->mbuf ) {
- dprintf((EPIC_FORMAT ": mbuf not freed in ifstart, up and down interface please\n",EPIC_ARGS(sc)));
- break;
- }
-
/* Fill fragments list */
for( m=m0, i=0;
(NULL != m) && (i < EPIC_MAX_FRAGS);
@@ -877,13 +859,9 @@ epic_ifstart(struct ifnet * const ifp){
/* Set watchdog timer */
ifp->if_timer = 8;
-#if NBPF > 0
+#if NBPFILTER > 0
if( ifp->if_bpf )
-#if defined(__FreeBSD__)
- bpf_mtap( ifp, m0 );
-#else /* __OpenBSD__ */
- bpf_mtap( ifp->if_bpf, m0 );
-#endif /* __FreeBSD__ */
+ bpf_mtap( EPIC_BPFTAP_ARG(ifp), m0 );
#endif
}
@@ -894,12 +872,11 @@ epic_ifstart(struct ifnet * const ifp){
}
/*
- *
- * splimp() invoked before epic_intr_normal()
+ * Synopsis: Finish all received frames.
*/
-static __inline void
-epic_rx_done __P((
- epic_softc_t *sc ))
+static void
+epic_rx_done(sc)
+ epic_softc_t *sc;
{
u_int16_t len;
struct epic_rx_buffer *buf;
@@ -947,15 +924,11 @@ epic_rx_done __P((
m->m_pkthdr.rcvif = &(sc->sc_if);
m->m_pkthdr.len = m->m_len = len;
-#if NBPF > 0
- /* Give mbuf to BPF */
+#if NBPFILTER > 0
+ /* Give mbuf to BPFILTER */
if( sc->sc_if.if_bpf )
-#if defined(__FreeBSD__)
- bpf_mtap( &sc->sc_if, m );
-#else /* __OpenBSD__ */
- bpf_mtap( sc->sc_if.if_bpf, m );
-#endif /* __FreeBSD__ */
-#endif /* NBPF */
+ bpf_mtap( EPIC_BPFTAP_ARG(&sc->sc_if), m );
+#endif /* NBPFILTER > 0 */
#ifdef BRIDGE
if (do_bridge) {
@@ -978,8 +951,7 @@ epic_rx_done __P((
}
#endif
-#if NBPF > 0
-#ifdef BRIDGE
+#if defined (__FreeBSD__)
/*
* This deserves explanation
* If the bridge is _on_, then the following check
@@ -989,11 +961,14 @@ epic_rx_done __P((
*
* But if the bridge is off, then we have to drop
* stuff that came in just via bpf.
+ *
+ * In OpenBSD such filter stands in ether_input. (?)
*/
- if (!do_bridge)
-#endif
/* Accept only our packets, broadcasts and multicasts */
- if( (eh->ether_dhost[0] & 1) == 0 &&
+#ifdef BRIDGE
+ if (do_bridge)
+#endif
+ if ((eh->ether_dhost[0] & 1) == 0 &&
bcmp(eh->ether_dhost,sc->sc_macaddr,ETHER_ADDR_LEN)){
m_freem(m);
continue;
@@ -1020,9 +995,9 @@ epic_rx_done __P((
* packet, switch to next descriptor and repeat until no packets
* are pending or descriptor is not transmitted yet.
*/
-static __inline void
-epic_tx_done __P((
- register epic_softc_t *sc ))
+static void
+epic_tx_done(sc)
+ epic_softc_t *sc;
{
struct epic_tx_buffer *buf;
struct epic_tx_desc *desc;
@@ -1060,12 +1035,10 @@ epic_tx_done __P((
/*
* Interrupt function
- *
- * splimp() assumed to be done
*/
static EPIC_INTR_RET_TYPE
-epic_intr (
- void *arg)
+epic_intr(arg)
+ void *arg;
{
epic_softc_t * sc = (epic_softc_t *) arg;
int status,i=4;
@@ -1073,7 +1046,6 @@ epic_intr (
int claimed = 0;
#endif
-
while( i-- && ((status = CSR_READ_4(sc, INTSTAT)) & INTSTAT_INT_ACTV) ){
#if defined(__OpenBSD__)
claimed = 1;
@@ -1088,8 +1060,6 @@ epic_intr (
printf(EPIC_FORMAT ": RX buffer overflow\n",EPIC_ARGS(sc));
if( status & INTSTAT_RQE )
printf(EPIC_FORMAT ": RX FIFO overflow\n",EPIC_ARGS(sc));
- if( sc->sc_if.if_flags & IFF_DEBUG )
- epic_dump_state(sc);
#endif
if( !(CSR_READ_4( sc, COMMAND ) & COMMAND_RXQUEUED) )
CSR_WRITE_4( sc, COMMAND, COMMAND_RXQUEUED );
@@ -1104,46 +1074,6 @@ epic_intr (
epic_ifstart( &sc->sc_if );
}
- if( (status & INTSTAT_GP2) && (QS6612_OUI == sc->phyid) ) {
- u_int32_t phystatus = PHY_READ_2( sc, QS6612_INTSTAT );
-
- if( phystatus & INTSTAT_AN_COMPLETE ) {
- u_int32_t bmcr;
- if( epic_autoneg(sc) == EPIC_FULL_DUPLEX ) {
- dprintf((EPIC_FORMAT ": going fullduplex\n",EPIC_ARGS(sc)));
- bmcr = BMCR_FULL_DUPLEX | PHY_READ_2( sc, DP83840_BMCR );
- sc->txcon |= TXCON_FULL_DUPLEX;
- } else {
- /* Default to half-duplex */
- dprintf((EPIC_FORMAT ": going halfduplex\n",EPIC_ARGS(sc)));
- bmcr = ~BMCR_FULL_DUPLEX & PHY_READ_2( sc, DP83840_BMCR );
- sc->txcon &= ~TXCON_FULL_DUPLEX;
- }
-
- /* There is apparently QS6612 chip bug: */
- /* BMCR_FULL_DUPLEX flag is not updated by */
- /* autonegotiation process, so update it by hands */
- /* so we can rely on it in epic_ifmedia_status() */
- PHY_WRITE_2( sc, DP83840_BMCR, bmcr );
-
- epic_stop_activity(sc);
- epic_set_tx_mode(sc);
- epic_start_activity(sc);
- }
-
- PHY_READ_2(sc, DP83840_BMSR);
- if( !(PHY_READ_2(sc, DP83840_BMSR) & BMSR_LINK_STATUS) ) {
- dprintf((EPIC_FORMAT ": WARNING! link down\n",EPIC_ARGS(sc)));
- sc->flags |= EPIC_LINK_DOWN;
- } else {
- dprintf((EPIC_FORMAT ": link up\n",EPIC_ARGS(sc)));
- sc->flags &= ~EPIC_LINK_DOWN;
- }
-
- /* We should clear GP2 int again after we clear it on PHY */
- CSR_WRITE_4( sc, INTSTAT, INTSTAT_GP2 );
- }
-
/* Check for errors */
if( status & (INTSTAT_FATAL|INTSTAT_PMA|INTSTAT_PTA|
INTSTAT_APE|INTSTAT_DPE|INTSTAT_TXU|INTSTAT_RXE) ){
@@ -1157,8 +1087,6 @@ epic_intr (
(status&INTSTAT_DPE)?" DPE":""
);
- epic_dump_state(sc);
-
epic_stop(sc);
epic_init(sc);
@@ -1202,12 +1130,10 @@ epic_intr (
* Synopsis: This one is called if packets wasn't transmitted
* during timeout. Try to deallocate transmitted packets, and
* if success continue to work.
- *
- * splimp() invoked here
*/
static void
-epic_ifwatchdog __P((
- struct ifnet *ifp))
+epic_ifwatchdog(ifp)
+ struct ifnet *ifp;
{
epic_softc_t *sc = ifp->if_softc;
int x;
@@ -1222,9 +1148,7 @@ epic_ifwatchdog __P((
/* If not successful */
if( sc->pending_txs > 0 ){
-#if defined(EPIC_DEBUG)
- if( ifp->if_flags & IFF_DEBUG ) epic_dump_state(sc);
-#endif
+
ifp->if_oerrors+=sc->pending_txs;
/* Reinitialize board */
@@ -1241,77 +1165,99 @@ epic_ifwatchdog __P((
splx(x);
}
-#if defined(SIOCSIFMEDIA) && !defined(EPIC_NOIFMEDIA)
+/*
+ * Set media options.
+ */
static int
-epic_ifmedia_change __P((
- struct ifnet * ifp))
+epic_ifmedia_upd(ifp)
+ struct ifnet *ifp;
{
- epic_softc_t *sc = (epic_softc_t *)(ifp->if_softc);
+ epic_softc_t *sc;
+ struct mii_data *mii;
- if (IFM_TYPE(sc->ifmedia.ifm_media) != IFM_ETHER)
- return (EINVAL);
+ sc = ifp->if_softc;
+ mii = device_get_softc(sc->miibus);
+ mii_mediachg(mii);
- if (!(ifp->if_flags & IFF_UP))
- return (0);
+ return(0);
+}
- epic_stop_activity(sc);
- epic_set_media_speed(sc);
- epic_start_activity(sc);
+/*
+ * Report current media status.
+ */
+static void
+epic_ifmedia_sts(ifp, ifmr)
+ struct ifnet *ifp;
+ struct ifmediareq *ifmr;
+{
+ epic_softc_t *sc;
+ struct mii_data *mii;
+
+ sc = ifp->if_softc;
+ mii = device_get_softc(sc->miibus);
+ if (ifp->if_flags & IFF_UP) {
+ mii_pollstat(mii);
+ ifmr->ifm_active = mii->mii_media_active;
+ ifmr->ifm_status = mii->mii_media_status;
+ } else {
+ ifmr->ifm_active = IFM_NONE;
+ ifmr->ifm_status = 0;
+ }
- return 0;
+ return;
}
+/*
+ * Callback routine, called on media change.
+ */
static void
-epic_ifmedia_status __P((
- struct ifnet * ifp,
- struct ifmediareq *ifmr))
+epic_miibus_statchg(dev)
+ device_t dev;
{
- epic_softc_t *sc = ifp->if_softc;
- u_int32_t bmcr;
- u_int32_t bmsr;
-
- if (!(ifp->if_flags & IFF_UP))
- return;
+ epic_softc_t *sc;
+ struct mii_data *mii;
- bmcr = PHY_READ_2( sc, DP83840_BMCR );
+ sc = device_get_softc(dev);
+ mii = device_get_softc(sc->miibus);
- PHY_READ_2( sc, DP83840_BMSR );
- bmsr = PHY_READ_2( sc, DP83840_BMSR );
+ sc->txcon &= ~(TXCON_LOOPBACK_MODE | TXCON_FULL_DUPLEX);
- ifmr->ifm_active = IFM_ETHER;
- ifmr->ifm_status = IFM_AVALID;
+ /*
+ * If we are in full-duplex mode or loopback operation,
+ * we need to decouple receiver and transmitter.
+ */
+ if (mii->mii_media_active & (IFM_FDX | IFM_LOOP))
+ sc->txcon |= TXCON_FULL_DUPLEX;
- if( !(bmsr & BMSR_LINK_STATUS) ) {
- ifmr->ifm_active |=
- (bmcr&BMCR_AUTONEGOTIATION)?IFM_AUTO:IFM_NONE;
- return;
- }
+ if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX)
+ sc->sc_if.if_baudrate = 100000000;
+ else
+ sc->sc_if.if_baudrate = 10000000;
- ifmr->ifm_status |= IFM_ACTIVE;
- ifmr->ifm_active |= (bmcr & BMCR_100MBPS) ? IFM_100_TX : IFM_10_T;
- ifmr->ifm_active |= (bmcr & BMCR_FULL_DUPLEX) ? IFM_FDX : 0;
- if ((sc->txcon & TXCON_LOOPBACK_MODE) == TXCON_LOOPBACK_MODE_INT)
- ifmr->ifm_active |= (IFM_LOOP | IFM_FLAG1);
- else if ((sc->txcon & TXCON_LOOPBACK_MODE) == TXCON_LOOPBACK_MODE_PHY)
- ifmr->ifm_active |= IFM_LOOP;
+ epic_set_tx_mode(sc);
+ return;
}
-#endif
/*
- * Reset chip, PHY, allocate rings
- *
- * splimp() invoked here
+ * Reset chip, allocate rings, and call miibus mediachg.
*/
-static int
-epic_init __P((
- epic_softc_t * sc))
+static int
+epic_init(sc)
+ epic_softc_t *sc;
{
struct ifnet *ifp = &sc->sc_if;
+ struct mii_data *mii;
int s,i;
s = splimp();
+ /* If interface is already running, then we need not do anything */
+ if (ifp->if_flags & IFF_RUNNING) {
+ splx(s);
+ return 0;
+ }
+
/* Soft reset the chip (we have to power up card before) */
CSR_WRITE_4( sc, GENCTL, 0 );
CSR_WRITE_4( sc, GENCTL, GENCTL_SOFT_RESET );
@@ -1357,17 +1303,13 @@ epic_init __P((
CSR_WRITE_4( sc, INTMASK,
INTSTAT_RCC | INTSTAT_RQE | INTSTAT_OVW | INTSTAT_RXE |
INTSTAT_TXC | INTSTAT_TCC | INTSTAT_TQE | INTSTAT_TXU |
- INTSTAT_FATAL |
- ((QS6612_OUI == sc->phyid)?INTSTAT_GP2:0) );
+ INTSTAT_FATAL);
/* Enable interrupts, set for PCI read multiple and etc */
CSR_WRITE_4( sc, GENCTL,
GENCTL_ENABLE_INTERRUPT | GENCTL_MEMORY_READ_MULTIPLE |
GENCTL_ONECOPY | GENCTL_RECEIVE_FIFO_THRESHOLD64 );
- /* Set media speed mode */
- epic_set_media_speed( sc );
-
/* Mark interface running ... */
if( ifp->if_flags & IFF_UP ) ifp->if_flags |= IFF_RUNNING;
else ifp->if_flags &= ~IFF_RUNNING;
@@ -1378,7 +1320,21 @@ epic_init __P((
/* Start Rx process */
epic_start_activity(sc);
+ /* Reset all PHYs */
+ mii = device_get_softc(sc->miibus);
+ if (mii->mii_instance) {
+ struct mii_softc *miisc;
+ for (miisc = LIST_FIRST(&mii->mii_phys); miisc != NULL;
+ miisc = LIST_NEXT(miisc, mii_list))
+ mii_phy_reset(miisc);
+ }
+
+ /* Fetch info from MII */
+ mii_mediachg(mii);
+ mii_pollstat(mii);
+
splx(s);
+
return 0;
}
@@ -1387,264 +1343,31 @@ epic_init __P((
* access RXCON.
*/
static void
-epic_set_rx_mode(
- epic_softc_t * sc)
+epic_set_rx_mode(sc)
+ epic_softc_t *sc;
{
- u_int32_t flags = sc->sc_if.if_flags;
- u_int32_t rxcon = RXCON_DEFAULT | RXCON_RECEIVE_MULTICAST_FRAMES | RXCON_RECEIVE_BROADCAST_FRAMES;
+ u_int32_t flags = sc->sc_if.if_flags;
+ u_int32_t rxcon = RXCON_DEFAULT;
- rxcon |= (flags & IFF_PROMISC)?RXCON_PROMISCUOUS_MODE:0;
+ rxcon |= (flags & IFF_PROMISC) ? RXCON_PROMISCUOUS_MODE : 0;
CSR_WRITE_4( sc, RXCON, rxcon );
return;
}
-#if 0
-void
-dump_phy_regs(epic_softc_t *sc)
-{
-
- printf("BMCR: 0x%04x\n", PHY_READ_2(sc, DP83840_BMCR));
- printf("BMSR: 0x%04x\n", PHY_READ_2(sc, DP83840_BMSR));
- printf("ANAR: 0x%04x\n", PHY_READ_2(sc, DP83840_ANAR));
- printf("LPAR: 0x%04x\n", PHY_READ_2(sc, DP83840_LPAR));
- printf("ANER: 0x%04x\n", PHY_READ_2(sc, DP83840_ANER));
- printf("MCTL: 0x%04x\n", PHY_READ_2(sc, QS6612_MCTL));
- printf("INTSTAT: 0x%04x\n", PHY_READ_2(sc, QS6612_INTSTAT));
- printf("INTMASK: 0x%04x\n", PHY_READ_2(sc, QS6612_INTMASK));
- printf("BPCR: 0x%04x\n", PHY_READ_2(sc, QS6612_BPCR));
-}
-#endif
-
/*
- * Synopsis: Reset PHY and do PHY-special initialization:
+ * Synopsis: Set transmit control register. Chip must be in idle state to
+ * access TXCON.
*/
static void
-epic_init_phy __P((
- epic_softc_t * sc))
-{
- u_int32_t i;
-
- /* Reset PHY (We have to take the delay from manual XXX) */
- PHY_WRITE_2(sc, DP83840_BMCR, BMCR_RESET);
- DELAY(10);
- for(i=0;i<0x1000;i++) {
- if( !(PHY_READ_2(sc, DP83840_BMCR) & BMCR_RESET) )
- break;
- DELAY(1);
- }
-
- if( PHY_READ_2(sc, DP83840_BMCR) & BMCR_RESET )
- printf(EPIC_FORMAT ": WARNING! cant reset PHY\n",EPIC_ARGS(sc));
-
- PHY_WRITE_2(sc, DP83840_BMCR, 0 );
- PHY_WRITE_2(sc, DP83840_BMCR, BMCR_LOOPBACK | BMCR_ISOLATE );
-
- switch( sc->phyid ){
- case QS6612_OUI: {
- /* Init QS6612 and EPIC to generate interrupt */
- CSR_WRITE_4(sc, NVCTL, NVCTL_GP1_OUTPUT_ENABLE | NVCTL_GP1);
-
- /* Mask interrupts sources */
- PHY_WRITE_2(sc, QS6612_INTMASK,
- PHY_READ_2(sc, QS6612_INTSTAT) |
- INTMASK_THUNDERLAN | INTSTAT_AN_COMPLETE |
- INTSTAT_LINK_STATUS );
-
- /* Enable QS6612 extended cable length capabilites */
- /* PHY_WRITE_2(sc, QS6612_MCTL, */
- /* PHY_READ_2(sc, QS6612_MCTL) | MCTL_BTEXT); */
-
- break;
- }
- default:
- break;
- }
-}
-
-/*
- * Synopsis: Set PHY to media type specified by IFF_LINK* flags or
- * ifmedia structure. Chip must be in idle state to access TXCON.
- */
-static void
-epic_set_media_speed __P((
- epic_softc_t * sc))
-{
- u_int16_t media;
-#if !defined(EPIC_NOIFMEDIA)
- u_int32_t tgtmedia = sc->ifmedia.ifm_cur->ifm_media;
-#endif
-
- epic_init_phy(sc);
-
-#if !defined(EPIC_NOIFMEDIA)
- if( IFM_SUBTYPE(tgtmedia) != IFM_AUTO ){
- /* Clean previous values */
- sc->txcon &= ~(TXCON_LOOPBACK_MODE | TXCON_FULL_DUPLEX);
- media = 0;
-
- /* Set mode */
- media |= (IFM_SUBTYPE(tgtmedia)==IFM_100_TX) ? BMCR_100MBPS : 0;
- if (tgtmedia & IFM_FDX) {
- media |= BMCR_FULL_DUPLEX;
- sc->txcon |= TXCON_FULL_DUPLEX;
- }
- if (tgtmedia & IFM_LOOP) {
- if (tgtmedia & IFM_FLAG1)
- sc->txcon |= TXCON_LOOPBACK_MODE_INT;
- else {
- media |= BMCR_LOOPBACK | BMCR_ISOLATE;
- sc->txcon |= TXCON_LOOPBACK_MODE_PHY;
- }
- }
-
- sc->sc_if.if_baudrate =
- (IFM_SUBTYPE(tgtmedia)==IFM_100_TX)?100000000:10000000;
-
- PHY_WRITE_2( sc, DP83840_BMCR, media );
- }
-#else /* EPIC_NOIFMEDIA */
- struct ifnet *ifp = &sc->sc_if;
-
- if( ifp->if_flags & IFF_LINK0 ) {
- /* Set mode */
- media = 0;
- media|= (ifp->if_flags & IFF_LINK2) ? BMCR_100MBPS : 0;
- media|= (ifp->if_flags & IFF_LINK1) ? BMCR_FULL_DUPLEX : 0;
-
- sc->sc_if.if_baudrate =
- (ifp->if_flags & IFF_LINK2)?100000000:10000000;
-
- PHY_WRITE_2( sc, DP83840_BMCR, media );
-
- if( ifp->if_flags & IFF_LINK2 ) sc->txcon |= TXCON_FULL_DUPLEX;
- else sc->txcon &= ~TXCON_FULL_DUPLEX;
-
- CSR_WRITE_4( sc, TXCON, sc->txcon );
- }
-#endif /* !EPIC_NOIFMEDIA */
- else {
- sc->sc_if.if_baudrate = 100000000;
-
- sc->txcon &= ~TXCON_FULL_DUPLEX;
- CSR_WRITE_4(sc, TXCON, sc->txcon);
-
- /* Set and restart autoneg */
- PHY_WRITE_2(sc, DP83840_BMCR, BMCR_AUTONEGOTIATION );
- PHY_WRITE_2(sc, DP83840_BMCR,
- BMCR_AUTONEGOTIATION | BMCR_RESTART_AUTONEG);
-
- /* If it is not QS6612 PHY, try to get result of autoneg. */
- if( QS6612_OUI != sc->phyid ) {
- /* Wait 3 seconds for the autoneg to finish
- * This is the recommended time from the DP83840A data
- * sheet Section 7.1
- */
- DELAY(3000000);
-
- if( epic_autoneg(sc) == EPIC_FULL_DUPLEX ) {
- sc->txcon |= TXCON_FULL_DUPLEX;
- CSR_WRITE_4(sc, TXCON, sc->txcon);
- }
- }
- /* Else it will be done when GP2 int occured */
- }
-
- epic_set_tx_mode(sc);
-
- return;
-}
-
-/*
- * This functions get results of the autoneg processes of the phy
- * It implements the workaround that is described in section 7.2 & 7.3 of the
- * DP83840A data sheet
- * http://www.national.com/ds/DP/DP83840A.pdf
- */
-static int
-epic_autoneg(
- epic_softc_t * sc)
-{
- u_int16_t media;
- u_int16_t i;
-
- /* BMSR must be read twice to update the link status bit
- * since that bit is a latch bit
- */
- PHY_READ_2( sc, DP83840_BMSR);
- i = PHY_READ_2( sc, DP83840_BMSR);
-
- if ((i & BMSR_LINK_STATUS) && (i & BMSR_AUTONEG_COMPLETE)){
- i = PHY_READ_2( sc, DP83840_LPAR );
-
- if ( i & (ANAR_100_TX_FD|ANAR_10_FD) )
- return EPIC_FULL_DUPLEX;
- else
- return EPIC_HALF_DUPLEX;
- } else {
- /*Auto-negotiation or link status is not 1
- Thus the auto-negotiation failed and one
- must take other means to fix it.
- */
-
- /* ANER must be read twice to get the correct reading for the
- * Multiple link fault bit -- it is a latched bit
- */
- PHY_READ_2( sc, DP83840_ANER );
- i = PHY_READ_2( sc, DP83840_ANER );
-
- if ( i & ANER_MULTIPLE_LINK_FAULT ) {
- /* it can be forced to 100Mb/s Half-Duplex */
- media = PHY_READ_2( sc, DP83840_BMCR );
- media &= ~(BMCR_AUTONEGOTIATION | BMCR_FULL_DUPLEX);
- media |= BMCR_100MBPS;
- PHY_WRITE_2( sc, DP83840_BMCR, media );
-
- /* read BMSR again to determine link status */
- PHY_READ_2( sc, DP83840_BMSR );
- i=PHY_READ_2( sc, DP83840_BMSR );
-
- if (i & BMSR_LINK_STATUS){
- /* port is linked to the non Auto-Negotiation
- * 100Mbs partner.
- */
- return EPIC_HALF_DUPLEX;
- }
- else {
- media = PHY_READ_2( sc, DP83840_BMCR);
- media &= ~(BMCR_AUTONEGOTIATION | BMCR_FULL_DUPLEX | BMCR_100MBPS);
- PHY_WRITE_2( sc, DP83840_BMCR, media);
- PHY_READ_2( sc, DP83840_BMSR );
- i = PHY_READ_2( sc, DP83840_BMSR );
-
- if (i & BMSR_LINK_STATUS) {
- /*port is linked to the non
- * Auto-Negotiation10Mbs partner
- */
- return EPIC_HALF_DUPLEX;
- }
- }
- }
- /* If we get here we are most likely not connected
- * so lets default it to half duplex
- */
- return EPIC_HALF_DUPLEX;
- }
-
-}
-
-/*
- */
-static void
-epic_set_tx_mode (
- epic_softc_t *sc )
+epic_set_tx_mode(sc)
+ epic_softc_t *sc;
{
+ if (sc->txcon & TXCON_EARLY_TRANSMIT_ENABLE)
+ CSR_WRITE_4 (sc, ETXTHR, sc->tx_threshold);
- if( sc->txcon & TXCON_EARLY_TRANSMIT_ENABLE )
- CSR_WRITE_4( sc, ETXTHR, sc->tx_threshold );
-
- CSR_WRITE_4( sc, TXCON, sc->txcon );
+ CSR_WRITE_4 (sc, TXCON, sc->txcon);
}
/*
@@ -1656,8 +1379,8 @@ epic_set_tx_mode (
* epic_start_activity() should help to do this.
*/
static void
-epic_set_mc_table (
- epic_softc_t * sc)
+epic_set_mc_table(sc)
+ epic_softc_t *sc;
{
struct ifnet *ifp = &sc->sc_if;
@@ -1676,14 +1399,14 @@ epic_set_mc_table (
* Synopsis: Start receive process and transmit one, if they need.
*/
static void
-epic_start_activity __P((
- epic_softc_t * sc))
+epic_start_activity(sc)
+ epic_softc_t *sc;
{
- /* Start rx process */
- CSR_WRITE_4(sc, COMMAND,
- COMMAND_RXQUEUED | COMMAND_START_RX |
- (sc->pending_txs?COMMAND_TXQUEUED:0));
- dprintf((EPIC_FORMAT ": activity started\n",EPIC_ARGS(sc)));
+ /* Start rx process */
+ CSR_WRITE_4(sc, COMMAND,
+ COMMAND_RXQUEUED | COMMAND_START_RX |
+ (sc->pending_txs?COMMAND_TXQUEUED:0));
+ dprintf((EPIC_FORMAT ": activity started\n",EPIC_ARGS(sc)));
}
/*
@@ -1691,8 +1414,8 @@ epic_start_activity __P((
* packet needs to be queued to stop Tx DMA.
*/
static void
-epic_stop_activity __P((
- epic_softc_t * sc))
+epic_stop_activity(sc)
+ epic_softc_t *sc;
{
int i;
@@ -1784,12 +1507,10 @@ epic_stop_activity __P((
/*
* Synopsis: Shut down board and deallocates rings.
- *
- * splimp() invoked here
*/
static void
-epic_stop __P((
- epic_softc_t * sc))
+epic_stop(sc)
+ epic_softc_t *sc;
{
int s;
@@ -1825,8 +1546,8 @@ epic_stop __P((
* Synopsis: This function should free all memory allocated for rings.
*/
static void
-epic_free_rings __P((
- epic_softc_t * sc))
+epic_free_rings(sc)
+ epic_softc_t *sc;
{
int i;
@@ -1861,7 +1582,9 @@ epic_free_rings __P((
* are bounded and aligned properly.
*/
static int
-epic_init_rings(epic_softc_t * sc){
+epic_init_rings(sc)
+ epic_softc_t *sc;
+{
int i;
sc->cur_rx = sc->cur_tx = sc->dirty_tx = sc->pending_txs = 0;
@@ -1910,9 +1633,10 @@ epic_init_rings(epic_softc_t * sc){
/*
* EEPROM operation functions
*/
-static void epic_write_eepromreg __P((
- epic_softc_t *sc,
- u_int8_t val))
+static void
+epic_write_eepromreg(sc, val)
+ epic_softc_t *sc;
+ u_int8_t val;
{
u_int16_t i;
@@ -1925,16 +1649,16 @@ static void epic_write_eepromreg __P((
}
static u_int8_t
-epic_read_eepromreg __P((
- epic_softc_t *sc))
+epic_read_eepromreg(sc)
+ epic_softc_t *sc;
{
- return CSR_READ_1( sc,EECTL );
+ return CSR_READ_1(sc, EECTL);
}
static u_int8_t
-epic_eeprom_clock __P((
- epic_softc_t *sc,
- u_int8_t val))
+epic_eeprom_clock(sc, val)
+ epic_softc_t *sc;
+ u_int8_t val;
{
epic_write_eepromreg( sc, val );
epic_write_eepromreg( sc, (val | 0x4) );
@@ -1944,9 +1668,9 @@ epic_eeprom_clock __P((
}
static void
-epic_output_eepromw __P((
- epic_softc_t * sc,
- u_int16_t val))
+epic_output_eepromw(sc, val)
+ epic_softc_t *sc;
+ u_int16_t val;
{
int i;
for( i = 0xF; i >= 0; i--){
@@ -1956,8 +1680,8 @@ epic_output_eepromw __P((
}
static u_int16_t
-epic_input_eepromw __P((
- epic_softc_t *sc))
+epic_input_eepromw(sc)
+ epic_softc_t *sc;
{
int i;
int tmp;
@@ -1973,9 +1697,9 @@ epic_input_eepromw __P((
}
static int
-epic_read_eeprom __P((
- epic_softc_t *sc,
- u_int16_t loc))
+epic_read_eeprom(sc, loc)
+ epic_softc_t *sc;
+ u_int16_t loc;
{
u_int16_t dataval;
u_int16_t read_cmd;
@@ -1996,74 +1720,66 @@ epic_read_eeprom __P((
return dataval;
}
-static u_int16_t
-epic_read_phy_register __P((
- epic_softc_t *sc,
- u_int16_t loc))
+/*
+ * Here goes MII read/write routines
+ */
+static int
+epic_read_phy_reg(sc, phy, reg)
+ epic_softc_t *sc;
+ int phy, reg;
{
int i;
- CSR_WRITE_4( sc, MIICTL, ((loc << 4) | 0x0601) );
+ CSR_WRITE_4 (sc, MIICTL, ((reg << 4) | (phy << 9) | 0x01));
for (i=0;i<0x100;i++) {
- if( !(CSR_READ_4( sc, MIICTL )&1) ) break;
+ if( !(CSR_READ_4(sc, MIICTL) & 0x01) ) break;
DELAY(1);
}
- return CSR_READ_4( sc, MIIDATA );
+ return (CSR_READ_4 (sc, MIIDATA));
}
static void
-epic_write_phy_register __P((
- epic_softc_t * sc,
- u_int16_t loc,
- u_int16_t val))
+epic_write_phy_reg(sc, phy, reg, val)
+ epic_softc_t *sc;
+ int phy, reg, val;
{
int i;
- CSR_WRITE_4( sc, MIIDATA, val );
- CSR_WRITE_4( sc, MIICTL, ((loc << 4) | 0x0602) );
+ CSR_WRITE_4 (sc, MIIDATA, val);
+ CSR_WRITE_4 (sc, MIICTL, ((reg << 4) | (phy << 9) | 0x02));
- for( i=0;i<0x100;i++) {
- if( !(CSR_READ_4( sc, MIICTL )&2) ) break;
+ for(i=0;i<0x100;i++) {
+ if( !(CSR_READ_4(sc, MIICTL) & 0x02) ) break;
DELAY(1);
}
return;
}
-static void
-epic_dump_state __P((
- epic_softc_t * sc))
+static int
+epic_miibus_readreg(dev, phy, reg)
+ device_t dev;
+ int phy, reg;
{
- int j;
- struct epic_tx_desc *tdesc;
- struct epic_rx_desc *rdesc;
- printf(EPIC_FORMAT ": cur_rx: %d, pending_txs: %d, dirty_tx: %d, cur_tx: %d\n", EPIC_ARGS(sc),sc->cur_rx,sc->pending_txs,sc->dirty_tx,sc->cur_tx);
- printf(EPIC_FORMAT ": COMMAND: 0x%08x, INTSTAT: 0x%08x\n",EPIC_ARGS(sc),CSR_READ_4(sc,COMMAND),CSR_READ_4(sc,INTSTAT));
- printf(EPIC_FORMAT ": PRCDAR: 0x%08x, PTCDAR: 0x%08x\n",EPIC_ARGS(sc),CSR_READ_4(sc,PRCDAR),CSR_READ_4(sc,PTCDAR));
- printf(EPIC_FORMAT ": dumping rx descriptors\n",EPIC_ARGS(sc));
- for(j=0;j<RX_RING_SIZE;j++){
- rdesc = sc->rx_desc + j;
- printf("desc%d: %4d 0x%04x, 0x%08x, %4d, 0x%08x\n",
- j,
- rdesc->rxlength,rdesc->status,
- rdesc->bufaddr,
- rdesc->buflength,
- rdesc->next
- );
- }
- printf(EPIC_FORMAT ": dumping tx descriptors\n",EPIC_ARGS(sc));
- for(j=0;j<TX_RING_SIZE;j++){
- tdesc = sc->tx_desc + j;
- printf(
- "desc%d: %4d 0x%04x, 0x%08lx, 0x%04x %4u, 0x%08lx, mbuf: %p\n",
- j,
- tdesc->txlength,tdesc->status,
- (u_long)tdesc->bufaddr,
- tdesc->control,tdesc->buflength,
- (u_long)tdesc->next,
- (void *)sc->tx_buffer[j].mbuf
- );
- }
+ epic_softc_t *sc;
+
+ sc = device_get_softc(dev);
+
+ return (PHY_READ_2(sc, phy, reg));
+}
+
+static int
+epic_miibus_writereg(dev, phy, reg, data)
+ device_t dev;
+ int phy, reg, data;
+{
+ epic_softc_t *sc;
+
+ sc = device_get_softc(dev);
+
+ PHY_WRITE_2(sc, phy, reg, data);
+
+ return (0);
}
diff --git a/sys/pci/if_txvar.h b/sys/pci/if_txvar.h
index 49a3941..35685af 100644
--- a/sys/pci/if_txvar.h
+++ b/sys/pci/if_txvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_txvar.h,v 1.3 1998/10/10 04:30:09 jason Exp $ */
+/* $OpenBSD: if_txvar.h,v 1.7 1999/11/17 05:21:19 jason Exp $ */
/* $FreeBSD$ */
/*-
@@ -25,13 +25,15 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- *
*/
/*
* Configuration
*/
+/*#define EPIC_DEBUG 1*/
+/*#define EPIC_USEIOSPACE 1*/
+#define EARLY_RX 1
+
#ifndef ETHER_MAX_LEN
#define ETHER_MAX_LEN 1518
#endif
@@ -46,33 +48,20 @@
/* confuse RX(TX)_RING_MASK */
#define TX_RING_MASK (TX_RING_SIZE - 1)
#define RX_RING_MASK (RX_RING_SIZE - 1)
-#define EPIC_FULL_DUPLEX 1
-#define EPIC_HALF_DUPLEX 0
#define ETHER_MAX_FRAME_LEN (ETHER_MAX_LEN + ETHER_CRC_LEN)
-#define EPIC_LINK_DOWN 0x00000001
+
+/* PCI aux configuration registers */
+#if defined(__FreeBSD__)
+#define PCIR_BASEIO (PCIR_MAPS + 0x0) /* Base IO Address */
+#define PCIR_BASEMEM (PCIR_MAPS + 0x4) /* Base Memory Address */
+#else /* __OpenBSD__ */
+#define PCI_BASEIO (PCI_MAPS + 0x0) /* Base IO Address */
+#define PCI_BASEMEM (PCI_MAPS + 0x4) /* Base Memory Address */
+#endif /* __FreeBSD__ */
/* PCI identification */
#define SMC_VENDORID 0x10B8
-#define CHIPID_83C170 0x0005
-#define PCI_VENDORID(x) ((x) & 0xFFFF)
-#define PCI_CHIPID(x) (((x) >> 16) & 0xFFFF)
-
-/* PCI configuration */
-#define PCI_CFID 0x00 /* Configuration ID */
-#define PCI_CFCS 0x04 /* Configurtion Command/Status */
-#define PCI_CFRV 0x08 /* Configuration Revision */
-#define PCI_CFLT 0x0c /* Configuration Latency Timer */
-#define PCI_CBIO 0x10 /* Configuration Base IO Address */
-#define PCI_CBMA 0x14 /* Configuration Base Memory Address */
-#define PCI_CFIT 0x3c /* Configuration Interrupt */
-#define PCI_CFDA 0x40 /* Configuration Driver Area */
-
-#define PCI_CFCS_IOEN 0x0001 /* IO Sapce Enable */
-#define PCI_CFCS_MAEN 0x0002 /* Memory Space Enable */
-#define PCI_CFCS_BMEN 0x0004 /* Bus Master Enable */
-
-#define PCI_CONF_WRITE(r, v) pci_conf_write(config_id, (r), (v))
-#define PCI_CONF_READ(r) pci_conf_read(config_id, (r))
+#define SMC_DEVICEID_83C170 0x0005
/* EPIC's registers */
#define COMMAND 0x0000
@@ -115,9 +104,6 @@
#define COMMAND_STOP_RDMA 0x40
#define COMMAND_TXUGO 0x80
-/* Tx threshold */
-#define TX_FIFO_THRESH 0x80 /* 0x40 or 0x10 */
-
/* Interrupt register bits */
#define INTSTAT_RCC 0x00000001
#define INTSTAT_HCC 0x00000002
@@ -200,80 +186,22 @@
#define TEST1_CLOCK_TEST 0x00000008
+/*
+ * Some default values
+ */
#define TXCON_DEFAULT (TXCON_SLOT_TIME | TXCON_EARLY_TRANSMIT_ENABLE)
-#define TRANSMIT_THRESHOLD 0x80
+#define TRANSMIT_THRESHOLD 0x300
#if defined(EARLY_RX)
- #define RXCON_DEFAULT (RXCON_EARLY_RECEIVE_ENABLE | RXCON_SAVE_ERRORED_PACKETS)
+#define RXCON_EARLY (RXCON_EARLY_RECEIVE_ENABLE | \
+ RXCON_SAVE_ERRORED_PACKETS)
#else
- #define RXCON_DEFAULT (0)
+#define RXCON_EARLY (0)
#endif
-/*
- * National Semiconductor's DP83840A Registers and bits
- */
-#define DP83840_OUI 0x080017
-#define DP83840_BMCR 0x00 /* Control register */
-#define DP83840_BMSR 0x01 /* Status rgister */
-#define DP83840_ANAR 0x04 /* Autonegotiation advertising register */
-#define DP83840_LPAR 0x05 /* Link Partner Ability register */
-#define DP83840_ANER 0x06 /* Auto-Negotiation Expansion Register */
-#define DP83840_PAR 0x19 /* PHY Address Register */
-#define DP83840_PHYIDR1 0x02
-#define DP83840_PHYIDR2 0x03
-
-#define BMCR_RESET 0x8000
-#define BMCR_LOOPBACK 0x4000
-#define BMCR_100MBPS 0x2000 /* 10/100 Mbps */
-#define BMCR_AUTONEGOTIATION 0x1000 /* ON/OFF */
-#define BMCR_POWERDOWN 0x0800
-#define BMCR_ISOLATE 0x0400
-#define BMCR_RESTART_AUTONEG 0x0200
-#define BMCR_FULL_DUPLEX 0x0100
-#define BMCR_COL_TEST 0x0080
-
-#define BMSR_100BASE_T4 0x8000
-#define BMSR_100BASE_TX_FD 0x4000
-#define BMSR_100BASE_TX 0x2000
-#define BMSR_10BASE_T_FD 0x1000
-#define BMSR_10BASE_T 0x0800
-#define BMSR_AUTONEG_COMPLETE 0x0020
-#define BMSR_AUTONEG_ABLE 0x0008
-#define BMSR_LINK_STATUS 0x0004
-
-#define PAR_FULL_DUPLEX 0x0400
-
-#define ANER_MULTIPLE_LINK_FAULT 0x10
-
-/* ANAR and LPAR have the same bits, define them only once */
-#define ANAR_10 0x0020
-#define ANAR_10_FD 0x0040
-#define ANAR_100_TX 0x0080
-#define ANAR_100_TX_FD 0x0100
-#define ANAR_100_T4 0x0200
-/*
- * Quality Semiconductor's QS6612 registers and bits
- */
-#define QS6612_OUI 0x006051
-#define QS6612_MCTL 17
-#define QS6612_INTSTAT 29
-#define QS6612_INTMASK 30
-#define QS6612_BPCR 31
-
-#define MCTL_T4_PRESENT 0x1000 /* External T4 Enabled, ignored */
- /* if AutoNeg is enabled */
-#define MCTL_BTEXT 0x0800 /* Reduces 10baset squelch level */
- /* for extended cable length */
-
-#define INTSTAT_AN_COMPLETE 0x40 /* Autonegotiation complete */
-#define INTSTAT_RF_DETECTED 0x20 /* Remote Fault detected */
-#define INTSTAT_LINK_STATUS 0x10 /* Link status changed */
-#define INTSTAT_AN_LP_ACK 0x08 /* Autoneg. LP Acknoledge */
-#define INTSTAT_PD_FAULT 0x04 /* Parallel Detection Fault */
-#define INTSTAT_AN_PAGE 0x04 /* Autoneg. Page Received */
-#define INTSTAT_RE_CNT_FULL 0x01 /* Receive Error Counter Full */
-
-#define INTMASK_THUNDERLAN 0x8000 /* Enable interrupts */
+#define RXCON_DEFAULT (RXCON_EARLY | \
+ RXCON_RECEIVE_MULTICAST_FRAMES | \
+ RXCON_RECEIVE_BROADCAST_FRAMES)
/*
* Structures definition and Functions prototypes
@@ -330,20 +258,20 @@ typedef struct {
struct arpcom arpcom;
#if defined(__OpenBSD__)
struct device sc_dev;
+ mii_data_t sc_mii;
+#else /* __FreeBSD__ */
+ struct resource *res;
+ struct resource *irq;
+
+ device_t miibus;
+ struct callout_handle stat_ch;
+
+ u_int32_t unit;
+#endif
void *sc_ih;
bus_space_tag_t sc_st;
bus_space_handle_t sc_sh;
-#else /* __FreeBSD__ */
-#if defined(EPIC_USEIOSPACE)
- u_int32_t iobase;
-#else
- caddr_t csr;
-#endif
-#endif
-#if !defined(EPIC_NOIFMEDIA)
- struct ifmedia ifmedia;
-#endif
- u_int32_t unit;
+
struct epic_rx_buffer rx_buffer[RX_RING_SIZE];
struct epic_tx_buffer tx_buffer[TX_RING_SIZE];
@@ -363,43 +291,31 @@ typedef struct {
void *pool;
} epic_softc_t;
+struct epic_type {
+ u_int16_t ven_id;
+ u_int16_t dev_id;
+ char *name;
+};
+
+#if defined(EPIC_DEBUG)
+#define dprintf(a) printf a
+#else
+#define dprintf(a)
+#endif
+
#if defined(__FreeBSD__)
#define EPIC_FORMAT "tx%d"
#define EPIC_ARGS(sc) (sc->unit)
-#define sc_if arpcom.ac_if
-#define sc_macaddr arpcom.ac_enaddr
-#if defined(EPIC_USEIOSPACE)
-#define CSR_WRITE_4(sc,reg,val) \
- outl( (sc)->iobase + (u_int32_t)(reg), (val) )
-#define CSR_WRITE_2(sc,reg,val) \
- outw( (sc)->iobase + (u_int32_t)(reg), (val) )
-#define CSR_WRITE_1(sc,reg,val) \
- outb( (sc)->iobase + (u_int32_t)(reg), (val) )
-#define CSR_READ_4(sc,reg) \
- inl( (sc)->iobase + (u_int32_t)(reg) )
-#define CSR_READ_2(sc,reg) \
- inw( (sc)->iobase + (u_int32_t)(reg) )
-#define CSR_READ_1(sc,reg) \
- inb( (sc)->iobase + (u_int32_t)(reg) )
-#else
-#define CSR_WRITE_1(sc,reg,val) \
- ((*(volatile u_int8_t*)((sc)->csr + (u_int32_t)(reg))) = (u_int8_t)(val))
-#define CSR_WRITE_2(sc,reg,val) \
- ((*(volatile u_int16_t*)((sc)->csr + (u_int32_t)(reg))) = (u_int16_t)(val))
-#define CSR_WRITE_4(sc,reg,val) \
- ((*(volatile u_int32_t*)((sc)->csr + (u_int32_t)(reg))) = (u_int32_t)(val))
-#define CSR_READ_1(sc,reg) \
- (*(volatile u_int8_t*)((sc)->csr + (u_int32_t)(reg)))
-#define CSR_READ_2(sc,reg) \
- (*(volatile u_int16_t*)((sc)->csr + (u_int32_t)(reg)))
-#define CSR_READ_4(sc,reg) \
- (*(volatile u_int32_t*)((sc)->csr + (u_int32_t)(reg)))
-#endif
+#define EPIC_BPFTAP_ARG(ifp) ifp
#else /* __OpenBSD__ */
#define EPIC_FORMAT "%s"
#define EPIC_ARGS(sc) (sc->sc_dev.dv_xname)
-#define sc_if arpcom.ac_if
+#define EPIC_BPFTAP_ARG(ifp) (ifp)->if_bpf
+#endif
+
+#define sc_if arpcom.ac_if
#define sc_macaddr arpcom.ac_enaddr
+
#define CSR_WRITE_4(sc,reg,val) \
bus_space_write_4( (sc)->sc_st, (sc)->sc_sh, (reg), (val) )
#define CSR_WRITE_2(sc,reg,val) \
@@ -412,8 +328,21 @@ typedef struct {
bus_space_read_2( (sc)->sc_st, (sc)->sc_sh, (reg) )
#define CSR_READ_1(sc,reg) \
bus_space_read_1( (sc)->sc_st, (sc)->sc_sh, (reg) )
-#endif
-#define PHY_READ_2(sc,reg) epic_read_phy_register(sc,reg)
-#define PHY_WRITE_2(sc,reg,val) epic_write_phy_register(sc,reg,val)
+#define PHY_READ_2(sc,phy,reg) \
+ epic_read_phy_reg((sc),(phy),(reg))
+#define PHY_WRITE_2(sc,phy,reg,val) \
+ epic_write_phy_reg((sc),(phy),(reg),(val))
+
+/* Macro to get either mbuf cluster or nothing */
+#define EPIC_MGETCLUSTER(m) \
+ { MGETHDR((m),M_DONTWAIT,MT_DATA); \
+ if (m) { \
+ MCLGET((m),M_DONTWAIT); \
+ if( 0 == ((m)->m_flags & M_EXT) ) { \
+ m_freem(m); \
+ (m) = NULL; \
+ } \
+ } \
+ }
OpenPOWER on IntegriCloud