1*62dadd65SYuri Pankov /*
2*62dadd65SYuri Pankov  * Copyright (C) 2007 VMware, Inc. All rights reserved.
3*62dadd65SYuri Pankov  *
4*62dadd65SYuri Pankov  * The contents of this file are subject to the terms of the Common
5*62dadd65SYuri Pankov  * Development and Distribution License (the "License") version 1.0
6*62dadd65SYuri Pankov  * and no later version.  You may not use this file except in
7*62dadd65SYuri Pankov  * compliance with the License.
8*62dadd65SYuri Pankov  *
9*62dadd65SYuri Pankov  * You can obtain a copy of the License at
10*62dadd65SYuri Pankov  *         http://www.opensource.org/licenses/cddl1.php
11*62dadd65SYuri Pankov  *
12*62dadd65SYuri Pankov  * See the License for the specific language governing permissions
13*62dadd65SYuri Pankov  * and limitations under the License.
14*62dadd65SYuri Pankov  */
15*62dadd65SYuri Pankov 
16*62dadd65SYuri Pankov /*
17*62dadd65SYuri Pankov  * Copyright (c) 2012 by Delphix. All rights reserved.
18*62dadd65SYuri Pankov  */
19*62dadd65SYuri Pankov 
20*62dadd65SYuri Pankov #ifndef	_VMXNET3_H_
21*62dadd65SYuri Pankov #define	_VMXNET3_H_
22*62dadd65SYuri Pankov 
23*62dadd65SYuri Pankov #include <sys/atomic.h>
24*62dadd65SYuri Pankov #include <sys/types.h>
25*62dadd65SYuri Pankov #include <sys/conf.h>
26*62dadd65SYuri Pankov #include <sys/debug.h>
27*62dadd65SYuri Pankov #include <sys/cmn_err.h>
28*62dadd65SYuri Pankov #include <sys/stropts.h>
29*62dadd65SYuri Pankov #include <sys/stream.h>
30*62dadd65SYuri Pankov #include <sys/strlog.h>
31*62dadd65SYuri Pankov #include <sys/kmem.h>
32*62dadd65SYuri Pankov #include <sys/stat.h>
33*62dadd65SYuri Pankov #include <sys/kstat.h>
34*62dadd65SYuri Pankov #include <sys/vtrace.h>
35*62dadd65SYuri Pankov #include <sys/dlpi.h>
36*62dadd65SYuri Pankov #include <sys/strsun.h>
37*62dadd65SYuri Pankov #include <sys/ethernet.h>
38*62dadd65SYuri Pankov #include <sys/vlan.h>
39*62dadd65SYuri Pankov #include <sys/modctl.h>
40*62dadd65SYuri Pankov #include <sys/errno.h>
41*62dadd65SYuri Pankov #include <sys/ddi.h>
42*62dadd65SYuri Pankov #include <sys/sunddi.h>
43*62dadd65SYuri Pankov #include <sys/ddi_impldefs.h>
44*62dadd65SYuri Pankov #include <sys/pci.h>
45*62dadd65SYuri Pankov #include <sys/strsubr.h>
46*62dadd65SYuri Pankov #include <sys/pattr.h>
47*62dadd65SYuri Pankov #include <sys/mac.h>
48*62dadd65SYuri Pankov #include <sys/sockio.h>
49*62dadd65SYuri Pankov #include <sys/mac_provider.h>
50*62dadd65SYuri Pankov #include <sys/mac_ether.h>
51*62dadd65SYuri Pankov #include <inet/common.h>
52*62dadd65SYuri Pankov #include <inet/ip.h>
53*62dadd65SYuri Pankov #include <inet/tcp.h>
54*62dadd65SYuri Pankov 
55*62dadd65SYuri Pankov #include <vmxnet3_defs.h>
56*62dadd65SYuri Pankov 
57*62dadd65SYuri Pankov typedef struct vmxnet3_dmabuf_t {
58*62dadd65SYuri Pankov 	caddr_t		buf;
59*62dadd65SYuri Pankov 	uint64_t	bufPA;
60*62dadd65SYuri Pankov 	size_t		bufLen;
61*62dadd65SYuri Pankov 	ddi_dma_handle_t dmaHandle;
62*62dadd65SYuri Pankov 	ddi_acc_handle_t dataHandle;
63*62dadd65SYuri Pankov } vmxnet3_dmabuf_t;
64*62dadd65SYuri Pankov 
65*62dadd65SYuri Pankov typedef struct vmxnet3_cmdring_t {
66*62dadd65SYuri Pankov 	vmxnet3_dmabuf_t dma;
67*62dadd65SYuri Pankov 	uint16_t	size;
68*62dadd65SYuri Pankov 	uint16_t	next2fill;
69*62dadd65SYuri Pankov 	uint16_t	avail;
70*62dadd65SYuri Pankov 	uint8_t		gen;
71*62dadd65SYuri Pankov } vmxnet3_cmdring_t;
72*62dadd65SYuri Pankov 
73*62dadd65SYuri Pankov typedef struct vmxnet3_compring_t {
74*62dadd65SYuri Pankov 	vmxnet3_dmabuf_t dma;
75*62dadd65SYuri Pankov 	uint16_t	size;
76*62dadd65SYuri Pankov 	uint16_t	next2comp;
77*62dadd65SYuri Pankov 	uint8_t		gen;
78*62dadd65SYuri Pankov } vmxnet3_compring_t;
79*62dadd65SYuri Pankov 
80*62dadd65SYuri Pankov typedef struct vmxnet3_metatx_t {
81*62dadd65SYuri Pankov 	mblk_t		*mp;
82*62dadd65SYuri Pankov 	uint16_t	sopIdx;
83*62dadd65SYuri Pankov 	uint16_t	frags;
84*62dadd65SYuri Pankov } vmxnet3_metatx_t;
85*62dadd65SYuri Pankov 
86*62dadd65SYuri Pankov typedef struct vmxnet3_txqueue_t {
87*62dadd65SYuri Pankov 	vmxnet3_cmdring_t cmdRing;
88*62dadd65SYuri Pankov 	vmxnet3_compring_t compRing;
89*62dadd65SYuri Pankov 	vmxnet3_metatx_t *metaRing;
90*62dadd65SYuri Pankov 	Vmxnet3_TxQueueCtrl *sharedCtrl;
91*62dadd65SYuri Pankov } vmxnet3_txqueue_t;
92*62dadd65SYuri Pankov 
93*62dadd65SYuri Pankov typedef struct vmxnet3_rxbuf_t {
94*62dadd65SYuri Pankov 	vmxnet3_dmabuf_t dma;
95*62dadd65SYuri Pankov 	mblk_t		*mblk;
96*62dadd65SYuri Pankov 	frtn_t		freeCB;
97*62dadd65SYuri Pankov 	struct vmxnet3_softc_t *dp;
98*62dadd65SYuri Pankov 	struct vmxnet3_rxbuf_t *next;
99*62dadd65SYuri Pankov } vmxnet3_rxbuf_t;
100*62dadd65SYuri Pankov 
101*62dadd65SYuri Pankov typedef struct vmxnet3_bufdesc_t {
102*62dadd65SYuri Pankov 	vmxnet3_rxbuf_t	*rxBuf;
103*62dadd65SYuri Pankov } vmxnet3_bufdesc_t;
104*62dadd65SYuri Pankov 
105*62dadd65SYuri Pankov typedef struct vmxnet3_rxpool_t {
106*62dadd65SYuri Pankov 	vmxnet3_rxbuf_t	*listHead;
107*62dadd65SYuri Pankov 	unsigned int	nBufs;
108*62dadd65SYuri Pankov 	unsigned int	nBufsLimit;
109*62dadd65SYuri Pankov } vmxnet3_rxpool_t;
110*62dadd65SYuri Pankov 
111*62dadd65SYuri Pankov typedef struct vmxnet3_rxqueue_t {
112*62dadd65SYuri Pankov 	vmxnet3_cmdring_t cmdRing;
113*62dadd65SYuri Pankov 	vmxnet3_compring_t compRing;
114*62dadd65SYuri Pankov 	vmxnet3_bufdesc_t *bufRing;
115*62dadd65SYuri Pankov 	Vmxnet3_RxQueueCtrl *sharedCtrl;
116*62dadd65SYuri Pankov } vmxnet3_rxqueue_t;
117*62dadd65SYuri Pankov 
118*62dadd65SYuri Pankov typedef struct vmxnet3_softc_t {
119*62dadd65SYuri Pankov 	dev_info_t	*dip;
120*62dadd65SYuri Pankov 	int		instance;
121*62dadd65SYuri Pankov 	mac_handle_t	mac;
122*62dadd65SYuri Pankov 
123*62dadd65SYuri Pankov 	ddi_acc_handle_t pciHandle;
124*62dadd65SYuri Pankov 	ddi_acc_handle_t bar0Handle, bar1Handle;
125*62dadd65SYuri Pankov 	caddr_t		bar0, bar1;
126*62dadd65SYuri Pankov 
127*62dadd65SYuri Pankov 	boolean_t	devEnabled;
128*62dadd65SYuri Pankov 	uint8_t		macaddr[6];
129*62dadd65SYuri Pankov 	uint32_t	cur_mtu;
130*62dadd65SYuri Pankov 	link_state_t	linkState;
131*62dadd65SYuri Pankov 	uint64_t	linkSpeed;
132*62dadd65SYuri Pankov 	vmxnet3_dmabuf_t sharedData;
133*62dadd65SYuri Pankov 	vmxnet3_dmabuf_t queueDescs;
134*62dadd65SYuri Pankov 
135*62dadd65SYuri Pankov 	kmutex_t	intrLock;
136*62dadd65SYuri Pankov 	int		intrType;
137*62dadd65SYuri Pankov 	int		intrMaskMode;
138*62dadd65SYuri Pankov 	int		intrCap;
139*62dadd65SYuri Pankov 	ddi_intr_handle_t intrHandle;
140*62dadd65SYuri Pankov 	ddi_taskq_t	*resetTask;
141*62dadd65SYuri Pankov 
142*62dadd65SYuri Pankov 	kmutex_t	txLock;
143*62dadd65SYuri Pankov 	vmxnet3_txqueue_t txQueue;
144*62dadd65SYuri Pankov 	ddi_dma_handle_t txDmaHandle;
145*62dadd65SYuri Pankov 	boolean_t	txMustResched;
146*62dadd65SYuri Pankov 
147*62dadd65SYuri Pankov 	vmxnet3_rxqueue_t rxQueue;
148*62dadd65SYuri Pankov 	kmutex_t	rxPoolLock;
149*62dadd65SYuri Pankov 	vmxnet3_rxpool_t rxPool;
150*62dadd65SYuri Pankov 	volatile uint32_t rxNumBufs;
151*62dadd65SYuri Pankov 	uint32_t	rxMode;
152*62dadd65SYuri Pankov 
153*62dadd65SYuri Pankov 	vmxnet3_dmabuf_t mfTable;
154*62dadd65SYuri Pankov 	kstat_t		*devKstats;
155*62dadd65SYuri Pankov 	uint32_t	reset_count;
156*62dadd65SYuri Pankov 	uint32_t	tx_pullup_needed;
157*62dadd65SYuri Pankov 	uint32_t	tx_pullup_failed;
158*62dadd65SYuri Pankov 	uint32_t	tx_ring_full;
159*62dadd65SYuri Pankov 	uint32_t	tx_error;
160*62dadd65SYuri Pankov 	uint32_t	rx_alloc_buf;
161*62dadd65SYuri Pankov 	uint32_t	rx_alloc_failed;
162*62dadd65SYuri Pankov } vmxnet3_softc_t;
163*62dadd65SYuri Pankov 
164*62dadd65SYuri Pankov typedef struct vmxnet3_kstats_t {
165*62dadd65SYuri Pankov 	kstat_named_t	reset_count;
166*62dadd65SYuri Pankov 	kstat_named_t	tx_pullup_needed;
167*62dadd65SYuri Pankov 	kstat_named_t	tx_ring_full;
168*62dadd65SYuri Pankov 	kstat_named_t	rx_alloc_buf;
169*62dadd65SYuri Pankov } vmxnet3_kstats_t;
170*62dadd65SYuri Pankov 
171*62dadd65SYuri Pankov int	vmxnet3_alloc_dma_mem_1(vmxnet3_softc_t *dp, vmxnet3_dmabuf_t *dma,
172*62dadd65SYuri Pankov 	    size_t size, boolean_t canSleep);
173*62dadd65SYuri Pankov int	vmxnet3_alloc_dma_mem_128(vmxnet3_softc_t *dp, vmxnet3_dmabuf_t *dma,
174*62dadd65SYuri Pankov 	    size_t size, boolean_t canSleep);
175*62dadd65SYuri Pankov int	vmxnet3_alloc_dma_mem_512(vmxnet3_softc_t *dp, vmxnet3_dmabuf_t *dma,
176*62dadd65SYuri Pankov 	    size_t size, boolean_t canSleep);
177*62dadd65SYuri Pankov void	vmxnet3_free_dma_mem(vmxnet3_dmabuf_t *dma);
178*62dadd65SYuri Pankov int	vmxnet3_getprop(vmxnet3_softc_t *dp, char *name, int min, int max,
179*62dadd65SYuri Pankov 	    int def);
180*62dadd65SYuri Pankov 
181*62dadd65SYuri Pankov int	vmxnet3_txqueue_init(vmxnet3_softc_t *dp, vmxnet3_txqueue_t *txq);
182*62dadd65SYuri Pankov mblk_t	*vmxnet3_tx(void *data, mblk_t *mps);
183*62dadd65SYuri Pankov boolean_t vmxnet3_tx_complete(vmxnet3_softc_t *dp, vmxnet3_txqueue_t *txq);
184*62dadd65SYuri Pankov void	vmxnet3_txqueue_fini(vmxnet3_softc_t *dp, vmxnet3_txqueue_t *txq);
185*62dadd65SYuri Pankov 
186*62dadd65SYuri Pankov int	vmxnet3_rxqueue_init(vmxnet3_softc_t *dp, vmxnet3_rxqueue_t *rxq);
187*62dadd65SYuri Pankov mblk_t	*vmxnet3_rx_intr(vmxnet3_softc_t *dp, vmxnet3_rxqueue_t *rxq);
188*62dadd65SYuri Pankov void	vmxnet3_rxqueue_fini(vmxnet3_softc_t *dp, vmxnet3_rxqueue_t *rxq);
189*62dadd65SYuri Pankov void	vmxnet3_log(int level, vmxnet3_softc_t *dp, char *fmt, ...);
190*62dadd65SYuri Pankov 
191*62dadd65SYuri Pankov extern ddi_device_acc_attr_t vmxnet3_dev_attr;
192*62dadd65SYuri Pankov 
193*62dadd65SYuri Pankov extern int vmxnet3s_debug;
194*62dadd65SYuri Pankov 
195*62dadd65SYuri Pankov #define	VMXNET3_MODNAME "vmxnet3s"
196*62dadd65SYuri Pankov 
197*62dadd65SYuri Pankov /* Logging stuff */
198*62dadd65SYuri Pankov #define	VMXNET3_WARN(Device, ...) vmxnet3_log(CE_WARN, Device, __VA_ARGS__)
199*62dadd65SYuri Pankov 
200*62dadd65SYuri Pankov #ifdef	DEBUG
201*62dadd65SYuri Pankov #define	VMXNET3_DEBUG(Device, Level, ...) {	 		\
202*62dadd65SYuri Pankov 	if (Level <= vmxnet3s_debug) {				\
203*62dadd65SYuri Pankov 		vmxnet3_log(CE_CONT, Device, "?" __VA_ARGS__);	\
204*62dadd65SYuri Pankov 	}							\
205*62dadd65SYuri Pankov }
206*62dadd65SYuri Pankov #else
207*62dadd65SYuri Pankov #define	VMXNET3_DEBUG(Device, Level, ...)
208*62dadd65SYuri Pankov #endif
209*62dadd65SYuri Pankov 
210*62dadd65SYuri Pankov #define	MACADDR_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
211*62dadd65SYuri Pankov #define	MACADDR_FMT_ARGS(mac) mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]
212*62dadd65SYuri Pankov 
213*62dadd65SYuri Pankov /* Default ring size */
214*62dadd65SYuri Pankov #define	VMXNET3_DEF_TX_RING_SIZE	256
215*62dadd65SYuri Pankov #define	VMXNET3_DEF_RX_RING_SIZE	256
216*62dadd65SYuri Pankov 
217*62dadd65SYuri Pankov /* Register access helpers */
218*62dadd65SYuri Pankov #define	VMXNET3_BAR0_GET32(Device, Reg) \
219*62dadd65SYuri Pankov 	ddi_get32((Device)->bar0Handle, (uint32_t *)((Device)->bar0 + (Reg)))
220*62dadd65SYuri Pankov #define	VMXNET3_BAR0_PUT32(Device, Reg, Value) \
221*62dadd65SYuri Pankov 	ddi_put32((Device)->bar0Handle, (uint32_t *)((Device)->bar0 + (Reg)), \
222*62dadd65SYuri Pankov 	    (Value))
223*62dadd65SYuri Pankov #define	VMXNET3_BAR1_GET32(Device, Reg) \
224*62dadd65SYuri Pankov 	ddi_get32((Device)->bar1Handle, (uint32_t *)((Device)->bar1 + (Reg)))
225*62dadd65SYuri Pankov #define	VMXNET3_BAR1_PUT32(Device, Reg, Value) \
226*62dadd65SYuri Pankov 	ddi_put32((Device)->bar1Handle, (uint32_t *)((Device)->bar1 + (Reg)), \
227*62dadd65SYuri Pankov 	    (Value))
228*62dadd65SYuri Pankov 
229*62dadd65SYuri Pankov /* Misc helpers */
230*62dadd65SYuri Pankov #define	VMXNET3_DS(Device) ((Vmxnet3_DriverShared *) (Device)->sharedData.buf)
231*62dadd65SYuri Pankov #define	VMXNET3_TQDESC(Device) \
232*62dadd65SYuri Pankov 	((Vmxnet3_TxQueueDesc *) (Device)->queueDescs.buf)
233*62dadd65SYuri Pankov #define	VMXNET3_RQDESC(Device) \
234*62dadd65SYuri Pankov 	((Vmxnet3_RxQueueDesc *) ((Device)->queueDescs.buf + \
235*62dadd65SYuri Pankov 	    sizeof (Vmxnet3_TxQueueDesc)))
236*62dadd65SYuri Pankov 
237*62dadd65SYuri Pankov #define	VMXNET3_ADDR_LO(addr) ((uint32_t)(addr))
238*62dadd65SYuri Pankov #define	VMXNET3_ADDR_HI(addr) ((uint32_t)(((uint64_t)(addr)) >> 32))
239*62dadd65SYuri Pankov 
240*62dadd65SYuri Pankov #define	VMXNET3_GET_DESC(Ring, Idx) \
241*62dadd65SYuri Pankov 	(((Vmxnet3_GenericDesc *) (Ring)->dma.buf) + Idx)
242*62dadd65SYuri Pankov 
243*62dadd65SYuri Pankov /* Rings handling */
244*62dadd65SYuri Pankov #define	VMXNET3_INC_RING_IDX(Ring, Idx) {	\
245*62dadd65SYuri Pankov 	(Idx)++;				\
246*62dadd65SYuri Pankov 	if ((Idx) == (Ring)->size) {		\
247*62dadd65SYuri Pankov 		(Idx) = 0;			\
248*62dadd65SYuri Pankov 		(Ring)->gen ^= 1;		\
249*62dadd65SYuri Pankov 	}					\
250*62dadd65SYuri Pankov }
251*62dadd65SYuri Pankov 
252*62dadd65SYuri Pankov #define	VMXNET3_DEC_RING_IDX(Ring, Idx) {	\
253*62dadd65SYuri Pankov 	if ((Idx) == 0) {			\
254*62dadd65SYuri Pankov 		(Idx) = (Ring)->size;		\
255*62dadd65SYuri Pankov 		(Ring)->gen ^= 1;		\
256*62dadd65SYuri Pankov 	}					\
257*62dadd65SYuri Pankov 	(Idx)--;				\
258*62dadd65SYuri Pankov }
259*62dadd65SYuri Pankov 
260*62dadd65SYuri Pankov #define	PCI_VENDOR_ID_VMWARE		0x15AD
261*62dadd65SYuri Pankov #define	PCI_DEVICE_ID_VMWARE_VMXNET3	0x07B0
262*62dadd65SYuri Pankov 
263*62dadd65SYuri Pankov #endif /* _VMXNET3_H_ */
264