From owner-svn-src-projects@FreeBSD.ORG Wed Mar 11 15:42:22 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 94847572; Wed, 11 Mar 2015 15:42:22 +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 7F3B6FD5; Wed, 11 Mar 2015 15:42:22 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t2BFgMXq073456; Wed, 11 Mar 2015 15:42:22 GMT (envelope-from glebius@FreeBSD.org) Received: (from glebius@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t2BFgMIH073454; Wed, 11 Mar 2015 15:42:22 GMT (envelope-from glebius@FreeBSD.org) Message-Id: <201503111542.t2BFgMIH073454@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: glebius set sender to glebius@FreeBSD.org using -f From: Gleb Smirnoff Date: Wed, 11 Mar 2015 15:42:22 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r279890 - projects/ifnet/sys/dev/e1000 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, 11 Mar 2015 15:42:22 -0000 Author: glebius Date: Wed Mar 11 15:42:21 2015 New Revision: 279890 URL: https://svnweb.freebsd.org/changeset/base/279890 Log: Convert igb(4) to new ifnet(9) KPI. Sponsored by: Nginx, Inc. Sponsored by: Netflix Modified: projects/ifnet/sys/dev/e1000/if_igb.c projects/ifnet/sys/dev/e1000/if_igb.h Modified: projects/ifnet/sys/dev/e1000/if_igb.c ============================================================================== --- projects/ifnet/sys/dev/e1000/if_igb.c Wed Mar 11 15:40:29 2015 (r279889) +++ projects/ifnet/sys/dev/e1000/if_igb.c Wed Mar 11 15:42:21 2015 (r279890) @@ -44,9 +44,7 @@ #include #include -#ifndef IGB_LEGACY_TX #include -#endif #include #include #include @@ -66,20 +64,14 @@ #include #include -#include #include #include -#include -#include #include #include #ifdef RSS #include #endif -#include -#include - #include #include #include @@ -194,22 +186,16 @@ static int igb_detach(device_t); static int igb_shutdown(device_t); static int igb_suspend(device_t); static int igb_resume(device_t); -#ifndef IGB_LEGACY_TX -static int igb_mq_start(struct ifnet *, struct mbuf *); -static int igb_mq_start_locked(struct ifnet *, struct tx_ring *); -static void igb_qflush(struct ifnet *); +static int igb_mq_start(if_t, struct mbuf *); +static int igb_mq_start_locked(if_t, struct tx_ring *); +static void igb_qflush(if_t); static void igb_deferred_mq_start(void *, int); -#else -static void igb_start(struct ifnet *); -static void igb_start_locked(struct tx_ring *, struct ifnet *ifp); -#endif -static int igb_ioctl(struct ifnet *, u_long, caddr_t); +static int igb_ioctl(if_t, u_long, void *, struct thread *); static uint64_t igb_get_counter(if_t, ift_counter); -static void igb_init(void *); -static void igb_init_locked(struct adapter *); +static void igb_init(struct adapter *); static void igb_stop(void *); -static void igb_media_status(struct ifnet *, struct ifmediareq *); -static int igb_media_change(struct ifnet *); +static void igb_media_status(if_t, struct ifmediareq *); +static int igb_media_change(if_t); static void igb_identify_hardware(struct adapter *); static int igb_allocate_pci_resources(struct adapter *); static int igb_allocate_msix(struct adapter *); @@ -218,7 +204,7 @@ static int igb_setup_msix(struct adapter static void igb_free_pci_resources(struct adapter *); static void igb_local_timer(void *); static void igb_reset(struct adapter *); -static int igb_setup_interface(device_t, struct adapter *); +static void igb_setup_interface(device_t, struct adapter *); static int igb_allocate_queues(struct adapter *); static void igb_configure_queues(struct adapter *); @@ -243,8 +229,8 @@ static void igb_update_stats_counters(st static bool igb_txeof(struct tx_ring *); static __inline void igb_rx_discard(struct rx_ring *, int); -static __inline void igb_rx_input(struct rx_ring *, - struct ifnet *, struct mbuf *, u32); +static __inline void igb_rx_input(struct rx_ring *, struct adapter *, + struct mbuf *, u32); static bool igb_rxeof(struct igb_queue *, int, int *); static void igb_rx_checksum(u32, struct mbuf *, u32); @@ -258,8 +244,8 @@ static void igb_set_multi(struct adapter static void igb_update_link_status(struct adapter *); static void igb_refresh_mbufs(struct rx_ring *, int); -static void igb_register_vlan(void *, struct ifnet *, u16); -static void igb_unregister_vlan(void *, struct ifnet *, u16); +static void igb_register_vlan(void *, if_t, u16); +static void igb_unregister_vlan(void *, if_t, u16); static void igb_setup_vlan_hw_support(struct adapter *); static int igb_xmit(struct tx_ring *, struct mbuf **); @@ -296,7 +282,7 @@ static int igb_sysctl_dmac(SYSCTL_HANDLE static int igb_sysctl_eee(SYSCTL_HANDLER_ARGS); #ifdef DEVICE_POLLING -static poll_handler_t igb_poll; +static int igb_poll(if_t, enum poll_cmd, int); #endif /* POLLING */ /********************************************************************* @@ -318,6 +304,22 @@ static driver_t igb_driver = { "igb", igb_methods, sizeof(struct adapter), }; +static struct ifdriver igb_ifdrv = { + .ifdrv_ops = { + .ifop_origin = IFOP_ORIGIN_DRIVER, + .ifop_ioctl = igb_ioctl, + .ifop_get_counter = igb_get_counter, + .ifop_transmit = igb_mq_start, + .ifop_qflush = igb_qflush, +#ifdef DEVICE_POLLING + .ifop_poll = igb_poll, +#endif + }, + .ifdrv_name = "igb", + .ifdrv_type = IFT_ETHER, + .ifdrv_hdrlen = sizeof(struct ether_vlan_header), +}; + static devclass_t igb_devclass; DRIVER_MODULE(igb, pci, igb_driver, igb_devclass, 0, 0); MODULE_DEPEND(igb, pci, 1, 1, 1); @@ -362,14 +364,12 @@ static int igb_max_interrupt_rate = 8000 SYSCTL_INT(_hw_igb, OID_AUTO, max_interrupt_rate, CTLFLAG_RDTUN, &igb_max_interrupt_rate, 0, "Maximum interrupts per second"); -#ifndef IGB_LEGACY_TX /* -** Tuneable number of buffers in the buf-ring (drbr_xxx) +** Tuneable number of buffers in the buf-ring */ static int igb_buf_ring_size = IGB_BR_SIZE; SYSCTL_INT(_hw_igb, OID_AUTO, buf_ring_size, CTLFLAG_RDTUN, &igb_buf_ring_size, 0, "Size of the bufring"); -#endif /* ** Header split causes the packet header to @@ -657,10 +657,6 @@ igb_attach(device_t dev) goto err_late; } - /* Setup OS specific network interface */ - if (igb_setup_interface(dev, adapter) != 0) - goto err_late; - /* Now get a good starting state */ igb_reset(adapter); @@ -695,8 +691,7 @@ igb_attach(device_t dev) igb_add_hw_stats(adapter); /* Tell the stack that the interface is not active */ - adapter->ifp->if_drv_flags &= ~IFF_DRV_RUNNING; - adapter->ifp->if_drv_flags |= IFF_DRV_OACTIVE; + adapter->flags &= ~IGB_RUNNING; adapter->led_dev = led_create(igb_led_func, adapter, device_get_nameunit(dev)); @@ -711,6 +706,9 @@ igb_attach(device_t dev) if (error) goto err_late; + /* Setup OS specific network interface */ + igb_setup_interface(dev, adapter); + #ifdef DEV_NETMAP igb_netmap_attach(adapter); #endif /* DEV_NETMAP */ @@ -725,8 +723,6 @@ err_late: igb_release_hw_control(adapter); err_pci: igb_free_pci_resources(adapter); - if (adapter->ifp != NULL) - if_free(adapter->ifp); free(adapter->mta, M_DEVBUF); IGB_CORE_LOCK_DESTROY(adapter); @@ -747,26 +743,19 @@ static int igb_detach(device_t dev) { struct adapter *adapter = device_get_softc(dev); - struct ifnet *ifp = adapter->ifp; INIT_DEBUGOUT("igb_detach: begin"); - /* Make sure VLANS are not using driver */ - if (adapter->ifp->if_vlantrunk != NULL) { - device_printf(dev,"Vlan in use, detach first\n"); - return (EBUSY); + if (adapter->ifp) { +#ifdef DEV_NETMAP + netmap_detach(adapter->ifp); +#endif /* DEV_NETMAP */ + if_detach(adapter->ifp); } - ether_ifdetach(adapter->ifp); - if (adapter->led_dev != NULL) led_destroy(adapter->led_dev); -#ifdef DEVICE_POLLING - if (ifp->if_capenable & IFCAP_POLLING) - ether_poll_deregister(ifp); -#endif - IGB_CORE_LOCK(adapter); adapter->in_detach = 1; igb_stop(adapter); @@ -792,12 +781,8 @@ igb_detach(device_t dev) callout_drain(&adapter->timer); -#ifdef DEV_NETMAP - netmap_detach(adapter->ifp); -#endif /* DEV_NETMAP */ igb_free_pci_resources(adapter); bus_generic_detach(dev); - if_free(ifp); igb_free_transmit_structures(adapter); igb_free_receive_structures(adapter); @@ -852,25 +837,20 @@ igb_resume(device_t dev) { struct adapter *adapter = device_get_softc(dev); struct tx_ring *txr = adapter->tx_rings; - struct ifnet *ifp = adapter->ifp; + if_t ifp = adapter->ifp; IGB_CORE_LOCK(adapter); - igb_init_locked(adapter); + igb_init(adapter); igb_init_manageability(adapter); - if ((ifp->if_flags & IFF_UP) && - (ifp->if_drv_flags & IFF_DRV_RUNNING) && adapter->link_active) { + if ((adapter->if_flags & IFF_UP) && + (adapter->flags & IGB_RUNNING) && adapter->link_active) { for (int i = 0; i < adapter->num_queues; i++, txr++) { IGB_TX_LOCK(txr); -#ifndef IGB_LEGACY_TX /* Process the stack queue only if not depleted */ if (((txr->queue_status & IGB_QUEUE_DEPLETED) == 0) && - !drbr_empty(ifp, txr->br)) + !buf_ring_empty(txr->br)) igb_mq_start_locked(ifp, txr); -#else - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - igb_start_locked(txr, ifp); -#endif IGB_TX_UNLOCK(txr); } } @@ -880,95 +860,15 @@ igb_resume(device_t dev) } -#ifdef IGB_LEGACY_TX - -/********************************************************************* - * Transmit entry point - * - * igb_start is called by the stack to initiate a transmit. - * The driver will remain in this routine as long as there are - * packets to transmit and transmit resources are available. - * In case resources are not available stack is notified and - * the packet is requeued. - **********************************************************************/ - -static void -igb_start_locked(struct tx_ring *txr, struct ifnet *ifp) -{ - struct adapter *adapter = ifp->if_softc; - struct mbuf *m_head; - - IGB_TX_LOCK_ASSERT(txr); - - if ((ifp->if_drv_flags & (IFF_DRV_RUNNING|IFF_DRV_OACTIVE)) != - IFF_DRV_RUNNING) - return; - if (!adapter->link_active) - return; - - /* Call cleanup if number of TX descriptors low */ - if (txr->tx_avail <= IGB_TX_CLEANUP_THRESHOLD) - igb_txeof(txr); - - while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) { - if (txr->tx_avail <= IGB_MAX_SCATTER) { - txr->queue_status |= IGB_QUEUE_DEPLETED; - break; - } - IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head); - if (m_head == NULL) - break; - /* - * Encapsulation can modify our pointer, and or make it - * NULL on failure. In that event, we can't requeue. - */ - if (igb_xmit(txr, &m_head)) { - if (m_head != NULL) - IFQ_DRV_PREPEND(&ifp->if_snd, m_head); - if (txr->tx_avail <= IGB_MAX_SCATTER) - txr->queue_status |= IGB_QUEUE_DEPLETED; - break; - } - - /* Send a copy of the frame to the BPF listener */ - ETHER_BPF_MTAP(ifp, m_head); - - /* Set watchdog on */ - txr->watchdog_time = ticks; - txr->queue_status |= IGB_QUEUE_WORKING; - } -} - -/* - * Legacy TX driver routine, called from the - * stack, always uses tx[0], and spins for it. - * Should not be used with multiqueue tx - */ -static void -igb_start(struct ifnet *ifp) -{ - struct adapter *adapter = ifp->if_softc; - struct tx_ring *txr = adapter->tx_rings; - - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - IGB_TX_LOCK(txr); - igb_start_locked(txr, ifp); - IGB_TX_UNLOCK(txr); - } - return; -} - -#else /* ~IGB_LEGACY_TX */ - /* ** Multiqueue Transmit Entry: ** quick turnaround to the stack ** */ static int -igb_mq_start(struct ifnet *ifp, struct mbuf *m) +igb_mq_start(if_t ifp, struct mbuf *m) { - struct adapter *adapter = ifp->if_softc; + struct adapter *adapter = if_getsoftc(ifp, IF_DRIVER_SOFTC); struct igb_queue *que; struct tx_ring *txr; int i, err = 0; @@ -1002,7 +902,7 @@ igb_mq_start(struct ifnet *ifp, struct m txr = &adapter->tx_rings[i]; que = &adapter->queues[i]; - err = drbr_enqueue(ifp, txr->br, m); + err = buf_ring_enqueue(txr->br, m); if (err) return (err); if (IGB_TX_TRYLOCK(txr)) { @@ -1015,7 +915,7 @@ igb_mq_start(struct ifnet *ifp, struct m } static int -igb_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr) +igb_mq_start_locked(if_t ifp, struct tx_ring *txr) { struct adapter *adapter = txr->adapter; struct mbuf *next; @@ -1023,34 +923,31 @@ igb_mq_start_locked(struct ifnet *ifp, s IGB_TX_LOCK_ASSERT(txr); - if (((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) || + if (((adapter->flags & IGB_RUNNING) == 0) || adapter->link_active == 0) return (ENETDOWN); /* Process the queue */ - while ((next = drbr_peek(ifp, txr->br)) != NULL) { + while ((next = buf_ring_peek(txr->br)) != NULL) { if ((err = igb_xmit(txr, &next)) != 0) { if (next == NULL) { /* It was freed, move forward */ - drbr_advance(ifp, txr->br); + buf_ring_advance_sc(txr->br); } else { /* * Still have one left, it may not be * the same since the transmit function * may have changed it. */ - drbr_putback(ifp, txr->br, next); + buf_ring_putback_sc(txr->br, next); } break; } - drbr_advance(ifp, txr->br); + buf_ring_advance_sc(txr->br); enq++; - if_inc_counter(ifp, IFCOUNTER_OBYTES, next->m_pkthdr.len); - if (next->m_flags & M_MCAST) - if_inc_counter(ifp, IFCOUNTER_OMCASTS, 1); - ETHER_BPF_MTAP(ifp, next); - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + if_mtap(ifp, next, NULL, 0); + if ((adapter->flags & IGB_RUNNING) == 0) break; } if (enq > 0) { @@ -1073,10 +970,10 @@ igb_deferred_mq_start(void *arg, int pen { struct tx_ring *txr = arg; struct adapter *adapter = txr->adapter; - struct ifnet *ifp = adapter->ifp; + if_t ifp = adapter->ifp; IGB_TX_LOCK(txr); - if (!drbr_empty(ifp, txr->br)) + if (!buf_ring_empty(txr->br)) igb_mq_start_locked(ifp, txr); IGB_TX_UNLOCK(txr); } @@ -1085,9 +982,9 @@ igb_deferred_mq_start(void *arg, int pen ** Flush all ring buffers */ static void -igb_qflush(struct ifnet *ifp) +igb_qflush(if_t ifp) { - struct adapter *adapter = ifp->if_softc; + struct adapter *adapter = if_getsoftc(ifp, IF_DRIVER_SOFTC); struct tx_ring *txr = adapter->tx_rings; struct mbuf *m; @@ -1097,9 +994,7 @@ igb_qflush(struct ifnet *ifp) m_freem(m); IGB_TX_UNLOCK(txr); } - if_qflush(ifp); } -#endif /* ~IGB_LEGACY_TX */ /********************************************************************* * Ioctl entry point @@ -1111,94 +1006,56 @@ igb_qflush(struct ifnet *ifp) **********************************************************************/ static int -igb_ioctl(struct ifnet *ifp, u_long command, caddr_t data) +igb_ioctl(if_t ifp, u_long command, void *data, struct thread *td) { - struct adapter *adapter = ifp->if_softc; + struct adapter *adapter = if_getsoftc(ifp, IF_DRIVER_SOFTC); struct ifreq *ifr = (struct ifreq *)data; -#if defined(INET) || defined(INET6) - struct ifaddr *ifa = (struct ifaddr *)data; -#endif - bool avoid_reset = FALSE; + uint32_t oflags, mask; int error = 0; if (adapter->in_detach) return (error); switch (command) { - case SIOCSIFADDR: -#ifdef INET - if (ifa->ifa_addr->sa_family == AF_INET) - avoid_reset = TRUE; -#endif -#ifdef INET6 - if (ifa->ifa_addr->sa_family == AF_INET6) - avoid_reset = TRUE; -#endif - /* - ** Calling init results in link renegotiation, - ** so we avoid doing it when possible. - */ - if (avoid_reset) { - ifp->if_flags |= IFF_UP; - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) - igb_init(adapter); -#ifdef INET - if (!(ifp->if_flags & IFF_NOARP)) - arp_ifinit(ifp, ifa); -#endif - } else - error = ether_ioctl(ifp, command, data); - break; case SIOCSIFMTU: - { - int max_frame_size; - IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFMTU (Set Interface MTU)"); - + if (ifr->ifr_mtu > 9234 - ETHER_HDR_LEN - ETHER_CRC_LEN) + return (EINVAL); IGB_CORE_LOCK(adapter); - max_frame_size = 9234; - if (ifr->ifr_mtu > max_frame_size - ETHER_HDR_LEN - - ETHER_CRC_LEN) { - IGB_CORE_UNLOCK(adapter); - error = EINVAL; - break; - } - - ifp->if_mtu = ifr->ifr_mtu; adapter->max_frame_size = - ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN; - igb_init_locked(adapter); + ifr->ifr_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN; + igb_init(adapter); IGB_CORE_UNLOCK(adapter); break; - } case SIOCSIFFLAGS: IOCTL_DEBUGOUT("ioctl rcv'd:\ SIOCSIFFLAGS (Set Interface Flags)"); IGB_CORE_LOCK(adapter); - if (ifp->if_flags & IFF_UP) { - if ((ifp->if_drv_flags & IFF_DRV_RUNNING)) { - if ((ifp->if_flags ^ adapter->if_flags) & + oflags = adapter->if_flags; + adapter->if_flags = ifr->ifr_flags; + if (adapter->if_flags & IFF_UP) { + if ((adapter->flags & IGB_RUNNING)) { + if ((oflags ^ adapter->if_flags) & (IFF_PROMISC | IFF_ALLMULTI)) { igb_disable_promisc(adapter); igb_set_promisc(adapter); } } else - igb_init_locked(adapter); + igb_init(adapter); } else - if (ifp->if_drv_flags & IFF_DRV_RUNNING) + if (adapter->flags & IGB_RUNNING) igb_stop(adapter); - adapter->if_flags = ifp->if_flags; IGB_CORE_UNLOCK(adapter); break; case SIOCADDMULTI: case SIOCDELMULTI: IOCTL_DEBUGOUT("ioctl rcv'd: SIOC(ADD|DEL)MULTI"); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + if (adapter->flags & IGB_RUNNING) { IGB_CORE_LOCK(adapter); igb_disable_intr(adapter); igb_set_multi(adapter); #ifdef DEVICE_POLLING - if (!(ifp->if_capenable & IFCAP_POLLING)) + if (!(adapter->if_capenable & IFCAP_POLLING)) #endif igb_enable_intr(adapter); IGB_CORE_UNLOCK(adapter); @@ -1220,68 +1077,36 @@ igb_ioctl(struct ifnet *ifp, u_long comm error = ifmedia_ioctl(ifp, ifr, &adapter->media, command); break; case SIOCSIFCAP: - { - int mask, reinit; - IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFCAP (Set Capabilities)"); - reinit = 0; - mask = ifr->ifr_reqcap ^ ifp->if_capenable; + mask = ifr->ifr_reqcap ^ ifr->ifr_curcap; + IGB_CORE_LOCK(adapter); #ifdef DEVICE_POLLING if (mask & IFCAP_POLLING) { - if (ifr->ifr_reqcap & IFCAP_POLLING) { - error = ether_poll_register(igb_poll, ifp); - if (error) - return (error); - IGB_CORE_LOCK(adapter); + if (ifr->ifr_reqcap & IFCAP_POLLING) igb_disable_intr(adapter); - ifp->if_capenable |= IFCAP_POLLING; - IGB_CORE_UNLOCK(adapter); - } else { - error = ether_poll_deregister(ifp); - /* Enable interrupt even in error case */ - IGB_CORE_LOCK(adapter); + else igb_enable_intr(adapter); - ifp->if_capenable &= ~IFCAP_POLLING; - IGB_CORE_UNLOCK(adapter); - } } #endif - if (mask & IFCAP_HWCSUM) { - ifp->if_capenable ^= IFCAP_HWCSUM; - reinit = 1; - } - if (mask & IFCAP_TSO4) { - ifp->if_capenable ^= IFCAP_TSO4; - reinit = 1; - } - if (mask & IFCAP_TSO6) { - ifp->if_capenable ^= IFCAP_TSO6; - reinit = 1; - } - if (mask & IFCAP_VLAN_HWTAGGING) { - ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING; - reinit = 1; - } - if (mask & IFCAP_VLAN_HWFILTER) { - ifp->if_capenable ^= IFCAP_VLAN_HWFILTER; - reinit = 1; - } - if (mask & IFCAP_VLAN_HWTSO) { - ifp->if_capenable ^= IFCAP_VLAN_HWTSO; - reinit = 1; - } - if (mask & IFCAP_LRO) { - ifp->if_capenable ^= IFCAP_LRO; - reinit = 1; + ifr->ifr_hwassist = 0; + if (ifr->ifr_reqcap & IFCAP_TXCSUM) { + ifr->ifr_hwassist |= (CSUM_TCP | CSUM_UDP); + if (adapter->hw.mac.type == e1000_82576) + ifr->ifr_hwassist |= CSUM_SCTP; } - if (reinit && (ifp->if_drv_flags & IFF_DRV_RUNNING)) + if (ifr->ifr_reqcap & IFCAP_TSO) + ifr->ifr_hwassist |= CSUM_TSO; + + adapter->if_capenable = ifr->ifr_reqcap; + if ((mask & (IFCAP_HWCSUM | IFCAP_TSO4 | IFCAP_TSO6 | + IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_HWFILTER | + IFCAP_VLAN_HWTSO | IFCAP_LRO)) && + (adapter->flags & IGB_RUNNING)) igb_init(adapter); - VLAN_CAPABILITIES(ifp); + IGB_CORE_UNLOCK(adapter); break; - } - default: - error = ether_ioctl(ifp, command, data); + error = EOPNOTSUPP; break; } @@ -1292,18 +1117,13 @@ igb_ioctl(struct ifnet *ifp, u_long comm /********************************************************************* * Init entry point * - * This routine is used in two ways. It is used by the stack as - * init entry point in network interface structure. It is also used - * by the driver as a hw/sw initialization routine to get to a - * consistent state. - * - * return 0 on success, positive on failure + * It is used by the driver as a hw/sw initialization routine to get + * to a consistent state. **********************************************************************/ static void -igb_init_locked(struct adapter *adapter) +igb_init(struct adapter *adapter) { - struct ifnet *ifp = adapter->ifp; device_t dev = adapter->dev; INIT_DEBUGOUT("igb_init: begin"); @@ -1314,8 +1134,7 @@ igb_init_locked(struct adapter *adapter) callout_stop(&adapter->timer); /* Get the latest mac address, User can use a LAA */ - bcopy(IF_LLADDR(adapter->ifp), adapter->hw.mac.addr, - ETHER_ADDR_LEN); + bcopy(if_lladdr(adapter->ifp), adapter->hw.mac.addr, ETHER_ADDR_LEN); /* Put the address into the Receive Address Array */ e1000_rar_set(&adapter->hw, adapter->hw.mac.addr, 0); @@ -1325,19 +1144,6 @@ igb_init_locked(struct adapter *adapter) E1000_WRITE_REG(&adapter->hw, E1000_VET, ETHERTYPE_VLAN); - /* Set hardware offload abilities */ - ifp->if_hwassist = 0; - if (ifp->if_capenable & IFCAP_TXCSUM) { - ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP); -#if __FreeBSD_version >= 800000 - if (adapter->hw.mac.type == e1000_82576) - ifp->if_hwassist |= CSUM_SCTP; -#endif - } - - if (ifp->if_capenable & IFCAP_TSO) - ifp->if_hwassist |= CSUM_TSO; - /* Configure for OS presence */ igb_init_manageability(adapter); @@ -1367,14 +1173,13 @@ igb_init_locked(struct adapter *adapter) igb_initialize_receive_units(adapter); /* Enable VLAN support */ - if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) + if (adapter->if_capenable & IFCAP_VLAN_HWTAGGING) igb_setup_vlan_hw_support(adapter); /* Don't lose promiscuous settings */ igb_set_promisc(adapter); - ifp->if_drv_flags |= IFF_DRV_RUNNING; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + adapter->flags |= IGB_RUNNING; callout_reset(&adapter->timer, hz, igb_local_timer, adapter); e1000_clear_hw_cntrs_base_generic(&adapter->hw); @@ -1389,7 +1194,7 @@ igb_init_locked(struct adapter *adapter) * Only enable interrupts if we are not polling, make sure * they are off otherwise. */ - if (ifp->if_capenable & IFCAP_POLLING) + if (adapter->if_capenable & IFCAP_POLLING) igb_disable_intr(adapter); else #endif /* DEVICE_POLLING */ @@ -1408,40 +1213,24 @@ igb_init_locked(struct adapter *adapter) } static void -igb_init(void *arg) -{ - struct adapter *adapter = arg; - - IGB_CORE_LOCK(adapter); - igb_init_locked(adapter); - IGB_CORE_UNLOCK(adapter); -} - - -static void igb_handle_que(void *context, int pending) { struct igb_queue *que = context; struct adapter *adapter = que->adapter; struct tx_ring *txr = que->txr; - struct ifnet *ifp = adapter->ifp; + if_t ifp = adapter->ifp; - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + if (adapter->flags & IGB_RUNNING) { bool more; more = igb_rxeof(que, adapter->rx_process_limit, NULL); IGB_TX_LOCK(txr); igb_txeof(txr); -#ifndef IGB_LEGACY_TX /* Process the stack queue only if not depleted */ if (((txr->queue_status & IGB_QUEUE_DEPLETED) == 0) && - !drbr_empty(ifp, txr->br)) + !buf_ring_empty(txr->br)) igb_mq_start_locked(ifp, txr); -#else - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - igb_start_locked(txr, ifp); -#endif IGB_TX_UNLOCK(txr); /* Do we need another? */ if (more) { @@ -1451,7 +1240,7 @@ igb_handle_que(void *context, int pendin } #ifdef DEVICE_POLLING - if (ifp->if_capenable & IFCAP_POLLING) + if (adapter->if_capenable & IFCAP_POLLING) return; #endif /* Reenable this interrupt */ @@ -1476,23 +1265,18 @@ static void igb_handle_link_locked(struct adapter *adapter) { struct tx_ring *txr = adapter->tx_rings; - struct ifnet *ifp = adapter->ifp; + if_t ifp = adapter->ifp; IGB_CORE_LOCK_ASSERT(adapter); adapter->hw.mac.get_link_status = 1; igb_update_link_status(adapter); - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) && adapter->link_active) { + if ((adapter->flags & IGB_RUNNING) && adapter->link_active) { for (int i = 0; i < adapter->num_queues; i++, txr++) { IGB_TX_LOCK(txr); -#ifndef IGB_LEGACY_TX /* Process the stack queue only if not depleted */ if (((txr->queue_status & IGB_QUEUE_DEPLETED) == 0) && - !drbr_empty(ifp, txr->br)) + !buf_ring_empty(txr->br)) igb_mq_start_locked(ifp, txr); -#else - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - igb_start_locked(txr, ifp); -#endif IGB_TX_UNLOCK(txr); } } @@ -1543,16 +1327,10 @@ igb_irq_fast(void *arg) } #ifdef DEVICE_POLLING -#if __FreeBSD_version >= 800000 -#define POLL_RETURN_COUNT(a) (a) static int -#else -#define POLL_RETURN_COUNT(a) -static void -#endif -igb_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) +igb_poll(if_t ifp, enum poll_cmd cmd, int count) { - struct adapter *adapter = ifp->if_softc; + struct adapter *adapter = if_getsoftc(ifp, IF_DRIVER_SOFTC); struct igb_queue *que; struct tx_ring *txr; u32 reg_icr, rx_done = 0; @@ -1560,9 +1338,9 @@ igb_poll(struct ifnet *ifp, enum poll_cm bool more; IGB_CORE_LOCK(adapter); - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + if ((adapter->flags & IGB_RUNNING) == 0) { IGB_CORE_UNLOCK(adapter); - return POLL_RETURN_COUNT(rx_done); + return (rx_done); } if (cmd == POLL_AND_CHECK_STATUS) { @@ -1586,17 +1364,12 @@ igb_poll(struct ifnet *ifp, enum poll_cm do { more = igb_txeof(txr); } while (loop-- && more); -#ifndef IGB_LEGACY_TX - if (!drbr_empty(ifp, txr->br)) + if (!buf_ring_empty(txr->br)) igb_mq_start_locked(ifp, txr); -#else - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - igb_start_locked(txr, ifp); -#endif IGB_TX_UNLOCK(txr); } - return POLL_RETURN_COUNT(rx_done); + return (rx_done); } #endif /* DEVICE_POLLING */ @@ -1610,14 +1383,14 @@ igb_msix_que(void *arg) { struct igb_queue *que = arg; struct adapter *adapter = que->adapter; - struct ifnet *ifp = adapter->ifp; + if_t ifp = adapter->ifp; struct tx_ring *txr = que->txr; struct rx_ring *rxr = que->rxr; u32 newitr = 0; bool more_rx; /* Ignore spurious interrupts */ - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + if ((adapter->flags & IGB_RUNNING) == 0) return; E1000_WRITE_REG(&adapter->hw, E1000_EIMC, que->eims); @@ -1625,15 +1398,10 @@ igb_msix_que(void *arg) IGB_TX_LOCK(txr); igb_txeof(txr); -#ifndef IGB_LEGACY_TX /* Process the stack queue only if not depleted */ if (((txr->queue_status & IGB_QUEUE_DEPLETED) == 0) && - !drbr_empty(ifp, txr->br)) + !buf_ring_empty(txr->br)) igb_mq_start_locked(ifp, txr); -#else - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - igb_start_locked(txr, ifp); -#endif IGB_TX_UNLOCK(txr); more_rx = igb_rxeof(que, adapter->rx_process_limit, NULL); @@ -1735,9 +1503,9 @@ spurious: * **********************************************************************/ static void -igb_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) +igb_media_status(if_t ifp, struct ifmediareq *ifmr) { - struct adapter *adapter = ifp->if_softc; + struct adapter *adapter = if_getsoftc(ifp, IF_DRIVER_SOFTC); INIT_DEBUGOUT("igb_media_status: begin"); @@ -1794,9 +1562,9 @@ igb_media_status(struct ifnet *ifp, stru * **********************************************************************/ static int -igb_media_change(struct ifnet *ifp) +igb_media_change(if_t ifp) { - struct adapter *adapter = ifp->if_softc; + struct adapter *adapter = if_getsoftc(ifp, IF_DRIVER_SOFTC); struct ifmedia *ifm = &adapter->media; INIT_DEBUGOUT("igb_media_change: begin"); @@ -1836,7 +1604,7 @@ igb_media_change(struct ifnet *ifp) device_printf(adapter->dev, "Unsupported media type\n"); } - igb_init_locked(adapter); + igb_init(adapter); IGB_CORE_UNLOCK(adapter); return (0); @@ -1990,10 +1758,10 @@ retry: return (0); } + static void igb_set_promisc(struct adapter *adapter) { - struct ifnet *ifp = adapter->ifp; struct e1000_hw *hw = &adapter->hw; u32 reg; @@ -2003,10 +1771,10 @@ igb_set_promisc(struct adapter *adapter) } reg = E1000_READ_REG(hw, E1000_RCTL); - if (ifp->if_flags & IFF_PROMISC) { + if (adapter->if_flags & IFF_PROMISC) { reg |= (E1000_RCTL_UPE | E1000_RCTL_MPE); E1000_WRITE_REG(hw, E1000_RCTL, reg); - } else if (ifp->if_flags & IFF_ALLMULTI) { + } else if (adapter->if_flags & IFF_ALLMULTI) { reg |= E1000_RCTL_MPE; reg &= ~E1000_RCTL_UPE; E1000_WRITE_REG(hw, E1000_RCTL, reg); @@ -2014,10 +1782,20 @@ igb_set_promisc(struct adapter *adapter) } static void +igb_count_maddr(void *arg, struct sockaddr *maddr) +{ + struct sockaddr_dl *sdl = (struct sockaddr_dl *)maddr; + int *mcnt = arg; + + if (sdl->sdl_family == AF_LINK) + (*mcnt)++; +} + +static void igb_disable_promisc(struct adapter *adapter) { struct e1000_hw *hw = &adapter->hw; - struct ifnet *ifp = adapter->ifp; + if_t ifp = adapter->ifp; u32 reg; int mcnt = 0; @@ -2026,29 +1804,11 @@ igb_disable_promisc(struct adapter *adap return; } reg = E1000_READ_REG(hw, E1000_RCTL); - reg &= (~E1000_RCTL_UPE); - if (ifp->if_flags & IFF_ALLMULTI) + reg &= (~E1000_RCTL_UPE); + if (adapter->if_flags & IFF_ALLMULTI) mcnt = MAX_NUM_MULTICAST_ADDRESSES; - else { - struct ifmultiaddr *ifma; -#if __FreeBSD_version < 800000 - IF_ADDR_LOCK(ifp); -#else - if_maddr_rlock(ifp); -#endif - TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - if (mcnt == MAX_NUM_MULTICAST_ADDRESSES) - break; - mcnt++; - } -#if __FreeBSD_version < 800000 - IF_ADDR_UNLOCK(ifp); -#else - if_maddr_runlock(ifp); *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***