usr/src/uts/intel/io/vmxnet3s/vmxnet3_solaris.h
author Sebastien Roy <seb@delphix.com>
Sun, 03 May 2015 18:26:55 +0100
changeset 14277 711401aaa206
parent 13976 814bae19b8a2
permissions -rw-r--r--
Delphix vmxnet3s fixes

/*********************************************************
 * Copyright (C) 2007 VMware, Inc. All rights reserved.
 *
 * The contents of this file are subject to the terms of the Common
 * Development and Distribution License (the "License") version 1.0
 * and no later version.  You may not use this file except in
 * compliance with the License.
 *
 * You can obtain a copy of the License at
 *         http://www.opensource.org/licenses/cddl1.php
 *
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 *********************************************************/
/*
 * Copyright (c) 2012 by Delphix. All rights reserved.
 */

#ifndef _VMXNET3_SOLARIS_H_
#define _VMXNET3_SOLARIS_H_

#include <sys/atomic.h>
#include <sys/types.h>
#include <sys/conf.h>
#include <sys/debug.h>
#include <sys/cmn_err.h>
#include <sys/stropts.h>
#include <sys/stream.h>
#include <sys/strlog.h>
#include <sys/kmem.h>
#include <sys/stat.h>
#include <sys/kstat.h>
#include <sys/vtrace.h>
#include <sys/dlpi.h>
#include <sys/strsun.h>
#include <sys/ethernet.h>
#include <sys/vlan.h>
#include <sys/modctl.h>
#include <sys/errno.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include <sys/ddi_impldefs.h>
#include <sys/pci.h>
#include <sys/strsubr.h>
#include <sys/pattr.h>
#include <sys/mac.h>
#include <sys/sockio.h>
#include <sys/mac_provider.h>
#include <sys/mac_ether.h>
#include <inet/common.h>
#include <inet/ip.h>
#include <inet/tcp.h>

#include <sys/vmware/vm_basic_types.h>
#include <vmxnet3_defs.h>

typedef struct vmxnet3_dmabuf_t {
   caddr_t              buf;
   uint64_t             bufPA;
   size_t               bufLen;
   ddi_dma_handle_t     dmaHandle;
   ddi_acc_handle_t     dataHandle;
} vmxnet3_dmabuf_t;

typedef struct vmxnet3_cmdring_t {
   vmxnet3_dmabuf_t     dma;
   uint16_t             size;
   uint16_t             next2fill;
   uint16_t             avail;
   uint8_t              gen;
} vmxnet3_cmdring_t;

typedef struct vmxnet3_compring_t {
   vmxnet3_dmabuf_t     dma;
   uint16_t             size;
   uint16_t             next2comp;
   uint8_t              gen;
} vmxnet3_compring_t;

typedef struct vmxnet3_metatx_t {
   mblk_t              *mp;
   uint16_t             sopIdx;
   uint16_t             frags;
} vmxnet3_metatx_t;

typedef struct vmxnet3_txqueue_t {
   vmxnet3_cmdring_t    cmdRing;
   vmxnet3_compring_t   compRing;
   vmxnet3_metatx_t    *metaRing;
   Vmxnet3_TxQueueCtrl *sharedCtrl;
} vmxnet3_txqueue_t;

typedef struct vmxnet3_rxbuf_t {
   vmxnet3_dmabuf_t        dma;
   mblk_t                 *mblk;
   frtn_t                  freeCB;
   struct vmxnet3_softc_t *dp;
   struct vmxnet3_rxbuf_t *next;
} vmxnet3_rxbuf_t;

typedef struct vmxnet3_bufdesc_t {
   vmxnet3_rxbuf_t     *rxBuf;
} vmxnet3_bufdesc_t;

typedef struct vmxnet3_rxpool_t {
   vmxnet3_rxbuf_t     *listHead;
   unsigned int         nBufs;
   unsigned int         nBufsLimit;
} vmxnet3_rxpool_t;

typedef struct vmxnet3_rxqueue_t {
   vmxnet3_cmdring_t    cmdRing;
   vmxnet3_compring_t   compRing;
   vmxnet3_bufdesc_t   *bufRing;
   Vmxnet3_RxQueueCtrl *sharedCtrl;
} vmxnet3_rxqueue_t;


typedef struct vmxnet3_softc_t {
   dev_info_t          *dip;
   int                  instance;
   mac_handle_t         mac;

   ddi_acc_handle_t     pciHandle;
   ddi_acc_handle_t     bar0Handle, bar1Handle;
   caddr_t              bar0, bar1;

   boolean_t            devEnabled;
   uint8_t              macaddr[6];
   uint32_t             cur_mtu;
   link_state_t         linkState;
   uint64_t             linkSpeed;
   vmxnet3_dmabuf_t     sharedData;
   vmxnet3_dmabuf_t     queueDescs;

   kmutex_t             intrLock;
   int                  intrType;
   int                  intrMaskMode;
   int                  intrCap;
   ddi_intr_handle_t    intrHandle;
   ddi_taskq_t         *resetTask;

   kmutex_t             txLock;
   vmxnet3_txqueue_t    txQueue;
   ddi_dma_handle_t     txDmaHandle;
   boolean_t            txMustResched;

   vmxnet3_rxqueue_t    rxQueue;
   kmutex_t             rxPoolLock;
   vmxnet3_rxpool_t     rxPool;
   volatile uint32_t    rxNumBufs;
   uint32_t             rxMode;

   vmxnet3_dmabuf_t     mfTable;
   kstat_t              *devKstats;
   uint32_t             reset_count;
   uint32_t             tx_pullup_needed;
   uint32_t		tx_pullup_failed;
   uint32_t             tx_ring_full;
   uint32_t		tx_error;
   uint32_t		rx_alloc_buf;
   uint32_t		rx_alloc_failed;
} vmxnet3_softc_t;

typedef struct vmxnet3_kstats_t {
   kstat_named_t	reset_count;
   kstat_named_t	tx_pullup_needed;
   kstat_named_t	tx_ring_full;
   kstat_named_t	rx_alloc_buf;
} vmxnet3_kstats_t;

int       vmxnet3_alloc_dma_mem_1(vmxnet3_softc_t *dp, vmxnet3_dmabuf_t *dma,
                                  size_t size, boolean_t canSleep);
int       vmxnet3_alloc_dma_mem_128(vmxnet3_softc_t *dp, vmxnet3_dmabuf_t *dma,
                                    size_t size, boolean_t canSleep);
int       vmxnet3_alloc_dma_mem_512(vmxnet3_softc_t *dp, vmxnet3_dmabuf_t *dma,
                                    size_t size, boolean_t canSleep);
void      vmxnet3_free_dma_mem(vmxnet3_dmabuf_t *dma);
int       vmxnet3_getprop(vmxnet3_softc_t *dp, char *name,
                          int min, int max, int def);

int       vmxnet3_txqueue_init(vmxnet3_softc_t *dp, vmxnet3_txqueue_t *txq);
mblk_t   *vmxnet3_tx(void *data, mblk_t *mps);
boolean_t vmxnet3_tx_complete(vmxnet3_softc_t *dp, vmxnet3_txqueue_t *txq);
void      vmxnet3_txqueue_fini(vmxnet3_softc_t *dp, vmxnet3_txqueue_t *txq);

int       vmxnet3_rxqueue_init(vmxnet3_softc_t *dp, vmxnet3_rxqueue_t *rxq);
mblk_t   *vmxnet3_rx_intr(vmxnet3_softc_t *dp, vmxnet3_rxqueue_t *rxq);
void      vmxnet3_rxqueue_fini(vmxnet3_softc_t *dp, vmxnet3_rxqueue_t *rxq);
void      vmxnet3_log(int level, vmxnet3_softc_t *dp, char *fmt, ...);

extern ddi_device_acc_attr_t vmxnet3_dev_attr;
extern int vmxnet3_debug_level;

#define VMXNET3_MODNAME "vmxnet3s"

/* Logging stuff */
#define VMXNET3_WARN(Device, ...)	\
   vmxnet3_log(CE_WARN, Device, __VA_ARGS__)

#ifdef DEBUG
#define VMXNET3_DEBUG(Device, Level, ...) {	 \
   if (Level <= vmxnet3_debug_level) {	         \
      vmxnet3_log(CE_CONT, Device, __VA_ARGS__); \
   }						 \
}
#else
#define VMXNET3_DEBUG(Device, Level, ...)
#endif

#define MACADDR_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
#define MACADDR_FMT_ARGS(mac) \
   mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]

/* Default ring size */
#define VMXNET3_DEF_TX_RING_SIZE 256
#define VMXNET3_DEF_RX_RING_SIZE 256

/* Register access helpers */
#define VMXNET3_BAR0_GET32(Device, Reg) \
   ddi_get32((Device)->bar0Handle, (uint32_t *) ((Device)->bar0 + (Reg)))
#define VMXNET3_BAR0_PUT32(Device, Reg, Value) \
   ddi_put32((Device)->bar0Handle, (uint32_t *) ((Device)->bar0 + (Reg)), (Value))
#define VMXNET3_BAR1_GET32(Device, Reg) \
   ddi_get32((Device)->bar1Handle, (uint32_t *) ((Device)->bar1 + (Reg)))
#define VMXNET3_BAR1_PUT32(Device, Reg, Value) \
   ddi_put32((Device)->bar1Handle, (uint32_t *) ((Device)->bar1 + (Reg)), (Value))

/* Misc helpers */
#define VMXNET3_DS(Device) \
   ((Vmxnet3_DriverShared *) (Device)->sharedData.buf)
#define VMXNET3_TQDESC(Device) \
   ((Vmxnet3_TxQueueDesc *) (Device)->queueDescs.buf)
#define VMXNET3_RQDESC(Device) \
   ((Vmxnet3_RxQueueDesc *) ((Device)->queueDescs.buf + sizeof(Vmxnet3_TxQueueDesc)))

#define VMXNET3_ADDR_LO(addr) ((uint32_t) (addr))
#define VMXNET3_ADDR_HI(addr) ((uint32_t) (((uint64_t) (addr)) >> 32))

#define VMXNET3_GET_DESC(Ring, Idx) \
   (((Vmxnet3_GenericDesc *) (Ring)->dma.buf) + Idx)

/* Rings handling */
#define VMXNET3_INC_RING_IDX(Ring, Idx) { \
      (Idx)++;                          \
      if ((Idx) == (Ring)->size) {      \
         (Idx) = 0;                     \
         (Ring)->gen ^= 1;              \
      }                                 \
   }

#define VMXNET3_DEC_RING_IDX(Ring, Idx) { \
      if ((Idx) == 0) {                 \
         (Idx) = (Ring)->size;          \
         (Ring)->gen ^= 1;              \
      }                                 \
      (Idx)--;                          \
   }

#define	PCI_VENDOR_ID_VMWARE		0x15AD
#define	PCI_DEVICE_ID_VMWARE_VMXNET3	0x07B0

#endif /* _VMXNET3_SOLARIS_H_ */