Skip to content

Commit

Permalink
Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git…
Browse files Browse the repository at this point in the history
…/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: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Nov 16, 2021
2 parents cf4f553 + 4293014 commit 848e5d6
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 22 deletions.
1 change: 1 addition & 0 deletions drivers/net/ethernet/intel/iavf/iavf.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "iavf_txrx.h"
#include "iavf_fdir.h"
#include "iavf_adv_rss.h"
#include <linux/bitmap.h>

#define DEFAULT_DEBUG_LEVEL_SHIFT 3
#define PFX "iavf: "
Expand Down
30 changes: 22 additions & 8 deletions drivers/net/ethernet/intel/iavf/iavf_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -1776,6 +1776,7 @@ static int iavf_set_channels(struct net_device *netdev,
{
struct iavf_adapter *adapter = netdev_priv(netdev);
u32 num_req = ch->combined_count;
int i;

if ((adapter->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ADQ) &&
adapter->num_tc) {
Expand All @@ -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
* 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;

if (num_req == adapter->num_active_queues)
Expand All @@ -1798,6 +1799,20 @@ static int iavf_set_channels(struct net_device *netdev,
adapter->num_req_queues = num_req;
adapter->flags |= IAVF_FLAG_REINIT_ITR_NEEDED;
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;
}

Expand Down Expand Up @@ -1844,14 +1859,13 @@ static int iavf_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,

if (hfunc)
*hfunc = ETH_RSS_HASH_TOP;
if (!indir)
return 0;

memcpy(key, adapter->rss_key, adapter->rss_key_size);
if (key)
memcpy(key, adapter->rss_key, adapter->rss_key_size);

/* Each 32 bits pointed by 'indir' is stored with a lut entry */
for (i = 0; i < adapter->rss_lut_size; i++)
indir[i] = (u32)adapter->rss_lut[i];
if (indir)
/* Each 32 bits pointed by 'indir' is stored with a lut entry */
for (i = 0; i < adapter->rss_lut_size; i++)
indir[i] = (u32)adapter->rss_lut[i];

return 0;
}
Expand Down
55 changes: 41 additions & 14 deletions drivers/net/ethernet/intel/iavf/iavf_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,23 @@ static void iavf_del_vlan(struct iavf_adapter *adapter, u16 vlan)
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
* @netdev: network device struct
Expand All @@ -709,8 +726,11 @@ static int iavf_vlan_rx_add_vid(struct net_device *netdev,

if (!VLAN_ALLOWED(adapter))
return -EIO;

if (iavf_add_vlan(adapter, vid) == NULL)
return -ENOMEM;

set_bit(vid, adapter->vsi.active_vlans);
return 0;
}

Expand All @@ -725,11 +745,13 @@ static int iavf_vlan_rx_kill_vid(struct net_device *netdev,
{
struct iavf_adapter *adapter = netdev_priv(netdev);

if (VLAN_ALLOWED(adapter)) {
iavf_del_vlan(adapter, vid);
return 0;
}
return -EIO;
if (!VLAN_ALLOWED(adapter))
return -EIO;

iavf_del_vlan(adapter, vid);
clear_bit(vid, adapter->vsi.active_vlans);

return 0;
}

/**
Expand Down Expand Up @@ -1639,8 +1661,7 @@ static int iavf_process_aq_command(struct iavf_adapter *adapter)
iavf_set_promiscuous(adapter, FLAG_VF_MULTICAST_PROMISC);
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)) {
iavf_set_promiscuous(adapter, 0);
return 0;
Expand Down Expand Up @@ -2123,8 +2144,8 @@ static void iavf_disable_vf(struct iavf_adapter *adapter)

iavf_free_misc_irq(adapter);
iavf_reset_interrupt_capability(adapter);
iavf_free_queues(adapter);
iavf_free_q_vectors(adapter);
iavf_free_queues(adapter);
memset(adapter->vf_res, 0, IAVF_VIRTCHNL_VF_RESOURCE_SIZE);
iavf_shutdown_adminq(&adapter->hw);
adapter->netdev->flags &= ~IFF_UP;
Expand Down Expand Up @@ -2410,7 +2431,7 @@ static void iavf_adminq_task(struct work_struct *work)

/* check for error indications */
val = rd32(hw, hw->aq.arq.len);
if (val == 0xdeadbeef) /* indicates device in reset */
if (val == 0xdeadbeef || val == 0xffffffff) /* device in reset */
goto freedom;
oldval = val;
if (val & IAVF_VF_ARQLEN1_ARQVFE_MASK) {
Expand Down Expand Up @@ -3095,8 +3116,10 @@ static int iavf_configure_clsflower(struct iavf_adapter *adapter,
return -ENOMEM;

while (!mutex_trylock(&adapter->crit_lock)) {
if (--count == 0)
goto err;
if (--count == 0) {
kfree(filter);
return err;
}
udelay(1);
}

Expand All @@ -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 */
filter->f.flow_type = VIRTCHNL_TCP_V4_FLOW;
err = iavf_parse_cls_flower(adapter, cls_flower, filter);
if (err < 0)
if (err)
goto err;

err = iavf_handle_tclass(adapter, tc, filter);
if (err < 0)
if (err)
goto err;

/* add filter to the list */
Expand Down Expand Up @@ -3308,6 +3331,9 @@ static int iavf_open(struct net_device *netdev)

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_up_complete(adapter);
Expand Down Expand Up @@ -3503,7 +3529,8 @@ static netdev_features_t iavf_fix_features(struct net_device *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 |
NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_CTAG_FILTER);
Expand Down

0 comments on commit 848e5d6

Please sign in to comment.