Skip to content

Commit 89e0c64

Browse files
committed
Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue
Tony Nguyen says: ==================== Intel Wired LAN Driver Updates 2023-12-12 (iavf) This series contains updates to iavf driver only. Piotr reworks Flow Director states to deal with issues in restoring filters. Slawomir fixes shutdown processing as it was missing needed calls. * '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue: iavf: Fix iavf_shutdown to call iavf_remove instead iavf_close iavf: Handle ntuple on/off based on new state machines for flow director iavf: Introduce new state machines for flow director ==================== Link: https://lore.kernel.org/r/20231212203613.513423-1-anthony.l.nguyen@intel.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents dc84bb1 + 7ae42ef commit 89e0c64

5 files changed

Lines changed: 219 additions & 74 deletions

File tree

drivers/net/ethernet/intel/iavf/iavf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ struct iavf_adapter {
292292
#define IAVF_FLAG_QUEUES_DISABLED BIT(17)
293293
#define IAVF_FLAG_SETUP_NETDEV_FEATURES BIT(18)
294294
#define IAVF_FLAG_REINIT_MSIX_NEEDED BIT(20)
295+
#define IAVF_FLAG_FDIR_ENABLED BIT(21)
295296
/* duplicates for common code */
296297
#define IAVF_FLAG_DCB_ENABLED 0
297298
/* flags for admin queue service task */

drivers/net/ethernet/intel/iavf/iavf_ethtool.c

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,7 +1061,7 @@ iavf_get_ethtool_fdir_entry(struct iavf_adapter *adapter,
10611061
struct iavf_fdir_fltr *rule = NULL;
10621062
int ret = 0;
10631063

1064-
if (!FDIR_FLTR_SUPPORT(adapter))
1064+
if (!(adapter->flags & IAVF_FLAG_FDIR_ENABLED))
10651065
return -EOPNOTSUPP;
10661066

10671067
spin_lock_bh(&adapter->fdir_fltr_lock);
@@ -1203,7 +1203,7 @@ iavf_get_fdir_fltr_ids(struct iavf_adapter *adapter, struct ethtool_rxnfc *cmd,
12031203
unsigned int cnt = 0;
12041204
int val = 0;
12051205

1206-
if (!FDIR_FLTR_SUPPORT(adapter))
1206+
if (!(adapter->flags & IAVF_FLAG_FDIR_ENABLED))
12071207
return -EOPNOTSUPP;
12081208

12091209
cmd->data = IAVF_MAX_FDIR_FILTERS;
@@ -1395,7 +1395,7 @@ static int iavf_add_fdir_ethtool(struct iavf_adapter *adapter, struct ethtool_rx
13951395
int count = 50;
13961396
int err;
13971397

1398-
if (!FDIR_FLTR_SUPPORT(adapter))
1398+
if (!(adapter->flags & IAVF_FLAG_FDIR_ENABLED))
13991399
return -EOPNOTSUPP;
14001400

14011401
if (fsp->flow_type & FLOW_MAC_EXT)
@@ -1436,12 +1436,16 @@ static int iavf_add_fdir_ethtool(struct iavf_adapter *adapter, struct ethtool_rx
14361436
spin_lock_bh(&adapter->fdir_fltr_lock);
14371437
iavf_fdir_list_add_fltr(adapter, fltr);
14381438
adapter->fdir_active_fltr++;
1439-
fltr->state = IAVF_FDIR_FLTR_ADD_REQUEST;
1440-
adapter->aq_required |= IAVF_FLAG_AQ_ADD_FDIR_FILTER;
1439+
if (adapter->link_up) {
1440+
fltr->state = IAVF_FDIR_FLTR_ADD_REQUEST;
1441+
adapter->aq_required |= IAVF_FLAG_AQ_ADD_FDIR_FILTER;
1442+
} else {
1443+
fltr->state = IAVF_FDIR_FLTR_INACTIVE;
1444+
}
14411445
spin_unlock_bh(&adapter->fdir_fltr_lock);
14421446

1443-
mod_delayed_work(adapter->wq, &adapter->watchdog_task, 0);
1444-
1447+
if (adapter->link_up)
1448+
mod_delayed_work(adapter->wq, &adapter->watchdog_task, 0);
14451449
ret:
14461450
if (err && fltr)
14471451
kfree(fltr);
@@ -1463,7 +1467,7 @@ static int iavf_del_fdir_ethtool(struct iavf_adapter *adapter, struct ethtool_rx
14631467
struct iavf_fdir_fltr *fltr = NULL;
14641468
int err = 0;
14651469

1466-
if (!FDIR_FLTR_SUPPORT(adapter))
1470+
if (!(adapter->flags & IAVF_FLAG_FDIR_ENABLED))
14671471
return -EOPNOTSUPP;
14681472

14691473
spin_lock_bh(&adapter->fdir_fltr_lock);
@@ -1472,6 +1476,11 @@ static int iavf_del_fdir_ethtool(struct iavf_adapter *adapter, struct ethtool_rx
14721476
if (fltr->state == IAVF_FDIR_FLTR_ACTIVE) {
14731477
fltr->state = IAVF_FDIR_FLTR_DEL_REQUEST;
14741478
adapter->aq_required |= IAVF_FLAG_AQ_DEL_FDIR_FILTER;
1479+
} else if (fltr->state == IAVF_FDIR_FLTR_INACTIVE) {
1480+
list_del(&fltr->list);
1481+
kfree(fltr);
1482+
adapter->fdir_active_fltr--;
1483+
fltr = NULL;
14751484
} else {
14761485
err = -EBUSY;
14771486
}
@@ -1780,7 +1789,7 @@ static int iavf_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
17801789
ret = 0;
17811790
break;
17821791
case ETHTOOL_GRXCLSRLCNT:
1783-
if (!FDIR_FLTR_SUPPORT(adapter))
1792+
if (!(adapter->flags & IAVF_FLAG_FDIR_ENABLED))
17841793
break;
17851794
spin_lock_bh(&adapter->fdir_fltr_lock);
17861795
cmd->rule_cnt = adapter->fdir_active_fltr;

drivers/net/ethernet/intel/iavf/iavf_fdir.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,25 @@
66

77
struct iavf_adapter;
88

9-
/* State of Flow Director filter */
9+
/* State of Flow Director filter
10+
*
11+
* *_REQUEST states are used to mark filter to be sent to PF driver to perform
12+
* an action (either add or delete filter). *_PENDING states are an indication
13+
* that request was sent to PF and the driver is waiting for response.
14+
*
15+
* Both DELETE and DISABLE states are being used to delete a filter in PF.
16+
* The difference is that after a successful response filter in DEL_PENDING
17+
* state is being deleted from VF driver as well and filter in DIS_PENDING state
18+
* is being changed to INACTIVE state.
19+
*/
1020
enum iavf_fdir_fltr_state_t {
1121
IAVF_FDIR_FLTR_ADD_REQUEST, /* User requests to add filter */
1222
IAVF_FDIR_FLTR_ADD_PENDING, /* Filter pending add by the PF */
1323
IAVF_FDIR_FLTR_DEL_REQUEST, /* User requests to delete filter */
1424
IAVF_FDIR_FLTR_DEL_PENDING, /* Filter pending delete by the PF */
25+
IAVF_FDIR_FLTR_DIS_REQUEST, /* Filter scheduled to be disabled */
26+
IAVF_FDIR_FLTR_DIS_PENDING, /* Filter pending disable by the PF */
27+
IAVF_FDIR_FLTR_INACTIVE, /* Filter inactive on link down */
1528
IAVF_FDIR_FLTR_ACTIVE, /* Filter is active */
1629
};
1730

drivers/net/ethernet/intel/iavf/iavf_main.c

Lines changed: 119 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -276,27 +276,6 @@ void iavf_free_virt_mem(struct iavf_hw *hw, struct iavf_virt_mem *mem)
276276
kfree(mem->va);
277277
}
278278

279-
/**
280-
* iavf_lock_timeout - try to lock mutex but give up after timeout
281-
* @lock: mutex that should be locked
282-
* @msecs: timeout in msecs
283-
*
284-
* Returns 0 on success, negative on failure
285-
**/
286-
static int iavf_lock_timeout(struct mutex *lock, unsigned int msecs)
287-
{
288-
unsigned int wait, delay = 10;
289-
290-
for (wait = 0; wait < msecs; wait += delay) {
291-
if (mutex_trylock(lock))
292-
return 0;
293-
294-
msleep(delay);
295-
}
296-
297-
return -1;
298-
}
299-
300279
/**
301280
* iavf_schedule_reset - Set the flags and schedule a reset event
302281
* @adapter: board private structure
@@ -1353,18 +1332,20 @@ static void iavf_clear_cloud_filters(struct iavf_adapter *adapter)
13531332
**/
13541333
static void iavf_clear_fdir_filters(struct iavf_adapter *adapter)
13551334
{
1356-
struct iavf_fdir_fltr *fdir, *fdirtmp;
1335+
struct iavf_fdir_fltr *fdir;
13571336

13581337
/* remove all Flow Director filters */
13591338
spin_lock_bh(&adapter->fdir_fltr_lock);
1360-
list_for_each_entry_safe(fdir, fdirtmp, &adapter->fdir_list_head,
1361-
list) {
1339+
list_for_each_entry(fdir, &adapter->fdir_list_head, list) {
13621340
if (fdir->state == IAVF_FDIR_FLTR_ADD_REQUEST) {
1363-
list_del(&fdir->list);
1364-
kfree(fdir);
1365-
adapter->fdir_active_fltr--;
1366-
} else {
1367-
fdir->state = IAVF_FDIR_FLTR_DEL_REQUEST;
1341+
/* Cancel a request, keep filter as inactive */
1342+
fdir->state = IAVF_FDIR_FLTR_INACTIVE;
1343+
} else if (fdir->state == IAVF_FDIR_FLTR_ADD_PENDING ||
1344+
fdir->state == IAVF_FDIR_FLTR_ACTIVE) {
1345+
/* Disable filters which are active or have a pending
1346+
* request to PF to be added
1347+
*/
1348+
fdir->state = IAVF_FDIR_FLTR_DIS_REQUEST;
13681349
}
13691350
}
13701351
spin_unlock_bh(&adapter->fdir_fltr_lock);
@@ -4112,6 +4093,33 @@ static int iavf_setup_tc(struct net_device *netdev, enum tc_setup_type type,
41124093
}
41134094
}
41144095

4096+
/**
4097+
* iavf_restore_fdir_filters
4098+
* @adapter: board private structure
4099+
*
4100+
* Restore existing FDIR filters when VF netdev comes back up.
4101+
**/
4102+
static void iavf_restore_fdir_filters(struct iavf_adapter *adapter)
4103+
{
4104+
struct iavf_fdir_fltr *f;
4105+
4106+
spin_lock_bh(&adapter->fdir_fltr_lock);
4107+
list_for_each_entry(f, &adapter->fdir_list_head, list) {
4108+
if (f->state == IAVF_FDIR_FLTR_DIS_REQUEST) {
4109+
/* Cancel a request, keep filter as active */
4110+
f->state = IAVF_FDIR_FLTR_ACTIVE;
4111+
} else if (f->state == IAVF_FDIR_FLTR_DIS_PENDING ||
4112+
f->state == IAVF_FDIR_FLTR_INACTIVE) {
4113+
/* Add filters which are inactive or have a pending
4114+
* request to PF to be deleted
4115+
*/
4116+
f->state = IAVF_FDIR_FLTR_ADD_REQUEST;
4117+
adapter->aq_required |= IAVF_FLAG_AQ_ADD_FDIR_FILTER;
4118+
}
4119+
}
4120+
spin_unlock_bh(&adapter->fdir_fltr_lock);
4121+
}
4122+
41154123
/**
41164124
* iavf_open - Called when a network interface is made active
41174125
* @netdev: network interface device structure
@@ -4179,8 +4187,9 @@ static int iavf_open(struct net_device *netdev)
41794187

41804188
spin_unlock_bh(&adapter->mac_vlan_list_lock);
41814189

4182-
/* Restore VLAN filters that were removed with IFF_DOWN */
4190+
/* Restore filters that were removed with IFF_DOWN */
41834191
iavf_restore_filters(adapter);
4192+
iavf_restore_fdir_filters(adapter);
41844193

41854194
iavf_configure(adapter);
41864195

@@ -4311,6 +4320,49 @@ static int iavf_change_mtu(struct net_device *netdev, int new_mtu)
43114320
return ret;
43124321
}
43134322

4323+
/**
4324+
* iavf_disable_fdir - disable Flow Director and clear existing filters
4325+
* @adapter: board private structure
4326+
**/
4327+
static void iavf_disable_fdir(struct iavf_adapter *adapter)
4328+
{
4329+
struct iavf_fdir_fltr *fdir, *fdirtmp;
4330+
bool del_filters = false;
4331+
4332+
adapter->flags &= ~IAVF_FLAG_FDIR_ENABLED;
4333+
4334+
/* remove all Flow Director filters */
4335+
spin_lock_bh(&adapter->fdir_fltr_lock);
4336+
list_for_each_entry_safe(fdir, fdirtmp, &adapter->fdir_list_head,
4337+
list) {
4338+
if (fdir->state == IAVF_FDIR_FLTR_ADD_REQUEST ||
4339+
fdir->state == IAVF_FDIR_FLTR_INACTIVE) {
4340+
/* Delete filters not registered in PF */
4341+
list_del(&fdir->list);
4342+
kfree(fdir);
4343+
adapter->fdir_active_fltr--;
4344+
} else if (fdir->state == IAVF_FDIR_FLTR_ADD_PENDING ||
4345+
fdir->state == IAVF_FDIR_FLTR_DIS_REQUEST ||
4346+
fdir->state == IAVF_FDIR_FLTR_ACTIVE) {
4347+
/* Filters registered in PF, schedule their deletion */
4348+
fdir->state = IAVF_FDIR_FLTR_DEL_REQUEST;
4349+
del_filters = true;
4350+
} else if (fdir->state == IAVF_FDIR_FLTR_DIS_PENDING) {
4351+
/* Request to delete filter already sent to PF, change
4352+
* state to DEL_PENDING to delete filter after PF's
4353+
* response, not set as INACTIVE
4354+
*/
4355+
fdir->state = IAVF_FDIR_FLTR_DEL_PENDING;
4356+
}
4357+
}
4358+
spin_unlock_bh(&adapter->fdir_fltr_lock);
4359+
4360+
if (del_filters) {
4361+
adapter->aq_required |= IAVF_FLAG_AQ_DEL_FDIR_FILTER;
4362+
mod_delayed_work(adapter->wq, &adapter->watchdog_task, 0);
4363+
}
4364+
}
4365+
43144366
#define NETIF_VLAN_OFFLOAD_FEATURES (NETIF_F_HW_VLAN_CTAG_RX | \
43154367
NETIF_F_HW_VLAN_CTAG_TX | \
43164368
NETIF_F_HW_VLAN_STAG_RX | \
@@ -4336,6 +4388,13 @@ static int iavf_set_features(struct net_device *netdev,
43364388
((netdev->features & NETIF_F_RXFCS) ^ (features & NETIF_F_RXFCS)))
43374389
iavf_schedule_reset(adapter, IAVF_FLAG_RESET_NEEDED);
43384390

4391+
if ((netdev->features & NETIF_F_NTUPLE) ^ (features & NETIF_F_NTUPLE)) {
4392+
if (features & NETIF_F_NTUPLE)
4393+
adapter->flags |= IAVF_FLAG_FDIR_ENABLED;
4394+
else
4395+
iavf_disable_fdir(adapter);
4396+
}
4397+
43394398
return 0;
43404399
}
43414400

@@ -4685,6 +4744,9 @@ static netdev_features_t iavf_fix_features(struct net_device *netdev,
46854744

46864745
features = iavf_fix_netdev_vlan_features(adapter, features);
46874746

4747+
if (!FDIR_FLTR_SUPPORT(adapter))
4748+
features &= ~NETIF_F_NTUPLE;
4749+
46884750
return iavf_fix_strip_features(adapter, features);
46894751
}
46904752

@@ -4802,6 +4864,12 @@ int iavf_process_config(struct iavf_adapter *adapter)
48024864
if (vfres->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN)
48034865
netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
48044866

4867+
if (FDIR_FLTR_SUPPORT(adapter)) {
4868+
netdev->hw_features |= NETIF_F_NTUPLE;
4869+
netdev->features |= NETIF_F_NTUPLE;
4870+
adapter->flags |= IAVF_FLAG_FDIR_ENABLED;
4871+
}
4872+
48054873
netdev->priv_flags |= IFF_UNICAST_FLT;
48064874

48074875
/* Do not turn on offloads when they are requested to be turned off.
@@ -4825,34 +4893,6 @@ int iavf_process_config(struct iavf_adapter *adapter)
48254893
return 0;
48264894
}
48274895

4828-
/**
4829-
* iavf_shutdown - Shutdown the device in preparation for a reboot
4830-
* @pdev: pci device structure
4831-
**/
4832-
static void iavf_shutdown(struct pci_dev *pdev)
4833-
{
4834-
struct iavf_adapter *adapter = iavf_pdev_to_adapter(pdev);
4835-
struct net_device *netdev = adapter->netdev;
4836-
4837-
netif_device_detach(netdev);
4838-
4839-
if (netif_running(netdev))
4840-
iavf_close(netdev);
4841-
4842-
if (iavf_lock_timeout(&adapter->crit_lock, 5000))
4843-
dev_warn(&adapter->pdev->dev, "%s: failed to acquire crit_lock\n", __func__);
4844-
/* Prevent the watchdog from running. */
4845-
iavf_change_state(adapter, __IAVF_REMOVE);
4846-
adapter->aq_required = 0;
4847-
mutex_unlock(&adapter->crit_lock);
4848-
4849-
#ifdef CONFIG_PM
4850-
pci_save_state(pdev);
4851-
4852-
#endif
4853-
pci_disable_device(pdev);
4854-
}
4855-
48564896
/**
48574897
* iavf_probe - Device Initialization Routine
48584898
* @pdev: PCI device information struct
@@ -5063,16 +5103,21 @@ static int __maybe_unused iavf_resume(struct device *dev_d)
50635103
**/
50645104
static void iavf_remove(struct pci_dev *pdev)
50655105
{
5066-
struct iavf_adapter *adapter = iavf_pdev_to_adapter(pdev);
50675106
struct iavf_fdir_fltr *fdir, *fdirtmp;
50685107
struct iavf_vlan_filter *vlf, *vlftmp;
50695108
struct iavf_cloud_filter *cf, *cftmp;
50705109
struct iavf_adv_rss *rss, *rsstmp;
50715110
struct iavf_mac_filter *f, *ftmp;
5111+
struct iavf_adapter *adapter;
50725112
struct net_device *netdev;
50735113
struct iavf_hw *hw;
50745114

5075-
netdev = adapter->netdev;
5115+
/* Don't proceed with remove if netdev is already freed */
5116+
netdev = pci_get_drvdata(pdev);
5117+
if (!netdev)
5118+
return;
5119+
5120+
adapter = iavf_pdev_to_adapter(pdev);
50765121
hw = &adapter->hw;
50775122

50785123
if (test_and_set_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section))
@@ -5184,11 +5229,25 @@ static void iavf_remove(struct pci_dev *pdev)
51845229

51855230
destroy_workqueue(adapter->wq);
51865231

5232+
pci_set_drvdata(pdev, NULL);
5233+
51875234
free_netdev(netdev);
51885235

51895236
pci_disable_device(pdev);
51905237
}
51915238

5239+
/**
5240+
* iavf_shutdown - Shutdown the device in preparation for a reboot
5241+
* @pdev: pci device structure
5242+
**/
5243+
static void iavf_shutdown(struct pci_dev *pdev)
5244+
{
5245+
iavf_remove(pdev);
5246+
5247+
if (system_state == SYSTEM_POWER_OFF)
5248+
pci_set_power_state(pdev, PCI_D3hot);
5249+
}
5250+
51925251
static SIMPLE_DEV_PM_OPS(iavf_pm_ops, iavf_suspend, iavf_resume);
51935252

51945253
static struct pci_driver iavf_driver = {

0 commit comments

Comments
 (0)