svn commit: r277192 - projects/ifnet/sys/dev/bge

Gleb Smirnoff glebius at FreeBSD.org
Wed Jan 14 19:47:52 UTC 2015


Author: glebius
Date: Wed Jan 14 19:47:51 2015
New Revision: 277192
URL: https://svnweb.freebsd.org/changeset/base/277192

Log:
  Convert bge(4) to new API.
  
  Committed via:	bge0
  Sponsored by:	Nginx, Inc.

Modified:
  projects/ifnet/sys/dev/bge/if_bge.c
  projects/ifnet/sys/dev/bge/if_bgereg.h

Modified: projects/ifnet/sys/dev/bge/if_bge.c
==============================================================================
--- projects/ifnet/sys/dev/bge/if_bge.c	Wed Jan 14 19:46:05 2015	(r277191)
+++ projects/ifnet/sys/dev/bge/if_bge.c	Wed Jan 14 19:47:51 2015	(r277192)
@@ -74,8 +74,10 @@ __FBSDID("$FreeBSD$");
 #include <sys/endian.h>
 #include <sys/systm.h>
 #include <sys/sockio.h>
+#include <sys/lock.h>
 #include <sys/mbuf.h>
 #include <sys/malloc.h>
+#include <sys/mutex.h>
 #include <sys/kernel.h>
 #include <sys/module.h>
 #include <sys/socket.h>
@@ -83,16 +85,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/bpf.h>
-
-#include <net/if_types.h>
-#include <net/if_vlan_var.h>
+#include <net/ethernet.h>
 
 #include <netinet/in_systm.h>
 #include <netinet/in.h>
@@ -422,8 +417,8 @@ static int bge_encap(struct bge_softc *,
 static void bge_intr(void *);
 static int bge_msi_intr(void *);
 static void bge_intr_task(void *, int);
-static void bge_start_locked(if_t);
-static void bge_start(if_t);
+static int bge_start_locked(struct bge_softc *);
+static int bge_transmit(if_t, struct mbuf *);
 static int bge_ioctl(if_t, u_long, caddr_t);
 static void bge_init_locked(struct bge_softc *);
 static void bge_init(void *);
@@ -474,6 +469,7 @@ static void bge_writereg_ind(struct bge_
 static int bge_miibus_readreg(device_t, int, int);
 static int bge_miibus_writereg(device_t, int, int, int);
 static void bge_miibus_statchg(device_t);
+static uint64_t bge_miibus_readvar(device_t, int);
 #ifdef DEVICE_POLLING
 static int bge_poll(if_t ifp, enum poll_cmd cmd, int count);
 #endif
@@ -526,6 +522,7 @@ static device_method_t bge_methods[] = {
 	DEVMETHOD(miibus_readreg,	bge_miibus_readreg),
 	DEVMETHOD(miibus_writereg,	bge_miibus_writereg),
 	DEVMETHOD(miibus_statchg,	bge_miibus_statchg),
+	DEVMETHOD(miibus_readvar,	bge_miibus_readvar),
 
 	DEVMETHOD_END
 };
@@ -536,6 +533,20 @@ static driver_t bge_driver = {
 	sizeof(struct bge_softc)
 };
 
+static struct ifdriver bge_ifdrv = {
+	.ifdrv_ops = {
+		.ifop_origin = IFOP_ORIGIN_DRIVER,
+		.ifop_ioctl = bge_ioctl,
+		.ifop_init = bge_init,
+		.ifop_transmit = bge_transmit,
+		.ifop_get_counter = bge_get_counter,
+	},
+	.ifdrv_name = "bge",
+	.ifdrv_type = IFT_ETHER,
+	.ifdrv_hdrlen = sizeof(struct ether_vlan_header),
+	.ifdrv_maxqlen = BGE_TX_RING_CNT - 1,
+};
+
 static devclass_t bge_devclass;
 
 DRIVER_MODULE(bge, pci, bge_driver, bge_devclass, 0, 0);
@@ -1245,7 +1256,7 @@ bge_miibus_statchg(device_t dev)
 	uint32_t mac_mode, rx_mode, tx_mode;
 
 	sc = device_get_softc(dev);
-	if ((if_getdrvflags(sc->bge_ifp) & IFF_DRV_RUNNING) == 0)
+	if ((sc->bge_flags & BGE_FLAG_RUNNING) == 0)
 		return;
 	mii = device_get_softc(sc->bge_miibus);
 
@@ -1270,6 +1281,14 @@ bge_miibus_statchg(device_t dev)
 		}
 	} else
 		sc->bge_link = 0;
+
+        if (sc->bge_ifp != NULL) { 
+		if_set(sc->bge_ifp, IF_BAUDRATE,
+		    ifmedia_baudrate(mii->mii_media_active));
+		if_link_state_change(sc->bge_ifp,
+		    ifmedia_link_state(mii->mii_media_status));
+        }
+
 	if (sc->bge_link == 0)
 		return;
 
@@ -1308,6 +1327,23 @@ bge_miibus_statchg(device_t dev)
 	CSR_WRITE_4(sc, BGE_RX_MODE, rx_mode);
 }
 
+static uint64_t
+bge_miibus_readvar(device_t dev, int var)
+{
+	struct bge_softc *sc;
+	if_t ifp;
+
+	sc = device_get_softc(dev);
+	ifp = sc->bge_ifp;
+
+	switch (var) {
+	case IF_MTU:
+		return (if_get(ifp, IF_MTU));
+	default:
+		return (0);
+	}
+}
+
 /*
  * Intialize a standard receive ring descriptor.
  */
@@ -1321,7 +1357,7 @@ bge_newbuf_std(struct bge_softc *sc, int
 	int error, nsegs;
 
 	if (sc->bge_flags & BGE_FLAG_JUMBO_STD &&
-	    (if_getmtu(sc->bge_ifp) + ETHER_HDR_LEN + ETHER_CRC_LEN +
+	    (if_get(sc->bge_ifp, IF_MTU) + ETHER_HDR_LEN + ETHER_CRC_LEN +
 	    ETHER_VLAN_ENCAP_LEN > (MCLBYTES - ETHER_ALIGN))) {
 		m = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, MJUM9BYTES);
 		if (m == NULL)
@@ -1605,36 +1641,38 @@ bge_setpromisc(struct bge_softc *sc)
 	ifp = sc->bge_ifp;
 
 	/* Enable or disable promiscuous mode as needed. */
-	if (if_getflags(ifp) & IFF_PROMISC)
+	if (if_get(ifp, IF_FLAGS) & IFF_PROMISC)
 		BGE_SETBIT(sc, BGE_RX_MODE, BGE_RXMODE_RX_PROMISC);
 	else
 		BGE_CLRBIT(sc, BGE_RX_MODE, BGE_RXMODE_RX_PROMISC);
 }
 
 static void
+bge_hash_maddr(void *arg, struct sockaddr *maddr)
+{
+	struct sockaddr_dl *sdl = (struct sockaddr_dl *)maddr;
+	uint32_t *hashes = arg;
+	int h;
+
+	if (sdl->sdl_family != AF_LINK)
+		return;
+
+	h = ether_crc32_le(LLADDR(sdl), ETHER_ADDR_LEN) & 0x7F;
+	hashes[(h & 0x60) >> 5] |= 1 << (h & 0x1F);
+}
+
+static void
 bge_setmulti(struct bge_softc *sc)
 {
 	if_t ifp;
-	int mc_count = 0;
 	uint32_t hashes[4] = { 0, 0, 0, 0 };
-	int h, i, mcnt;
-	unsigned char *mta;
+	int i;
 
 	BGE_LOCK_ASSERT(sc);
 
 	ifp = sc->bge_ifp;
 
-	mc_count = if_multiaddr_count(ifp, -1);
-	mta = malloc(sizeof(unsigned char) *  ETHER_ADDR_LEN *
-	    mc_count, M_DEVBUF, M_NOWAIT);
-
-	if(mta == NULL) {
-		device_printf(sc->bge_dev, 
-		    "Failed to allocated temp mcast list\n");
-		return;
-	}
-
-	if (if_getflags(ifp) & IFF_ALLMULTI || if_getflags(ifp) & IFF_PROMISC) {
+	if (if_get(ifp, IF_FLAGS) & (IFF_ALLMULTI | IFF_PROMISC)) {
 		for (i = 0; i < 4; i++)
 			CSR_WRITE_4(sc, BGE_MAR0 + (i * 4), 0xFFFFFFFF);
 		return;
@@ -1644,17 +1682,10 @@ bge_setmulti(struct bge_softc *sc)
 	for (i = 0; i < 4; i++)
 		CSR_WRITE_4(sc, BGE_MAR0 + (i * 4), 0);
 
-	if_multiaddr_array(ifp, mta, &mcnt, mc_count);
-	for(i = 0; i < mcnt; i++) {
-		h = ether_crc32_le(mta + (i * ETHER_ADDR_LEN),
-		    ETHER_ADDR_LEN) & 0x7F;
-		hashes[(h & 0x60) >> 5] |= 1 << (h & 0x1F);
-	}
+	if_foreach_maddr(ifp, bge_hash_maddr, hashes);
 
 	for (i = 0; i < 4; i++)
 		CSR_WRITE_4(sc, BGE_MAR0 + (i * 4), hashes[i]);
-
-	free(mta, M_DEVBUF);
 }
 
 static void
@@ -1667,7 +1698,7 @@ bge_setvlan(struct bge_softc *sc)
 	ifp = sc->bge_ifp;
 
 	/* Enable or disable VLAN tag stripping as needed. */
-	if (if_getcapenable(ifp) & IFCAP_VLAN_HWTAGGING)
+	if (if_get(ifp, IF_CAPENABLE) & IFCAP_VLAN_HWTAGGING)
 		BGE_CLRBIT(sc, BGE_RX_MODE, BGE_RXMODE_RX_KEEP_VLAN_DIAG);
 	else
 		BGE_SETBIT(sc, BGE_RX_MODE, BGE_RXMODE_RX_KEEP_VLAN_DIAG);
@@ -2001,7 +2032,7 @@ bge_blockinit(struct bge_softc *sc)
 	/* Configure mbuf pool watermarks */
 	if (BGE_IS_5717_PLUS(sc)) {
 		CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x0);
-		if (if_getmtu(sc->bge_ifp) > ETHERMTU) {
+		if (if_get(sc->bge_ifp, IF_MTU) > ETHERMTU) {
 			CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x7e);
 			CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0xea);
 		} else {
@@ -2318,9 +2349,9 @@ bge_blockinit(struct bge_softc *sc)
 
 	/* Set random backoff seed for TX */
 	CSR_WRITE_4(sc, BGE_TX_RANDOM_BACKOFF,
-	    (IF_LLADDR(sc->bge_ifp)[0] + IF_LLADDR(sc->bge_ifp)[1] +
-	    IF_LLADDR(sc->bge_ifp)[2] + IF_LLADDR(sc->bge_ifp)[3] +
-	    IF_LLADDR(sc->bge_ifp)[4] + IF_LLADDR(sc->bge_ifp)[5]) &
+	    (if_lladdr(sc->bge_ifp)[0] + if_lladdr(sc->bge_ifp)[1] +
+	    if_lladdr(sc->bge_ifp)[2] + if_lladdr(sc->bge_ifp)[3] +
+	    if_lladdr(sc->bge_ifp)[4] + if_lladdr(sc->bge_ifp)[5]) &
 	    BGE_TX_BACKOFF_SEED_MASK);
 
 	/* Set inter-packet gap */
@@ -3301,7 +3332,13 @@ bge_devinfo(struct bge_softc *sc)
 static int
 bge_attach(device_t dev)
 {
-	if_t ifp;
+	struct if_attach_args ifat = {
+		.ifat_version = IF_ATTACH_VERSION,
+		.ifat_drv = &bge_ifdrv,
+		.ifat_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST,
+		.ifat_capabilities = IFCAP_HWCSUM | IFCAP_VLAN_HWTAGGING |
+		    IFCAP_VLAN_MTU | IFCAP_VLAN_HWCSUM,
+	};
 	struct bge_softc *sc;
 	uint32_t hwcfg = 0, misccfg, pcistate;
 	u_char eaddr[ETHER_ADDR_LEN];
@@ -3723,47 +3760,6 @@ bge_attach(device_t dev)
 	if (sc->bge_forced_udpcsum != 0)
 		sc->bge_csum_features |= CSUM_UDP;
 
-	/* Set up ifnet structure */
-	ifp = sc->bge_ifp = if_alloc(IFT_ETHER);
-	if (ifp == NULL) {
-		device_printf(sc->bge_dev, "failed to if_alloc()\n");
-		error = ENXIO;
-		goto fail;
-	}
-	if_setsoftc(ifp, sc);
-	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
-	if_setflags(ifp, IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST);
-	if_setioctlfn(ifp, bge_ioctl);
-	if_setstartfn(ifp, bge_start);
-	if_setinitfn(ifp, bge_init);
-	if_setgetcounterfn(ifp, bge_get_counter);
-	if_setsendqlen(ifp, BGE_TX_RING_CNT - 1);
-	if_setsendqready(ifp);
-	if_sethwassist(ifp, sc->bge_csum_features);
-	if_setcapabilities(ifp, IFCAP_HWCSUM | IFCAP_VLAN_HWTAGGING |
-	    IFCAP_VLAN_MTU);
-	if ((sc->bge_flags & (BGE_FLAG_TSO | BGE_FLAG_TSO3)) != 0) {
-		if_sethwassistbits(ifp, CSUM_TSO, 0);
-		if_setcapabilitiesbit(ifp, IFCAP_TSO4 | IFCAP_VLAN_HWTSO, 0);
-	}
-#ifdef IFCAP_VLAN_HWCSUM
-	if_setcapabilitiesbit(ifp, IFCAP_VLAN_HWCSUM, 0);
-#endif
-	if_setcapenable(ifp, if_getcapabilities(ifp));
-#ifdef DEVICE_POLLING
-	if_setcapabilitiesbit(ifp, IFCAP_POLLING, 0);
-#endif
-
-	/*
-	 * 5700 B0 chips do not support checksumming correctly due
-	 * to hardware bugs.
-	 */
-	if (sc->bge_chipid == BGE_CHIPID_BCM5700_B0) {
-		if_setcapabilitiesbit(ifp, 0, IFCAP_HWCSUM);
-		if_setcapenablebit(ifp, 0, IFCAP_HWCSUM);
-		if_sethwassist(ifp, 0);
-	}
-
 	/*
 	 * Figure out what sort of media we have by checking the
 	 * hardware config word in the first 32k of NIC internal memory,
@@ -3857,7 +3853,7 @@ bge_attach(device_t dev)
 again:
 		bge_asf_driver_up(sc);
 
-		error = mii_attach(dev, &sc->bge_miibus, ifp, 
+		error = mii_attach(dev, &sc->bge_miibus,
 		    (ifm_change_cb_t)bge_ifmedia_upd,
 		    (ifm_stat_cb_t)bge_ifmedia_sts, capmask, sc->bge_phy_addr, 
 		    MII_OFFSET_ANY, MIIF_DOPAUSE);
@@ -3892,14 +3888,6 @@ again:
                 sc->bge_flags |= BGE_FLAG_RX_ALIGNBUG;
 
 	/*
-	 * Call MI attach routine.
-	 */
-	ether_ifattach(ifp, eaddr);
-
-	/* Tell upper layer we support long frames. */
-	if_setifheaderlen(ifp, sizeof(struct ether_vlan_header));
-
-	/*
 	 * Hookup IRQ last.
 	 */
 	if (BGE_IS_5755_PLUS(sc) && sc->bge_flags & BGE_FLAG_MSI) {
@@ -3910,7 +3898,6 @@ again:
 		    taskqueue_thread_enqueue, &sc->bge_tq);
 		if (sc->bge_tq == NULL) {
 			device_printf(dev, "could not create taskqueue.\n");
-			ether_ifdetach(ifp);
 			error = ENOMEM;
 			goto fail;
 		}
@@ -3918,7 +3905,6 @@ again:
 		    "%s taskq", device_get_nameunit(sc->bge_dev));
 		if (error != 0) {
 			device_printf(dev, "could not start threads.\n");
-			ether_ifdetach(ifp);
 			goto fail;
 		}
 		error = bus_setup_intr(dev, sc->bge_irq,
@@ -3930,13 +3916,39 @@ again:
 		    &sc->bge_intrhand);
 
 	if (error) {
-		ether_ifdetach(ifp);
 		device_printf(sc->bge_dev, "couldn't set up irq\n");
+		goto fail;
 	}
 
+	/* Attach interface. */
+	ifat.ifat_softc = sc;
+	ifat.ifat_dunit = device_get_unit(dev);
+	ifat.ifat_lla = eaddr;
+	ifat.ifat_hwassist = sc->bge_csum_features;
+	if ((sc->bge_flags & (BGE_FLAG_TSO | BGE_FLAG_TSO3)) != 0) {
+		ifat.ifat_hwassist |= CSUM_TSO;
+		ifat.ifat_capabilities |= IFCAP_TSO4 | IFCAP_VLAN_HWTSO;
+	}
+	ifat.ifat_capenable = ifat.ifat_capabilities;
+#ifdef DEVICE_POLLING
+	ifat.ifat_capabilities |= IFCAP_POLLING;
+#endif
+	/*
+	 * 5700 B0 chips do not support checksumming correctly due
+	 * to hardware bugs.
+	 */
+	if (sc->bge_chipid == BGE_CHIPID_BCM5700_B0) {
+		ifat.ifat_capabilities &= ~IFCAP_HWCSUM;
+		ifat.ifat_capenable &= ~IFCAP_HWCSUM;
+		ifat.ifat_hwassist = 0;
+	}
+
+	sc->bge_ifp = if_attach(&ifat);
+
+	return (0);
+
 fail:
-	if (error)
-		bge_detach(dev);
+	bge_detach(dev);
 	return (error);
 }
 
@@ -3950,12 +3962,12 @@ bge_detach(device_t dev)
 	ifp = sc->bge_ifp;
 
 #ifdef DEVICE_POLLING
-	if (if_getcapenable(ifp) & IFCAP_POLLING)
+	if (if_get(ifp, IF_CAPENABLE) & IFCAP_POLLING)
 		ether_poll_deregister(ifp);
 #endif
 
 	if (device_is_attached(dev)) {
-		ether_ifdetach(ifp);
+		if_detach(ifp);
 		BGE_LOCK(sc);
 		bge_stop(sc);
 		BGE_UNLOCK(sc);
@@ -4004,9 +4016,6 @@ bge_release_resources(struct bge_softc *
 		bus_release_resource(dev, SYS_RES_MEMORY,
 		    rman_get_rid(sc->bge_res2), sc->bge_res2);
 
-	if (sc->bge_ifp != NULL)
-		if_free(sc->bge_ifp);
-
 	bge_dma_free(sc);
 
 	if (mtx_initialized(&sc->bge_mtx))	/* XXX */
@@ -4323,7 +4332,7 @@ bge_rxeof(struct bge_softc *sc, uint16_t
 	bus_dmamap_sync(sc->bge_cdata.bge_rx_std_ring_tag,
 	    sc->bge_cdata.bge_rx_std_ring_map, BUS_DMASYNC_POSTWRITE);
 	if (BGE_IS_JUMBO_CAPABLE(sc) &&
-	    if_getmtu(ifp) + ETHER_HDR_LEN + ETHER_CRC_LEN + 
+	    if_get(ifp, IF_MTU) + ETHER_HDR_LEN + ETHER_CRC_LEN + 
 	    ETHER_VLAN_ENCAP_LEN > (MCLBYTES - ETHER_ALIGN))
 		bus_dmamap_sync(sc->bge_cdata.bge_rx_jumbo_ring_tag,
 		    sc->bge_cdata.bge_rx_jumbo_ring_map, BUS_DMASYNC_POSTWRITE);
@@ -4336,7 +4345,7 @@ bge_rxeof(struct bge_softc *sc, uint16_t
 		int			have_tag = 0;
 
 #ifdef DEVICE_POLLING
-		if (if_getcapenable(ifp) & IFCAP_POLLING) {
+		if (if_get(ifp, IF_CAPENABLE) & IFCAP_POLLING) {
 			if (sc->rxcycles <= 0)
 				break;
 			sc->rxcycles--;
@@ -4348,7 +4357,7 @@ bge_rxeof(struct bge_softc *sc, uint16_t
 		rxidx = cur_rx->bge_idx;
 		BGE_INC(rx_cons, sc->bge_return_ring_cnt);
 
-		if (if_getcapenable(ifp) & IFCAP_VLAN_HWTAGGING &&
+		if (if_get(ifp, IF_CAPENABLE) & IFCAP_VLAN_HWTAGGING &&
 		    cur_rx->bge_flags & BGE_RXBDFLAG_VLAN_TAG) {
 			have_tag = 1;
 			vlan_tag = cur_rx->bge_vlan_tag;
@@ -4397,7 +4406,7 @@ bge_rxeof(struct bge_softc *sc, uint16_t
 		m->m_pkthdr.len = m->m_len = cur_rx->bge_len - ETHER_CRC_LEN;
 		m->m_pkthdr.rcvif = ifp;
 
-		if (if_getcapenable(ifp) & IFCAP_RXCSUM)
+		if (if_get(ifp, IF_CAPENABLE) & IFCAP_RXCSUM)
 			bge_rxcsum(sc, cur_rx, m);
 
 		/*
@@ -4417,7 +4426,7 @@ bge_rxeof(struct bge_softc *sc, uint16_t
 			if_input(ifp, m);
 		rx_npkts++;
 
-		if (!(if_getdrvflags(ifp) & IFF_DRV_RUNNING))
+		if (!(sc->bge_flags & BGE_FLAG_RUNNING))
 			return (rx_npkts);
 	}
 
@@ -4513,19 +4522,22 @@ bge_txeof(struct bge_softc *sc, uint16_t
 		if (cur_tx->bge_flags & BGE_TXBDFLAG_END)
 			if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
 		if (sc->bge_cdata.bge_tx_chain[idx] != NULL) {
+			struct mbuf *m;
+
 			bus_dmamap_sync(sc->bge_cdata.bge_tx_mtag,
 			    sc->bge_cdata.bge_tx_dmamap[idx],
 			    BUS_DMASYNC_POSTWRITE);
 			bus_dmamap_unload(sc->bge_cdata.bge_tx_mtag,
 			    sc->bge_cdata.bge_tx_dmamap[idx]);
-			m_freem(sc->bge_cdata.bge_tx_chain[idx]);
+
+			m = sc->bge_cdata.bge_tx_chain[idx];
 			sc->bge_cdata.bge_tx_chain[idx] = NULL;
+			if_inc_counter(ifp, IFCOUNTER_OBYTES, m->m_pkthdr.len);
+			m_freem(m);
 		}
 		sc->bge_txcnt--;
 		BGE_INC(sc->bge_tx_saved_considx, BGE_TX_RING_CNT);
 	}
-
-	if_setdrvflagbits(ifp, 0, IFF_DRV_OACTIVE);
 	if (sc->bge_txcnt == 0)
 		sc->bge_timer = 0;
 }
@@ -4534,13 +4546,13 @@ bge_txeof(struct bge_softc *sc, uint16_t
 static int
 bge_poll(if_t ifp, enum poll_cmd cmd, int count)
 {
-	struct bge_softc *sc = if_getsoftc(ifp);
+	struct bge_softc *sc = if_getsoftc(ifp, IF_DRIVER_SOFTC);
 	uint16_t rx_prod, tx_cons;
 	uint32_t statusword;
 	int rx_npkts = 0;
 
 	BGE_LOCK(sc);
-	if (!(if_getdrvflags(ifp) & IFF_DRV_RUNNING)) {
+	if (!(sc->bge_flags & BGE_FLAG_RUNNING)) {
 		BGE_UNLOCK(sc);
 		return (rx_npkts);
 	}
@@ -4572,13 +4584,13 @@ bge_poll(if_t ifp, enum poll_cmd cmd, in
 
 	sc->rxcycles = count;
 	rx_npkts = bge_rxeof(sc, rx_prod, 1);
-	if (!(if_getdrvflags(ifp) & IFF_DRV_RUNNING)) {
+	if (!(sc->bge_flags & BGE_FLAG_RUNNING)) {
 		BGE_UNLOCK(sc);
 		return (rx_npkts);
 	}
 	bge_txeof(sc, tx_cons);
-	if (!if_sendq_empty(ifp))
-		bge_start_locked(ifp);
+	if (if_snd_len(ifp))
+		bge_start_locked(sc);
 
 	BGE_UNLOCK(sc);
 	return (rx_npkts);
@@ -4611,7 +4623,7 @@ bge_intr_task(void *arg, int pending)
 	ifp = sc->bge_ifp;
 
 	BGE_LOCK(sc);
-	if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) == 0) {
+	if ((sc->bge_flags & BGE_FLAG_RUNNING) == 0) {
 		BGE_UNLOCK(sc);
 		return;
 	}
@@ -4640,18 +4652,18 @@ bge_intr_task(void *arg, int pending)
 	/* Let controller work. */
 	bge_writembx(sc, BGE_MBX_IRQ0_LO, status_tag);
 
-	if (if_getdrvflags(ifp) & IFF_DRV_RUNNING &&
+	if (sc->bge_flags & BGE_FLAG_RUNNING &&
 	    sc->bge_rx_saved_considx != rx_prod) {
 		/* Check RX return ring producer/consumer. */
 		BGE_UNLOCK(sc);
 		bge_rxeof(sc, rx_prod, 0);
 		BGE_LOCK(sc);
 	}
-	if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
+	if (sc->bge_flags & BGE_FLAG_RUNNING) {
 		/* Check TX ring producer/consumer. */
 		bge_txeof(sc, tx_cons);
-		if (!if_sendq_empty(ifp))
-			bge_start_locked(ifp);
+		if (if_snd_len(ifp))
+			bge_start_locked(sc);
 	}
 	BGE_UNLOCK(sc);
 }
@@ -4671,7 +4683,7 @@ bge_intr(void *xsc)
 	ifp = sc->bge_ifp;
 
 #ifdef DEVICE_POLLING
-	if (if_getcapenable(ifp) & IFCAP_POLLING) {
+	if (if_get(ifp, IF_CAPENABLE) & IFCAP_POLLING) {
 		BGE_UNLOCK(sc);
 		return;
 	}
@@ -4720,19 +4732,18 @@ bge_intr(void *xsc)
 	    statusword || sc->bge_link_evt)
 		bge_link_upd(sc);
 
-	if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
+	if (sc->bge_flags & BGE_FLAG_RUNNING) {
 		/* Check RX return ring producer/consumer. */
 		bge_rxeof(sc, rx_prod, 1);
 	}
 
-	if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
+	if (sc->bge_flags & BGE_FLAG_RUNNING) {
 		/* Check TX ring producer/consumer. */
 		bge_txeof(sc, tx_cons);
 	}
 
-	if (if_getdrvflags(ifp) & IFF_DRV_RUNNING &&
-	    !if_sendq_empty(ifp))
-		bge_start_locked(ifp);
+	if (sc->bge_flags & BGE_FLAG_RUNNING && if_snd_len(ifp))
+		bge_start_locked(sc);
 
 	BGE_UNLOCK(sc);
 }
@@ -5332,52 +5343,37 @@ bge_encap(struct bge_softc *sc, struct m
  * Main transmit routine. To avoid having to do mbuf copies, we put pointers
  * to the mbuf data regions directly in the transmit descriptors.
  */
-static void
-bge_start_locked(if_t ifp)
+static int
+bge_start_locked(struct bge_softc *sc)
 {
-	struct bge_softc *sc;
-	struct mbuf *m_head;
+	if_t ifp;
+	struct mbuf *m;
 	uint32_t prodidx;
-	int count;
+	int error, count;
 
-	sc = if_getsoftc(ifp);
 	BGE_LOCK_ASSERT(sc);
 
-	if (!sc->bge_link ||
-	    (if_getdrvflags(ifp) & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
-	    IFF_DRV_RUNNING)
-		return;
+	if (!sc->bge_link || (sc->bge_flags & BGE_FLAG_RUNNING) == 0)
+		return (ENETDOWN);
 
+	ifp = sc->bge_ifp;
 	prodidx = sc->bge_tx_prodidx;
-
-	for (count = 0; !if_sendq_empty(ifp);) {
-		if (sc->bge_txcnt > BGE_TX_RING_CNT - 16) {
-			if_setdrvflagbits(ifp, IFF_DRV_OACTIVE, 0);
-			break;
-		}
-		m_head = if_dequeue(ifp);
-		if (m_head == NULL)
-			break;
-
+	error = count = 0;
+	while (sc->bge_txcnt <= BGE_TX_RING_CNT - 16 &&
+	    (m = if_snd_dequeue(ifp)) != NULL) {
 		/*
 		 * Pack the data into the transmit ring. If we
 		 * don't have room, set the OACTIVE flag and wait
 		 * for the NIC to drain the ring.
 		 */
-		if (bge_encap(sc, &m_head, &prodidx)) {
-			if (m_head == NULL)
+		if (bge_encap(sc, &m, &prodidx)) {
+			if (m == NULL)
 				break;
-			if_sendq_prepend(ifp, m_head);
-			if_setdrvflagbits(ifp, IFF_DRV_OACTIVE, 0);
+			if_snd_prepend(ifp, m);
 			break;
 		}
 		++count;
-
-		/*
-		 * If there's a BPF listener, bounce a copy of this frame
-		 * to him.
-		 */
-		if_bpfmtap(ifp, m_head);
+		if_mtap(ifp, m, NULL, 0);
 	}
 
 	if (count > 0) {
@@ -5396,21 +5392,29 @@ bge_start_locked(if_t ifp)
 		 */
 		sc->bge_timer = BGE_TX_TIMEOUT;
 	}
+	
+	return (0);
 }
 
 /*
  * Main transmit routine. To avoid having to do mbuf copies, we put pointers
  * to the mbuf data regions directly in the transmit descriptors.
  */
-static void
-bge_start(if_t ifp)
+static int
+bge_transmit(if_t ifp, struct mbuf *m)
 {
 	struct bge_softc *sc;
+	int error;
 
-	sc = if_getsoftc(ifp);
-	BGE_LOCK(sc);
-	bge_start_locked(ifp);
+	if ((error = if_snd_enqueue(ifp, m)) != 0)
+		return (error);
+
+	sc = if_getsoftc(ifp, IF_DRIVER_SOFTC);
+	if (BGE_TRYLOCK(sc) == 0)
+		return (0);
+	error = bge_start_locked(sc);
 	BGE_UNLOCK(sc);
+	return (error);
 }
 
 static void
@@ -5424,7 +5428,7 @@ bge_init_locked(struct bge_softc *sc)
 
 	ifp = sc->bge_ifp;
 
-	if (if_getdrvflags(ifp) & IFF_DRV_RUNNING)
+	if (sc->bge_flags & BGE_FLAG_RUNNING)
 		return;
 
 	/* Cancel pending I/O and flush buffers. */
@@ -5450,12 +5454,12 @@ bge_init_locked(struct bge_softc *sc)
 	ifp = sc->bge_ifp;
 
 	/* Specify MTU. */
-	CSR_WRITE_4(sc, BGE_RX_MTU, if_getmtu(ifp) +
+	CSR_WRITE_4(sc, BGE_RX_MTU, if_get(ifp, IF_MTU) +
 	    ETHER_HDR_LEN + ETHER_CRC_LEN +
-	    (if_getcapenable(ifp) & IFCAP_VLAN_MTU ? ETHER_VLAN_ENCAP_LEN : 0));
+	    (if_get(ifp, IF_CAPENABLE) & IFCAP_VLAN_MTU ? ETHER_VLAN_ENCAP_LEN : 0));
 
 	/* Load our MAC address. */
-	m = (uint16_t *)IF_LLADDR(sc->bge_ifp);
+	m = (uint16_t *)if_lladdr(sc->bge_ifp);
 	CSR_WRITE_4(sc, BGE_MAC_ADDR1_LO, htons(m[0]));
 	CSR_WRITE_4(sc, BGE_MAC_ADDR1_HI, (htons(m[1]) << 16) | htons(m[2]));
 
@@ -5473,10 +5477,10 @@ bge_init_locked(struct bge_softc *sc)
 		sc->bge_csum_features &= ~CSUM_UDP;
 	else
 		sc->bge_csum_features |= CSUM_UDP;
-	if (if_getcapabilities(ifp) & IFCAP_TXCSUM &&
-	    if_getcapenable(ifp) & IFCAP_TXCSUM) {
-		if_sethwassistbits(ifp, 0, (BGE_CSUM_FEATURES | CSUM_UDP));
-		if_sethwassistbits(ifp, sc->bge_csum_features, 0);
+	if (if_get(ifp, IF_CAPABILITIES) & IFCAP_TXCSUM &&
+	    if_get(ifp, IF_CAPENABLE) & IFCAP_TXCSUM) {
+		if_clrflags(ifp, IF_CAPABILITIES, BGE_CSUM_FEATURES | CSUM_UDP);
+		if_addflags(ifp, IF_CAPABILITIES, sc->bge_csum_features);
 	}
 
 	/* Init RX ring. */
@@ -5506,7 +5510,7 @@ bge_init_locked(struct bge_softc *sc)
 
 	/* Init jumbo RX ring. */
 	if (BGE_IS_JUMBO_CAPABLE(sc) &&
-	    if_getmtu(ifp) + ETHER_HDR_LEN + ETHER_CRC_LEN + 
+	    if_get(ifp, IF_MTU) + ETHER_HDR_LEN + ETHER_CRC_LEN + 
      	    ETHER_VLAN_ENCAP_LEN > (MCLBYTES - ETHER_ALIGN)) {
 		if (bge_init_rx_ring_jumbo(sc) != 0) {
 			device_printf(sc->bge_dev,
@@ -5568,7 +5572,7 @@ bge_init_locked(struct bge_softc *sc)
 
 #ifdef DEVICE_POLLING
 	/* Disable interrupts if we are polling. */
-	if (if_getcapenable(ifp) & IFCAP_POLLING) {
+	if (if_get(ifp, IF_CAPENABLE) & IFCAP_POLLING) {
 		BGE_SETBIT(sc, BGE_PCI_MISC_CTL,
 		    BGE_PCIMISCCTL_MASK_PCI_INTR);
 		bge_writembx(sc, BGE_MBX_IRQ0_LO, 1);
@@ -5582,8 +5586,7 @@ bge_init_locked(struct bge_softc *sc)
 	bge_writembx(sc, BGE_MBX_IRQ0_LO, 0);
 	}
 
-	if_setdrvflagbits(ifp, IFF_DRV_RUNNING, 0);
-	if_setdrvflagbits(ifp, 0, IFF_DRV_OACTIVE);
+	sc->bge_flags |= BGE_FLAG_RUNNING;
 
 	bge_ifmedia_upd_locked(ifp);
 
@@ -5606,7 +5609,7 @@ bge_init(void *xsc)
 static int
 bge_ifmedia_upd(if_t ifp)
 {
-	struct bge_softc *sc = if_getsoftc(ifp);
+	struct bge_softc *sc = if_getsoftc(ifp, IF_DRIVER_SOFTC);
 	int res;
 
 	BGE_LOCK(sc);
@@ -5619,7 +5622,7 @@ bge_ifmedia_upd(if_t ifp)
 static int
 bge_ifmedia_upd_locked(if_t ifp)
 {
-	struct bge_softc *sc = if_getsoftc(ifp);
+	struct bge_softc *sc = if_getsoftc(ifp, IF_DRIVER_SOFTC);
 	struct mii_data *mii;
 	struct mii_softc *miisc;
 	struct ifmedia *ifm;
@@ -5704,12 +5707,12 @@ bge_ifmedia_upd_locked(if_t ifp)
 static void
 bge_ifmedia_sts(if_t ifp, struct ifmediareq *ifmr)
 {
-	struct bge_softc *sc = if_getsoftc(ifp);
+	struct bge_softc *sc = if_getsoftc(ifp, IF_DRIVER_SOFTC);
 	struct mii_data *mii;
 
 	BGE_LOCK(sc);
 
-	if ((if_getflags(ifp) & IFF_UP) == 0) {
+	if ((if_get(ifp, IF_FLAGS) & IFF_UP) == 0) {
 		BGE_UNLOCK(sc);
 		return;
 	}
@@ -5744,7 +5747,7 @@ bge_ifmedia_sts(if_t ifp, struct ifmedia
 static int
 bge_ioctl(if_t ifp, u_long command, caddr_t data)
 {
-	struct bge_softc *sc = if_getsoftc(ifp);
+	struct bge_softc *sc = if_getsoftc(ifp, IF_DRIVER_SOFTC);
 	struct ifreq *ifr = (struct ifreq *) data;
 	struct mii_data *mii;
 	int flags, mask, error = 0;
@@ -5763,10 +5766,10 @@ bge_ioctl(if_t ifp, u_long command, cadd
 			break;
 		}
 		BGE_LOCK(sc);
-		if (if_getmtu(ifp) != ifr->ifr_mtu) {
-			if_setmtu(ifp, ifr->ifr_mtu);
-			if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
-				if_setdrvflagbits(ifp, 0, IFF_DRV_RUNNING);
+		if (if_get(ifp, IF_MTU) != ifr->ifr_mtu) {
+			if_set(ifp, IF_MTU, ifr->ifr_mtu);
+			if (sc->bge_flags & BGE_FLAG_RUNNING) {
+				sc->bge_flags &= ~BGE_FLAG_RUNNING;
 				bge_init_locked(sc);
 			}
 		}
@@ -5774,7 +5777,7 @@ bge_ioctl(if_t ifp, u_long command, cadd
 		break;
 	case SIOCSIFFLAGS:
 		BGE_LOCK(sc);
-		if (if_getflags(ifp) & IFF_UP) {
+		if (if_get(ifp, IF_FLAGS) & IFF_UP) {
 			/*
 			 * If only the state of the PROMISC flag changed,
 			 * then just use the 'set promisc mode' command
@@ -5783,8 +5786,9 @@ bge_ioctl(if_t ifp, u_long command, cadd
 			 * waiting for it to start up, which may take a
 			 * second or two.  Similarly for ALLMULTI.
 			 */
-			if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
-				flags = if_getflags(ifp) ^ sc->bge_if_flags;
+			if (sc->bge_flags & BGE_FLAG_RUNNING) {
+				flags = if_get(ifp, IF_FLAGS) ^
+				    sc->bge_if_flags;
 				if (flags & IFF_PROMISC)
 					bge_setpromisc(sc);
 				if (flags & IFF_ALLMULTI)
@@ -5792,17 +5796,17 @@ bge_ioctl(if_t ifp, u_long command, cadd
 			} else
 				bge_init_locked(sc);
 		} else {
-			if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
+			if (sc->bge_flags & BGE_FLAG_RUNNING) {
 				bge_stop(sc);
 			}
 		}
-		sc->bge_if_flags = if_getflags(ifp);
+		sc->bge_if_flags = if_get(ifp, IF_FLAGS);
 		BGE_UNLOCK(sc);
 		error = 0;
 		break;
 	case SIOCADDMULTI:
 	case SIOCDELMULTI:
-		if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
+		if (sc->bge_flags & BGE_FLAG_RUNNING) {
 			BGE_LOCK(sc);
 			bge_setmulti(sc);
 			BGE_UNLOCK(sc);
@@ -5821,7 +5825,7 @@ bge_ioctl(if_t ifp, u_long command, cadd
 		}
 		break;
 	case SIOCSIFCAP:
-		mask = ifr->ifr_reqcap ^ if_getcapenable(ifp);
+		mask = ifr->ifr_reqcap ^ if_get(ifp, IF_CAPENABLE);
 #ifdef DEVICE_POLLING
 		if (mask & IFCAP_POLLING) {
 			if (ifr->ifr_reqcap & IFCAP_POLLING) {
@@ -5847,53 +5851,50 @@ bge_ioctl(if_t ifp, u_long command, cadd
 		}
 #endif
 		if ((mask & IFCAP_TXCSUM) != 0 &&
-		    (if_getcapabilities(ifp) & IFCAP_TXCSUM) != 0) {
-			if_togglecapenable(ifp, IFCAP_TXCSUM);
-			if ((if_getcapenable(ifp) & IFCAP_TXCSUM) != 0)
-				if_sethwassistbits(ifp,
-				    sc->bge_csum_features, 0);
+		    (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,
+				    sc->bge_csum_features);
 			else
-				if_sethwassistbits(ifp, 0,
+				if_clrflags(ifp, IF_HWASSIST,
 				    sc->bge_csum_features);
 		}
 
 		if ((mask & IFCAP_RXCSUM) != 0 &&
-		    (if_getcapabilities(ifp) & IFCAP_RXCSUM) != 0)
-			if_togglecapenable(ifp, IFCAP_RXCSUM);
+		    (if_get(ifp, IF_CAPABILITIES) & IFCAP_RXCSUM) != 0)
+			if_xorflags(ifp, IF_CAPENABLE, IFCAP_RXCSUM);
 
 		if ((mask & IFCAP_TSO4) != 0 &&
-		    (if_getcapabilities(ifp) & IFCAP_TSO4) != 0) {
-			if_togglecapenable(ifp, IFCAP_TSO4);
-			if ((if_getcapenable(ifp) & IFCAP_TSO4) != 0)
-				if_sethwassistbits(ifp, CSUM_TSO, 0);
+		    (if_get(ifp, IF_CAPABILITIES) & IFCAP_TSO4) != 0) {
+			if_xorflags(ifp, IF_CAPENABLE, IFCAP_TSO4);
+			if ((if_get(ifp, IF_CAPENABLE) & IFCAP_TSO4) != 0)
+				if_addflags(ifp, IF_HWASSIST, CSUM_TSO);
 			else
-				if_sethwassistbits(ifp, 0, CSUM_TSO);
+				if_clrflags(ifp, IF_HWASSIST, CSUM_TSO);
 		}
 
 		if (mask & IFCAP_VLAN_MTU) {
-			if_togglecapenable(ifp, IFCAP_VLAN_MTU);
-			if_setdrvflagbits(ifp, 0, IFF_DRV_RUNNING);
+			if_xorflags(ifp, IF_CAPENABLE, IFCAP_VLAN_MTU);
+			sc->bge_flags &= ~BGE_FLAG_RUNNING;
 			bge_init(sc);
 		}
 
 		if ((mask & IFCAP_VLAN_HWTSO) != 0 &&
-		    (if_getcapabilities(ifp) & IFCAP_VLAN_HWTSO) != 0)
-			if_togglecapenable(ifp, IFCAP_VLAN_HWTSO);
+		    (if_get(ifp, IF_CAPABILITIES) & IFCAP_VLAN_HWTSO) != 0)
+			if_xorflags(ifp, IF_CAPENABLE, IFCAP_VLAN_HWTSO);
 		if ((mask & IFCAP_VLAN_HWTAGGING) != 0 &&
-		    (if_getcapabilities(ifp) & IFCAP_VLAN_HWTAGGING) != 0) {
-			if_togglecapenable(ifp, IFCAP_VLAN_HWTAGGING);
-			if ((if_getcapenable(ifp) & IFCAP_VLAN_HWTAGGING) == 0)
-				if_setcapenablebit(ifp, 0, IFCAP_VLAN_HWTSO);
+		    (if_get(ifp, IF_CAPABILITIES) & IFCAP_VLAN_HWTAGGING) != 0) {
+			if_xorflags(ifp, IF_CAPENABLE, IFCAP_VLAN_HWTAGGING);
+			if ((if_get(ifp, IF_CAPENABLE) & IFCAP_VLAN_HWTAGGING) == 0)
+				if_clrflags(ifp, IF_CAPENABLE, IFCAP_VLAN_HWTSO);
 			BGE_LOCK(sc);
 			bge_setvlan(sc);
 			BGE_UNLOCK(sc);
 		}
-#ifdef VLAN_CAPABILITIES
-		if_vlancap(ifp);
-#endif
 		break;
 	default:
-		error = ether_ioctl(ifp, command, data);
+		error = EOPNOTSUPP;
 		break;
 	}
 
@@ -5942,7 +5943,7 @@ bge_watchdog(struct bge_softc *sc)
 
 	if_printf(ifp, "watchdog timeout -- resetting\n");
 
-	if_setdrvflagbits(ifp, 0, IFF_DRV_RUNNING);
+	sc->bge_flags &= ~BGE_FLAG_RUNNING;
 	bge_init_locked(sc);
 
 	if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
@@ -6058,8 +6059,7 @@ bge_stop(struct bge_softc *sc)
 	if (bootverbose && sc->bge_link)
 		if_printf(sc->bge_ifp, "link DOWN\n");
 	sc->bge_link = 0;
-
-	if_setdrvflagbits(ifp, 0, (IFF_DRV_RUNNING | IFF_DRV_OACTIVE));
+	sc->bge_flags &= ~BGE_FLAG_RUNNING;
 }
 
 /*
@@ -6101,10 +6101,10 @@ bge_resume(device_t dev)
 	sc = device_get_softc(dev);
 	BGE_LOCK(sc);
 	ifp = sc->bge_ifp;
-	if (if_getflags(ifp) & IFF_UP) {
+	if (if_get(ifp, IF_FLAGS) & IFF_UP) {
 		bge_init_locked(sc);
-		if (if_getdrvflags(ifp) & IFF_DRV_RUNNING)
-			bge_start_locked(ifp);
+		if (sc->bge_flags & BGE_FLAG_RUNNING)
+			bge_start_locked(sc);
 	}
 	BGE_UNLOCK(sc);
 
@@ -6772,7 +6772,7 @@ bge_get_counter(if_t ifp, ift_counter cn
 	struct bge_softc *sc;
 	struct bge_mac_stats *stats;
 
-	sc = if_getsoftc(ifp);
+	sc = if_getsoftc(ifp, IF_DRIVER_SOFTC);
 	if (!BGE_IS_5705_PLUS(sc))
 		return (if_get_counter_default(ifp, cnt));
 	stats = &sc->bge_mac_stats;

Modified: projects/ifnet/sys/dev/bge/if_bgereg.h
==============================================================================
--- projects/ifnet/sys/dev/bge/if_bgereg.h	Wed Jan 14 19:46:05 2015	(r277191)
+++ projects/ifnet/sys/dev/bge/if_bgereg.h	Wed Jan 14 19:47:51 2015	(r277192)
@@ -2953,7 +2953,7 @@ struct bge_bcom_hack {
 #define	ASF_STACKUP		4
 
 struct bge_softc {
-	struct ifnet		*bge_ifp;	/* interface info */
+	if_t			bge_ifp;	/* interface info */
 	device_t		bge_dev;
 	struct mtx		bge_mtx;
 	device_t		bge_miibus;
@@ -2996,6 +2996,7 @@ struct bge_softc {
 #define	BGE_FLAG_4K_RDMA_BUG	0x10000000
 #define	BGE_FLAG_MBOX_REORDER	0x20000000
 #define	BGE_FLAG_RDMA_BUG	0x40000000
+#define	BGE_FLAG_RUNNING	0x80000000
 	uint32_t		bge_mfw_flags;	/* Management F/W flags */
 #define	BGE_MFW_ON_RXCPU	0x00000001
 #define	BGE_MFW_ON_APE		0x00000002
@@ -3060,6 +3061,7 @@ struct bge_softc {
 #define	BGE_LOCK_INIT(_sc, _name) \
 	mtx_init(&(_sc)->bge_mtx, _name, MTX_NETWORK_LOCK, MTX_DEF)
 #define	BGE_LOCK(_sc)		mtx_lock(&(_sc)->bge_mtx)

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-projects mailing list