/* * Initialize the device - called from Slot manager. */ static int ep_pccard_probe(device_t dev) { struct ep_softc * sc = device_get_softc(dev); struct ep_board * epb = &sc->epb; const char * desc; int error; error = ep_alloc(dev); if (error) return error; /* * 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. [email protected] 09/11/1999 */ epb->cmd_off = 0; epb->prod_id = get_e(sc, EEPROM_PROD_ID); if ((desc = ep_pccard_identify(epb->prod_id)) == NULL) { if (bootverbose) device_printf(dev, "Pass 1 of 2 detection " "failed (nonfatal)\n"); epb->cmd_off = 2; epb->prod_id = get_e(sc, EEPROM_PROD_ID); if ((desc = ep_pccard_identify(epb->prod_id)) == NULL) { device_printf(dev, "Unit failed to come ready or " "product ID unknown! (id 0x%x)\n", epb->prod_id); ep_free(dev); return (ENXIO); } } device_set_desc(dev, desc); /* * For some reason the 3c574 needs this. */ ep_get_macaddr(sc, (u_char *)&sc->arpcom.ac_enaddr); ep_free(dev); return (0); }
int ep_attach(struct ep_softc *sc) { struct ifnet * ifp = NULL; struct ifmedia * ifm = NULL; u_short * p; uint8_t ether_addr[ETHER_ADDR_LEN]; int i; sc->gone = 0; ep_get_macaddr(sc, ether_addr); /* * Setup the station address */ p = (u_short*)ether_addr; GO_WINDOW(2); for (i = 0; i < 3; i++) { outw(BASE + EP_W2_ADDR_0 + (i * 2), ntohs(p[i])); } ifp = &sc->arpcom.ac_if; ifp->if_softc = sc; ifp->if_mtu = ETHERMTU; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_start = ep_if_start; ifp->if_ioctl = ep_if_ioctl; ifp->if_watchdog = ep_if_watchdog; ifp->if_init = ep_if_init; ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN); ifq_set_ready(&ifp->if_snd); if (!sc->epb.mii_trans) { ifmedia_init(&sc->ifmedia, 0, ep_ifmedia_upd, ep_ifmedia_sts); if (sc->ep_connectors & AUI) ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_5, 0, NULL); if (sc->ep_connectors & UTP) ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T, 0, NULL); if (sc->ep_connectors & BNC) ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_2, 0, NULL); if (!sc->ep_connectors) ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_NONE, 0, NULL); ifmedia_set(&sc->ifmedia, IFM_ETHER|ep_media2if_media[sc->ep_connector]); ifm = &sc->ifmedia; ifm->ifm_media = ifm->ifm_cur->ifm_media; ep_ifmedia_upd(ifp); } ether_ifattach(ifp, ether_addr, NULL); #ifdef EP_LOCAL_STATS sc->rx_no_first = sc->rx_no_mbuf = sc->rx_bpf_disc = sc->rx_overrunf = sc->rx_overrunl = sc->tx_underrun = 0; #endif EP_FSET(sc, F_RX_FIRST); sc->top = sc->mcur = 0; return 0; }