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