/* SPDX-License-Identifier: GPL-2.0-only *//* * * Copyright (c) 2011, Microsoft Corporation. * * Authors: * Haiyang Zhang <haiyangz@microsoft.com> * Hank Janssen <hjanssen@microsoft.com> * K. Y. Srinivasan <kys@microsoft.com> */ #ifndef _HYPERV_NET_H#define _HYPERV_NET_H #include <linux/list.h>#include <linux/hyperv.h>#include <linux/rndis.h>#include <linux/jhash.h>#include <net/xdp.h> /* RSS related */#define OID_GEN_RECEIVE_SCALE_CAPABILITIES 0x00010203 /* query only */#define OID_GEN_RECEIVE_SCALE_PARAMETERS 0x00010204 /* query and set */ #define NDIS_OBJECT_TYPE_RSS_CAPABILITIES 0x88#define NDIS_OBJECT_TYPE_RSS_PARAMETERS 0x89#define NDIS_OBJECT_TYPE_OFFLOAD 0xa7 #define NDIS_RECEIVE_SCALE_CAPABILITIES_REVISION_2 2#define NDIS_RECEIVE_SCALE_PARAMETERS_REVISION_2 2 struct ndis_obj_header { u8 type; u8 rev; u16 size;} __packed; /* ndis_recv_scale_cap/cap_flag */#define NDIS_RSS_CAPS_MESSAGE_SIGNALED_INTERRUPTS 0x01000000#define NDIS_RSS_CAPS_CLASSIFICATION_AT_ISR 0x02000000#define NDIS_RSS_CAPS_CLASSIFICATION_AT_DPC 0x04000000#define NDIS_RSS_CAPS_USING_MSI_X 0x08000000#define NDIS_RSS_CAPS_RSS_AVAILABLE_ON_PORTS 0x10000000#define NDIS_RSS_CAPS_SUPPORTS_MSI_X 0x20000000#define NDIS_RSS_CAPS_HASH_TYPE_TCP_IPV4 0x00000100#define NDIS_RSS_CAPS_HASH_TYPE_TCP_IPV6 0x00000200#define NDIS_RSS_CAPS_HASH_TYPE_TCP_IPV6_EX 0x00000400 struct ndis_recv_scale_cap { /* NDIS_RECEIVE_SCALE_CAPABILITIES */ struct ndis_obj_header hdr; u32 cap_flag; u32 num_int_msg; u32 num_recv_que; u16 num_indirect_tabent;} __packed; /* ndis_recv_scale_param flags */#define NDIS_RSS_PARAM_FLAG_BASE_CPU_UNCHANGED 0x0001#define NDIS_RSS_PARAM_FLAG_HASH_INFO_UNCHANGED 0x0002#define NDIS_RSS_PARAM_FLAG_ITABLE_UNCHANGED 0x0004#define NDIS_RSS_PARAM_FLAG_HASH_KEY_UNCHANGED 0x0008#define NDIS_RSS_PARAM_FLAG_DISABLE_RSS 0x0010 /* Hash info bits */#define NDIS_HASH_FUNC_TOEPLITZ 0x00000001#define NDIS_HASH_IPV4 0x00000100#define NDIS_HASH_TCP_IPV4 0x00000200#define NDIS_HASH_IPV6 0x00000400#define NDIS_HASH_IPV6_EX 0x00000800#define NDIS_HASH_TCP_IPV6 0x00001000#define NDIS_HASH_TCP_IPV6_EX 0x00002000 #define NDIS_RSS_INDIRECTION_TABLE_MAX_SIZE_REVISION_2 (128 * 4)#define NDIS_RSS_HASH_SECRET_KEY_MAX_SIZE_REVISION_2 40 #define ITAB_NUM 128#define ITAB_NUM_MAX 256 struct ndis_recv_scale_param { /* NDIS_RECEIVE_SCALE_PARAMETERS */ struct ndis_obj_header hdr; /* Qualifies the rest of the information */ u16 flag; /* The base CPU number to do receive processing. not used */ u16 base_cpu_number; /* This describes the hash function and type being enabled */ u32 hashinfo; /* The size of indirection table array */ u16 indirect_tabsize; /* The offset of the indirection table from the beginning of this * structure */ u32 indirect_taboffset; /* The size of the hash secret key */ u16 hashkey_size; /* The offset of the secret key from the beginning of this structure */ u32 hashkey_offset; u32 processor_masks_offset; u32 num_processor_masks; u32 processor_masks_entry_size;}; struct ndis_tcp_ip_checksum_info { union { struct { u32 is_ipv4:1; u32 is_ipv6:1; u32 tcp_checksum:1; u32 udp_checksum:1; u32 ip_header_checksum:1; u32 reserved:11; u32 tcp_header_offset:10; } transmit; struct { u32 tcp_checksum_failed:1; u32 udp_checksum_failed:1; u32 ip_checksum_failed:1; u32 tcp_checksum_succeeded:1; u32 udp_checksum_succeeded:1; u32 ip_checksum_succeeded:1; u32 loopback:1; u32 tcp_checksum_value_invalid:1; u32 ip_checksum_value_invalid:1; } receive; u32 value; };}; struct ndis_pkt_8021q_info { union { struct { u32 pri:3; /* User Priority */ u32 cfi:1; /* Canonical Format ID */ u32 vlanid:12; /* VLAN ID */ u32 reserved:16; }; u32 value; };}; /* * Represent netvsc packet which contains 1 RNDIS and 1 ethernet frame * within the RNDIS * * The size of this structure is less than 48 bytes and we can now * place this structure in the skb->cb field. */struct hv_netvsc_packet { /* Bookkeeping stuff */ u8 cp_partial; /* partial copy into send buffer */ u8 rmsg_size; /* RNDIS header and PPI size */ u8 page_buf_cnt; u16 q_idx; u16 total_packets; u32 total_bytes; u32 send_buf_index; u32 total_data_buflen; struct hv_dma_range *dma_range;}; #define NETVSC_HASH_KEYLEN 40 struct netvsc_device_info { unsigned char mac_adr[ETH_ALEN]; u32 num_chn; u32 send_sections; u32 recv_sections; u32 send_section_size; u32 recv_section_size; struct bpf_prog *bprog; u8 rss_key[NETVSC_HASH_KEYLEN];}; enum rndis_device_state { RNDIS_DEV_UNINITIALIZED = 0, RNDIS_DEV_INITIALIZING, RNDIS_DEV_INITIALIZED, RNDIS_DEV_DATAINITIALIZED,}; struct rndis_device { struct net_device *ndev; enum rndis_device_state state; atomic_t new_req_id; spinlock_t request_lock; struct list_head req_list; struct work_struct mcast_work; u32 filter; bool link_state; /* 0 - link up, 1 - link down */ u8 hw_mac_adr[ETH_ALEN]; u8 rss_key[NETVSC_HASH_KEYLEN];}; /* Interface */struct rndis_message;struct ndis_offload_params;struct netvsc_device;struct netvsc_channel;struct net_device_context; extern u32 netvsc_ring_bytes; int netvsc_workqueue_init(void);void netvsc_workqueue_destroy(void);struct netvsc_device *netvsc_device_add(struct hv_device *device, const struct netvsc_device_info *info);int netvsc_alloc_recv_comp_ring(struct netvsc_device *net_device, u32 q_idx);void netvsc_device_remove(struct hv_device *device);int netvsc_send(struct net_device *net, struct hv_netvsc_packet *packet, struct rndis_message *rndis_msg, struct hv_page_buffer *page_buffer, struct sk_buff *skb, bool xdp_tx);void netvsc_linkstatus_callback(struct net_device *net, struct rndis_message *resp, void *data, u32 data_buflen);int netvsc_recv_callback(struct net_device *net, struct netvsc_device *nvdev, struct netvsc_channel *nvchan);void netvsc_channel_cb(void *context);int netvsc_poll(struct napi_struct *napi, int budget); void netvsc_xdp_xmit(struct sk_buff *skb, struct net_device *ndev);u32 netvsc_run_xdp(struct net_device *ndev, struct netvsc_channel *nvchan, struct xdp_buff *xdp);unsigned int netvsc_xdp_fraglen(unsigned int len);struct bpf_prog *netvsc_xdp_get(struct netvsc_device *nvdev);int netvsc_xdp_set(struct net_device *dev, struct bpf_prog *prog, struct netlink_ext_ack *extack, struct netvsc_device *nvdev);int netvsc_vf_setxdp(struct net_device *vf_netdev, struct bpf_prog *prog);int netvsc_bpf(struct net_device *dev, struct netdev_bpf *bpf);int netvsc_ndoxdp_xmit(struct net_device *ndev, int n, struct xdp_frame **frames, u32 flags); int rndis_set_subchannel(struct net_device *ndev, struct netvsc_device *nvdev, struct netvsc_device_info *dev_info);int rndis_filter_open(struct netvsc_device *nvdev);int rndis_filter_close(struct netvsc_device *nvdev);struct netvsc_device *rndis_filter_device_add(struct hv_device *dev, struct netvsc_device_info *info);void rndis_filter_update(struct netvsc_device *nvdev);void rndis_filter_device_remove(struct hv_device *dev, struct netvsc_device *nvdev);int rndis_filter_set_rss_param(struct rndis_device *rdev, const u8 *key);int rndis_filter_set_offload_params(struct net_device *ndev, struct netvsc_device *nvdev, struct ndis_offload_params *req_offloads);int rndis_filter_receive(struct net_device *ndev, struct netvsc_device *net_dev, struct netvsc_channel *nvchan, void *data, u32 buflen); int rndis_filter_set_device_mac(struct netvsc_device *ndev, const char *mac); int netvsc_switch_datapath(struct net_device *nv_dev, bool vf); #define NVSP_INVALID_PROTOCOL_VERSION ((u32)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_PROTOCOL_VERSION_6 0x60000#define NVSP_PROTOCOL_VERSION_61 0x60001 enum { NVSP_MSG_TYPE_NONE = 0, /* Init Messages */ NVSP_MSG_TYPE_INIT = 1, NVSP_MSG_TYPE_INIT_COMPLETE = 2, NVSP_VERSION_MSG_START = 100, /* Version 1 Messages */ NVSP_MSG1_TYPE_SEND_NDIS_VER = NVSP_VERSION_MSG_START, NVSP_MSG1_TYPE_SEND_RECV_BUF, NVSP_MSG1_TYPE_SEND_RECV_BUF_COMPLETE, NVSP_MSG1_TYPE_REVOKE_RECV_BUF, NVSP_MSG1_TYPE_SEND_SEND_BUF, NVSP_MSG1_TYPE_SEND_SEND_BUF_COMPLETE, NVSP_MSG1_TYPE_REVOKE_SEND_BUF, NVSP_MSG1_TYPE_SEND_RNDIS_PKT, NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE, /* Version 2 messages */ NVSP_MSG2_TYPE_SEND_CHIMNEY_DELEGATED_BUF, NVSP_MSG2_TYPE_SEND_CHIMNEY_DELEGATED_BUF_COMP, NVSP_MSG2_TYPE_REVOKE_CHIMNEY_DELEGATED_BUF, NVSP_MSG2_TYPE_RESUME_CHIMNEY_RX_INDICATION, NVSP_MSG2_TYPE_TERMINATE_CHIMNEY, NVSP_MSG2_TYPE_TERMINATE_CHIMNEY_COMP, NVSP_MSG2_TYPE_INDICATE_CHIMNEY_EVENT, NVSP_MSG2_TYPE_SEND_CHIMNEY_PKT, NVSP_MSG2_TYPE_SEND_CHIMNEY_PKT_COMP, NVSP_MSG2_TYPE_POST_CHIMNEY_RECV_REQ, NVSP_MSG2_TYPE_POST_CHIMNEY_RECV_REQ_COMP, NVSP_MSG2_TYPE_ALLOC_RXBUF, NVSP_MSG2_TYPE_ALLOC_RXBUF_COMP, NVSP_MSG2_TYPE_FREE_RXBUF, NVSP_MSG2_TYPE_SEND_VMQ_RNDIS_PKT, NVSP_MSG2_TYPE_SEND_VMQ_RNDIS_PKT_COMP, NVSP_MSG2_TYPE_SEND_NDIS_CONFIG, NVSP_MSG2_TYPE_ALLOC_CHIMNEY_HANDLE, NVSP_MSG2_TYPE_ALLOC_CHIMNEY_HANDLE_COMP, NVSP_MSG2_MAX = NVSP_MSG2_TYPE_ALLOC_CHIMNEY_HANDLE_COMP, /* Version 4 messages */ NVSP_MSG4_TYPE_SEND_VF_ASSOCIATION, NVSP_MSG4_TYPE_SWITCH_DATA_PATH, NVSP_MSG4_TYPE_UPLINK_CONNECT_STATE_DEPRECATED, NVSP_MSG4_MAX = NVSP_MSG4_TYPE_UPLINK_CONNECT_STATE_DEPRECATED, /* Version 5 messages */ NVSP_MSG5_TYPE_OID_QUERY_EX, NVSP_MSG5_TYPE_OID_QUERY_EX_COMP, NVSP_MSG5_TYPE_SUBCHANNEL, NVSP_MSG5_TYPE_SEND_INDIRECTION_TABLE, NVSP_MSG5_MAX = NVSP_MSG5_TYPE_SEND_INDIRECTION_TABLE, /* Version 6 messages */ NVSP_MSG6_TYPE_PD_API, NVSP_MSG6_TYPE_PD_POST_BATCH, NVSP_MSG6_MAX = NVSP_MSG6_TYPE_PD_POST_BATCH}; enum { NVSP_STAT_NONE = 0, NVSP_STAT_SUCCESS, NVSP_STAT_FAIL, NVSP_STAT_PROTOCOL_TOO_NEW, NVSP_STAT_PROTOCOL_TOO_OLD, NVSP_STAT_INVALID_RNDIS_PKT, NVSP_STAT_BUSY, NVSP_STAT_PROTOCOL_UNSUPPORTED, NVSP_STAT_MAX,}; struct nvsp_message_header { u32 msg_type;}; /* Init Messages */ /* * This message is used by the VSC to initialize the channel after the channels * has been opened. This message should never include anything other then * versioning (i.e. this message will be the same for ever). */struct nvsp_message_init { u32 min_protocol_ver; u32 max_protocol_ver;} __packed; /* * This message is used by the VSP to complete the initialization of the * channel. This message should never include anything other then versioning * (i.e. this message will be the same for ever). */struct nvsp_message_init_complete { u32 negotiated_protocol_ver; u32 max_mdl_chain_len; u32 status;} __packed; union nvsp_message_init_uber { struct nvsp_message_init init; struct nvsp_message_init_complete init_complete;} __packed; /* Version 1 Messages */ /* * This message is used by the VSC to send the NDIS version to the VSP. The VSP * can use this information when handling OIDs sent by the VSC. */struct nvsp_1_message_send_ndis_version { u32 ndis_major_ver; u32 ndis_minor_ver;} __packed; /* * This message is used by the VSC to send a receive buffer to the VSP. The VSP * can then use the receive buffer to send data to the VSC. */struct nvsp_1_message_send_receive_buffer { u32 gpadl_handle; u16 id;} __packed; struct nvsp_1_receive_buffer_section { u32 offset; u32 sub_alloc_size; u32 num_sub_allocs; u32 end_offset;} __packed; /* * This message is used by the VSP to acknowledge a receive buffer send by the * VSC. This message must be sent by the VSP before the VSP uses the receive * buffer. */struct nvsp_1_message_send_receive_buffer_complete { u32 status; u32 num_sections; /* * The receive buffer is split into two parts, a large suballocation * section and a small suballocation section. These sections are then * suballocated by a certain size. */ /* * For example, the following break up of the receive buffer has 6 * large suballocations and 10 small suballocations. */ /* * | Large Section | | Small Section | * ------------------------------------------------------------ * | | | | | | | | | | | | | | | | | | * | | * LargeOffset SmallOffset */ struct nvsp_1_receive_buffer_section sections[];} __packed; /* * This message is sent by the VSC to revoke the receive buffer. After the VSP * completes this transaction, the vsp should never use the receive buffer * again. */struct nvsp_1_message_revoke_receive_buffer { u16 id;}; /* * This message is used by the VSC to send a send buffer to the VSP. The VSC * can then use the send buffer to send data to the VSP. */struct nvsp_1_message_send_send_buffer { u32 gpadl_handle; u16 id;} __packed; /* * This message is used by the VSP to acknowledge a send buffer sent by the * VSC. This message must be sent by the VSP before the VSP uses the sent * buffer. */struct nvsp_1_message_send_send_buffer_complete { u32 status; /* * The VSC gets to choose the size of the send buffer and the VSP gets * to choose the sections size of the buffer. This was done to enable * dynamic reconfigurations when the cost of GPA-direct buffersLines 1–500 of 1827. Load more
/* SPDX-License-Identifier: GPL-2.0-only */ /* * * Copyright (c) 2011, Microsoft Corporation. * * Authors: * Haiyang Zhang <haiyangz@microsoft.com> * Hank Janssen <hjanssen@microsoft.com> * K. Y. Srinivasan <kys@microsoft.com> */ #ifndef _HYPERV_NET_H #define _HYPERV_NET_H #include <linux/list.h> #include <linux/hyperv.h> #include <linux/rndis.h> #include <linux/jhash.h> #include <net/xdp.h> /* RSS related */ #define OID_GEN_RECEIVE_SCALE_CAPABILITIES 0x00010203 /* query only */ #define OID_GEN_RECEIVE_SCALE_PARAMETERS 0x00010204 /* query and set */ #define NDIS_OBJECT_TYPE_RSS_CAPABILITIES 0x88 #define NDIS_OBJECT_TYPE_RSS_PARAMETERS 0x89 #define NDIS_OBJECT_TYPE_OFFLOAD 0xa7 #define NDIS_RECEIVE_SCALE_CAPABILITIES_REVISION_2 2 #define NDIS_RECEIVE_SCALE_PARAMETERS_REVISION_2 2 struct ndis_obj_header { u8 type; u8 rev; u16 size; } __packed; /* ndis_recv_scale_cap/cap_flag */ #define NDIS_RSS_CAPS_MESSAGE_SIGNALED_INTERRUPTS 0x01000000 #define NDIS_RSS_CAPS_CLASSIFICATION_AT_ISR 0x02000000 #define NDIS_RSS_CAPS_CLASSIFICATION_AT_DPC 0x04000000 #define NDIS_RSS_CAPS_USING_MSI_X 0x08000000 #define NDIS_RSS_CAPS_RSS_AVAILABLE_ON_PORTS 0x10000000 #define NDIS_RSS_CAPS_SUPPORTS_MSI_X 0x20000000 #define NDIS_RSS_CAPS_HASH_TYPE_TCP_IPV4 0x00000100 #define NDIS_RSS_CAPS_HASH_TYPE_TCP_IPV6 0x00000200 #define NDIS_RSS_CAPS_HASH_TYPE_TCP_IPV6_EX 0x00000400 struct ndis_recv_scale_cap { /* NDIS_RECEIVE_SCALE_CAPABILITIES */ struct ndis_obj_header hdr; u32 cap_flag; u32 num_int_msg; u32 num_recv_que; u16 num_indirect_tabent; } __packed; /* ndis_recv_scale_param flags */ #define NDIS_RSS_PARAM_FLAG_BASE_CPU_UNCHANGED 0x0001 #define NDIS_RSS_PARAM_FLAG_HASH_INFO_UNCHANGED 0x0002 #define NDIS_RSS_PARAM_FLAG_ITABLE_UNCHANGED 0x0004 #define NDIS_RSS_PARAM_FLAG_HASH_KEY_UNCHANGED 0x0008 #define NDIS_RSS_PARAM_FLAG_DISABLE_RSS 0x0010 /* Hash info bits */ #define NDIS_HASH_FUNC_TOEPLITZ 0x00000001 #define NDIS_HASH_IPV4 0x00000100 #define NDIS_HASH_TCP_IPV4 0x00000200 #define NDIS_HASH_IPV6 0x00000400 #define NDIS_HASH_IPV6_EX 0x00000800 #define NDIS_HASH_TCP_IPV6 0x00001000 #define NDIS_HASH_TCP_IPV6_EX 0x00002000 #define NDIS_RSS_INDIRECTION_TABLE_MAX_SIZE_REVISION_2 (128 * 4) #define NDIS_RSS_HASH_SECRET_KEY_MAX_SIZE_REVISION_2 40 #define ITAB_NUM 128 #define ITAB_NUM_MAX 256 struct ndis_recv_scale_param { /* NDIS_RECEIVE_SCALE_PARAMETERS */ struct ndis_obj_header hdr; /* Qualifies the rest of the information */ u16 flag; /* The base CPU number to do receive processing. not used */ u16 base_cpu_number; /* This describes the hash function and type being enabled */ u32 hashinfo; /* The size of indirection table array */ u16 indirect_tabsize; /* The offset of the indirection table from the beginning of this * structure */ u32 indirect_taboffset; /* The size of the hash secret key */ u16 hashkey_size; /* The offset of the secret key from the beginning of this structure */ u32 hashkey_offset; u32 processor_masks_offset; u32 num_processor_masks; u32 processor_masks_entry_size; }; struct ndis_tcp_ip_checksum_info { union { struct { u32 is_ipv4:1; u32 is_ipv6:1; u32 tcp_checksum:1; u32 udp_checksum:1; u32 ip_header_checksum:1; u32 reserved:11; u32 tcp_header_offset:10; } transmit; struct { u32 tcp_checksum_failed:1; u32 udp_checksum_failed:1; u32 ip_checksum_failed:1; u32 tcp_checksum_succeeded:1; u32 udp_checksum_succeeded:1; u32 ip_checksum_succeeded:1; u32 loopback:1; u32 tcp_checksum_value_invalid:1; u32 ip_checksum_value_invalid:1; } receive; u32 value; }; }; struct ndis_pkt_8021q_info { union { struct { u32 pri:3; /* User Priority */ u32 cfi:1; /* Canonical Format ID */ u32 vlanid:12; /* VLAN ID */ u32 reserved:16; }; u32 value; }; }; /* * Represent netvsc packet which contains 1 RNDIS and 1 ethernet frame * within the RNDIS * * The size of this structure is less than 48 bytes and we can now * place this structure in the skb->cb field. */ struct hv_netvsc_packet { /* Bookkeeping stuff */ u8 cp_partial; /* partial copy into send buffer */ u8 rmsg_size; /* RNDIS header and PPI size */ u8 page_buf_cnt; u16 q_idx; u16 total_packets; u32 total_bytes; u32 send_buf_index; u32 total_data_buflen; struct hv_dma_range *dma_range; }; #define NETVSC_HASH_KEYLEN 40 struct netvsc_device_info { unsigned char mac_adr[ETH_ALEN]; u32 num_chn; u32 send_sections; u32 recv_sections; u32 send_section_size; u32 recv_section_size; struct bpf_prog *bprog; u8 rss_key[NETVSC_HASH_KEYLEN]; }; enum rndis_device_state { RNDIS_DEV_UNINITIALIZED = 0, RNDIS_DEV_INITIALIZING, RNDIS_DEV_INITIALIZED, RNDIS_DEV_DATAINITIALIZED, }; struct rndis_device { struct net_device *ndev; enum rndis_device_state state; atomic_t new_req_id; spinlock_t request_lock; struct list_head req_list; struct work_struct mcast_work; u32 filter; bool link_state; /* 0 - link up, 1 - link down */ u8 hw_mac_adr[ETH_ALEN]; u8 rss_key[NETVSC_HASH_KEYLEN]; }; /* Interface */ struct rndis_message; struct ndis_offload_params; struct netvsc_device; struct netvsc_channel; struct net_device_context; extern u32 netvsc_ring_bytes; int netvsc_workqueue_init(void); void netvsc_workqueue_destroy(void); struct netvsc_device *netvsc_device_add(struct hv_device *device, const struct netvsc_device_info *info); int netvsc_alloc_recv_comp_ring(struct netvsc_device *net_device, u32 q_idx); void netvsc_device_remove(struct hv_device *device); int netvsc_send(struct net_device *net, struct hv_netvsc_packet *packet, struct rndis_message *rndis_msg, struct hv_page_buffer *page_buffer, struct sk_buff *skb, bool xdp_tx); void netvsc_linkstatus_callback(struct net_device *net, struct rndis_message *resp, void *data, u32 data_buflen); int netvsc_recv_callback(struct net_device *net, struct netvsc_device *nvdev, struct netvsc_channel *nvchan); void netvsc_channel_cb(void *context); int netvsc_poll(struct napi_struct *napi, int budget); void netvsc_xdp_xmit(struct sk_buff *skb, struct net_device *ndev); u32 netvsc_run_xdp(struct net_device *ndev, struct netvsc_channel *nvchan, struct xdp_buff *xdp); unsigned int netvsc_xdp_fraglen(unsigned int len); struct bpf_prog *netvsc_xdp_get(struct netvsc_device *nvdev); int netvsc_xdp_set(struct net_device *dev, struct bpf_prog *prog, struct netlink_ext_ack *extack, struct netvsc_device *nvdev); int netvsc_vf_setxdp(struct net_device *vf_netdev, struct bpf_prog *prog); int netvsc_bpf(struct net_device *dev, struct netdev_bpf *bpf); int netvsc_ndoxdp_xmit(struct net_device *ndev, int n, struct xdp_frame **frames, u32 flags); int rndis_set_subchannel(struct net_device *ndev, struct netvsc_device *nvdev, struct netvsc_device_info *dev_info); int rndis_filter_open(struct netvsc_device *nvdev); int rndis_filter_close(struct netvsc_device *nvdev); struct netvsc_device *rndis_filter_device_add(struct hv_device *dev, struct netvsc_device_info *info); void rndis_filter_update(struct netvsc_device *nvdev); void rndis_filter_device_remove(struct hv_device *dev, struct netvsc_device *nvdev); int rndis_filter_set_rss_param(struct rndis_device *rdev, const u8 *key); int rndis_filter_set_offload_params(struct net_device *ndev, struct netvsc_device *nvdev, struct ndis_offload_params *req_offloads); int rndis_filter_receive(struct net_device *ndev, struct netvsc_device *net_dev, struct netvsc_channel *nvchan, void *data, u32 buflen); int rndis_filter_set_device_mac(struct netvsc_device *ndev, const char *mac); int netvsc_switch_datapath(struct net_device *nv_dev, bool vf); #define NVSP_INVALID_PROTOCOL_VERSION ((u32)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_PROTOCOL_VERSION_6 0x60000 #define NVSP_PROTOCOL_VERSION_61 0x60001 enum { NVSP_MSG_TYPE_NONE = 0, /* Init Messages */ NVSP_MSG_TYPE_INIT = 1, NVSP_MSG_TYPE_INIT_COMPLETE = 2, NVSP_VERSION_MSG_START = 100, /* Version 1 Messages */ NVSP_MSG1_TYPE_SEND_NDIS_VER = NVSP_VERSION_MSG_START, NVSP_MSG1_TYPE_SEND_RECV_BUF, NVSP_MSG1_TYPE_SEND_RECV_BUF_COMPLETE, NVSP_MSG1_TYPE_REVOKE_RECV_BUF, NVSP_MSG1_TYPE_SEND_SEND_BUF, NVSP_MSG1_TYPE_SEND_SEND_BUF_COMPLETE, NVSP_MSG1_TYPE_REVOKE_SEND_BUF, NVSP_MSG1_TYPE_SEND_RNDIS_PKT, NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE, /* Version 2 messages */ NVSP_MSG2_TYPE_SEND_CHIMNEY_DELEGATED_BUF, NVSP_MSG2_TYPE_SEND_CHIMNEY_DELEGATED_BUF_COMP, NVSP_MSG2_TYPE_REVOKE_CHIMNEY_DELEGATED_BUF, NVSP_MSG2_TYPE_RESUME_CHIMNEY_RX_INDICATION, NVSP_MSG2_TYPE_TERMINATE_CHIMNEY, NVSP_MSG2_TYPE_TERMINATE_CHIMNEY_COMP, NVSP_MSG2_TYPE_INDICATE_CHIMNEY_EVENT, NVSP_MSG2_TYPE_SEND_CHIMNEY_PKT, NVSP_MSG2_TYPE_SEND_CHIMNEY_PKT_COMP, NVSP_MSG2_TYPE_POST_CHIMNEY_RECV_REQ, NVSP_MSG2_TYPE_POST_CHIMNEY_RECV_REQ_COMP, NVSP_MSG2_TYPE_ALLOC_RXBUF, NVSP_MSG2_TYPE_ALLOC_RXBUF_COMP, NVSP_MSG2_TYPE_FREE_RXBUF, NVSP_MSG2_TYPE_SEND_VMQ_RNDIS_PKT, NVSP_MSG2_TYPE_SEND_VMQ_RNDIS_PKT_COMP, NVSP_MSG2_TYPE_SEND_NDIS_CONFIG, NVSP_MSG2_TYPE_ALLOC_CHIMNEY_HANDLE, NVSP_MSG2_TYPE_ALLOC_CHIMNEY_HANDLE_COMP, NVSP_MSG2_MAX = NVSP_MSG2_TYPE_ALLOC_CHIMNEY_HANDLE_COMP, /* Version 4 messages */ NVSP_MSG4_TYPE_SEND_VF_ASSOCIATION, NVSP_MSG4_TYPE_SWITCH_DATA_PATH, NVSP_MSG4_TYPE_UPLINK_CONNECT_STATE_DEPRECATED, NVSP_MSG4_MAX = NVSP_MSG4_TYPE_UPLINK_CONNECT_STATE_DEPRECATED, /* Version 5 messages */ NVSP_MSG5_TYPE_OID_QUERY_EX, NVSP_MSG5_TYPE_OID_QUERY_EX_COMP, NVSP_MSG5_TYPE_SUBCHANNEL, NVSP_MSG5_TYPE_SEND_INDIRECTION_TABLE, NVSP_MSG5_MAX = NVSP_MSG5_TYPE_SEND_INDIRECTION_TABLE, /* Version 6 messages */ NVSP_MSG6_TYPE_PD_API, NVSP_MSG6_TYPE_PD_POST_BATCH, NVSP_MSG6_MAX = NVSP_MSG6_TYPE_PD_POST_BATCH }; enum { NVSP_STAT_NONE = 0, NVSP_STAT_SUCCESS, NVSP_STAT_FAIL, NVSP_STAT_PROTOCOL_TOO_NEW, NVSP_STAT_PROTOCOL_TOO_OLD, NVSP_STAT_INVALID_RNDIS_PKT, NVSP_STAT_BUSY, NVSP_STAT_PROTOCOL_UNSUPPORTED, NVSP_STAT_MAX, }; struct nvsp_message_header { u32 msg_type; }; /* Init Messages */ /* * This message is used by the VSC to initialize the channel after the channels * has been opened. This message should never include anything other then * versioning (i.e. this message will be the same for ever). */ struct nvsp_message_init { u32 min_protocol_ver; u32 max_protocol_ver; } __packed; /* * This message is used by the VSP to complete the initialization of the * channel. This message should never include anything other then versioning * (i.e. this message will be the same for ever). */ struct nvsp_message_init_complete { u32 negotiated_protocol_ver; u32 max_mdl_chain_len; u32 status; } __packed; union nvsp_message_init_uber { struct nvsp_message_init init; struct nvsp_message_init_complete init_complete; } __packed; /* Version 1 Messages */ /* * This message is used by the VSC to send the NDIS version to the VSP. The VSP * can use this information when handling OIDs sent by the VSC. */ struct nvsp_1_message_send_ndis_version { u32 ndis_major_ver; u32 ndis_minor_ver; } __packed; /* * This message is used by the VSC to send a receive buffer to the VSP. The VSP * can then use the receive buffer to send data to the VSC. */ struct nvsp_1_message_send_receive_buffer { u32 gpadl_handle; u16 id; } __packed; struct nvsp_1_receive_buffer_section { u32 offset; u32 sub_alloc_size; u32 num_sub_allocs; u32 end_offset; } __packed; /* * This message is used by the VSP to acknowledge a receive buffer send by the * VSC. This message must be sent by the VSP before the VSP uses the receive * buffer. */ struct nvsp_1_message_send_receive_buffer_complete { u32 status; u32 num_sections; /* * The receive buffer is split into two parts, a large suballocation * section and a small suballocation section. These sections are then * suballocated by a certain size. */ /* * For example, the following break up of the receive buffer has 6 * large suballocations and 10 small suballocations. */ /* * | Large Section | | Small Section | * ------------------------------------------------------------ * | | | | | | | | | | | | | | | | | | * | | * LargeOffset SmallOffset */ struct nvsp_1_receive_buffer_section sections[]; } __packed; /* * This message is sent by the VSC to revoke the receive buffer. After the VSP * completes this transaction, the vsp should never use the receive buffer * again. */ struct nvsp_1_message_revoke_receive_buffer { u16 id; }; /* * This message is used by the VSC to send a send buffer to the VSP. The VSC * can then use the send buffer to send data to the VSP. */ struct nvsp_1_message_send_send_buffer { u32 gpadl_handle; u16 id; } __packed; /* * This message is used by the VSP to acknowledge a send buffer sent by the * VSC. This message must be sent by the VSP before the VSP uses the sent * buffer. */ struct nvsp_1_message_send_send_buffer_complete { u32 status; /* * The VSC gets to choose the size of the send buffer and the VSP gets * to choose the sections size of the buffer. This was done to enable * dynamic reconfigurations when the cost of GPA-direct buffers