summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSerge Semin <fancer.lancer@gmail.com>2025-09-08 18:56:40 +0300
committerSerge Semin <fancer.lancer@gmail.com>2026-08-13 20:34:12 +0300
commit5eeb71f19acb81724c6ba962bd32e599691b4faf (patch)
treea85d574290623de932db0595da2a9596aaef8b92
parent7af0d9110c1cb46f69add1b36d7b2327ba03b688 (diff)
downloadlinux-5eeb71f19acb81724c6ba962bd32e599691b4faf.tar.gz
linux-5eeb71f19acb81724c6ba962bd32e599691b4faf.zip
net: stmmac: vlan: Report correct number of Ext VLAN filters
The amount of the Extended Rx Perfect Filter slots is reported via the FEATURE3.NRVF field on the DW IP-core supporting that features: DW QoS Ether and DW XGMAC/XLGMAC/etc. The field encrypts the size of the filter as follows: - 000: No Extended Rx VLAN Filters - 001: 4 Extended Rx VLAN Filters - 010: 8 Extended Rx VLAN Filters - 011: 16 Extended Rx VLAN Filters - 100: 24 Extended Rx VLAN Filters - 101: 32 Extended Rx VLAN Filters - 110-111: Reserved In the meantime the dma_cap DebugFS node incorrectly decrypts the field as (nrvf << 1) and only for the DW XGMAC IP-core. Let's fix that by appropriately parsing the FEATURE3.NRVF field on the both IP-cores supporting the Extended Rx Perfect Filter feature. Fixes: ed64639bc1e0 ("net: stmmac: Add support for VLAN Rx filtering") Fixes: 669a55560e4b ("net: stmmac: Check more MAC HW features for XGMAC Core 3.20") Signed-off-by: Serge Semin <fancer.lancer@gmail.com>
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c17
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c16
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c5
3 files changed, 35 insertions, 3 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
index 93e9c636d86c..a75206682c41 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
@@ -485,6 +485,23 @@ static int dwmac4_get_hw_feature(void __iomem *ioaddr,
dma_cap->frpsel = (hw_cap & GMAC_HW_FEAT_FRPSEL) >> 10;
dma_cap->dvlan = (hw_cap & GMAC_HW_FEAT_DVLAN) >> 5;
+ /* Number of Extended VLAN Tag Filters */
+ dma_cap->nrvf_num = (hw_cap & GMAC_HW_FEAT_NRVF) >> 0;
+ switch (dma_cap->nrvf_num) {
+ case 1 ... 3:
+ dma_cap->nrvf_num = 1 << (dma_cap->nrvf_num + 1);
+ break;
+ case 4:
+ dma_cap->nrvf_num = 24;
+ break;
+ case 5:
+ dma_cap->nrvf_num = 32;
+ break;
+ default:
+ dma_cap->nrvf_num = 0;
+ break;
+ }
+
return 0;
}
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
index 6b2362910285..a50f79a47266 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
@@ -499,7 +499,23 @@ static int dwxgmac2_get_hw_feature(void __iomem *ioaddr,
dma_cap->frppipe_num = ((hw_cap & XGMAC_HWFEAT_FRPPIPE) >> 5) + 1;
dma_cap->cbtisel = (hw_cap & XGMAC_HWFEAT_CBTISEL) >> 4;
dma_cap->frpsel = (hw_cap & XGMAC_HWFEAT_FRPSEL) >> 3;
+
+ /* Number of Extended VLAN Tag Filters */
dma_cap->nrvf_num = (hw_cap & XGMAC_HWFEAT_NRVF) >> 0;
+ switch (dma_cap->nrvf_num) {
+ case 1 ... 3:
+ dma_cap->nrvf_num = 1 << (dma_cap->nrvf_num + 1);
+ break;
+ case 4:
+ dma_cap->nrvf_num = 24;
+ break;
+ case 5:
+ dma_cap->nrvf_num = 32;
+ break;
+ default:
+ dma_cap->nrvf_num = 0;
+ break;
+ }
/* MAC HW feature 4 */
hw_cap = readl(ioaddr + XGMAC_HW_FEATURE4);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index a23e9e3a05ea..921aa3231d2d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -7025,9 +7025,8 @@ static int stmmac_dma_cap_show(struct seq_file *seq, void *v)
BIT(priv->dma_cap.frpbs) << 6);
seq_printf(seq, "\tParallel Instruction Processor Engines: %d\n",
priv->dma_cap.frppipe_num);
- seq_printf(seq, "\tNumber of Extended VLAN Tag Filters: %lu\n",
- priv->dma_cap.nrvf_num ?
- (BIT(priv->dma_cap.nrvf_num) << 1) : 0);
+ seq_printf(seq, "\tNumber of Extended VLAN Tag Filters: %u\n",
+ priv->dma_cap.nrvf_num);
seq_printf(seq, "\tWidth of the Time Interval Field in GCL: %d\n",
priv->dma_cap.estwid ? 4 * priv->dma_cap.estwid + 12 : 0);
seq_printf(seq, "\tDepth of GCL: %lu\n",