Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 13 Jan 2015 09:09:41 +0000 (UTC)
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r277124 - projects/ifnet/sys/dev/xl
Message-ID:  <201501130909.t0D99fMq077974@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <sys/endian.h>
 #include <sys/mbuf.h>
 #include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
 #include <sys/module.h>
 #include <sys/socket.h>
 #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/bpf.h>
 
 #include <machine/bus.h>
 #include <machine/resource.h>
@@ -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 ***



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