Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 25 Mar 2015 17:21:00 +0000 (UTC)
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r280627 - in projects/ifnet/sys/dev: re rl
Message-ID:  <201503251721.t2PHL0ox090898@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <mp39590 gmail.com>

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 <sys/taskqueue.h>
 
 #include <net/if.h>
-#include <net/if_var.h>
-#include <net/if_arp.h>
 #include <net/ethernet.h>
 #include <net/if_dl.h>
 #include <net/if_media.h>
-#include <net/if_types.h>
-#include <net/if_vlan_var.h>
-
-#include <net/bpf.h>
 
 #include <machine/bus.h>
 #include <machine/resource.h>
@@ -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, &reg) == 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 ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201503251721.t2PHL0ox090898>