Commit 23044d77 authored by David S. Miller's avatar David S. Miller

Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue

Tony Nguyen says:

====================
40GbE Intel Wired LAN Driver Updates 2021-12-17

Brett Creeley says:

This patch series adds support in the iavf driver for communicating and
using VIRTCHNL_VF_OFFLOAD_VLAN_V2. The current VIRTCHNL_VF_OFFLOAD_VLAN
is very limited and covers all 802.1Q VLAN offloads and filtering with
no granularity.

The new VIRTCHNL_VF_OFFLOAD_VLAN_V2 adds more granularity, flexibility,
and support for 802.1ad offloads and filtering. This includes the VF
negotiating which VLAN offloads/filtering it's allowed, where VLAN tags
should be inserted and/or stripped into and from descriptors, and the
supported VLAN protocols.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 7e1c5d7b 92fc5085
......@@ -55,7 +55,8 @@ enum iavf_vsi_state_t {
struct iavf_vsi {
struct iavf_adapter *back;
struct net_device *netdev;
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
unsigned long active_cvlans[BITS_TO_LONGS(VLAN_N_VID)];
unsigned long active_svlans[BITS_TO_LONGS(VLAN_N_VID)];
u16 seid;
u16 id;
DECLARE_BITMAP(state, __IAVF_VSI_STATE_SIZE__);
......@@ -146,9 +147,15 @@ struct iavf_mac_filter {
};
};
#define IAVF_VLAN(vid, tpid) ((struct iavf_vlan){ vid, tpid })
struct iavf_vlan {
u16 vid;
u16 tpid;
};
struct iavf_vlan_filter {
struct list_head list;
u16 vlan;
struct iavf_vlan vlan;
bool remove; /* filter needs to be removed */
bool add; /* filter needs to be added */
};
......@@ -181,6 +188,8 @@ enum iavf_state_t {
__IAVF_REMOVE, /* driver is being unloaded */
__IAVF_INIT_VERSION_CHECK, /* aq msg sent, awaiting reply */
__IAVF_INIT_GET_RESOURCES, /* aq msg sent, awaiting reply */
__IAVF_INIT_GET_OFFLOAD_VLAN_V2_CAPS,
__IAVF_INIT_CONFIG_ADAPTER,
__IAVF_INIT_SW, /* got resources, setting up structs */
__IAVF_INIT_FAILED, /* init failed, restarting procedure */
__IAVF_RESETTING, /* in reset */
......@@ -278,38 +287,47 @@ struct iavf_adapter {
/* duplicates for common code */
#define IAVF_FLAG_DCB_ENABLED 0
/* flags for admin queue service task */
u32 aq_required;
#define IAVF_FLAG_AQ_ENABLE_QUEUES BIT(0)
#define IAVF_FLAG_AQ_DISABLE_QUEUES BIT(1)
#define IAVF_FLAG_AQ_ADD_MAC_FILTER BIT(2)
#define IAVF_FLAG_AQ_ADD_VLAN_FILTER BIT(3)
#define IAVF_FLAG_AQ_DEL_MAC_FILTER BIT(4)
#define IAVF_FLAG_AQ_DEL_VLAN_FILTER BIT(5)
#define IAVF_FLAG_AQ_CONFIGURE_QUEUES BIT(6)
#define IAVF_FLAG_AQ_MAP_VECTORS BIT(7)
#define IAVF_FLAG_AQ_HANDLE_RESET BIT(8)
#define IAVF_FLAG_AQ_CONFIGURE_RSS BIT(9) /* direct AQ config */
#define IAVF_FLAG_AQ_GET_CONFIG BIT(10)
u64 aq_required;
#define IAVF_FLAG_AQ_ENABLE_QUEUES BIT_ULL(0)
#define IAVF_FLAG_AQ_DISABLE_QUEUES BIT_ULL(1)
#define IAVF_FLAG_AQ_ADD_MAC_FILTER BIT_ULL(2)
#define IAVF_FLAG_AQ_ADD_VLAN_FILTER BIT_ULL(3)
#define IAVF_FLAG_AQ_DEL_MAC_FILTER BIT_ULL(4)
#define IAVF_FLAG_AQ_DEL_VLAN_FILTER BIT_ULL(5)
#define IAVF_FLAG_AQ_CONFIGURE_QUEUES BIT_ULL(6)
#define IAVF_FLAG_AQ_MAP_VECTORS BIT_ULL(7)
#define IAVF_FLAG_AQ_HANDLE_RESET BIT_ULL(8)
#define IAVF_FLAG_AQ_CONFIGURE_RSS BIT_ULL(9) /* direct AQ config */
#define IAVF_FLAG_AQ_GET_CONFIG BIT_ULL(10)
/* Newer style, RSS done by the PF so we can ignore hardware vagaries. */
#define IAVF_FLAG_AQ_GET_HENA BIT(11)
#define IAVF_FLAG_AQ_SET_HENA BIT(12)
#define IAVF_FLAG_AQ_SET_RSS_KEY BIT(13)
#define IAVF_FLAG_AQ_SET_RSS_LUT BIT(14)
#define IAVF_FLAG_AQ_REQUEST_PROMISC BIT(15)
#define IAVF_FLAG_AQ_RELEASE_PROMISC BIT(16)
#define IAVF_FLAG_AQ_REQUEST_ALLMULTI BIT(17)
#define IAVF_FLAG_AQ_RELEASE_ALLMULTI BIT(18)
#define IAVF_FLAG_AQ_ENABLE_VLAN_STRIPPING BIT(19)
#define IAVF_FLAG_AQ_DISABLE_VLAN_STRIPPING BIT(20)
#define IAVF_FLAG_AQ_ENABLE_CHANNELS BIT(21)
#define IAVF_FLAG_AQ_DISABLE_CHANNELS BIT(22)
#define IAVF_FLAG_AQ_ADD_CLOUD_FILTER BIT(23)
#define IAVF_FLAG_AQ_DEL_CLOUD_FILTER BIT(24)
#define IAVF_FLAG_AQ_ADD_FDIR_FILTER BIT(25)
#define IAVF_FLAG_AQ_DEL_FDIR_FILTER BIT(26)
#define IAVF_FLAG_AQ_ADD_ADV_RSS_CFG BIT(27)
#define IAVF_FLAG_AQ_DEL_ADV_RSS_CFG BIT(28)
#define IAVF_FLAG_AQ_REQUEST_STATS BIT(29)
#define IAVF_FLAG_AQ_GET_HENA BIT_ULL(11)
#define IAVF_FLAG_AQ_SET_HENA BIT_ULL(12)
#define IAVF_FLAG_AQ_SET_RSS_KEY BIT_ULL(13)
#define IAVF_FLAG_AQ_SET_RSS_LUT BIT_ULL(14)
#define IAVF_FLAG_AQ_REQUEST_PROMISC BIT_ULL(15)
#define IAVF_FLAG_AQ_RELEASE_PROMISC BIT_ULL(16)
#define IAVF_FLAG_AQ_REQUEST_ALLMULTI BIT_ULL(17)
#define IAVF_FLAG_AQ_RELEASE_ALLMULTI BIT_ULL(18)
#define IAVF_FLAG_AQ_ENABLE_VLAN_STRIPPING BIT_ULL(19)
#define IAVF_FLAG_AQ_DISABLE_VLAN_STRIPPING BIT_ULL(20)
#define IAVF_FLAG_AQ_ENABLE_CHANNELS BIT_ULL(21)
#define IAVF_FLAG_AQ_DISABLE_CHANNELS BIT_ULL(22)
#define IAVF_FLAG_AQ_ADD_CLOUD_FILTER BIT_ULL(23)
#define IAVF_FLAG_AQ_DEL_CLOUD_FILTER BIT_ULL(24)
#define IAVF_FLAG_AQ_ADD_FDIR_FILTER BIT_ULL(25)
#define IAVF_FLAG_AQ_DEL_FDIR_FILTER BIT_ULL(26)
#define IAVF_FLAG_AQ_ADD_ADV_RSS_CFG BIT_ULL(27)
#define IAVF_FLAG_AQ_DEL_ADV_RSS_CFG BIT_ULL(28)
#define IAVF_FLAG_AQ_REQUEST_STATS BIT_ULL(29)
#define IAVF_FLAG_AQ_GET_OFFLOAD_VLAN_V2_CAPS BIT_ULL(30)
#define IAVF_FLAG_AQ_ENABLE_CTAG_VLAN_STRIPPING BIT_ULL(31)
#define IAVF_FLAG_AQ_DISABLE_CTAG_VLAN_STRIPPING BIT_ULL(32)
#define IAVF_FLAG_AQ_ENABLE_STAG_VLAN_STRIPPING BIT_ULL(33)
#define IAVF_FLAG_AQ_DISABLE_STAG_VLAN_STRIPPING BIT_ULL(34)
#define IAVF_FLAG_AQ_ENABLE_CTAG_VLAN_INSERTION BIT_ULL(35)
#define IAVF_FLAG_AQ_DISABLE_CTAG_VLAN_INSERTION BIT_ULL(36)
#define IAVF_FLAG_AQ_ENABLE_STAG_VLAN_INSERTION BIT_ULL(37)
#define IAVF_FLAG_AQ_DISABLE_STAG_VLAN_INSERTION BIT_ULL(38)
/* OS defined structs */
struct net_device *netdev;
......@@ -349,6 +367,14 @@ struct iavf_adapter {
VIRTCHNL_VF_OFFLOAD_RSS_PF)))
#define VLAN_ALLOWED(_a) ((_a)->vf_res->vf_cap_flags & \
VIRTCHNL_VF_OFFLOAD_VLAN)
#define VLAN_V2_ALLOWED(_a) ((_a)->vf_res->vf_cap_flags & \
VIRTCHNL_VF_OFFLOAD_VLAN_V2)
#define VLAN_V2_FILTERING_ALLOWED(_a) \
(VLAN_V2_ALLOWED((_a)) && \
((_a)->vlan_v2_caps.filtering.filtering_support.outer || \
(_a)->vlan_v2_caps.filtering.filtering_support.inner))
#define VLAN_FILTERING_ALLOWED(_a) \
(VLAN_ALLOWED((_a)) || VLAN_V2_FILTERING_ALLOWED((_a)))
#define ADV_LINK_SUPPORT(_a) ((_a)->vf_res->vf_cap_flags & \
VIRTCHNL_VF_CAP_ADV_LINK_SPEED)
#define FDIR_FLTR_SUPPORT(_a) ((_a)->vf_res->vf_cap_flags & \
......@@ -360,6 +386,7 @@ struct iavf_adapter {
struct virtchnl_version_info pf_version;
#define PF_IS_V11(_a) (((_a)->pf_version.major == 1) && \
((_a)->pf_version.minor == 1))
struct virtchnl_vlan_caps vlan_v2_caps;
u16 msg_enable;
struct iavf_eth_stats current_stats;
struct iavf_vsi vsi;
......@@ -448,6 +475,7 @@ static inline void iavf_change_state(struct iavf_adapter *adapter,
int iavf_up(struct iavf_adapter *adapter);
void iavf_down(struct iavf_adapter *adapter);
int iavf_process_config(struct iavf_adapter *adapter);
int iavf_parse_vf_resource_msg(struct iavf_adapter *adapter);
void iavf_schedule_reset(struct iavf_adapter *adapter);
void iavf_schedule_request_stats(struct iavf_adapter *adapter);
void iavf_reset(struct iavf_adapter *adapter);
......@@ -466,6 +494,9 @@ int iavf_send_api_ver(struct iavf_adapter *adapter);
int iavf_verify_api_ver(struct iavf_adapter *adapter);
int iavf_send_vf_config_msg(struct iavf_adapter *adapter);
int iavf_get_vf_config(struct iavf_adapter *adapter);
int iavf_get_vf_vlan_v2_caps(struct iavf_adapter *adapter);
int iavf_send_vf_offload_vlan_v2_msg(struct iavf_adapter *adapter);
void iavf_set_queue_vlan_tag_loc(struct iavf_adapter *adapter);
void iavf_irq_enable(struct iavf_adapter *adapter, bool flush);
void iavf_configure_queues(struct iavf_adapter *adapter);
void iavf_deconfigure_queues(struct iavf_adapter *adapter);
......@@ -501,6 +532,14 @@ void iavf_enable_channels(struct iavf_adapter *adapter);
void iavf_disable_channels(struct iavf_adapter *adapter);
void iavf_add_cloud_filter(struct iavf_adapter *adapter);
void iavf_del_cloud_filter(struct iavf_adapter *adapter);
void iavf_enable_vlan_stripping_v2(struct iavf_adapter *adapter, u16 tpid);
void iavf_disable_vlan_stripping_v2(struct iavf_adapter *adapter, u16 tpid);
void iavf_enable_vlan_insertion_v2(struct iavf_adapter *adapter, u16 tpid);
void iavf_disable_vlan_insertion_v2(struct iavf_adapter *adapter, u16 tpid);
void
iavf_set_vlan_offload_features(struct iavf_adapter *adapter,
netdev_features_t prev_features,
netdev_features_t features);
void iavf_add_fdir_filter(struct iavf_adapter *adapter);
void iavf_del_fdir_filter(struct iavf_adapter *adapter);
void iavf_add_adv_rss_cfg(struct iavf_adapter *adapter);
......
This diff is collapsed.
......@@ -865,6 +865,9 @@ static void iavf_receive_skb(struct iavf_ring *rx_ring,
if ((rx_ring->netdev->features & NETIF_F_HW_VLAN_CTAG_RX) &&
(vlan_tag & VLAN_VID_MASK))
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_tag);
else if ((rx_ring->netdev->features & NETIF_F_HW_VLAN_STAG_RX) &&
vlan_tag & VLAN_VID_MASK)
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021AD), vlan_tag);
napi_gro_receive(&q_vector->napi, skb);
}
......@@ -1468,7 +1471,7 @@ static int iavf_clean_rx_irq(struct iavf_ring *rx_ring, int budget)
struct iavf_rx_buffer *rx_buffer;
union iavf_rx_desc *rx_desc;
unsigned int size;
u16 vlan_tag;
u16 vlan_tag = 0;
u8 rx_ptype;
u64 qword;
......@@ -1551,9 +1554,13 @@ static int iavf_clean_rx_irq(struct iavf_ring *rx_ring, int budget)
/* populate checksum, VLAN, and protocol */
iavf_process_skb_fields(rx_ring, rx_desc, skb, rx_ptype);
vlan_tag = (qword & BIT(IAVF_RX_DESC_STATUS_L2TAG1P_SHIFT)) ?
le16_to_cpu(rx_desc->wb.qword0.lo_dword.l2tag1) : 0;
if (qword & BIT(IAVF_RX_DESC_STATUS_L2TAG1P_SHIFT) &&
rx_ring->flags & IAVF_TXRX_FLAGS_VLAN_TAG_LOC_L2TAG1)
vlan_tag = le16_to_cpu(rx_desc->wb.qword0.lo_dword.l2tag1);
if (rx_desc->wb.qword2.ext_status &
cpu_to_le16(BIT(IAVF_RX_DESC_EXT_STATUS_L2TAG2P_SHIFT)) &&
rx_ring->flags & IAVF_RXR_FLAGS_VLAN_TAG_LOC_L2TAG2_2)
vlan_tag = le16_to_cpu(rx_desc->wb.qword2.l2tag2_2);
iavf_trace(clean_rx_irq_rx, rx_ring, rx_desc, skb);
iavf_receive_skb(rx_ring, skb, vlan_tag);
......@@ -1781,46 +1788,29 @@ int iavf_napi_poll(struct napi_struct *napi, int budget)
* Returns error code indicate the frame should be dropped upon error and the
* otherwise returns 0 to indicate the flags has been set properly.
**/
static inline int iavf_tx_prepare_vlan_flags(struct sk_buff *skb,
struct iavf_ring *tx_ring,
u32 *flags)
static void iavf_tx_prepare_vlan_flags(struct sk_buff *skb,
struct iavf_ring *tx_ring, u32 *flags)
{
__be16 protocol = skb->protocol;
u32 tx_flags = 0;
if (protocol == htons(ETH_P_8021Q) &&
!(tx_ring->netdev->features & NETIF_F_HW_VLAN_CTAG_TX)) {
/* When HW VLAN acceleration is turned off by the user the
* stack sets the protocol to 8021q so that the driver
* can take any steps required to support the SW only
* VLAN handling. In our case the driver doesn't need
* to take any further steps so just set the protocol
* to the encapsulated ethertype.
*/
skb->protocol = vlan_get_protocol(skb);
goto out;
}
/* if we have a HW VLAN tag being added, default to the HW one */
if (skb_vlan_tag_present(skb)) {
tx_flags |= skb_vlan_tag_get(skb) << IAVF_TX_FLAGS_VLAN_SHIFT;
tx_flags |= IAVF_TX_FLAGS_HW_VLAN;
/* else if it is a SW VLAN, check the next protocol and store the tag */
} else if (protocol == htons(ETH_P_8021Q)) {
struct vlan_hdr *vhdr, _vhdr;
vhdr = skb_header_pointer(skb, ETH_HLEN, sizeof(_vhdr), &_vhdr);
if (!vhdr)
return -EINVAL;
/* stack will only request hardware VLAN insertion offload for protocols
* that the driver supports and has enabled
*/
if (!skb_vlan_tag_present(skb))
return;
protocol = vhdr->h_vlan_encapsulated_proto;
tx_flags |= ntohs(vhdr->h_vlan_TCI) << IAVF_TX_FLAGS_VLAN_SHIFT;
tx_flags |= IAVF_TX_FLAGS_SW_VLAN;
tx_flags |= skb_vlan_tag_get(skb) << IAVF_TX_FLAGS_VLAN_SHIFT;
if (tx_ring->flags & IAVF_TXR_FLAGS_VLAN_TAG_LOC_L2TAG2) {
tx_flags |= IAVF_TX_FLAGS_HW_OUTER_SINGLE_VLAN;
} else if (tx_ring->flags & IAVF_TXRX_FLAGS_VLAN_TAG_LOC_L2TAG1) {
tx_flags |= IAVF_TX_FLAGS_HW_VLAN;
} else {
dev_dbg(tx_ring->dev, "Unsupported Tx VLAN tag location requested\n");
return;
}
out:
*flags = tx_flags;
return 0;
}
/**
......@@ -2440,8 +2430,13 @@ static netdev_tx_t iavf_xmit_frame_ring(struct sk_buff *skb,
first->gso_segs = 1;
/* prepare the xmit flags */
if (iavf_tx_prepare_vlan_flags(skb, tx_ring, &tx_flags))
goto out_drop;
iavf_tx_prepare_vlan_flags(skb, tx_ring, &tx_flags);
if (tx_flags & IAVF_TX_FLAGS_HW_OUTER_SINGLE_VLAN) {
cd_type_cmd_tso_mss |= IAVF_TX_CTX_DESC_IL2TAG2 <<
IAVF_TXD_CTX_QW1_CMD_SHIFT;
cd_l2tag2 = (tx_flags & IAVF_TX_FLAGS_VLAN_MASK) >>
IAVF_TX_FLAGS_VLAN_SHIFT;
}
/* obtain protocol of skb */
protocol = vlan_get_protocol(skb);
......
......@@ -243,19 +243,20 @@ static inline unsigned int iavf_txd_use_count(unsigned int size)
#define DESC_NEEDED (MAX_SKB_FRAGS + 6)
#define IAVF_MIN_DESC_PENDING 4
#define IAVF_TX_FLAGS_HW_VLAN BIT(1)
#define IAVF_TX_FLAGS_SW_VLAN BIT(2)
#define IAVF_TX_FLAGS_TSO BIT(3)
#define IAVF_TX_FLAGS_IPV4 BIT(4)
#define IAVF_TX_FLAGS_IPV6 BIT(5)
#define IAVF_TX_FLAGS_FCCRC BIT(6)
#define IAVF_TX_FLAGS_FSO BIT(7)
#define IAVF_TX_FLAGS_FD_SB BIT(9)
#define IAVF_TX_FLAGS_VXLAN_TUNNEL BIT(10)
#define IAVF_TX_FLAGS_VLAN_MASK 0xffff0000
#define IAVF_TX_FLAGS_VLAN_PRIO_MASK 0xe0000000
#define IAVF_TX_FLAGS_VLAN_PRIO_SHIFT 29
#define IAVF_TX_FLAGS_VLAN_SHIFT 16
#define IAVF_TX_FLAGS_HW_VLAN BIT(1)
#define IAVF_TX_FLAGS_SW_VLAN BIT(2)
#define IAVF_TX_FLAGS_TSO BIT(3)
#define IAVF_TX_FLAGS_IPV4 BIT(4)
#define IAVF_TX_FLAGS_IPV6 BIT(5)
#define IAVF_TX_FLAGS_FCCRC BIT(6)
#define IAVF_TX_FLAGS_FSO BIT(7)
#define IAVF_TX_FLAGS_FD_SB BIT(9)
#define IAVF_TX_FLAGS_VXLAN_TUNNEL BIT(10)
#define IAVF_TX_FLAGS_HW_OUTER_SINGLE_VLAN BIT(11)
#define IAVF_TX_FLAGS_VLAN_MASK 0xffff0000
#define IAVF_TX_FLAGS_VLAN_PRIO_MASK 0xe0000000
#define IAVF_TX_FLAGS_VLAN_PRIO_SHIFT 29
#define IAVF_TX_FLAGS_VLAN_SHIFT 16
struct iavf_tx_buffer {
struct iavf_tx_desc *next_to_watch;
......@@ -362,6 +363,9 @@ struct iavf_ring {
u16 flags;
#define IAVF_TXR_FLAGS_WB_ON_ITR BIT(0)
#define IAVF_RXR_FLAGS_BUILD_SKB_ENABLED BIT(1)
#define IAVF_TXRX_FLAGS_VLAN_TAG_LOC_L2TAG1 BIT(3)
#define IAVF_TXR_FLAGS_VLAN_TAG_LOC_L2TAG2 BIT(4)
#define IAVF_RXR_FLAGS_VLAN_TAG_LOC_L2TAG2_2 BIT(5)
/* stats structs */
struct iavf_queue_stats stats;
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment