summaryrefslogtreecommitdiffstats
path: root/sys/i386/isa/if_ep.c
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>1999-09-19 06:20:23 +0000
committerobrien <obrien@FreeBSD.org>1999-09-19 06:20:23 +0000
commit9e003228b65115ddf59cf0d8ac934fbc2c771d09 (patch)
treef4bb6ea31dd34321ca8959bb53200d77e6ce4f25 /sys/i386/isa/if_ep.c
parent166e2f82f79baaf5fe1490987e977eb9a01b9fa0 (diff)
downloadFreeBSD-src-9e003228b65115ddf59cf0d8ac934fbc2c771d09.zip
FreeBSD-src-9e003228b65115ddf59cf0d8ac934fbc2c771d09.tar.gz
This adds support for the 3Com Megahertz 574B ethernet 16-bit PC-Card.
1) Reworked the probe routine 2) Addition of the 574B's product ID. 3) Added useful info when booting verbosely. Submitted by: Jason Young <doogie@anet-stl.com>
Diffstat (limited to 'sys/i386/isa/if_ep.c')
-rw-r--r--sys/i386/isa/if_ep.c73
1 files changed, 54 insertions, 19 deletions
diff --git a/sys/i386/isa/if_ep.c b/sys/i386/isa/if_ep.c
index a4027a6..dd64447 100644
--- a/sys/i386/isa/if_ep.c
+++ b/sys/i386/isa/if_ep.c
@@ -155,6 +155,7 @@ static int ep_pccard_init __P((struct pccard_devinfo *));
static int ep_pccard_attach __P((struct pccard_devinfo *));
static void ep_unload __P((struct pccard_devinfo *));
static int card_intr __P((struct pccard_devinfo *));
+static int ep_pccard_identify (struct ep_board *epb, int unit);
PCCARD_MODULE(ep, ep_pccard_init, ep_unload, card_intr, 0, net_imask);
@@ -182,26 +183,27 @@ ep_pccard_init(devi)
/* get_e() requires these. */
sc->ep_io_addr = is->id_iobase;
sc->unit = is->id_unit;
- epb->cmd_off = 0;
- if (is->id_flags & EP_FLAGS_100TX)
- epb->cmd_off = 2;
-
epb->epb_addr = is->id_iobase;
epb->epb_used = 1;
- epb->prod_id = get_e(sc, EEPROM_PROD_ID);
- epb->mii_trans = 0;
- /* product id */
- switch (epb->prod_id) {
- case 0x6055: /* 3C556 */
- case 0x4057: /* 3C574 */
- epb->mii_trans = 1;
- break;
- case 0x9058: /* 3C589 */
- break;
- default:
- printf("ep%d: failed to come ready.\n", is->id_unit);
- return (ENXIO);
+ /*
+ * XXX - Certain (newer?) 3Com cards need epb->cmd_off == 2. Sadly,
+ * you need to have a correct cmd_off in order to identify the card.
+ * So we have to hit it with both and cross our virtual fingers. There's
+ * got to be a better way to do this. jyoung@accessus.net 09/11/1999
+ */
+
+ epb->cmd_off = 0;
+ epb->prod_id = get_e(sc, EEPROM_PROD_ID);
+ if (bootverbose) printf("ep%d: Pass 1 of 2 detection failed (nonfatal)\n", is->id_unit);
+ if (!ep_pccard_identify(epb, is->id_unit)) {
+ epb->cmd_off = 2;
+ epb->prod_id = get_e(sc, EEPROM_PROD_ID);
+ if (!ep_pccard_identify(epb, is->id_unit)) {
+ if (bootverbose) printf("ep%d: Pass 2 of 2 detection failed (fatal!)\n", is->id_unit);
+ printf("ep%d: Unit failed to come ready or product ID unknown! (id 0x%x)\n", is->id_unit, epb->prod_id);
+ return (ENXIO);
+ }
}
epb->res_cfg = get_e(sc, EEPROM_RESOURCE_CFG);
@@ -216,6 +218,37 @@ ep_pccard_init(devi)
}
static int
+ep_pccard_identify(epb, unit)
+ struct ep_board *epb;
+ int unit;
+{
+ /* Determine device type and associated MII capabilities */
+ switch (epb->prod_id) {
+ case 0x6055: /* 3C556 */
+ if (bootverbose) printf("ep%d: 3Com 3C556\n", unit);
+ epb->mii_trans = 1;
+ return (1);
+ break; /* NOTREACHED */
+ case 0x4057: /* 3C574 */
+ if (bootverbose) printf("ep%d: 3Com 3C574\n", unit);
+ epb->mii_trans = 1;
+ return (1);
+ break; /* NOTREACHED */
+ case 0x4b57: /* 3C574B */
+ if (bootverbose) printf("ep%d: 3Com 3C574B, Megahertz 3CCFE574BT or Fast Etherlink 3C574-TX\n", unit);
+ epb->mii_trans = 1;
+ return (1);
+ break; /* NOTREACHED */
+ case 0x9058: /* 3C589 */
+ if (bootverbose) printf("ep%d: 3Com Etherlink III 3C589[B/C/D]\n", unit);
+ epb->mii_trans = 0;
+ return (1);
+ break; /* NOTREACHED */
+ }
+ return (0);
+}
+
+static int
ep_pccard_attach(devi)
struct pccard_devinfo *devi;
{
@@ -232,7 +265,9 @@ ep_pccard_attach(devi)
sc->ep_connectors |= UTP;
}
if (!(sc->ep_connectors & 7))
- printf("ep%d: No connectors or MII.\n", is->id_unit);
+ /* (Apparently) non-fatal */
+ if(bootverbose) printf("ep%d: No connectors or MII.\n", is->id_unit);
+
sc->ep_connector = inw(BASE + EP_W0_ADDRESS_CFG) >> ACF_CONNECTOR_BITS;
/* ROM size = 0, ROM base = 0 */
@@ -246,7 +281,7 @@ ep_pccard_attach(devi)
if (sc->epb->mii_trans) {
/*
- * turn on the MII tranceiver
+ * turn on the MII transciever
*/
GO_WINDOW(3);
outw(BASE + EP_W3_OPTIONS, 0x8040);
OpenPOWER on IntegriCloud