svn commit: r279890 - projects/ifnet/sys/dev/e1000
Gleb Smirnoff
glebius at FreeBSD.org
Wed Mar 11 15:42:22 UTC 2015
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 <sys/param.h>
#include <sys/systm.h>
-#ifndef IGB_LEGACY_TX
#include <sys/buf_ring.h>
-#endif
#include <sys/bus.h>
#include <sys/endian.h>
#include <sys/kernel.h>
@@ -66,20 +64,14 @@
#include <machine/bus.h>
#include <machine/resource.h>
-#include <net/bpf.h>
#include <net/ethernet.h>
#include <net/if.h>
-#include <net/if_var.h>
-#include <net/if_arp.h>
#include <net/if_dl.h>
#include <net/if_media.h>
#ifdef RSS
#include <net/rss_config.h>
#endif
-#include <net/if_types.h>
-#include <net/if_vlan_var.h>
-
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
@@ -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 ***
More information about the svn-src-projects
mailing list