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