Skip to content

Commit f016804

Browse files
vladimirolteandavem330
authored andcommitted
net: enetc: reimplement RFS/RSS memory clearing as PCI quirk
The workaround implemented in commit 3222b5b ("net: enetc: initialize RFS/RSS memories for unused ports too") is no longer effective after commit 6fffbc7 ("PCI: Honor firmware's device disabled status"). Thus, it has introduced a regression and we see AER errors being reported again: $ ip link set sw2p0 up && dhclient -i sw2p0 && ip addr show sw2p0 fsl_enetc 0000:00:00.2 eno2: configuring for fixed/internal link mode fsl_enetc 0000:00:00.2 eno2: Link is Up - 2.5Gbps/Full - flow control rx/tx mscc_felix 0000:00:00.5 swp2: configuring for fixed/sgmii link mode mscc_felix 0000:00:00.5 swp2: Link is Up - 1Gbps/Full - flow control off sja1105 spi2.2 sw2p0: configuring for phy/rgmii-id link mode sja1105 spi2.2 sw2p0: Link is Up - 1Gbps/Full - flow control off pcieport 0000:00:1f.0: AER: Multiple Corrected error received: 0000:00:00.0 pcieport 0000:00:1f.0: AER: can't find device of ID0000 Rob's suggestion is to reimplement the enetc driver workaround as a PCI fixup, and to modify the PCI core to run the fixups for all PCI functions. This change handles the first part. We refactor the common code in enetc_psi_create() and enetc_psi_destroy(), and use the PCI fixup only for those functions for which enetc_pf_probe() won't get called. This avoids some work being done twice for the PFs which are enabled. Fixes: 6fffbc7 ("PCI: Honor firmware's device disabled status") Link: https://lore.kernel.org/netdev/CAL_JsqLsVYiPLx2kcHkDQ4t=hQVCR7NHziDwi9cCFUFhx48Qow@mail.gmail.com/ Suggested-by: Rob Herring <robh@kernel.org> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 1a8c251 commit f016804

File tree

1 file changed

+73
-30
lines changed

1 file changed

+73
-30
lines changed

drivers/net/ethernet/freescale/enetc/enetc_pf.c

Lines changed: 73 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,50 +1208,81 @@ static int enetc_pf_register_with_ierb(struct pci_dev *pdev)
12081208
return enetc_ierb_register_pf(ierb_pdev, pdev);
12091209
}
12101210

1211-
static int enetc_pf_probe(struct pci_dev *pdev,
1212-
const struct pci_device_id *ent)
1211+
static struct enetc_si *enetc_psi_create(struct pci_dev *pdev)
12131212
{
1214-
struct device_node *node = pdev->dev.of_node;
1215-
struct enetc_ndev_priv *priv;
1216-
struct net_device *ndev;
12171213
struct enetc_si *si;
1218-
struct enetc_pf *pf;
12191214
int err;
12201215

1221-
err = enetc_pf_register_with_ierb(pdev);
1222-
if (err == -EPROBE_DEFER)
1223-
return err;
1224-
if (err)
1225-
dev_warn(&pdev->dev,
1226-
"Could not register with IERB driver: %pe, please update the device tree\n",
1227-
ERR_PTR(err));
1228-
1229-
err = enetc_pci_probe(pdev, KBUILD_MODNAME, sizeof(*pf));
1230-
if (err)
1231-
return dev_err_probe(&pdev->dev, err, "PCI probing failed\n");
1216+
err = enetc_pci_probe(pdev, KBUILD_MODNAME, sizeof(struct enetc_pf));
1217+
if (err) {
1218+
dev_err_probe(&pdev->dev, err, "PCI probing failed\n");
1219+
goto out;
1220+
}
12321221

12331222
si = pci_get_drvdata(pdev);
12341223
if (!si->hw.port || !si->hw.global) {
12351224
err = -ENODEV;
12361225
dev_err(&pdev->dev, "could not map PF space, probing a VF?\n");
1237-
goto err_map_pf_space;
1226+
goto out_pci_remove;
12381227
}
12391228

12401229
err = enetc_setup_cbdr(&pdev->dev, &si->hw, ENETC_CBDR_DEFAULT_SIZE,
12411230
&si->cbd_ring);
12421231
if (err)
1243-
goto err_setup_cbdr;
1232+
goto out_pci_remove;
12441233

12451234
err = enetc_init_port_rfs_memory(si);
12461235
if (err) {
12471236
dev_err(&pdev->dev, "Failed to initialize RFS memory\n");
1248-
goto err_init_port_rfs;
1237+
goto out_teardown_cbdr;
12491238
}
12501239

12511240
err = enetc_init_port_rss_memory(si);
12521241
if (err) {
12531242
dev_err(&pdev->dev, "Failed to initialize RSS memory\n");
1254-
goto err_init_port_rss;
1243+
goto out_teardown_cbdr;
1244+
}
1245+
1246+
return si;
1247+
1248+
out_teardown_cbdr:
1249+
enetc_teardown_cbdr(&si->cbd_ring);
1250+
out_pci_remove:
1251+
enetc_pci_remove(pdev);
1252+
out:
1253+
return ERR_PTR(err);
1254+
}
1255+
1256+
static void enetc_psi_destroy(struct pci_dev *pdev)
1257+
{
1258+
struct enetc_si *si = pci_get_drvdata(pdev);
1259+
1260+
enetc_teardown_cbdr(&si->cbd_ring);
1261+
enetc_pci_remove(pdev);
1262+
}
1263+
1264+
static int enetc_pf_probe(struct pci_dev *pdev,
1265+
const struct pci_device_id *ent)
1266+
{
1267+
struct device_node *node = pdev->dev.of_node;
1268+
struct enetc_ndev_priv *priv;
1269+
struct net_device *ndev;
1270+
struct enetc_si *si;
1271+
struct enetc_pf *pf;
1272+
int err;
1273+
1274+
err = enetc_pf_register_with_ierb(pdev);
1275+
if (err == -EPROBE_DEFER)
1276+
return err;
1277+
if (err)
1278+
dev_warn(&pdev->dev,
1279+
"Could not register with IERB driver: %pe, please update the device tree\n",
1280+
ERR_PTR(err));
1281+
1282+
si = enetc_psi_create(pdev);
1283+
if (IS_ERR(si)) {
1284+
err = PTR_ERR(si);
1285+
goto err_psi_create;
12551286
}
12561287

12571288
if (node && !of_device_is_available(node)) {
@@ -1339,15 +1370,10 @@ static int enetc_pf_probe(struct pci_dev *pdev,
13391370
si->ndev = NULL;
13401371
free_netdev(ndev);
13411372
err_alloc_netdev:
1342-
err_init_port_rss:
1343-
err_init_port_rfs:
13441373
err_device_disabled:
13451374
err_setup_mac_addresses:
1346-
enetc_teardown_cbdr(&si->cbd_ring);
1347-
err_setup_cbdr:
1348-
err_map_pf_space:
1349-
enetc_pci_remove(pdev);
1350-
1375+
enetc_psi_destroy(pdev);
1376+
err_psi_create:
13511377
return err;
13521378
}
13531379

@@ -1370,12 +1396,29 @@ static void enetc_pf_remove(struct pci_dev *pdev)
13701396
enetc_free_msix(priv);
13711397

13721398
enetc_free_si_resources(priv);
1373-
enetc_teardown_cbdr(&si->cbd_ring);
13741399

13751400
free_netdev(si->ndev);
13761401

1377-
enetc_pci_remove(pdev);
1402+
enetc_psi_destroy(pdev);
1403+
}
1404+
1405+
static void enetc_fixup_clear_rss_rfs(struct pci_dev *pdev)
1406+
{
1407+
struct device_node *node = pdev->dev.of_node;
1408+
struct enetc_si *si;
1409+
1410+
/* Only apply quirk for disabled functions. For the ones
1411+
* that are enabled, enetc_pf_probe() will apply it.
1412+
*/
1413+
if (node && of_device_is_available(node))
1414+
return;
1415+
1416+
si = enetc_psi_create(pdev);
1417+
if (si)
1418+
enetc_psi_destroy(pdev);
13781419
}
1420+
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_FREESCALE, ENETC_DEV_ID_PF,
1421+
enetc_fixup_clear_rss_rfs);
13791422

13801423
static const struct pci_device_id enetc_pf_id_table[] = {
13811424
{ PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, ENETC_DEV_ID_PF) },

0 commit comments

Comments
 (0)