From owner-freebsd-current Thu Sep 16 9:10:52 1999 Delivered-To: freebsd-current@freebsd.org Received: from users.anet-stl.com (users.anet-stl.com [209.145.150.20]) by hub.freebsd.org (Postfix) with ESMTP id 0328714E1C for ; Thu, 16 Sep 1999 09:10:43 -0700 (PDT) (envelope-from doogie@anet-stl.com) Received: from earth.anet-stl.com (earth.anet-stl.com [209.83.128.12]) by users.anet-stl.com (8.9.3/8.8.5) with SMTP id LAA36589 for ; Thu, 16 Sep 1999 11:10:42 -0500 (CDT) Date: Thu, 16 Sep 1999 11:10:41 -0500 (CDT) From: Jason Young To: current@freebsd.org Subject: 3Com Megahertz 574B patches Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG Here is a patch that gets my 3Com Megahertz 574B ethernet PC-card working. I'd submit it as a PR, but I'm not at all sure I'm doing the right thing to detect it. The gist of the patch: 1) Reworked the probe routine to avoid having to set a flag to find my card, mostly on account of I couldn't figure out how to set the flag. This is the "I'm probably doing this wrong" part. 2) Addition of the 574B's product ID. 3) Output of some more useful info when booting verbosely. Jason Young accessUS Chief Network Engineer *** /home/doogie/if_ep.c Tue Sep 14 11:22:12 1999 --- if_ep.c Tue Sep 14 11:29:13 1999 *************** *** 162,171 **** --- 162,172 ---- */ 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); /* * Initialize the device - called from Slot manager. *************** *** 189,232 **** } /* 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); } epb->res_cfg = get_e(sc, EEPROM_RESOURCE_CFG); ! for (i = 0; i < 3; i++) sc->epb->eth_addr[i] = get_e(sc, EEPROM_NODE_ADDR_0 + i); if (ep_pccard_attach(devi) == 0) return (ENXIO); sc->arpcom.ac_if.if_snd.ifq_maxlen = ifqmaxlen; return (0); } static int ep_pccard_attach(devi) struct pccard_devinfo *devi; { struct isa_device *is = &devi->isahd; struct ep_softc *sc = ep_softc[is->id_unit]; --- 190,265 ---- } /* get_e() requires these. */ sc->ep_io_addr = is->id_iobase; sc->unit = is->id_unit; epb->epb_addr = is->id_iobase; epb->epb_used = 1; ! /* ! * 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); ! for (i = 0; i < 3; i++) sc->epb->eth_addr[i] = get_e(sc, EEPROM_NODE_ADDR_0 + i); if (ep_pccard_attach(devi) == 0) return (ENXIO); sc->arpcom.ac_if.if_snd.ifq_maxlen = ifqmaxlen; return (0); } 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; { struct isa_device *is = &devi->isahd; struct ep_softc *sc = ep_softc[is->id_unit]; *************** *** 239,249 **** } if (config & IS_UTP) { sc->ep_connectors |= UTP; } if (!(sc->ep_connectors & 7)) ! 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 */ /* For now, ignore AUTO SELECT feature of 3C589B and later. */ outw(BASE + EP_W0_ADDRESS_CFG, get_e(sc, EEPROM_ADDR_CFG) & 0xc000); --- 272,284 ---- } if (config & IS_UTP) { sc->ep_connectors |= UTP; } if (!(sc->ep_connectors & 7)) ! /* (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 */ /* For now, ignore AUTO SELECT feature of 3C589B and later. */ outw(BASE + EP_W0_ADDRESS_CFG, get_e(sc, EEPROM_ADDR_CFG) & 0xc000); *************** *** 253,263 **** outw(BASE + EP_W0_PRODUCT_ID, sc->epb->prod_id); if (sc->epb->mii_trans) { /* ! * turn on the MII tranceiver */ GO_WINDOW(3); outw(BASE + EP_W3_OPTIONS, 0x8040); DELAY(1000); outw(BASE + EP_W3_OPTIONS, 0xc040); --- 288,298 ---- outw(BASE + EP_W0_PRODUCT_ID, sc->epb->prod_id); if (sc->epb->mii_trans) { /* ! * turn on the MII transciever */ GO_WINDOW(3); outw(BASE + EP_W3_OPTIONS, 0x8040); DELAY(1000); outw(BASE + EP_W3_OPTIONS, 0xc040); To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message