diff options
Diffstat (limited to 'target')
37 files changed, 2202 insertions, 104 deletions
diff --git a/target/linux/generic/pending-5.15/733-01-net-ethernet-mtk_wed-introduce-wed-mcu-support.patch b/target/linux/generic/backport-5.15/729-01-v6.1-net-ethernet-mtk_wed-introduce-wed-mcu-support.patch index c48613929d..c48613929d 100644 --- a/target/linux/generic/pending-5.15/733-01-net-ethernet-mtk_wed-introduce-wed-mcu-support.patch +++ b/target/linux/generic/backport-5.15/729-01-v6.1-net-ethernet-mtk_wed-introduce-wed-mcu-support.patch diff --git a/target/linux/generic/pending-5.15/733-02-net-ethernet-mtk_wed-introduce-wed-wo-support.patch b/target/linux/generic/backport-5.15/729-02-v6.1-net-ethernet-mtk_wed-introduce-wed-wo-support.patch index dbd7e30fbb..dbd7e30fbb 100644 --- a/target/linux/generic/pending-5.15/733-02-net-ethernet-mtk_wed-introduce-wed-wo-support.patch +++ b/target/linux/generic/backport-5.15/729-02-v6.1-net-ethernet-mtk_wed-introduce-wed-wo-support.patch diff --git a/target/linux/generic/pending-5.15/733-03-net-ethernet-mtk_wed-rename-tx_wdma-array-in-rx_wdma.patch b/target/linux/generic/backport-5.15/729-03-v6.1-net-ethernet-mtk_wed-rename-tx_wdma-array-in-rx_wdma.patch index ffd6bc3589..ffd6bc3589 100644 --- a/target/linux/generic/pending-5.15/733-03-net-ethernet-mtk_wed-rename-tx_wdma-array-in-rx_wdma.patch +++ b/target/linux/generic/backport-5.15/729-03-v6.1-net-ethernet-mtk_wed-rename-tx_wdma-array-in-rx_wdma.patch diff --git a/target/linux/generic/pending-5.15/733-04-net-ethernet-mtk_wed-add-configure-wed-wo-support.patch b/target/linux/generic/backport-5.15/729-04-v6.1-net-ethernet-mtk_wed-add-configure-wed-wo-support.patch index 4c34d0cb33..4c34d0cb33 100644 --- a/target/linux/generic/pending-5.15/733-04-net-ethernet-mtk_wed-add-configure-wed-wo-support.patch +++ b/target/linux/generic/backport-5.15/729-04-v6.1-net-ethernet-mtk_wed-add-configure-wed-wo-support.patch diff --git a/target/linux/generic/pending-5.15/733-05-net-ethernet-mtk_wed-add-rx-mib-counters.patch b/target/linux/generic/backport-5.15/729-05-v6.1-net-ethernet-mtk_wed-add-rx-mib-counters.patch index bb1066dece..bb1066dece 100644 --- a/target/linux/generic/pending-5.15/733-05-net-ethernet-mtk_wed-add-rx-mib-counters.patch +++ b/target/linux/generic/backport-5.15/729-05-v6.1-net-ethernet-mtk_wed-add-rx-mib-counters.patch diff --git a/target/linux/generic/backport-5.15/729-06-v6.1-net-ethernet-mtk_eth_soc-do-not-overwrite-mtu-config.patch b/target/linux/generic/backport-5.15/729-06-v6.1-net-ethernet-mtk_eth_soc-do-not-overwrite-mtu-config.patch new file mode 100644 index 0000000000..f9e7caa27c --- /dev/null +++ b/target/linux/generic/backport-5.15/729-06-v6.1-net-ethernet-mtk_eth_soc-do-not-overwrite-mtu-config.patch @@ -0,0 +1,98 @@ +From: Lorenzo Bianconi <lorenzo@kernel.org> +Date: Thu, 17 Nov 2022 00:35:04 +0100 +Subject: [PATCH] net: ethernet: mtk_eth_soc: do not overwrite mtu + configuration running reset routine + +Restore user configured MTU running mtk_hw_init() during tx timeout routine +since it will be overwritten after a hw reset. + +Reported-by: Felix Fietkau <nbd@nbd.name> +Fixes: 9ea4d311509f ("net: ethernet: mediatek: add the whole ethernet reset into the reset process") +Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -3175,6 +3175,30 @@ static void mtk_dim_tx(struct work_struc + dim->state = DIM_START_MEASURE; + } + ++static void mtk_set_mcr_max_rx(struct mtk_mac *mac, u32 val) ++{ ++ struct mtk_eth *eth = mac->hw; ++ u32 mcr_cur, mcr_new; ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) ++ return; ++ ++ mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id)); ++ mcr_new = mcr_cur & ~MAC_MCR_MAX_RX_MASK; ++ ++ if (val <= 1518) ++ mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1518); ++ else if (val <= 1536) ++ mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1536); ++ else if (val <= 1552) ++ mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1552); ++ else ++ mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_2048); ++ ++ if (mcr_new != mcr_cur) ++ mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id)); ++} ++ + static int mtk_hw_init(struct mtk_eth *eth) + { + u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA | +@@ -3249,8 +3273,16 @@ static int mtk_hw_init(struct mtk_eth *e + * up with the more appropriate value when mtk_mac_config call is being + * invoked. + */ +- for (i = 0; i < MTK_MAC_COUNT; i++) ++ for (i = 0; i < MTK_MAC_COUNT; i++) { ++ struct net_device *dev = eth->netdev[i]; ++ + mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i)); ++ if (dev) { ++ struct mtk_mac *mac = netdev_priv(dev); ++ ++ mtk_set_mcr_max_rx(mac, dev->mtu + MTK_RX_ETH_HLEN); ++ } ++ } + + /* Indicates CDM to parse the MTK special tag from CPU + * which also is working out for untag packets. +@@ -3366,7 +3398,6 @@ static int mtk_change_mtu(struct net_dev + int length = new_mtu + MTK_RX_ETH_HLEN; + struct mtk_mac *mac = netdev_priv(dev); + struct mtk_eth *eth = mac->hw; +- u32 mcr_cur, mcr_new; + + if (rcu_access_pointer(eth->prog) && + length > MTK_PP_MAX_BUF_SIZE) { +@@ -3374,23 +3405,7 @@ static int mtk_change_mtu(struct net_dev + return -EINVAL; + } + +- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) { +- mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id)); +- mcr_new = mcr_cur & ~MAC_MCR_MAX_RX_MASK; +- +- if (length <= 1518) +- mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1518); +- else if (length <= 1536) +- mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1536); +- else if (length <= 1552) +- mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1552); +- else +- mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_2048); +- +- if (mcr_new != mcr_cur) +- mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id)); +- } +- ++ mtk_set_mcr_max_rx(mac, length); + dev->mtu = new_mtu; + + return 0; diff --git a/target/linux/generic/backport-5.15/729-07-v6.1-net-ethernet-mtk_eth_soc-remove-cpu_relax-in-mtk_pen.patch b/target/linux/generic/backport-5.15/729-07-v6.1-net-ethernet-mtk_eth_soc-remove-cpu_relax-in-mtk_pen.patch new file mode 100644 index 0000000000..e51dd7b97a --- /dev/null +++ b/target/linux/generic/backport-5.15/729-07-v6.1-net-ethernet-mtk_eth_soc-remove-cpu_relax-in-mtk_pen.patch @@ -0,0 +1,36 @@ +From: Lorenzo Bianconi <lorenzo@kernel.org> +Date: Thu, 17 Nov 2022 00:58:46 +0100 +Subject: [PATCH] net: ethernet: mtk_eth_soc: remove cpu_relax in + mtk_pending_work + +Get rid of cpu_relax in mtk_pending_work routine since MTK_RESETTING is +set only in mtk_pending_work() and it runs holding rtnl lock + +Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -3436,11 +3436,8 @@ static void mtk_pending_work(struct work + rtnl_lock(); + + dev_dbg(eth->dev, "[%s][%d] reset\n", __func__, __LINE__); ++ set_bit(MTK_RESETTING, ð->state); + +- while (test_and_set_bit_lock(MTK_RESETTING, ð->state)) +- cpu_relax(); +- +- dev_dbg(eth->dev, "[%s][%d] mtk_stop starts\n", __func__, __LINE__); + /* stop all devices to make sure that dma is properly shut down */ + for (i = 0; i < MTK_MAC_COUNT; i++) { + if (!eth->netdev[i]) +@@ -3474,7 +3471,7 @@ static void mtk_pending_work(struct work + + dev_dbg(eth->dev, "[%s][%d] reset done\n", __func__, __LINE__); + +- clear_bit_unlock(MTK_RESETTING, ð->state); ++ clear_bit(MTK_RESETTING, ð->state); + + rtnl_unlock(); + } diff --git a/target/linux/generic/backport-5.15/729-08-v6.2-net-ethernet-mtk_eth_soc-fix-RSTCTRL_PPE-0-1-definit.patch b/target/linux/generic/backport-5.15/729-08-v6.2-net-ethernet-mtk_eth_soc-fix-RSTCTRL_PPE-0-1-definit.patch new file mode 100644 index 0000000000..69df58eed1 --- /dev/null +++ b/target/linux/generic/backport-5.15/729-08-v6.2-net-ethernet-mtk_eth_soc-fix-RSTCTRL_PPE-0-1-definit.patch @@ -0,0 +1,63 @@ +From: Lorenzo Bianconi <lorenzo@kernel.org> +Date: Thu, 17 Nov 2022 15:29:53 +0100 +Subject: [PATCH] net: ethernet: mtk_eth_soc: fix RSTCTRL_PPE{0,1} definitions + +Fix RSTCTRL_PPE0 and RSTCTRL_PPE1 register mask definitions for +MTK_NETSYS_V2. +Remove duplicated definitions. + +Fixes: 160d3a9b1929 ("net: ethernet: mtk_eth_soc: introduce MTK_NETSYS_V2 support") +Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -3238,16 +3238,17 @@ static int mtk_hw_init(struct mtk_eth *e + return 0; + } + +- val = RSTCTRL_FE | RSTCTRL_PPE; + if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { + regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0); +- +- val |= RSTCTRL_ETH; +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) +- val |= RSTCTRL_PPE1; ++ val = RSTCTRL_PPE0_V2; ++ } else { ++ val = RSTCTRL_PPE0; + } + +- ethsys_reset(eth, val); ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) ++ val |= RSTCTRL_PPE1; ++ ++ ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val); + + if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { + regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -444,18 +444,14 @@ + /* ethernet reset control register */ + #define ETHSYS_RSTCTRL 0x34 + #define RSTCTRL_FE BIT(6) +-#define RSTCTRL_PPE BIT(31) +-#define RSTCTRL_PPE1 BIT(30) ++#define RSTCTRL_PPE0 BIT(31) ++#define RSTCTRL_PPE0_V2 BIT(30) ++#define RSTCTRL_PPE1 BIT(31) + #define RSTCTRL_ETH BIT(23) + + /* ethernet reset check idle register */ + #define ETHSYS_FE_RST_CHK_IDLE_EN 0x28 + +-/* ethernet reset control register */ +-#define ETHSYS_RSTCTRL 0x34 +-#define RSTCTRL_FE BIT(6) +-#define RSTCTRL_PPE BIT(31) +- + /* ethernet dma channel agent map */ + #define ETHSYS_DMA_AG_MAP 0x408 + #define ETHSYS_DMA_AG_MAP_PDMA BIT(0) diff --git a/target/linux/generic/backport-5.15/729-09-v6.2-net-ethernet-mtk_wed-add-wcid-overwritten-support-fo.patch b/target/linux/generic/backport-5.15/729-09-v6.2-net-ethernet-mtk_wed-add-wcid-overwritten-support-fo.patch new file mode 100644 index 0000000000..d91d829911 --- /dev/null +++ b/target/linux/generic/backport-5.15/729-09-v6.2-net-ethernet-mtk_wed-add-wcid-overwritten-support-fo.patch @@ -0,0 +1,80 @@ +From: Sujuan Chen <sujuan.chen@mediatek.com> +Date: Thu, 24 Nov 2022 11:18:14 +0800 +Subject: [PATCH] net: ethernet: mtk_wed: add wcid overwritten support for wed + v1 + +All wed versions should enable the wcid overwritten feature, +since the wcid size is controlled by the wlan driver. + +Tested-by: Sujuan Chen <sujuan.chen@mediatek.com> +Co-developed-by: Bo Jiao <bo.jiao@mediatek.com> +Signed-off-by: Bo Jiao <bo.jiao@mediatek.com> +Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -526,9 +526,9 @@ mtk_wed_dma_disable(struct mtk_wed_devic + MTK_WED_WPDMA_RX_D_RX_DRV_EN); + wed_clr(dev, MTK_WED_WDMA_GLO_CFG, + MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK); +- +- mtk_wed_set_512_support(dev, false); + } ++ ++ mtk_wed_set_512_support(dev, false); + } + + static void +@@ -1297,9 +1297,10 @@ mtk_wed_start(struct mtk_wed_device *dev + if (mtk_wed_rro_cfg(dev)) + return; + +- mtk_wed_set_512_support(dev, dev->wlan.wcid_512); + } + ++ mtk_wed_set_512_support(dev, dev->wlan.wcid_512); ++ + mtk_wed_dma_enable(dev); + dev->running = true; + } +@@ -1365,11 +1366,13 @@ mtk_wed_attach(struct mtk_wed_device *de + } + + mtk_wed_hw_init_early(dev); +- if (hw->version == 1) ++ if (hw->version == 1) { + regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, + BIT(hw->index), 0); +- else ++ } else { ++ dev->rev_id = wed_r32(dev, MTK_WED_REV_ID); + ret = mtk_wed_wo_init(hw); ++ } + out: + if (ret) + mtk_wed_detach(dev); +--- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h ++++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h +@@ -20,6 +20,8 @@ struct mtk_wdma_desc { + __le32 info; + } __packed __aligned(4); + ++#define MTK_WED_REV_ID 0x004 ++ + #define MTK_WED_RESET 0x008 + #define MTK_WED_RESET_TX_BM BIT(0) + #define MTK_WED_RESET_TX_FREE_AGENT BIT(4) +--- a/include/linux/soc/mediatek/mtk_wed.h ++++ b/include/linux/soc/mediatek/mtk_wed.h +@@ -85,6 +85,9 @@ struct mtk_wed_device { + int irq; + u8 version; + ++ /* used by wlan driver */ ++ u32 rev_id; ++ + struct mtk_wed_ring tx_ring[MTK_WED_TX_QUEUES]; + struct mtk_wed_ring rx_ring[MTK_WED_RX_QUEUES]; + struct mtk_wed_ring txfree_ring; diff --git a/target/linux/generic/backport-5.15/729-10-v6.2-net-ethernet-mtk_wed-return-status-value-in-mtk_wdma.patch b/target/linux/generic/backport-5.15/729-10-v6.2-net-ethernet-mtk_wed-return-status-value-in-mtk_wdma.patch new file mode 100644 index 0000000000..d97bb715e0 --- /dev/null +++ b/target/linux/generic/backport-5.15/729-10-v6.2-net-ethernet-mtk_wed-return-status-value-in-mtk_wdma.patch @@ -0,0 +1,85 @@ +From: Lorenzo Bianconi <lorenzo@kernel.org> +Date: Thu, 24 Nov 2022 16:22:51 +0100 +Subject: [PATCH] net: ethernet: mtk_wed: return status value in + mtk_wdma_rx_reset + +Move MTK_WDMA_RESET_IDX configuration in mtk_wdma_rx_reset routine. +Increase poll timeout to 10ms in order to be aligned with vendor sdk. +This is a preliminary patch to add Wireless Ethernet Dispatcher reset +support. + +Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com> +Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com> +Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> +Signed-off-by: Paolo Abeni <pabeni@redhat.com> +--- + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -101,17 +101,21 @@ mtk_wdma_read_reset(struct mtk_wed_devic + return wdma_r32(dev, MTK_WDMA_GLO_CFG); + } + +-static void ++static int + mtk_wdma_rx_reset(struct mtk_wed_device *dev) + { + u32 status, mask = MTK_WDMA_GLO_CFG_RX_DMA_BUSY; +- int i; ++ int i, ret; + + wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_RX_DMA_EN); +- if (readx_poll_timeout(mtk_wdma_read_reset, dev, status, +- !(status & mask), 0, 1000)) ++ ret = readx_poll_timeout(mtk_wdma_read_reset, dev, status, ++ !(status & mask), 0, 10000); ++ if (ret) + dev_err(dev->hw->dev, "rx reset failed\n"); + ++ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX); ++ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); ++ + for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++) { + if (dev->rx_wdma[i].desc) + continue; +@@ -119,6 +123,8 @@ mtk_wdma_rx_reset(struct mtk_wed_device + wdma_w32(dev, + MTK_WDMA_RING_RX(i) + MTK_WED_RING_OFS_CPU_IDX, 0); + } ++ ++ return ret; + } + + static void +@@ -565,9 +571,7 @@ mtk_wed_detach(struct mtk_wed_device *de + + mtk_wed_stop(dev); + +- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX); +- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); +- ++ mtk_wdma_rx_reset(dev); + mtk_wed_reset(dev, MTK_WED_RESET_WED); + if (mtk_wed_get_rx_capa(dev)) { + wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN); +@@ -582,7 +586,6 @@ mtk_wed_detach(struct mtk_wed_device *de + mtk_wed_wo_reset(dev); + mtk_wed_free_rx_rings(dev); + mtk_wed_wo_deinit(hw); +- mtk_wdma_rx_reset(dev); + } + + if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) { +@@ -1006,11 +1009,7 @@ mtk_wed_reset_dma(struct mtk_wed_device + wed_w32(dev, MTK_WED_RESET_IDX, 0); + } + +- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX); +- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); +- +- if (mtk_wed_get_rx_capa(dev)) +- mtk_wdma_rx_reset(dev); ++ mtk_wdma_rx_reset(dev); + + if (busy) { + mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT); diff --git a/target/linux/generic/backport-5.15/729-11-v6.2-net-ethernet-mtk_wed-move-MTK_WDMA_RESET_IDX_TX-conf.patch b/target/linux/generic/backport-5.15/729-11-v6.2-net-ethernet-mtk_wed-move-MTK_WDMA_RESET_IDX_TX-conf.patch new file mode 100644 index 0000000000..10c1732c96 --- /dev/null +++ b/target/linux/generic/backport-5.15/729-11-v6.2-net-ethernet-mtk_wed-move-MTK_WDMA_RESET_IDX_TX-conf.patch @@ -0,0 +1,52 @@ +From: Lorenzo Bianconi <lorenzo@kernel.org> +Date: Thu, 24 Nov 2022 16:22:52 +0100 +Subject: [PATCH] net: ethernet: mtk_wed: move MTK_WDMA_RESET_IDX_TX + configuration in mtk_wdma_tx_reset + +Remove duplicated code. Increase poll timeout to 10ms in order to be +aligned with vendor sdk. +This is a preliminary patch to add Wireless Ethernet Dispatcher reset +support. + +Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com> +Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com> +Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> +Signed-off-by: Paolo Abeni <pabeni@redhat.com> +--- + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -135,16 +135,15 @@ mtk_wdma_tx_reset(struct mtk_wed_device + + wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN); + if (readx_poll_timeout(mtk_wdma_read_reset, dev, status, +- !(status & mask), 0, 1000)) ++ !(status & mask), 0, 10000)) + dev_err(dev->hw->dev, "tx reset failed\n"); + +- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) { +- if (dev->tx_wdma[i].desc) +- continue; ++ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX); ++ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); + ++ for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) + wdma_w32(dev, + MTK_WDMA_RING_TX(i) + MTK_WED_RING_OFS_CPU_IDX, 0); +- } + } + + static void +@@ -573,12 +572,6 @@ mtk_wed_detach(struct mtk_wed_device *de + + mtk_wdma_rx_reset(dev); + mtk_wed_reset(dev, MTK_WED_RESET_WED); +- if (mtk_wed_get_rx_capa(dev)) { +- wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN); +- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX); +- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); +- } +- + mtk_wed_free_tx_buffer(dev); + mtk_wed_free_tx_rings(dev); + diff --git a/target/linux/generic/backport-5.15/729-12-v6.2-net-ethernet-mtk_wed-update-mtk_wed_stop.patch b/target/linux/generic/backport-5.15/729-12-v6.2-net-ethernet-mtk_wed-update-mtk_wed_stop.patch new file mode 100644 index 0000000000..dfc0f8c3f3 --- /dev/null +++ b/target/linux/generic/backport-5.15/729-12-v6.2-net-ethernet-mtk_wed-update-mtk_wed_stop.patch @@ -0,0 +1,98 @@ +From: Lorenzo Bianconi <lorenzo@kernel.org> +Date: Thu, 24 Nov 2022 16:22:53 +0100 +Subject: [PATCH] net: ethernet: mtk_wed: update mtk_wed_stop + +Update mtk_wed_stop routine and rename old mtk_wed_stop() to +mtk_wed_deinit(). This is a preliminary patch to add Wireless Ethernet +Dispatcher reset support. + +Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com> +Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com> +Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> +Signed-off-by: Paolo Abeni <pabeni@redhat.com> +--- + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -539,14 +539,8 @@ mtk_wed_dma_disable(struct mtk_wed_devic + static void + mtk_wed_stop(struct mtk_wed_device *dev) + { +- mtk_wed_dma_disable(dev); + mtk_wed_set_ext_int(dev, false); + +- wed_clr(dev, MTK_WED_CTRL, +- MTK_WED_CTRL_WDMA_INT_AGENT_EN | +- MTK_WED_CTRL_WPDMA_INT_AGENT_EN | +- MTK_WED_CTRL_WED_TX_BM_EN | +- MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); + wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER, 0); + wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, 0); + wdma_w32(dev, MTK_WDMA_INT_MASK, 0); +@@ -558,7 +552,27 @@ mtk_wed_stop(struct mtk_wed_device *dev) + + wed_w32(dev, MTK_WED_EXT_INT_MASK1, 0); + wed_w32(dev, MTK_WED_EXT_INT_MASK2, 0); +- wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN); ++} ++ ++static void ++mtk_wed_deinit(struct mtk_wed_device *dev) ++{ ++ mtk_wed_stop(dev); ++ mtk_wed_dma_disable(dev); ++ ++ wed_clr(dev, MTK_WED_CTRL, ++ MTK_WED_CTRL_WDMA_INT_AGENT_EN | ++ MTK_WED_CTRL_WPDMA_INT_AGENT_EN | ++ MTK_WED_CTRL_WED_TX_BM_EN | ++ MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); ++ ++ if (dev->hw->version == 1) ++ return; ++ ++ wed_clr(dev, MTK_WED_CTRL, ++ MTK_WED_CTRL_RX_ROUTE_QM_EN | ++ MTK_WED_CTRL_WED_RX_BM_EN | ++ MTK_WED_CTRL_RX_RRO_QM_EN); + } + + static void +@@ -568,7 +582,7 @@ mtk_wed_detach(struct mtk_wed_device *de + + mutex_lock(&hw_lock); + +- mtk_wed_stop(dev); ++ mtk_wed_deinit(dev); + + mtk_wdma_rx_reset(dev); + mtk_wed_reset(dev, MTK_WED_RESET_WED); +@@ -677,7 +691,7 @@ mtk_wed_hw_init_early(struct mtk_wed_dev + { + u32 mask, set; + +- mtk_wed_stop(dev); ++ mtk_wed_deinit(dev); + mtk_wed_reset(dev, MTK_WED_RESET_WED); + mtk_wed_set_wpdma(dev); + +--- a/include/linux/soc/mediatek/mtk_wed.h ++++ b/include/linux/soc/mediatek/mtk_wed.h +@@ -234,6 +234,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_devic + (_dev)->ops->ppe_check(_dev, _skb, _reason, _hash) + #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) \ + (_dev)->ops->msg_update(_dev, _id, _msg, _len) ++#define mtk_wed_device_stop(_dev) (_dev)->ops->stop(_dev) ++#define mtk_wed_device_dma_reset(_dev) (_dev)->ops->reset_dma(_dev) + #else + static inline bool mtk_wed_device_active(struct mtk_wed_device *dev) + { +@@ -250,6 +252,8 @@ static inline bool mtk_wed_device_active + #define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) -ENODEV + #define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) do {} while (0) + #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV ++#define mtk_wed_device_stop(_dev) do {} while (0) ++#define mtk_wed_device_dma_reset(_dev) do {} while (0) + #endif + + #endif diff --git a/target/linux/generic/backport-5.15/729-13-v6.2-net-ethernet-mtk_wed-add-mtk_wed_rx_reset-routine.patch b/target/linux/generic/backport-5.15/729-13-v6.2-net-ethernet-mtk_wed-add-mtk_wed_rx_reset-routine.patch new file mode 100644 index 0000000000..2205fea513 --- /dev/null +++ b/target/linux/generic/backport-5.15/729-13-v6.2-net-ethernet-mtk_wed-add-mtk_wed_rx_reset-routine.patch @@ -0,0 +1,309 @@ +From: Lorenzo Bianconi <lorenzo@kernel.org> +Date: Thu, 24 Nov 2022 16:22:54 +0100 +Subject: [PATCH] net: ethernet: mtk_wed: add mtk_wed_rx_reset routine + +Introduce mtk_wed_rx_reset routine in order to reset rx DMA for Wireless +Ethernet Dispatcher available on MT7986 SoC. + +Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com> +Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com> +Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> +Signed-off-by: Paolo Abeni <pabeni@redhat.com> +--- + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -951,42 +951,130 @@ mtk_wed_ring_reset(struct mtk_wed_ring * + } + + static u32 +-mtk_wed_check_busy(struct mtk_wed_device *dev) ++mtk_wed_check_busy(struct mtk_wed_device *dev, u32 reg, u32 mask) + { +- if (wed_r32(dev, MTK_WED_GLO_CFG) & MTK_WED_GLO_CFG_TX_DMA_BUSY) +- return true; +- +- if (wed_r32(dev, MTK_WED_WPDMA_GLO_CFG) & +- MTK_WED_WPDMA_GLO_CFG_TX_DRV_BUSY) +- return true; +- +- if (wed_r32(dev, MTK_WED_CTRL) & MTK_WED_CTRL_WDMA_INT_AGENT_BUSY) +- return true; +- +- if (wed_r32(dev, MTK_WED_WDMA_GLO_CFG) & +- MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY) +- return true; +- +- if (wdma_r32(dev, MTK_WDMA_GLO_CFG) & +- MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY) +- return true; +- +- if (wed_r32(dev, MTK_WED_CTRL) & +- (MTK_WED_CTRL_WED_TX_BM_BUSY | MTK_WED_CTRL_WED_TX_FREE_AGENT_BUSY)) +- return true; +- +- return false; ++ return !!(wed_r32(dev, reg) & mask); + } + + static int +-mtk_wed_poll_busy(struct mtk_wed_device *dev) ++mtk_wed_poll_busy(struct mtk_wed_device *dev, u32 reg, u32 mask) + { + int sleep = 15000; + int timeout = 100 * sleep; + u32 val; + + return read_poll_timeout(mtk_wed_check_busy, val, !val, sleep, +- timeout, false, dev); ++ timeout, false, dev, reg, mask); ++} ++ ++static int ++mtk_wed_rx_reset(struct mtk_wed_device *dev) ++{ ++ struct mtk_wed_wo *wo = dev->hw->wed_wo; ++ u8 val = MTK_WED_WO_STATE_SER_RESET; ++ int i, ret; ++ ++ ret = mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, ++ MTK_WED_WO_CMD_CHANGE_STATE, &val, ++ sizeof(val), true); ++ if (ret) ++ return ret; ++ ++ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, MTK_WED_WPDMA_RX_D_RX_DRV_EN); ++ ret = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, ++ MTK_WED_WPDMA_RX_D_RX_DRV_BUSY); ++ if (ret) { ++ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT); ++ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_RX_D_DRV); ++ } else { ++ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, ++ MTK_WED_WPDMA_RX_D_RST_CRX_IDX | ++ MTK_WED_WPDMA_RX_D_RST_DRV_IDX); ++ ++ wed_set(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, ++ MTK_WED_WPDMA_RX_D_RST_INIT_COMPLETE | ++ MTK_WED_WPDMA_RX_D_FSM_RETURN_IDLE); ++ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, ++ MTK_WED_WPDMA_RX_D_RST_INIT_COMPLETE | ++ MTK_WED_WPDMA_RX_D_FSM_RETURN_IDLE); ++ ++ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0); ++ } ++ ++ /* reset rro qm */ ++ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_RRO_QM_EN); ++ ret = mtk_wed_poll_busy(dev, MTK_WED_CTRL, ++ MTK_WED_CTRL_RX_RRO_QM_BUSY); ++ if (ret) { ++ mtk_wed_reset(dev, MTK_WED_RESET_RX_RRO_QM); ++ } else { ++ wed_set(dev, MTK_WED_RROQM_RST_IDX, ++ MTK_WED_RROQM_RST_IDX_MIOD | ++ MTK_WED_RROQM_RST_IDX_FDBK); ++ wed_w32(dev, MTK_WED_RROQM_RST_IDX, 0); ++ } ++ ++ /* reset route qm */ ++ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_ROUTE_QM_EN); ++ ret = mtk_wed_poll_busy(dev, MTK_WED_CTRL, ++ MTK_WED_CTRL_RX_ROUTE_QM_BUSY); ++ if (ret) ++ mtk_wed_reset(dev, MTK_WED_RESET_RX_ROUTE_QM); ++ else ++ wed_set(dev, MTK_WED_RTQM_GLO_CFG, ++ MTK_WED_RTQM_Q_RST); ++ ++ /* reset tx wdma */ ++ mtk_wdma_tx_reset(dev); ++ ++ /* reset tx wdma drv */ ++ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_TX_DRV_EN); ++ mtk_wed_poll_busy(dev, MTK_WED_CTRL, ++ MTK_WED_CTRL_WDMA_INT_AGENT_BUSY); ++ mtk_wed_reset(dev, MTK_WED_RESET_WDMA_TX_DRV); ++ ++ /* reset wed rx dma */ ++ ret = mtk_wed_poll_busy(dev, MTK_WED_GLO_CFG, ++ MTK_WED_GLO_CFG_RX_DMA_BUSY); ++ wed_clr(dev, MTK_WED_GLO_CFG, MTK_WED_GLO_CFG_RX_DMA_EN); ++ if (ret) { ++ mtk_wed_reset(dev, MTK_WED_RESET_WED_RX_DMA); ++ } else { ++ struct mtk_eth *eth = dev->hw->eth; ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ wed_set(dev, MTK_WED_RESET_IDX, ++ MTK_WED_RESET_IDX_RX_V2); ++ else ++ wed_set(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_IDX_RX); ++ wed_w32(dev, MTK_WED_RESET_IDX, 0); ++ } ++ ++ /* reset rx bm */ ++ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN); ++ mtk_wed_poll_busy(dev, MTK_WED_CTRL, ++ MTK_WED_CTRL_WED_RX_BM_BUSY); ++ mtk_wed_reset(dev, MTK_WED_RESET_RX_BM); ++ ++ /* wo change to enable state */ ++ val = MTK_WED_WO_STATE_ENABLE; ++ ret = mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, ++ MTK_WED_WO_CMD_CHANGE_STATE, &val, ++ sizeof(val), true); ++ if (ret) ++ return ret; ++ ++ /* wed_rx_ring_reset */ ++ for (i = 0; i < ARRAY_SIZE(dev->rx_ring); i++) { ++ if (!dev->rx_ring[i].desc) ++ continue; ++ ++ mtk_wed_ring_reset(&dev->rx_ring[i], MTK_WED_RX_RING_SIZE, ++ false); ++ } ++ mtk_wed_free_rx_buffer(dev); ++ ++ return 0; + } + + static void +@@ -1004,19 +1092,23 @@ mtk_wed_reset_dma(struct mtk_wed_device + true); + } + +- if (mtk_wed_poll_busy(dev)) +- busy = mtk_wed_check_busy(dev); +- ++ /* 1. reset WED tx DMA */ ++ wed_clr(dev, MTK_WED_GLO_CFG, MTK_WED_GLO_CFG_TX_DMA_EN); ++ busy = mtk_wed_poll_busy(dev, MTK_WED_GLO_CFG, ++ MTK_WED_GLO_CFG_TX_DMA_BUSY); + if (busy) { + mtk_wed_reset(dev, MTK_WED_RESET_WED_TX_DMA); + } else { +- wed_w32(dev, MTK_WED_RESET_IDX, +- MTK_WED_RESET_IDX_TX | +- MTK_WED_RESET_IDX_RX); ++ wed_w32(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_IDX_TX); + wed_w32(dev, MTK_WED_RESET_IDX, 0); + } + +- mtk_wdma_rx_reset(dev); ++ /* 2. reset WDMA rx DMA */ ++ busy = !!mtk_wdma_rx_reset(dev); ++ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_RX_DRV_EN); ++ if (!busy) ++ busy = mtk_wed_poll_busy(dev, MTK_WED_WDMA_GLO_CFG, ++ MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY); + + if (busy) { + mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT); +@@ -1033,6 +1125,9 @@ mtk_wed_reset_dma(struct mtk_wed_device + MTK_WED_WDMA_GLO_CFG_RST_INIT_COMPLETE); + } + ++ /* 3. reset WED WPDMA tx */ ++ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); ++ + for (i = 0; i < 100; i++) { + val = wed_r32(dev, MTK_WED_TX_BM_INTF); + if (FIELD_GET(MTK_WED_TX_BM_INTF_TKFIFO_FDEP, val) == 0x40) +@@ -1040,8 +1135,19 @@ mtk_wed_reset_dma(struct mtk_wed_device + } + + mtk_wed_reset(dev, MTK_WED_RESET_TX_FREE_AGENT); ++ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_TX_BM_EN); + mtk_wed_reset(dev, MTK_WED_RESET_TX_BM); + ++ /* 4. reset WED WPDMA tx */ ++ busy = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_GLO_CFG, ++ MTK_WED_WPDMA_GLO_CFG_TX_DRV_BUSY); ++ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, ++ MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN | ++ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN); ++ if (!busy) ++ busy = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_GLO_CFG, ++ MTK_WED_WPDMA_GLO_CFG_RX_DRV_BUSY); ++ + if (busy) { + mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT); + mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_TX_DRV); +@@ -1052,6 +1158,17 @@ mtk_wed_reset_dma(struct mtk_wed_device + MTK_WED_WPDMA_RESET_IDX_RX); + wed_w32(dev, MTK_WED_WPDMA_RESET_IDX, 0); + } ++ ++ dev->init_done = false; ++ if (dev->hw->version == 1) ++ return; ++ ++ if (!busy) { ++ wed_w32(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_WPDMA_IDX_RX); ++ wed_w32(dev, MTK_WED_RESET_IDX, 0); ++ } ++ ++ mtk_wed_rx_reset(dev); + } + + static int +@@ -1274,6 +1391,9 @@ mtk_wed_start(struct mtk_wed_device *dev + { + int i; + ++ if (mtk_wed_get_rx_capa(dev) && mtk_wed_rx_buffer_alloc(dev)) ++ return; ++ + for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++) + if (!dev->rx_wdma[i].desc) + mtk_wed_wdma_rx_ring_setup(dev, i, 16); +@@ -1362,10 +1482,6 @@ mtk_wed_attach(struct mtk_wed_device *de + goto out; + + if (mtk_wed_get_rx_capa(dev)) { +- ret = mtk_wed_rx_buffer_alloc(dev); +- if (ret) +- goto out; +- + ret = mtk_wed_rro_alloc(dev); + if (ret) + goto out; +--- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h ++++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h +@@ -24,11 +24,15 @@ struct mtk_wdma_desc { + + #define MTK_WED_RESET 0x008 + #define MTK_WED_RESET_TX_BM BIT(0) ++#define MTK_WED_RESET_RX_BM BIT(1) + #define MTK_WED_RESET_TX_FREE_AGENT BIT(4) + #define MTK_WED_RESET_WPDMA_TX_DRV BIT(8) + #define MTK_WED_RESET_WPDMA_RX_DRV BIT(9) ++#define MTK_WED_RESET_WPDMA_RX_D_DRV BIT(10) + #define MTK_WED_RESET_WPDMA_INT_AGENT BIT(11) + #define MTK_WED_RESET_WED_TX_DMA BIT(12) ++#define MTK_WED_RESET_WED_RX_DMA BIT(13) ++#define MTK_WED_RESET_WDMA_TX_DRV BIT(16) + #define MTK_WED_RESET_WDMA_RX_DRV BIT(17) + #define MTK_WED_RESET_WDMA_INT_AGENT BIT(19) + #define MTK_WED_RESET_RX_RRO_QM BIT(20) +@@ -158,6 +162,8 @@ struct mtk_wdma_desc { + #define MTK_WED_RESET_IDX 0x20c + #define MTK_WED_RESET_IDX_TX GENMASK(3, 0) + #define MTK_WED_RESET_IDX_RX GENMASK(17, 16) ++#define MTK_WED_RESET_IDX_RX_V2 GENMASK(7, 6) ++#define MTK_WED_RESET_WPDMA_IDX_RX GENMASK(31, 30) + + #define MTK_WED_TX_MIB(_n) (0x2a0 + (_n) * 4) + #define MTK_WED_RX_MIB(_n) (0x2e0 + (_n) * 4) +@@ -267,6 +273,9 @@ struct mtk_wdma_desc { + + #define MTK_WED_WPDMA_RX_D_GLO_CFG 0x75c + #define MTK_WED_WPDMA_RX_D_RX_DRV_EN BIT(0) ++#define MTK_WED_WPDMA_RX_D_RX_DRV_BUSY BIT(1) ++#define MTK_WED_WPDMA_RX_D_FSM_RETURN_IDLE BIT(3) ++#define MTK_WED_WPDMA_RX_D_RST_INIT_COMPLETE BIT(4) + #define MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL GENMASK(11, 7) + #define MTK_WED_WPDMA_RX_D_RXD_READ_LEN GENMASK(31, 24) + diff --git a/target/linux/generic/backport-5.15/729-14-v6.2-net-ethernet-mtk_wed-add-reset-to-tx_ring_setup-call.patch b/target/linux/generic/backport-5.15/729-14-v6.2-net-ethernet-mtk_wed-add-reset-to-tx_ring_setup-call.patch new file mode 100644 index 0000000000..602483bcb8 --- /dev/null +++ b/target/linux/generic/backport-5.15/729-14-v6.2-net-ethernet-mtk_wed-add-reset-to-tx_ring_setup-call.patch @@ -0,0 +1,103 @@ +From: Lorenzo Bianconi <lorenzo@kernel.org> +Date: Thu, 24 Nov 2022 16:22:55 +0100 +Subject: [PATCH] net: ethernet: mtk_wed: add reset to tx_ring_setup callback + +Introduce reset parameter to mtk_wed_tx_ring_setup signature. +This is a preliminary patch to add Wireless Ethernet Dispatcher reset +support. + +Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com> +Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com> +Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> +Signed-off-by: Paolo Abeni <pabeni@redhat.com> +--- + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -1188,7 +1188,8 @@ mtk_wed_ring_alloc(struct mtk_wed_device + } + + static int +-mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size) ++mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size, ++ bool reset) + { + u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version; + struct mtk_wed_ring *wdma; +@@ -1197,8 +1198,8 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_we + return -EINVAL; + + wdma = &dev->rx_wdma[idx]; +- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size, +- true)) ++ if (!reset && mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, ++ desc_size, true)) + return -ENOMEM; + + wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE, +@@ -1396,7 +1397,7 @@ mtk_wed_start(struct mtk_wed_device *dev + + for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++) + if (!dev->rx_wdma[i].desc) +- mtk_wed_wdma_rx_ring_setup(dev, i, 16); ++ mtk_wed_wdma_rx_ring_setup(dev, i, 16, false); + + mtk_wed_hw_init(dev); + mtk_wed_configure_irq(dev, irq_mask); +@@ -1505,7 +1506,8 @@ unlock: + } + + static int +-mtk_wed_tx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs) ++mtk_wed_tx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs, ++ bool reset) + { + struct mtk_wed_ring *ring = &dev->tx_ring[idx]; + +@@ -1524,11 +1526,12 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev + if (WARN_ON(idx >= ARRAY_SIZE(dev->tx_ring))) + return -EINVAL; + +- if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE, +- sizeof(*ring->desc), true)) ++ if (!reset && mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE, ++ sizeof(*ring->desc), true)) + return -ENOMEM; + +- if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE)) ++ if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE, ++ reset)) + return -ENOMEM; + + ring->reg_base = MTK_WED_RING_TX(idx); +--- a/include/linux/soc/mediatek/mtk_wed.h ++++ b/include/linux/soc/mediatek/mtk_wed.h +@@ -158,7 +158,7 @@ struct mtk_wed_device { + struct mtk_wed_ops { + int (*attach)(struct mtk_wed_device *dev); + int (*tx_ring_setup)(struct mtk_wed_device *dev, int ring, +- void __iomem *regs); ++ void __iomem *regs, bool reset); + int (*rx_ring_setup)(struct mtk_wed_device *dev, int ring, + void __iomem *regs); + int (*txfree_ring_setup)(struct mtk_wed_device *dev, +@@ -216,8 +216,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_devic + #define mtk_wed_device_active(_dev) !!(_dev)->ops + #define mtk_wed_device_detach(_dev) (_dev)->ops->detach(_dev) + #define mtk_wed_device_start(_dev, _mask) (_dev)->ops->start(_dev, _mask) +-#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs) \ +- (_dev)->ops->tx_ring_setup(_dev, _ring, _regs) ++#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs, _reset) \ ++ (_dev)->ops->tx_ring_setup(_dev, _ring, _regs, _reset) + #define mtk_wed_device_txfree_ring_setup(_dev, _regs) \ + (_dev)->ops->txfree_ring_setup(_dev, _regs) + #define mtk_wed_device_reg_read(_dev, _reg) \ +@@ -243,7 +243,7 @@ static inline bool mtk_wed_device_active + } + #define mtk_wed_device_detach(_dev) do {} while (0) + #define mtk_wed_device_start(_dev, _mask) do {} while (0) +-#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs) -ENODEV ++#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs, _reset) -ENODEV + #define mtk_wed_device_txfree_ring_setup(_dev, _ring, _regs) -ENODEV + #define mtk_wed_device_reg_read(_dev, _reg) 0 + #define mtk_wed_device_reg_write(_dev, _reg, _val) do {} while (0) diff --git a/target/linux/generic/backport-5.15/729-15-v6.2-net-ethernet-mtk_wed-fix-sleep-while-atomic-in-mtk_w.patch b/target/linux/generic/backport-5.15/729-15-v6.2-net-ethernet-mtk_wed-fix-sleep-while-atomic-in-mtk_w.patch new file mode 100644 index 0000000000..f9b11326b1 --- /dev/null +++ b/target/linux/generic/backport-5.15/729-15-v6.2-net-ethernet-mtk_wed-fix-sleep-while-atomic-in-mtk_w.patch @@ -0,0 +1,103 @@ +From: Lorenzo Bianconi <lorenzo@kernel.org> +Date: Thu, 1 Dec 2022 16:26:53 +0100 +Subject: [PATCH] net: ethernet: mtk_wed: fix sleep while atomic in + mtk_wed_wo_queue_refill + +In order to fix the following sleep while atomic bug always alloc pages +with GFP_ATOMIC in mtk_wed_wo_queue_refill since page_frag_alloc runs in +spin_lock critical section. + +[ 9.049719] Hardware name: MediaTek MT7986a RFB (DT) +[ 9.054665] Call trace: +[ 9.057096] dump_backtrace+0x0/0x154 +[ 9.060751] show_stack+0x14/0x1c +[ 9.064052] dump_stack_lvl+0x64/0x7c +[ 9.067702] dump_stack+0x14/0x2c +[ 9.071001] ___might_sleep+0xec/0x120 +[ 9.074736] __might_sleep+0x4c/0x9c +[ 9.078296] __alloc_pages+0x184/0x2e4 +[ 9.082030] page_frag_alloc_align+0x98/0x1ac +[ 9.086369] mtk_wed_wo_queue_refill+0x134/0x234 +[ 9.090974] mtk_wed_wo_init+0x174/0x2c0 +[ 9.094881] mtk_wed_attach+0x7c8/0x7e0 +[ 9.098701] mt7915_mmio_wed_init+0x1f0/0x3a0 [mt7915e] +[ 9.103940] mt7915_pci_probe+0xec/0x3bc [mt7915e] +[ 9.108727] pci_device_probe+0xac/0x13c +[ 9.112638] really_probe.part.0+0x98/0x2f4 +[ 9.116807] __driver_probe_device+0x94/0x13c +[ 9.121147] driver_probe_device+0x40/0x114 +[ 9.125314] __driver_attach+0x7c/0x180 +[ 9.129133] bus_for_each_dev+0x5c/0x90 +[ 9.132953] driver_attach+0x20/0x2c +[ 9.136513] bus_add_driver+0x104/0x1fc +[ 9.140333] driver_register+0x74/0x120 +[ 9.144153] __pci_register_driver+0x40/0x50 +[ 9.148407] mt7915_init+0x5c/0x1000 [mt7915e] +[ 9.152848] do_one_initcall+0x40/0x25c +[ 9.156669] do_init_module+0x44/0x230 +[ 9.160403] load_module+0x1f30/0x2750 +[ 9.164135] __do_sys_init_module+0x150/0x200 +[ 9.168475] __arm64_sys_init_module+0x18/0x20 +[ 9.172901] invoke_syscall.constprop.0+0x4c/0xe0 +[ 9.177589] do_el0_svc+0x48/0xe0 +[ 9.180889] el0_svc+0x14/0x50 +[ 9.183929] el0t_64_sync_handler+0x9c/0x120 +[ 9.188183] el0t_64_sync+0x158/0x15c + +Fixes: 799684448e3e ("net: ethernet: mtk_wed: introduce wed wo support") +Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> +Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com> +Link: https://lore.kernel.org/r/67ca94bdd3d9eaeb86e52b3050fbca0bcf7bb02f.1669908312.git.lorenzo@kernel.org +Signed-off-by: Jakub Kicinski <kuba@kernel.org> +--- + +--- a/drivers/net/ethernet/mediatek/mtk_wed_wo.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c +@@ -133,17 +133,18 @@ mtk_wed_wo_dequeue(struct mtk_wed_wo *wo + + static int + mtk_wed_wo_queue_refill(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q, +- gfp_t gfp, bool rx) ++ bool rx) + { + enum dma_data_direction dir = rx ? DMA_FROM_DEVICE : DMA_TO_DEVICE; + int n_buf = 0; + + spin_lock_bh(&q->lock); + while (q->queued < q->n_desc) { +- void *buf = page_frag_alloc(&q->cache, q->buf_size, gfp); + struct mtk_wed_wo_queue_entry *entry; + dma_addr_t addr; ++ void *buf; + ++ buf = page_frag_alloc(&q->cache, q->buf_size, GFP_ATOMIC); + if (!buf) + break; + +@@ -215,7 +216,7 @@ mtk_wed_wo_rx_run_queue(struct mtk_wed_w + mtk_wed_mcu_rx_unsolicited_event(wo, skb); + } + +- if (mtk_wed_wo_queue_refill(wo, q, GFP_ATOMIC, true)) { ++ if (mtk_wed_wo_queue_refill(wo, q, true)) { + u32 index = (q->head - 1) % q->n_desc; + + mtk_wed_wo_queue_kick(wo, q, index); +@@ -432,7 +433,7 @@ mtk_wed_wo_hardware_init(struct mtk_wed_ + if (ret) + goto error; + +- mtk_wed_wo_queue_refill(wo, &wo->q_tx, GFP_KERNEL, false); ++ mtk_wed_wo_queue_refill(wo, &wo->q_tx, false); + mtk_wed_wo_queue_reset(wo, &wo->q_tx); + + regs.desc_base = MTK_WED_WO_CCIF_DUMMY5; +@@ -446,7 +447,7 @@ mtk_wed_wo_hardware_init(struct mtk_wed_ + if (ret) + goto error; + +- mtk_wed_wo_queue_refill(wo, &wo->q_rx, GFP_KERNEL, true); ++ mtk_wed_wo_queue_refill(wo, &wo->q_rx, true); + mtk_wed_wo_queue_reset(wo, &wo->q_rx); + + /* rx queue irqmask */ diff --git a/target/linux/generic/backport-5.15/729-16-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-rx-qu.patch b/target/linux/generic/backport-5.15/729-16-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-rx-qu.patch new file mode 100644 index 0000000000..fa6f56dbe7 --- /dev/null +++ b/target/linux/generic/backport-5.15/729-16-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-rx-qu.patch @@ -0,0 +1,52 @@ +From: Lorenzo Bianconi <lorenzo@kernel.org> +Date: Tue, 10 Jan 2023 10:31:26 +0100 +Subject: [PATCH] net: ethernet: mtk_wed: get rid of queue lock for rx queue + +Queue spinlock is currently held in mtk_wed_wo_queue_rx_clean and +mtk_wed_wo_queue_refill routines for MTK Wireless Ethernet Dispatcher +MCU rx queue. mtk_wed_wo_queue_refill() is running during initialization +and in rx tasklet while mtk_wed_wo_queue_rx_clean() is running in +mtk_wed_wo_hw_deinit() during hw de-init phase after rx tasklet has been +disabled. Since mtk_wed_wo_queue_rx_clean and mtk_wed_wo_queue_refill +routines can't run concurrently get rid of spinlock for mcu rx queue. + +Reviewed-by: Alexander Duyck <alexanderduyck@fb.com> +Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> +Link: https://lore.kernel.org/r/36ec3b729542ea60898471d890796f745479ba32.1673342990.git.lorenzo@kernel.org +Signed-off-by: Jakub Kicinski <kuba@kernel.org> +--- + +--- a/drivers/net/ethernet/mediatek/mtk_wed_wo.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c +@@ -138,7 +138,6 @@ mtk_wed_wo_queue_refill(struct mtk_wed_w + enum dma_data_direction dir = rx ? DMA_FROM_DEVICE : DMA_TO_DEVICE; + int n_buf = 0; + +- spin_lock_bh(&q->lock); + while (q->queued < q->n_desc) { + struct mtk_wed_wo_queue_entry *entry; + dma_addr_t addr; +@@ -172,7 +171,6 @@ mtk_wed_wo_queue_refill(struct mtk_wed_w + q->queued++; + n_buf++; + } +- spin_unlock_bh(&q->lock); + + return n_buf; + } +@@ -316,7 +314,6 @@ mtk_wed_wo_queue_rx_clean(struct mtk_wed + { + struct page *page; + +- spin_lock_bh(&q->lock); + for (;;) { + void *buf = mtk_wed_wo_dequeue(wo, q, NULL, true); + +@@ -325,7 +322,6 @@ mtk_wed_wo_queue_rx_clean(struct mtk_wed + + skb_free_frag(buf); + } +- spin_unlock_bh(&q->lock); + + if (!q->cache.va) + return; diff --git a/target/linux/generic/backport-5.15/729-17-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-tx-qu.patch b/target/linux/generic/backport-5.15/729-17-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-tx-qu.patch new file mode 100644 index 0000000000..9b1e4c3250 --- /dev/null +++ b/target/linux/generic/backport-5.15/729-17-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-tx-qu.patch @@ -0,0 +1,75 @@ +From: Lorenzo Bianconi <lorenzo@kernel.org> +Date: Thu, 12 Jan 2023 10:21:29 +0100 +Subject: [PATCH] net: ethernet: mtk_wed: get rid of queue lock for tx queue + +Similar to MTK Wireless Ethernet Dispatcher (WED) MCU rx queue, +we do not need to protect WED MCU tx queue with a spin lock since +the tx queue is accessed in the two following routines: +- mtk_wed_wo_queue_tx_skb(): + it is run at initialization and during mt7915 normal operation. + Moreover MCU messages are serialized through MCU mutex. +- mtk_wed_wo_queue_tx_clean(): + it runs just at mt7915 driver module unload when no more messages + are sent to the MCU. + +Remove tx queue spinlock. + +Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> +Link: https://lore.kernel.org/r/7bd0337b2a13ab1a63673b7c03fd35206b3b284e.1673515140.git.lorenzo@kernel.org +Signed-off-by: Jakub Kicinski <kuba@kernel.org> +--- + +--- a/drivers/net/ethernet/mediatek/mtk_wed_wo.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c +@@ -258,7 +258,6 @@ mtk_wed_wo_queue_alloc(struct mtk_wed_wo + int n_desc, int buf_size, int index, + struct mtk_wed_wo_queue_regs *regs) + { +- spin_lock_init(&q->lock); + q->regs = *regs; + q->n_desc = n_desc; + q->buf_size = buf_size; +@@ -290,7 +289,6 @@ mtk_wed_wo_queue_tx_clean(struct mtk_wed + struct page *page; + int i; + +- spin_lock_bh(&q->lock); + for (i = 0; i < q->n_desc; i++) { + struct mtk_wed_wo_queue_entry *entry = &q->entry[i]; + +@@ -299,7 +297,6 @@ mtk_wed_wo_queue_tx_clean(struct mtk_wed + skb_free_frag(entry->buf); + entry->buf = NULL; + } +- spin_unlock_bh(&q->lock); + + if (!q->cache.va) + return; +@@ -347,8 +344,6 @@ int mtk_wed_wo_queue_tx_skb(struct mtk_w + int ret = 0, index; + u32 ctrl; + +- spin_lock_bh(&q->lock); +- + q->tail = mtk_wed_mmio_r32(wo, q->regs.dma_idx); + index = (q->head + 1) % q->n_desc; + if (q->tail == index) { +@@ -379,8 +374,6 @@ int mtk_wed_wo_queue_tx_skb(struct mtk_w + mtk_wed_wo_queue_kick(wo, q, q->head); + mtk_wed_wo_kickout(wo); + out: +- spin_unlock_bh(&q->lock); +- + dev_kfree_skb(skb); + + return ret; +--- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h ++++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h +@@ -211,7 +211,6 @@ struct mtk_wed_wo_queue { + struct mtk_wed_wo_queue_regs regs; + + struct page_frag_cache cache; +- spinlock_t lock; + + struct mtk_wed_wo_queue_desc *desc; + dma_addr_t desc_dma; diff --git a/target/linux/generic/backport-5.15/729-18-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_reset-util.patch b/target/linux/generic/backport-5.15/729-18-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_reset-util.patch new file mode 100644 index 0000000000..f5e9dddd42 --- /dev/null +++ b/target/linux/generic/backport-5.15/729-18-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_reset-util.patch @@ -0,0 +1,70 @@ +From: Lorenzo Bianconi <lorenzo@kernel.org> +Date: Sat, 14 Jan 2023 18:01:28 +0100 +Subject: [PATCH] net: ethernet: mtk_eth_soc: introduce mtk_hw_reset utility + routine + +This is a preliminary patch to add Wireless Ethernet Dispatcher reset +support. + +Reviewed-by: Leon Romanovsky <leonro@nvidia.com> +Tested-by: Daniel Golle <daniel@makrotopia.org> +Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com> +Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com> +Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> +Signed-off-by: Paolo Abeni <pabeni@redhat.com> +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -3199,6 +3199,27 @@ static void mtk_set_mcr_max_rx(struct mt + mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id)); + } + ++static void mtk_hw_reset(struct mtk_eth *eth) ++{ ++ u32 val; ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0); ++ val = RSTCTRL_PPE0_V2; ++ } else { ++ val = RSTCTRL_PPE0; ++ } ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) ++ val |= RSTCTRL_PPE1; ++ ++ ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val); ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, ++ 0x3ffffff); ++} ++ + static int mtk_hw_init(struct mtk_eth *eth) + { + u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA | +@@ -3238,22 +3259,9 @@ static int mtk_hw_init(struct mtk_eth *e + return 0; + } + +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { +- regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0); +- val = RSTCTRL_PPE0_V2; +- } else { +- val = RSTCTRL_PPE0; +- } +- +- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) +- val |= RSTCTRL_PPE1; +- +- ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val); ++ mtk_hw_reset(eth); + + if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { +- regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, +- 0x3ffffff); +- + /* Set FE to PDMAv2 if necessary */ + val = mtk_r32(eth, MTK_FE_GLO_MISC); + mtk_w32(eth, val | BIT(4), MTK_FE_GLO_MISC); diff --git a/target/linux/generic/backport-5.15/729-19-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_warm_reset.patch b/target/linux/generic/backport-5.15/729-19-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_warm_reset.patch new file mode 100644 index 0000000000..f2c9a7e53d --- /dev/null +++ b/target/linux/generic/backport-5.15/729-19-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_warm_reset.patch @@ -0,0 +1,107 @@ +From: Lorenzo Bianconi <lorenzo@kernel.org> +Date: Sat, 14 Jan 2023 18:01:29 +0100 +Subject: [PATCH] net: ethernet: mtk_eth_soc: introduce mtk_hw_warm_reset + support + +Introduce mtk_hw_warm_reset utility routine. This is a preliminary patch +to align reset procedure to vendor sdk and avoid to power down the chip +during hw reset. + +Reviewed-by: Leon Romanovsky <leonro@nvidia.com> +Tested-by: Daniel Golle <daniel@makrotopia.org> +Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com> +Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com> +Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> +Signed-off-by: Paolo Abeni <pabeni@redhat.com> +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -3220,7 +3220,54 @@ static void mtk_hw_reset(struct mtk_eth + 0x3ffffff); + } + +-static int mtk_hw_init(struct mtk_eth *eth) ++static u32 mtk_hw_reset_read(struct mtk_eth *eth) ++{ ++ u32 val; ++ ++ regmap_read(eth->ethsys, ETHSYS_RSTCTRL, &val); ++ return val; ++} ++ ++static void mtk_hw_warm_reset(struct mtk_eth *eth) ++{ ++ u32 rst_mask, val; ++ ++ regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, RSTCTRL_FE, ++ RSTCTRL_FE); ++ if (readx_poll_timeout_atomic(mtk_hw_reset_read, eth, val, ++ val & RSTCTRL_FE, 1, 1000)) { ++ dev_err(eth->dev, "warm reset failed\n"); ++ mtk_hw_reset(eth); ++ return; ++ } ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V2; ++ else ++ rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0; ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) ++ rst_mask |= RSTCTRL_PPE1; ++ ++ regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, rst_mask, rst_mask); ++ ++ udelay(1); ++ val = mtk_hw_reset_read(eth); ++ if (!(val & rst_mask)) ++ dev_err(eth->dev, "warm reset stage0 failed %08x (%08x)\n", ++ val, rst_mask); ++ ++ rst_mask |= RSTCTRL_FE; ++ regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, rst_mask, ~rst_mask); ++ ++ udelay(1); ++ val = mtk_hw_reset_read(eth); ++ if (val & rst_mask) ++ dev_err(eth->dev, "warm reset stage1 failed %08x (%08x)\n", ++ val, rst_mask); ++} ++ ++static int mtk_hw_init(struct mtk_eth *eth, bool reset) + { + u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA | + ETHSYS_DMA_AG_MAP_PPE; +@@ -3259,7 +3306,12 @@ static int mtk_hw_init(struct mtk_eth *e + return 0; + } + +- mtk_hw_reset(eth); ++ msleep(100); ++ ++ if (reset) ++ mtk_hw_warm_reset(eth); ++ else ++ mtk_hw_reset(eth); + + if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { + /* Set FE to PDMAv2 if necessary */ +@@ -3464,7 +3516,7 @@ static void mtk_pending_work(struct work + if (eth->dev->pins) + pinctrl_select_state(eth->dev->pins->p, + eth->dev->pins->default_state); +- mtk_hw_init(eth); ++ mtk_hw_init(eth, true); + + /* restart DMA and enable IRQs */ + for (i = 0; i < MTK_MAC_COUNT; i++) { +@@ -4056,7 +4108,7 @@ static int mtk_probe(struct platform_dev + eth->msg_enable = netif_msg_init(mtk_msg_level, MTK_DEFAULT_MSG_ENABLE); + INIT_WORK(ð->pending_work, mtk_pending_work); + +- err = mtk_hw_init(eth); ++ err = mtk_hw_init(eth, false); + if (err) + goto err_wed_exit; + diff --git a/target/linux/generic/backport-5.15/729-20-v6.3-net-ethernet-mtk_eth_soc-align-reset-procedure-to-ve.patch b/target/linux/generic/backport-5.15/729-20-v6.3-net-ethernet-mtk_eth_soc-align-reset-procedure-to-ve.patch new file mode 100644 index 0000000000..02e34bb7cd --- /dev/null +++ b/target/linux/generic/backport-5.15/729-20-v6.3-net-ethernet-mtk_eth_soc-align-reset-procedure-to-ve.patch @@ -0,0 +1,262 @@ +From: Lorenzo Bianconi <lorenzo@kernel.org> +Date: Sat, 14 Jan 2023 18:01:30 +0100 +Subject: [PATCH] net: ethernet: mtk_eth_soc: align reset procedure to vendor + sdk + +Avoid to power-down the ethernet chip during hw reset and align reset +procedure to vendor sdk. + +Reviewed-by: Leon Romanovsky <leonro@nvidia.com> +Tested-by: Daniel Golle <daniel@makrotopia.org> +Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com> +Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com> +Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> +Signed-off-by: Paolo Abeni <pabeni@redhat.com> +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -2785,14 +2785,29 @@ static void mtk_dma_free(struct mtk_eth + kfree(eth->scratch_head); + } + ++static bool mtk_hw_reset_check(struct mtk_eth *eth) ++{ ++ u32 val = mtk_r32(eth, MTK_INT_STATUS2); ++ ++ return (val & MTK_FE_INT_FQ_EMPTY) || (val & MTK_FE_INT_RFIFO_UF) || ++ (val & MTK_FE_INT_RFIFO_OV) || (val & MTK_FE_INT_TSO_FAIL) || ++ (val & MTK_FE_INT_TSO_ALIGN) || (val & MTK_FE_INT_TSO_ILLEGAL); ++} ++ + static void mtk_tx_timeout(struct net_device *dev, unsigned int txqueue) + { + struct mtk_mac *mac = netdev_priv(dev); + struct mtk_eth *eth = mac->hw; + ++ if (test_bit(MTK_RESETTING, ð->state)) ++ return; ++ ++ if (!mtk_hw_reset_check(eth)) ++ return; ++ + eth->netdev[mac->id]->stats.tx_errors++; +- netif_err(eth, tx_err, dev, +- "transmit timed out\n"); ++ netif_err(eth, tx_err, dev, "transmit timed out\n"); ++ + schedule_work(ð->pending_work); + } + +@@ -3274,15 +3289,17 @@ static int mtk_hw_init(struct mtk_eth *e + const struct mtk_reg_map *reg_map = eth->soc->reg_map; + int i, val, ret; + +- if (test_and_set_bit(MTK_HW_INIT, ð->state)) ++ if (!reset && test_and_set_bit(MTK_HW_INIT, ð->state)) + return 0; + +- pm_runtime_enable(eth->dev); +- pm_runtime_get_sync(eth->dev); ++ if (!reset) { ++ pm_runtime_enable(eth->dev); ++ pm_runtime_get_sync(eth->dev); + +- ret = mtk_clk_enable(eth); +- if (ret) +- goto err_disable_pm; ++ ret = mtk_clk_enable(eth); ++ if (ret) ++ goto err_disable_pm; ++ } + + if (eth->ethsys) + regmap_update_bits(eth->ethsys, ETHSYS_DMA_AG_MAP, dma_mask, +@@ -3408,8 +3425,10 @@ static int mtk_hw_init(struct mtk_eth *e + return 0; + + err_disable_pm: +- pm_runtime_put_sync(eth->dev); +- pm_runtime_disable(eth->dev); ++ if (!reset) { ++ pm_runtime_put_sync(eth->dev); ++ pm_runtime_disable(eth->dev); ++ } + + return ret; + } +@@ -3488,30 +3507,53 @@ static int mtk_do_ioctl(struct net_devic + return -EOPNOTSUPP; + } + ++static void mtk_prepare_for_reset(struct mtk_eth *eth) ++{ ++ u32 val; ++ int i; ++ ++ /* disabe FE P3 and P4 */ ++ val = mtk_r32(eth, MTK_FE_GLO_CFG) | MTK_FE_LINK_DOWN_P3; ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) ++ val |= MTK_FE_LINK_DOWN_P4; ++ mtk_w32(eth, val, MTK_FE_GLO_CFG); ++ ++ /* adjust PPE configurations to prepare for reset */ ++ for (i = 0; i < ARRAY_SIZE(eth->ppe); i++) ++ mtk_ppe_prepare_reset(eth->ppe[i]); ++ ++ /* disable NETSYS interrupts */ ++ mtk_w32(eth, 0, MTK_FE_INT_ENABLE); ++ ++ /* force link down GMAC */ ++ for (i = 0; i < 2; i++) { ++ val = mtk_r32(eth, MTK_MAC_MCR(i)) & ~MAC_MCR_FORCE_LINK; ++ mtk_w32(eth, val, MTK_MAC_MCR(i)); ++ } ++} ++ + static void mtk_pending_work(struct work_struct *work) + { + struct mtk_eth *eth = container_of(work, struct mtk_eth, pending_work); +- int err, i; + unsigned long restart = 0; ++ u32 val; ++ int i; + + rtnl_lock(); +- +- dev_dbg(eth->dev, "[%s][%d] reset\n", __func__, __LINE__); + set_bit(MTK_RESETTING, ð->state); + ++ mtk_prepare_for_reset(eth); ++ + /* stop all devices to make sure that dma is properly shut down */ + for (i = 0; i < MTK_MAC_COUNT; i++) { +- if (!eth->netdev[i]) ++ if (!eth->netdev[i] || !netif_running(eth->netdev[i])) + continue; ++ + mtk_stop(eth->netdev[i]); + __set_bit(i, &restart); + } +- dev_dbg(eth->dev, "[%s][%d] mtk_stop ends\n", __func__, __LINE__); + +- /* restart underlying hardware such as power, clock, pin mux +- * and the connected phy +- */ +- mtk_hw_deinit(eth); ++ usleep_range(15000, 16000); + + if (eth->dev->pins) + pinctrl_select_state(eth->dev->pins->p, +@@ -3522,15 +3564,19 @@ static void mtk_pending_work(struct work + for (i = 0; i < MTK_MAC_COUNT; i++) { + if (!test_bit(i, &restart)) + continue; +- err = mtk_open(eth->netdev[i]); +- if (err) { ++ ++ if (mtk_open(eth->netdev[i])) { + netif_alert(eth, ifup, eth->netdev[i], +- "Driver up/down cycle failed, closing device.\n"); ++ "Driver up/down cycle failed\n"); + dev_close(eth->netdev[i]); + } + } + +- dev_dbg(eth->dev, "[%s][%d] reset done\n", __func__, __LINE__); ++ /* enabe FE P3 and P4 */ ++ val = mtk_r32(eth, MTK_FE_GLO_CFG) & ~MTK_FE_LINK_DOWN_P3; ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) ++ val &= ~MTK_FE_LINK_DOWN_P4; ++ mtk_w32(eth, val, MTK_FE_GLO_CFG); + + clear_bit(MTK_RESETTING, ð->state); + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -72,12 +72,24 @@ + #define MTK_HW_LRO_REPLACE_DELTA 1000 + #define MTK_HW_LRO_SDL_REMAIN_ROOM 1522 + ++/* Frame Engine Global Configuration */ ++#define MTK_FE_GLO_CFG 0x00 ++#define MTK_FE_LINK_DOWN_P3 BIT(11) ++#define MTK_FE_LINK_DOWN_P4 BIT(12) ++ + /* Frame Engine Global Reset Register */ + #define MTK_RST_GL 0x04 + #define RST_GL_PSE BIT(0) + + /* Frame Engine Interrupt Status Register */ + #define MTK_INT_STATUS2 0x08 ++#define MTK_FE_INT_ENABLE 0x0c ++#define MTK_FE_INT_FQ_EMPTY BIT(8) ++#define MTK_FE_INT_TSO_FAIL BIT(12) ++#define MTK_FE_INT_TSO_ILLEGAL BIT(13) ++#define MTK_FE_INT_TSO_ALIGN BIT(14) ++#define MTK_FE_INT_RFIFO_OV BIT(18) ++#define MTK_FE_INT_RFIFO_UF BIT(19) + #define MTK_GDM1_AF BIT(28) + #define MTK_GDM2_AF BIT(29) + +--- a/drivers/net/ethernet/mediatek/mtk_ppe.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c +@@ -716,6 +716,33 @@ int mtk_foe_entry_idle_time(struct mtk_p + return __mtk_foe_entry_idle_time(ppe, entry->data.ib1); + } + ++int mtk_ppe_prepare_reset(struct mtk_ppe *ppe) ++{ ++ if (!ppe) ++ return -EINVAL; ++ ++ /* disable KA */ ++ ppe_clear(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_CFG_KEEPALIVE); ++ ppe_clear(ppe, MTK_PPE_BIND_LMT1, MTK_PPE_NTU_KEEPALIVE); ++ ppe_w32(ppe, MTK_PPE_KEEPALIVE, 0); ++ usleep_range(10000, 11000); ++ ++ /* set KA timer to maximum */ ++ ppe_set(ppe, MTK_PPE_BIND_LMT1, MTK_PPE_NTU_KEEPALIVE); ++ ppe_w32(ppe, MTK_PPE_KEEPALIVE, 0xffffffff); ++ ++ /* set KA tick select */ ++ ppe_set(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_TICK_SEL); ++ ppe_set(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_CFG_KEEPALIVE); ++ usleep_range(10000, 11000); ++ ++ /* disable scan mode */ ++ ppe_clear(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_CFG_SCAN_MODE); ++ usleep_range(10000, 11000); ++ ++ return mtk_ppe_wait_busy(ppe); ++} ++ + struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, + int version, int index) + { +--- a/drivers/net/ethernet/mediatek/mtk_ppe.h ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h +@@ -306,6 +306,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ + int version, int index); + void mtk_ppe_start(struct mtk_ppe *ppe); + int mtk_ppe_stop(struct mtk_ppe *ppe); ++int mtk_ppe_prepare_reset(struct mtk_ppe *ppe); + + void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash); + +--- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h ++++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h +@@ -58,6 +58,12 @@ + #define MTK_PPE_TB_CFG_SCAN_MODE GENMASK(17, 16) + #define MTK_PPE_TB_CFG_HASH_DEBUG GENMASK(19, 18) + #define MTK_PPE_TB_CFG_INFO_SEL BIT(20) ++#define MTK_PPE_TB_TICK_SEL BIT(24) ++ ++#define MTK_PPE_BIND_LMT1 0x230 ++#define MTK_PPE_NTU_KEEPALIVE GENMASK(23, 16) ++ ++#define MTK_PPE_KEEPALIVE 0x234 + + enum { + MTK_PPE_SCAN_MODE_DISABLED, diff --git a/target/linux/generic/backport-5.15/729-21-v6.3-net-ethernet-mtk_eth_soc-add-dma-checks-to-mtk_hw_re.patch b/target/linux/generic/backport-5.15/729-21-v6.3-net-ethernet-mtk_eth_soc-add-dma-checks-to-mtk_hw_re.patch new file mode 100644 index 0000000000..240e7897c6 --- /dev/null +++ b/target/linux/generic/backport-5.15/729-21-v6.3-net-ethernet-mtk_eth_soc-add-dma-checks-to-mtk_hw_re.patch @@ -0,0 +1,249 @@ +From: Lorenzo Bianconi <lorenzo@kernel.org> +Date: Sat, 14 Jan 2023 18:01:31 +0100 +Subject: [PATCH] net: ethernet: mtk_eth_soc: add dma checks to + mtk_hw_reset_check + +Introduce mtk_hw_check_dma_hang routine to monitor possible dma hangs. + +Reviewed-by: Leon Romanovsky <leonro@nvidia.com> +Tested-by: Daniel Golle <daniel@makrotopia.org> +Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com> +Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com> +Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> +Signed-off-by: Paolo Abeni <pabeni@redhat.com> +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -50,6 +50,7 @@ static const struct mtk_reg_map mtk_reg_ + .delay_irq = 0x0a0c, + .irq_status = 0x0a20, + .irq_mask = 0x0a28, ++ .adma_rx_dbg0 = 0x0a38, + .int_grp = 0x0a50, + }, + .qdma = { +@@ -79,6 +80,8 @@ static const struct mtk_reg_map mtk_reg_ + [0] = 0x2800, + [1] = 0x2c00, + }, ++ .pse_iq_sta = 0x0110, ++ .pse_oq_sta = 0x0118, + }; + + static const struct mtk_reg_map mt7628_reg_map = { +@@ -109,6 +112,7 @@ static const struct mtk_reg_map mt7986_r + .delay_irq = 0x620c, + .irq_status = 0x6220, + .irq_mask = 0x6228, ++ .adma_rx_dbg0 = 0x6238, + .int_grp = 0x6250, + }, + .qdma = { +@@ -138,6 +142,8 @@ static const struct mtk_reg_map mt7986_r + [0] = 0x4800, + [1] = 0x4c00, + }, ++ .pse_iq_sta = 0x0180, ++ .pse_oq_sta = 0x01a0, + }; + + /* strings used by ethtool */ +@@ -3282,6 +3288,102 @@ static void mtk_hw_warm_reset(struct mtk + val, rst_mask); + } + ++static bool mtk_hw_check_dma_hang(struct mtk_eth *eth) ++{ ++ const struct mtk_reg_map *reg_map = eth->soc->reg_map; ++ bool gmac1_tx, gmac2_tx, gdm1_tx, gdm2_tx; ++ bool oq_hang, cdm1_busy, adma_busy; ++ bool wtx_busy, cdm_full, oq_free; ++ u32 wdidx, val, gdm1_fc, gdm2_fc; ++ bool qfsm_hang, qfwd_hang; ++ bool ret = false; ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) ++ return false; ++ ++ /* WDMA sanity checks */ ++ wdidx = mtk_r32(eth, reg_map->wdma_base[0] + 0xc); ++ ++ val = mtk_r32(eth, reg_map->wdma_base[0] + 0x204); ++ wtx_busy = FIELD_GET(MTK_TX_DMA_BUSY, val); ++ ++ val = mtk_r32(eth, reg_map->wdma_base[0] + 0x230); ++ cdm_full = !FIELD_GET(MTK_CDM_TXFIFO_RDY, val); ++ ++ oq_free = (!(mtk_r32(eth, reg_map->pse_oq_sta) & GENMASK(24, 16)) && ++ !(mtk_r32(eth, reg_map->pse_oq_sta + 0x4) & GENMASK(8, 0)) && ++ !(mtk_r32(eth, reg_map->pse_oq_sta + 0x10) & GENMASK(24, 16))); ++ ++ if (wdidx == eth->reset.wdidx && wtx_busy && cdm_full && oq_free) { ++ if (++eth->reset.wdma_hang_count > 2) { ++ eth->reset.wdma_hang_count = 0; ++ ret = true; ++ } ++ goto out; ++ } ++ ++ /* QDMA sanity checks */ ++ qfsm_hang = !!mtk_r32(eth, reg_map->qdma.qtx_cfg + 0x234); ++ qfwd_hang = !mtk_r32(eth, reg_map->qdma.qtx_cfg + 0x308); ++ ++ gdm1_tx = FIELD_GET(GENMASK(31, 16), mtk_r32(eth, MTK_FE_GDM1_FSM)) > 0; ++ gdm2_tx = FIELD_GET(GENMASK(31, 16), mtk_r32(eth, MTK_FE_GDM2_FSM)) > 0; ++ gmac1_tx = FIELD_GET(GENMASK(31, 24), mtk_r32(eth, MTK_MAC_FSM(0))) != 1; ++ gmac2_tx = FIELD_GET(GENMASK(31, 24), mtk_r32(eth, MTK_MAC_FSM(1))) != 1; ++ gdm1_fc = mtk_r32(eth, reg_map->gdm1_cnt + 0x24); ++ gdm2_fc = mtk_r32(eth, reg_map->gdm1_cnt + 0x64); ++ ++ if (qfsm_hang && qfwd_hang && ++ ((gdm1_tx && gmac1_tx && gdm1_fc < 1) || ++ (gdm2_tx && gmac2_tx && gdm2_fc < 1))) { ++ if (++eth->reset.qdma_hang_count > 2) { ++ eth->reset.qdma_hang_count = 0; ++ ret = true; ++ } ++ goto out; ++ } ++ ++ /* ADMA sanity checks */ ++ oq_hang = !!(mtk_r32(eth, reg_map->pse_oq_sta) & GENMASK(8, 0)); ++ cdm1_busy = !!(mtk_r32(eth, MTK_FE_CDM1_FSM) & GENMASK(31, 16)); ++ adma_busy = !(mtk_r32(eth, reg_map->pdma.adma_rx_dbg0) & GENMASK(4, 0)) && ++ !(mtk_r32(eth, reg_map->pdma.adma_rx_dbg0) & BIT(6)); ++ ++ if (oq_hang && cdm1_busy && adma_busy) { ++ if (++eth->reset.adma_hang_count > 2) { ++ eth->reset.adma_hang_count = 0; ++ ret = true; ++ } ++ goto out; ++ } ++ ++ eth->reset.wdma_hang_count = 0; ++ eth->reset.qdma_hang_count = 0; ++ eth->reset.adma_hang_count = 0; ++out: ++ eth->reset.wdidx = wdidx; ++ ++ return ret; ++} ++ ++static void mtk_hw_reset_monitor_work(struct work_struct *work) ++{ ++ struct delayed_work *del_work = to_delayed_work(work); ++ struct mtk_eth *eth = container_of(del_work, struct mtk_eth, ++ reset.monitor_work); ++ ++ if (test_bit(MTK_RESETTING, ð->state)) ++ goto out; ++ ++ /* DMA stuck checks */ ++ if (mtk_hw_check_dma_hang(eth)) ++ schedule_work(ð->pending_work); ++ ++out: ++ schedule_delayed_work(ð->reset.monitor_work, ++ MTK_DMA_MONITOR_TIMEOUT); ++} ++ + static int mtk_hw_init(struct mtk_eth *eth, bool reset) + { + u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA | +@@ -3614,6 +3716,7 @@ static int mtk_cleanup(struct mtk_eth *e + mtk_unreg_dev(eth); + mtk_free_dev(eth); + cancel_work_sync(ð->pending_work); ++ cancel_delayed_work_sync(ð->reset.monitor_work); + + return 0; + } +@@ -4041,6 +4144,7 @@ static int mtk_probe(struct platform_dev + + eth->rx_dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE; + INIT_WORK(ð->rx_dim.work, mtk_dim_rx); ++ INIT_DELAYED_WORK(ð->reset.monitor_work, mtk_hw_reset_monitor_work); + + eth->tx_dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE; + INIT_WORK(ð->tx_dim.work, mtk_dim_tx); +@@ -4245,6 +4349,8 @@ static int mtk_probe(struct platform_dev + NAPI_POLL_WEIGHT); + + platform_set_drvdata(pdev, eth); ++ schedule_delayed_work(ð->reset.monitor_work, ++ MTK_DMA_MONITOR_TIMEOUT); + + return 0; + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -256,6 +256,8 @@ + + #define MTK_RX_DONE_INT_V2 BIT(14) + ++#define MTK_CDM_TXFIFO_RDY BIT(7) ++ + /* QDMA Interrupt grouping registers */ + #define MTK_RLS_DONE_INT BIT(0) + +@@ -537,6 +539,17 @@ + #define MT7628_SDM_RBCNT (MT7628_SDM_OFFSET + 0x10c) + #define MT7628_SDM_CS_ERR (MT7628_SDM_OFFSET + 0x110) + ++#define MTK_FE_CDM1_FSM 0x220 ++#define MTK_FE_CDM2_FSM 0x224 ++#define MTK_FE_CDM3_FSM 0x238 ++#define MTK_FE_CDM4_FSM 0x298 ++#define MTK_FE_CDM5_FSM 0x318 ++#define MTK_FE_CDM6_FSM 0x328 ++#define MTK_FE_GDM1_FSM 0x228 ++#define MTK_FE_GDM2_FSM 0x22C ++ ++#define MTK_MAC_FSM(x) (0x1010C + ((x) * 0x100)) ++ + struct mtk_rx_dma { + unsigned int rxd1; + unsigned int rxd2; +@@ -933,6 +946,7 @@ struct mtk_reg_map { + u32 delay_irq; /* delay interrupt */ + u32 irq_status; /* interrupt status */ + u32 irq_mask; /* interrupt mask */ ++ u32 adma_rx_dbg0; + u32 int_grp; + } pdma; + struct { +@@ -959,6 +973,8 @@ struct mtk_reg_map { + u32 gdma_to_ppe0; + u32 ppe_base; + u32 wdma_base[2]; ++ u32 pse_iq_sta; ++ u32 pse_oq_sta; + }; + + /* struct mtk_eth_data - This is the structure holding all differences +@@ -1001,6 +1017,8 @@ struct mtk_soc_data { + } txrx; + }; + ++#define MTK_DMA_MONITOR_TIMEOUT msecs_to_jiffies(1000) ++ + /* currently no SoC has more than 2 macs */ + #define MTK_MAX_DEVS 2 + +@@ -1123,6 +1141,14 @@ struct mtk_eth { + struct rhashtable flow_table; + + struct bpf_prog __rcu *prog; ++ ++ struct { ++ struct delayed_work monitor_work; ++ u32 wdidx; ++ u8 wdma_hang_count; ++ u8 qdma_hang_count; ++ u8 adma_hang_count; ++ } reset; + }; + + /* struct mtk_mac - the structure that holds the info about the MACs of the diff --git a/target/linux/generic/backport-5.15/729-22-v6.3-net-ethernet-mtk_wed-add-reset-reset_complete-callba.patch b/target/linux/generic/backport-5.15/729-22-v6.3-net-ethernet-mtk_wed-add-reset-reset_complete-callba.patch new file mode 100644 index 0000000000..9f67e97e6f --- /dev/null +++ b/target/linux/generic/backport-5.15/729-22-v6.3-net-ethernet-mtk_wed-add-reset-reset_complete-callba.patch @@ -0,0 +1,124 @@ +From: Lorenzo Bianconi <lorenzo@kernel.org> +Date: Sat, 14 Jan 2023 18:01:32 +0100 +Subject: [PATCH] net: ethernet: mtk_wed: add reset/reset_complete callbacks + +Introduce reset and reset_complete wlan callback to schedule WLAN driver +reset when ethernet/wed driver is resetting. + +Tested-by: Daniel Golle <daniel@makrotopia.org> +Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com> +Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com> +Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> +Signed-off-by: Paolo Abeni <pabeni@redhat.com> +--- + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -3645,6 +3645,11 @@ static void mtk_pending_work(struct work + set_bit(MTK_RESETTING, ð->state); + + mtk_prepare_for_reset(eth); ++ mtk_wed_fe_reset(); ++ /* Run again reset preliminary configuration in order to avoid any ++ * possible race during FE reset since it can run releasing RTNL lock. ++ */ ++ mtk_prepare_for_reset(eth); + + /* stop all devices to make sure that dma is properly shut down */ + for (i = 0; i < MTK_MAC_COUNT; i++) { +@@ -3682,6 +3687,8 @@ static void mtk_pending_work(struct work + + clear_bit(MTK_RESETTING, ð->state); + ++ mtk_wed_fe_reset_complete(); ++ + rtnl_unlock(); + } + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -205,6 +205,48 @@ mtk_wed_wo_reset(struct mtk_wed_device * + iounmap(reg); + } + ++void mtk_wed_fe_reset(void) ++{ ++ int i; ++ ++ mutex_lock(&hw_lock); ++ ++ for (i = 0; i < ARRAY_SIZE(hw_list); i++) { ++ struct mtk_wed_hw *hw = hw_list[i]; ++ struct mtk_wed_device *dev = hw->wed_dev; ++ int err; ++ ++ if (!dev || !dev->wlan.reset) ++ continue; ++ ++ /* reset callback blocks until WLAN reset is completed */ ++ err = dev->wlan.reset(dev); ++ if (err) ++ dev_err(dev->dev, "wlan reset failed: %d\n", err); ++ } ++ ++ mutex_unlock(&hw_lock); ++} ++ ++void mtk_wed_fe_reset_complete(void) ++{ ++ int i; ++ ++ mutex_lock(&hw_lock); ++ ++ for (i = 0; i < ARRAY_SIZE(hw_list); i++) { ++ struct mtk_wed_hw *hw = hw_list[i]; ++ struct mtk_wed_device *dev = hw->wed_dev; ++ ++ if (!dev || !dev->wlan.reset_complete) ++ continue; ++ ++ dev->wlan.reset_complete(dev); ++ } ++ ++ mutex_unlock(&hw_lock); ++} ++ + static struct mtk_wed_hw * + mtk_wed_assign(struct mtk_wed_device *dev) + { +--- a/drivers/net/ethernet/mediatek/mtk_wed.h ++++ b/drivers/net/ethernet/mediatek/mtk_wed.h +@@ -128,6 +128,8 @@ void mtk_wed_add_hw(struct device_node * + void mtk_wed_exit(void); + int mtk_wed_flow_add(int index); + void mtk_wed_flow_remove(int index); ++void mtk_wed_fe_reset(void); ++void mtk_wed_fe_reset_complete(void); + #else + static inline void + mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, +@@ -147,6 +149,13 @@ static inline void mtk_wed_flow_remove(i + { + } + ++static inline void mtk_wed_fe_reset(void) ++{ ++} ++ ++static inline void mtk_wed_fe_reset_complete(void) ++{ ++} + #endif + + #ifdef CONFIG_DEBUG_FS +--- a/include/linux/soc/mediatek/mtk_wed.h ++++ b/include/linux/soc/mediatek/mtk_wed.h +@@ -151,6 +151,8 @@ struct mtk_wed_device { + void (*release_rx_buf)(struct mtk_wed_device *wed); + void (*update_wo_rx_stats)(struct mtk_wed_device *wed, + struct mtk_wed_wo_rx_stats *stats); ++ int (*reset)(struct mtk_wed_device *wed); ++ void (*reset_complete)(struct mtk_wed_device *wed); + } wlan; + #endif + }; diff --git a/target/linux/generic/backport-5.15/729-23-v6.3-net-ethernet-mtk_wed-add-reset-to-rx_ring_setup-call.patch b/target/linux/generic/backport-5.15/729-23-v6.3-net-ethernet-mtk_wed-add-reset-to-rx_ring_setup-call.patch new file mode 100644 index 0000000000..cf81acf491 --- /dev/null +++ b/target/linux/generic/backport-5.15/729-23-v6.3-net-ethernet-mtk_wed-add-reset-to-rx_ring_setup-call.patch @@ -0,0 +1,106 @@ +From: Lorenzo Bianconi <lorenzo@kernel.org> +Date: Mon, 5 Dec 2022 12:34:42 +0100 +Subject: [PATCH] net: ethernet: mtk_wed: add reset to rx_ring_setup callback + +This patch adds reset parameter to mtk_wed_rx_ring_setup signature +in order to align rx_ring_setup callback to tx_ring_setup one introduced +in 'commit 23dca7a90017 ("net: ethernet: mtk_wed: add reset to +tx_ring_setup callback")' + +Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com> +Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com> +Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> +Reviewed-by: Leon Romanovsky <leonro@nvidia.com> +Link: https://lore.kernel.org/r/29c6e7a5469e784406cf3e2920351d1207713d05.1670239984.git.lorenzo@kernel.org +Signed-off-by: Jakub Kicinski <kuba@kernel.org> +--- + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -1259,7 +1259,8 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_we + } + + static int +-mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size) ++mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size, ++ bool reset) + { + u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version; + struct mtk_wed_ring *wdma; +@@ -1268,8 +1269,8 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_we + return -EINVAL; + + wdma = &dev->tx_wdma[idx]; +- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size, +- true)) ++ if (!reset && mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, ++ desc_size, true)) + return -ENOMEM; + + wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE, +@@ -1279,6 +1280,9 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_we + wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_CPU_IDX, 0); + wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_DMA_IDX, 0); + ++ if (reset) ++ mtk_wed_ring_reset(wdma, MTK_WED_WDMA_RING_SIZE, true); ++ + if (!idx) { + wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_BASE, + wdma->desc_phys); +@@ -1618,18 +1622,20 @@ mtk_wed_txfree_ring_setup(struct mtk_wed + } + + static int +-mtk_wed_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs) ++mtk_wed_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs, ++ bool reset) + { + struct mtk_wed_ring *ring = &dev->rx_ring[idx]; + + if (WARN_ON(idx >= ARRAY_SIZE(dev->rx_ring))) + return -EINVAL; + +- if (mtk_wed_ring_alloc(dev, ring, MTK_WED_RX_RING_SIZE, +- sizeof(*ring->desc), false)) ++ if (!reset && mtk_wed_ring_alloc(dev, ring, MTK_WED_RX_RING_SIZE, ++ sizeof(*ring->desc), false)) + return -ENOMEM; + +- if (mtk_wed_wdma_tx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE)) ++ if (mtk_wed_wdma_tx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE, ++ reset)) + return -ENOMEM; + + ring->reg_base = MTK_WED_RING_RX_DATA(idx); +--- a/include/linux/soc/mediatek/mtk_wed.h ++++ b/include/linux/soc/mediatek/mtk_wed.h +@@ -162,7 +162,7 @@ struct mtk_wed_ops { + int (*tx_ring_setup)(struct mtk_wed_device *dev, int ring, + void __iomem *regs, bool reset); + int (*rx_ring_setup)(struct mtk_wed_device *dev, int ring, +- void __iomem *regs); ++ void __iomem *regs, bool reset); + int (*txfree_ring_setup)(struct mtk_wed_device *dev, + void __iomem *regs); + int (*msg_update)(struct mtk_wed_device *dev, int cmd_id, +@@ -230,8 +230,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_devic + (_dev)->ops->irq_get(_dev, _mask) + #define mtk_wed_device_irq_set_mask(_dev, _mask) \ + (_dev)->ops->irq_set_mask(_dev, _mask) +-#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) \ +- (_dev)->ops->rx_ring_setup(_dev, _ring, _regs) ++#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs, _reset) \ ++ (_dev)->ops->rx_ring_setup(_dev, _ring, _regs, _reset) + #define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) \ + (_dev)->ops->ppe_check(_dev, _skb, _reason, _hash) + #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) \ +@@ -251,7 +251,7 @@ static inline bool mtk_wed_device_active + #define mtk_wed_device_reg_write(_dev, _reg, _val) do {} while (0) + #define mtk_wed_device_irq_get(_dev, _mask) 0 + #define mtk_wed_device_irq_set_mask(_dev, _mask) do {} while (0) +-#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) -ENODEV ++#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs, _reset) -ENODEV + #define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) do {} while (0) + #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV + #define mtk_wed_device_stop(_dev) do {} while (0) diff --git a/target/linux/generic/hack-5.10/100-update-mtk_wed_h.patch b/target/linux/generic/hack-5.10/100-update-mtk_wed_h.patch index fe49100e4f..151f2e8054 100644 --- a/target/linux/generic/hack-5.10/100-update-mtk_wed_h.patch +++ b/target/linux/generic/hack-5.10/100-update-mtk_wed_h.patch @@ -77,11 +77,14 @@ struct mtk_wed_device { #ifdef CONFIG_NET_MEDIATEK_SOC_WED const struct mtk_wed_ops *ops; -@@ -28,30 +83,71 @@ struct mtk_wed_device { +@@ -28,30 +83,76 @@ struct mtk_wed_device { bool init_done, running; int wdma_idx; int irq; + u8 version; ++ ++ /* used by wlan driver */ ++ u32 rev_id; struct mtk_wed_ring tx_ring[MTK_WED_TX_QUEUES]; + struct mtk_wed_ring rx_ring[MTK_WED_RX_QUEUES]; @@ -148,15 +151,19 @@ + void (*release_rx_buf)(struct mtk_wed_device *wed); + void (*update_wo_rx_stats)(struct mtk_wed_device *wed, + struct mtk_wed_wo_rx_stats *stats); ++ int (*reset)(struct mtk_wed_device *wed); ++ void (*reset_complete)(struct mtk_wed_device *wed); } wlan; #endif }; -@@ -60,9 +156,15 @@ struct mtk_wed_ops { +@@ -59,10 +160,16 @@ struct mtk_wed_device { + struct mtk_wed_ops { int (*attach)(struct mtk_wed_device *dev); int (*tx_ring_setup)(struct mtk_wed_device *dev, int ring, - void __iomem *regs); +- void __iomem *regs); ++ void __iomem *regs, bool reset); + int (*rx_ring_setup)(struct mtk_wed_device *dev, int ring, -+ void __iomem *regs); ++ void __iomem *regs, bool reset); int (*txfree_ring_setup)(struct mtk_wed_device *dev, void __iomem *regs); + int (*msg_update)(struct mtk_wed_device *dev, int cmd_id, @@ -167,7 +174,7 @@ void (*stop)(struct mtk_wed_device *dev); void (*start)(struct mtk_wed_device *dev, u32 irq_mask); -@@ -97,6 +199,16 @@ mtk_wed_device_attach(struct mtk_wed_dev +@@ -97,12 +204,22 @@ mtk_wed_device_attach(struct mtk_wed_dev return ret; } @@ -184,26 +191,45 @@ #ifdef CONFIG_NET_MEDIATEK_SOC_WED #define mtk_wed_device_active(_dev) !!(_dev)->ops #define mtk_wed_device_detach(_dev) (_dev)->ops->detach(_dev) -@@ -113,6 +225,12 @@ mtk_wed_device_attach(struct mtk_wed_dev + #define mtk_wed_device_start(_dev, _mask) (_dev)->ops->start(_dev, _mask) +-#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs) \ +- (_dev)->ops->tx_ring_setup(_dev, _ring, _regs) ++#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs, _reset) \ ++ (_dev)->ops->tx_ring_setup(_dev, _ring, _regs, _reset) + #define mtk_wed_device_txfree_ring_setup(_dev, _regs) \ + (_dev)->ops->txfree_ring_setup(_dev, _regs) + #define mtk_wed_device_reg_read(_dev, _reg) \ +@@ -113,6 +230,14 @@ mtk_wed_device_attach(struct mtk_wed_dev (_dev)->ops->irq_get(_dev, _mask) #define mtk_wed_device_irq_set_mask(_dev, _mask) \ (_dev)->ops->irq_set_mask(_dev, _mask) -+#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) \ -+ (_dev)->ops->rx_ring_setup(_dev, _ring, _regs) ++#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs, _reset) \ ++ (_dev)->ops->rx_ring_setup(_dev, _ring, _regs, _reset) +#define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) \ + (_dev)->ops->ppe_check(_dev, _skb, _reason, _hash) +#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) \ + (_dev)->ops->msg_update(_dev, _id, _msg, _len) ++#define mtk_wed_device_stop(_dev) (_dev)->ops->stop(_dev) ++#define mtk_wed_device_dma_reset(_dev) (_dev)->ops->reset_dma(_dev) #else static inline bool mtk_wed_device_active(struct mtk_wed_device *dev) { -@@ -126,6 +244,9 @@ static inline bool mtk_wed_device_active +@@ -120,12 +245,17 @@ static inline bool mtk_wed_device_active + } + #define mtk_wed_device_detach(_dev) do {} while (0) + #define mtk_wed_device_start(_dev, _mask) do {} while (0) +-#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs) -ENODEV ++#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs, _reset) -ENODEV + #define mtk_wed_device_txfree_ring_setup(_dev, _ring, _regs) -ENODEV + #define mtk_wed_device_reg_read(_dev, _reg) 0 #define mtk_wed_device_reg_write(_dev, _reg, _val) do {} while (0) #define mtk_wed_device_irq_get(_dev, _mask) 0 #define mtk_wed_device_irq_set_mask(_dev, _mask) do {} while (0) -+#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) -ENODEV ++#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs, _reset) -ENODEV +#define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) do {} while (0) +#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV ++#define mtk_wed_device_stop(_dev) do {} while (0) ++#define mtk_wed_device_dma_reset(_dev) do {} while (0) #endif #endif diff --git a/target/linux/generic/pending-5.15/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch b/target/linux/generic/pending-5.15/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch index 3be68a9e35..b046c3eb5f 100644 --- a/target/linux/generic/pending-5.15/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch +++ b/target/linux/generic/pending-5.15/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch @@ -10,7 +10,7 @@ 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 -@@ -2802,8 +2802,8 @@ static irqreturn_t mtk_handle_irq_rx(int +@@ -2823,8 +2823,8 @@ static irqreturn_t mtk_handle_irq_rx(int eth->rx_events++; if (likely(napi_schedule_prep(ð->rx_napi))) { @@ -20,7 +20,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> } return IRQ_HANDLED; -@@ -2815,8 +2815,8 @@ static irqreturn_t mtk_handle_irq_tx(int +@@ -2836,8 +2836,8 @@ static irqreturn_t mtk_handle_irq_tx(int eth->tx_events++; if (likely(napi_schedule_prep(ð->tx_napi))) { @@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> } return IRQ_HANDLED; -@@ -4120,6 +4120,8 @@ static int mtk_probe(struct platform_dev +@@ -4350,6 +4350,8 @@ static int mtk_probe(struct platform_dev * for NAPI to work */ init_dummy_netdev(ð->dummy_dev); diff --git a/target/linux/generic/pending-5.15/731-net-ethernet-mediatek-ppe-add-support-for-flow-accou.patch b/target/linux/generic/pending-5.15/731-net-ethernet-mediatek-ppe-add-support-for-flow-accou.patch index c76a00eabd..26b88e4967 100644 --- a/target/linux/generic/pending-5.15/731-net-ethernet-mediatek-ppe-add-support-for-flow-accou.patch +++ b/target/linux/generic/pending-5.15/731-net-ethernet-mediatek-ppe-add-support-for-flow-accou.patch @@ -53,7 +53,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -4090,7 +4090,9 @@ static int mtk_probe(struct platform_dev +@@ -4320,7 +4320,9 @@ static int mtk_probe(struct platform_dev u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400; eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr, @@ -64,7 +64,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov if (!eth->ppe[i]) { err = -ENOMEM; goto err_free_dev; -@@ -4213,6 +4215,7 @@ static const struct mtk_soc_data mt7622_ +@@ -4445,6 +4447,7 @@ static const struct mtk_soc_data mt7622_ .required_pctl = false, .offload_version = 2, .hash_offset = 2, @@ -72,7 +72,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, .txrx = { .txd_size = sizeof(struct mtk_tx_dma), -@@ -4250,6 +4253,7 @@ static const struct mtk_soc_data mt7629_ +@@ -4482,6 +4485,7 @@ static const struct mtk_soc_data mt7629_ .hw_features = MTK_HW_FEATURES, .required_clks = MT7629_CLKS_BITMAP, .required_pctl = false, @@ -80,7 +80,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov .txrx = { .txd_size = sizeof(struct mtk_tx_dma), .rxd_size = sizeof(struct mtk_rx_dma), -@@ -4270,6 +4274,7 @@ static const struct mtk_soc_data mt7986_ +@@ -4502,6 +4506,7 @@ static const struct mtk_soc_data mt7986_ .offload_version = 2, .hash_offset = 4, .foe_entry_size = sizeof(struct mtk_foe_entry), @@ -90,7 +90,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov .rxd_size = sizeof(struct mtk_rx_dma_v2), --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -983,6 +983,7 @@ struct mtk_soc_data { +@@ -1007,6 +1007,7 @@ struct mtk_soc_data { u8 hash_offset; u16 foe_entry_size; netdev_features_t hw_features; @@ -171,8 +171,8 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov dma_wmb(); mtk_ppe_cache_clear(ppe); -@@ -716,14 +766,42 @@ int mtk_foe_entry_idle_time(struct mtk_p - return __mtk_foe_entry_idle_time(ppe, entry->data.ib1); +@@ -743,14 +793,42 @@ int mtk_ppe_prepare_reset(struct mtk_ppe + return mtk_ppe_wait_busy(ppe); } +struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index, @@ -215,7 +215,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov ppe = devm_kzalloc(dev, sizeof(*ppe), GFP_KERNEL); if (!ppe) -@@ -738,6 +816,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ +@@ -765,6 +843,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ ppe->eth = eth; ppe->dev = dev; ppe->version = version; @@ -223,7 +223,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov foe = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * soc->foe_entry_size, -@@ -753,6 +832,25 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ +@@ -780,6 +859,25 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ if (!ppe->foe_flow) return NULL; @@ -249,7 +249,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov mtk_ppe_debugfs_init(ppe, index); return ppe; -@@ -867,6 +965,16 @@ void mtk_ppe_start(struct mtk_ppe *ppe) +@@ -894,6 +992,16 @@ void mtk_ppe_start(struct mtk_ppe *ppe) ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT1, 0xcb777); ppe_w32(ppe, MTK_PPE_SBW_CTRL, 0x7f); } @@ -319,8 +319,8 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov + int version, int index, bool accounting); void mtk_ppe_start(struct mtk_ppe *ppe); int mtk_ppe_stop(struct mtk_ppe *ppe); - -@@ -354,5 +373,7 @@ int mtk_foe_entry_commit(struct mtk_ppe + int mtk_ppe_prepare_reset(struct mtk_ppe *ppe); +@@ -355,5 +374,7 @@ int mtk_foe_entry_commit(struct mtk_ppe void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index); @@ -386,7 +386,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov --- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h +++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h -@@ -143,6 +143,20 @@ enum { +@@ -149,6 +149,20 @@ enum { #define MTK_PPE_MIB_TB_BASE 0x338 diff --git a/target/linux/generic/pending-5.15/732-02-net-ethernet-mtk_eth_soc-increase-tx-ring-side-for-Q.patch b/target/linux/generic/pending-5.15/732-02-net-ethernet-mtk_eth_soc-increase-tx-ring-side-for-Q.patch index c6526a39a8..85c29e77de 100644 --- a/target/linux/generic/pending-5.15/732-02-net-ethernet-mtk_eth_soc-increase-tx-ring-side-for-Q.patch +++ b/target/linux/generic/pending-5.15/732-02-net-ethernet-mtk_eth_soc-increase-tx-ring-side-for-Q.patch @@ -12,7 +12,7 @@ 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 -@@ -894,7 +894,7 @@ static int mtk_init_fq_dma(struct mtk_et +@@ -900,7 +900,7 @@ static int mtk_init_fq_dma(struct mtk_et { const struct mtk_soc_data *soc = eth->soc; dma_addr_t phy_ring_tail; @@ -21,7 +21,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> dma_addr_t dma_addr; int i; -@@ -2148,19 +2148,25 @@ static int mtk_tx_alloc(struct mtk_eth * +@@ -2154,19 +2154,25 @@ static int mtk_tx_alloc(struct mtk_eth * struct mtk_tx_ring *ring = ð->tx_ring; int i, sz = soc->txrx.txd_size; struct mtk_tx_dma_v2 *txd; @@ -51,7 +51,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> u32 next_ptr = ring->phys + next * sz; txd = ring->dma + i * sz; -@@ -2180,22 +2186,22 @@ static int mtk_tx_alloc(struct mtk_eth * +@@ -2186,22 +2192,22 @@ static int mtk_tx_alloc(struct mtk_eth * * descriptors in ring->dma_pdma. */ if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) { @@ -79,7 +79,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> ring->thresh = MAX_SKB_FRAGS; /* make sure that all changes to the dma ring are flushed before we -@@ -2207,14 +2213,14 @@ static int mtk_tx_alloc(struct mtk_eth * +@@ -2213,14 +2219,14 @@ static int mtk_tx_alloc(struct mtk_eth * mtk_w32(eth, ring->phys, soc->reg_map->qdma.ctx_ptr); mtk_w32(eth, ring->phys, soc->reg_map->qdma.dtx_ptr); mtk_w32(eth, @@ -96,7 +96,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> mtk_w32(eth, 0, MT7628_TX_CTX_IDX0); mtk_w32(eth, MT7628_PST_DTX_IDX0, soc->reg_map->pdma.rst_idx); } -@@ -2232,7 +2238,7 @@ static void mtk_tx_clean(struct mtk_eth +@@ -2238,7 +2244,7 @@ static void mtk_tx_clean(struct mtk_eth int i; if (ring->buf) { @@ -105,7 +105,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> mtk_tx_unmap(eth, &ring->buf[i], false); kfree(ring->buf); ring->buf = NULL; -@@ -2240,14 +2246,14 @@ static void mtk_tx_clean(struct mtk_eth +@@ -2246,14 +2252,14 @@ static void mtk_tx_clean(struct mtk_eth if (ring->dma) { dma_free_coherent(eth->dma_dev, @@ -122,7 +122,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> ring->dma_pdma, ring->phys_pdma); ring->dma_pdma = NULL; } -@@ -2767,7 +2773,7 @@ static void mtk_dma_free(struct mtk_eth +@@ -2773,7 +2779,7 @@ static void mtk_dma_free(struct mtk_eth netdev_reset_queue(eth->netdev[i]); if (eth->scratch_ring) { dma_free_coherent(eth->dma_dev, diff --git a/target/linux/generic/pending-5.15/732-03-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch b/target/linux/generic/pending-5.15/732-03-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch index 2e9594c872..8c425bc8c4 100644 --- a/target/linux/generic/pending-5.15/732-03-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch +++ b/target/linux/generic/pending-5.15/732-03-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch @@ -12,7 +12,7 @@ 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 -@@ -4199,7 +4199,7 @@ static const struct mtk_soc_data mt7621_ +@@ -4431,7 +4431,7 @@ static const struct mtk_soc_data mt7621_ .hw_features = MTK_HW_FEATURES, .required_clks = MT7621_CLKS_BITMAP, .required_pctl = false, @@ -21,7 +21,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> .hash_offset = 2, .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, .txrx = { -@@ -4239,7 +4239,7 @@ static const struct mtk_soc_data mt7623_ +@@ -4471,7 +4471,7 @@ static const struct mtk_soc_data mt7623_ .hw_features = MTK_HW_FEATURES, .required_clks = MT7623_CLKS_BITMAP, .required_pctl = true, diff --git a/target/linux/generic/pending-5.15/732-04-net-ethernet-mtk_eth_soc-implement-multi-queue-suppo.patch b/target/linux/generic/pending-5.15/732-04-net-ethernet-mtk_eth_soc-implement-multi-queue-suppo.patch index 0e817cd272..8a801f77e8 100644 --- a/target/linux/generic/pending-5.15/732-04-net-ethernet-mtk_eth_soc-implement-multi-queue-suppo.patch +++ b/target/linux/generic/pending-5.15/732-04-net-ethernet-mtk_eth_soc-implement-multi-queue-suppo.patch @@ -22,7 +22,7 @@ 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 -@@ -54,6 +54,7 @@ static const struct mtk_reg_map mtk_reg_ +@@ -55,6 +55,7 @@ static const struct mtk_reg_map mtk_reg_ }, .qdma = { .qtx_cfg = 0x1800, @@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> .rx_ptr = 0x1900, .rx_cnt_cfg = 0x1904, .qcrx_ptr = 0x1908, -@@ -61,6 +62,7 @@ static const struct mtk_reg_map mtk_reg_ +@@ -62,6 +63,7 @@ static const struct mtk_reg_map mtk_reg_ .rst_idx = 0x1a08, .delay_irq = 0x1a0c, .fc_th = 0x1a10, @@ -38,7 +38,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> .int_grp = 0x1a20, .hred = 0x1a44, .ctx_ptr = 0x1b00, -@@ -113,6 +115,7 @@ static const struct mtk_reg_map mt7986_r +@@ -117,6 +119,7 @@ static const struct mtk_reg_map mt7986_r }, .qdma = { .qtx_cfg = 0x4400, @@ -46,7 +46,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> .rx_ptr = 0x4500, .rx_cnt_cfg = 0x4504, .qcrx_ptr = 0x4508, -@@ -130,6 +133,7 @@ static const struct mtk_reg_map mt7986_r +@@ -134,6 +137,7 @@ static const struct mtk_reg_map mt7986_r .fq_tail = 0x4724, .fq_count = 0x4728, .fq_blen = 0x472c, @@ -54,7 +54,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> }, .gdm1_cnt = 0x1c00, .gdma_to_ppe0 = 0x3333, -@@ -570,6 +574,75 @@ static void mtk_mac_link_down(struct phy +@@ -576,6 +580,75 @@ static void mtk_mac_link_down(struct phy mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id)); } @@ -130,7 +130,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> static void mtk_mac_link_up(struct phylink_config *config, struct phy_device *phy, unsigned int mode, phy_interface_t interface, -@@ -595,6 +668,8 @@ static void mtk_mac_link_up(struct phyli +@@ -601,6 +674,8 @@ static void mtk_mac_link_up(struct phyli break; } @@ -139,7 +139,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> /* Configure duplex */ if (duplex == DUPLEX_FULL) mcr |= MAC_MCR_FORCE_DPX; -@@ -1053,7 +1128,8 @@ static void mtk_tx_set_dma_desc_v1(struc +@@ -1059,7 +1134,8 @@ static void mtk_tx_set_dma_desc_v1(struc WRITE_ONCE(desc->txd1, info->addr); @@ -149,7 +149,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> if (info->last) data |= TX_DMA_LS0; WRITE_ONCE(desc->txd3, data); -@@ -1087,9 +1163,6 @@ static void mtk_tx_set_dma_desc_v2(struc +@@ -1093,9 +1169,6 @@ static void mtk_tx_set_dma_desc_v2(struc data |= TX_DMA_LS0; WRITE_ONCE(desc->txd3, data); @@ -159,7 +159,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */ data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid); WRITE_ONCE(desc->txd4, data); -@@ -1133,11 +1206,12 @@ static int mtk_tx_map(struct sk_buff *sk +@@ -1139,11 +1212,12 @@ static int mtk_tx_map(struct sk_buff *sk .gso = gso, .csum = skb->ip_summed == CHECKSUM_PARTIAL, .vlan = skb_vlan_tag_present(skb), @@ -173,7 +173,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> struct mtk_mac *mac = netdev_priv(dev); struct mtk_eth *eth = mac->hw; const struct mtk_soc_data *soc = eth->soc; -@@ -1145,8 +1219,10 @@ static int mtk_tx_map(struct sk_buff *sk +@@ -1151,8 +1225,10 @@ static int mtk_tx_map(struct sk_buff *sk struct mtk_tx_dma *itxd_pdma, *txd_pdma; struct mtk_tx_buf *itx_buf, *tx_buf; int i, n_desc = 1; @@ -184,7 +184,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> itxd = ring->next_free; itxd_pdma = qdma_to_pdma(ring, itxd); if (itxd == ring->last_free) -@@ -1195,7 +1271,7 @@ static int mtk_tx_map(struct sk_buff *sk +@@ -1201,7 +1277,7 @@ static int mtk_tx_map(struct sk_buff *sk memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info)); txd_info.size = min_t(unsigned int, frag_size, soc->txrx.dma_max_len); @@ -193,7 +193,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> txd_info.last = i == skb_shinfo(skb)->nr_frags - 1 && !(frag_size - txd_info.size); txd_info.addr = skb_frag_dma_map(eth->dma_dev, frag, -@@ -1234,7 +1310,7 @@ static int mtk_tx_map(struct sk_buff *sk +@@ -1240,7 +1316,7 @@ static int mtk_tx_map(struct sk_buff *sk txd_pdma->txd2 |= TX_DMA_LS1; } @@ -202,7 +202,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> skb_tx_timestamp(skb); ring->next_free = mtk_qdma_phys_to_virt(ring, txd->txd2); -@@ -1246,8 +1322,7 @@ static int mtk_tx_map(struct sk_buff *sk +@@ -1252,8 +1328,7 @@ static int mtk_tx_map(struct sk_buff *sk wmb(); if (MTK_HAS_CAPS(soc->caps, MTK_QDMA)) { @@ -212,7 +212,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> mtk_w32(eth, txd->txd2, soc->reg_map->qdma.ctx_ptr); } else { int next_idx; -@@ -1316,7 +1391,7 @@ static void mtk_wake_queue(struct mtk_et +@@ -1322,7 +1397,7 @@ static void mtk_wake_queue(struct mtk_et for (i = 0; i < MTK_MAC_COUNT; i++) { if (!eth->netdev[i]) continue; @@ -221,7 +221,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> } } -@@ -1340,7 +1415,7 @@ static netdev_tx_t mtk_start_xmit(struct +@@ -1346,7 +1421,7 @@ static netdev_tx_t mtk_start_xmit(struct tx_num = mtk_cal_txd_req(eth, skb); if (unlikely(atomic_read(&ring->free_count) <= tx_num)) { @@ -230,7 +230,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> netif_err(eth, tx_queued, dev, "Tx Ring full when queue awake!\n"); spin_unlock(ð->page_lock); -@@ -1366,7 +1441,7 @@ static netdev_tx_t mtk_start_xmit(struct +@@ -1372,7 +1447,7 @@ static netdev_tx_t mtk_start_xmit(struct goto drop; if (unlikely(atomic_read(&ring->free_count) <= ring->thresh)) @@ -239,7 +239,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> spin_unlock(ð->page_lock); -@@ -1533,10 +1608,12 @@ static int mtk_xdp_submit_frame(struct m +@@ -1539,10 +1614,12 @@ static int mtk_xdp_submit_frame(struct m struct skb_shared_info *sinfo = xdp_get_shared_info_from_frame(xdpf); const struct mtk_soc_data *soc = eth->soc; struct mtk_tx_ring *ring = ð->tx_ring; @@ -252,7 +252,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> }; int err, index = 0, n_desc = 1, nr_frags; struct mtk_tx_dma *htxd, *txd, *txd_pdma; -@@ -1587,6 +1664,7 @@ static int mtk_xdp_submit_frame(struct m +@@ -1593,6 +1670,7 @@ static int mtk_xdp_submit_frame(struct m memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info)); txd_info.size = skb_frag_size(&sinfo->frags[index]); txd_info.last = index + 1 == nr_frags; @@ -260,7 +260,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> data = skb_frag_address(&sinfo->frags[index]); index++; -@@ -1938,8 +2016,46 @@ rx_done: +@@ -1944,8 +2022,46 @@ rx_done: return done; } @@ -308,7 +308,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> { const struct mtk_reg_map *reg_map = eth->soc->reg_map; struct mtk_tx_ring *ring = ð->tx_ring; -@@ -1969,12 +2085,9 @@ static int mtk_poll_tx_qdma(struct mtk_e +@@ -1975,12 +2091,9 @@ static int mtk_poll_tx_qdma(struct mtk_e break; if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { @@ -323,7 +323,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> budget--; } mtk_tx_unmap(eth, tx_buf, true); -@@ -1992,7 +2105,7 @@ static int mtk_poll_tx_qdma(struct mtk_e +@@ -1998,7 +2111,7 @@ static int mtk_poll_tx_qdma(struct mtk_e } static int mtk_poll_tx_pdma(struct mtk_eth *eth, int budget, @@ -332,7 +332,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> { struct mtk_tx_ring *ring = ð->tx_ring; struct mtk_tx_buf *tx_buf; -@@ -2008,12 +2121,8 @@ static int mtk_poll_tx_pdma(struct mtk_e +@@ -2014,12 +2127,8 @@ static int mtk_poll_tx_pdma(struct mtk_e break; if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { @@ -347,7 +347,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> budget--; } mtk_tx_unmap(eth, tx_buf, true); -@@ -2034,26 +2143,15 @@ static int mtk_poll_tx(struct mtk_eth *e +@@ -2040,26 +2149,15 @@ static int mtk_poll_tx(struct mtk_eth *e { struct mtk_tx_ring *ring = ð->tx_ring; struct dim_sample dim_sample = {}; @@ -379,7 +379,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> dim_update_sample(eth->tx_events, eth->tx_packets, eth->tx_bytes, &dim_sample); -@@ -2063,7 +2161,7 @@ static int mtk_poll_tx(struct mtk_eth *e +@@ -2069,7 +2167,7 @@ static int mtk_poll_tx(struct mtk_eth *e (atomic_read(&ring->free_count) > ring->thresh)) mtk_wake_queue(eth); @@ -388,7 +388,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> } static void mtk_handle_status_irq(struct mtk_eth *eth) -@@ -2149,6 +2247,7 @@ static int mtk_tx_alloc(struct mtk_eth * +@@ -2155,6 +2253,7 @@ static int mtk_tx_alloc(struct mtk_eth * int i, sz = soc->txrx.txd_size; struct mtk_tx_dma_v2 *txd; int ring_size; @@ -396,7 +396,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> if (MTK_HAS_CAPS(soc->caps, MTK_QDMA)) ring_size = MTK_QDMA_RING_SIZE; -@@ -2216,8 +2315,25 @@ static int mtk_tx_alloc(struct mtk_eth * +@@ -2222,8 +2321,25 @@ static int mtk_tx_alloc(struct mtk_eth * ring->phys + ((ring_size - 1) * sz), soc->reg_map->qdma.crx_ptr); mtk_w32(eth, ring->last_free_ptr, soc->reg_map->qdma.drx_ptr); @@ -424,7 +424,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> } else { mtk_w32(eth, ring->phys_pdma, MT7628_TX_BASE_PTR0); mtk_w32(eth, ring_size, MT7628_TX_MAX_CNT0); -@@ -2882,7 +2998,7 @@ static int mtk_start_dma(struct mtk_eth +@@ -2903,7 +3019,7 @@ static int mtk_start_dma(struct mtk_eth if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) val |= MTK_MUTLI_CNT | MTK_RESV_BUF | MTK_WCOMP_EN | MTK_DMAD_WR_WDONE | @@ -433,7 +433,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> else val |= MTK_RX_BT_32DWORDS; mtk_w32(eth, val, reg_map->qdma.glo_cfg); -@@ -2928,6 +3044,45 @@ static void mtk_gdm_config(struct mtk_et +@@ -2949,6 +3065,45 @@ static void mtk_gdm_config(struct mtk_et mtk_w32(eth, 0, MTK_RST_GL); } @@ -479,7 +479,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> static int mtk_open(struct net_device *dev) { struct mtk_mac *mac = netdev_priv(dev); -@@ -2972,7 +3127,8 @@ static int mtk_open(struct net_device *d +@@ -2993,7 +3148,8 @@ static int mtk_open(struct net_device *d refcount_inc(ð->dma_refcnt); phylink_start(mac->phylink); @@ -489,7 +489,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> return 0; } -@@ -3488,8 +3644,12 @@ static int mtk_unreg_dev(struct mtk_eth +@@ -3716,8 +3872,12 @@ static int mtk_unreg_dev(struct mtk_eth int i; for (i = 0; i < MTK_MAC_COUNT; i++) { @@ -502,7 +502,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> unregister_netdev(eth->netdev[i]); } -@@ -3705,6 +3865,23 @@ static int mtk_set_rxnfc(struct net_devi +@@ -3934,6 +4094,23 @@ static int mtk_set_rxnfc(struct net_devi return ret; } @@ -526,7 +526,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> static const struct ethtool_ops mtk_ethtool_ops = { .get_link_ksettings = mtk_get_link_ksettings, .set_link_ksettings = mtk_set_link_ksettings, -@@ -3740,6 +3917,7 @@ static const struct net_device_ops mtk_n +@@ -3969,6 +4146,7 @@ static const struct net_device_ops mtk_n .ndo_setup_tc = mtk_eth_setup_tc, .ndo_bpf = mtk_xdp, .ndo_xdp_xmit = mtk_xdp_xmit, @@ -534,7 +534,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> }; static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) -@@ -3749,6 +3927,7 @@ static int mtk_add_mac(struct mtk_eth *e +@@ -3978,6 +4156,7 @@ static int mtk_add_mac(struct mtk_eth *e struct phylink *phylink; struct mtk_mac *mac; int id, err; @@ -542,7 +542,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> if (!_id) { dev_err(eth->dev, "missing mac id\n"); -@@ -3766,7 +3945,10 @@ static int mtk_add_mac(struct mtk_eth *e +@@ -3995,7 +4174,10 @@ static int mtk_add_mac(struct mtk_eth *e return -EINVAL; } @@ -554,7 +554,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> if (!eth->netdev[id]) { dev_err(eth->dev, "alloc_etherdev failed\n"); return -ENOMEM; -@@ -3863,6 +4045,11 @@ static int mtk_add_mac(struct mtk_eth *e +@@ -4092,6 +4274,11 @@ static int mtk_add_mac(struct mtk_eth *e else eth->netdev[id]->max_mtu = MTK_MAX_RX_LENGTH_2K - MTK_RX_ETH_HLEN; @@ -576,7 +576,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> #define MTK_QDMA_PAGE_SIZE 2048 #define MTK_MAX_RX_LENGTH 1536 #define MTK_MAX_RX_LENGTH_2K 2048 -@@ -203,8 +204,26 @@ +@@ -215,8 +216,26 @@ #define MTK_RING_MAX_AGG_CNT_H ((MTK_HW_LRO_MAX_AGG_CNT >> 6) & 0x3) /* QDMA TX Queue Configuration Registers */ @@ -603,7 +603,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> /* QDMA Global Configuration Register */ #define MTK_RX_2B_OFFSET BIT(31) #define MTK_RX_BT_32DWORDS (3 << 11) -@@ -223,6 +242,7 @@ +@@ -235,6 +254,7 @@ #define MTK_WCOMP_EN BIT(24) #define MTK_RESV_BUF (0x40 << 16) #define MTK_MUTLI_CNT (0x4 << 12) @@ -611,7 +611,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> /* QDMA Flow Control Register */ #define FC_THRES_DROP_MODE BIT(20) -@@ -251,8 +271,6 @@ +@@ -265,8 +285,6 @@ #define MTK_STAT_OFFSET 0x40 /* QDMA TX NUM */ @@ -620,7 +620,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> #define QID_BITS_V2(x) (((x) & 0x3f) << 16) #define MTK_QDMA_GMAC2_QID 8 -@@ -282,6 +300,7 @@ +@@ -296,6 +314,7 @@ #define TX_DMA_PLEN0(x) (((x) & eth->soc->txrx.dma_max_len) << eth->soc->txrx.dma_len_offset) #define TX_DMA_PLEN1(x) ((x) & eth->soc->txrx.dma_max_len) #define TX_DMA_SWC BIT(14) @@ -628,7 +628,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> /* PDMA on MT7628 */ #define TX_DMA_DONE BIT(31) -@@ -930,6 +949,7 @@ struct mtk_reg_map { +@@ -952,6 +971,7 @@ struct mtk_reg_map { } pdma; struct { u32 qtx_cfg; /* tx queue configuration */ @@ -636,7 +636,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> u32 rx_ptr; /* rx base pointer */ u32 rx_cnt_cfg; /* rx max count configuration */ u32 qcrx_ptr; /* rx cpu pointer */ -@@ -947,6 +967,7 @@ struct mtk_reg_map { +@@ -969,6 +989,7 @@ struct mtk_reg_map { u32 fq_tail; /* fq tail pointer */ u32 fq_count; /* fq free page count */ u32 fq_blen; /* fq free page buffer length */ @@ -644,7 +644,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> } qdma; u32 gdm1_cnt; u32 gdma_to_ppe0; -@@ -1139,6 +1160,7 @@ struct mtk_mac { +@@ -1173,6 +1194,7 @@ struct mtk_mac { __be32 hwlro_ip[MTK_MAX_LRO_IP_CNT]; int hwlro_ip_cnt; unsigned int syscfg0; diff --git a/target/linux/generic/pending-5.15/732-06-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch b/target/linux/generic/pending-5.15/732-06-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch index 05161c3479..8a7cb9f91e 100644 --- a/target/linux/generic/pending-5.15/732-06-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch +++ b/target/linux/generic/pending-5.15/732-06-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch @@ -47,7 +47,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> #define MTK_FOE_IB2_DEST_PORT_V2 GENMASK(12, 9) #define MTK_FOE_IB2_MULTICAST_V2 BIT(13) #define MTK_FOE_IB2_WDMA_WINFO_V2 BIT(19) -@@ -369,6 +371,8 @@ int mtk_foe_entry_set_pppoe(struct mtk_e +@@ -370,6 +372,8 @@ int mtk_foe_entry_set_pppoe(struct mtk_e int sid); int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry, int wdma_idx, int txq, int bss, int wcid); diff --git a/target/linux/generic/pending-5.15/732-07-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch b/target/linux/generic/pending-5.15/732-07-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch index 8c711ba802..d7e7492aa2 100644 --- a/target/linux/generic/pending-5.15/732-07-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch +++ b/target/linux/generic/pending-5.15/732-07-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch @@ -11,7 +11,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -895,7 +895,13 @@ enum mkt_eth_capabilities { +@@ -916,7 +916,13 @@ enum mkt_eth_capabilities { #define MTK_MUX_GMAC12_TO_GEPHY_SGMII \ (MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX) diff --git a/target/linux/generic/pending-5.15/732-09-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch b/target/linux/generic/pending-5.15/732-09-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch index 933112c17a..a130358101 100644 --- a/target/linux/generic/pending-5.15/732-09-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch +++ b/target/linux/generic/pending-5.15/732-09-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch @@ -22,7 +22,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> #include "mtk_eth_soc.h" #include "mtk_wed.h" -@@ -1967,16 +1968,22 @@ static int mtk_poll_rx(struct napi_struc +@@ -1973,16 +1974,22 @@ static int mtk_poll_rx(struct napi_struc htons(RX_DMA_VPID(trxd.rxd4)), RX_DMA_VID(trxd.rxd4)); } else if (trxd.rxd2 & RX_DMA_VTAG) { @@ -52,7 +52,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> } skb_record_rx_queue(skb, 0); -@@ -2793,15 +2800,30 @@ static netdev_features_t mtk_fix_feature +@@ -2799,15 +2806,30 @@ static netdev_features_t mtk_fix_feature static int mtk_set_features(struct net_device *dev, netdev_features_t features) { @@ -88,7 +88,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> } /* wait for DMA to finish whatever it is doing before we start using it again */ -@@ -3083,11 +3105,45 @@ found: +@@ -3104,11 +3126,45 @@ found: return NOTIFY_DONE; } @@ -135,7 +135,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0); if (err) { -@@ -3419,6 +3475,10 @@ static int mtk_hw_init(struct mtk_eth *e +@@ -3631,6 +3687,10 @@ static int mtk_hw_init(struct mtk_eth *e */ val = mtk_r32(eth, MTK_CDMQ_IG_CTRL); mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL); @@ -146,7 +146,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> /* Enable RX VLan Offloading */ mtk_w32(eth, 1, MTK_CDMP_EG_CTRL); -@@ -3636,6 +3696,12 @@ static int mtk_free_dev(struct mtk_eth * +@@ -3864,6 +3924,12 @@ static int mtk_free_dev(struct mtk_eth * free_netdev(eth->netdev[i]); } @@ -171,7 +171,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> #define MTK_QDMA_NUM_QUEUES 16 #define MTK_QDMA_PAGE_SIZE 2048 #define MTK_MAX_RX_LENGTH 1536 -@@ -93,6 +96,9 @@ +@@ -105,6 +108,9 @@ #define MTK_CDMQ_IG_CTRL 0x1400 #define MTK_CDMQ_STAG_EN BIT(0) @@ -181,7 +181,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> /* CDMP Ingress Control Register */ #define MTK_CDMP_IG_CTRL 0x400 #define MTK_CDMP_STAG_EN BIT(0) -@@ -1140,6 +1146,8 @@ struct mtk_eth { +@@ -1166,6 +1172,8 @@ struct mtk_eth { int ip_align; diff --git a/target/linux/generic/pending-5.15/732-10-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch b/target/linux/generic/pending-5.15/732-10-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch index f19128d809..777e6f0ed1 100644 --- a/target/linux/generic/pending-5.15/732-10-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch +++ b/target/linux/generic/pending-5.15/732-10-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch @@ -16,7 +16,7 @@ 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 -@@ -1396,12 +1396,28 @@ static void mtk_wake_queue(struct mtk_et +@@ -1402,12 +1402,28 @@ static void mtk_wake_queue(struct mtk_et } } @@ -45,7 +45,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> bool gso = false; int tx_num; -@@ -1423,6 +1439,18 @@ static netdev_tx_t mtk_start_xmit(struct +@@ -1429,6 +1445,18 @@ static netdev_tx_t mtk_start_xmit(struct return NETDEV_TX_BUSY; } @@ -64,7 +64,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> /* TSO: fill MSS info in tcp checksum field */ if (skb_is_gso(skb)) { if (skb_cow_head(skb, 0)) { -@@ -1438,8 +1466,14 @@ static netdev_tx_t mtk_start_xmit(struct +@@ -1444,8 +1472,14 @@ static netdev_tx_t mtk_start_xmit(struct } } @@ -83,7 +83,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> netif_tx_stop_all_queues(dev); --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -246,7 +246,7 @@ +@@ -258,7 +258,7 @@ #define MTK_CHK_DDONE_EN BIT(28) #define MTK_DMAD_WR_WDONE BIT(26) #define MTK_WCOMP_EN BIT(24) diff --git a/target/linux/generic/pending-5.15/732-12-net-ethernet-mtk_eth_soc-drop-packets-to-WDMA-if-the.patch b/target/linux/generic/pending-5.15/732-12-net-ethernet-mtk_eth_soc-drop-packets-to-WDMA-if-the.patch index 416dfb6cf7..6c81d880f9 100644 --- a/target/linux/generic/pending-5.15/732-12-net-ethernet-mtk_eth_soc-drop-packets-to-WDMA-if-the.patch +++ b/target/linux/generic/pending-5.15/732-12-net-ethernet-mtk_eth_soc-drop-packets-to-WDMA-if-the.patch @@ -11,7 +11,7 @@ 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 -@@ -3533,9 +3533,12 @@ static int mtk_hw_init(struct mtk_eth *e +@@ -3745,9 +3745,12 @@ static int mtk_hw_init(struct mtk_eth *e mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP); if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { @@ -27,7 +27,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -127,6 +127,7 @@ +@@ -139,6 +139,7 @@ #define PSE_FQFC_CFG1 0x100 #define PSE_FQFC_CFG2 0x104 #define PSE_DROP_CFG 0x108 diff --git a/target/linux/generic/pending-5.15/732-14-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch b/target/linux/generic/pending-5.15/732-14-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch index 0d575b84a0..128501f38c 100644 --- a/target/linux/generic/pending-5.15/732-14-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch +++ b/target/linux/generic/pending-5.15/732-14-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch @@ -17,7 +17,7 @@ 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 -@@ -1995,29 +1995,16 @@ static int mtk_poll_rx(struct napi_struc +@@ -2001,29 +2001,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); @@ -50,7 +50,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> } skb_record_rx_queue(skb, 0); -@@ -2834,29 +2821,11 @@ static netdev_features_t mtk_fix_feature +@@ -2840,29 +2827,11 @@ static netdev_features_t mtk_fix_feature static int mtk_set_features(struct net_device *dev, netdev_features_t features) { @@ -80,7 +80,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> return 0; } -@@ -3155,30 +3124,6 @@ static int mtk_open(struct net_device *d +@@ -3176,30 +3145,6 @@ static int mtk_open(struct net_device *d struct mtk_eth *eth = mac->hw; int i, err; @@ -111,7 +111,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0); if (err) { netdev_err(dev, "%s: could not attach PHY: %d\n", __func__, -@@ -3219,6 +3164,35 @@ static int mtk_open(struct net_device *d +@@ -3240,6 +3185,35 @@ static int mtk_open(struct net_device *d phylink_start(mac->phylink); netif_tx_start_all_queues(dev); @@ -147,7 +147,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> return 0; } -@@ -3512,10 +3486,9 @@ static int mtk_hw_init(struct mtk_eth *e +@@ -3724,10 +3698,9 @@ static int mtk_hw_init(struct mtk_eth *e if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { val = mtk_r32(eth, MTK_CDMP_IG_CTRL); mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL); @@ -160,7 +160,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> /* set interrupt delays based on current Net DIM sample */ mtk_dim_rx(ð->rx_dim.work); -@@ -4136,7 +4109,7 @@ static int mtk_add_mac(struct mtk_eth *e +@@ -4365,7 +4338,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 & diff --git a/target/linux/generic/pending-5.15/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch b/target/linux/generic/pending-5.15/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch index 39d6d0c879..7bd4df5fff 100644 --- a/target/linux/generic/pending-5.15/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch +++ b/target/linux/generic/pending-5.15/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch @@ -12,7 +12,7 @@ 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 -@@ -1992,9 +1992,6 @@ static int mtk_poll_rx(struct napi_struc +@@ -1998,9 +1998,6 @@ static int mtk_poll_rx(struct napi_struc skb_checksum_none_assert(skb); skb->protocol = eth_type_trans(skb, netdev); @@ -22,7 +22,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> /* When using VLAN untagging in combination with DSA, the * hardware treats the MTK special tag as a VLAN and untags it. */ -@@ -2007,6 +2004,9 @@ static int mtk_poll_rx(struct napi_struc +@@ -2013,6 +2010,9 @@ static int mtk_poll_rx(struct napi_struc skb_dst_set_noref(skb, ð->dsa_meta[port]->dst); } diff --git a/target/linux/mediatek/patches-5.15/703-v5.17-net-ethernet-mtk_eth_soc-implement-Clause-45-MDIO-ac.patch b/target/linux/mediatek/patches-5.15/703-v5.17-net-ethernet-mtk_eth_soc-implement-Clause-45-MDIO-ac.patch index 82cd4088c9..757750832c 100644 --- a/target/linux/mediatek/patches-5.15/703-v5.17-net-ethernet-mtk_eth_soc-implement-Clause-45-MDIO-ac.patch +++ b/target/linux/mediatek/patches-5.15/703-v5.17-net-ethernet-mtk_eth_soc-implement-Clause-45-MDIO-ac.patch @@ -20,7 +20,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net> --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -224,13 +224,35 @@ static int _mtk_mdio_write(struct mtk_et +@@ -230,13 +230,35 @@ static int _mtk_mdio_write(struct mtk_et if (ret < 0) return ret; @@ -63,7 +63,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net> ret = mtk_mdio_busy_wait(eth); if (ret < 0) -@@ -247,12 +269,33 @@ static int _mtk_mdio_read(struct mtk_eth +@@ -253,12 +275,33 @@ static int _mtk_mdio_read(struct mtk_eth if (ret < 0) return ret; @@ -103,7 +103,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net> ret = mtk_mdio_busy_wait(eth); if (ret < 0) -@@ -720,6 +763,7 @@ static int mtk_mdio_init(struct mtk_eth +@@ -726,6 +769,7 @@ static int mtk_mdio_init(struct mtk_eth eth->mii_bus->name = "mdio"; eth->mii_bus->read = mtk_mdio_read; eth->mii_bus->write = mtk_mdio_write; @@ -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 -@@ -355,9 +355,12 @@ +@@ -369,9 +369,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) |