Skip to content

Commit

Permalink
iavf: Add support for VIRTCHNL_VF_OFFLOAD_VLAN_V2 offload enable/disable
Browse files Browse the repository at this point in the history
The new VIRTCHNL_VF_OFFLOAD_VLAN_V2 capability added support that allows
the VF to support 802.1Q and 802.1ad VLAN insertion and stripping if
successfully negotiated via VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS.
Multiple changes were needed to support this new functionality.

1. Added new aq_required flags to support any kind of VLAN stripping and
   insertion offload requests via virtchnl.

2. Added the new method iavf_set_vlan_offload_features() that's
   used during VF initialization, VF reset, and iavf_set_features() to
   set the aq_required bits based on the current VLAN offload
   configuration of the VF's netdev.

3. Added virtchnl handling for VIRTCHNL_OP_ENABLE_STRIPPING_V2,
   VIRTCHNL_OP_DISABLE_STRIPPING_V2, VIRTCHNL_OP_ENABLE_INSERTION_V2,
   and VIRTCHNL_OP_ENABLE_INSERTION_V2.

Signed-off-by: Brett Creeley <brett.creeley@intel.com>
Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
  • Loading branch information
Brett Creeley authored and Tony Nguyen committed Dec 17, 2021
1 parent ccd219d commit 8afadd1
Show file tree
Hide file tree
Showing 3 changed files with 383 additions and 51 deletions.
80 changes: 48 additions & 32 deletions drivers/net/ethernet/intel/iavf/iavf.h
Original file line number Diff line number Diff line change
Expand Up @@ -287,39 +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_OFFLOAD_VLAN_V2_CAPS BIT(30)
#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;
Expand Down Expand Up @@ -524,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);
Expand Down
151 changes: 132 additions & 19 deletions drivers/net/ethernet/intel/iavf/iavf_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1815,6 +1815,39 @@ static int iavf_process_aq_command(struct iavf_adapter *adapter)
iavf_del_adv_rss_cfg(adapter);
return 0;
}
if (adapter->aq_required & IAVF_FLAG_AQ_DISABLE_CTAG_VLAN_STRIPPING) {
iavf_disable_vlan_stripping_v2(adapter, ETH_P_8021Q);
return 0;
}
if (adapter->aq_required & IAVF_FLAG_AQ_DISABLE_STAG_VLAN_STRIPPING) {
iavf_disable_vlan_stripping_v2(adapter, ETH_P_8021AD);
return 0;
}
if (adapter->aq_required & IAVF_FLAG_AQ_ENABLE_CTAG_VLAN_STRIPPING) {
iavf_enable_vlan_stripping_v2(adapter, ETH_P_8021Q);
return 0;
}
if (adapter->aq_required & IAVF_FLAG_AQ_ENABLE_STAG_VLAN_STRIPPING) {
iavf_enable_vlan_stripping_v2(adapter, ETH_P_8021AD);
return 0;
}
if (adapter->aq_required & IAVF_FLAG_AQ_DISABLE_CTAG_VLAN_INSERTION) {
iavf_disable_vlan_insertion_v2(adapter, ETH_P_8021Q);
return 0;
}
if (adapter->aq_required & IAVF_FLAG_AQ_DISABLE_STAG_VLAN_INSERTION) {
iavf_disable_vlan_insertion_v2(adapter, ETH_P_8021AD);
return 0;
}
if (adapter->aq_required & IAVF_FLAG_AQ_ENABLE_CTAG_VLAN_INSERTION) {
iavf_enable_vlan_insertion_v2(adapter, ETH_P_8021Q);
return 0;
}
if (adapter->aq_required & IAVF_FLAG_AQ_ENABLE_STAG_VLAN_INSERTION) {
iavf_enable_vlan_insertion_v2(adapter, ETH_P_8021AD);
return 0;
}

if (adapter->aq_required & IAVF_FLAG_AQ_REQUEST_STATS) {
iavf_request_stats(adapter);
return 0;
Expand All @@ -1823,6 +1856,91 @@ static int iavf_process_aq_command(struct iavf_adapter *adapter)
return -EAGAIN;
}

/**
* iavf_set_vlan_offload_features - set VLAN offload configuration
* @adapter: board private structure
* @prev_features: previous features used for comparison
* @features: updated features used for configuration
*
* Set the aq_required bit(s) based on the requested features passed in to
* configure VLAN stripping and/or VLAN insertion if supported. Also, schedule
* the watchdog if any changes are requested to expedite the request via
* virtchnl.
**/
void
iavf_set_vlan_offload_features(struct iavf_adapter *adapter,
netdev_features_t prev_features,
netdev_features_t features)
{
bool enable_stripping = true, enable_insertion = true;
u16 vlan_ethertype = 0;
u64 aq_required = 0;

/* keep cases separate because one ethertype for offloads can be
* disabled at the same time as another is disabled, so check for an
* enabled ethertype first, then check for disabled. Default to
* ETH_P_8021Q so an ethertype is specified if disabling insertion and
* stripping.
*/
if (features & (NETIF_F_HW_VLAN_STAG_RX | NETIF_F_HW_VLAN_STAG_TX))
vlan_ethertype = ETH_P_8021AD;
else if (features & (NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_TX))
vlan_ethertype = ETH_P_8021Q;
else if (prev_features & (NETIF_F_HW_VLAN_STAG_RX | NETIF_F_HW_VLAN_STAG_TX))
vlan_ethertype = ETH_P_8021AD;
else if (prev_features & (NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_TX))
vlan_ethertype = ETH_P_8021Q;
else
vlan_ethertype = ETH_P_8021Q;

if (!(features & (NETIF_F_HW_VLAN_STAG_RX | NETIF_F_HW_VLAN_CTAG_RX)))
enable_stripping = false;
if (!(features & (NETIF_F_HW_VLAN_STAG_TX | NETIF_F_HW_VLAN_CTAG_TX)))
enable_insertion = false;

if (VLAN_ALLOWED(adapter)) {
/* VIRTCHNL_VF_OFFLOAD_VLAN only has support for toggling VLAN
* stripping via virtchnl. VLAN insertion can be toggled on the
* netdev, but it doesn't require a virtchnl message
*/
if (enable_stripping)
aq_required |= IAVF_FLAG_AQ_ENABLE_VLAN_STRIPPING;
else
aq_required |= IAVF_FLAG_AQ_DISABLE_VLAN_STRIPPING;

} else if (VLAN_V2_ALLOWED(adapter)) {
switch (vlan_ethertype) {
case ETH_P_8021Q:
if (enable_stripping)
aq_required |= IAVF_FLAG_AQ_ENABLE_CTAG_VLAN_STRIPPING;
else
aq_required |= IAVF_FLAG_AQ_DISABLE_CTAG_VLAN_STRIPPING;

if (enable_insertion)
aq_required |= IAVF_FLAG_AQ_ENABLE_CTAG_VLAN_INSERTION;
else
aq_required |= IAVF_FLAG_AQ_DISABLE_CTAG_VLAN_INSERTION;
break;
case ETH_P_8021AD:
if (enable_stripping)
aq_required |= IAVF_FLAG_AQ_ENABLE_STAG_VLAN_STRIPPING;
else
aq_required |= IAVF_FLAG_AQ_DISABLE_STAG_VLAN_STRIPPING;

if (enable_insertion)
aq_required |= IAVF_FLAG_AQ_ENABLE_STAG_VLAN_INSERTION;
else
aq_required |= IAVF_FLAG_AQ_DISABLE_STAG_VLAN_INSERTION;
break;
}
}

if (aq_required) {
adapter->aq_required |= aq_required;
mod_delayed_work(iavf_wq, &adapter->watchdog_task, 0);
}
}

/**
* iavf_startup - first step of driver startup
* @adapter: board private structure
Expand Down Expand Up @@ -2179,6 +2297,10 @@ static void iavf_init_config_adapter(struct iavf_adapter *adapter)
else
iavf_init_rss(adapter);

if (VLAN_V2_ALLOWED(adapter))
/* request initial VLAN offload settings */
iavf_set_vlan_offload_features(adapter, 0, netdev->features);

return;
err_mem:
iavf_free_rss(adapter);
Expand Down Expand Up @@ -3684,6 +3806,11 @@ static int iavf_change_mtu(struct net_device *netdev, int new_mtu)
return 0;
}

#define NETIF_VLAN_OFFLOAD_FEATURES (NETIF_F_HW_VLAN_CTAG_RX | \
NETIF_F_HW_VLAN_CTAG_TX | \
NETIF_F_HW_VLAN_STAG_RX | \
NETIF_F_HW_VLAN_STAG_TX)

/**
* iavf_set_features - set the netdev feature flags
* @netdev: ptr to the netdev being adjusted
Expand All @@ -3695,25 +3822,11 @@ static int iavf_set_features(struct net_device *netdev,
{
struct iavf_adapter *adapter = netdev_priv(netdev);

/* Don't allow enabling VLAN features when adapter is not capable
* of VLAN offload/filtering
*/
if (!VLAN_ALLOWED(adapter)) {
netdev->hw_features &= ~(NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_FILTER);
if (features & (NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_FILTER))
return -EINVAL;
} else if ((netdev->features ^ features) & NETIF_F_HW_VLAN_CTAG_RX) {
if (features & NETIF_F_HW_VLAN_CTAG_RX)
adapter->aq_required |=
IAVF_FLAG_AQ_ENABLE_VLAN_STRIPPING;
else
adapter->aq_required |=
IAVF_FLAG_AQ_DISABLE_VLAN_STRIPPING;
}
/* trigger update on any VLAN feature change */
if ((netdev->features & NETIF_VLAN_OFFLOAD_FEATURES) ^
(features & NETIF_VLAN_OFFLOAD_FEATURES))
iavf_set_vlan_offload_features(adapter, netdev->features,
features);

return 0;
}
Expand Down
Loading

0 comments on commit 8afadd1

Please sign in to comment.