Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/vmware/vmxnet3/if_vmx.c
Show All 22 Lines | |||||
typedef enum { | typedef enum { | ||||
VMXNET3_BARRIER_RD, | VMXNET3_BARRIER_RD, | ||||
VMXNET3_BARRIER_WR, | VMXNET3_BARRIER_WR, | ||||
VMXNET3_BARRIER_RDWR, | VMXNET3_BARRIER_RDWR, | ||||
} vmxnet3_barrier_t; | } vmxnet3_barrier_t; | ||||
static void vmxnet3_barrier(struct vmxnet3_softc *, vmxnet3_barrier_t); | static void vmxnet3_barrier(struct vmxnet3_softc *, vmxnet3_barrier_t); | ||||
#ifdef DEV_NETMAP | |||||
#include "vmx_netmap.h" | |||||
#endif | |||||
/* Tunables. */ | /* Tunables. */ | ||||
static int vmxnet3_mq_disable = 0; | static int vmxnet3_mq_disable = 0; | ||||
TUNABLE_INT("hw.vmx.mq_disable", &vmxnet3_mq_disable); | TUNABLE_INT("hw.vmx.mq_disable", &vmxnet3_mq_disable); | ||||
static int vmxnet3_default_txnqueue = VMXNET3_DEF_TX_QUEUES; | static int vmxnet3_default_txnqueue = VMXNET3_DEF_TX_QUEUES; | ||||
TUNABLE_INT("hw.vmx.txnqueue", &vmxnet3_default_txnqueue); | TUNABLE_INT("hw.vmx.txnqueue", &vmxnet3_default_txnqueue); | ||||
static int vmxnet3_default_rxnqueue = VMXNET3_DEF_RX_QUEUES; | static int vmxnet3_default_rxnqueue = VMXNET3_DEF_RX_QUEUES; | ||||
TUNABLE_INT("hw.vmx.rxnqueue", &vmxnet3_default_rxnqueue); | TUNABLE_INT("hw.vmx.rxnqueue", &vmxnet3_default_rxnqueue); | ||||
static int vmxnet3_default_txndesc = VMXNET3_DEF_TX_NDESC; | static int vmxnet3_default_txndesc = VMXNET3_DEF_TX_NDESC; | ||||
Show All 15 Lines | |||||
"vmx", vmxnet3_methods, sizeof(struct vmxnet3_softc) | "vmx", vmxnet3_methods, sizeof(struct vmxnet3_softc) | ||||
}; | }; | ||||
static devclass_t vmxnet3_devclass; | static devclass_t vmxnet3_devclass; | ||||
DRIVER_MODULE(vmx, pci, vmxnet3_driver, vmxnet3_devclass, 0, 0); | DRIVER_MODULE(vmx, pci, vmxnet3_driver, vmxnet3_devclass, 0, 0); | ||||
MODULE_DEPEND(vmx, pci, 1, 1, 1); | MODULE_DEPEND(vmx, pci, 1, 1, 1); | ||||
MODULE_DEPEND(vmx, ether, 1, 1, 1); | MODULE_DEPEND(vmx, ether, 1, 1, 1); | ||||
#ifdef DEV_NETMAP | |||||
MODULE_DEPEND(vmx, netmap, 1, 1, 1); | |||||
#endif | |||||
#define VMXNET3_VMWARE_VENDOR_ID 0x15AD | #define VMXNET3_VMWARE_VENDOR_ID 0x15AD | ||||
#define VMXNET3_VMWARE_DEVICE_ID 0x07B0 | #define VMXNET3_VMWARE_DEVICE_ID 0x07B0 | ||||
static int | static int | ||||
vmxnet3_probe(device_t dev) | vmxnet3_probe(device_t dev) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | |||||
goto fail; | goto fail; | ||||
} | } | ||||
vmxnet3_setup_sysctl(sc); | vmxnet3_setup_sysctl(sc); | ||||
#ifndef VMXNET3_LEGACY_TX | #ifndef VMXNET3_LEGACY_TX | ||||
vmxnet3_start_taskqueue(sc); | vmxnet3_start_taskqueue(sc); | ||||
#endif | #endif | ||||
#ifdef DEV_NETMAP | |||||
vmxnet3_netmap_attach(sc); | |||||
#endif | |||||
fail: | fail: | ||||
if (error) | if (error) | ||||
vmxnet3_detach(dev); | vmxnet3_detach(dev); | ||||
return (error); | return (error); | ||||
} | } | ||||
static int | static int | ||||
Show All 27 Lines | |||||
sc->vmx_vlan_detach = NULL; | sc->vmx_vlan_detach = NULL; | ||||
} | } | ||||
#ifndef VMXNET3_LEGACY_TX | #ifndef VMXNET3_LEGACY_TX | ||||
vmxnet3_free_taskqueue(sc); | vmxnet3_free_taskqueue(sc); | ||||
#endif | #endif | ||||
vmxnet3_free_interrupts(sc); | vmxnet3_free_interrupts(sc); | ||||
#ifdef DEV_NETMAP | |||||
netmap_detach(ifp); | |||||
#endif | |||||
if (ifp != NULL) { | if (ifp != NULL) { | ||||
if_free(ifp); | if_free(ifp); | ||||
sc->vmx_ifp = NULL; | sc->vmx_ifp = NULL; | ||||
} | } | ||||
ifmedia_removeall(&sc->vmx_media); | ifmedia_removeall(&sc->vmx_media); | ||||
vmxnet3_free_data(sc); | vmxnet3_free_data(sc); | ||||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | |||||
struct mbuf *m; | struct mbuf *m; | ||||
u_int sop; | u_int sop; | ||||
sc = txq->vxtxq_sc; | sc = txq->vxtxq_sc; | ||||
ifp = sc->vmx_ifp; | ifp = sc->vmx_ifp; | ||||
txr = &txq->vxtxq_cmd_ring; | txr = &txq->vxtxq_cmd_ring; | ||||
txc = &txq->vxtxq_comp_ring; | txc = &txq->vxtxq_comp_ring; | ||||
#ifdef DEV_NETMAP | |||||
if (netmap_tx_irq(sc->vmx_ifp, txq - sc->vmx_txq) != NM_IRQ_PASS) | |||||
return; | |||||
#endif | |||||
VMXNET3_TXQ_LOCK_ASSERT(txq); | VMXNET3_TXQ_LOCK_ASSERT(txq); | ||||
for (;;) { | for (;;) { | ||||
txcd = &txc->vxcr_u.txcd[txc->vxcr_next]; | txcd = &txc->vxcr_u.txcd[txc->vxcr_next]; | ||||
if (txcd->gen != txc->vxcr_gen) | if (txcd->gen != txc->vxcr_gen) | ||||
break; | break; | ||||
vmxnet3_barrier(sc, VMXNET3_BARRIER_RD); | vmxnet3_barrier(sc, VMXNET3_BARRIER_RD); | ||||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | |||||
struct vmxnet3_rxcompdesc *rxcd; | struct vmxnet3_rxcompdesc *rxcd; | ||||
struct mbuf *m, *m_head, *m_tail; | struct mbuf *m, *m_head, *m_tail; | ||||
int idx, length; | int idx, length; | ||||
sc = rxq->vxrxq_sc; | sc = rxq->vxrxq_sc; | ||||
ifp = sc->vmx_ifp; | ifp = sc->vmx_ifp; | ||||
rxc = &rxq->vxrxq_comp_ring; | rxc = &rxq->vxrxq_comp_ring; | ||||
#ifdef DEV_NETMAP | |||||
{ | |||||
int dummy; | |||||
if (netmap_rx_irq(ifp, rxq - sc->vmx_rxq, &dummy) != NM_IRQ_PASS) | |||||
vmaffione: Can you please break this long line? Second level indents are four spaces, see style(9) | |||||
return; | |||||
} | |||||
#endif | |||||
VMXNET3_RXQ_LOCK_ASSERT(rxq); | VMXNET3_RXQ_LOCK_ASSERT(rxq); | ||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) | if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) | ||||
return; | return; | ||||
m_head = rxq->vxrxq_mhead; | m_head = rxq->vxrxq_mhead; | ||||
rxq->vxrxq_mhead = NULL; | rxq->vxrxq_mhead = NULL; | ||||
m_tail = rxq->vxrxq_mtail; | m_tail = rxq->vxrxq_mtail; | ||||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | |||||
static void | static void | ||||
vmxnet3_stop_rendezvous(struct vmxnet3_softc *sc) | vmxnet3_stop_rendezvous(struct vmxnet3_softc *sc) | ||||
{ | { | ||||
struct vmxnet3_rxqueue *rxq; | struct vmxnet3_rxqueue *rxq; | ||||
struct vmxnet3_txqueue *txq; | struct vmxnet3_txqueue *txq; | ||||
int i; | int i; | ||||
#ifdef DEV_NETMAP | |||||
netmap_disable_all_rings(sc->vmx_ifp); | |||||
#endif | |||||
for (i = 0; i < sc->vmx_nrxqueues; i++) { | for (i = 0; i < sc->vmx_nrxqueues; i++) { | ||||
rxq = &sc->vmx_rxq[i]; | rxq = &sc->vmx_rxq[i]; | ||||
VMXNET3_RXQ_LOCK(rxq); | VMXNET3_RXQ_LOCK(rxq); | ||||
VMXNET3_RXQ_UNLOCK(rxq); | VMXNET3_RXQ_UNLOCK(rxq); | ||||
} | } | ||||
for (i = 0; i < sc->vmx_ntxqueues; i++) { | for (i = 0; i < sc->vmx_ntxqueues; i++) { | ||||
txq = &sc->vmx_txq[i]; | txq = &sc->vmx_txq[i]; | ||||
Show All 37 Lines | |||||
txr = &txq->vxtxq_cmd_ring; | txr = &txq->vxtxq_cmd_ring; | ||||
txr->vxtxr_head = 0; | txr->vxtxr_head = 0; | ||||
txr->vxtxr_next = 0; | txr->vxtxr_next = 0; | ||||
txr->vxtxr_gen = VMXNET3_INIT_GEN; | txr->vxtxr_gen = VMXNET3_INIT_GEN; | ||||
bzero(txr->vxtxr_txd, | bzero(txr->vxtxr_txd, | ||||
txr->vxtxr_ndesc * sizeof(struct vmxnet3_txdesc)); | txr->vxtxr_ndesc * sizeof(struct vmxnet3_txdesc)); | ||||
#ifdef DEV_NETMAP | |||||
vmxnet3_netmap_txq_init(sc, txq); | |||||
#endif | |||||
txc = &txq->vxtxq_comp_ring; | txc = &txq->vxtxq_comp_ring; | ||||
txc->vxcr_next = 0; | txc->vxcr_next = 0; | ||||
txc->vxcr_gen = VMXNET3_INIT_GEN; | txc->vxcr_gen = VMXNET3_INIT_GEN; | ||||
bzero(txc->vxcr_u.txcd, | bzero(txc->vxcr_u.txcd, | ||||
txc->vxcr_ndesc * sizeof(struct vmxnet3_txcompdesc)); | txc->vxcr_ndesc * sizeof(struct vmxnet3_txcompdesc)); | ||||
} | } | ||||
static int | static int | ||||
vmxnet3_rxinit(struct vmxnet3_softc *sc, struct vmxnet3_rxqueue *rxq) | vmxnet3_rxinit(struct vmxnet3_softc *sc, struct vmxnet3_rxqueue *rxq) | ||||
{ | { | ||||
struct ifnet *ifp; | struct ifnet *ifp; | ||||
struct vmxnet3_rxring *rxr; | struct vmxnet3_rxring *rxr; | ||||
struct vmxnet3_comp_ring *rxc; | struct vmxnet3_comp_ring *rxc; | ||||
int i, populate, idx, frame_size, error; | int i, populate, idx, frame_size, error; | ||||
#ifdef DEV_NETMAP | |||||
struct netmap_adapter *na; | |||||
struct netmap_slot *slot; | |||||
#endif | |||||
ifp = sc->vmx_ifp; | ifp = sc->vmx_ifp; | ||||
frame_size = ETHER_ALIGN + sizeof(struct ether_vlan_header) + | frame_size = ETHER_ALIGN + sizeof(struct ether_vlan_header) + | ||||
ifp->if_mtu; | ifp->if_mtu; | ||||
/* | /* | ||||
* If the MTU causes us to exceed what a regular sized cluster can | * If the MTU causes us to exceed what a regular sized cluster can | ||||
* handle, we allocate a second MJUMPAGESIZE cluster after it in | * handle, we allocate a second MJUMPAGESIZE cluster after it in | ||||
Show All 14 Lines | |||||
* exceeds what ring 0 can contain. | * exceeds what ring 0 can contain. | ||||
*/ | */ | ||||
if ((ifp->if_capenable & IFCAP_LRO) == 0 && | if ((ifp->if_capenable & IFCAP_LRO) == 0 && | ||||
frame_size <= MCLBYTES + MJUMPAGESIZE) | frame_size <= MCLBYTES + MJUMPAGESIZE) | ||||
populate = 1; | populate = 1; | ||||
else | else | ||||
populate = VMXNET3_RXRINGS_PERQ; | populate = VMXNET3_RXRINGS_PERQ; | ||||
#ifdef DEV_NETMAP | |||||
na = NA(ifp); | |||||
slot = netmap_reset(na, NR_RX, rxq - sc->vmx_rxq, 0); | |||||
#endif | |||||
for (i = 0; i < populate; i++) { | for (i = 0; i < populate; i++) { | ||||
rxr = &rxq->vxrxq_cmd_ring[i]; | rxr = &rxq->vxrxq_cmd_ring[i]; | ||||
rxr->vxrxr_fill = 0; | rxr->vxrxr_fill = 0; | ||||
rxr->vxrxr_gen = VMXNET3_INIT_GEN; | rxr->vxrxr_gen = VMXNET3_INIT_GEN; | ||||
bzero(rxr->vxrxr_rxd, | bzero(rxr->vxrxr_rxd, | ||||
rxr->vxrxr_ndesc * sizeof(struct vmxnet3_rxdesc)); | rxr->vxrxr_ndesc * sizeof(struct vmxnet3_rxdesc)); | ||||
#ifdef DEV_NETMAP | |||||
if (slot != NULL) { | |||||
vmxnet3_netmap_rxq_init(sc, rxq, rxr, slot); | |||||
i = populate; | |||||
break; | |||||
} | |||||
#endif | |||||
for (idx = 0; idx < rxr->vxrxr_ndesc; idx++) { | for (idx = 0; idx < rxr->vxrxr_ndesc; idx++) { | ||||
error = vmxnet3_newbuf(sc, rxr); | error = vmxnet3_newbuf(sc, rxr); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | |||||
if (vmxnet3_reinit(sc) != 0) { | if (vmxnet3_reinit(sc) != 0) { | ||||
vmxnet3_stop(sc); | vmxnet3_stop(sc); | ||||
return; | return; | ||||
} | } | ||||
ifp->if_drv_flags |= IFF_DRV_RUNNING; | ifp->if_drv_flags |= IFF_DRV_RUNNING; | ||||
vmxnet3_link_status(sc); | vmxnet3_link_status(sc); | ||||
#ifdef DEV_NETMAP | |||||
netmap_enable_all_rings(ifp); | |||||
#endif | |||||
vmxnet3_enable_all_intrs(sc); | vmxnet3_enable_all_intrs(sc); | ||||
callout_reset(&sc->vmx_tick, hz, vmxnet3_tick, sc); | callout_reset(&sc->vmx_tick, hz, vmxnet3_tick, sc); | ||||
} | } | ||||
static void | static void | ||||
vmxnet3_init(void *xsc) | vmxnet3_init(void *xsc) | ||||
{ | { | ||||
struct vmxnet3_softc *sc; | struct vmxnet3_softc *sc; | ||||
Show All 22 Lines |
Can you please break this long line? Second level indents are four spaces, see style(9)