diff options
author | imp <imp@FreeBSD.org> | 2005-02-12 16:44:15 +0000 |
---|---|---|
committer | imp <imp@FreeBSD.org> | 2005-02-12 16:44:15 +0000 |
commit | 0aa9858b9a0a82cbd590123df68bb3fec05140ec (patch) | |
tree | ab20973a96dc442ea5d5638d9f958df38821e0fd /sys | |
parent | 91f542fb50567910f3c13d9d4d2b3bbde0ec0634 (diff) | |
download | FreeBSD-src-0aa9858b9a0a82cbd590123df68bb3fec05140ec.zip FreeBSD-src-0aa9858b9a0a82cbd590123df68bb3fec05140ec.tar.gz |
Improve the mining of MAC address from the card:
o Add a fallback location for the MAC address. Most of the early ne2000
PC Cards were built from the same parts, so most of them have the same
address in the CIS to grab the MAC from. Use this address as our
fallback if we don't find anything better.
o Add printf, in bootverbose, noting the MAC addresses that we find along
the way.
# Better sanity checking of the MAC address is needed. Will have to
# investigate using/creating a centralized function to do this as a number
# of other PC Card drivers each have their own ad-hoc tests.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/ed/if_ed_pccard.c | 43 |
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); |