Skip to content

Commit 3222b5b

Browse files
vladimirolteandavem330
authored andcommitted
net: enetc: initialize RFS/RSS memories for unused ports too
Michael reports that since linux-next-20210211, the AER messages for ECC errors have started reappearing, and this time they can be reliably reproduced with the first ping on one of his LS1028A boards. $ ping 1[ 33.258069] pcieport 0000:00:1f.0: AER: Multiple Corrected error received: 0000:00:00.0 72.16.0.1 PING [ 33.267050] pcieport 0000:00:1f.0: AER: can't find device of ID0000 172.16.0.1 (172.16.0.1): 56 data bytes 64 bytes from 172.16.0.1: seq=0 ttl=64 time=17.124 ms 64 bytes from 172.16.0.1: seq=1 ttl=64 time=0.273 ms $ devmem 0x1f8010e10 32 0xC0000006 It isn't clear why this is necessary, but it seems that for the errors to go away, we must clear the entire RFS and RSS memory, not just for the ports in use. Sadly the code is structured in such a way that we can't have unified logic for the used and unused ports. For the minimal initialization of an unused port, we need just to enable and ioremap the PF memory space, and a control buffer descriptor ring. Unused ports must then free the CBDR because the driver will exit, but used ports can not pick up from where that code path left, since the CBDR API does not reinitialize a ring when setting it up, so its producer and consumer indices are out of sync between the software and hardware state. So a separate enetc_init_unused_port function was created, and it gets called right after the PF memory space is enabled. Fixes: 07bf34a ("net: enetc: initialize the RFS and RSS memories") Reported-by: Michael Walle <michael@walle.cc> Cc: Jesse Brandeburg <jesse.brandeburg@intel.com> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Tested-by: Michael Walle <michael@walle.cc> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent c646d10 commit 3222b5b

File tree

3 files changed

+36
-9
lines changed

3 files changed

+36
-9
lines changed

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -984,7 +984,7 @@ static void enetc_free_rxtx_rings(struct enetc_ndev_priv *priv)
984984
enetc_free_tx_ring(priv->tx_ring[i]);
985985
}
986986

987-
static int enetc_alloc_cbdr(struct device *dev, struct enetc_cbdr *cbdr)
987+
int enetc_alloc_cbdr(struct device *dev, struct enetc_cbdr *cbdr)
988988
{
989989
int size = cbdr->bd_count * sizeof(struct enetc_cbd);
990990

@@ -1005,15 +1005,15 @@ static int enetc_alloc_cbdr(struct device *dev, struct enetc_cbdr *cbdr)
10051005
return 0;
10061006
}
10071007

1008-
static void enetc_free_cbdr(struct device *dev, struct enetc_cbdr *cbdr)
1008+
void enetc_free_cbdr(struct device *dev, struct enetc_cbdr *cbdr)
10091009
{
10101010
int size = cbdr->bd_count * sizeof(struct enetc_cbd);
10111011

10121012
dma_free_coherent(dev, size, cbdr->bd_base, cbdr->bd_dma_base);
10131013
cbdr->bd_base = NULL;
10141014
}
10151015

1016-
static void enetc_setup_cbdr(struct enetc_hw *hw, struct enetc_cbdr *cbdr)
1016+
void enetc_setup_cbdr(struct enetc_hw *hw, struct enetc_cbdr *cbdr)
10171017
{
10181018
/* set CBDR cache attributes */
10191019
enetc_wr(hw, ENETC_SICAR2,
@@ -1033,7 +1033,7 @@ static void enetc_setup_cbdr(struct enetc_hw *hw, struct enetc_cbdr *cbdr)
10331033
cbdr->cir = hw->reg + ENETC_SICBDRCIR;
10341034
}
10351035

1036-
static void enetc_clear_cbdr(struct enetc_hw *hw)
1036+
void enetc_clear_cbdr(struct enetc_hw *hw)
10371037
{
10381038
enetc_wr(hw, ENETC_SICBDRMR, 0);
10391039
}

drivers/net/ethernet/freescale/enetc/enetc.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,10 @@ int enetc_setup_tc(struct net_device *ndev, enum tc_setup_type type,
310310
void enetc_set_ethtool_ops(struct net_device *ndev);
311311

312312
/* control buffer descriptor ring (CBDR) */
313+
int enetc_alloc_cbdr(struct device *dev, struct enetc_cbdr *cbdr);
314+
void enetc_free_cbdr(struct device *dev, struct enetc_cbdr *cbdr);
315+
void enetc_setup_cbdr(struct enetc_hw *hw, struct enetc_cbdr *cbdr);
316+
void enetc_clear_cbdr(struct enetc_hw *hw);
313317
int enetc_set_mac_flt_entry(struct enetc_si *si, int index,
314318
char *mac_addr, int si_map);
315319
int enetc_clear_mac_flt_entry(struct enetc_si *si, int index);

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

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,6 +1041,26 @@ static int enetc_init_port_rss_memory(struct enetc_si *si)
10411041
return err;
10421042
}
10431043

1044+
static void enetc_init_unused_port(struct enetc_si *si)
1045+
{
1046+
struct device *dev = &si->pdev->dev;
1047+
struct enetc_hw *hw = &si->hw;
1048+
int err;
1049+
1050+
si->cbd_ring.bd_count = ENETC_CBDR_DEFAULT_SIZE;
1051+
err = enetc_alloc_cbdr(dev, &si->cbd_ring);
1052+
if (err)
1053+
return;
1054+
1055+
enetc_setup_cbdr(hw, &si->cbd_ring);
1056+
1057+
enetc_init_port_rfs_memory(si);
1058+
enetc_init_port_rss_memory(si);
1059+
1060+
enetc_clear_cbdr(hw);
1061+
enetc_free_cbdr(dev, &si->cbd_ring);
1062+
}
1063+
10441064
static int enetc_pf_probe(struct pci_dev *pdev,
10451065
const struct pci_device_id *ent)
10461066
{
@@ -1051,11 +1071,6 @@ static int enetc_pf_probe(struct pci_dev *pdev,
10511071
struct enetc_pf *pf;
10521072
int err;
10531073

1054-
if (node && !of_device_is_available(node)) {
1055-
dev_info(&pdev->dev, "device is disabled, skipping\n");
1056-
return -ENODEV;
1057-
}
1058-
10591074
err = enetc_pci_probe(pdev, KBUILD_MODNAME, sizeof(*pf));
10601075
if (err) {
10611076
dev_err(&pdev->dev, "PCI probing failed\n");
@@ -1069,6 +1084,13 @@ static int enetc_pf_probe(struct pci_dev *pdev,
10691084
goto err_map_pf_space;
10701085
}
10711086

1087+
if (node && !of_device_is_available(node)) {
1088+
enetc_init_unused_port(si);
1089+
dev_info(&pdev->dev, "device is disabled, skipping\n");
1090+
err = -ENODEV;
1091+
goto err_device_disabled;
1092+
}
1093+
10721094
pf = enetc_si_priv(si);
10731095
pf->si = si;
10741096
pf->total_vfs = pci_sriov_get_totalvfs(pdev);
@@ -1151,6 +1173,7 @@ static int enetc_pf_probe(struct pci_dev *pdev,
11511173
si->ndev = NULL;
11521174
free_netdev(ndev);
11531175
err_alloc_netdev:
1176+
err_device_disabled:
11541177
err_map_pf_space:
11551178
enetc_pci_remove(pdev);
11561179

0 commit comments

Comments
 (0)