From owner-svn-src-projects@FreeBSD.ORG Wed Jan 14 19:47:52 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 ADD3BC18; Wed, 14 Jan 2015 19:47:52 +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 998A6DB; Wed, 14 Jan 2015 19:47:52 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t0EJlqRQ073249; Wed, 14 Jan 2015 19:47:52 GMT (envelope-from glebius@FreeBSD.org) Received: (from glebius@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t0EJlqku073247; Wed, 14 Jan 2015 19:47:52 GMT (envelope-from glebius@FreeBSD.org) Message-Id: <201501141947.t0EJlqku073247@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: glebius set sender to glebius@FreeBSD.org using -f From: Gleb Smirnoff Date: Wed, 14 Jan 2015 19:47:52 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r277192 - projects/ifnet/sys/dev/bge 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, 14 Jan 2015 19:47:52 -0000 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 #include #include +#include #include #include +#include #include #include #include @@ -83,16 +85,9 @@ __FBSDID("$FreeBSD$"); #include #include -#include -#include -#include #include #include - -#include - -#include -#include +#include #include #include @@ -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 ***