Commit 48ea8ea3 authored by Jakub Kicinski's avatar Jakub Kicinski

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

Tony Nguyen says:

====================
Intel Wired LAN Driver Updates 2022-07-18

This series contains updates to iavf driver only.

Przemyslaw fixes handling of multiple VLAN requests to account for
individual errors instead of rejecting them all. He removes incorrect
implementations of ETHTOOL_COALESCE_MAX_FRAMES and
ETHTOOL_COALESCE_MAX_FRAMES_IRQ.

He also corrects an issue with NULL pointer caused by improper handling of
dummy receive descriptors. Finally, he corrects debug prints reporting an
unknown state.

* '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue:
  iavf: Fix missing state logs
  iavf: Fix handling of dummy receive descriptors
  iavf: Disallow changing rx/tx-frames and rx/tx-frames-irq
  iavf: Fix VLAN_V2 addition/rejection
====================

Link: https://lore.kernel.org/r/20220718174807.4113582-1-anthony.l.nguyen@intel.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents c6b10de5 d8fa2fd7
...@@ -64,7 +64,6 @@ struct iavf_vsi { ...@@ -64,7 +64,6 @@ struct iavf_vsi {
u16 id; u16 id;
DECLARE_BITMAP(state, __IAVF_VSI_STATE_SIZE__); DECLARE_BITMAP(state, __IAVF_VSI_STATE_SIZE__);
int base_vector; int base_vector;
u16 work_limit;
u16 qs_handle; u16 qs_handle;
void *priv; /* client driver data reference. */ void *priv; /* client driver data reference. */
}; };
...@@ -159,8 +158,12 @@ struct iavf_vlan { ...@@ -159,8 +158,12 @@ struct iavf_vlan {
struct iavf_vlan_filter { struct iavf_vlan_filter {
struct list_head list; struct list_head list;
struct iavf_vlan vlan; struct iavf_vlan vlan;
bool remove; /* filter needs to be removed */ struct {
bool add; /* filter needs to be added */ u8 is_new_vlan:1; /* filter is new, wait for PF answer */
u8 remove:1; /* filter needs to be removed */
u8 add:1; /* filter needs to be added */
u8 padding:5;
};
}; };
#define IAVF_MAX_TRAFFIC_CLASS 4 #define IAVF_MAX_TRAFFIC_CLASS 4
...@@ -461,6 +464,10 @@ static inline const char *iavf_state_str(enum iavf_state_t state) ...@@ -461,6 +464,10 @@ static inline const char *iavf_state_str(enum iavf_state_t state)
return "__IAVF_INIT_VERSION_CHECK"; return "__IAVF_INIT_VERSION_CHECK";
case __IAVF_INIT_GET_RESOURCES: case __IAVF_INIT_GET_RESOURCES:
return "__IAVF_INIT_GET_RESOURCES"; return "__IAVF_INIT_GET_RESOURCES";
case __IAVF_INIT_EXTENDED_CAPS:
return "__IAVF_INIT_EXTENDED_CAPS";
case __IAVF_INIT_CONFIG_ADAPTER:
return "__IAVF_INIT_CONFIG_ADAPTER";
case __IAVF_INIT_SW: case __IAVF_INIT_SW:
return "__IAVF_INIT_SW"; return "__IAVF_INIT_SW";
case __IAVF_INIT_FAILED: case __IAVF_INIT_FAILED:
...@@ -520,6 +527,7 @@ int iavf_get_vf_config(struct iavf_adapter *adapter); ...@@ -520,6 +527,7 @@ int iavf_get_vf_config(struct iavf_adapter *adapter);
int iavf_get_vf_vlan_v2_caps(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); 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_set_queue_vlan_tag_loc(struct iavf_adapter *adapter);
u16 iavf_get_num_vlans_added(struct iavf_adapter *adapter);
void iavf_irq_enable(struct iavf_adapter *adapter, bool flush); void iavf_irq_enable(struct iavf_adapter *adapter, bool flush);
void iavf_configure_queues(struct iavf_adapter *adapter); void iavf_configure_queues(struct iavf_adapter *adapter);
void iavf_deconfigure_queues(struct iavf_adapter *adapter); void iavf_deconfigure_queues(struct iavf_adapter *adapter);
......
...@@ -692,12 +692,8 @@ static int __iavf_get_coalesce(struct net_device *netdev, ...@@ -692,12 +692,8 @@ static int __iavf_get_coalesce(struct net_device *netdev,
struct ethtool_coalesce *ec, int queue) struct ethtool_coalesce *ec, int queue)
{ {
struct iavf_adapter *adapter = netdev_priv(netdev); struct iavf_adapter *adapter = netdev_priv(netdev);
struct iavf_vsi *vsi = &adapter->vsi;
struct iavf_ring *rx_ring, *tx_ring; struct iavf_ring *rx_ring, *tx_ring;
ec->tx_max_coalesced_frames = vsi->work_limit;
ec->rx_max_coalesced_frames = vsi->work_limit;
/* Rx and Tx usecs per queue value. If user doesn't specify the /* Rx and Tx usecs per queue value. If user doesn't specify the
* queue, return queue 0's value to represent. * queue, return queue 0's value to represent.
*/ */
...@@ -825,12 +821,8 @@ static int __iavf_set_coalesce(struct net_device *netdev, ...@@ -825,12 +821,8 @@ static int __iavf_set_coalesce(struct net_device *netdev,
struct ethtool_coalesce *ec, int queue) struct ethtool_coalesce *ec, int queue)
{ {
struct iavf_adapter *adapter = netdev_priv(netdev); struct iavf_adapter *adapter = netdev_priv(netdev);
struct iavf_vsi *vsi = &adapter->vsi;
int i; int i;
if (ec->tx_max_coalesced_frames_irq || ec->rx_max_coalesced_frames_irq)
vsi->work_limit = ec->tx_max_coalesced_frames_irq;
if (ec->rx_coalesce_usecs == 0) { if (ec->rx_coalesce_usecs == 0) {
if (ec->use_adaptive_rx_coalesce) if (ec->use_adaptive_rx_coalesce)
netif_info(adapter, drv, netdev, "rx-usecs=0, need to disable adaptive-rx for a complete disable\n"); netif_info(adapter, drv, netdev, "rx-usecs=0, need to disable adaptive-rx for a complete disable\n");
...@@ -1969,8 +1961,6 @@ static int iavf_set_rxfh(struct net_device *netdev, const u32 *indir, ...@@ -1969,8 +1961,6 @@ static int iavf_set_rxfh(struct net_device *netdev, const u32 *indir,
static const struct ethtool_ops iavf_ethtool_ops = { static const struct ethtool_ops iavf_ethtool_ops = {
.supported_coalesce_params = ETHTOOL_COALESCE_USECS | .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
ETHTOOL_COALESCE_MAX_FRAMES |
ETHTOOL_COALESCE_MAX_FRAMES_IRQ |
ETHTOOL_COALESCE_USE_ADAPTIVE, ETHTOOL_COALESCE_USE_ADAPTIVE,
.get_drvinfo = iavf_get_drvinfo, .get_drvinfo = iavf_get_drvinfo,
.get_link = ethtool_op_get_link, .get_link = ethtool_op_get_link,
......
...@@ -843,7 +843,7 @@ static void iavf_restore_filters(struct iavf_adapter *adapter) ...@@ -843,7 +843,7 @@ static void iavf_restore_filters(struct iavf_adapter *adapter)
* iavf_get_num_vlans_added - get number of VLANs added * iavf_get_num_vlans_added - get number of VLANs added
* @adapter: board private structure * @adapter: board private structure
*/ */
static u16 iavf_get_num_vlans_added(struct iavf_adapter *adapter) u16 iavf_get_num_vlans_added(struct iavf_adapter *adapter)
{ {
return bitmap_weight(adapter->vsi.active_cvlans, VLAN_N_VID) + return bitmap_weight(adapter->vsi.active_cvlans, VLAN_N_VID) +
bitmap_weight(adapter->vsi.active_svlans, VLAN_N_VID); bitmap_weight(adapter->vsi.active_svlans, VLAN_N_VID);
...@@ -906,11 +906,6 @@ static int iavf_vlan_rx_add_vid(struct net_device *netdev, ...@@ -906,11 +906,6 @@ static int iavf_vlan_rx_add_vid(struct net_device *netdev,
if (!iavf_add_vlan(adapter, IAVF_VLAN(vid, be16_to_cpu(proto)))) if (!iavf_add_vlan(adapter, IAVF_VLAN(vid, be16_to_cpu(proto))))
return -ENOMEM; return -ENOMEM;
if (proto == cpu_to_be16(ETH_P_8021Q))
set_bit(vid, adapter->vsi.active_cvlans);
else
set_bit(vid, adapter->vsi.active_svlans);
return 0; return 0;
} }
...@@ -2245,7 +2240,6 @@ int iavf_parse_vf_resource_msg(struct iavf_adapter *adapter) ...@@ -2245,7 +2240,6 @@ int iavf_parse_vf_resource_msg(struct iavf_adapter *adapter)
adapter->vsi.back = adapter; adapter->vsi.back = adapter;
adapter->vsi.base_vector = 1; adapter->vsi.base_vector = 1;
adapter->vsi.work_limit = IAVF_DEFAULT_IRQ_WORK;
vsi->netdev = adapter->netdev; vsi->netdev = adapter->netdev;
vsi->qs_handle = adapter->vsi_res->qset_handle; vsi->qs_handle = adapter->vsi_res->qset_handle;
if (adapter->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF) { if (adapter->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF) {
...@@ -2956,6 +2950,9 @@ static void iavf_reset_task(struct work_struct *work) ...@@ -2956,6 +2950,9 @@ static void iavf_reset_task(struct work_struct *work)
adapter->aq_required |= IAVF_FLAG_AQ_ADD_CLOUD_FILTER; adapter->aq_required |= IAVF_FLAG_AQ_ADD_CLOUD_FILTER;
iavf_misc_irq_enable(adapter); iavf_misc_irq_enable(adapter);
bitmap_clear(adapter->vsi.active_cvlans, 0, VLAN_N_VID);
bitmap_clear(adapter->vsi.active_svlans, 0, VLAN_N_VID);
mod_delayed_work(iavf_wq, &adapter->watchdog_task, 2); mod_delayed_work(iavf_wq, &adapter->watchdog_task, 2);
/* We were running when the reset started, so we need to restore some /* We were running when the reset started, so we need to restore some
......
...@@ -194,7 +194,7 @@ static bool iavf_clean_tx_irq(struct iavf_vsi *vsi, ...@@ -194,7 +194,7 @@ static bool iavf_clean_tx_irq(struct iavf_vsi *vsi,
struct iavf_tx_buffer *tx_buf; struct iavf_tx_buffer *tx_buf;
struct iavf_tx_desc *tx_desc; struct iavf_tx_desc *tx_desc;
unsigned int total_bytes = 0, total_packets = 0; unsigned int total_bytes = 0, total_packets = 0;
unsigned int budget = vsi->work_limit; unsigned int budget = IAVF_DEFAULT_IRQ_WORK;
tx_buf = &tx_ring->tx_bi[i]; tx_buf = &tx_ring->tx_bi[i];
tx_desc = IAVF_TX_DESC(tx_ring, i); tx_desc = IAVF_TX_DESC(tx_ring, i);
...@@ -1285,11 +1285,10 @@ static struct iavf_rx_buffer *iavf_get_rx_buffer(struct iavf_ring *rx_ring, ...@@ -1285,11 +1285,10 @@ static struct iavf_rx_buffer *iavf_get_rx_buffer(struct iavf_ring *rx_ring,
{ {
struct iavf_rx_buffer *rx_buffer; struct iavf_rx_buffer *rx_buffer;
if (!size)
return NULL;
rx_buffer = &rx_ring->rx_bi[rx_ring->next_to_clean]; rx_buffer = &rx_ring->rx_bi[rx_ring->next_to_clean];
prefetchw(rx_buffer->page); prefetchw(rx_buffer->page);
if (!size)
return rx_buffer;
/* we are reusing so sync this buffer for CPU use */ /* we are reusing so sync this buffer for CPU use */
dma_sync_single_range_for_cpu(rx_ring->dev, dma_sync_single_range_for_cpu(rx_ring->dev,
......
...@@ -626,6 +626,33 @@ static void iavf_mac_add_reject(struct iavf_adapter *adapter) ...@@ -626,6 +626,33 @@ static void iavf_mac_add_reject(struct iavf_adapter *adapter)
spin_unlock_bh(&adapter->mac_vlan_list_lock); spin_unlock_bh(&adapter->mac_vlan_list_lock);
} }
/**
* iavf_vlan_add_reject
* @adapter: adapter structure
*
* Remove VLAN filters from list based on PF response.
**/
static void iavf_vlan_add_reject(struct iavf_adapter *adapter)
{
struct iavf_vlan_filter *f, *ftmp;
spin_lock_bh(&adapter->mac_vlan_list_lock);
list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) {
if (f->is_new_vlan) {
if (f->vlan.tpid == ETH_P_8021Q)
clear_bit(f->vlan.vid,
adapter->vsi.active_cvlans);
else
clear_bit(f->vlan.vid,
adapter->vsi.active_svlans);
list_del(&f->list);
kfree(f);
}
}
spin_unlock_bh(&adapter->mac_vlan_list_lock);
}
/** /**
* iavf_add_vlans * iavf_add_vlans
* @adapter: adapter structure * @adapter: adapter structure
...@@ -683,6 +710,7 @@ void iavf_add_vlans(struct iavf_adapter *adapter) ...@@ -683,6 +710,7 @@ void iavf_add_vlans(struct iavf_adapter *adapter)
vvfl->vlan_id[i] = f->vlan.vid; vvfl->vlan_id[i] = f->vlan.vid;
i++; i++;
f->add = false; f->add = false;
f->is_new_vlan = true;
if (i == count) if (i == count)
break; break;
} }
...@@ -695,10 +723,18 @@ void iavf_add_vlans(struct iavf_adapter *adapter) ...@@ -695,10 +723,18 @@ void iavf_add_vlans(struct iavf_adapter *adapter)
iavf_send_pf_msg(adapter, VIRTCHNL_OP_ADD_VLAN, (u8 *)vvfl, len); iavf_send_pf_msg(adapter, VIRTCHNL_OP_ADD_VLAN, (u8 *)vvfl, len);
kfree(vvfl); kfree(vvfl);
} else { } else {
u16 max_vlans = adapter->vlan_v2_caps.filtering.max_filters;
u16 current_vlans = iavf_get_num_vlans_added(adapter);
struct virtchnl_vlan_filter_list_v2 *vvfl_v2; struct virtchnl_vlan_filter_list_v2 *vvfl_v2;
adapter->current_op = VIRTCHNL_OP_ADD_VLAN_V2; adapter->current_op = VIRTCHNL_OP_ADD_VLAN_V2;
if ((count + current_vlans) > max_vlans &&
current_vlans < max_vlans) {
count = max_vlans - iavf_get_num_vlans_added(adapter);
more = true;
}
len = sizeof(*vvfl_v2) + ((count - 1) * len = sizeof(*vvfl_v2) + ((count - 1) *
sizeof(struct virtchnl_vlan_filter)); sizeof(struct virtchnl_vlan_filter));
if (len > IAVF_MAX_AQ_BUF_SIZE) { if (len > IAVF_MAX_AQ_BUF_SIZE) {
...@@ -725,6 +761,9 @@ void iavf_add_vlans(struct iavf_adapter *adapter) ...@@ -725,6 +761,9 @@ void iavf_add_vlans(struct iavf_adapter *adapter)
&adapter->vlan_v2_caps.filtering.filtering_support; &adapter->vlan_v2_caps.filtering.filtering_support;
struct virtchnl_vlan *vlan; struct virtchnl_vlan *vlan;
if (i == count)
break;
/* give priority over outer if it's enabled */ /* give priority over outer if it's enabled */
if (filtering_support->outer) if (filtering_support->outer)
vlan = &vvfl_v2->filters[i].outer; vlan = &vvfl_v2->filters[i].outer;
...@@ -736,8 +775,7 @@ void iavf_add_vlans(struct iavf_adapter *adapter) ...@@ -736,8 +775,7 @@ void iavf_add_vlans(struct iavf_adapter *adapter)
i++; i++;
f->add = false; f->add = false;
if (i == count) f->is_new_vlan = true;
break;
} }
} }
...@@ -2080,6 +2118,11 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter, ...@@ -2080,6 +2118,11 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
*/ */
iavf_netdev_features_vlan_strip_set(netdev, true); iavf_netdev_features_vlan_strip_set(netdev, true);
break; break;
case VIRTCHNL_OP_ADD_VLAN_V2:
iavf_vlan_add_reject(adapter);
dev_warn(&adapter->pdev->dev, "Failed to add VLAN filter, error %s\n",
iavf_stat_str(&adapter->hw, v_retval));
break;
default: default:
dev_err(&adapter->pdev->dev, "PF returned error %d (%s) to our request %d\n", dev_err(&adapter->pdev->dev, "PF returned error %d (%s) to our request %d\n",
v_retval, iavf_stat_str(&adapter->hw, v_retval), v_retval, iavf_stat_str(&adapter->hw, v_retval),
...@@ -2332,6 +2375,24 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter, ...@@ -2332,6 +2375,24 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
spin_unlock_bh(&adapter->adv_rss_lock); spin_unlock_bh(&adapter->adv_rss_lock);
} }
break; break;
case VIRTCHNL_OP_ADD_VLAN_V2: {
struct iavf_vlan_filter *f;
spin_lock_bh(&adapter->mac_vlan_list_lock);
list_for_each_entry(f, &adapter->vlan_filter_list, list) {
if (f->is_new_vlan) {
f->is_new_vlan = false;
if (f->vlan.tpid == ETH_P_8021Q)
set_bit(f->vlan.vid,
adapter->vsi.active_cvlans);
else
set_bit(f->vlan.vid,
adapter->vsi.active_svlans);
}
}
spin_unlock_bh(&adapter->mac_vlan_list_lock);
}
break;
case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING: case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING:
/* PF enabled vlan strip on this VF. /* PF enabled vlan strip on this VF.
* Update netdev->features if needed to be in sync with ethtool. * Update netdev->features if needed to be in sync with ethtool.
......
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