162dadd65SYuri Pankov /*
2ca5345b6SSebastien Roy  * Copyright (C) 2007-2014 VMware, Inc. All rights reserved.
362dadd65SYuri Pankov  *
462dadd65SYuri Pankov  * The contents of this file are subject to the terms of the Common
562dadd65SYuri Pankov  * Development and Distribution License (the "License") version 1.0
662dadd65SYuri Pankov  * and no later version.  You may not use this file except in
762dadd65SYuri Pankov  * compliance with the License.
862dadd65SYuri Pankov  *
962dadd65SYuri Pankov  * You can obtain a copy of the License at
1062dadd65SYuri Pankov  *         http://www.opensource.org/licenses/cddl1.php
1162dadd65SYuri Pankov  *
1262dadd65SYuri Pankov  * See the License for the specific language governing permissions
1362dadd65SYuri Pankov  * and limitations under the License.
1462dadd65SYuri Pankov  */
1562dadd65SYuri Pankov 
1662dadd65SYuri Pankov /*
176849994eSSebastien Roy  * Copyright (c) 2012, 2016 by Delphix. All rights reserved.
1862dadd65SYuri Pankov  */
1962dadd65SYuri Pankov 
2062dadd65SYuri Pankov #ifndef	_VMXNET3_H_
2162dadd65SYuri Pankov #define	_VMXNET3_H_
2262dadd65SYuri Pankov 
2362dadd65SYuri Pankov #include <sys/atomic.h>
2462dadd65SYuri Pankov #include <sys/types.h>
2562dadd65SYuri Pankov #include <sys/conf.h>
2662dadd65SYuri Pankov #include <sys/debug.h>
2762dadd65SYuri Pankov #include <sys/cmn_err.h>
2862dadd65SYuri Pankov #include <sys/stropts.h>
2962dadd65SYuri Pankov #include <sys/stream.h>
3062dadd65SYuri Pankov #include <sys/strlog.h>
3162dadd65SYuri Pankov #include <sys/kmem.h>
3262dadd65SYuri Pankov #include <sys/stat.h>
3362dadd65SYuri Pankov #include <sys/kstat.h>
3462dadd65SYuri Pankov #include <sys/vtrace.h>
3562dadd65SYuri Pankov #include <sys/dlpi.h>
3662dadd65SYuri Pankov #include <sys/strsun.h>
3762dadd65SYuri Pankov #include <sys/ethernet.h>
3862dadd65SYuri Pankov #include <sys/vlan.h>
3962dadd65SYuri Pankov #include <sys/modctl.h>
4062dadd65SYuri Pankov #include <sys/errno.h>
4162dadd65SYuri Pankov #include <sys/ddi.h>
4262dadd65SYuri Pankov #include <sys/sunddi.h>
4362dadd65SYuri Pankov #include <sys/ddi_impldefs.h>
4462dadd65SYuri Pankov #include <sys/pci.h>
4562dadd65SYuri Pankov #include <sys/strsubr.h>
4662dadd65SYuri Pankov #include <sys/pattr.h>
4762dadd65SYuri Pankov #include <sys/mac.h>
4862dadd65SYuri Pankov #include <sys/sockio.h>
4962dadd65SYuri Pankov #include <sys/mac_provider.h>
5062dadd65SYuri Pankov #include <sys/mac_ether.h>
5162dadd65SYuri Pankov #include <inet/common.h>
5262dadd65SYuri Pankov #include <inet/ip.h>
5362dadd65SYuri Pankov #include <inet/tcp.h>
5462dadd65SYuri Pankov 
5562dadd65SYuri Pankov #include <vmxnet3_defs.h>
5662dadd65SYuri Pankov 
5762dadd65SYuri Pankov typedef struct vmxnet3_dmabuf_t {
5862dadd65SYuri Pankov 	caddr_t		buf;
5962dadd65SYuri Pankov 	uint64_t	bufPA;
6062dadd65SYuri Pankov 	size_t		bufLen;
6162dadd65SYuri Pankov 	ddi_dma_handle_t dmaHandle;
6262dadd65SYuri Pankov 	ddi_acc_handle_t dataHandle;
6362dadd65SYuri Pankov } vmxnet3_dmabuf_t;
6462dadd65SYuri Pankov 
6562dadd65SYuri Pankov typedef struct vmxnet3_cmdring_t {
6662dadd65SYuri Pankov 	vmxnet3_dmabuf_t dma;
6762dadd65SYuri Pankov 	uint16_t	size;
6862dadd65SYuri Pankov 	uint16_t	next2fill;
6962dadd65SYuri Pankov 	uint16_t	avail;
7062dadd65SYuri Pankov 	uint8_t		gen;
7162dadd65SYuri Pankov } vmxnet3_cmdring_t;
7262dadd65SYuri Pankov 
7362dadd65SYuri Pankov typedef struct vmxnet3_compring_t {
7462dadd65SYuri Pankov 	vmxnet3_dmabuf_t dma;
7562dadd65SYuri Pankov 	uint16_t	size;
7662dadd65SYuri Pankov 	uint16_t	next2comp;
7762dadd65SYuri Pankov 	uint8_t		gen;
7862dadd65SYuri Pankov } vmxnet3_compring_t;
7962dadd65SYuri Pankov 
8062dadd65SYuri Pankov typedef struct vmxnet3_metatx_t {
8162dadd65SYuri Pankov 	mblk_t		*mp;
8262dadd65SYuri Pankov 	uint16_t	sopIdx;
8362dadd65SYuri Pankov 	uint16_t	frags;
8462dadd65SYuri Pankov } vmxnet3_metatx_t;
8562dadd65SYuri Pankov 
8662dadd65SYuri Pankov typedef struct vmxnet3_txqueue_t {
8762dadd65SYuri Pankov 	vmxnet3_cmdring_t cmdRing;
8862dadd65SYuri Pankov 	vmxnet3_compring_t compRing;
8962dadd65SYuri Pankov 	vmxnet3_metatx_t *metaRing;
9062dadd65SYuri Pankov 	Vmxnet3_TxQueueCtrl *sharedCtrl;
9162dadd65SYuri Pankov } vmxnet3_txqueue_t;
9262dadd65SYuri Pankov 
9362dadd65SYuri Pankov typedef struct vmxnet3_rxbuf_t {
9462dadd65SYuri Pankov 	vmxnet3_dmabuf_t dma;
9562dadd65SYuri Pankov 	mblk_t		*mblk;
9662dadd65SYuri Pankov 	frtn_t		freeCB;
9762dadd65SYuri Pankov 	struct vmxnet3_softc_t *dp;
9862dadd65SYuri Pankov 	struct vmxnet3_rxbuf_t *next;
9962dadd65SYuri Pankov } vmxnet3_rxbuf_t;
10062dadd65SYuri Pankov 
10162dadd65SYuri Pankov typedef struct vmxnet3_bufdesc_t {
10262dadd65SYuri Pankov 	vmxnet3_rxbuf_t	*rxBuf;
10362dadd65SYuri Pankov } vmxnet3_bufdesc_t;
10462dadd65SYuri Pankov 
10562dadd65SYuri Pankov typedef struct vmxnet3_rxpool_t {
10662dadd65SYuri Pankov 	vmxnet3_rxbuf_t	*listHead;
10762dadd65SYuri Pankov 	unsigned int	nBufs;
10862dadd65SYuri Pankov 	unsigned int	nBufsLimit;
10962dadd65SYuri Pankov } vmxnet3_rxpool_t;
11062dadd65SYuri Pankov 
11162dadd65SYuri Pankov typedef struct vmxnet3_rxqueue_t {
11262dadd65SYuri Pankov 	vmxnet3_cmdring_t cmdRing;
11362dadd65SYuri Pankov 	vmxnet3_compring_t compRing;
11462dadd65SYuri Pankov 	vmxnet3_bufdesc_t *bufRing;
11562dadd65SYuri Pankov 	Vmxnet3_RxQueueCtrl *sharedCtrl;
11662dadd65SYuri Pankov } vmxnet3_rxqueue_t;
11762dadd65SYuri Pankov 
11862dadd65SYuri Pankov typedef struct vmxnet3_softc_t {
11962dadd65SYuri Pankov 	dev_info_t	*dip;
12062dadd65SYuri Pankov 	int		instance;
12162dadd65SYuri Pankov 	mac_handle_t	mac;
12262dadd65SYuri Pankov 
12362dadd65SYuri Pankov 	ddi_acc_handle_t pciHandle;
12462dadd65SYuri Pankov 	ddi_acc_handle_t bar0Handle, bar1Handle;
12562dadd65SYuri Pankov 	caddr_t		bar0, bar1;
12662dadd65SYuri Pankov 
12762dadd65SYuri Pankov 	boolean_t	devEnabled;
12862dadd65SYuri Pankov 	uint8_t		macaddr[6];
12962dadd65SYuri Pankov 	uint32_t	cur_mtu;
130ca5345b6SSebastien Roy 	boolean_t	allow_jumbo;
13162dadd65SYuri Pankov 	link_state_t	linkState;
13262dadd65SYuri Pankov 	uint64_t	linkSpeed;
13362dadd65SYuri Pankov 	vmxnet3_dmabuf_t sharedData;
13462dadd65SYuri Pankov 	vmxnet3_dmabuf_t queueDescs;
13562dadd65SYuri Pankov 
13662dadd65SYuri Pankov 	kmutex_t	intrLock;
13762dadd65SYuri Pankov 	int		intrType;
13862dadd65SYuri Pankov 	int		intrMaskMode;
13962dadd65SYuri Pankov 	int		intrCap;
14062dadd65SYuri Pankov 	ddi_intr_handle_t intrHandle;
14162dadd65SYuri Pankov 	ddi_taskq_t	*resetTask;
14262dadd65SYuri Pankov 
14362dadd65SYuri Pankov 	kmutex_t	txLock;
14462dadd65SYuri Pankov 	vmxnet3_txqueue_t txQueue;
14562dadd65SYuri Pankov 	ddi_dma_handle_t txDmaHandle;
14662dadd65SYuri Pankov 	boolean_t	txMustResched;
14762dadd65SYuri Pankov 
14862dadd65SYuri Pankov 	vmxnet3_rxqueue_t rxQueue;
14962dadd65SYuri Pankov 	kmutex_t	rxPoolLock;
15062dadd65SYuri Pankov 	vmxnet3_rxpool_t rxPool;
15162dadd65SYuri Pankov 	uint32_t	rxMode;
1526849994eSSebastien Roy 	boolean_t	alloc_ok;
15362dadd65SYuri Pankov 
15462dadd65SYuri Pankov 	vmxnet3_dmabuf_t mfTable;
15562dadd65SYuri Pankov 	kstat_t		*devKstats;
15662dadd65SYuri Pankov 	uint32_t	reset_count;
15762dadd65SYuri Pankov 	uint32_t	tx_pullup_needed;
15862dadd65SYuri Pankov 	uint32_t	tx_pullup_failed;
15962dadd65SYuri Pankov 	uint32_t	tx_ring_full;
16062dadd65SYuri Pankov 	uint32_t	tx_error;
1616849994eSSebastien Roy 	uint32_t	rx_num_bufs;
16262dadd65SYuri Pankov 	uint32_t	rx_alloc_buf;
16362dadd65SYuri Pankov 	uint32_t	rx_alloc_failed;
1646849994eSSebastien Roy 	uint32_t	rx_pool_empty;
16562dadd65SYuri Pankov } vmxnet3_softc_t;
16662dadd65SYuri Pankov 
16762dadd65SYuri Pankov typedef struct vmxnet3_kstats_t {
16862dadd65SYuri Pankov 	kstat_named_t	reset_count;
16962dadd65SYuri Pankov 	kstat_named_t	tx_pullup_needed;
17062dadd65SYuri Pankov 	kstat_named_t	tx_ring_full;
17162dadd65SYuri Pankov 	kstat_named_t	rx_alloc_buf;
1726849994eSSebastien Roy 	kstat_named_t	rx_pool_empty;
1736849994eSSebastien Roy 	kstat_named_t	rx_num_bufs;
17462dadd65SYuri Pankov } vmxnet3_kstats_t;
17562dadd65SYuri Pankov 
1766849994eSSebastien Roy int	vmxnet3_dmaerr2errno(int);
17762dadd65SYuri Pankov int	vmxnet3_alloc_dma_mem_1(vmxnet3_softc_t *dp, vmxnet3_dmabuf_t *dma,
17862dadd65SYuri Pankov 	    size_t size, boolean_t canSleep);
17962dadd65SYuri Pankov int	vmxnet3_alloc_dma_mem_128(vmxnet3_softc_t *dp, vmxnet3_dmabuf_t *dma,
18062dadd65SYuri Pankov 	    size_t size, boolean_t canSleep);
18162dadd65SYuri Pankov int	vmxnet3_alloc_dma_mem_512(vmxnet3_softc_t *dp, vmxnet3_dmabuf_t *dma,
18262dadd65SYuri Pankov 	    size_t size, boolean_t canSleep);
18362dadd65SYuri Pankov void	vmxnet3_free_dma_mem(vmxnet3_dmabuf_t *dma);
18462dadd65SYuri Pankov int	vmxnet3_getprop(vmxnet3_softc_t *dp, char *name, int min, int max,
18562dadd65SYuri Pankov 	    int def);
18662dadd65SYuri Pankov 
18762dadd65SYuri Pankov int	vmxnet3_txqueue_init(vmxnet3_softc_t *dp, vmxnet3_txqueue_t *txq);
18862dadd65SYuri Pankov mblk_t	*vmxnet3_tx(void *data, mblk_t *mps);
18962dadd65SYuri Pankov boolean_t vmxnet3_tx_complete(vmxnet3_softc_t *dp, vmxnet3_txqueue_t *txq);
19062dadd65SYuri Pankov void	vmxnet3_txqueue_fini(vmxnet3_softc_t *dp, vmxnet3_txqueue_t *txq);
19162dadd65SYuri Pankov 
19262dadd65SYuri Pankov int	vmxnet3_rxqueue_init(vmxnet3_softc_t *dp, vmxnet3_rxqueue_t *rxq);
19362dadd65SYuri Pankov mblk_t	*vmxnet3_rx_intr(vmxnet3_softc_t *dp, vmxnet3_rxqueue_t *rxq);
19462dadd65SYuri Pankov void	vmxnet3_rxqueue_fini(vmxnet3_softc_t *dp, vmxnet3_rxqueue_t *rxq);
19562dadd65SYuri Pankov void	vmxnet3_log(int level, vmxnet3_softc_t *dp, char *fmt, ...);
19662dadd65SYuri Pankov 
19762dadd65SYuri Pankov extern ddi_device_acc_attr_t vmxnet3_dev_attr;
19862dadd65SYuri Pankov 
19962dadd65SYuri Pankov extern int vmxnet3s_debug;
20062dadd65SYuri Pankov 
201ca5345b6SSebastien Roy #define	VMXNET3_MODNAME	"vmxnet3s"
202ca5345b6SSebastien Roy #define	VMXNET3_DRIVER_VERSION_STRING	""
20362dadd65SYuri Pankov 
20462dadd65SYuri Pankov /* Logging stuff */
205*5ceaf02cSYuri Pankov #define	VMXNET3_WARN(Device, ...) \
206*5ceaf02cSYuri Pankov 	dev_err((Device)->dip, CE_WARN, "!" __VA_ARGS__)
20762dadd65SYuri Pankov 
20862dadd65SYuri Pankov #ifdef	DEBUG
209*5ceaf02cSYuri Pankov #define	VMXNET3_DEBUG(Device, Level, ...) {				\
210*5ceaf02cSYuri Pankov 	if (Level <= vmxnet3s_debug) {					\
211*5ceaf02cSYuri Pankov 		dev_err((Device)->dip, CE_CONT, "?" __VA_ARGS__);	\
212*5ceaf02cSYuri Pankov 	}								\
21362dadd65SYuri Pankov }
21462dadd65SYuri Pankov #else
21562dadd65SYuri Pankov #define	VMXNET3_DEBUG(Device, Level, ...)
21662dadd65SYuri Pankov #endif
21762dadd65SYuri Pankov 
21862dadd65SYuri Pankov #define	MACADDR_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
21962dadd65SYuri Pankov #define	MACADDR_FMT_ARGS(mac) mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]
22062dadd65SYuri Pankov 
22162dadd65SYuri Pankov /* Default ring size */
22262dadd65SYuri Pankov #define	VMXNET3_DEF_TX_RING_SIZE	256
22362dadd65SYuri Pankov #define	VMXNET3_DEF_RX_RING_SIZE	256
22462dadd65SYuri Pankov 
22562dadd65SYuri Pankov /* Register access helpers */
22662dadd65SYuri Pankov #define	VMXNET3_BAR0_GET32(Device, Reg) \
22762dadd65SYuri Pankov 	ddi_get32((Device)->bar0Handle, (uint32_t *)((Device)->bar0 + (Reg)))
22862dadd65SYuri Pankov #define	VMXNET3_BAR0_PUT32(Device, Reg, Value) \
22962dadd65SYuri Pankov 	ddi_put32((Device)->bar0Handle, (uint32_t *)((Device)->bar0 + (Reg)), \
23062dadd65SYuri Pankov 	    (Value))
23162dadd65SYuri Pankov #define	VMXNET3_BAR1_GET32(Device, Reg) \
23262dadd65SYuri Pankov 	ddi_get32((Device)->bar1Handle, (uint32_t *)((Device)->bar1 + (Reg)))
23362dadd65SYuri Pankov #define	VMXNET3_BAR1_PUT32(Device, Reg, Value) \
23462dadd65SYuri Pankov 	ddi_put32((Device)->bar1Handle, (uint32_t *)((Device)->bar1 + (Reg)), \
23562dadd65SYuri Pankov 	    (Value))
23662dadd65SYuri Pankov 
23762dadd65SYuri Pankov /* Misc helpers */
23862dadd65SYuri Pankov #define	VMXNET3_DS(Device) ((Vmxnet3_DriverShared *) (Device)->sharedData.buf)
23962dadd65SYuri Pankov #define	VMXNET3_TQDESC(Device) \
24062dadd65SYuri Pankov 	((Vmxnet3_TxQueueDesc *) (Device)->queueDescs.buf)
24162dadd65SYuri Pankov #define	VMXNET3_RQDESC(Device) \
24262dadd65SYuri Pankov 	((Vmxnet3_RxQueueDesc *) ((Device)->queueDescs.buf + \
24362dadd65SYuri Pankov 	    sizeof (Vmxnet3_TxQueueDesc)))
24462dadd65SYuri Pankov 
24562dadd65SYuri Pankov #define	VMXNET3_ADDR_LO(addr) ((uint32_t)(addr))
24662dadd65SYuri Pankov #define	VMXNET3_ADDR_HI(addr) ((uint32_t)(((uint64_t)(addr)) >> 32))
24762dadd65SYuri Pankov 
24862dadd65SYuri Pankov #define	VMXNET3_GET_DESC(Ring, Idx) \
24962dadd65SYuri Pankov 	(((Vmxnet3_GenericDesc *) (Ring)->dma.buf) + Idx)
25062dadd65SYuri Pankov 
25162dadd65SYuri Pankov /* Rings handling */
25262dadd65SYuri Pankov #define	VMXNET3_INC_RING_IDX(Ring, Idx) {	\
25362dadd65SYuri Pankov 	(Idx)++;				\
25462dadd65SYuri Pankov 	if ((Idx) == (Ring)->size) {		\
25562dadd65SYuri Pankov 		(Idx) = 0;			\
25662dadd65SYuri Pankov 		(Ring)->gen ^= 1;		\
25762dadd65SYuri Pankov 	}					\
25862dadd65SYuri Pankov }
25962dadd65SYuri Pankov 
26062dadd65SYuri Pankov #define	VMXNET3_DEC_RING_IDX(Ring, Idx) {	\
26162dadd65SYuri Pankov 	if ((Idx) == 0) {			\
26262dadd65SYuri Pankov 		(Idx) = (Ring)->size;		\
26362dadd65SYuri Pankov 		(Ring)->gen ^= 1;		\
26462dadd65SYuri Pankov 	}					\
26562dadd65SYuri Pankov 	(Idx)--;				\
26662dadd65SYuri Pankov }
26762dadd65SYuri Pankov 
26862dadd65SYuri Pankov #define	PCI_VENDOR_ID_VMWARE		0x15AD
26962dadd65SYuri Pankov #define	PCI_DEVICE_ID_VMWARE_VMXNET3	0x07B0
27062dadd65SYuri Pankov 
27162dadd65SYuri Pankov #endif /* _VMXNET3_H_ */