summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/ep/if_ep.c62
-rw-r--r--sys/dev/ep/if_ep_pccard.c45
-rw-r--r--sys/dev/ep/if_epvar.h6
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))
OpenPOWER on IntegriCloud