Minor cleanup of ep driver and pccard attachment:

o Grab the MAC address out of the CIS if the card has the special
  3Com 0x88 tuple.  Most 3Com cards don't have this tuple, but we
  prefer it to the eeprom since it only appears to be present when
  the eeprom doesn't have the info.  So far, I've only observed this
  on my 3C362 and 3C362B cards, but the NetBSD driver implies that
  the 3C362C also has this tuple, and that some 3C574 cards do too (none
  of mine do).  ep_pccard_mac was written after looking at the NetBSD
  code.
o Store the enet addr in the softc for this device, so we can use the
  overridden MAC to set the station address.
o Create a routine to set the station address and use it where we need it.
o setup the cmd shitfs and such before we call ep_alloc(), and remove
  setting up the cmd shift value there.  It initializes to 0, and those
  attachments that need to frob it do so before calling ep_alloc.
o Remove some obsolete comments
o No longer a need to export ep_get_macaddr, so make it static
o ep_alloc already grabs the EEPROM id, so we don't need to grab it again
  in ep_pccard_attach.
o eliminate unit, it isn't needed, fix some printfs to be device_printf
  instead.

# All my pccards except the 3C1 work now.  Didn't test ISA or cbus cards
# that I have: 3C509B-TP or 3C569B-J-TPO

Tested on: 3C589B, 3C589C, 3C589D, 3C589D-TP, 3C562, 3C562B/3C563B,
	3C562D/3C563D, 3CCFE574BT, 3CXEM556, 3CCSH572BT, 3C574-TX,
	3CCE589EC, 3CXE589EC, 3CCFEM556, 3C1
Approved by: re (scottl)
This commit is contained in:
Warner Losh 2005-07-01 04:23:32 +00:00
parent 8fd99e38e0
commit 880266e041
3 changed files with 68 additions and 45 deletions

View File

@ -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 @@ ep_intr(void *arg)
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 @@ ep_intr(void *arg)
#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

View File

@ -111,6 +111,28 @@ ep_pccard_probe(device_t dev)
return 0;
}
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)
{
@ -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;

View File

@ -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))