Type: improvement Change-Id: Ifea4badd58f7e2b5e792d7506f6747851a08587f Signed-off-by: Benoît Ganne <bganne@cisco.com>
805 lines
21 KiB
C
805 lines
21 KiB
C
/*
|
|
* Copyright (c) 2018 Cisco and/or its affiliates.
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at:
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef __included_vmnet_vmnet_h__
|
|
#define __included_vmnet_vmnet_h__
|
|
|
|
#define foreach_vmxnet3_tx_func_error \
|
|
_(ERROR_PACKETS, "error packets") \
|
|
_(LINK_DOWN, "link down") \
|
|
_(NO_FREE_SLOTS, "no free tx slots")
|
|
|
|
typedef enum
|
|
{
|
|
#define _(f,s) VMXNET3_TX_ERROR_##f,
|
|
foreach_vmxnet3_tx_func_error
|
|
#undef _
|
|
VMXNET3_TX_N_ERROR,
|
|
} vmxnet3_tx_func_error_t;
|
|
|
|
#define foreach_vmxnet3_rxmode_flags \
|
|
_(0, UCAST, "unicast") \
|
|
_(1, MCAST, "multicast") \
|
|
_(2, BCAST, "broadcast") \
|
|
_(3, ALL_MULTI, "all multicast") \
|
|
_(4, PROMISC, "promiscuous")
|
|
|
|
enum
|
|
{
|
|
#define _(a, b, c) VMXNET3_RXMODE_##b = (1 << a),
|
|
foreach_vmxnet3_rxmode_flags
|
|
#undef _
|
|
};
|
|
|
|
#define foreach_vmxnet3_show_entry \
|
|
_(RX_COMP, "rx comp") \
|
|
_(RX_DESC0, "rx desc 0") \
|
|
_(RX_DESC1, "rx desc 1") \
|
|
_(TX_COMP, "tx comp") \
|
|
_(TX_DESC, "tx desc")
|
|
|
|
enum
|
|
{
|
|
#define _(a, b) VMXNET3_SHOW_##a,
|
|
foreach_vmxnet3_show_entry
|
|
#undef _
|
|
};
|
|
|
|
#define foreach_vmxnet3_feature_flags \
|
|
_(0, RXCSUM, "rx checksum") \
|
|
_(1, RSS, "RSS") \
|
|
_(2, RXVLAN, "rx VLAN") \
|
|
_(3, LRO, "LRO")
|
|
|
|
enum
|
|
{
|
|
#define _(a, b, c) VMXNET3_F_##b = (1 << a),
|
|
foreach_vmxnet3_feature_flags
|
|
#undef _
|
|
};
|
|
|
|
#define foreach_vmxnet3_rss_hash_type \
|
|
_(0, IPV4, "ipv4") \
|
|
_(1, TCP_IPV4, "tcp ipv4") \
|
|
_(2, IPV6, "ipv6") \
|
|
_(3, TCP_IPV6, "tcp ipv6")
|
|
|
|
enum
|
|
{
|
|
#define _(a, b, c) VMXNET3_RSS_HASH_TYPE_##b = (1 << a),
|
|
foreach_vmxnet3_rss_hash_type
|
|
#undef _
|
|
};
|
|
|
|
#define VMXNET3_RSS_HASH_FUNC_TOEPLITZ 1
|
|
#define VMXNET3_RSS_MAX_KEY_SZ 40
|
|
#define VMXNET3_RSS_MAX_IND_TABLE_SZ 128
|
|
|
|
#define VMXNET3_TXQ_MAX 8
|
|
#define VMXNET3_RXQ_MAX 16
|
|
#define VMXNET3_TX_START(vd) ((vd)->queues)
|
|
#define VMXNET3_RX_START(vd) \
|
|
((vd)->queues + (vd)->num_tx_queues * sizeof (vmxnet3_tx_queue))
|
|
|
|
/* BAR 0 */
|
|
#define VMXNET3_REG_IMR 0x0000 /* Interrupt Mask Register */
|
|
#define VMXNET3_REG_TXPROD 0x0600 /* Tx Producer Index */
|
|
#define VMXNET3_REG_RXPROD 0x0800 /* Rx Producer Index for ring 1 */
|
|
#define VMXNET3_REG_RXPROD2 0x0A00 /* Rx Producer Index for ring 2 */
|
|
|
|
|
|
/* BAR 1 */
|
|
#define VMXNET3_REG_VRRS 0x0000 /* VMXNET3 Revision Report Selection */
|
|
#define VMXNET3_REG_UVRS 0x0008 /* UPT Version Report Selection */
|
|
#define VMXNET3_REG_DSAL 0x0010 /* Driver Shared Address Low */
|
|
#define VMXNET3_REG_DSAH 0x0018 /* Driver Shared Address High */
|
|
#define VMXNET3_REG_CMD 0x0020 /* Command */
|
|
#define VMXNET3_REG_MACL 0x0028 /* MAC Address Low */
|
|
#define VMXNET3_REG_MACH 0x0030 /* MAC Address High */
|
|
#define VMXNET3_REG_ICR 0x0038 /* Interrupt Cause Register */
|
|
#define VMXNET3_REG_ECR 0x0040 /* Event Cause Register */
|
|
|
|
#define VMXNET3_VLAN_LEN 4
|
|
#define VMXNET3_FCS_LEN 4
|
|
#define VMXNET3_MTU (1514 + VMXNET3_VLAN_LEN + VMXNET3_FCS_LEN)
|
|
|
|
#define VMXNET3_RXF_BTYPE (1 << 14) /* rx body buffer type */
|
|
#define VMXNET3_RXF_GEN (1 << 31) /* rx generation */
|
|
|
|
#define VMXNET3_RXCF_CKSUM_MASK (0xFFFF) /* rx checksum mask */
|
|
#define VMXNET3_RXCF_TUC (1 << 16) /* rx udp/tcp checksum correct */
|
|
#define VMXNET3_RXCF_UDP (1 << 17) /* rx udp packet */
|
|
#define VMXNET3_RXCF_TCP (1 << 18) /* rx tcp packet */
|
|
#define VMXNET3_RXCF_IPC (1 << 19) /* rx ip checksum correct */
|
|
#define VMXNET3_RXCF_IP6 (1 << 20) /* rx ip6 packet */
|
|
#define VMXNET3_RXCF_IP4 (1 << 21) /* rx ip4 packet */
|
|
#define VMXNET3_RXCF_CT (0x7F << 24) /* rx completion type 24-30, 7 bits */
|
|
#define VMXNET3_RXCF_GEN (1 << 31) /* rx completion generation */
|
|
|
|
#define VMXNET3_RXC_INDEX (0xFFF) /* rx completion index mask */
|
|
|
|
#define foreach_vmxnet3_offload \
|
|
_(0, NONE, "none") \
|
|
_(2, CSUM, "checksum") \
|
|
_(3, TSO, "tso")
|
|
|
|
enum
|
|
{
|
|
#define _(a, b, c) VMXNET3_OM_##b = (a),
|
|
foreach_vmxnet3_offload
|
|
#undef _
|
|
};
|
|
|
|
/* tx desc flag 0 */
|
|
#define VMXNET3_TXF_GEN (1 << 14) /* tx generation */
|
|
|
|
/* tx desc flag 1 */
|
|
#define VMXNET3_TXF_OM(x) ((x) << 10) /* tx offload mode */
|
|
#define VMXNET3_TXF_MSSCOF(x) ((x) << 18) /* tx MSS checksum offset, flags */
|
|
#define VMXNET3_TXF_EOP (1 << 12) /* tx end of packet */
|
|
#define VMXNET3_TXF_CQ (1 << 13) /* tx completion request */
|
|
|
|
/* tx completion flag */
|
|
#define VMXNET3_TXCF_GEN (1 << 31) /* tx completion generation */
|
|
#define VMXNET3_TXC_INDEX (0xFFF) /* tx completion index mask */
|
|
|
|
#define VMXNET3_RX_RING_SIZE 2
|
|
#define VMXNET3_INPUT_REFILL_THRESHOLD 32
|
|
#define VMXNET3_NUM_TX_DESC 1024
|
|
#define VMXNET3_NUM_TX_COMP VMXNET3_NUM_TX_DESC
|
|
#define VMXNET3_NUM_RX_DESC 1024
|
|
#define VMXNET3_NUM_RX_COMP VMXNET3_NUM_RX_DESC
|
|
|
|
#define VMXNET3_VERSION_MAGIC 0x69505845
|
|
#define VMXNET3_SHARED_MAGIC 0xbabefee1
|
|
#define VMXNET3_VERSION_SELECT 1
|
|
#define VMXNET3_UPT_VERSION_SELECT 1
|
|
#define VMXNET3_MAX_INTRS 25
|
|
#define VMXNET3_IC_DISABLE_ALL 0x1
|
|
|
|
#define VMXNET3_GOS_BITS_32 (1 << 0)
|
|
#define VMXNET3_GOS_BITS_64 (2 << 0)
|
|
#define VMXNET3_GOS_TYPE_LINUX (1 << 2)
|
|
#define VMXNET3_RXCL_LEN_MASK (0x3FFF) // 14 bits
|
|
#define VMXNET3_RXCL_ERROR (1 << 14)
|
|
|
|
#define VMXNET3_RXCI_EOP (1 << 14) /* end of packet */
|
|
#define VMXNET3_RXCI_SOP (1 << 15) /* start of packet */
|
|
#define VMXNET3_RXCI_CNC (1 << 30) /* Checksum not calculated */
|
|
|
|
#define VMXNET3_RXCOMP_TYPE (3 << 24) /* RX completion descriptor */
|
|
#define VMXNET3_RXCOMP_TYPE_LRO (4 << 24) /* RX completion descriptor for LRO */
|
|
|
|
#define VMXNET3_RXECF_MSS_MASK (0xFFFF) // 16 bits
|
|
|
|
#define foreach_vmxnet3_device_flags \
|
|
_(0, INITIALIZED, "initialized") \
|
|
_(1, ERROR, "error") \
|
|
_(2, ADMIN_UP, "admin-up") \
|
|
_(3, IOVA, "iova") \
|
|
_(4, LINK_UP, "link-up") \
|
|
_(5, SHARED_TXQ_LOCK, "shared-txq-lock") \
|
|
_(6, ELOG, "elog")
|
|
|
|
enum
|
|
{
|
|
#define _(a, b, c) VMXNET3_DEVICE_F_##b = (1 << a),
|
|
foreach_vmxnet3_device_flags
|
|
#undef _
|
|
};
|
|
|
|
#define foreach_vmxnet3_set_cmds \
|
|
_(0, ACTIVATE_DEV, "activate device") \
|
|
_(1, QUIESCE_DEV, "quiesce device") \
|
|
_(2, RESET_DEV, "reset device") \
|
|
_(3, UPDATE_RX_MODE, "update rx mode") \
|
|
_(4, UPDATE_MAC_FILTERS, "update mac filters") \
|
|
_(5, UPDATE_VLAN_FILTERS, "update vlan filters") \
|
|
_(6, UPDATE_RSSIDT, "update rss idt") \
|
|
_(7, UPDATE_IML, "update iml") \
|
|
_(8, UPDATE_PMCFG, "update pm cfg") \
|
|
_(9, UPDATE_FEATURE, "update feature") \
|
|
_(10, STOP_EMULATION, "stop emulation") \
|
|
_(11, LOAD_PLUGIN, "load plugin") \
|
|
_(12, ACTIVATE_VF, "activate vf") \
|
|
_(13, RESERVED3, "reserved 3") \
|
|
_(14, RESERVED4, "reservced 4") \
|
|
_(15, REGISTER_MEMREGS, "register mem regs")
|
|
|
|
enum
|
|
{
|
|
#define _(a, b, c) VMXNET3_CMD_##b = (a + 0xCAFE0000),
|
|
foreach_vmxnet3_set_cmds
|
|
#undef _
|
|
};
|
|
|
|
#define foreach_vmxnet3_get_cmds \
|
|
_(0, GET_QUEUE_STATUS, "get queue status") \
|
|
_(1, GET_STATS, "get stats") \
|
|
_(2, GET_LINK, "get link") \
|
|
_(3, GET_PERM_MAC_LO, "get perm mac lo") \
|
|
_(4, GET_PERM_MAC_HI, "get perm mac hi") \
|
|
_(5, GET_DID_LO, "get did lo") \
|
|
_(6, GET_DID_HI, "get did hi") \
|
|
_(7, GET_DEV_EXTRA_INFO, "get dev extra info") \
|
|
_(8, GET_CONF_INTR, "get conf intr") \
|
|
_(9, GET_ADAPTIVE_RING_INFO, "get adaptive ring info") \
|
|
_(10, GET_TXDATA_DESC_SIZE, "get txdata desc size") \
|
|
_(11, RESERVED5, "reserved5")
|
|
|
|
enum
|
|
{
|
|
#define _(a, b, c) VMXNET3_CMD_##b = (a + 0xF00D0000),
|
|
foreach_vmxnet3_get_cmds
|
|
#undef _
|
|
};
|
|
|
|
typedef CLIB_PACKED (struct
|
|
{
|
|
u32 version; u32 guest_info; u32 version_support;
|
|
u32 upt_version_support; u64 upt_features;
|
|
u64 driver_data_address; u64 queue_desc_address;
|
|
u32 driver_data_len; u32 queue_desc_len;
|
|
u32 mtu;
|
|
u16 max_num_rx_sg; u8 num_tx_queues; u8 num_rx_queues;
|
|
u32 pad[4];
|
|
}) vmxnet3_misc_config;
|
|
|
|
typedef CLIB_PACKED (struct
|
|
{
|
|
u8 mask_mode;
|
|
u8 num_intrs;
|
|
u8 event_intr_index;
|
|
u8 moderation_level[VMXNET3_MAX_INTRS]; u32 control;
|
|
u32 pad[2];
|
|
}) vmxnet3_interrupt_config;
|
|
|
|
typedef CLIB_PACKED (struct
|
|
{
|
|
u32 mode; u16 multicast_len; u16 pad;
|
|
u64 multicast_address; u8 vlan_filter[512];
|
|
}) vmxnet3_rx_filter_config;
|
|
|
|
typedef CLIB_PACKED (struct
|
|
{
|
|
u32 version; u32 length;
|
|
u64 address;
|
|
}) vmxnet3_variable_config;
|
|
|
|
typedef CLIB_PACKED (struct
|
|
{
|
|
u32 magic;
|
|
u32 pad;
|
|
vmxnet3_misc_config misc;
|
|
vmxnet3_interrupt_config interrupt;
|
|
vmxnet3_rx_filter_config rx_filter;
|
|
vmxnet3_variable_config rss;
|
|
vmxnet3_variable_config pattern;
|
|
vmxnet3_variable_config plugin; u32 ecr;
|
|
u32 pad1[5];
|
|
}) vmxnet3_shared;
|
|
|
|
typedef CLIB_PACKED (struct
|
|
{
|
|
u8 stopped;
|
|
u8 pad[3];
|
|
u32 error;
|
|
}) vmxnet3_queue_status;
|
|
|
|
typedef CLIB_PACKED (struct
|
|
{
|
|
u32 num_deferred; u32 threshold;
|
|
u64 pad;
|
|
}) vmxnet3_tx_queue_control;
|
|
|
|
typedef CLIB_PACKED (struct
|
|
{
|
|
u64 desc_address;
|
|
u64 data_address;
|
|
u64 comp_address; u64 driver_data_address; u64 pad;
|
|
u32 num_desc;
|
|
u32 num_data; u32 num_comp; u32 driver_data_len;
|
|
u8 intr_index;
|
|
u8 pad1; u16 data_address_size; u8 pad2[4];
|
|
}) vmxnet3_tx_queue_config;
|
|
|
|
typedef CLIB_PACKED (struct
|
|
{
|
|
u64 tso_pkts;
|
|
u64 tso_bytes;
|
|
u64 ucast_pkts; u64 ucast_bytes; u64 mcast_pkts;
|
|
u64 mcast_bytes;
|
|
u64 bcast_pkts; u64 bcast_bytes; u64 error_pkts;
|
|
u64 discard_pkts;
|
|
}) vmxnet3_tx_stats;
|
|
|
|
typedef CLIB_PACKED (struct
|
|
{
|
|
vmxnet3_tx_queue_control ctrl;
|
|
vmxnet3_tx_queue_config cfg;
|
|
vmxnet3_queue_status status; vmxnet3_tx_stats stats;
|
|
u8 pad[88];
|
|
}) vmxnet3_tx_queue;
|
|
|
|
typedef CLIB_PACKED (struct
|
|
{
|
|
u8 update_prod; u8 pad[7];
|
|
u64 pad1;
|
|
}) vmxnet3_rx_queue_control;
|
|
|
|
typedef CLIB_PACKED (struct
|
|
{
|
|
u64 desc_address[2];
|
|
u64 comp_address; u64 driver_data_address;
|
|
u64 data_address; u32 num_desc[2];
|
|
u32 num_comp;
|
|
u32 driver_data_len; u8 intr_index; u8 pad1;
|
|
u16 data_address_size; u8 pad2[4];
|
|
}) vmxnet3_rx_queue_config;
|
|
|
|
typedef CLIB_PACKED (struct
|
|
{
|
|
u64 lro_pkts;
|
|
u64 lro_bytes;
|
|
u64 ucast_pkts; u64 ucast_bytes; u64 mcast_pkts;
|
|
u64 mcast_bytes;
|
|
u64 bcast_pkts; u64 bcast_bytes; u64 nobuf_pkts;
|
|
u64 error_pkts;
|
|
}) vmxnet3_rx_stats;
|
|
|
|
typedef CLIB_PACKED (struct
|
|
{
|
|
vmxnet3_rx_queue_control ctrl;
|
|
vmxnet3_rx_queue_config cfg;
|
|
vmxnet3_queue_status status; vmxnet3_rx_stats stats;
|
|
u8 pad[88];
|
|
}) vmxnet3_rx_queue;
|
|
|
|
/*
|
|
* flags:
|
|
* buffer length -- bits 0-13
|
|
* buffer type -- bit 14
|
|
* descriptor type -- bit 15
|
|
* reserved -- bits 16-30
|
|
* generation -- bit 31
|
|
*/
|
|
typedef CLIB_PACKED (struct
|
|
{
|
|
u64 address;
|
|
u32 flags;
|
|
u32 pad;
|
|
}) vmxnet3_rx_desc;
|
|
|
|
/*
|
|
* index:
|
|
* RX desc index -- bits 0-11
|
|
* ext1 -- bits 12-13
|
|
* end of packet -- bit 14
|
|
* start of packet -- bit 15
|
|
* ring ID -- bits 16-25
|
|
* RSS hash type -- bits 26-29
|
|
* checksum not calculated -- bit 30
|
|
* ext2 -- bit 31
|
|
*
|
|
* rss: RSS hash value
|
|
*
|
|
* len:
|
|
* data length -- bits 0-13
|
|
* error -- bit 14
|
|
* tag is stripped -- bit 15
|
|
* tag stripped -- bits 16-31
|
|
*
|
|
* flags:
|
|
* checksum -- bits 0 - 15
|
|
* tcp/udp checksum correct-- bit 16
|
|
* udp packet -- bit 17
|
|
* tcp packet -- bit 18
|
|
* ip checksum correct -- bit 19
|
|
* ipv6 -- bit 20
|
|
* ipv4 -- bit 21
|
|
* ip fragment -- bit 22
|
|
* frame crc correct -- bit 23
|
|
* completion type -- bits 24-30
|
|
* generation -- bit 31
|
|
*/
|
|
typedef CLIB_PACKED (struct
|
|
{
|
|
u32 index; u32 rss;
|
|
u32 len;
|
|
u32 flags;
|
|
}) vmxnet3_rx_comp;
|
|
|
|
/*
|
|
* flags:
|
|
* mss -- bits 0 - 15
|
|
* tcp/udp checksum correct-- bit 16
|
|
* udp packet -- bit 17
|
|
* tcp packet -- bit 18
|
|
* ip checksum correct -- bit 19
|
|
* ipv6 -- bit 20
|
|
* ipv4 -- bit 21
|
|
* ip fragment -- bit 22
|
|
* frame crc correct -- bit 23
|
|
* completion type -- bits 24-30
|
|
* generation -- bit 31
|
|
*/
|
|
typedef CLIB_PACKED (struct
|
|
{
|
|
u32 dword1;
|
|
u8 seg_cnt; u8 dup_ack_cnt; u16 ts_delta; u32 dword2;
|
|
u32 flags;
|
|
}) vmxnet3_rx_comp_ext;
|
|
|
|
/*
|
|
* index:
|
|
* TX desc index -- bits 0-11
|
|
* ext1 -- bits 12-31
|
|
*
|
|
* flags:
|
|
* reserved -- bits 0-23
|
|
* completion type -- bits 24-30
|
|
* generation -- bit 31
|
|
*/
|
|
typedef CLIB_PACKED (struct
|
|
{
|
|
u32 index;
|
|
u32 pad[2];
|
|
u32 flags;
|
|
}) vmxnet3_tx_comp;
|
|
|
|
/*
|
|
* flags[0]:
|
|
* length -- bits 0-13
|
|
* generation -- bit 14
|
|
* reserved -- bit 15
|
|
* descriptor type -- bit 16
|
|
* ext1 -- bit 17
|
|
* MSS, checksum offset -- bits 18-31
|
|
* flags[1]:
|
|
* header length -- bits 0-9
|
|
* offload mode -- bits 10-11
|
|
* end of packet -- bit 12
|
|
* completion request -- bit 13
|
|
* ext2 -- bit 14
|
|
* vlan tag insertion -- bit 15
|
|
* tag to insert -- bits 16-31
|
|
*/
|
|
typedef CLIB_PACKED (struct
|
|
{
|
|
u64 address;
|
|
u32 flags[2];
|
|
}) vmxnet3_tx_desc;
|
|
|
|
typedef CLIB_PACKED (struct
|
|
{
|
|
u16 hash_type;
|
|
u16 hash_func;
|
|
u16 hash_key_sz;
|
|
u16 ind_table_sz;
|
|
u8 hash_key[VMXNET3_RSS_MAX_KEY_SZ];
|
|
u8 ind_table[VMXNET3_RSS_MAX_IND_TABLE_SZ];
|
|
}) vmxnet3_rss_shared;
|
|
|
|
typedef struct
|
|
{
|
|
CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
|
|
u32 *bufs;
|
|
u32 gen;
|
|
u16 fill;
|
|
u16 rid;
|
|
u16 produce;
|
|
u16 consume;
|
|
} vmxnet3_rx_ring;
|
|
|
|
typedef struct
|
|
{
|
|
CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
|
|
u32 gen;
|
|
u16 next;
|
|
} vmxnet3_rx_comp_ring;
|
|
|
|
typedef struct
|
|
{
|
|
CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
|
|
u32 polling_q_count;
|
|
} vmxnet3_per_thread_data_t;
|
|
|
|
typedef struct
|
|
{
|
|
CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
|
|
u16 size;
|
|
u32 mode;
|
|
u8 buffer_pool_index;
|
|
u32 queue_index;
|
|
u32 thread_index;
|
|
vmxnet3_rx_ring rx_ring[VMXNET3_RX_RING_SIZE];
|
|
vmxnet3_rx_desc *rx_desc[VMXNET3_RX_RING_SIZE];
|
|
vmxnet3_rx_comp *rx_comp;
|
|
vmxnet3_rx_comp_ring rx_comp_ring;
|
|
} vmxnet3_rxq_t;
|
|
|
|
typedef struct
|
|
{
|
|
CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
|
|
u32 *bufs;
|
|
u32 gen;
|
|
u16 produce;
|
|
u16 consume;
|
|
} vmxnet3_tx_ring;
|
|
|
|
typedef struct
|
|
{
|
|
CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
|
|
u32 gen;
|
|
u16 next;
|
|
} vmxnet3_tx_comp_ring;
|
|
|
|
typedef struct
|
|
{
|
|
CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
|
|
u16 size;
|
|
u32 queue_index;
|
|
u32 reg_txprod;
|
|
clib_spinlock_t lock;
|
|
|
|
vmxnet3_tx_desc *tx_desc;
|
|
vmxnet3_tx_comp *tx_comp;
|
|
vmxnet3_tx_ring tx_ring;
|
|
vmxnet3_tx_comp_ring tx_comp_ring;
|
|
} vmxnet3_txq_t;
|
|
|
|
typedef struct
|
|
{
|
|
CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
|
|
u32 flags;
|
|
u32 per_interface_next_index;
|
|
|
|
u32 dev_instance;
|
|
u32 sw_if_index;
|
|
u32 hw_if_index;
|
|
u32 numa_node;
|
|
vlib_pci_dev_handle_t pci_dev_handle;
|
|
vlib_pci_addr_t pci_addr;
|
|
void *bar[2];
|
|
|
|
/* queues */
|
|
vmxnet3_rxq_t *rxqs;
|
|
vmxnet3_txq_t *txqs;
|
|
|
|
u16 num_tx_queues;
|
|
u16 num_rx_queues;
|
|
u16 num_intrs;
|
|
|
|
u8 version;
|
|
u8 mac_addr[6];
|
|
|
|
clib_error_t *error;
|
|
|
|
vmxnet3_shared *driver_shared;
|
|
void *queues;
|
|
vmxnet3_rss_shared *rss;
|
|
u32 link_speed;
|
|
u8 gso_enable;
|
|
vmxnet3_tx_stats *tx_stats;
|
|
vmxnet3_rx_stats *rx_stats;
|
|
} vmxnet3_device_t;
|
|
|
|
typedef struct
|
|
{
|
|
vmxnet3_device_t *devices;
|
|
u16 msg_id_base;
|
|
vlib_log_class_t log_default;
|
|
vmxnet3_per_thread_data_t *per_thread_data;
|
|
} vmxnet3_main_t;
|
|
|
|
extern vmxnet3_main_t vmxnet3_main;
|
|
|
|
typedef enum
|
|
{
|
|
VMXNET3_BIND_NONE = 0,
|
|
VMXNET3_BIND_DEFAULT = 1,
|
|
VMXNET3_BIND_FORCE = 2,
|
|
} __clib_packed vmxnet3_bind_t;
|
|
|
|
typedef struct
|
|
{
|
|
vlib_pci_addr_t addr;
|
|
u32 enable_elog;
|
|
u16 rxq_size;
|
|
u16 rxq_num;
|
|
u16 txq_size;
|
|
u16 txq_num;
|
|
vmxnet3_bind_t bind;
|
|
u8 enable_gso;
|
|
/* return */
|
|
i32 rv;
|
|
u32 sw_if_index;
|
|
clib_error_t *error;
|
|
} vmxnet3_create_if_args_t;
|
|
|
|
typedef struct
|
|
{
|
|
u32 next_index;
|
|
u32 hw_if_index;
|
|
vlib_buffer_t buffer;
|
|
} vmxnet3_input_trace_t;
|
|
|
|
void vmxnet3_create_if (vlib_main_t * vm, vmxnet3_create_if_args_t * args);
|
|
void vmxnet3_delete_if (vlib_main_t * vm, vmxnet3_device_t * ad);
|
|
|
|
extern clib_error_t *vmxnet3_plugin_api_hookup (vlib_main_t * vm);
|
|
extern vlib_node_registration_t vmxnet3_input_node;
|
|
extern vnet_device_class_t vmxnet3_device_class;
|
|
|
|
/* format.c */
|
|
format_function_t format_vmxnet3_device;
|
|
format_function_t format_vmxnet3_device_name;
|
|
format_function_t format_vmxnet3_input_trace;
|
|
|
|
#define vmxnet3_log_debug(dev, f, ...) \
|
|
vlib_log (VLIB_LOG_LEVEL_DEBUG, vmxnet3_main.log_default, "%U: " f, \
|
|
format_vlib_pci_addr, &dev->pci_addr, \
|
|
## __VA_ARGS__)
|
|
|
|
#define vmxnet3_log_error(dev, f, ...) \
|
|
vlib_log (VLIB_LOG_LEVEL_ERR, vmxnet3_main.log_default, "%U: " f, \
|
|
format_vlib_pci_addr, &dev->pci_addr, \
|
|
## __VA_ARGS__)
|
|
|
|
/* no log version, called by data plane */
|
|
static_always_inline void
|
|
vmxnet3_reg_write_inline (vmxnet3_device_t * vd, u8 bar, u32 addr, u32 val)
|
|
{
|
|
*(volatile u32 *) ((u8 *) vd->bar[bar] + addr) = val;
|
|
}
|
|
|
|
static_always_inline void
|
|
vmxnet3_reg_write (vmxnet3_device_t * vd, u8 bar, u32 addr, u32 val)
|
|
{
|
|
vmxnet3_log_debug (vd, "reg wr bar %u addr 0x%x val 0x%x", bar, addr, val);
|
|
vmxnet3_reg_write_inline (vd, bar, addr, val);
|
|
}
|
|
|
|
static_always_inline u32
|
|
vmxnet3_reg_read (vmxnet3_device_t * vd, u8 bar, u32 addr)
|
|
{
|
|
u32 val;
|
|
|
|
val = *(volatile u32 *) (vd->bar[bar] + addr);
|
|
vmxnet3_log_debug (vd, "reg rd bar %u addr 0x%x val 0x%x", bar, addr, val);
|
|
|
|
return val;
|
|
}
|
|
|
|
static_always_inline uword
|
|
vmxnet3_dma_addr (vlib_main_t * vm, vmxnet3_device_t * vd, void *p)
|
|
{
|
|
return (vd->flags & VMXNET3_DEVICE_F_IOVA) ? pointer_to_uword (p) :
|
|
vlib_physmem_get_pa (vm, p);
|
|
}
|
|
|
|
static_always_inline void
|
|
vmxnet3_rx_ring_advance_produce (vmxnet3_rxq_t * rxq, vmxnet3_rx_ring * ring)
|
|
{
|
|
ring->produce++;
|
|
if (PREDICT_FALSE (ring->produce == rxq->size))
|
|
{
|
|
ring->produce = 0;
|
|
ring->gen ^= VMXNET3_RXF_GEN;
|
|
}
|
|
}
|
|
|
|
static_always_inline clib_error_t *
|
|
vmxnet3_rxq_refill_ring0 (vlib_main_t * vm, vmxnet3_device_t * vd,
|
|
vmxnet3_rxq_t * rxq)
|
|
{
|
|
vmxnet3_rx_desc *rxd;
|
|
u16 n_refill, n_alloc;
|
|
vmxnet3_rx_ring *ring;
|
|
vmxnet3_rx_queue *rx;
|
|
|
|
ring = &rxq->rx_ring[0];
|
|
n_refill = rxq->size - ring->fill;
|
|
|
|
if (PREDICT_TRUE (n_refill <= VMXNET3_INPUT_REFILL_THRESHOLD))
|
|
return 0;
|
|
|
|
n_alloc =
|
|
vlib_buffer_alloc_to_ring_from_pool (vm, ring->bufs, ring->produce,
|
|
rxq->size, n_refill,
|
|
rxq->buffer_pool_index);
|
|
if (PREDICT_FALSE (n_alloc != n_refill))
|
|
{
|
|
if (n_alloc)
|
|
vlib_buffer_free_from_ring (vm, ring->bufs, ring->produce, rxq->size,
|
|
n_alloc);
|
|
return clib_error_return (0, "buffer alloc failed");
|
|
}
|
|
|
|
while (n_alloc)
|
|
{
|
|
vlib_buffer_t *b = vlib_get_buffer (vm, ring->bufs[ring->produce]);
|
|
rxd = &rxq->rx_desc[0][ring->produce];
|
|
rxd->address = vlib_buffer_get_pa (vm, b);
|
|
rxd->flags = ring->gen | vlib_buffer_get_default_data_size (vm);
|
|
|
|
vmxnet3_rx_ring_advance_produce (rxq, ring);
|
|
ring->fill++;
|
|
n_alloc--;
|
|
}
|
|
|
|
rx = VMXNET3_RX_START (vd);
|
|
if (PREDICT_FALSE (rx->ctrl.update_prod))
|
|
vmxnet3_reg_write_inline (vd, 0, VMXNET3_REG_RXPROD, ring->produce);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static_always_inline clib_error_t *
|
|
vmxnet3_rxq_refill_ring1 (vlib_main_t * vm, vmxnet3_device_t * vd,
|
|
vmxnet3_rxq_t * rxq)
|
|
{
|
|
vmxnet3_rx_desc *rxd;
|
|
u16 n_refill, n_alloc;
|
|
vmxnet3_rx_ring *ring;
|
|
vmxnet3_rx_queue *rx;
|
|
|
|
ring = &rxq->rx_ring[1];
|
|
n_refill = rxq->size - ring->fill;
|
|
|
|
if (PREDICT_TRUE (n_refill <= VMXNET3_INPUT_REFILL_THRESHOLD))
|
|
return 0;
|
|
|
|
n_alloc =
|
|
vlib_buffer_alloc_to_ring_from_pool (vm, ring->bufs, ring->produce,
|
|
rxq->size, n_refill,
|
|
rxq->buffer_pool_index);
|
|
if (PREDICT_FALSE (n_alloc != n_refill))
|
|
{
|
|
if (n_alloc)
|
|
vlib_buffer_free_from_ring (vm, ring->bufs, ring->produce, rxq->size,
|
|
n_alloc);
|
|
return clib_error_return (0, "buffer alloc failed");
|
|
}
|
|
|
|
while (n_alloc)
|
|
{
|
|
vlib_buffer_t *b = vlib_get_buffer (vm, ring->bufs[ring->produce]);
|
|
rxd = &rxq->rx_desc[1][ring->produce];
|
|
rxd->address = vlib_buffer_get_pa (vm, b);
|
|
rxd->flags = ring->gen | vlib_buffer_get_default_data_size (vm) |
|
|
VMXNET3_RXF_BTYPE;
|
|
|
|
vmxnet3_rx_ring_advance_produce (rxq, ring);
|
|
ring->fill++;
|
|
n_alloc--;
|
|
}
|
|
|
|
rx = VMXNET3_RX_START (vd);
|
|
if (PREDICT_FALSE (rx->ctrl.update_prod))
|
|
vmxnet3_reg_write_inline (vd, 0, VMXNET3_REG_RXPROD2, ring->produce);
|
|
|
|
return 0;
|
|
}
|
|
|
|
#endif /* __included_vmnet_vmnet_h__ */
|
|
/*
|
|
* fd.io coding-style-patch-verification: ON
|
|
*
|
|
* Local Variables:
|
|
* eval: (c-set-style "gnu")
|
|
* End:
|
|
*/
|