From owner-svn-src-projects@FreeBSD.ORG Wed Mar 25 17:21:00 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 7A9A69C6; Wed, 25 Mar 2015 17:21:00 +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 646BC7C9; Wed, 25 Mar 2015 17:21:00 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t2PHL0Mr090901; Wed, 25 Mar 2015 17:21:00 GMT (envelope-from glebius@FreeBSD.org) Received: (from glebius@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t2PHL0ox090898; Wed, 25 Mar 2015 17:21:00 GMT (envelope-from glebius@FreeBSD.org) Message-Id: <201503251721.t2PHL0ox090898@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: glebius set sender to glebius@FreeBSD.org using -f From: Gleb Smirnoff Date: Wed, 25 Mar 2015 17:21:00 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r280627 - in projects/ifnet/sys/dev: re rl 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: Wed, 25 Mar 2015 17:21:00 -0000 Author: glebius Date: Wed Mar 25 17:20:59 2015 New Revision: 280627 URL: https://svnweb.freebsd.org/changeset/base/280627 Log: Convert re(4) to new ifnet KPI. Big thanks to Mikhail for providing the patch of very good quality and tested. If a hundred people would do the same, then the opaque ifnet project seems to be an achievable goal. :) Submitted by: Mikhail Modified: projects/ifnet/sys/dev/re/if_re.c projects/ifnet/sys/dev/rl/if_rlreg.h Modified: projects/ifnet/sys/dev/re/if_re.c ============================================================================== --- projects/ifnet/sys/dev/re/if_re.c Wed Mar 25 16:54:37 2015 (r280626) +++ projects/ifnet/sys/dev/re/if_re.c Wed Mar 25 17:20:59 2015 (r280627) @@ -127,15 +127,9 @@ __FBSDID("$FreeBSD$"); #include #include -#include -#include #include #include #include -#include -#include - -#include #include #include @@ -265,25 +259,24 @@ static __inline void re_fixup_rx static int re_rxeof (struct rl_softc *, int *); static void re_txeof (struct rl_softc *); #ifdef DEVICE_POLLING -static int re_poll (struct ifnet *, enum poll_cmd, int); -static int re_poll_locked (struct ifnet *, enum poll_cmd, int); +static int re_poll (if_t, enum poll_cmd, int); +static int re_poll_locked (if_t, enum poll_cmd, int); #endif static int re_intr (void *); static void re_intr_msi (void *); static void re_tick (void *); static void re_int_task (void *, int); -static void re_start (struct ifnet *); -static void re_start_locked (struct ifnet *); -static int re_ioctl (struct ifnet *, u_long, caddr_t); -static void re_init (void *); -static void re_init_locked (struct rl_softc *); +static int re_start (struct rl_softc *); +static int re_transmit (if_t, struct mbuf *); +static int re_ioctl (if_t, u_long, void *, struct thread *); +static void re_init (struct rl_softc *); static void re_stop (struct rl_softc *); static void re_watchdog (struct rl_softc *); static int re_suspend (device_t); static int re_resume (device_t); static int re_shutdown (device_t); -static int re_ifmedia_upd (struct ifnet *); -static void re_ifmedia_sts (struct ifnet *, struct ifmediareq *); +static int re_ifmedia_upd (if_t); +static void re_ifmedia_sts (if_t, struct ifmediareq *); static void re_eeprom_putbyte (struct rl_softc *, int); static void re_eeprom_getword (struct rl_softc *, int, u_int16_t *); @@ -296,7 +289,8 @@ static int re_miibus_writereg (device_t, static void re_miibus_statchg (device_t); static void re_set_jumbo (struct rl_softc *, int); -static void re_set_rxmode (struct rl_softc *); +static void re_hash_maddr (void *, struct sockaddr *); +static void re_set_rxmode (struct rl_softc *); static void re_reset (struct rl_softc *); static void re_setwol (struct rl_softc *); static void re_clrwol (struct rl_softc *); @@ -315,6 +309,20 @@ static int re_sysctl_stats (SYSCTL_HANDL static int sysctl_int_range (SYSCTL_HANDLER_ARGS, int, int); static int sysctl_hw_re_int_mod (SYSCTL_HANDLER_ARGS); +static struct ifdriver re_ifdrv = { + .ifdrv_ops = { + .ifop_ioctl = re_ioctl, + .ifop_transmit = re_transmit, +#ifdef DEVICE_POLLING + .ifop_poll = re_poll, +#endif + }, + .ifdrv_name = "re", + .ifdrv_type = IFT_ETHER, + .ifdrv_hdrlen = sizeof(struct ether_vlan_header), + .ifdrv_maxqlen = RL_IFQ_MAXLEN, +}; + static device_method_t re_methods[] = { /* Device interface */ DEVMETHOD(device_probe, re_probe), @@ -606,14 +614,14 @@ static void re_miibus_statchg(device_t dev) { struct rl_softc *sc; - struct ifnet *ifp; + if_t ifp; struct mii_data *mii; sc = device_get_softc(dev); mii = device_get_softc(sc->rl_miibus); ifp = sc->rl_ifp; if (mii == NULL || ifp == NULL || - (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + (sc->rl_flags & RL_FLAG_RUNNING) == 0) return; sc->rl_flags &= ~RL_FLAG_LINK; @@ -633,6 +641,10 @@ re_miibus_statchg(device_t dev) break; } } + + if_setbaudrate(ifp, ifmedia_baudrate(mii->mii_media_active)); + if_link_state_change(ifp, ifmedia_link_state(mii->mii_media_status)); + /* * RealTek controllers does not provide any interface to * Tx/Rx MACs for resolved speed, duplex and flow-control @@ -640,14 +652,31 @@ re_miibus_statchg(device_t dev) */ } +static void +re_hash_maddr(void *arg, struct sockaddr *maddr) +{ + struct sockaddr_dl *sdl = (struct sockaddr_dl *)maddr; + uint32_t *hashes, h; + + if (sdl->sdl_family != AF_LINK) + return; + + hashes = arg; + h = ether_crc32_be(LLADDR(sdl), ETHER_ADDR_LEN) >> 26; + if (h < 32) + hashes[0] |= (1 << h); + else + hashes[1] |= (1 << (h - 32)); +} + + /* * Set the RX configuration and 64-bit multicast hash filter. */ static void re_set_rxmode(struct rl_softc *sc) { - struct ifnet *ifp; - struct ifmultiaddr *ifma; + if_t ifp; uint32_t hashes[2] = { 0, 0 }; uint32_t h, rxfilt; @@ -661,8 +690,8 @@ re_set_rxmode(struct rl_softc *sc) else if ((sc->rl_flags & RL_FLAG_EARLYOFFV2) != 0) rxfilt |= RL_RXCFG_EARLYOFFV2; - if (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) { - if (ifp->if_flags & IFF_PROMISC) + if (sc->rl_if_flags & (IFF_ALLMULTI | IFF_PROMISC)) { + if (sc->rl_if_flags & IFF_PROMISC) rxfilt |= RL_RXCFG_RX_ALLPHYS; /* * Unlike other hardwares, we have to explicitly set @@ -674,18 +703,7 @@ re_set_rxmode(struct rl_softc *sc) goto done; } - if_maddr_rlock(ifp); - TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - h = ether_crc32_be(LLADDR((struct sockaddr_dl *) - ifma->ifma_addr), ETHER_ADDR_LEN) >> 26; - if (h < 32) - hashes[0] |= (1 << h); - else - hashes[1] |= (1 << (h - 32)); - } - if_maddr_runlock(ifp); + if_foreach_maddr(ifp, re_hash_maddr, hashes); if (hashes[0] != 0 || hashes[1] != 0) { /* @@ -763,7 +781,7 @@ re_reset(struct rl_softc *sc) static int re_diag(struct rl_softc *sc) { - struct ifnet *ifp = sc->rl_ifp; + if_t ifp = sc->rl_ifp; struct mbuf *m0; struct ether_header *eh; struct rl_desc *cur_rx; @@ -772,6 +790,7 @@ re_diag(struct rl_softc *sc) int total_len, i, error = 0, phyaddr; u_int8_t dst[] = { 0x00, 'h', 'e', 'l', 'l', 'o' }; u_int8_t src[] = { 0x00, 'w', 'o', 'r', 'l', 'd' }; + struct ifreq ifr; /* Allocate a single mbuf */ MGETHDR(m0, M_NOWAIT, MT_DATA); @@ -789,10 +808,13 @@ re_diag(struct rl_softc *sc) * - Leaves interrupts turned off */ - ifp->if_flags |= IFF_PROMISC; + if_drvioctl(ifp, SIOCGIFFLAGS, &ifr, curthread); + ifr.ifr_flags |= IFF_PROMISC; + if_drvioctl(ifp, SIOCSIFFLAGS, &ifr, curthread); + sc->rl_testmode = 1; - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; - re_init_locked(sc); + sc->rl_flags &= ~RL_FLAG_RUNNING; + re_init(sc); sc->rl_flags |= RL_FLAG_LINK; if (sc->rl_type == RL_8169) phyaddr = 1; @@ -821,13 +843,12 @@ re_diag(struct rl_softc *sc) /* * Queue the packet, start transmission. - * Note: IF_HANDOFF() ultimately calls re_start() for us. */ CSR_WRITE_2(sc, RL_ISR, 0xFFFF); RL_UNLOCK(sc); /* XXX: re_diag must not be called when in ALTQ mode */ - IF_HANDOFF(&ifp->if_snd, m0, ifp); + re_transmit(ifp, m0); RL_LOCK(sc); m0 = NULL; @@ -905,7 +926,9 @@ done: sc->rl_testmode = 0; sc->rl_flags &= ~RL_FLAG_LINK; - ifp->if_flags &= ~IFF_PROMISC; + if_drvioctl(ifp, SIOCGIFFLAGS, &ifr, curthread); + ifr.ifr_flags &= ~IFF_PROMISC; + if_drvioctl(ifp, SIOCSIFFLAGS, &ifr, curthread); re_stop(sc); if (m0 != NULL) m_freem(m0); @@ -1200,10 +1223,16 @@ re_allocmem(device_t dev, struct rl_soft static int re_attach(device_t dev) { + struct if_attach_args ifat = { + .ifat_version = IF_ATTACH_VERSION, + .ifat_drv = &re_ifdrv, + .ifat_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST, + .ifat_capabilities = IFCAP_LINKSTATE, + }; u_char eaddr[ETHER_ADDR_LEN]; u_int16_t as[ETHER_ADDR_LEN / 2]; struct rl_softc *sc; - struct ifnet *ifp; + if_t ifp; const struct rl_hwrev *hw_rev; u_int32_t cap, ctl; int hwrev; @@ -1211,6 +1240,7 @@ re_attach(device_t dev) int error = 0, i, phy, rid; int msic, msixc, reg; uint8_t cfg; + struct mii_data *mii; sc = device_get_softc(dev); sc->rl_dev = dev; @@ -1570,6 +1600,7 @@ re_attach(device_t dev) as[i] = le16toh(as[i]); bcopy(as, eaddr, ETHER_ADDR_LEN); } + ifat.ifat_lla = eaddr; if (sc->rl_type == RL_8169) { /* Set RX length mask and number of descriptors. */ @@ -1590,13 +1621,6 @@ re_attach(device_t dev) goto fail; re_add_sysctls(sc); - ifp = sc->rl_ifp = if_alloc(IFT_ETHER); - if (ifp == NULL) { - device_printf(dev, "can not if_alloc()\n"); - error = ENOSPC; - goto fail; - } - /* Take controller out of deep sleep mode. */ if ((sc->rl_flags & RL_FLAG_MACSLEEP) != 0) { if ((CSR_READ_1(sc, RL_MACDBG) & 0x80) == 0x80) @@ -1618,11 +1642,9 @@ re_attach(device_t dev) re_gmii_writereg(dev, 1, 0x0e, 0); } - ifp->if_softc = sc; - if_initname(ifp, device_get_name(dev), device_get_unit(dev)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_ioctl = re_ioctl; - ifp->if_start = re_start; + ifat.ifat_softc = sc; + ifat.ifat_dunit = device_get_unit(dev); + /* * RTL8168/8111C generates wrong IP checksummed frame if the * packet has IP options so disable TX checksum offloading. @@ -1630,18 +1652,14 @@ re_attach(device_t dev) if (sc->rl_hwrev->rl_rev == RL_HWREV_8168C || sc->rl_hwrev->rl_rev == RL_HWREV_8168C_SPIN2 || sc->rl_hwrev->rl_rev == RL_HWREV_8168CP) { - ifp->if_hwassist = 0; - ifp->if_capabilities = IFCAP_RXCSUM | IFCAP_TSO4; + ifat.ifat_hwassist = 0; + ifat.ifat_capabilities = IFCAP_RXCSUM | IFCAP_TSO4; } else { - ifp->if_hwassist = CSUM_IP | CSUM_TCP | CSUM_UDP; - ifp->if_capabilities = IFCAP_HWCSUM | IFCAP_TSO4; + ifat.ifat_hwassist = CSUM_IP | CSUM_TCP | CSUM_UDP; + ifat.ifat_capabilities = IFCAP_HWCSUM | IFCAP_TSO4; } - ifp->if_hwassist |= CSUM_TSO; - ifp->if_capenable = ifp->if_capabilities; - ifp->if_init = re_init; - IFQ_SET_MAXLEN(&ifp->if_snd, RL_IFQ_MAXLEN); - ifp->if_snd.ifq_drv_maxlen = RL_IFQ_MAXLEN; - IFQ_SET_READY(&ifp->if_snd); + ifat.ifat_hwassist |= CSUM_TSO; + ifat.ifat_capenable = ifat.ifat_capabilities; TASK_INIT(&sc->rl_inttask, 0, re_int_task, sc); @@ -1651,43 +1669,40 @@ re_attach(device_t dev) phy = RE_PHYAD_INTERNAL; if (sc->rl_type == RL_8169) phy = 1; - error = mii_attach(dev, &sc->rl_miibus, ifp, re_ifmedia_upd, - re_ifmedia_sts, BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY, MIIF_DOPAUSE); + error = mii_attach(dev, &sc->rl_miibus, re_ifmedia_upd, re_ifmedia_sts, + BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY, MIIF_DOPAUSE); if (error != 0) { device_printf(dev, "attaching PHYs failed\n"); goto fail; } + mii = device_get_softc(sc->rl_miibus); + ifat.ifat_baudrate = ifmedia_baudrate(mii->mii_media_active); + /* * Call MI attach routine. */ - ether_ifattach(ifp, eaddr); /* VLAN capability setup */ - ifp->if_capabilities |= IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING; - if (ifp->if_capabilities & IFCAP_HWCSUM) - ifp->if_capabilities |= IFCAP_VLAN_HWCSUM; + ifat.ifat_capabilities |= IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING; + if (ifat.ifat_capabilities & IFCAP_HWCSUM) + ifat.ifat_capabilities |= IFCAP_VLAN_HWCSUM; /* Enable WOL if PM is supported. */ if (pci_find_cap(sc->rl_dev, PCIY_PMG, ®) == 0) - ifp->if_capabilities |= IFCAP_WOL; - ifp->if_capenable = ifp->if_capabilities; - ifp->if_capenable &= ~(IFCAP_WOL_UCAST | IFCAP_WOL_MCAST); + ifat.ifat_capabilities |= IFCAP_WOL; + ifat.ifat_capenable = ifat.ifat_capabilities; + ifat.ifat_capenable &= ~(IFCAP_WOL_UCAST | IFCAP_WOL_MCAST); /* * Don't enable TSO by default. It is known to generate * corrupted TCP segments(bad TCP options) under certain * circumstances. */ - ifp->if_hwassist &= ~CSUM_TSO; - ifp->if_capenable &= ~(IFCAP_TSO4 | IFCAP_VLAN_HWTSO); + ifat.ifat_hwassist &= ~CSUM_TSO; + ifat.ifat_capenable &= ~(IFCAP_TSO4 | IFCAP_VLAN_HWTSO); #ifdef DEVICE_POLLING - ifp->if_capabilities |= IFCAP_POLLING; + ifat.ifat_capabilities |= IFCAP_POLLING; #endif - /* - * Tell the upper layer(s) we support long frames. - * Must appear after the call to ether_ifattach() because - * ether_ifattach() sets ifi_hdrlen to the default value. - */ - ifp->if_hdrlen = sizeof(struct ether_vlan_header); + ifp = sc->rl_ifp = if_attach(&ifat); #ifdef DEV_NETMAP re_netmap_attach(sc); @@ -1703,8 +1718,7 @@ re_attach(device_t dev) error = re_diag(sc); if (error) { device_printf(dev, - "attach aborted due to hardware diag failure\n"); - ether_ifdetach(ifp); + "attach aborted due to hardware diag failure\n"); goto fail; } } @@ -1726,7 +1740,6 @@ re_attach(device_t dev) } if (error) { device_printf(dev, "couldn't set up irq\n"); - ether_ifdetach(ifp); } fail: @@ -1748,7 +1761,7 @@ static int re_detach(device_t dev) { struct rl_softc *sc; - struct ifnet *ifp; + if_t ifp; int i, rid; sc = device_get_softc(dev); @@ -1757,10 +1770,6 @@ re_detach(device_t dev) /* These should only be active if attach succeeded */ if (device_is_attached(dev)) { -#ifdef DEVICE_POLLING - if (ifp->if_capenable & IFCAP_POLLING) - ether_poll_deregister(ifp); -#endif RL_LOCK(sc); #if 0 sc->suspended = 1; @@ -1781,8 +1790,8 @@ re_detach(device_t dev) * to invoke the re_tick() function that isn't there * anymore. */ - ifp->if_flags &= ~IFF_UP; - ether_ifdetach(ifp); + sc->rl_if_flags &= ~IFF_UP; + if_detach(ifp); } if (sc->rl_miibus) device_delete_child(dev, sc->rl_miibus); @@ -1801,7 +1810,6 @@ re_detach(device_t dev) #ifdef DEV_NETMAP netmap_detach(ifp); #endif /* DEV_NETMAP */ - if_free(ifp); } if ((sc->rl_flags & (RL_FLAG_MSI | RL_FLAG_MSIX)) == 0) rid = 0; @@ -1906,7 +1914,7 @@ re_discard_rxbuf(struct rl_softc *sc, in struct rl_rxdesc *rxd; uint32_t cmdstat; - if (sc->rl_ifp->if_mtu > RL_MTU && + if (sc->rl_mtu > RL_MTU && (sc->rl_flags & RL_FLAG_JUMBOV2) != 0) rxd = &sc->rl_ldata.rl_jrx_desc[idx]; else @@ -2145,7 +2153,7 @@ static int re_rxeof(struct rl_softc *sc, int *rx_npktsp) { struct mbuf *m; - struct ifnet *ifp; + if_t ifp; int i, rxerr, total_len; struct rl_desc *cur_rx; u_int32_t rxstat, rxvlan; @@ -2158,7 +2166,7 @@ re_rxeof(struct rl_softc *sc, int *rx_np if (netmap_rx_irq(ifp, 0, &rx_npkts)) return 0; #endif /* DEV_NETMAP */ - if (ifp->if_mtu > RL_MTU && (sc->rl_flags & RL_FLAG_JUMBOV2) != 0) + if (sc->rl_mtu > RL_MTU && (sc->rl_flags & RL_FLAG_JUMBOV2) != 0) jumbo = 1; else jumbo = 0; @@ -2171,7 +2179,7 @@ re_rxeof(struct rl_softc *sc, int *rx_np for (i = sc->rl_ldata.rl_rx_prodidx; maxpkt > 0; i = RL_RX_DESC_NXT(sc, i)) { - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + if ((sc->rl_flags & RL_FLAG_RUNNING) == 0) break; cur_rx = &sc->rl_ldata.rl_rx_list[i]; rxstat = le32toh(cur_rx->rl_cmdstat); @@ -2313,11 +2321,12 @@ re_rxeof(struct rl_softc *sc, int *rx_np re_fixup_rx(m); #endif if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); + if_inc_counter(ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len); m->m_pkthdr.rcvif = ifp; /* Do RX checksumming if enabled */ - if (ifp->if_capenable & IFCAP_RXCSUM) { + if (sc->rl_capenable & IFCAP_RXCSUM) { if ((sc->rl_flags & RL_FLAG_DESCV2) == 0) { /* Check IP header checksum */ if (rxstat & RL_RDESC_STAT_PROTOID) @@ -2365,7 +2374,7 @@ re_rxeof(struct rl_softc *sc, int *rx_np m->m_flags |= M_VLANTAG; } RL_UNLOCK(sc); - (*ifp->if_input)(ifp, m); + if_input(ifp, m); RL_LOCK(sc); rx_npkts++; } @@ -2389,7 +2398,7 @@ re_rxeof(struct rl_softc *sc, int *rx_np static void re_txeof(struct rl_softc *sc) { - struct ifnet *ifp; + if_t ifp; struct rl_txdesc *txd; u_int32_t txstat; int cons; @@ -2427,18 +2436,17 @@ re_txeof(struct rl_softc *sc) txd->tx_dmamap); KASSERT(txd->tx_m != NULL, ("%s: freeing NULL mbufs!", __func__)); - m_freem(txd->tx_m); - txd->tx_m = NULL; if (txstat & (RL_TDESC_STAT_EXCESSCOL| RL_TDESC_STAT_COLCNT)) if_inc_counter(ifp, IFCOUNTER_COLLISIONS, 1); if (txstat & RL_TDESC_STAT_TXERRSUM) if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); else - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); + if_inc_txcounters(ifp, txd->tx_m); + m_freem(txd->tx_m); + txd->tx_m = NULL; } sc->rl_ldata.rl_tx_free++; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; } sc->rl_ldata.rl_tx_considx = cons; @@ -2485,22 +2493,22 @@ re_tick(void *xsc) #ifdef DEVICE_POLLING static int -re_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) +re_poll(if_t ifp, enum poll_cmd cmd, int count) { - struct rl_softc *sc = ifp->if_softc; + struct rl_softc *sc = if_getsoftc(ifp, IF_DRIVER_SOFTC); int rx_npkts = 0; RL_LOCK(sc); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) + if (sc->rl_flags & RL_FLAG_RUNNING) rx_npkts = re_poll_locked(ifp, cmd, count); RL_UNLOCK(sc); return (rx_npkts); } static int -re_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count) +re_poll_locked(if_t ifp, enum poll_cmd cmd, int count) { - struct rl_softc *sc = ifp->if_softc; + struct rl_softc *sc = if_getsoftc(ifp, IF_DRIVER_SOFTC); int rx_npkts; RL_LOCK_ASSERT(sc); @@ -2509,8 +2517,7 @@ re_poll_locked(struct ifnet *ifp, enum p re_rxeof(sc, &rx_npkts); re_txeof(sc); - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - re_start_locked(ifp); + re_start(sc); if (cmd == POLL_AND_CHECK_STATUS) { /* also check status register */ u_int16_t status; @@ -2529,8 +2536,8 @@ re_poll_locked(struct ifnet *ifp, enum p */ if (status & RL_ISR_SYSTEM_ERR) { - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; - re_init_locked(sc); + sc->rl_flags &= ~RL_FLAG_RUNNING; + re_init(sc); } } return (rx_npkts); @@ -2559,7 +2566,7 @@ static void re_int_task(void *arg, int npending) { struct rl_softc *sc; - struct ifnet *ifp; + if_t ifp; u_int16_t status; int rval = 0; @@ -2572,13 +2579,13 @@ re_int_task(void *arg, int npending) CSR_WRITE_2(sc, RL_ISR, status); if (sc->suspended || - (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + (sc->rl_flags & RL_FLAG_RUNNING) == 0) { RL_UNLOCK(sc); return; } #ifdef DEVICE_POLLING - if (ifp->if_capenable & IFCAP_POLLING) { + if (sc->rl_capenable & IFCAP_POLLING) { RL_UNLOCK(sc); return; } @@ -2608,12 +2615,11 @@ re_int_task(void *arg, int npending) re_txeof(sc); if (status & RL_ISR_SYSTEM_ERR) { - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; - re_init_locked(sc); + sc->rl_flags &= ~RL_FLAG_RUNNING; + re_init(sc); } - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - re_start_locked(ifp); + re_start(sc); RL_UNLOCK(sc); @@ -2629,7 +2635,7 @@ static void re_intr_msi(void *xsc) { struct rl_softc *sc; - struct ifnet *ifp; + if_t ifp; uint16_t intrs, status; sc = xsc; @@ -2637,14 +2643,14 @@ re_intr_msi(void *xsc) ifp = sc->rl_ifp; #ifdef DEVICE_POLLING - if (ifp->if_capenable & IFCAP_POLLING) { + if (sc->rl_capenable & IFCAP_POLLING) { RL_UNLOCK(sc); return; } #endif /* Disable interrupts. */ CSR_WRITE_2(sc, RL_IMR, 0); - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + if ((sc->rl_flags & RL_FLAG_RUNNING) == 0) { RL_UNLOCK(sc); return; } @@ -2662,7 +2668,7 @@ re_intr_msi(void *xsc) if (status & (RL_ISR_TIMEOUT_EXPIRED | RL_ISR_RX_OK | RL_ISR_RX_ERR | RL_ISR_FIFO_OFLOW | RL_ISR_RX_OVERRUN)) { re_rxeof(sc, NULL); - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) { + if ((sc->rl_flags & RL_FLAG_RUNNING) != 0) { if (sc->rl_int_rx_mod != 0 && (status & (RL_ISR_RX_OK | RL_ISR_RX_ERR | RL_ISR_FIFO_OFLOW | RL_ISR_RX_OVERRUN)) != 0) { @@ -2694,13 +2700,12 @@ re_intr_msi(void *xsc) re_txeof(sc); if (status & RL_ISR_SYSTEM_ERR) { - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; - re_init_locked(sc); + sc->rl_flags &= ~RL_FLAG_RUNNING; + re_init(sc); } - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) { - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - re_start_locked(ifp); + if ((sc->rl_flags & RL_FLAG_RUNNING) != 0) { + re_start(sc); CSR_WRITE_2(sc, RL_IMR, intrs); } RL_UNLOCK(sc); @@ -2898,32 +2903,35 @@ re_encap(struct rl_softc *sc, struct mbu return (0); } -static void -re_start(struct ifnet *ifp) +/* + * Main transmit routine for C+ and gigE NICs. + */ + +static int +re_transmit(if_t ifp, struct mbuf *m) { struct rl_softc *sc; + int error; + + if ((error = if_snd_enqueue(ifp, m)) != 0) + return (error); - sc = ifp->if_softc; + sc = if_getsoftc(ifp, IF_DRIVER_SOFTC); RL_LOCK(sc); - re_start_locked(ifp); + error = re_start(sc); RL_UNLOCK(sc); + return (error); } -/* - * Main transmit routine for C+ and gigE NICs. - */ -static void -re_start_locked(struct ifnet *ifp) +static int +re_start(struct rl_softc *sc) { - struct rl_softc *sc; - struct mbuf *m_head; - int queued; - - sc = ifp->if_softc; + struct mbuf *m; + int error, queued; #ifdef DEV_NETMAP /* XXX is this necessary ? */ - if (ifp->if_capenable & IFCAP_NETMAP) { + if (sc->rl_capenable & IFCAP_NETMAP) { struct netmap_kring *kring = &NA(ifp)->tx_rings[0]; if (sc->rl_ldata.rl_tx_prodidx != kring->nr_hwcur) { /* kick the tx unit */ @@ -2933,33 +2941,24 @@ re_start_locked(struct ifnet *ifp) #endif sc->rl_watchdog_timer = 5; } - return; + return (0); } #endif /* DEV_NETMAP */ - if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != - IFF_DRV_RUNNING || (sc->rl_flags & RL_FLAG_LINK) == 0) - return; - for (queued = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd) && - sc->rl_ldata.rl_tx_free > 1;) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head); - if (m_head == NULL) - break; + if ((sc->rl_flags & RL_FLAG_LINK) == 0) + return (ENETDOWN); - if (re_encap(sc, &m_head) != 0) { - if (m_head == NULL) + error = queued = 0; + while (sc->rl_ldata.rl_tx_free > 1 && + (m = if_snd_dequeue(sc->rl_ifp)) != NULL) { + if ((error = re_encap(sc, &m)) != 0) { + if (m == NULL) break; - IFQ_DRV_PREPEND(&ifp->if_snd, m_head); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; + if_snd_prepend(sc->rl_ifp, m); break; } - /* - * If there's a BPF listener, bounce a copy of this frame - * to him. - */ - ETHER_BPF_MTAP(ifp, m_head); - + if_mtap(sc->rl_ifp, m, NULL, 0); queued++; } @@ -2968,7 +2967,7 @@ re_start_locked(struct ifnet *ifp) if (sc->rl_ldata.rl_tx_free != sc->rl_ldata.rl_tx_desc_cnt) CSR_WRITE_4(sc, RL_TIMERCNT, 1); #endif - return; + return (0); } /* Flush the TX descriptors */ @@ -2995,6 +2994,8 @@ re_start_locked(struct ifnet *ifp) * Set a timeout in case the chip goes out to lunch. */ sc->rl_watchdog_timer = 5; + + return (0); } static void @@ -3051,32 +3052,19 @@ re_set_jumbo(struct rl_softc *sc, int ju } static void -re_init(void *xsc) -{ - struct rl_softc *sc = xsc; - - RL_LOCK(sc); - re_init_locked(sc); - RL_UNLOCK(sc); -} - -static void -re_init_locked(struct rl_softc *sc) +re_init(struct rl_softc *sc) { - struct ifnet *ifp = sc->rl_ifp; + if_t ifp = sc->rl_ifp; struct mii_data *mii; uint32_t reg; uint16_t cfg; - union { - uint32_t align_dummy; - u_char eaddr[ETHER_ADDR_LEN]; - } eaddr; + uint8_t *eaddr; RL_LOCK_ASSERT(sc); mii = device_get_softc(sc->rl_miibus); - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) + if ((sc->rl_flags & RL_FLAG_RUNNING) != 0) return; /* @@ -3091,16 +3079,13 @@ re_init_locked(struct rl_softc *sc) * For C+ mode, initialize the RX descriptors and mbufs. */ if ((sc->rl_flags & RL_FLAG_JUMBOV2) != 0) { - if (ifp->if_mtu > RL_MTU) { + if (sc->rl_mtu > RL_MTU) { if (re_jrx_list_init(sc) != 0) { device_printf(sc->rl_dev, "no memory for jumbo RX buffers\n"); re_stop(sc); return; } - /* Disable checksum offloading for jumbo frames. */ - ifp->if_capenable &= ~(IFCAP_HWCSUM | IFCAP_TSO4); - ifp->if_hwassist &= ~(RE_CSUM_FEATURES | CSUM_TSO); } else { if (re_rx_list_init(sc) != 0) { device_printf(sc->rl_dev, @@ -3109,7 +3094,7 @@ re_init_locked(struct rl_softc *sc) return; } } - re_set_jumbo(sc, ifp->if_mtu > RL_MTU); + re_set_jumbo(sc, sc->rl_mtu > RL_MTU); } else { if (re_rx_list_init(sc) != 0) { device_printf(sc->rl_dev, "no memory for RX buffers\n"); @@ -3118,7 +3103,7 @@ re_init_locked(struct rl_softc *sc) } if ((sc->rl_flags & RL_FLAG_PCIE) != 0 && pci_get_device(sc->rl_dev) != RT_DEVICEID_8101E) { - if (ifp->if_mtu > RL_MTU) + if (sc->rl_mtu > RL_MTU) pci_set_max_read_req(sc->rl_dev, 512); else pci_set_max_read_req(sc->rl_dev, 4096); @@ -3132,9 +3117,9 @@ re_init_locked(struct rl_softc *sc) * before all others. */ cfg = RL_CPLUSCMD_PCI_MRW; - if ((ifp->if_capenable & IFCAP_RXCSUM) != 0) + if ((sc->rl_capenable & IFCAP_RXCSUM) != 0) cfg |= RL_CPLUSCMD_RXCSUM_ENB; - if ((ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0) + if ((sc->rl_capenable & IFCAP_VLAN_HWTAGGING) != 0) cfg |= RL_CPLUSCMD_VLANSTRIP; if ((sc->rl_flags & RL_FLAG_MACSTAT) != 0) { cfg |= RL_CPLUSCMD_MACSTAT_DIS; @@ -3154,14 +3139,6 @@ re_init_locked(struct rl_softc *sc) /* Disable interrupt mitigation. */ CSR_WRITE_2(sc, 0xe2, 0); } - /* - * Disable TSO if interface MTU size is greater than MSS - * allowed in controller. - */ - if (ifp->if_mtu > RL_TSO_MTU && (ifp->if_capenable & IFCAP_TSO4) != 0) { - ifp->if_capenable &= ~IFCAP_TSO4; - ifp->if_hwassist &= ~CSUM_TSO; - } /* * Init our MAC address. Even though the chipset @@ -3169,12 +3146,12 @@ re_init_locked(struct rl_softc *sc) * register write enable" mode to modify the ID registers. */ /* Copy MAC address on stack to align. */ - bcopy(IF_LLADDR(ifp), eaddr.eaddr, ETHER_ADDR_LEN); + eaddr = if_lladdr(ifp); CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_WRITECFG); CSR_WRITE_4(sc, RL_IDR0, - htole32(*(u_int32_t *)(&eaddr.eaddr[0]))); + htole32(*(u_int32_t *)(&eaddr[0]))); CSR_WRITE_4(sc, RL_IDR4, - htole32(*(u_int32_t *)(&eaddr.eaddr[4]))); + htole32(*(u_int32_t *)(&eaddr[4]))); CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF); /* @@ -3230,7 +3207,7 @@ re_init_locked(struct rl_softc *sc) /* * Disable interrupts if we are polling. */ - if (ifp->if_capenable & IFCAP_POLLING) + if (sc->rl_capenable & IFCAP_POLLING) CSR_WRITE_2(sc, RL_IMR, 0); else /* otherwise ... */ #endif @@ -3296,7 +3273,7 @@ re_init_locked(struct rl_softc *sc) * set maximum size of jumbo frame depending on * controller revisions. */ - if (ifp->if_mtu > RL_MTU) + if (sc->rl_mtu > RL_MTU) CSR_WRITE_2(sc, RL_MAXRXPKTLEN, sc->rl_hwrev->rl_max_mtu + ETHER_VLAN_ENCAP_LEN + ETHER_HDR_LEN + @@ -3318,8 +3295,7 @@ re_init_locked(struct rl_softc *sc) CSR_WRITE_1(sc, sc->rl_cfg1, CSR_READ_1(sc, sc->rl_cfg1) | RL_CFG1_DRVLOAD); - ifp->if_drv_flags |= IFF_DRV_RUNNING; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + sc->rl_flags |= RL_FLAG_RUNNING; sc->rl_flags &= ~RL_FLAG_LINK; mii_mediachg(mii); @@ -3332,13 +3308,13 @@ re_init_locked(struct rl_softc *sc) * Set media options. */ static int -re_ifmedia_upd(struct ifnet *ifp) +re_ifmedia_upd(if_t ifp) { struct rl_softc *sc; struct mii_data *mii; int error; - sc = ifp->if_softc; + sc = if_getsoftc(ifp, IF_DRIVER_SOFTC); mii = device_get_softc(sc->rl_miibus); RL_LOCK(sc); error = mii_mediachg(mii); @@ -3351,12 +3327,12 @@ re_ifmedia_upd(struct ifnet *ifp) * Report current media status. */ static void -re_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) +re_ifmedia_sts(if_t ifp, struct ifmediareq *ifmr) { struct rl_softc *sc; struct mii_data *mii; - sc = ifp->if_softc; + sc = if_getsoftc(ifp, IF_DRIVER_SOFTC); mii = device_get_softc(sc->rl_miibus); RL_LOCK(sc); @@ -3366,61 +3342,79 @@ re_ifmedia_sts(struct ifnet *ifp, struct RL_UNLOCK(sc); } + static int -re_ioctl(struct ifnet *ifp, u_long command, caddr_t data) +re_ioctl(if_t ifp, u_long command, void *data, struct thread *td) { - struct rl_softc *sc = ifp->if_softc; + struct rl_softc *sc = if_getsoftc(ifp, IF_DRIVER_SOFTC); struct ifreq *ifr = (struct ifreq *) data; struct mii_data *mii; int error = 0; + uint32_t oflags; switch (command) { case SIOCSIFMTU: - if (ifr->ifr_mtu < ETHERMIN || - ifr->ifr_mtu > sc->rl_hwrev->rl_max_mtu || + if (ifr->ifr_mtu > sc->rl_hwrev->rl_max_mtu || ((sc->rl_flags & RL_FLAG_FASTETHER) != 0 && ifr->ifr_mtu > RL_MTU)) { error = EINVAL; break; } RL_LOCK(sc); - if (ifp->if_mtu != ifr->ifr_mtu) { - ifp->if_mtu = ifr->ifr_mtu; - if ((sc->rl_flags & RL_FLAG_JUMBOV2) != 0 && - (ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) { - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; - re_init_locked(sc); - } - if (ifp->if_mtu > RL_TSO_MTU && - (ifp->if_capenable & IFCAP_TSO4) != 0) { - ifp->if_capenable &= ~(IFCAP_TSO4 | - IFCAP_VLAN_HWTSO); - ifp->if_hwassist &= ~CSUM_TSO; *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***