Commit 848e5d66 authored by David S. Miller's avatar David S. Miller

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

Tony Nguyen says:

====================
Intel Wired LAN Driver Updates 2021-11-15

This series contains updates to iavf driver only.

Mateusz adds a wait for reset completion when changing queue count which
could otherwise cause issues with VF reset.

Nick adds a null check for vf_res in iavf_fix_features(), corrects
ordering of function calls to resolve dependency issues, and prevents
possible freeing of a lock which isn't being held.

Piotr fixes logic that did not allow setting all multicast mode without
promiscuous mode.

Jake prevents possible accidental freeing of filter structure.

Mitch adds null checks for key and indir parameters in iavf_get_rxfh().

Surabhi adds an additional check that would, previously, cause the driver
to print a false error due to values obtained while the VF is in reset.

Grzegorz prevents a queue request of 0 which would cause queue count to
reset to default values.

Akeem restores VLAN filters when bringing the interface back up.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents cf4f5530 42930142
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "iavf_txrx.h" #include "iavf_txrx.h"
#include "iavf_fdir.h" #include "iavf_fdir.h"
#include "iavf_adv_rss.h" #include "iavf_adv_rss.h"
#include <linux/bitmap.h>
#define DEFAULT_DEBUG_LEVEL_SHIFT 3 #define DEFAULT_DEBUG_LEVEL_SHIFT 3
#define PFX "iavf: " #define PFX "iavf: "
......
...@@ -1776,6 +1776,7 @@ static int iavf_set_channels(struct net_device *netdev, ...@@ -1776,6 +1776,7 @@ static int iavf_set_channels(struct net_device *netdev,
{ {
struct iavf_adapter *adapter = netdev_priv(netdev); struct iavf_adapter *adapter = netdev_priv(netdev);
u32 num_req = ch->combined_count; u32 num_req = ch->combined_count;
int i;
if ((adapter->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ADQ) && if ((adapter->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ADQ) &&
adapter->num_tc) { adapter->num_tc) {
...@@ -1786,7 +1787,7 @@ static int iavf_set_channels(struct net_device *netdev, ...@@ -1786,7 +1787,7 @@ static int iavf_set_channels(struct net_device *netdev,
/* All of these should have already been checked by ethtool before this /* All of these should have already been checked by ethtool before this
* even gets to us, but just to be sure. * even gets to us, but just to be sure.
*/ */
if (num_req > adapter->vsi_res->num_queue_pairs) if (num_req == 0 || num_req > adapter->vsi_res->num_queue_pairs)
return -EINVAL; return -EINVAL;
if (num_req == adapter->num_active_queues) if (num_req == adapter->num_active_queues)
...@@ -1798,6 +1799,20 @@ static int iavf_set_channels(struct net_device *netdev, ...@@ -1798,6 +1799,20 @@ static int iavf_set_channels(struct net_device *netdev,
adapter->num_req_queues = num_req; adapter->num_req_queues = num_req;
adapter->flags |= IAVF_FLAG_REINIT_ITR_NEEDED; adapter->flags |= IAVF_FLAG_REINIT_ITR_NEEDED;
iavf_schedule_reset(adapter); iavf_schedule_reset(adapter);
/* wait for the reset is done */
for (i = 0; i < IAVF_RESET_WAIT_COMPLETE_COUNT; i++) {
msleep(IAVF_RESET_WAIT_MS);
if (adapter->flags & IAVF_FLAG_RESET_PENDING)
continue;
break;
}
if (i == IAVF_RESET_WAIT_COMPLETE_COUNT) {
adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED;
adapter->num_active_queues = num_req;
return -EOPNOTSUPP;
}
return 0; return 0;
} }
...@@ -1844,11 +1859,10 @@ static int iavf_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key, ...@@ -1844,11 +1859,10 @@ static int iavf_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
if (hfunc) if (hfunc)
*hfunc = ETH_RSS_HASH_TOP; *hfunc = ETH_RSS_HASH_TOP;
if (!indir) if (key)
return 0;
memcpy(key, adapter->rss_key, adapter->rss_key_size); memcpy(key, adapter->rss_key, adapter->rss_key_size);
if (indir)
/* Each 32 bits pointed by 'indir' is stored with a lut entry */ /* Each 32 bits pointed by 'indir' is stored with a lut entry */
for (i = 0; i < adapter->rss_lut_size; i++) for (i = 0; i < adapter->rss_lut_size; i++)
indir[i] = (u32)adapter->rss_lut[i]; indir[i] = (u32)adapter->rss_lut[i];
......
...@@ -696,6 +696,23 @@ static void iavf_del_vlan(struct iavf_adapter *adapter, u16 vlan) ...@@ -696,6 +696,23 @@ static void iavf_del_vlan(struct iavf_adapter *adapter, u16 vlan)
spin_unlock_bh(&adapter->mac_vlan_list_lock); spin_unlock_bh(&adapter->mac_vlan_list_lock);
} }
/**
* iavf_restore_filters
* @adapter: board private structure
*
* Restore existing non MAC filters when VF netdev comes back up
**/
static void iavf_restore_filters(struct iavf_adapter *adapter)
{
/* re-add all VLAN filters */
if (VLAN_ALLOWED(adapter)) {
u16 vid;
for_each_set_bit(vid, adapter->vsi.active_vlans, VLAN_N_VID)
iavf_add_vlan(adapter, vid);
}
}
/** /**
* iavf_vlan_rx_add_vid - Add a VLAN filter to a device * iavf_vlan_rx_add_vid - Add a VLAN filter to a device
* @netdev: network device struct * @netdev: network device struct
...@@ -709,8 +726,11 @@ static int iavf_vlan_rx_add_vid(struct net_device *netdev, ...@@ -709,8 +726,11 @@ static int iavf_vlan_rx_add_vid(struct net_device *netdev,
if (!VLAN_ALLOWED(adapter)) if (!VLAN_ALLOWED(adapter))
return -EIO; return -EIO;
if (iavf_add_vlan(adapter, vid) == NULL) if (iavf_add_vlan(adapter, vid) == NULL)
return -ENOMEM; return -ENOMEM;
set_bit(vid, adapter->vsi.active_vlans);
return 0; return 0;
} }
...@@ -725,11 +745,13 @@ static int iavf_vlan_rx_kill_vid(struct net_device *netdev, ...@@ -725,11 +745,13 @@ static int iavf_vlan_rx_kill_vid(struct net_device *netdev,
{ {
struct iavf_adapter *adapter = netdev_priv(netdev); struct iavf_adapter *adapter = netdev_priv(netdev);
if (VLAN_ALLOWED(adapter)) { if (!VLAN_ALLOWED(adapter))
return -EIO;
iavf_del_vlan(adapter, vid); iavf_del_vlan(adapter, vid);
clear_bit(vid, adapter->vsi.active_vlans);
return 0; return 0;
}
return -EIO;
} }
/** /**
...@@ -1639,8 +1661,7 @@ static int iavf_process_aq_command(struct iavf_adapter *adapter) ...@@ -1639,8 +1661,7 @@ static int iavf_process_aq_command(struct iavf_adapter *adapter)
iavf_set_promiscuous(adapter, FLAG_VF_MULTICAST_PROMISC); iavf_set_promiscuous(adapter, FLAG_VF_MULTICAST_PROMISC);
return 0; return 0;
} }
if ((adapter->aq_required & IAVF_FLAG_AQ_RELEASE_PROMISC) ||
if ((adapter->aq_required & IAVF_FLAG_AQ_RELEASE_PROMISC) &&
(adapter->aq_required & IAVF_FLAG_AQ_RELEASE_ALLMULTI)) { (adapter->aq_required & IAVF_FLAG_AQ_RELEASE_ALLMULTI)) {
iavf_set_promiscuous(adapter, 0); iavf_set_promiscuous(adapter, 0);
return 0; return 0;
...@@ -2123,8 +2144,8 @@ static void iavf_disable_vf(struct iavf_adapter *adapter) ...@@ -2123,8 +2144,8 @@ static void iavf_disable_vf(struct iavf_adapter *adapter)
iavf_free_misc_irq(adapter); iavf_free_misc_irq(adapter);
iavf_reset_interrupt_capability(adapter); iavf_reset_interrupt_capability(adapter);
iavf_free_queues(adapter);
iavf_free_q_vectors(adapter); iavf_free_q_vectors(adapter);
iavf_free_queues(adapter);
memset(adapter->vf_res, 0, IAVF_VIRTCHNL_VF_RESOURCE_SIZE); memset(adapter->vf_res, 0, IAVF_VIRTCHNL_VF_RESOURCE_SIZE);
iavf_shutdown_adminq(&adapter->hw); iavf_shutdown_adminq(&adapter->hw);
adapter->netdev->flags &= ~IFF_UP; adapter->netdev->flags &= ~IFF_UP;
...@@ -2410,7 +2431,7 @@ static void iavf_adminq_task(struct work_struct *work) ...@@ -2410,7 +2431,7 @@ static void iavf_adminq_task(struct work_struct *work)
/* check for error indications */ /* check for error indications */
val = rd32(hw, hw->aq.arq.len); val = rd32(hw, hw->aq.arq.len);
if (val == 0xdeadbeef) /* indicates device in reset */ if (val == 0xdeadbeef || val == 0xffffffff) /* device in reset */
goto freedom; goto freedom;
oldval = val; oldval = val;
if (val & IAVF_VF_ARQLEN1_ARQVFE_MASK) { if (val & IAVF_VF_ARQLEN1_ARQVFE_MASK) {
...@@ -3095,8 +3116,10 @@ static int iavf_configure_clsflower(struct iavf_adapter *adapter, ...@@ -3095,8 +3116,10 @@ static int iavf_configure_clsflower(struct iavf_adapter *adapter,
return -ENOMEM; return -ENOMEM;
while (!mutex_trylock(&adapter->crit_lock)) { while (!mutex_trylock(&adapter->crit_lock)) {
if (--count == 0) if (--count == 0) {
goto err; kfree(filter);
return err;
}
udelay(1); udelay(1);
} }
...@@ -3107,11 +3130,11 @@ static int iavf_configure_clsflower(struct iavf_adapter *adapter, ...@@ -3107,11 +3130,11 @@ static int iavf_configure_clsflower(struct iavf_adapter *adapter,
/* start out with flow type and eth type IPv4 to begin with */ /* start out with flow type and eth type IPv4 to begin with */
filter->f.flow_type = VIRTCHNL_TCP_V4_FLOW; filter->f.flow_type = VIRTCHNL_TCP_V4_FLOW;
err = iavf_parse_cls_flower(adapter, cls_flower, filter); err = iavf_parse_cls_flower(adapter, cls_flower, filter);
if (err < 0) if (err)
goto err; goto err;
err = iavf_handle_tclass(adapter, tc, filter); err = iavf_handle_tclass(adapter, tc, filter);
if (err < 0) if (err)
goto err; goto err;
/* add filter to the list */ /* add filter to the list */
...@@ -3308,6 +3331,9 @@ static int iavf_open(struct net_device *netdev) ...@@ -3308,6 +3331,9 @@ static int iavf_open(struct net_device *netdev)
spin_unlock_bh(&adapter->mac_vlan_list_lock); spin_unlock_bh(&adapter->mac_vlan_list_lock);
/* Restore VLAN filters that were removed with IFF_DOWN */
iavf_restore_filters(adapter);
iavf_configure(adapter); iavf_configure(adapter);
iavf_up_complete(adapter); iavf_up_complete(adapter);
...@@ -3503,7 +3529,8 @@ static netdev_features_t iavf_fix_features(struct net_device *netdev, ...@@ -3503,7 +3529,8 @@ static netdev_features_t iavf_fix_features(struct net_device *netdev,
{ {
struct iavf_adapter *adapter = netdev_priv(netdev); struct iavf_adapter *adapter = netdev_priv(netdev);
if (!(adapter->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN)) if (adapter->vf_res &&
!(adapter->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN))
features &= ~(NETIF_F_HW_VLAN_CTAG_TX | features &= ~(NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_CTAG_FILTER); NETIF_F_HW_VLAN_CTAG_FILTER);
......
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