freebsd-dev/sys/dev/hyperv/netvsc/hv_net_vsc.h
Sepherosa Ziehau 8caa09bd36 hyperv/hn: Get rid of the useless netvsc_packet
MFC after:	1 week
Sponsored by:	Microsoft
Differential Revision:	https://reviews.freebsd.org/D7544
2016-08-18 05:52:03 +00:00

424 lines
12 KiB
C

/*-
* Copyright (c) 2009-2012,2016 Microsoft Corp.
* Copyright (c) 2010-2012 Citrix Inc.
* Copyright (c) 2012 NetApp Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice unmodified, this list of conditions, and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
/*
* HyperV vmbus (virtual machine bus) network VSC (virtual services client)
* header file
*
* (Updated from unencumbered NvspProtocol.h)
*/
#ifndef __HV_NET_VSC_H__
#define __HV_NET_VSC_H__
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/queue.h>
#include <sys/taskqueue.h>
#include <sys/sema.h>
#include <sys/sx.h>
#include <machine/bus.h>
#include <sys/bus.h>
#include <sys/bus_dma.h>
#include <netinet/in.h>
#include <netinet/tcp_lro.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <net/if_media.h>
#include <dev/hyperv/include/hyperv.h>
#include <dev/hyperv/include/hyperv_busdma.h>
#include <dev/hyperv/include/vmbus.h>
#define HN_USE_TXDESC_BUFRING
MALLOC_DECLARE(M_NETVSC);
#define NVSP_INVALID_PROTOCOL_VERSION (0xFFFFFFFF)
#define NVSP_PROTOCOL_VERSION_1 2
#define NVSP_PROTOCOL_VERSION_2 0x30002
#define NVSP_PROTOCOL_VERSION_4 0x40000
#define NVSP_PROTOCOL_VERSION_5 0x50000
#define NVSP_MIN_PROTOCOL_VERSION (NVSP_PROTOCOL_VERSION_1)
#define NVSP_MAX_PROTOCOL_VERSION (NVSP_PROTOCOL_VERSION_2)
#define NVSP_PROTOCOL_VERSION_CURRENT NVSP_PROTOCOL_VERSION_2
#define VERSION_4_OFFLOAD_SIZE 22
#define NVSP_OPERATIONAL_STATUS_OK (0x00000000)
#define NVSP_OPERATIONAL_STATUS_DEGRADED (0x00000001)
#define NVSP_OPERATIONAL_STATUS_NONRECOVERABLE (0x00000002)
#define NVSP_OPERATIONAL_STATUS_NO_CONTACT (0x00000003)
#define NVSP_OPERATIONAL_STATUS_LOST_COMMUNICATION (0x00000004)
/*
* Maximun number of transfer pages (packets) the VSP will use on a receive
*/
#define NVSP_MAX_PACKETS_PER_RECEIVE 375
/* vRSS stuff */
#define RNDIS_OBJECT_TYPE_RSS_CAPABILITIES 0x88
#define RNDIS_OBJECT_TYPE_RSS_PARAMETERS 0x89
#define RNDIS_RECEIVE_SCALE_CAPABILITIES_REVISION_2 2
#define RNDIS_RECEIVE_SCALE_PARAMETERS_REVISION_2 2
struct rndis_obj_header {
uint8_t type;
uint8_t rev;
uint16_t size;
} __packed;
/* rndis_recv_scale_cap/cap_flag */
#define RNDIS_RSS_CAPS_MESSAGE_SIGNALED_INTERRUPTS 0x01000000
#define RNDIS_RSS_CAPS_CLASSIFICATION_AT_ISR 0x02000000
#define RNDIS_RSS_CAPS_CLASSIFICATION_AT_DPC 0x04000000
#define RNDIS_RSS_CAPS_USING_MSI_X 0x08000000
#define RNDIS_RSS_CAPS_RSS_AVAILABLE_ON_PORTS 0x10000000
#define RNDIS_RSS_CAPS_SUPPORTS_MSI_X 0x20000000
#define RNDIS_RSS_CAPS_HASH_TYPE_TCP_IPV4 0x00000100
#define RNDIS_RSS_CAPS_HASH_TYPE_TCP_IPV6 0x00000200
#define RNDIS_RSS_CAPS_HASH_TYPE_TCP_IPV6_EX 0x00000400
/* RNDIS_RECEIVE_SCALE_CAPABILITIES */
struct rndis_recv_scale_cap {
struct rndis_obj_header hdr;
uint32_t cap_flag;
uint32_t num_int_msg;
uint32_t num_recv_que;
uint16_t num_indirect_tabent;
} __packed;
/* rndis_recv_scale_param flags */
#define RNDIS_RSS_PARAM_FLAG_BASE_CPU_UNCHANGED 0x0001
#define RNDIS_RSS_PARAM_FLAG_HASH_INFO_UNCHANGED 0x0002
#define RNDIS_RSS_PARAM_FLAG_ITABLE_UNCHANGED 0x0004
#define RNDIS_RSS_PARAM_FLAG_HASH_KEY_UNCHANGED 0x0008
#define RNDIS_RSS_PARAM_FLAG_DISABLE_RSS 0x0010
/* Hash info bits */
#define RNDIS_HASH_FUNC_TOEPLITZ 0x00000001
#define RNDIS_HASH_IPV4 0x00000100
#define RNDIS_HASH_TCP_IPV4 0x00000200
#define RNDIS_HASH_IPV6 0x00000400
#define RNDIS_HASH_IPV6_EX 0x00000800
#define RNDIS_HASH_TCP_IPV6 0x00001000
#define RNDIS_HASH_TCP_IPV6_EX 0x00002000
#define RNDIS_RSS_INDIRECTION_TABLE_MAX_SIZE_REVISION_2 (128 * 4)
#define RNDIS_RSS_HASH_SECRET_KEY_MAX_SIZE_REVISION_2 40
#define ITAB_NUM 128
#define HASH_KEYLEN RNDIS_RSS_HASH_SECRET_KEY_MAX_SIZE_REVISION_2
/* RNDIS_RECEIVE_SCALE_PARAMETERS */
typedef struct rndis_recv_scale_param_ {
struct rndis_obj_header hdr;
/* Qualifies the rest of the information */
uint16_t flag;
/* The base CPU number to do receive processing. not used */
uint16_t base_cpu_number;
/* This describes the hash function and type being enabled */
uint32_t hashinfo;
/* The size of indirection table array */
uint16_t indirect_tabsize;
/* The offset of the indirection table from the beginning of this
* structure
*/
uint32_t indirect_taboffset;
/* The size of the hash secret key */
uint16_t hashkey_size;
/* The offset of the secret key from the beginning of this structure */
uint32_t hashkey_offset;
uint32_t processor_masks_offset;
uint32_t num_processor_masks;
uint32_t processor_masks_entry_size;
} rndis_recv_scale_param;
/*
* The following arguably belongs in a separate header file
*/
/*
* Defines
*/
#define NETVSC_SEND_BUFFER_SIZE (1024*1024*15) /* 15M */
#define NETVSC_SEND_BUFFER_ID 0xface
#define NETVSC_RECEIVE_BUFFER_SIZE_LEGACY (1024*1024*15) /* 15MB */
#define NETVSC_RECEIVE_BUFFER_SIZE (1024*1024*16) /* 16MB */
#define NETVSC_RECEIVE_BUFFER_ID 0xcafe
#define NETVSC_RECEIVE_SG_COUNT 1
/* Preallocated receive packets */
#define NETVSC_RECEIVE_PACKETLIST_COUNT 256
/*
* Maximum MTU we permit to be configured for a netvsc interface.
* When the code was developed, a max MTU of 12232 was tested and
* proven to work. 9K is a reasonable maximum for an Ethernet.
*/
#define NETVSC_MAX_CONFIGURABLE_MTU (9 * 1024)
#define NETVSC_PACKET_SIZE PAGE_SIZE
#define VRSS_SEND_TABLE_SIZE 16
/*
* Data types
*/
/*
* Per netvsc channel-specific
*/
typedef struct netvsc_dev_ {
struct hn_softc *sc;
/* Send buffer allocated by us but manages by NetVSP */
void *send_buf;
uint32_t send_buf_size;
uint32_t send_buf_gpadl_handle;
uint32_t send_section_size;
uint32_t send_section_count;
unsigned long bitsmap_words;
unsigned long *send_section_bitsmap;
/* Receive buffer allocated by us but managed by NetVSP */
void *rx_buf;
uint32_t rx_buf_size;
uint32_t rx_buf_gpadl_handle;
uint32_t rx_section_count;
/* Holds rndis device info */
void *extension;
uint8_t destroy;
/* Negotiated NVSP version */
uint32_t nvsp_version;
uint32_t num_channel;
struct hyperv_dma rxbuf_dma;
struct hyperv_dma txbuf_dma;
} netvsc_dev;
struct vmbus_channel;
typedef void (*pfn_on_send_rx_completion)(struct vmbus_channel *, void *);
#define NETVSC_DEVICE_RING_BUFFER_SIZE (128 * PAGE_SIZE)
#define NETVSC_PACKET_MAXPAGE 32
#define NETVSC_VLAN_PRIO_MASK 0xe000
#define NETVSC_VLAN_PRIO_SHIFT 13
#define NETVSC_VLAN_VID_MASK 0x0fff
#define TYPE_IPV4 2
#define TYPE_IPV6 4
#define TYPE_TCP 2
#define TYPE_UDP 4
#define TRANSPORT_TYPE_NOT_IP 0
#define TRANSPORT_TYPE_IPV4_TCP ((TYPE_IPV4 << 16) | TYPE_TCP)
#define TRANSPORT_TYPE_IPV4_UDP ((TYPE_IPV4 << 16) | TYPE_UDP)
#define TRANSPORT_TYPE_IPV6_TCP ((TYPE_IPV6 << 16) | TYPE_TCP)
#define TRANSPORT_TYPE_IPV6_UDP ((TYPE_IPV6 << 16) | TYPE_UDP)
#ifdef __LP64__
#define BITS_PER_LONG 64
#else
#define BITS_PER_LONG 32
#endif
typedef struct {
uint8_t mac_addr[6]; /* Assumption unsigned long */
uint8_t link_state;
} netvsc_device_info;
#ifndef HN_USE_TXDESC_BUFRING
struct hn_txdesc;
SLIST_HEAD(hn_txdesc_list, hn_txdesc);
#else
struct buf_ring;
#endif
struct hn_tx_ring;
struct hn_rx_ring {
struct ifnet *hn_ifp;
struct hn_tx_ring *hn_txr;
void *hn_rdbuf;
int hn_rx_idx;
/* Trust csum verification on host side */
int hn_trust_hcsum; /* HN_TRUST_HCSUM_ */
struct lro_ctrl hn_lro;
u_long hn_csum_ip;
u_long hn_csum_tcp;
u_long hn_csum_udp;
u_long hn_csum_trusted;
u_long hn_lro_tried;
u_long hn_small_pkts;
u_long hn_pkts;
u_long hn_rss_pkts;
/* Rarely used stuffs */
struct sysctl_oid *hn_rx_sysctl_tree;
int hn_rx_flags;
} __aligned(CACHE_LINE_SIZE);
#define HN_TRUST_HCSUM_IP 0x0001
#define HN_TRUST_HCSUM_TCP 0x0002
#define HN_TRUST_HCSUM_UDP 0x0004
#define HN_RX_FLAG_ATTACHED 0x1
struct hn_tx_ring {
#ifndef HN_USE_TXDESC_BUFRING
struct mtx hn_txlist_spin;
struct hn_txdesc_list hn_txlist;
#else
struct buf_ring *hn_txdesc_br;
#endif
int hn_txdesc_cnt;
int hn_txdesc_avail;
u_short hn_has_txeof;
u_short hn_txdone_cnt;
int hn_sched_tx;
void (*hn_txeof)(struct hn_tx_ring *);
struct taskqueue *hn_tx_taskq;
struct task hn_tx_task;
struct task hn_txeof_task;
struct buf_ring *hn_mbuf_br;
int hn_oactive;
int hn_tx_idx;
struct mtx hn_tx_lock;
struct hn_softc *hn_sc;
struct vmbus_channel *hn_chan;
int hn_direct_tx_size;
int hn_tx_chimney_size;
bus_dma_tag_t hn_tx_data_dtag;
uint64_t hn_csum_assist;
int hn_gpa_cnt;
struct vmbus_gpa hn_gpa[NETVSC_PACKET_MAXPAGE];
u_long hn_no_txdescs;
u_long hn_send_failed;
u_long hn_txdma_failed;
u_long hn_tx_collapsed;
u_long hn_tx_chimney_tried;
u_long hn_tx_chimney;
u_long hn_pkts;
/* Rarely used stuffs */
struct hn_txdesc *hn_txdesc;
bus_dma_tag_t hn_tx_rndis_dtag;
struct sysctl_oid *hn_tx_sysctl_tree;
int hn_tx_flags;
} __aligned(CACHE_LINE_SIZE);
#define HN_TX_FLAG_ATTACHED 0x1
/*
* Device-specific softc structure
*/
typedef struct hn_softc {
struct ifnet *hn_ifp;
struct ifmedia hn_media;
device_t hn_dev;
uint8_t hn_unit;
int hn_carrier;
int hn_if_flags;
struct mtx hn_lock;
int hn_initdone;
/* See hv_netvsc_drv_freebsd.c for rules on how to use */
int temp_unusable;
netvsc_dev *net_dev;
struct vmbus_channel *hn_prichan;
int hn_rx_ring_cnt;
int hn_rx_ring_inuse;
struct hn_rx_ring *hn_rx_ring;
int hn_tx_ring_cnt;
int hn_tx_ring_inuse;
struct hn_tx_ring *hn_tx_ring;
int hn_cpu;
int hn_tx_chimney_max;
struct taskqueue *hn_tx_taskq;
struct sysctl_oid *hn_tx_sysctl_tree;
struct sysctl_oid *hn_rx_sysctl_tree;
struct vmbus_xact_ctx *hn_xact;
} hn_softc_t;
/*
* Externs
*/
extern int hv_promisc_mode;
struct hn_send_ctx;
void netvsc_linkstatus_callback(struct hn_softc *sc, uint32_t status);
netvsc_dev *hv_nv_on_device_add(struct hn_softc *sc,
void *additional_info, struct hn_rx_ring *rxr);
int hv_nv_on_device_remove(struct hn_softc *sc,
boolean_t destroy_channel);
int hv_nv_on_send(struct vmbus_channel *chan, uint32_t rndis_mtype,
struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt);
int hv_nv_get_next_send_section(netvsc_dev *net_dev);
void hv_nv_subchan_attach(struct vmbus_channel *chan,
struct hn_rx_ring *rxr);
#endif /* __HV_NET_VSC_H__ */