mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-09 14:50:19 +00:00
net: enetc: reimplement RFS/RSS memory clearing as PCI quirk
The workaround implemented in commit 3222b5b613db ("net: enetc: initialize RFS/RSS memories for unused ports too") is no longer effective after commit 6fffbc7ae137 ("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: 6fffbc7ae137 ("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>
This commit is contained in:
parent
1a8c251cff
commit
f0168042a2
@ -1208,6 +1208,59 @@ static int enetc_pf_register_with_ierb(struct pci_dev *pdev)
|
||||
return enetc_ierb_register_pf(ierb_pdev, pdev);
|
||||
}
|
||||
|
||||
static struct enetc_si *enetc_psi_create(struct pci_dev *pdev)
|
||||
{
|
||||
struct enetc_si *si;
|
||||
int err;
|
||||
|
||||
err = enetc_pci_probe(pdev, KBUILD_MODNAME, sizeof(struct enetc_pf));
|
||||
if (err) {
|
||||
dev_err_probe(&pdev->dev, err, "PCI probing failed\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
si = pci_get_drvdata(pdev);
|
||||
if (!si->hw.port || !si->hw.global) {
|
||||
err = -ENODEV;
|
||||
dev_err(&pdev->dev, "could not map PF space, probing a VF?\n");
|
||||
goto out_pci_remove;
|
||||
}
|
||||
|
||||
err = enetc_setup_cbdr(&pdev->dev, &si->hw, ENETC_CBDR_DEFAULT_SIZE,
|
||||
&si->cbd_ring);
|
||||
if (err)
|
||||
goto out_pci_remove;
|
||||
|
||||
err = enetc_init_port_rfs_memory(si);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "Failed to initialize RFS memory\n");
|
||||
goto out_teardown_cbdr;
|
||||
}
|
||||
|
||||
err = enetc_init_port_rss_memory(si);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "Failed to initialize RSS memory\n");
|
||||
goto out_teardown_cbdr;
|
||||
}
|
||||
|
||||
return si;
|
||||
|
||||
out_teardown_cbdr:
|
||||
enetc_teardown_cbdr(&si->cbd_ring);
|
||||
out_pci_remove:
|
||||
enetc_pci_remove(pdev);
|
||||
out:
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
static void enetc_psi_destroy(struct pci_dev *pdev)
|
||||
{
|
||||
struct enetc_si *si = pci_get_drvdata(pdev);
|
||||
|
||||
enetc_teardown_cbdr(&si->cbd_ring);
|
||||
enetc_pci_remove(pdev);
|
||||
}
|
||||
|
||||
static int enetc_pf_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent)
|
||||
{
|
||||
@ -1226,32 +1279,10 @@ static int enetc_pf_probe(struct pci_dev *pdev,
|
||||
"Could not register with IERB driver: %pe, please update the device tree\n",
|
||||
ERR_PTR(err));
|
||||
|
||||
err = enetc_pci_probe(pdev, KBUILD_MODNAME, sizeof(*pf));
|
||||
if (err)
|
||||
return dev_err_probe(&pdev->dev, err, "PCI probing failed\n");
|
||||
|
||||
si = pci_get_drvdata(pdev);
|
||||
if (!si->hw.port || !si->hw.global) {
|
||||
err = -ENODEV;
|
||||
dev_err(&pdev->dev, "could not map PF space, probing a VF?\n");
|
||||
goto err_map_pf_space;
|
||||
}
|
||||
|
||||
err = enetc_setup_cbdr(&pdev->dev, &si->hw, ENETC_CBDR_DEFAULT_SIZE,
|
||||
&si->cbd_ring);
|
||||
if (err)
|
||||
goto err_setup_cbdr;
|
||||
|
||||
err = enetc_init_port_rfs_memory(si);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "Failed to initialize RFS memory\n");
|
||||
goto err_init_port_rfs;
|
||||
}
|
||||
|
||||
err = enetc_init_port_rss_memory(si);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "Failed to initialize RSS memory\n");
|
||||
goto err_init_port_rss;
|
||||
si = enetc_psi_create(pdev);
|
||||
if (IS_ERR(si)) {
|
||||
err = PTR_ERR(si);
|
||||
goto err_psi_create;
|
||||
}
|
||||
|
||||
if (node && !of_device_is_available(node)) {
|
||||
@ -1339,15 +1370,10 @@ err_alloc_si_res:
|
||||
si->ndev = NULL;
|
||||
free_netdev(ndev);
|
||||
err_alloc_netdev:
|
||||
err_init_port_rss:
|
||||
err_init_port_rfs:
|
||||
err_device_disabled:
|
||||
err_setup_mac_addresses:
|
||||
enetc_teardown_cbdr(&si->cbd_ring);
|
||||
err_setup_cbdr:
|
||||
err_map_pf_space:
|
||||
enetc_pci_remove(pdev);
|
||||
|
||||
enetc_psi_destroy(pdev);
|
||||
err_psi_create:
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -1370,13 +1396,30 @@ static void enetc_pf_remove(struct pci_dev *pdev)
|
||||
enetc_free_msix(priv);
|
||||
|
||||
enetc_free_si_resources(priv);
|
||||
enetc_teardown_cbdr(&si->cbd_ring);
|
||||
|
||||
free_netdev(si->ndev);
|
||||
|
||||
enetc_pci_remove(pdev);
|
||||
enetc_psi_destroy(pdev);
|
||||
}
|
||||
|
||||
static void enetc_fixup_clear_rss_rfs(struct pci_dev *pdev)
|
||||
{
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
struct enetc_si *si;
|
||||
|
||||
/* Only apply quirk for disabled functions. For the ones
|
||||
* that are enabled, enetc_pf_probe() will apply it.
|
||||
*/
|
||||
if (node && of_device_is_available(node))
|
||||
return;
|
||||
|
||||
si = enetc_psi_create(pdev);
|
||||
if (si)
|
||||
enetc_psi_destroy(pdev);
|
||||
}
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_FREESCALE, ENETC_DEV_ID_PF,
|
||||
enetc_fixup_clear_rss_rfs);
|
||||
|
||||
static const struct pci_device_id enetc_pf_id_table[] = {
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, ENETC_DEV_ID_PF) },
|
||||
{ 0, } /* End of table. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user