1254738Sbryanv/*- 2254738Sbryanv * Copyright (c) 2013 Tsubai Masanari 3254738Sbryanv * Copyright (c) 2013 Bryan Venteicher <bryanv@FreeBSD.org> 4254738Sbryanv * 5254738Sbryanv * Permission to use, copy, modify, and distribute this software for any 6254738Sbryanv * purpose with or without fee is hereby granted, provided that the above 7254738Sbryanv * copyright notice and this permission notice appear in all copies. 8254738Sbryanv * 9254738Sbryanv * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10254738Sbryanv * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11254738Sbryanv * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12254738Sbryanv * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13254738Sbryanv * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14254738Sbryanv * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15254738Sbryanv * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16254738Sbryanv * 17254738Sbryanv * $FreeBSD: stable/11/sys/dev/vmware/vmxnet3/if_vmxvar.h 337856 2018-08-15 16:16:59Z loos $ 18254738Sbryanv */ 19254738Sbryanv 20254738Sbryanv#ifndef _IF_VMXVAR_H 21254738Sbryanv#define _IF_VMXVAR_H 22254738Sbryanv 23254738Sbryanvstruct vmxnet3_softc; 24254738Sbryanv 25254738Sbryanvstruct vmxnet3_dma_alloc { 26254738Sbryanv bus_addr_t dma_paddr; 27254738Sbryanv caddr_t dma_vaddr; 28254738Sbryanv bus_dma_tag_t dma_tag; 29254738Sbryanv bus_dmamap_t dma_map; 30254738Sbryanv bus_size_t dma_size; 31254738Sbryanv}; 32254738Sbryanv 33254738Sbryanv/* 34263259Sbryanv * The number of Rx/Tx queues this driver prefers. 35254738Sbryanv */ 36263259Sbryanv#define VMXNET3_DEF_RX_QUEUES 8 37263259Sbryanv#define VMXNET3_DEF_TX_QUEUES 8 38254738Sbryanv 39254738Sbryanv/* 40254738Sbryanv * The number of Rx rings in each Rx queue. 41254738Sbryanv */ 42254738Sbryanv#define VMXNET3_RXRINGS_PERQ 2 43254738Sbryanv 44254738Sbryanv/* 45255055Sbryanv * The number of descriptors in each Rx/Tx ring. 46254738Sbryanv */ 47255055Sbryanv#define VMXNET3_DEF_TX_NDESC 512 48255055Sbryanv#define VMXNET3_MAX_TX_NDESC 4096 49255055Sbryanv#define VMXNET3_MIN_TX_NDESC 32 50255055Sbryanv#define VMXNET3_MASK_TX_NDESC 0x1F 51255055Sbryanv#define VMXNET3_DEF_RX_NDESC 256 52255055Sbryanv#define VMXNET3_MAX_RX_NDESC 2048 53255055Sbryanv#define VMXNET3_MIN_RX_NDESC 32 54255055Sbryanv#define VMXNET3_MASK_RX_NDESC 0x1F 55255055Sbryanv 56254738Sbryanv#define VMXNET3_MAX_TX_NCOMPDESC VMXNET3_MAX_TX_NDESC 57254738Sbryanv#define VMXNET3_MAX_RX_NCOMPDESC \ 58254738Sbryanv (VMXNET3_MAX_RX_NDESC * VMXNET3_RXRINGS_PERQ) 59254738Sbryanv 60254738Sbryanvstruct vmxnet3_txbuf { 61254738Sbryanv bus_dmamap_t vtxb_dmamap; 62254738Sbryanv struct mbuf *vtxb_m; 63254738Sbryanv}; 64254738Sbryanv 65254738Sbryanvstruct vmxnet3_txring { 66254738Sbryanv struct vmxnet3_txbuf *vxtxr_txbuf; 67254738Sbryanv u_int vxtxr_head; 68254738Sbryanv u_int vxtxr_next; 69254738Sbryanv u_int vxtxr_ndesc; 70254738Sbryanv int vxtxr_gen; 71254738Sbryanv bus_dma_tag_t vxtxr_txtag; 72254738Sbryanv struct vmxnet3_txdesc *vxtxr_txd; 73254738Sbryanv struct vmxnet3_dma_alloc vxtxr_dma; 74254738Sbryanv}; 75254738Sbryanv 76254738Sbryanvstatic inline int 77254738SbryanvVMXNET3_TXRING_AVAIL(struct vmxnet3_txring *txr) 78254738Sbryanv{ 79254738Sbryanv int avail = txr->vxtxr_next - txr->vxtxr_head - 1; 80254738Sbryanv return (avail < 0 ? txr->vxtxr_ndesc + avail : avail); 81254738Sbryanv} 82254738Sbryanv 83254738Sbryanvstruct vmxnet3_rxbuf { 84254738Sbryanv bus_dmamap_t vrxb_dmamap; 85254738Sbryanv struct mbuf *vrxb_m; 86254738Sbryanv}; 87254738Sbryanv 88254738Sbryanvstruct vmxnet3_rxring { 89254738Sbryanv struct vmxnet3_rxbuf *vxrxr_rxbuf; 90254738Sbryanv struct vmxnet3_rxdesc *vxrxr_rxd; 91254738Sbryanv u_int vxrxr_fill; 92254738Sbryanv u_int vxrxr_ndesc; 93254738Sbryanv int vxrxr_gen; 94254738Sbryanv int vxrxr_rid; 95254738Sbryanv bus_dma_tag_t vxrxr_rxtag; 96254738Sbryanv struct vmxnet3_dma_alloc vxrxr_dma; 97254738Sbryanv bus_dmamap_t vxrxr_spare_dmap; 98254738Sbryanv}; 99254738Sbryanv 100254738Sbryanvstatic inline void 101254738Sbryanvvmxnet3_rxr_increment_fill(struct vmxnet3_rxring *rxr) 102254738Sbryanv{ 103254738Sbryanv 104254738Sbryanv if (++rxr->vxrxr_fill == rxr->vxrxr_ndesc) { 105254738Sbryanv rxr->vxrxr_fill = 0; 106254738Sbryanv rxr->vxrxr_gen ^= 1; 107254738Sbryanv } 108254738Sbryanv} 109254738Sbryanv 110254738Sbryanvstruct vmxnet3_comp_ring { 111254738Sbryanv union { 112254738Sbryanv struct vmxnet3_txcompdesc *txcd; 113254738Sbryanv struct vmxnet3_rxcompdesc *rxcd; 114254738Sbryanv } vxcr_u; 115254738Sbryanv u_int vxcr_next; 116254738Sbryanv u_int vxcr_ndesc; 117254738Sbryanv int vxcr_gen; 118254738Sbryanv struct vmxnet3_dma_alloc vxcr_dma; 119254738Sbryanv}; 120254738Sbryanv 121254738Sbryanvstruct vmxnet3_txq_stats { 122263259Sbryanv uint64_t vmtxs_opackets; /* if_opackets */ 123263259Sbryanv uint64_t vmtxs_obytes; /* if_obytes */ 124263259Sbryanv uint64_t vmtxs_omcasts; /* if_omcasts */ 125263259Sbryanv uint64_t vmtxs_csum; 126263259Sbryanv uint64_t vmtxs_tso; 127263259Sbryanv uint64_t vmtxs_full; 128263259Sbryanv uint64_t vmtxs_offload_failed; 129254738Sbryanv}; 130254738Sbryanv 131254738Sbryanvstruct vmxnet3_txqueue { 132254738Sbryanv struct mtx vxtxq_mtx; 133254738Sbryanv struct vmxnet3_softc *vxtxq_sc; 134337856Sloos#ifndef VMXNET3_LEGACY_TX 135263259Sbryanv struct buf_ring *vxtxq_br; 136263259Sbryanv#endif 137254738Sbryanv int vxtxq_id; 138254738Sbryanv int vxtxq_intr_idx; 139254738Sbryanv int vxtxq_watchdog; 140254738Sbryanv struct vmxnet3_txring vxtxq_cmd_ring; 141254738Sbryanv struct vmxnet3_comp_ring vxtxq_comp_ring; 142254738Sbryanv struct vmxnet3_txq_stats vxtxq_stats; 143254738Sbryanv struct vmxnet3_txq_shared *vxtxq_ts; 144254738Sbryanv struct sysctl_oid_list *vxtxq_sysctl; 145337856Sloos#ifndef VMXNET3_LEGACY_TX 146263259Sbryanv struct task vxtxq_defrtask; 147263259Sbryanv#endif 148254738Sbryanv char vxtxq_name[16]; 149263259Sbryanv} __aligned(CACHE_LINE_SIZE); 150254738Sbryanv 151254738Sbryanv#define VMXNET3_TXQ_LOCK(_txq) mtx_lock(&(_txq)->vxtxq_mtx) 152254738Sbryanv#define VMXNET3_TXQ_TRYLOCK(_txq) mtx_trylock(&(_txq)->vxtxq_mtx) 153254738Sbryanv#define VMXNET3_TXQ_UNLOCK(_txq) mtx_unlock(&(_txq)->vxtxq_mtx) 154254738Sbryanv#define VMXNET3_TXQ_LOCK_ASSERT(_txq) \ 155254738Sbryanv mtx_assert(&(_txq)->vxtxq_mtx, MA_OWNED) 156254738Sbryanv#define VMXNET3_TXQ_LOCK_ASSERT_NOTOWNED(_txq) \ 157254738Sbryanv mtx_assert(&(_txq)->vxtxq_mtx, MA_NOTOWNED) 158254738Sbryanv 159254738Sbryanvstruct vmxnet3_rxq_stats { 160263259Sbryanv uint64_t vmrxs_ipackets; /* if_ipackets */ 161263259Sbryanv uint64_t vmrxs_ibytes; /* if_ibytes */ 162263259Sbryanv uint64_t vmrxs_iqdrops; /* if_iqdrops */ 163263259Sbryanv uint64_t vmrxs_ierrors; /* if_ierrors */ 164254738Sbryanv}; 165254738Sbryanv 166254738Sbryanvstruct vmxnet3_rxqueue { 167254738Sbryanv struct mtx vxrxq_mtx; 168254738Sbryanv struct vmxnet3_softc *vxrxq_sc; 169254738Sbryanv int vxrxq_id; 170254738Sbryanv int vxrxq_intr_idx; 171267662Sbryanv struct mbuf *vxrxq_mhead; 172267662Sbryanv struct mbuf *vxrxq_mtail; 173254738Sbryanv struct vmxnet3_rxring vxrxq_cmd_ring[VMXNET3_RXRINGS_PERQ]; 174254738Sbryanv struct vmxnet3_comp_ring vxrxq_comp_ring; 175254738Sbryanv struct vmxnet3_rxq_stats vxrxq_stats; 176254738Sbryanv struct vmxnet3_rxq_shared *vxrxq_rs; 177254738Sbryanv struct sysctl_oid_list *vxrxq_sysctl; 178254738Sbryanv char vxrxq_name[16]; 179263259Sbryanv} __aligned(CACHE_LINE_SIZE); 180254738Sbryanv 181254738Sbryanv#define VMXNET3_RXQ_LOCK(_rxq) mtx_lock(&(_rxq)->vxrxq_mtx) 182254738Sbryanv#define VMXNET3_RXQ_UNLOCK(_rxq) mtx_unlock(&(_rxq)->vxrxq_mtx) 183254738Sbryanv#define VMXNET3_RXQ_LOCK_ASSERT(_rxq) \ 184254738Sbryanv mtx_assert(&(_rxq)->vxrxq_mtx, MA_OWNED) 185254738Sbryanv#define VMXNET3_RXQ_LOCK_ASSERT_NOTOWNED(_rxq) \ 186254738Sbryanv mtx_assert(&(_rxq)->vxrxq_mtx, MA_NOTOWNED) 187254738Sbryanv 188254738Sbryanvstruct vmxnet3_statistics { 189263259Sbryanv uint32_t vmst_defragged; 190263259Sbryanv uint32_t vmst_defrag_failed; 191254738Sbryanv uint32_t vmst_mgetcl_failed; 192254738Sbryanv uint32_t vmst_mbuf_load_failed; 193254738Sbryanv}; 194254738Sbryanv 195254738Sbryanvstruct vmxnet3_interrupt { 196254738Sbryanv struct resource *vmxi_irq; 197254738Sbryanv int vmxi_rid; 198254738Sbryanv void *vmxi_handler; 199254738Sbryanv}; 200254738Sbryanv 201254738Sbryanvstruct vmxnet3_softc { 202254738Sbryanv device_t vmx_dev; 203254738Sbryanv struct ifnet *vmx_ifp; 204254738Sbryanv struct vmxnet3_driver_shared *vmx_ds; 205254738Sbryanv uint32_t vmx_flags; 206254738Sbryanv#define VMXNET3_FLAG_NO_MSIX 0x0001 207263259Sbryanv#define VMXNET3_FLAG_RSS 0x0002 208254738Sbryanv 209254738Sbryanv struct vmxnet3_rxqueue *vmx_rxq; 210254738Sbryanv struct vmxnet3_txqueue *vmx_txq; 211254738Sbryanv 212254738Sbryanv struct resource *vmx_res0; 213254738Sbryanv bus_space_tag_t vmx_iot0; 214254738Sbryanv bus_space_handle_t vmx_ioh0; 215254738Sbryanv struct resource *vmx_res1; 216254738Sbryanv bus_space_tag_t vmx_iot1; 217254738Sbryanv bus_space_handle_t vmx_ioh1; 218254738Sbryanv struct resource *vmx_msix_res; 219254738Sbryanv 220254738Sbryanv int vmx_link_active; 221254738Sbryanv int vmx_link_speed; 222254738Sbryanv int vmx_if_flags; 223254738Sbryanv int vmx_ntxqueues; 224254738Sbryanv int vmx_nrxqueues; 225254738Sbryanv int vmx_ntxdescs; 226254738Sbryanv int vmx_nrxdescs; 227254738Sbryanv int vmx_max_rxsegs; 228254738Sbryanv int vmx_rx_max_chain; 229254738Sbryanv 230254738Sbryanv struct vmxnet3_statistics vmx_stats; 231254738Sbryanv 232254738Sbryanv int vmx_intr_type; 233254738Sbryanv int vmx_intr_mask_mode; 234254738Sbryanv int vmx_event_intr_idx; 235254738Sbryanv int vmx_nintrs; 236254738Sbryanv struct vmxnet3_interrupt vmx_intrs[VMXNET3_MAX_INTRS]; 237254738Sbryanv 238254738Sbryanv struct mtx vmx_mtx; 239263259Sbryanv#ifndef VMXNET3_LEGACY_TX 240263259Sbryanv struct taskqueue *vmx_tq; 241263259Sbryanv#endif 242254738Sbryanv uint8_t *vmx_mcast; 243254738Sbryanv void *vmx_qs; 244263259Sbryanv struct vmxnet3_rss_shared *vmx_rss; 245254738Sbryanv struct callout vmx_tick; 246254738Sbryanv struct vmxnet3_dma_alloc vmx_ds_dma; 247254738Sbryanv struct vmxnet3_dma_alloc vmx_qs_dma; 248254738Sbryanv struct vmxnet3_dma_alloc vmx_mcast_dma; 249263259Sbryanv struct vmxnet3_dma_alloc vmx_rss_dma; 250254738Sbryanv struct ifmedia vmx_media; 251263259Sbryanv int vmx_max_ntxqueues; 252263259Sbryanv int vmx_max_nrxqueues; 253254738Sbryanv eventhandler_tag vmx_vlan_attach; 254254738Sbryanv eventhandler_tag vmx_vlan_detach; 255255400Sbryanv uint32_t vmx_vlan_filter[4096/32]; 256254738Sbryanv uint8_t vmx_lladdr[ETHER_ADDR_LEN]; 257254738Sbryanv}; 258254738Sbryanv 259254738Sbryanv#define VMXNET3_CORE_LOCK_INIT(_sc, _name) \ 260254738Sbryanv mtx_init(&(_sc)->vmx_mtx, _name, "VMXNET3 Lock", MTX_DEF) 261254738Sbryanv#define VMXNET3_CORE_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->vmx_mtx) 262254738Sbryanv#define VMXNET3_CORE_LOCK(_sc) mtx_lock(&(_sc)->vmx_mtx) 263254738Sbryanv#define VMXNET3_CORE_UNLOCK(_sc) mtx_unlock(&(_sc)->vmx_mtx) 264254738Sbryanv#define VMXNET3_CORE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->vmx_mtx, MA_OWNED) 265254738Sbryanv#define VMXNET3_CORE_LOCK_ASSERT_NOTOWNED(_sc) \ 266254738Sbryanv mtx_assert(&(_sc)->vmx_mtx, MA_NOTOWNED) 267254738Sbryanv 268254738Sbryanv/* 269254738Sbryanv * Our driver version we report to the hypervisor; we just keep 270254738Sbryanv * this value constant. 271254738Sbryanv */ 272254738Sbryanv#define VMXNET3_DRIVER_VERSION 0x00010000 273254738Sbryanv 274254738Sbryanv/* 275254738Sbryanv * Max descriptors per Tx packet. We must limit the size of the 276254738Sbryanv * any TSO packets based on the number of segments. 277254738Sbryanv */ 278254738Sbryanv#define VMXNET3_TX_MAXSEGS 32 279263259Sbryanv#define VMXNET3_TX_MAXSIZE (VMXNET3_TX_MAXSEGS * MCLBYTES) 280254738Sbryanv 281254738Sbryanv/* 282254738Sbryanv * Maximum support Tx segments size. The length field in the 283254738Sbryanv * Tx descriptor is 14 bits. 284254738Sbryanv */ 285271551Shselasky#define VMXNET3_TX_MAXSEGSIZE (1 << 14) 286254738Sbryanv 287254738Sbryanv/* 288254950Sbryanv * The maximum number of Rx segments we accept. When LRO is enabled, 289254950Sbryanv * this allows us to receive the maximum sized frame with one MCLBYTES 290254950Sbryanv * cluster followed by 16 MJUMPAGESIZE clusters. 291254950Sbryanv */ 292254950Sbryanv#define VMXNET3_MAX_RX_SEGS 17 293254950Sbryanv 294254950Sbryanv/* 295254738Sbryanv * Predetermined size of the multicast MACs filter table. If the 296254738Sbryanv * number of multicast addresses exceeds this size, then the 297254738Sbryanv * ALL_MULTI mode is use instead. 298254738Sbryanv */ 299254738Sbryanv#define VMXNET3_MULTICAST_MAX 32 300254738Sbryanv 301254738Sbryanv/* 302254738Sbryanv * Our Tx watchdog timeout. 303254738Sbryanv */ 304254738Sbryanv#define VMXNET3_WATCHDOG_TIMEOUT 5 305254738Sbryanv 306254738Sbryanv/* 307263259Sbryanv * Number of slots in the Tx bufrings. This value matches most other 308263259Sbryanv * multiqueue drivers. 309263259Sbryanv */ 310263259Sbryanv#define VMXNET3_DEF_BUFRING_SIZE 4096 311263259Sbryanv 312263259Sbryanv/* 313254738Sbryanv * IP protocols that we can perform Tx checksum offloading of. 314254738Sbryanv */ 315254738Sbryanv#define VMXNET3_CSUM_OFFLOAD (CSUM_TCP | CSUM_UDP) 316254738Sbryanv#define VMXNET3_CSUM_OFFLOAD_IPV6 (CSUM_TCP_IPV6 | CSUM_UDP_IPV6) 317254738Sbryanv 318254738Sbryanv#define VMXNET3_CSUM_ALL_OFFLOAD \ 319254738Sbryanv (VMXNET3_CSUM_OFFLOAD | VMXNET3_CSUM_OFFLOAD_IPV6 | CSUM_TSO) 320254738Sbryanv 321254738Sbryanv/* 322254738Sbryanv * Compat macros to keep this driver compiling on old releases. 323254738Sbryanv */ 324254738Sbryanv 325254738Sbryanv#if !defined(SYSCTL_ADD_UQUAD) 326254738Sbryanv#define SYSCTL_ADD_UQUAD SYSCTL_ADD_QUAD 327254738Sbryanv#endif 328254738Sbryanv 329254738Sbryanv#if !defined(IFCAP_TXCSUM_IPV6) 330254738Sbryanv#define IFCAP_TXCSUM_IPV6 0 331254738Sbryanv#endif 332254738Sbryanv 333254738Sbryanv#if !defined(IFCAP_RXCSUM_IPV6) 334254738Sbryanv#define IFCAP_RXCSUM_IPV6 0 335254738Sbryanv#endif 336254738Sbryanv 337254738Sbryanv#if !defined(CSUM_TCP_IPV6) 338254738Sbryanv#define CSUM_TCP_IPV6 0 339254738Sbryanv#endif 340254738Sbryanv 341254738Sbryanv#if !defined(CSUM_UDP_IPV6) 342254738Sbryanv#define CSUM_UDP_IPV6 0 343254738Sbryanv#endif 344254738Sbryanv 345254738Sbryanv#endif /* _IF_VMXVAR_H */ 346