Add netmap support for ixgbe SRIOV VFs (that is, to if_ixv).
Differential Revision: https://reviews.freebsd.org/D2923 Reviewed by: erj, gnn Approved by: jmallett (mentor) Sponsored by: Norse Corp, Inc.
This commit is contained in:
parent
fd3e9bafbd
commit
8aa7fdbd78
@ -362,7 +362,7 @@ device xenpci # Xen HVM Hypervisor services driver
|
||||
device vmx # VMware VMXNET3 Ethernet
|
||||
|
||||
# Netmap provides direct access to TX/RX rings on supported NICs
|
||||
device netmap # netmap(4) support
|
||||
# device netmap # netmap(4) support
|
||||
|
||||
# The crypto framework is required by IPSEC
|
||||
device crypto # Required by IPSEC
|
||||
|
@ -442,6 +442,11 @@ ixgbe_attach(device_t dev)
|
||||
adapter->dev = adapter->osdep.dev = dev;
|
||||
hw = &adapter->hw;
|
||||
|
||||
#ifdef DEV_NETMAP
|
||||
adapter->init_locked = ixgbe_init_locked;
|
||||
adapter->stop_locked = ixgbe_stop;
|
||||
#endif
|
||||
|
||||
/* Core Lock Init*/
|
||||
IXGBE_CORE_LOCK_INIT(adapter, device_get_nameunit(dev));
|
||||
|
||||
|
@ -124,6 +124,18 @@ static void ixv_msix_mbx(void *);
|
||||
static void ixv_handle_que(void *, int);
|
||||
static void ixv_handle_mbx(void *, int);
|
||||
|
||||
#ifdef DEV_NETMAP
|
||||
/*
|
||||
* This is defined in <dev/netmap/ixgbe_netmap.h>, which is included by
|
||||
* if_ix.c.
|
||||
*/
|
||||
extern void ixgbe_netmap_attach(struct adapter *adapter);
|
||||
|
||||
#include <net/netmap.h>
|
||||
#include <sys/selinfo.h>
|
||||
#include <dev/netmap/netmap_kern.h>
|
||||
#endif /* DEV_NETMAP */
|
||||
|
||||
/*********************************************************************
|
||||
* FreeBSD Device Interface Entry Points
|
||||
*********************************************************************/
|
||||
@ -145,6 +157,9 @@ devclass_t ixv_devclass;
|
||||
DRIVER_MODULE(ixv, pci, ixv_driver, ixv_devclass, 0, 0);
|
||||
MODULE_DEPEND(ixv, pci, 1, 1, 1);
|
||||
MODULE_DEPEND(ixv, ether, 1, 1, 1);
|
||||
#ifdef DEV_NETMAP
|
||||
MODULE_DEPEND(ix, netmap, 1, 1, 1);
|
||||
#endif /* DEV_NETMAP */
|
||||
/* XXX depend on 'ix' ? */
|
||||
|
||||
/*
|
||||
@ -278,6 +293,11 @@ ixv_attach(device_t dev)
|
||||
adapter->dev = adapter->osdep.dev = dev;
|
||||
hw = &adapter->hw;
|
||||
|
||||
#ifdef DEV_NETMAP
|
||||
adapter->init_locked = ixv_init_locked;
|
||||
adapter->stop_locked = ixv_stop;
|
||||
#endif
|
||||
|
||||
/* Core Lock Init*/
|
||||
IXGBE_CORE_LOCK_INIT(adapter, device_get_nameunit(dev));
|
||||
|
||||
@ -381,6 +401,9 @@ ixv_attach(device_t dev)
|
||||
adapter->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig,
|
||||
ixv_unregister_vlan, adapter, EVENTHANDLER_PRI_FIRST);
|
||||
|
||||
#ifdef DEV_NETMAP
|
||||
ixgbe_netmap_attach(adapter);
|
||||
#endif /* DEV_NETMAP */
|
||||
INIT_DEBUGOUT("ixv_attach: end");
|
||||
return (0);
|
||||
|
||||
@ -444,6 +467,9 @@ ixv_detach(device_t dev)
|
||||
|
||||
ether_ifdetach(adapter->ifp);
|
||||
callout_drain(&adapter->timer);
|
||||
#ifdef DEV_NETMAP
|
||||
netmap_detach(adapter->ifp);
|
||||
#endif /* DEV_NETMAP */
|
||||
ixv_free_pci_resources(adapter);
|
||||
bus_generic_detach(dev);
|
||||
if_free(adapter->ifp);
|
||||
@ -1685,8 +1711,33 @@ ixv_initialize_receive_units(struct adapter *adapter)
|
||||
wmb();
|
||||
|
||||
/* Set the Tail Pointer */
|
||||
IXGBE_WRITE_REG(hw, IXGBE_VFRDT(rxr->me),
|
||||
adapter->num_rx_desc - 1);
|
||||
#ifdef DEV_NETMAP
|
||||
/*
|
||||
* In netmap mode, we must preserve the buffers made
|
||||
* available to userspace before the if_init()
|
||||
* (this is true by default on the TX side, because
|
||||
* init makes all buffers available to userspace).
|
||||
*
|
||||
* netmap_reset() and the device specific routines
|
||||
* (e.g. ixgbe_setup_receive_rings()) map these
|
||||
* buffers at the end of the NIC ring, so here we
|
||||
* must set the RDT (tail) register to make sure
|
||||
* they are not overwritten.
|
||||
*
|
||||
* In this driver the NIC ring starts at RDH = 0,
|
||||
* RDT points to the last slot available for reception (?),
|
||||
* so RDT = num_rx_desc - 1 means the whole ring is available.
|
||||
*/
|
||||
if (ifp->if_capenable & IFCAP_NETMAP) {
|
||||
struct netmap_adapter *na = NA(adapter->ifp);
|
||||
struct netmap_kring *kring = &na->rx_rings[i];
|
||||
int t = na->num_rx_desc - 1 - nm_kr_rxspace(kring);
|
||||
|
||||
IXGBE_WRITE_REG(hw, IXGBE_VFRDT(rxr->me), t);
|
||||
} else
|
||||
#endif /* DEV_NETMAP */
|
||||
IXGBE_WRITE_REG(hw, IXGBE_VFRDT(rxr->me),
|
||||
adapter->num_rx_desc - 1);
|
||||
}
|
||||
|
||||
rxcsum = IXGBE_READ_REG(hw, IXGBE_RXCSUM);
|
||||
|
@ -555,6 +555,10 @@ struct adapter {
|
||||
#ifdef PCI_IOV
|
||||
struct ixgbe_vf *vfs;
|
||||
#endif
|
||||
#ifdef DEV_NETMAP
|
||||
void (*init_locked)(struct adapter *);
|
||||
void (*stop_locked)(void *);
|
||||
#endif
|
||||
|
||||
/* Misc stats maintained by the driver */
|
||||
unsigned long dropped_pkts;
|
||||
|
@ -26,7 +26,7 @@
|
||||
/*
|
||||
* $FreeBSD$
|
||||
*
|
||||
* netmap support for: ixgbe
|
||||
* netmap support for: ixgbe (both ix and ixv)
|
||||
*
|
||||
* This file is meant to be a reference on how to implement
|
||||
* netmap support for a network driver.
|
||||
@ -48,6 +48,7 @@
|
||||
*/
|
||||
#include <dev/netmap/netmap_kern.h>
|
||||
|
||||
void ixgbe_netmap_attach(struct adapter *adapter);
|
||||
|
||||
/*
|
||||
* device-specific sysctl variables:
|
||||
@ -120,20 +121,19 @@ ixgbe_netmap_reg(struct netmap_adapter *na, int onoff)
|
||||
struct adapter *adapter = ifp->if_softc;
|
||||
|
||||
IXGBE_CORE_LOCK(adapter);
|
||||
ixgbe_disable_intr(adapter); // XXX maybe ixgbe_stop ?
|
||||
adapter->stop_locked(adapter);
|
||||
|
||||
/* Tell the stack that the interface is no longer active */
|
||||
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
|
||||
|
||||
set_crcstrip(&adapter->hw, onoff);
|
||||
if (!IXGBE_IS_VF(adapter))
|
||||
set_crcstrip(&adapter->hw, onoff);
|
||||
/* enable or disable flags and callbacks in na and ifp */
|
||||
if (onoff) {
|
||||
nm_set_native_flags(na);
|
||||
} else {
|
||||
nm_clear_native_flags(na);
|
||||
}
|
||||
ixgbe_init_locked(adapter); /* also enables intr */
|
||||
set_crcstrip(&adapter->hw, onoff); // XXX why twice ?
|
||||
adapter->init_locked(adapter); /* also enables intr */
|
||||
if (!IXGBE_IS_VF(adapter))
|
||||
set_crcstrip(&adapter->hw, onoff); // XXX why twice ?
|
||||
IXGBE_CORE_UNLOCK(adapter);
|
||||
return (ifp->if_drv_flags & IFF_DRV_RUNNING ? 0 : 1);
|
||||
}
|
||||
@ -266,7 +266,7 @@ ixgbe_netmap_txsync(struct netmap_kring *kring, int flags)
|
||||
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
||||
|
||||
/* (re)start the tx unit up to slot nic_i (excluded) */
|
||||
IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDT(txr->me), nic_i);
|
||||
IXGBE_WRITE_REG(&adapter->hw, txr->tail, nic_i);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -310,7 +310,8 @@ ixgbe_netmap_txsync(struct netmap_kring *kring, int flags)
|
||||
* REPORT_STATUS in a few slots so TDH is the only
|
||||
* good way.
|
||||
*/
|
||||
nic_i = IXGBE_READ_REG(&adapter->hw, IXGBE_TDH(kring->ring_id));
|
||||
nic_i = IXGBE_READ_REG(&adapter->hw, IXGBE_IS_VF(adapter) ?
|
||||
IXGBE_VFTDH(kring->ring_id) : IXGBE_TDH(kring->ring_id));
|
||||
if (nic_i >= kring->nkr_num_slots) { /* XXX can it happen ? */
|
||||
D("TDH wrap %d", nic_i);
|
||||
nic_i -= kring->nkr_num_slots;
|
||||
@ -379,7 +380,7 @@ ixgbe_netmap_rxsync(struct netmap_kring *kring, int flags)
|
||||
* rxr->next_to_check is set to 0 on a ring reinit
|
||||
*/
|
||||
if (netmap_no_pendintr || force_update) {
|
||||
int crclen = ix_crcstrip ? 0 : 4;
|
||||
int crclen = (ix_crcstrip || IXGBE_IS_VF(adapter) ) ? 0 : 4;
|
||||
uint16_t slot_flags = kring->nkr_slot_flags;
|
||||
|
||||
nic_i = rxr->next_to_check; // or also k2n(kring->nr_hwtail)
|
||||
@ -453,7 +454,7 @@ ixgbe_netmap_rxsync(struct netmap_kring *kring, int flags)
|
||||
* so move nic_i back by one unit
|
||||
*/
|
||||
nic_i = nm_prev(nic_i, lim);
|
||||
IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDT(rxr->me), nic_i);
|
||||
IXGBE_WRITE_REG(&adapter->hw, rxr->tail, nic_i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -470,7 +471,7 @@ ixgbe_netmap_rxsync(struct netmap_kring *kring, int flags)
|
||||
* netmap mode will be disabled and the driver will only
|
||||
* operate in standard mode.
|
||||
*/
|
||||
static void
|
||||
void
|
||||
ixgbe_netmap_attach(struct adapter *adapter)
|
||||
{
|
||||
struct netmap_adapter na;
|
||||
|
Loading…
Reference in New Issue
Block a user