summaryrefslogtreecommitdiffstats
path: root/sys/dev/ed/if_ed_pccard.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/ed/if_ed_pccard.c')
-rw-r--r--sys/dev/ed/if_ed_pccard.c43
1 files changed, 36 insertions, 7 deletions
diff --git a/sys/dev/ed/if_ed_pccard.c b/sys/dev/ed/if_ed_pccard.c
index 02e57fe..c2abc38 100644
--- a/sys/dev/ed/if_ed_pccard.c
+++ b/sys/dev/ed/if_ed_pccard.c
@@ -70,6 +70,16 @@ MODULE_DEPEND(ed, miibus, 1, 1, 1);
MODULE_DEPEND(ed, ether, 1, 1, 1);
/*
+ * PC Cards should be using a network specific FUNCE in the CIS to
+ * communicate their MAC address to the driver. However, there are a
+ * large number of NE-2000ish PC Cards that don't do this. Nearly all
+ * of them store the MAC address at a fixed offset into attribute
+ * memory, without any reference at all appearing in the CIS. And
+ * nearly all of those store it at the same location.
+ */
+#define ED_DEFAULT_MAC_OFFSET 0xff0
+
+/*
* PC-Card (PCMCIA) specific code.
*/
static int ed_pccard_match(device_t);
@@ -233,7 +243,7 @@ ed_pccard_attach(device_t dev)
int i;
struct ed_softc *sc = device_get_softc(dev);
u_char sum;
- u_char ether_addr[ETHER_ADDR_LEN];
+ u_char enaddr[ETHER_ADDR_LEN];
const struct ed_product *pp;
if ((pp = (const struct ed_product *) pccard_product_lookup(dev,
@@ -263,18 +273,37 @@ ed_pccard_attach(device_t dev)
* now.
*/
if (sc->chip_type == ED_CHIP_TYPE_DP8390) {
- pccard_get_ether(dev, ether_addr);
+ pccard_get_ether(dev, enaddr);
+ if (bootverbose)
+ device_printf(dev, "CIS MAC %6D\n", enaddr, ":");
for (i = 0, sum = 0; i < ETHER_ADDR_LEN; i++)
- sum |= ether_addr[i];
+ sum |= enaddr[i];
if (sum == 0 && pp->flags & NE2000DVF_ENADDR) {
for (i = 0; i < ETHER_ADDR_LEN; i++) {
ed_pccard_memread(dev, pp->enoff + i * 2,
- ether_addr + i);
- sum |= ether_addr[i];
+ enaddr + i);
+ sum |= enaddr[i];
}
+ if (bootverbose)
+ device_printf(dev, "Hint MAC %6D\n", enaddr,
+ ":");
+ }
+ if (sum == 0) {
+ for (i = 0; i < ETHER_ADDR_LEN; i++) {
+ ed_pccard_memread(dev, ED_DEFAULT_MAC_OFFSET +
+ i * 2, enaddr + i);
+ sum |= enaddr[i];
+ }
+ if (bootverbose)
+ device_printf(dev, "Fallback MAC %6D\n",
+ enaddr, ":");
+ }
+ if (sum == 0) {
+ device_printf(dev, "Cannot extract MAC address.\n");
+ ed_release_resources(dev);
+ return (ENXIO);
}
- if (sum)
- bcopy(ether_addr, sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
+ bcopy(enaddr, sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
}
error = ed_attach(dev);
OpenPOWER on IntegriCloud