mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-19 13:48:06 +00:00
kernel: add more fixes for mtk_eth_soc
Fix corner cases in DSA offload Add refcounting fix for flow offload Fix VLAN untagging issue on MT7986 Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
parent
0d375de10d
commit
9b482ee22f
@ -12,11 +12,12 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
--- a/net/core/flow_dissector.c
|
||||
+++ b/net/core/flow_dissector.c
|
||||
@@ -941,11 +941,13 @@ bool __skb_flow_dissect(const struct net
|
||||
@@ -940,12 +940,14 @@ bool __skb_flow_dissect(const struct net
|
||||
#if IS_ENABLED(CONFIG_NET_DSA)
|
||||
if (unlikely(skb->dev && netdev_uses_dsa(skb->dev) &&
|
||||
proto == htons(ETH_P_XDSA))) {
|
||||
const struct dsa_device_ops *ops;
|
||||
+ struct metadata_dst *md_dst = skb_metadata_dst(skb);
|
||||
const struct dsa_device_ops *ops;
|
||||
int offset = 0;
|
||||
|
||||
ops = skb->dev->dsa_ptr->tag_ops;
|
||||
@ -53,7 +54,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
+ if (md_dst && md_dst->type == METADATA_HW_PORT_MUX) {
|
||||
+ unsigned int port = md_dst->u.port_info.port_id;
|
||||
+
|
||||
+ skb_dst_set(skb, NULL);
|
||||
+ skb_dst_drop(skb);
|
||||
+ if (!skb_has_extensions(skb))
|
||||
+ skb->slow_gro = 0;
|
||||
+
|
||||
|
@ -109,7 +109,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
- int err;
|
||||
+ int i, err;
|
||||
+
|
||||
+ if (mtk_uses_dsa(dev)) {
|
||||
+ if (mtk_uses_dsa(dev) && !eth->prog) {
|
||||
+ for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) {
|
||||
+ struct metadata_dst *md_dst = eth->dsa_meta[i];
|
||||
+
|
||||
|
@ -0,0 +1,52 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Thu, 17 Nov 2022 11:58:21 +0100
|
||||
Subject: [PATCH] net: ethernet: mtk_eth_soc: fix flow_offload related refcount
|
||||
bug
|
||||
|
||||
Since we call flow_block_cb_decref on FLOW_BLOCK_UNBIND, we need to call
|
||||
flow_block_cb_incref unconditionally, even for a newly allocated cb.
|
||||
Fixes a use-after-free bug
|
||||
|
||||
Fixes: 502e84e2382d ("net: ethernet: mtk_eth_soc: add flow offloading support")
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
|
||||
@@ -561,6 +561,7 @@ mtk_eth_setup_tc_block(struct net_device
|
||||
struct mtk_eth *eth = mac->hw;
|
||||
static LIST_HEAD(block_cb_list);
|
||||
struct flow_block_cb *block_cb;
|
||||
+ bool register_block = false;
|
||||
flow_setup_cb_t *cb;
|
||||
|
||||
if (!eth->soc->offload_version)
|
||||
@@ -575,16 +576,20 @@ mtk_eth_setup_tc_block(struct net_device
|
||||
switch (f->command) {
|
||||
case FLOW_BLOCK_BIND:
|
||||
block_cb = flow_block_cb_lookup(f->block, cb, dev);
|
||||
- if (block_cb) {
|
||||
- flow_block_cb_incref(block_cb);
|
||||
- return 0;
|
||||
+ if (!block_cb) {
|
||||
+ block_cb = flow_block_cb_alloc(cb, dev, dev, NULL);
|
||||
+ if (IS_ERR(block_cb))
|
||||
+ return PTR_ERR(block_cb);
|
||||
+
|
||||
+ register_block = true;
|
||||
}
|
||||
- block_cb = flow_block_cb_alloc(cb, dev, dev, NULL);
|
||||
- if (IS_ERR(block_cb))
|
||||
- return PTR_ERR(block_cb);
|
||||
|
||||
- flow_block_cb_add(block_cb, f);
|
||||
- list_add_tail(&block_cb->driver_list, &block_cb_list);
|
||||
+ flow_block_cb_incref(block_cb);
|
||||
+
|
||||
+ if (register_block) {
|
||||
+ flow_block_cb_add(block_cb, f);
|
||||
+ list_add_tail(&block_cb->driver_list, &block_cb_list);
|
||||
+ }
|
||||
return 0;
|
||||
case FLOW_BLOCK_UNBIND:
|
||||
block_cb = flow_block_cb_lookup(f->block, cb, dev);
|
@ -0,0 +1,193 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Sun, 20 Nov 2022 23:01:00 +0100
|
||||
Subject: [PATCH] net: ethernet: mtk_eth_soc: drop generic vlan rx offload,
|
||||
only use DSA untagging
|
||||
|
||||
Through testing I found out that hardware vlan rx offload support seems to
|
||||
have some hardware issues. At least when using multiple MACs and when receiving
|
||||
tagged packets on the secondary MAC, the hardware can sometimes start to emit
|
||||
wrong tags on the first MAC as well.
|
||||
|
||||
In order to avoid such issues, drop the feature configuration and use the
|
||||
offload feature only for DSA hardware untagging on MT7621/MT7622 devices which
|
||||
only use one MAC.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -1993,29 +1993,16 @@ static int mtk_poll_rx(struct napi_struc
|
||||
if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
|
||||
mtk_ppe_check_skb(eth->ppe[0], skb, hash);
|
||||
|
||||
- if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) {
|
||||
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
|
||||
- if (trxd.rxd3 & RX_DMA_VTAG_V2)
|
||||
- __vlan_hwaccel_put_tag(skb,
|
||||
- htons(RX_DMA_VPID(trxd.rxd4)),
|
||||
- RX_DMA_VID(trxd.rxd4));
|
||||
- } else if (trxd.rxd2 & RX_DMA_VTAG) {
|
||||
- __vlan_hwaccel_put_tag(skb, htons(RX_DMA_VPID(trxd.rxd3)),
|
||||
- RX_DMA_VID(trxd.rxd3));
|
||||
- }
|
||||
- }
|
||||
-
|
||||
/* When using VLAN untagging in combination with DSA, the
|
||||
* hardware treats the MTK special tag as a VLAN and untags it.
|
||||
*/
|
||||
- if (skb_vlan_tag_present(skb) && netdev_uses_dsa(netdev)) {
|
||||
- unsigned int port = ntohs(skb->vlan_proto) & GENMASK(2, 0);
|
||||
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) &&
|
||||
+ (trxd.rxd2 & RX_DMA_VTAG) && netdev_uses_dsa(netdev)) {
|
||||
+ unsigned int port = RX_DMA_VPID(trxd.rxd3) & GENMASK(2, 0);
|
||||
|
||||
if (port < ARRAY_SIZE(eth->dsa_meta) &&
|
||||
eth->dsa_meta[port])
|
||||
skb_dst_set_noref(skb, ð->dsa_meta[port]->dst);
|
||||
-
|
||||
- __vlan_hwaccel_clear_tag(skb);
|
||||
}
|
||||
|
||||
skb_record_rx_queue(skb, 0);
|
||||
@@ -2832,29 +2819,11 @@ static netdev_features_t mtk_fix_feature
|
||||
|
||||
static int mtk_set_features(struct net_device *dev, netdev_features_t features)
|
||||
{
|
||||
- struct mtk_mac *mac = netdev_priv(dev);
|
||||
- struct mtk_eth *eth = mac->hw;
|
||||
netdev_features_t diff = dev->features ^ features;
|
||||
- int i;
|
||||
|
||||
if ((diff & NETIF_F_LRO) && !(features & NETIF_F_LRO))
|
||||
mtk_hwlro_netdev_disable(dev);
|
||||
|
||||
- /* Set RX VLAN offloading */
|
||||
- if (!(diff & NETIF_F_HW_VLAN_CTAG_RX))
|
||||
- return 0;
|
||||
-
|
||||
- mtk_w32(eth, !!(features & NETIF_F_HW_VLAN_CTAG_RX),
|
||||
- MTK_CDMP_EG_CTRL);
|
||||
-
|
||||
- /* sync features with other MAC */
|
||||
- for (i = 0; i < MTK_MAC_COUNT; i++) {
|
||||
- if (!eth->netdev[i] || eth->netdev[i] == dev)
|
||||
- continue;
|
||||
- eth->netdev[i]->features &= ~NETIF_F_HW_VLAN_CTAG_RX;
|
||||
- eth->netdev[i]->features |= features & NETIF_F_HW_VLAN_CTAG_RX;
|
||||
- }
|
||||
-
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3153,30 +3122,6 @@ static int mtk_open(struct net_device *d
|
||||
struct mtk_eth *eth = mac->hw;
|
||||
int i, err;
|
||||
|
||||
- if (mtk_uses_dsa(dev) && !eth->prog) {
|
||||
- for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) {
|
||||
- struct metadata_dst *md_dst = eth->dsa_meta[i];
|
||||
-
|
||||
- if (md_dst)
|
||||
- continue;
|
||||
-
|
||||
- md_dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX,
|
||||
- GFP_KERNEL);
|
||||
- if (!md_dst)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- md_dst->u.port_info.port_id = i;
|
||||
- eth->dsa_meta[i] = md_dst;
|
||||
- }
|
||||
- } else {
|
||||
- /* Hardware special tag parsing needs to be disabled if at least
|
||||
- * one MAC does not use DSA.
|
||||
- */
|
||||
- u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
|
||||
- val &= ~MTK_CDMP_STAG_EN;
|
||||
- mtk_w32(eth, val, MTK_CDMP_IG_CTRL);
|
||||
- }
|
||||
-
|
||||
err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0);
|
||||
if (err) {
|
||||
netdev_err(dev, "%s: could not attach PHY: %d\n", __func__,
|
||||
@@ -3215,6 +3160,39 @@ static int mtk_open(struct net_device *d
|
||||
phylink_start(mac->phylink);
|
||||
netif_tx_start_all_queues(dev);
|
||||
|
||||
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
|
||||
+ return 0;
|
||||
+
|
||||
+ if (mtk_uses_dsa(dev) && !eth->prog) {
|
||||
+ for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) {
|
||||
+ struct metadata_dst *md_dst = eth->dsa_meta[i];
|
||||
+
|
||||
+ if (md_dst)
|
||||
+ continue;
|
||||
+
|
||||
+ md_dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX,
|
||||
+ GFP_KERNEL);
|
||||
+ if (!md_dst)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ md_dst->u.port_info.port_id = i;
|
||||
+ eth->dsa_meta[i] = md_dst;
|
||||
+ }
|
||||
+ } else {
|
||||
+ /* Hardware special tag parsing needs to be disabled if at least
|
||||
+ * one MAC does not use DSA.
|
||||
+ */
|
||||
+ u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
|
||||
+ val &= ~MTK_CDMP_STAG_EN;
|
||||
+ mtk_w32(eth, val, MTK_CDMP_IG_CTRL);
|
||||
+
|
||||
+ val = mtk_r32(eth, MTK_CDMQ_IG_CTRL);
|
||||
+ val &= ~MTK_CDMQ_STAG_EN;
|
||||
+ mtk_w32(eth, val, MTK_CDMQ_IG_CTRL);
|
||||
+
|
||||
+ mtk_w32(eth, 0, MTK_CDMP_EG_CTRL);
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3503,15 +3481,15 @@ static int mtk_hw_init(struct mtk_eth *e
|
||||
/* Indicates CDM to parse the MTK special tag from CPU
|
||||
* which also is working out for untag packets.
|
||||
*/
|
||||
- val = mtk_r32(eth, MTK_CDMQ_IG_CTRL);
|
||||
- mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL);
|
||||
if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
|
||||
+ val = mtk_r32(eth, MTK_CDMQ_IG_CTRL);
|
||||
+ mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL);
|
||||
+
|
||||
val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
|
||||
mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL);
|
||||
- }
|
||||
|
||||
- /* Enable RX VLan Offloading */
|
||||
- mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
|
||||
+ mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
|
||||
+ }
|
||||
|
||||
/* set interrupt delays based on current Net DIM sample */
|
||||
mtk_dim_rx(ð->rx_dim.work);
|
||||
@@ -4132,7 +4110,7 @@ static int mtk_add_mac(struct mtk_eth *e
|
||||
eth->netdev[id]->hw_features |= NETIF_F_LRO;
|
||||
|
||||
eth->netdev[id]->vlan_features = eth->soc->hw_features &
|
||||
- ~(NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX);
|
||||
+ ~NETIF_F_HW_VLAN_CTAG_TX;
|
||||
eth->netdev[id]->features |= eth->soc->hw_features;
|
||||
eth->netdev[id]->ethtool_ops = &mtk_ethtool_ops;
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -48,7 +48,6 @@
|
||||
#define MTK_HW_FEATURES (NETIF_F_IP_CSUM | \
|
||||
NETIF_F_RXCSUM | \
|
||||
NETIF_F_HW_VLAN_CTAG_TX | \
|
||||
- NETIF_F_HW_VLAN_CTAG_RX | \
|
||||
NETIF_F_SG | NETIF_F_ALL_TSO | \
|
||||
NETIF_F_IPV6_CSUM |\
|
||||
NETIF_F_HW_TC)
|
@ -113,7 +113,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -356,9 +356,12 @@
|
||||
@@ -355,9 +355,12 @@
|
||||
#define PHY_IAC_ADDR_MASK GENMASK(24, 20)
|
||||
#define PHY_IAC_ADDR(x) FIELD_PREP(PHY_IAC_ADDR_MASK, (x))
|
||||
#define PHY_IAC_CMD_MASK GENMASK(19, 18)
|
||||
|
Loading…
Reference in New Issue
Block a user