#ifndef _IF_VMXVAR_H
#define _IF_VMXVAR_H
struct vmxnet3_softc;
struct vmxnet3_dma_alloc {
bus_addr_t dma_paddr;
caddr_t dma_vaddr;
bus_dma_tag_t dma_tag;
bus_dmamap_t dma_map;
bus_size_t dma_size;
};
#define VMXNET3_DEF_RX_QUEUES 8
#define VMXNET3_DEF_TX_QUEUES 8
#define VMXNET3_RXRINGS_PERQ 2
#define VMXNET3_DEF_TX_NDESC 512
#define VMXNET3_MAX_TX_NDESC 4096
#define VMXNET3_MIN_TX_NDESC 32
#define VMXNET3_MASK_TX_NDESC 0x1F
#define VMXNET3_DEF_RX_NDESC 256
#define VMXNET3_MAX_RX_NDESC 2048
#define VMXNET3_MIN_RX_NDESC 32
#define VMXNET3_MASK_RX_NDESC 0x1F
#define VMXNET3_MAX_TX_NCOMPDESC VMXNET3_MAX_TX_NDESC
#define VMXNET3_MAX_RX_NCOMPDESC \
(VMXNET3_MAX_RX_NDESC * VMXNET3_RXRINGS_PERQ)
struct vmxnet3_txbuf {
bus_dmamap_t vtxb_dmamap;
struct mbuf *vtxb_m;
};
struct vmxnet3_txring {
struct vmxnet3_txbuf *vxtxr_txbuf;
u_int vxtxr_head;
u_int vxtxr_next;
u_int vxtxr_ndesc;
int vxtxr_gen;
bus_dma_tag_t vxtxr_txtag;
struct vmxnet3_txdesc *vxtxr_txd;
struct vmxnet3_dma_alloc vxtxr_dma;
};
static inline int
VMXNET3_TXRING_AVAIL(struct vmxnet3_txring *txr)
{
int avail = txr->vxtxr_next - txr->vxtxr_head - 1;
return (avail < 0 ? txr->vxtxr_ndesc + avail : avail);
}
struct vmxnet3_rxbuf {
bus_dmamap_t vrxb_dmamap;
struct mbuf *vrxb_m;
};
struct vmxnet3_rxring {
struct vmxnet3_rxbuf *vxrxr_rxbuf;
struct vmxnet3_rxdesc *vxrxr_rxd;
u_int vxrxr_fill;
u_int vxrxr_ndesc;
int vxrxr_gen;
int vxrxr_rid;
bus_dma_tag_t vxrxr_rxtag;
struct vmxnet3_dma_alloc vxrxr_dma;
bus_dmamap_t vxrxr_spare_dmap;
};
static inline void
vmxnet3_rxr_increment_fill(struct vmxnet3_rxring *rxr)
{
if (++rxr->vxrxr_fill == rxr->vxrxr_ndesc) {
rxr->vxrxr_fill = 0;
rxr->vxrxr_gen ^= 1;
}
}
struct vmxnet3_comp_ring {
union {
struct vmxnet3_txcompdesc *txcd;
struct vmxnet3_rxcompdesc *rxcd;
} vxcr_u;
u_int vxcr_next;
u_int vxcr_ndesc;
int vxcr_gen;
struct vmxnet3_dma_alloc vxcr_dma;
};
struct vmxnet3_txq_stats {
uint64_t vmtxs_opackets;
uint64_t vmtxs_obytes;
uint64_t vmtxs_omcasts;
uint64_t vmtxs_csum;
uint64_t vmtxs_tso;
uint64_t vmtxs_full;
uint64_t vmtxs_offload_failed;
};
struct vmxnet3_txqueue {
struct lock vxtxq_lock;
struct vmxnet3_softc *vxtxq_sc;
#ifndef VMXNET3_LEGACY_TX
struct buf_ring *vxtxq_br;
#endif
int vxtxq_id;
int vxtxq_intr_idx;
int vxtxq_watchdog;
struct vmxnet3_txring vxtxq_cmd_ring;
struct vmxnet3_comp_ring vxtxq_comp_ring;
struct vmxnet3_txq_stats vxtxq_stats;
struct vmxnet3_txq_shared *vxtxq_ts;
struct sysctl_oid_list *vxtxq_sysctl;
#ifndef VMXNET3_LEGACY_TX
struct task vxtxq_defrtask;
#endif
char vxtxq_name[16];
} __cachealign;
#define VMXNET3_TXQ_LOCK(_txq) lockmgr(&(_txq)->vxtxq_lock, LK_EXCLUSIVE)
#define VMXNET3_TXQ_TRYLOCK(_txq) lockmgr_try(&(_txq)->vxtxq_lock, LK_EXCLUSIVE)
#define VMXNET3_TXQ_UNLOCK(_txq) lockmgr(&(_txq)->vxtxq_lock, LK_RELEASE)
#define VMXNET3_TXQ_LOCK_ASSERT(_txq) \
KKASSERT(lockowned(&(_txq)->vxtxq_lock) != 0)
#define VMXNET3_TXQ_LOCK_ASSERT_NOTOWNED(_txq) \
KKASSERT(lockowned(&(_txq)->vxtxq_lock) == 0)
struct vmxnet3_rxq_stats {
uint64_t vmrxs_ipackets;
uint64_t vmrxs_ibytes;
uint64_t vmrxs_iqdrops;
uint64_t vmrxs_ierrors;
};
struct vmxnet3_rxqueue {
struct lock vxrxq_lock;
struct vmxnet3_softc *vxrxq_sc;
int vxrxq_id;
int vxrxq_intr_idx;
struct mbuf *vxrxq_mhead;
struct mbuf *vxrxq_mtail;
struct vmxnet3_rxring vxrxq_cmd_ring[VMXNET3_RXRINGS_PERQ];
struct vmxnet3_comp_ring vxrxq_comp_ring;
struct vmxnet3_rxq_stats vxrxq_stats;
struct vmxnet3_rxq_shared *vxrxq_rs;
struct sysctl_oid_list *vxrxq_sysctl;
char vxrxq_name[16];
} __cachealign;
#define VMXNET3_RXQ_LOCK(_rxq) lockmgr(&(_rxq)->vxrxq_lock, LK_EXCLUSIVE)
#define VMXNET3_RXQ_UNLOCK(_rxq) lockmgr(&(_rxq)->vxrxq_lock, LK_RELEASE)
#define VMXNET3_RXQ_LOCK_ASSERT(_rxq) \
KKASSERT(lockowned(&(_rxq)->vxrxq_lock) != 0)
#define VMXNET3_RXQ_LOCK_ASSERT_NOTOWNED(_rxq) \
KKASSERT(lockowned(&(_rxq)->vxrxq_lock) == 0)
struct vmxnet3_statistics {
uint32_t vmst_defragged;
uint32_t vmst_defrag_failed;
uint32_t vmst_mgetcl_failed;
uint32_t vmst_mbuf_load_failed;
};
struct vmxnet3_interrupt {
struct resource *vmxi_irq;
int vmxi_rid;
void *vmxi_handler;
};
struct vmxnet3_softc {
device_t vmx_dev;
struct ifnet *vmx_ifp;
struct vmxnet3_driver_shared *vmx_ds;
uint32_t vmx_flags;
#define VMXNET3_FLAG_NO_MSIX 0x0001
#define VMXNET3_FLAG_RSS 0x0002
struct vmxnet3_rxqueue *vmx_rxq;
struct vmxnet3_txqueue *vmx_txq;
struct resource *vmx_res0;
bus_space_tag_t vmx_iot0;
bus_space_handle_t vmx_ioh0;
struct resource *vmx_res1;
bus_space_tag_t vmx_iot1;
bus_space_handle_t vmx_ioh1;
struct resource *vmx_msix_res;
int vmx_link_active;
int vmx_link_speed;
int vmx_if_flags;
int vmx_ntxqueues;
int vmx_nrxqueues;
int vmx_ntxdescs;
int vmx_nrxdescs;
int vmx_max_rxsegs;
int vmx_rx_max_chain;
struct vmxnet3_statistics vmx_stats;
int vmx_irq_type;
u_int vmx_irq_flags;
int vmx_intr_type;
int vmx_intr_mask_mode;
int vmx_event_intr_idx;
int vmx_nintrs;
struct vmxnet3_interrupt vmx_intrs[VMXNET3_MAX_INTRS];
struct lock vmx_lock;
#ifndef VMXNET3_LEGACY_TX
struct taskqueue *vmx_tq;
#endif
uint8_t *vmx_mcast;
void *vmx_qs;
struct vmxnet3_rss_shared *vmx_rss;
struct callout vmx_tick;
struct vmxnet3_dma_alloc vmx_ds_dma;
struct vmxnet3_dma_alloc vmx_qs_dma;
struct vmxnet3_dma_alloc vmx_mcast_dma;
struct vmxnet3_dma_alloc vmx_rss_dma;
struct ifmedia vmx_media;
int vmx_max_ntxqueues;
int vmx_max_nrxqueues;
eventhandler_tag vmx_vlan_attach;
eventhandler_tag vmx_vlan_detach;
uint32_t vmx_vlan_filter[4096/32];
uint8_t vmx_lladdr[ETHER_ADDR_LEN];
};
#define VMXNET3_CORE_LOCK_INIT(_sc, _name) \
lockinit(&(_sc)->vmx_lock, "VMXNET3 Lock", 0, 0)
#define VMXNET3_CORE_LOCK_DESTROY(_sc) lockuninit(&(_sc)->vmx_lock)
#define VMXNET3_CORE_LOCK(_sc) lockmgr(&(_sc)->vmx_lock, LK_EXCLUSIVE)
#define VMXNET3_CORE_UNLOCK(_sc) lockmgr(&(_sc)->vmx_lock, LK_RELEASE)
#define VMXNET3_CORE_LOCK_ASSERT(_sc) KKASSERT(lockowned(&(_sc)->vmx_lock) != 0)
#define VMXNET3_CORE_LOCK_ASSERT_NOTOWNED(_sc) \
KKASSERT(lockowned(&(_sc)->vmx_lock) == 0)
#define VMXNET3_DRIVER_VERSION 0x00010000
#define VMXNET3_TX_MAXSEGS 32
#define VMXNET3_TX_MAXSIZE (VMXNET3_TX_MAXSEGS * MCLBYTES)
#define VMXNET3_TX_MAXSEGSIZE (1 << 14)
#define VMXNET3_MAX_RX_SEGS 17
#define VMXNET3_MULTICAST_MAX 32
#define VMXNET3_WATCHDOG_TIMEOUT 5
#define VMXNET3_DEF_BUFRING_SIZE 4096
#define VMXNET3_CSUM_OFFLOAD (CSUM_TCP | CSUM_UDP)
#define VMXNET3_CSUM_OFFLOAD_IPV6 (CSUM_TCP_IPV6 | CSUM_UDP_IPV6)
#define VMXNET3_CSUM_ALL_OFFLOAD \
(VMXNET3_CSUM_OFFLOAD | VMXNET3_CSUM_OFFLOAD_IPV6 | CSUM_TSO)
#if !defined(SYSCTL_ADD_UQUAD)
#define SYSCTL_ADD_UQUAD SYSCTL_ADD_QUAD
#endif
#if !defined(IFCAP_TXCSUM_IPV6)
#define IFCAP_TXCSUM_IPV6 0
#endif
#if !defined(IFCAP_RXCSUM_IPV6)
#define IFCAP_RXCSUM_IPV6 0
#endif
#if !defined(CSUM_TCP_IPV6)
#define CSUM_TCP_IPV6 0
#endif
#if !defined(CSUM_UDP_IPV6)
#define CSUM_UDP_IPV6 0
#endif
#endif