diff options
-rw-r--r-- | sys/dev/ep/if_ep.c | 62 | ||||
-rw-r--r-- | sys/dev/ep/if_ep_pccard.c | 45 | ||||
-rw-r--r-- | sys/dev/ep/if_epvar.h | 6 |
3 files changed, 68 insertions, 45 deletions
diff --git a/sys/dev/ep/if_ep.c b/sys/dev/ep/if_ep.c index ee1e946..39141b4 100644 --- a/sys/dev/ep/if_ep.c +++ b/sys/dev/ep/if_ep.c @@ -117,7 +117,7 @@ eeprom_rdy(struct ep_softc *sc) DELAY(100); if (i >= MAX_EEPROMBUSY) { - printf("ep%d: eeprom failed to come ready.\n", sc->unit); + device_printf(sc->dev, "eeprom failed to come ready.\n"); return (ENXIO); } @@ -146,7 +146,7 @@ ep_get_e(struct ep_softc *sc, uint16_t offset, uint16_t *result) return (0); } -int +static int ep_get_macaddr(struct ep_softc *sc, u_char *addr) { int i; @@ -163,7 +163,6 @@ ep_get_macaddr(struct ep_softc *sc, u_char *addr) return (error); macaddr[i] = htons(result); } - return (0); } @@ -191,7 +190,6 @@ ep_alloc(device_t dev) goto bad; } sc->dev = dev; - sc->unit = device_get_unit(dev); sc->stat = 0; /* 16 bit access */ sc->bst = rman_get_bustag(sc->iobase); @@ -201,7 +199,6 @@ ep_alloc(device_t dev) sc->ep_connector = 0; GO_WINDOW(sc, 0); - sc->epb.cmd_off = 0; error = ep_get_e(sc, EEPROM_PROD_ID, &result); if (error) @@ -258,32 +255,37 @@ ep_free(device_t dev) bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq); } +static void +ep_setup_station(struct ep_softc *sc, u_char *enaddr) +{ + int i; + + /* + * Setup the station address + */ + GO_WINDOW(sc, 2); + for (i = 0; i < ETHER_ADDR_LEN; i++) + CSR_WRITE_1(sc, EP_W2_ADDR_0 + i, enaddr[i]); +} + int ep_attach(struct ep_softc *sc) { struct ifnet *ifp = NULL; struct ifmedia *ifm = NULL; - u_char eaddr[6]; - u_short *p; - int i; int error; sc->gone = 0; EP_LOCK_INIT(sc); - error = ep_get_macaddr(sc, eaddr); - if (error) { - device_printf(sc->dev, "Unable to get Ethernet address!\n"); - EP_LOCK_DESTORY(sc); - return (ENXIO); + if (! (sc->stat & F_ENADDR_SKIP)) { + error = ep_get_macaddr(sc, sc->eaddr); + if (error) { + device_printf(sc->dev, "Unable to get MAC address!\n"); + EP_LOCK_DESTORY(sc); + return (ENXIO); + } } - /* - * Setup the station address - */ - p = (u_short *)eaddr; - GO_WINDOW(sc, 2); - for (i = 0; i < 3; i++) - CSR_WRITE_2(sc, EP_W2_ADDR_0 + (i * 2), ntohs(p[i])); - + ep_setup_station(sc, sc->eaddr); ifp = sc->ifp = if_alloc(IFT_ETHER); if (ifp == NULL) { device_printf(sc->dev, "can not if_alloc()\n"); @@ -324,7 +326,7 @@ ep_attach(struct ep_softc *sc) ifm->ifm_media = ifm->ifm_cur->ifm_media; ep_ifmedia_upd(ifp); } - ether_ifattach(ifp, eaddr); + ether_ifattach(ifp, sc->eaddr); #ifdef EP_LOCAL_STATS sc->rx_no_first = sc->rx_no_mbuf = sc->rx_bpf_disc = @@ -404,10 +406,8 @@ epinit_locked(struct ep_softc *sc) CSR_WRITE_2(sc, EP_W0_CONFIG_CTRL, ENABLE_DRQ_IRQ); GO_WINDOW(sc, 2); - /* Reload the ether_addr. */ - for (i = 0; i < 6; i++) - CSR_WRITE_1(sc, EP_W2_ADDR_0 + i, IFP2ENADDR(sc->ifp)[i]); + ep_setup_station(sc, IFP2ENADDR(sc->ifp)); CSR_WRITE_2(sc, EP_COMMAND, RX_RESET); CSR_WRITE_2(sc, EP_COMMAND, TX_RESET); @@ -453,12 +453,6 @@ epinit_locked(struct ep_softc *sc) CSR_WRITE_2(sc, EP_COMMAND, SET_RX_EARLY_THRESH | RX_INIT_EARLY_THRESH); CSR_WRITE_2(sc, EP_COMMAND, SET_TX_START_THRESH | 16); - /* - * Store up a bunch of mbuf's for use later. (MAX_MBS). - * First we free up any that we had in case we're being - * called from intr or somewhere else. - */ - GO_WINDOW(sc, 1); epstart_locked(ifp); } @@ -621,7 +615,7 @@ rescan: if (status & S_CARD_FAILURE) { ifp->if_timer = 0; #ifdef EP_LOCAL_STATS - printf("\nep%d:\n\tStatus: %x\n", sc->unit, status); + device_printf(sc->dev, "\n\tStatus: %x\n", status); GO_WINDOW(sc, 4); printf("\tFIFO Diagnostic: %x\n", CSR_READ_2(sc, EP_W4_FIFO_DIAG)); @@ -634,8 +628,8 @@ rescan: #else #ifdef DIAGNOSTIC - printf("ep%d: Status: %x (input buffer overflow)\n", - sc->unit, status); + device_printf(sc->dev, + "Status: %x (input buffer overflow)\n", status); #else ++ifp->if_ierrors; #endif diff --git a/sys/dev/ep/if_ep_pccard.c b/sys/dev/ep/if_ep_pccard.c index b3537e7..4707fc5 100644 --- a/sys/dev/ep/if_ep_pccard.c +++ b/sys/dev/ep/if_ep_pccard.c @@ -112,6 +112,28 @@ ep_pccard_probe(device_t dev) } static int +ep_pccard_mac(struct pccard_tuple *tuple, void *argp) +{ + uint8_t *enaddr = argp; + int i; + + /* Code 0x88 is 3com's special cis node contianing the MAC */ + if (tuple->code != 0x88) + return (0); + + /* Make sure this is a sane node */ + if (tuple->length < ETHER_ADDR_LEN) + return (0); + + /* Copy the MAC ADDR and return success */ + for (i = 0; i < ETHER_ADDR_LEN; i += 2) { + enaddr[i] = pccard_tuple_read_1(tuple, i + 1); + enaddr[i + 1] = pccard_tuple_read_1(tuple, i); + } + return (1); +} + +static int ep_pccard_attach(device_t dev) { struct ep_softc *sc = device_get_softc(dev); @@ -122,11 +144,6 @@ ep_pccard_attach(device_t dev) if ((pp = ep_pccard_lookup(dev)) == NULL) panic("ep_pccard_attach: can't find product in attach."); - if ((error = ep_alloc(dev))) { - device_printf(dev, "ep_alloc() failed! (%d)\n", error); - goto bad; - } - if (pp->chipset == EP_CHIP_589) { sc->epb.mii_trans = 0; sc->epb.cmd_off = 0; @@ -135,8 +152,10 @@ ep_pccard_attach(device_t dev) sc->epb.cmd_off = 2; } - error = ep_get_e(sc, EEPROM_PROD_ID, &result); - sc->epb.prod_id = result; + if ((error = ep_alloc(dev))) { + device_printf(dev, "ep_alloc() failed! (%d)\n", error); + goto bad; + } /* ROM size = 0, ROM base = 0 */ /* For now, ignore AUTO SELECT feature of 3C589B and later. */ @@ -168,6 +187,18 @@ ep_pccard_attach(device_t dev) } else ep_get_media(sc); + /* + * The 3C562 (a-c revisions) stores the MAC in the CIS in a + * way that's unique to 3com. If we have one of these cards, + * scan the CIS for that MAC address, and use it if we find + * it. The NetBSD driver says that the ROADRUNNER chips also + * do this, which may be true, but none of the cards that I + * have include this TUPLE. Always prefer the MAC addr in the + * CIS tuple to the one returned by the card, as it appears that + * only those cards that need it have this special tuple. + */ + if (CARD_CIS_SCAN(device_get_parent(dev), ep_pccard_mac, sc->eaddr)) + sc->stat |= F_ENADDR_SKIP; if ((error = ep_attach(sc))) { device_printf(dev, "ep_attach() failed! (%d)\n", error); goto bad; diff --git a/sys/dev/ep/if_epvar.h b/sys/dev/ep/if_epvar.h index 31ff786..3c3fc62 100644 --- a/sys/dev/ep/if_epvar.h +++ b/sys/dev/ep/if_epvar.h @@ -55,14 +55,13 @@ struct ep_softc { int stat; /* some flags */ #define F_RX_FIRST 0x001 +#define F_ENADDR_SKIP 0x002 #define F_PROMISC 0x008 #define F_ACCESS_32_BITS 0x100 int gone; /* adapter is not present (for PCCARD) */ - struct ep_board epb; - - int unit; + uint8_t eaddr[6]; #ifdef EP_LOCAL_STATS short tx_underrun; @@ -80,7 +79,6 @@ void ep_get_media(struct ep_softc *); int ep_attach(struct ep_softc *); void ep_intr(void *); int ep_get_e(struct ep_softc *, uint16_t, uint16_t *); -int ep_get_macaddr(struct ep_softc *, u_char *); #define CSR_READ_1(sc, off) (bus_space_read_1((sc)->bst, (sc)->bsh, off)) #define CSR_READ_2(sc, off) (bus_space_read_2((sc)->bst, (sc)->bsh, off)) |