From owner-svn-src-projects@FreeBSD.ORG Tue Jan 13 09:09:41 2015 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id AD98AF8B; Tue, 13 Jan 2015 09:09:41 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 98F71DC6; Tue, 13 Jan 2015 09:09:41 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t0D99fi5077976; Tue, 13 Jan 2015 09:09:41 GMT (envelope-from glebius@FreeBSD.org) Received: (from glebius@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t0D99fMq077974; Tue, 13 Jan 2015 09:09:41 GMT (envelope-from glebius@FreeBSD.org) Message-Id: <201501130909.t0D99fMq077974@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: glebius set sender to glebius@FreeBSD.org using -f From: Gleb Smirnoff Date: Tue, 13 Jan 2015 09:09:41 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r277124 - projects/ifnet/sys/dev/xl X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 13 Jan 2015 09:09:41 -0000 Author: glebius Date: Tue Jan 13 09:09:40 2015 New Revision: 277124 URL: https://svnweb.freebsd.org/changeset/base/277124 Log: Convert xl(4) to opaque ifnet API. Committed via: xl0 Sponsored by: Nginx, Inc. Modified: projects/ifnet/sys/dev/xl/if_xl.c projects/ifnet/sys/dev/xl/if_xlreg.h Modified: projects/ifnet/sys/dev/xl/if_xl.c ============================================================================== --- projects/ifnet/sys/dev/xl/if_xl.c Tue Jan 13 09:05:49 2015 (r277123) +++ projects/ifnet/sys/dev/xl/if_xl.c Tue Jan 13 09:09:40 2015 (r277124) @@ -108,19 +108,16 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include #include #include #include -#include -#include #include #include #include -#include - -#include #include #include @@ -237,10 +234,10 @@ static void xl_txeof(struct xl_softc *); static void xl_txeof_90xB(struct xl_softc *); static void xl_txeoc(struct xl_softc *); static void xl_intr(void *); -static void xl_start(struct ifnet *); -static void xl_start_locked(struct ifnet *); -static void xl_start_90xB_locked(struct ifnet *); -static int xl_ioctl(struct ifnet *, u_long, caddr_t); +static int xl_transmit(if_t, struct mbuf *); +static void xl_start_locked(struct xl_softc *); +static void xl_start_90xB_locked(struct xl_softc *); +static int xl_ioctl(if_t, u_long, caddr_t); static void xl_init(void *); static void xl_init_locked(struct xl_softc *); static void xl_stop(struct xl_softc *); @@ -251,12 +248,12 @@ static int xl_resume(device_t); static void xl_setwol(struct xl_softc *); #ifdef DEVICE_POLLING -static int xl_poll(struct ifnet *ifp, enum poll_cmd cmd, int count); -static int xl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count); +static int xl_poll(if_t, enum poll_cmd cmd, int count); +static int xl_poll_locked(if_t, enum poll_cmd cmd, int count); #endif -static int xl_ifmedia_upd(struct ifnet *); -static void xl_ifmedia_sts(struct ifnet *, struct ifmediareq *); +static int xl_ifmedia_upd(if_t); +static void xl_ifmedia_sts(if_t, struct ifmediareq *); static int xl_eeprom_wait(struct xl_softc *); static int xl_read_eeprom(struct xl_softc *, caddr_t, int, int, int); @@ -282,6 +279,7 @@ static void xl_testpacket(struct xl_soft static int xl_miibus_readreg(device_t, int, int); static int xl_miibus_writereg(device_t, int, int, int); static void xl_miibus_statchg(device_t); +static void xl_miibus_linkchg(device_t); static void xl_miibus_mediainit(device_t); /* @@ -315,6 +313,7 @@ static device_method_t xl_methods[] = { DEVMETHOD(miibus_readreg, xl_miibus_readreg), DEVMETHOD(miibus_writereg, xl_miibus_writereg), DEVMETHOD(miibus_statchg, xl_miibus_statchg), + DEVMETHOD(miibus_linkchg, xl_miibus_linkchg), DEVMETHOD(miibus_mediainit, xl_miibus_mediainit), DEVMETHOD_END @@ -332,6 +331,18 @@ DRIVER_MODULE_ORDERED(xl, pci, xl_driver SI_ORDER_ANY); DRIVER_MODULE(miibus, xl, miibus_driver, miibus_devclass, NULL, NULL); +static struct ifdriver xl_ifdrv = { + .ifdrv_ops = { + .ifop_origin = IFOP_ORIGIN_DRIVER, + .ifop_ioctl = xl_ioctl, + .ifop_transmit = xl_transmit, + .ifop_init = xl_init, + }, + .ifdrv_name = "xl", + .ifdrv_type = IFT_ETHER, + .ifdrv_maxqlen = XL_TX_LIST_CNT - 1, +}; + static void xl_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error) { @@ -466,6 +477,25 @@ xl_miibus_statchg(device_t dev) macctl &= ~XL_MACCTRL_FLOW_CONTROL_ENB; } CSR_WRITE_1(sc, XL_W3_MAC_CTRL, macctl); + if (sc->xl_ifp != NULL) + if_set(sc->xl_ifp, IF_BAUDRATE, + ifmedia_baudrate(mii->mii_media_active)); +} + +static void +xl_miibus_linkchg(device_t dev) +{ + struct xl_softc *sc; + struct mii_data *mii; + if_t ifp; + + sc = device_get_softc(dev); + mii = device_get_softc(sc->xl_miibus); + ifp = sc->xl_ifp; + + if (ifp != NULL) + if_link_state_change(ifp, + ifmedia_link_state(mii->mii_media_status)); } /* @@ -602,15 +632,25 @@ xl_rxfilter(struct xl_softc *sc) * is to enable reception of all multicast frames. */ static void +xl_check_maddr_90x(void *arg, struct sockaddr *maddr) +{ + struct sockaddr *sa = (struct sockaddr *)maddr; + uint8_t *rxfilt = arg; + + if (sa->sa_family == AF_LINK) + *rxfilt |= XL_RXFILTER_ALLMULTI; +} +static void xl_rxfilter_90x(struct xl_softc *sc) { - struct ifnet *ifp; - struct ifmultiaddr *ifma; - u_int8_t rxfilt; + if_t ifp; + uint32_t flags; + uint8_t rxfilt; XL_LOCK_ASSERT(sc); ifp = sc->xl_ifp; + flags = if_get(ifp, IF_FLAGS); XL_SEL_WIN(5); rxfilt = CSR_READ_1(sc, XL_W5_RX_FILTER); @@ -620,25 +660,17 @@ xl_rxfilter_90x(struct xl_softc *sc) /* Set the individual bit to receive frames for this host only. */ rxfilt |= XL_RXFILTER_INDIVIDUAL; /* Set capture broadcast bit to capture broadcast frames. */ - if (ifp->if_flags & IFF_BROADCAST) + if (flags & IFF_BROADCAST) rxfilt |= XL_RXFILTER_BROADCAST; /* If we want promiscuous mode, set the allframes bit. */ - if (ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI)) { - if (ifp->if_flags & IFF_PROMISC) + if (flags & (IFF_PROMISC | IFF_ALLMULTI)) { + if (flags & IFF_PROMISC) rxfilt |= XL_RXFILTER_ALLFRAMES; - if (ifp->if_flags & IFF_ALLMULTI) - rxfilt |= XL_RXFILTER_ALLMULTI; - } else { - if_maddr_rlock(ifp); - TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; + if (flags & IFF_ALLMULTI) rxfilt |= XL_RXFILTER_ALLMULTI; - break; - } - if_maddr_runlock(ifp); - } + } else + if_foreach_maddr(ifp, xl_check_maddr_90x, &rxfilt); CSR_WRITE_2(sc, XL_COMMAND, rxfilt | XL_CMD_RX_SET_FILT); XL_SEL_WIN(7); @@ -646,19 +678,38 @@ xl_rxfilter_90x(struct xl_softc *sc) /* * 3c905B adapters have a hash filter that we can program. - */ + * Note: the 3c905B currently only supports a 64-bit hash table, which means + * we really only need 6 bits, but the manual indicates that future chip + * revisions will have a 256-bit hash table, hence the routine is set up to + * calculate 8 bits of position info in case we need it some day. + * Note II, The Sequel: _CURRENT_ versions of the 3c905B have a 256 bit hash + * table. This means we have to use all 8 bits regardless. On older cards, + * the upper 2 bits will be ignored. Grrrr.... + */ +static void +xl_check_maddr_90xB(void *arg, struct sockaddr *maddr) +{ + struct sockaddr_dl *sdl = (struct sockaddr_dl *)maddr; + struct xl_softc *sc = arg; + uint16_t h; + + if (sdl->sdl_family != AF_LINK) + return; + + h = ether_crc32_be(LLADDR(sdl), ETHER_ADDR_LEN) & 0xFF; + CSR_WRITE_2(sc, XL_COMMAND, h | XL_CMD_RX_SET_HASH | XL_HASH_SET); +} static void xl_rxfilter_90xB(struct xl_softc *sc) { - struct ifnet *ifp; - struct ifmultiaddr *ifma; - int i, mcnt; - u_int16_t h; - u_int8_t rxfilt; + if_t ifp; + uint32_t flags; + uint8_t rxfilt; XL_LOCK_ASSERT(sc); ifp = sc->xl_ifp; + flags = if_get(ifp, IF_FLAGS); XL_SEL_WIN(5); rxfilt = CSR_READ_1(sc, XL_W5_RX_FILTER); @@ -669,47 +720,27 @@ xl_rxfilter_90xB(struct xl_softc *sc) /* Set the individual bit to receive frames for this host only. */ rxfilt |= XL_RXFILTER_INDIVIDUAL; /* Set capture broadcast bit to capture broadcast frames. */ - if (ifp->if_flags & IFF_BROADCAST) + if (flags & IFF_BROADCAST) rxfilt |= XL_RXFILTER_BROADCAST; /* If we want promiscuous mode, set the allframes bit. */ - if (ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI)) { - if (ifp->if_flags & IFF_PROMISC) + if (flags & (IFF_PROMISC | IFF_ALLMULTI)) { + if (flags & IFF_PROMISC) rxfilt |= XL_RXFILTER_ALLFRAMES; - if (ifp->if_flags & IFF_ALLMULTI) + if (flags & IFF_ALLMULTI) rxfilt |= XL_RXFILTER_ALLMULTI; } else { /* First, zot all the existing hash bits. */ - for (i = 0; i < XL_HASHFILT_SIZE; i++) + for (int i = 0; i < XL_HASHFILT_SIZE; i++) CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_HASH | i); /* Now program new ones. */ - mcnt = 0; - if_maddr_rlock(ifp); - TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - /* - * Note: the 3c905B currently only supports a 64-bit - * hash table, which means we really only need 6 bits, - * but the manual indicates that future chip revisions - * will have a 256-bit hash table, hence the routine - * is set up to calculate 8 bits of position info in - * case we need it some day. - * Note II, The Sequel: _CURRENT_ versions of the - * 3c905B have a 256 bit hash table. This means we have - * to use all 8 bits regardless. On older cards, the - * upper 2 bits will be ignored. Grrrr.... - */ - h = ether_crc32_be(LLADDR((struct sockaddr_dl *) - ifma->ifma_addr), ETHER_ADDR_LEN) & 0xFF; - CSR_WRITE_2(sc, XL_COMMAND, - h | XL_CMD_RX_SET_HASH | XL_HASH_SET); - mcnt++; - } - if_maddr_runlock(ifp); - if (mcnt > 0) - rxfilt |= XL_RXFILTER_MULTIHASH; + if_foreach_maddr(ifp, xl_check_maddr_90xB, sc); + /* + * XXXGL: a bit dirty, but easier then make a context + * containing softc and rxfilt. + */ + if_foreach_maddr(ifp, xl_check_maddr_90x, &rxfilt); } CSR_WRITE_2(sc, XL_COMMAND, rxfilt | XL_CMD_RX_SET_FILT); @@ -1062,12 +1093,18 @@ xl_choose_xcvr(struct xl_softc *sc, int static int xl_attach(device_t dev) { + struct if_attach_args ifat = { + .ifat_version = IF_ATTACH_VERSION, + .ifat_drv = &xl_ifdrv, + .ifat_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST, + .ifat_capabilities = IFCAP_VLAN_MTU | IFCAP_LINKSTATE, + }; u_char eaddr[ETHER_ADDR_LEN]; u_int16_t sinfo2, xcvr[2]; struct xl_softc *sc; - struct ifnet *ifp; + if_t ifp; int media, pmcap; - int error = 0, phy, rid, res, unit; + int error = 0, rid, res, unit; uint16_t did; sc = device_get_softc(dev); @@ -1191,16 +1228,6 @@ xl_attach(device_t dev) goto fail; } - /* Initialize interface name. */ - ifp = sc->xl_ifp = if_alloc(IFT_ETHER); - if (ifp == NULL) { - device_printf(dev, "can not if_alloc()\n"); - error = ENOSPC; - goto fail; - } - ifp->if_softc = sc; - if_initname(ifp, device_get_name(dev), device_get_unit(dev)); - /* Reset the adapter. */ XL_LOCK(sc); xl_reset(sc); @@ -1338,29 +1365,6 @@ xl_attach(device_t dev) /* Set the TX start threshold for best performance. */ sc->xl_tx_thresh = XL_MIN_FRAMELEN; - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_ioctl = xl_ioctl; - ifp->if_capabilities = IFCAP_VLAN_MTU; - if (sc->xl_type == XL_TYPE_905B) { - ifp->if_hwassist = XL905B_CSUM_FEATURES; -#ifdef XL905B_TXCSUM_BROKEN - ifp->if_capabilities |= IFCAP_RXCSUM; -#else - ifp->if_capabilities |= IFCAP_HWCSUM; -#endif - } - if ((sc->xl_flags & XL_FLAG_WOL) != 0) - ifp->if_capabilities |= IFCAP_WOL_MAGIC; - ifp->if_capenable = ifp->if_capabilities; -#ifdef DEVICE_POLLING - ifp->if_capabilities |= IFCAP_POLLING; -#endif - ifp->if_start = xl_start; - ifp->if_init = xl_init; - IFQ_SET_MAXLEN(&ifp->if_snd, XL_TX_LIST_CNT - 1); - ifp->if_snd.ifq_drv_maxlen = XL_TX_LIST_CNT - 1; - IFQ_SET_READY(&ifp->if_snd); - /* * Now we have to see what sort of media we have. * This includes probing for an MII interace and a @@ -1381,6 +1385,9 @@ xl_attach(device_t dev) if (sc->xl_media & XL_MEDIAOPT_MII || sc->xl_media & XL_MEDIAOPT_BTX || sc->xl_media & XL_MEDIAOPT_BT4) { + struct mii_data *mii; + int phy; + if (bootverbose) device_printf(dev, "found MII/AUTO\n"); xl_setcfg(sc); @@ -1393,14 +1400,16 @@ xl_attach(device_t dev) phy = MII_PHY_ANY; if ((sc->xl_flags & XL_FLAG_PHYOK) == 0) phy = 24; - error = mii_attach(dev, &sc->xl_miibus, ifp, xl_ifmedia_upd, + error = mii_attach(dev, &sc->xl_miibus, xl_ifmedia_upd, xl_ifmedia_sts, BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY, sc->xl_type == XL_TYPE_905B ? MIIF_DOPAUSE : 0); if (error != 0) { device_printf(dev, "attaching PHYs failed\n"); goto fail; } - goto done; + mii = device_get_softc(sc->xl_miibus); + ifat.ifat_baudrate = ifmedia_baudrate(mii->mii_media_active); + goto media_done; } /* @@ -1462,29 +1471,45 @@ xl_attach(device_t dev) if (sc->xl_miibus == NULL) ifmedia_set(&sc->ifmedia, media); + ifat.ifat_baudrate = ifmedia_baudrate(sc->ifmedia.ifm_media); -done: +media_done: if (sc->xl_flags & XL_FLAG_NO_XCVR_PWR) { XL_SEL_WIN(0); CSR_WRITE_2(sc, XL_W0_MFG_ID, XL_NO_XCVR_PWR_MAGICBITS); } - /* - * Call MI attach routine. - */ - ether_ifattach(ifp, eaddr); - error = bus_setup_intr(dev, sc->xl_irq, INTR_TYPE_NET | INTR_MPSAFE, NULL, xl_intr, sc, &sc->xl_intrhand); if (error) { device_printf(dev, "couldn't set up irq\n"); - ether_ifdetach(ifp); goto fail; } + /* Initialize interface. */ + ifat.ifat_softc = sc; + ifat.ifat_dunit = device_get_unit(dev); + ifat.ifat_lla = eaddr; + if (sc->xl_type == XL_TYPE_905B) { + ifat.ifat_hwassist = XL905B_CSUM_FEATURES; +#ifdef XL905B_TXCSUM_BROKEN + ifat.ifat_capabilities |= IFCAP_RXCSUM; +#else + ifat.ifat_capabilities |= IFCAP_HWCSUM; +#endif + } + if ((sc->xl_flags & XL_FLAG_WOL) != 0) + ifat.ifat_capabilities |= IFCAP_WOL_MAGIC; + ifat.ifat_capenable = ifat.ifat_capabilities; +#ifdef DEVICE_POLLING + ifat.ifat_capabilities |= IFCAP_POLLING; +#endif + ifp = sc->xl_ifp = if_attach(&ifat); + + return (0); + fail: - if (error) - xl_detach(dev); + xl_detach(dev); return (error); } @@ -1553,7 +1578,7 @@ static int xl_detach(device_t dev) { struct xl_softc *sc; - struct ifnet *ifp; + if_t ifp; int rid, res; sc = device_get_softc(dev); @@ -1581,7 +1606,7 @@ xl_detach(device_t dev) XL_UNLOCK(sc); taskqueue_drain(taskqueue_swi, &sc->xl_task); callout_drain(&sc->xl_tick_callout); - ether_ifdetach(ifp); + if_detach(ifp); } if (sc->xl_miibus) device_delete_child(dev, sc->xl_miibus); @@ -1598,9 +1623,6 @@ xl_detach(device_t dev) if (sc->xl_res) bus_release_resource(dev, res, rid, sc->xl_res); - if (ifp) - if_free(ifp); - if (sc->xl_mtag) { bus_dmamap_destroy(sc->xl_mtag, sc->xl_tmpmap); bus_dma_tag_destroy(sc->xl_mtag); @@ -1914,7 +1936,7 @@ again: m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = total_len; - if (ifp->if_capenable & IFCAP_RXCSUM) { + if (if_get(ifp, IF_CAPENABLE) & IFCAP_RXCSUM) { /* Do IP checksum checking. */ if (rxstat & XL_RXSTAT_IPCKOK) m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED; @@ -1931,7 +1953,7 @@ again: } XL_UNLOCK(sc); - (*ifp->if_input)(ifp, m); + if_input(ifp, m); XL_LOCK(sc); /* @@ -1939,7 +1961,7 @@ again: * might have been stopped while we were passing the last * packet up the network stack. */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) + if (!(sc->xl_flags & XL_FLAG_RUNNING)) return (rx_npkts); } @@ -1976,7 +1998,7 @@ xl_rxeof_task(void *arg, int pending) struct xl_softc *sc = (struct xl_softc *)arg; XL_LOCK(sc); - if (sc->xl_ifp->if_drv_flags & IFF_DRV_RUNNING) + if (sc->xl_flags & XL_FLAG_RUNNING) xl_rxeof(sc); XL_UNLOCK(sc); } @@ -1989,7 +2011,6 @@ static void xl_txeof(struct xl_softc *sc) { struct xl_chain *cur_tx; - struct ifnet *ifp = sc->xl_ifp; XL_LOCK_ASSERT(sc); @@ -2012,11 +2033,9 @@ xl_txeof(struct xl_softc *sc) bus_dmamap_sync(sc->xl_mtag, cur_tx->xl_map, BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->xl_mtag, cur_tx->xl_map); + if_inc_txcounters(sc->xl_ifp, cur_tx->xl_mbuf); m_freem(cur_tx->xl_mbuf); cur_tx->xl_mbuf = NULL; - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - cur_tx->xl_next = sc->xl_cdata.xl_tx_free; sc->xl_cdata.xl_tx_free = cur_tx; } @@ -2038,7 +2057,6 @@ static void xl_txeof_90xB(struct xl_softc *sc) { struct xl_chain *cur_tx = NULL; - struct ifnet *ifp = sc->xl_ifp; int idx; XL_LOCK_ASSERT(sc); @@ -2057,12 +2075,11 @@ xl_txeof_90xB(struct xl_softc *sc) bus_dmamap_sync(sc->xl_mtag, cur_tx->xl_map, BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->xl_mtag, cur_tx->xl_map); + if_inc_txcounters(sc->xl_ifp, cur_tx->xl_mbuf); m_freem(cur_tx->xl_mbuf); cur_tx->xl_mbuf = NULL; } - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - sc->xl_cdata.xl_tx_cnt--; XL_INC(idx, XL_TX_LIST_CNT); } @@ -2070,9 +2087,6 @@ xl_txeof_90xB(struct xl_softc *sc) if (sc->xl_cdata.xl_tx_cnt == 0) sc->xl_wdog_timer = 0; sc->xl_cdata.xl_tx_cons = idx; - - if (cur_tx != NULL) - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; } /* @@ -2167,7 +2181,7 @@ xl_intr(void *arg) break; CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ACK|(status & XL_INTRS)); - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + if ((sc->xl_flags & XL_FLAG_RUNNING) == 0) break; if (status & XL_STAT_UP_COMPLETE) { @@ -2190,7 +2204,7 @@ xl_intr(void *arg) } if (status & XL_STAT_ADFAIL) { - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + sc->xl_flags &= ~XL_FLAG_RUNNING; xl_init_locked(sc); break; } @@ -2199,12 +2213,11 @@ xl_intr(void *arg) xl_stats_update(sc); } - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd) && - ifp->if_drv_flags & IFF_DRV_RUNNING) { + if (if_snd_len(ifp) && sc->xl_flags & XL_FLAG_RUNNING) { if (sc->xl_type == XL_TYPE_905B) - xl_start_90xB_locked(ifp); + xl_start_90xB_locked(sc); else - xl_start_locked(ifp); + xl_start_locked(sc); } XL_UNLOCK(sc); @@ -2218,7 +2231,7 @@ xl_poll(struct ifnet *ifp, enum poll_cmd int rx_npkts = 0; XL_LOCK(sc); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) + if (sc->xl_flags & XL_FLAG_RUNNING) rx_npkts = xl_poll_locked(ifp, cmd, count); XL_UNLOCK(sc); return (rx_npkts); @@ -2239,7 +2252,7 @@ xl_poll_locked(struct ifnet *ifp, enum p else xl_txeof(sc); - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) { + if (if_snd_len(ifp)) { if (sc->xl_type == XL_TYPE_905B) xl_start_90xB_locked(ifp); else @@ -2260,7 +2273,7 @@ xl_poll_locked(struct ifnet *ifp, enum p } if (status & XL_STAT_ADFAIL) { - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + sc->xl_flags &= ~XL_FLAG_RUNNING; xl_init_locked(sc); } @@ -2429,25 +2442,29 @@ xl_encap(struct xl_softc *sc, struct xl_ * physical addresses. */ -static void -xl_start(struct ifnet *ifp) +static int +xl_transmit(if_t ifp, struct mbuf *m) { - struct xl_softc *sc = ifp->if_softc; + struct xl_softc *sc; + int error; - XL_LOCK(sc); + if ((error = if_snd_enqueue(ifp, m)) != 0) + return (error); + sc = if_getsoftc(ifp, IF_DRIVER_SOFTC); + if (XL_TRY_LOCK(sc) == 0) + return (0); if (sc->xl_type == XL_TYPE_905B) - xl_start_90xB_locked(ifp); + xl_start_90xB_locked(sc); else - xl_start_locked(ifp); - + xl_start_locked(sc); XL_UNLOCK(sc); + return (0); } static void -xl_start_locked(struct ifnet *ifp) +xl_start_locked(struct xl_softc *sc) { - struct xl_softc *sc = ifp->if_softc; struct mbuf *m_head; struct xl_chain *prev = NULL, *cur_tx = NULL, *start_tx; struct xl_chain *prev_tx; @@ -2455,8 +2472,7 @@ xl_start_locked(struct ifnet *ifp) XL_LOCK_ASSERT(sc); - if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != - IFF_DRV_RUNNING) + if ((sc->xl_flags & XL_FLAG_RUNNING) != XL_FLAG_RUNNING) return; /* * Check for an available queue slot. If there are none, @@ -2465,20 +2481,14 @@ xl_start_locked(struct ifnet *ifp) if (sc->xl_cdata.xl_tx_free == NULL) { xl_txeoc(sc); xl_txeof(sc); - if (sc->xl_cdata.xl_tx_free == NULL) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; + if (sc->xl_cdata.xl_tx_free == NULL) return; - } } start_tx = sc->xl_cdata.xl_tx_free; - for (; !IFQ_DRV_IS_EMPTY(&ifp->if_snd) && - sc->xl_cdata.xl_tx_free != NULL;) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head); - if (m_head == NULL) - break; - + while (sc->xl_cdata.xl_tx_free != NULL && + ((m_head = if_snd_dequeue(sc->xl_ifp)) != NULL)) { /* Pick a descriptor off the free list. */ prev_tx = cur_tx; cur_tx = sc->xl_cdata.xl_tx_free; @@ -2489,8 +2499,7 @@ xl_start_locked(struct ifnet *ifp) cur_tx = prev_tx; if (m_head == NULL) break; - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - IFQ_DRV_PREPEND(&ifp->if_snd, m_head); + if_snd_prepend(sc->xl_ifp, m_head); break; } @@ -2508,7 +2517,7 @@ xl_start_locked(struct ifnet *ifp) * If there's a BPF listener, bounce a copy of this frame * to him. */ - BPF_MTAP(ifp, cur_tx->xl_mbuf); + if_mtap(sc->xl_ifp, cur_tx->xl_mbuf, NULL, 0); } /* @@ -2577,9 +2586,8 @@ xl_start_locked(struct ifnet *ifp) } static void -xl_start_90xB_locked(struct ifnet *ifp) +xl_start_90xB_locked(struct xl_softc *sc) { - struct xl_softc *sc = ifp->if_softc; struct mbuf *m_head; struct xl_chain *prev = NULL, *cur_tx = NULL, *start_tx; struct xl_chain *prev_tx; @@ -2587,24 +2595,15 @@ xl_start_90xB_locked(struct ifnet *ifp) XL_LOCK_ASSERT(sc); - if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != - IFF_DRV_RUNNING) + if ((sc->xl_flags & XL_FLAG_RUNNING) != XL_FLAG_RUNNING) return; idx = sc->xl_cdata.xl_tx_prod; start_tx = &sc->xl_cdata.xl_tx_chain[idx]; - for (; !IFQ_DRV_IS_EMPTY(&ifp->if_snd) && - sc->xl_cdata.xl_tx_chain[idx].xl_mbuf == NULL;) { - if ((XL_TX_LIST_CNT - sc->xl_cdata.xl_tx_cnt) < 3) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } - - IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head); - if (m_head == NULL) - break; - + while (sc->xl_cdata.xl_tx_chain[idx].xl_mbuf == NULL && + ((XL_TX_LIST_CNT - sc->xl_cdata.xl_tx_cnt) >= 3) && + ((m_head = if_snd_dequeue(sc->xl_ifp)) != NULL)) { prev_tx = cur_tx; cur_tx = &sc->xl_cdata.xl_tx_chain[idx]; @@ -2614,8 +2613,7 @@ xl_start_90xB_locked(struct ifnet *ifp) cur_tx = prev_tx; if (m_head == NULL) break; - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - IFQ_DRV_PREPEND(&ifp->if_snd, m_head); + if_snd_prepend(sc->xl_ifp, m_head); break; } @@ -2628,7 +2626,7 @@ xl_start_90xB_locked(struct ifnet *ifp) * If there's a BPF listener, bounce a copy of this frame * to him. */ - BPF_MTAP(ifp, cur_tx->xl_mbuf); + if_mtap(sc->xl_ifp, cur_tx->xl_mbuf, NULL, 0); XL_INC(idx, XL_TX_LIST_CNT); sc->xl_cdata.xl_tx_cnt++; @@ -2674,13 +2672,12 @@ xl_init(void *xsc) static void xl_init_locked(struct xl_softc *sc) { - struct ifnet *ifp = sc->xl_ifp; int error, i; struct mii_data *mii = NULL; XL_LOCK_ASSERT(sc); - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) + if ((sc->xl_flags & XL_FLAG_RUNNING) != 0) return; /* * Cancel pending I/O and free all RX/TX buffers. @@ -2714,7 +2711,7 @@ xl_init_locked(struct xl_softc *sc) XL_SEL_WIN(2); for (i = 0; i < ETHER_ADDR_LEN; i++) { CSR_WRITE_1(sc, XL_W2_STATION_ADDR_LO + i, - IF_LLADDR(sc->xl_ifp)[i]); + if_lladdr(sc->xl_ifp)[i]); } /* Clear the station mask. */ @@ -2869,8 +2866,7 @@ xl_init_locked(struct xl_softc *sc) /* Select window 7 for normal operations. */ XL_SEL_WIN(7); - ifp->if_drv_flags |= IFF_DRV_RUNNING; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + sc->xl_flags |= XL_FLAG_RUNNING; sc->xl_wdog_timer = 0; callout_reset(&sc->xl_tick_callout, hz, xl_tick, sc); @@ -2882,10 +2878,11 @@ xl_init_locked(struct xl_softc *sc) static int xl_ifmedia_upd(struct ifnet *ifp) { - struct xl_softc *sc = ifp->if_softc; + struct xl_softc *sc; struct ifmedia *ifm = NULL; struct mii_data *mii = NULL; + sc = if_getsoftc(ifp, IF_DRIVER_SOFTC); XL_LOCK(sc); if (sc->xl_miibus != NULL) @@ -2908,7 +2905,7 @@ xl_ifmedia_upd(struct ifnet *ifp) if (sc->xl_media & XL_MEDIAOPT_MII || sc->xl_media & XL_MEDIAOPT_BTX || sc->xl_media & XL_MEDIAOPT_BT4) { - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + sc->xl_flags &= ~XL_FLAG_RUNNING; xl_init_locked(sc); } else { xl_setmode(sc, ifm->ifm_media); @@ -2925,11 +2922,12 @@ xl_ifmedia_upd(struct ifnet *ifp) static void xl_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) { - struct xl_softc *sc = ifp->if_softc; + struct xl_softc *sc; u_int32_t icfg; u_int16_t status = 0; struct mii_data *mii = NULL; + sc = if_getsoftc(ifp, IF_DRIVER_SOFTC); XL_LOCK(sc); if (sc->xl_miibus != NULL) @@ -2997,33 +2995,37 @@ xl_ifmedia_sts(struct ifnet *ifp, struct static int xl_ioctl(struct ifnet *ifp, u_long command, caddr_t data) { - struct xl_softc *sc = ifp->if_softc; + struct xl_softc *sc; struct ifreq *ifr = (struct ifreq *) data; - int error = 0, mask; + uint32_t flags, mask; + int error = 0; struct mii_data *mii = NULL; + sc = if_getsoftc(ifp, IF_DRIVER_SOFTC); + switch (command) { case SIOCSIFFLAGS: XL_LOCK(sc); - if (ifp->if_flags & IFF_UP) { - if (ifp->if_drv_flags & IFF_DRV_RUNNING && - (ifp->if_flags ^ sc->xl_if_flags) & + flags = if_get(ifp, IF_FLAGS); + if (flags & IFF_UP) { + if (sc->xl_flags & XL_FLAG_RUNNING && + (flags ^ sc->xl_if_flags) & (IFF_PROMISC | IFF_ALLMULTI)) xl_rxfilter(sc); else xl_init_locked(sc); } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) + if (sc->xl_flags & XL_FLAG_RUNNING) xl_stop(sc); } - sc->xl_if_flags = ifp->if_flags; + sc->xl_if_flags = flags; XL_UNLOCK(sc); break; case SIOCADDMULTI: case SIOCDELMULTI: /* XXX Downcall from if_addmulti() possibly with locks held. */ XL_LOCK(sc); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) + if (sc->xl_flags & XL_FLAG_RUNNING) xl_rxfilter(sc); XL_UNLOCK(sc); break; @@ -3039,19 +3041,19 @@ xl_ioctl(struct ifnet *ifp, u_long comma &mii->mii_media, command); break; case SIOCSIFCAP: - mask = ifr->ifr_reqcap ^ ifp->if_capenable; + mask = ifr->ifr_reqcap ^ if_get(ifp, IF_CAPENABLE); #ifdef DEVICE_POLLING if ((mask & IFCAP_POLLING) != 0 && - (ifp->if_capabilities & IFCAP_POLLING) != 0) { - ifp->if_capenable ^= IFCAP_POLLING; - if ((ifp->if_capenable & IFCAP_POLLING) != 0) { + (if_get(ifp, IF_CAPABILITIES) & IFCAP_POLLING) != 0) { + if_xorflags(ifp, IF_CAPENABLE, IFCAP_POLLING); + if ((if_get(ifp, IF_CAPENABLE) & IFCAP_POLLING) != 0) { error = ether_poll_register(xl_poll, ifp); if (error) break; XL_LOCK(sc); /* Disable interrupts */ CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|0); - ifp->if_capenable |= IFCAP_POLLING; + if_addflags(ifp, IF_CAPENABLE, IFCAP_POLLING); XL_UNLOCK(sc); } else { error = ether_poll_deregister(ifp); @@ -3070,23 +3072,25 @@ xl_ioctl(struct ifnet *ifp, u_long comma #endif /* DEVICE_POLLING */ XL_LOCK(sc); if ((mask & IFCAP_TXCSUM) != 0 && - (ifp->if_capabilities & IFCAP_TXCSUM) != 0) { - ifp->if_capenable ^= IFCAP_TXCSUM; - if ((ifp->if_capenable & IFCAP_TXCSUM) != 0) - ifp->if_hwassist |= XL905B_CSUM_FEATURES; + (if_get(ifp, IF_CAPABILITIES) & IFCAP_TXCSUM) != 0) { + if_xorflags(ifp, IF_CAPENABLE, IFCAP_TXCSUM); + if ((if_get(ifp, IF_CAPENABLE) & IFCAP_TXCSUM) != 0) + if_addflags(ifp, IF_HWASSIST, + XL905B_CSUM_FEATURES); else - ifp->if_hwassist &= ~XL905B_CSUM_FEATURES; + if_clrflags(ifp, IF_HWASSIST, + XL905B_CSUM_FEATURES); } if ((mask & IFCAP_RXCSUM) != 0 && - (ifp->if_capabilities & IFCAP_RXCSUM) != 0) - ifp->if_capenable ^= IFCAP_RXCSUM; + (if_get(ifp, IF_CAPABILITIES) & IFCAP_RXCSUM) != 0) + if_xorflags(ifp, IF_CAPENABLE, IFCAP_RXCSUM); if ((mask & IFCAP_WOL_MAGIC) != 0 && - (ifp->if_capabilities & IFCAP_WOL_MAGIC) != 0) - ifp->if_capenable ^= IFCAP_WOL_MAGIC; + (if_get(ifp, IF_CAPABILITIES) & IFCAP_WOL_MAGIC) != 0) + if_xorflags(ifp, IF_CAPENABLE, IFCAP_WOL_MAGIC); XL_UNLOCK(sc); break; default: - error = ether_ioctl(ifp, command, data); + error = EOPNOTSUPP; break; } @@ -3132,14 +3136,14 @@ xl_watchdog(struct xl_softc *sc) device_printf(sc->xl_dev, "no carrier - transceiver cable problem?\n"); - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + sc->xl_flags &= ~XL_FLAG_RUNNING; xl_init_locked(sc); - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) { + if (if_snd_len(ifp)) { if (sc->xl_type == XL_TYPE_905B) - xl_start_90xB_locked(ifp); + xl_start_90xB_locked(sc); else - xl_start_locked(ifp); + xl_start_locked(sc); } return (EJUSTRETURN); @@ -3153,7 +3157,6 @@ static void xl_stop(struct xl_softc *sc) { register int i; - struct ifnet *ifp = sc->xl_ifp; XL_LOCK_ASSERT(sc); @@ -3215,7 +3218,7 @@ xl_stop(struct xl_softc *sc) if (sc->xl_ldata.xl_tx_list != NULL) bzero(sc->xl_ldata.xl_tx_list, XL_TX_LIST_SZ); - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + sc->xl_flags &= ~XL_FLAG_RUNNING; } /* @@ -3255,8 +3258,8 @@ xl_resume(device_t dev) XL_LOCK(sc); - if (ifp->if_flags & IFF_UP) { - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + if (if_get(ifp, IF_FLAGS) & IFF_UP) { + sc->xl_flags &= ~XL_FLAG_RUNNING; xl_init_locked(sc); } @@ -3279,16 +3282,16 @@ xl_setwol(struct xl_softc *sc) /* Clear any pending PME events. */ CSR_READ_2(sc, XL_W7_BM_PME); cfg = 0; - if ((ifp->if_capenable & IFCAP_WOL_MAGIC) != 0) + if ((if_get(ifp, IF_CAPENABLE) & IFCAP_WOL_MAGIC) != 0) cfg |= XL_BM_PME_MAGIC; CSR_WRITE_2(sc, XL_W7_BM_PME, cfg); /* Enable RX. */ - if ((ifp->if_capenable & IFCAP_WOL_MAGIC) != 0) + if ((if_get(ifp, IF_CAPENABLE) & IFCAP_WOL_MAGIC) != 0) CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_ENABLE); /* Request PME. */ *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***