freebsd-skq/sys/dev/vmware/vmxnet3/if_vmxvar.h
bryanv 4b0fdddd62 Few more minor if_vmx tweaks
- Allow the Rx/Tx queue sizes to be configured by tunables
 - Bail out earlier if the Tx queue unlikely has enough free
   descriptors to hold the frame
 - Cleanup some of the offloading capabilities handling
2013-08-30 05:53:00 +00:00

327 lines
8.5 KiB
C

/*-
* Copyright (c) 2013 Tsubai Masanari
* Copyright (c) 2013 Bryan Venteicher <bryanv@FreeBSD.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $FreeBSD$
*/
#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;
};
/*
* The number of Rx/Tx queues this driver supports.
*/
#define VMXNET3_RX_QUEUES 1
#define VMXNET3_TX_QUEUES 1
/*
* The number of Rx rings in each Rx queue.
*/
#define VMXNET3_RXRINGS_PERQ 2
/*
* The number of descriptors in each Rx/Tx ring.
*/
#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 vtxrs_full;
uint64_t vtxrs_offload_failed;
};
struct vmxnet3_txqueue {
struct mtx vxtxq_mtx;
struct vmxnet3_softc *vxtxq_sc;
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;
char vxtxq_name[16];
};
#define VMXNET3_TXQ_LOCK(_txq) mtx_lock(&(_txq)->vxtxq_mtx)
#define VMXNET3_TXQ_TRYLOCK(_txq) mtx_trylock(&(_txq)->vxtxq_mtx)
#define VMXNET3_TXQ_UNLOCK(_txq) mtx_unlock(&(_txq)->vxtxq_mtx)
#define VMXNET3_TXQ_LOCK_ASSERT(_txq) \
mtx_assert(&(_txq)->vxtxq_mtx, MA_OWNED)
#define VMXNET3_TXQ_LOCK_ASSERT_NOTOWNED(_txq) \
mtx_assert(&(_txq)->vxtxq_mtx, MA_NOTOWNED)
struct vmxnet3_rxq_stats {
};
struct vmxnet3_rxqueue {
struct mtx vxrxq_mtx;
struct vmxnet3_softc *vxrxq_sc;
int vxrxq_id;
int vxrxq_intr_idx;
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];
};
#define VMXNET3_RXQ_LOCK(_rxq) mtx_lock(&(_rxq)->vxrxq_mtx)
#define VMXNET3_RXQ_UNLOCK(_rxq) mtx_unlock(&(_rxq)->vxrxq_mtx)
#define VMXNET3_RXQ_LOCK_ASSERT(_rxq) \
mtx_assert(&(_rxq)->vxrxq_mtx, MA_OWNED)
#define VMXNET3_RXQ_LOCK_ASSERT_NOTOWNED(_rxq) \
mtx_assert(&(_rxq)->vxrxq_mtx, MA_NOTOWNED)
struct vmxnet3_statistics {
uint32_t vmst_collapsed;
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
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_intr_type;
int vmx_intr_mask_mode;
int vmx_event_intr_idx;
int vmx_nintrs;
struct vmxnet3_interrupt vmx_intrs[VMXNET3_MAX_INTRS];
struct mtx vmx_mtx;
uint8_t *vmx_mcast;
void *vmx_qs;
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 ifmedia vmx_media;
eventhandler_tag vmx_vlan_attach;
eventhandler_tag vmx_vlan_detach;
uint8_t vmx_vlan_filter[4096/32];
uint8_t vmx_lladdr[ETHER_ADDR_LEN];
};
#define VMXNET3_CORE_LOCK_INIT(_sc, _name) \
mtx_init(&(_sc)->vmx_mtx, _name, "VMXNET3 Lock", MTX_DEF)
#define VMXNET3_CORE_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->vmx_mtx)
#define VMXNET3_CORE_LOCK(_sc) mtx_lock(&(_sc)->vmx_mtx)
#define VMXNET3_CORE_UNLOCK(_sc) mtx_unlock(&(_sc)->vmx_mtx)
#define VMXNET3_CORE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->vmx_mtx, MA_OWNED)
#define VMXNET3_CORE_LOCK_ASSERT_NOTOWNED(_sc) \
mtx_assert(&(_sc)->vmx_mtx, MA_NOTOWNED)
/*
* Our driver version we report to the hypervisor; we just keep
* this value constant.
*/
#define VMXNET3_DRIVER_VERSION 0x00010000
/*
* Convert the FreeBSD version in to something the hypervisor
* understands. This is apparently what VMware's driver reports
* so mimic it even though it probably is not required.
*/
#define VMXNET3_GUEST_OS_VERSION \
(((__FreeBSD_version / 100000) << 14) | \
(((__FreeBSD_version / 1000) % 100) << 6 ) | \
(((__FreeBSD_version / 100) % 10) << 30) | \
((__FreeBSD_version % 100) << 22))
/*
* Max descriptors per Tx packet. We must limit the size of the
* any TSO packets based on the number of segments.
*/
#define VMXNET3_TX_MAXSEGS 32
#define VMXNET3_TSO_MAXSIZE 65550
/*
* Maximum support Tx segments size. The length field in the
* Tx descriptor is 14 bits.
*/
#define VMXNET3_TX_MAXSEGSIZE (1 << 14)
/*
* The maximum number of Rx segments we accept. When LRO is enabled,
* this allows us to receive the maximum sized frame with one MCLBYTES
* cluster followed by 16 MJUMPAGESIZE clusters.
*/
#define VMXNET3_MAX_RX_SEGS 17
/*
* Predetermined size of the multicast MACs filter table. If the
* number of multicast addresses exceeds this size, then the
* ALL_MULTI mode is use instead.
*/
#define VMXNET3_MULTICAST_MAX 32
/*
* Our Tx watchdog timeout.
*/
#define VMXNET3_WATCHDOG_TIMEOUT 5
/*
* IP protocols that we can perform Tx checksum offloading of.
*/
#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)
/*
* Compat macros to keep this driver compiling on old releases.
*/
#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 /* _IF_VMXVAR_H */