Skip to content

Commit 07bf34a

Browse files
vladimirolteankuba-moo
authored andcommitted
net: enetc: initialize the RFS and RSS memories
Michael tried to enable Advanced Error Reporting through the ENETC's Root Complex Event Collector, and the system started spitting out single bit correctable ECC errors coming from the ENETC interfaces: pcieport 0000:00:1f.0: AER: Multiple Corrected error received: 0000:00:00.0 fsl_enetc 0000:00:00.0: PCIe Bus Error: severity=Corrected, type=Transaction Layer, (Receiver ID) fsl_enetc 0000:00:00.0: device [1957:e100] error status/mask=00004000/00000000 fsl_enetc 0000:00:00.0: [14] CorrIntErr fsl_enetc 0000:00:00.1: PCIe Bus Error: severity=Corrected, type=Transaction Layer, (Receiver ID) fsl_enetc 0000:00:00.1: device [1957:e100] error status/mask=00004000/00000000 fsl_enetc 0000:00:00.1: [14] CorrIntErr Further investigating the port correctable memory error detect register (PCMEDR) shows that these AER errors have an associated SOURCE_ID of 6 (RFS/RSS): $ devmem 0x1f8010e10 32 0xC0000006 $ devmem 0x1f8050e10 32 0xC0000006 Discussion with the hardware design engineers reveals that on LS1028A, the hardware does not do initialization of that RFS/RSS memory, and that software should clear/initialize the entire table before starting to operate. That comes as a bit of a surprise, since the driver does not do initialization of the RFS memory. Also, the initialization of the Receive Side Scaling is done only partially. Even though the entire ENETC IP has a single shared flow steering memory, the flow steering service should returns matches only for TCAM entries that are within the range of the Station Interface that is doing the search. Therefore, it should be sufficient for a Station Interface to initialize all of its own entries in order to avoid any ECC errors, and only the Station Interfaces in use should need initialization. There are Physical Station Interfaces associated with PCIe PFs and Virtual Station Interfaces associated with PCIe VFs. We let the PF driver initialize the entire port's memory, which includes the RFS entries which are going to be used by the VF. Reported-by: Michael Walle <michael@walle.cc> Fixes: d4fd040 ("enetc: Introduce basic PF and VF ENETC ethernet drivers") Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Tested-by: Michael Walle <michael@walle.cc> Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com> Link: https://lore.kernel.org/r/20210204134511.2640309-1-vladimir.oltean@nxp.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 12bc8df commit 07bf34a

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,8 @@ enum enetc_bdr_type {TX, RX};
196196
#define ENETC_CBS_BW_MASK GENMASK(6, 0)
197197
#define ENETC_PTCCBSR1(n) (0x1114 + (n) * 8) /* n = 0 to 7*/
198198
#define ENETC_RSSHASH_KEY_SIZE 40
199+
#define ENETC_PRSSCAPR 0x1404
200+
#define ENETC_PRSSCAPR_GET_NUM_RSS(val) (BIT((val) & 0xf) * 32)
199201
#define ENETC_PRSSK(n) (0x1410 + (n) * 4) /* n = [0..9] */
200202
#define ENETC_PSIVLANFMR 0x1700
201203
#define ENETC_PSIVLANFMR_VS BIT(0)

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

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -996,6 +996,51 @@ static void enetc_phylink_destroy(struct enetc_ndev_priv *priv)
996996
phylink_destroy(priv->phylink);
997997
}
998998

999+
/* Initialize the entire shared memory for the flow steering entries
1000+
* of this port (PF + VFs)
1001+
*/
1002+
static int enetc_init_port_rfs_memory(struct enetc_si *si)
1003+
{
1004+
struct enetc_cmd_rfse rfse = {0};
1005+
struct enetc_hw *hw = &si->hw;
1006+
int num_rfs, i, err = 0;
1007+
u32 val;
1008+
1009+
val = enetc_port_rd(hw, ENETC_PRFSCAPR);
1010+
num_rfs = ENETC_PRFSCAPR_GET_NUM_RFS(val);
1011+
1012+
for (i = 0; i < num_rfs; i++) {
1013+
err = enetc_set_fs_entry(si, &rfse, i);
1014+
if (err)
1015+
break;
1016+
}
1017+
1018+
return err;
1019+
}
1020+
1021+
static int enetc_init_port_rss_memory(struct enetc_si *si)
1022+
{
1023+
struct enetc_hw *hw = &si->hw;
1024+
int num_rss, err;
1025+
int *rss_table;
1026+
u32 val;
1027+
1028+
val = enetc_port_rd(hw, ENETC_PRSSCAPR);
1029+
num_rss = ENETC_PRSSCAPR_GET_NUM_RSS(val);
1030+
if (!num_rss)
1031+
return 0;
1032+
1033+
rss_table = kcalloc(num_rss, sizeof(*rss_table), GFP_KERNEL);
1034+
if (!rss_table)
1035+
return -ENOMEM;
1036+
1037+
err = enetc_set_rss_table(si, rss_table, num_rss);
1038+
1039+
kfree(rss_table);
1040+
1041+
return err;
1042+
}
1043+
9991044
static int enetc_pf_probe(struct pci_dev *pdev,
10001045
const struct pci_device_id *ent)
10011046
{
@@ -1051,6 +1096,18 @@ static int enetc_pf_probe(struct pci_dev *pdev,
10511096
goto err_alloc_si_res;
10521097
}
10531098

1099+
err = enetc_init_port_rfs_memory(si);
1100+
if (err) {
1101+
dev_err(&pdev->dev, "Failed to initialize RFS memory\n");
1102+
goto err_init_port_rfs;
1103+
}
1104+
1105+
err = enetc_init_port_rss_memory(si);
1106+
if (err) {
1107+
dev_err(&pdev->dev, "Failed to initialize RSS memory\n");
1108+
goto err_init_port_rss;
1109+
}
1110+
10541111
err = enetc_alloc_msix(priv);
10551112
if (err) {
10561113
dev_err(&pdev->dev, "MSIX alloc failed\n");
@@ -1079,6 +1136,8 @@ static int enetc_pf_probe(struct pci_dev *pdev,
10791136
enetc_mdiobus_destroy(pf);
10801137
err_mdiobus_create:
10811138
enetc_free_msix(priv);
1139+
err_init_port_rss:
1140+
err_init_port_rfs:
10821141
err_alloc_msix:
10831142
enetc_free_si_resources(priv);
10841143
err_alloc_si_res:

0 commit comments

Comments
 (0)