003ca9bae69969dd35e9a4140681e9dd66536e35
[openwrt/staging/ldir.git] /
1 From: Lorenzo Bianconi <lorenzo@kernel.org>
2 Date: Thu, 17 Nov 2022 00:35:04 +0100
3 Subject: [PATCH] net: ethernet: mtk_eth_soc: do not overwrite mtu
4 configuration running reset routine
5
6 Restore user configured MTU running mtk_hw_init() during tx timeout routine
7 since it will be overwritten after a hw reset.
8
9 Reported-by: Felix Fietkau <nbd@nbd.name>
10 Fixes: 9ea4d311509f ("net: ethernet: mediatek: add the whole ethernet reset into the reset process")
11 Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
12 Signed-off-by: David S. Miller <davem@davemloft.net>
13 ---
14
15 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
16 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
17 @@ -3176,6 +3176,30 @@ static void mtk_dim_tx(struct work_struc
18 dim->state = DIM_START_MEASURE;
19 }
20
21 +static void mtk_set_mcr_max_rx(struct mtk_mac *mac, u32 val)
22 +{
23 + struct mtk_eth *eth = mac->hw;
24 + u32 mcr_cur, mcr_new;
25 +
26 + if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
27 + return;
28 +
29 + mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
30 + mcr_new = mcr_cur & ~MAC_MCR_MAX_RX_MASK;
31 +
32 + if (val <= 1518)
33 + mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1518);
34 + else if (val <= 1536)
35 + mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1536);
36 + else if (val <= 1552)
37 + mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1552);
38 + else
39 + mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_2048);
40 +
41 + if (mcr_new != mcr_cur)
42 + mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id));
43 +}
44 +
45 static int mtk_hw_init(struct mtk_eth *eth)
46 {
47 u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA |
48 @@ -3250,8 +3274,16 @@ static int mtk_hw_init(struct mtk_eth *e
49 * up with the more appropriate value when mtk_mac_config call is being
50 * invoked.
51 */
52 - for (i = 0; i < MTK_MAC_COUNT; i++)
53 + for (i = 0; i < MTK_MAC_COUNT; i++) {
54 + struct net_device *dev = eth->netdev[i];
55 +
56 mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i));
57 + if (dev) {
58 + struct mtk_mac *mac = netdev_priv(dev);
59 +
60 + mtk_set_mcr_max_rx(mac, dev->mtu + MTK_RX_ETH_HLEN);
61 + }
62 + }
63
64 /* Indicates CDM to parse the MTK special tag from CPU
65 * which also is working out for untag packets.
66 @@ -3367,7 +3399,6 @@ static int mtk_change_mtu(struct net_dev
67 int length = new_mtu + MTK_RX_ETH_HLEN;
68 struct mtk_mac *mac = netdev_priv(dev);
69 struct mtk_eth *eth = mac->hw;
70 - u32 mcr_cur, mcr_new;
71
72 if (rcu_access_pointer(eth->prog) &&
73 length > MTK_PP_MAX_BUF_SIZE) {
74 @@ -3375,23 +3406,7 @@ static int mtk_change_mtu(struct net_dev
75 return -EINVAL;
76 }
77
78 - if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) {
79 - mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
80 - mcr_new = mcr_cur & ~MAC_MCR_MAX_RX_MASK;
81 -
82 - if (length <= 1518)
83 - mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1518);
84 - else if (length <= 1536)
85 - mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1536);
86 - else if (length <= 1552)
87 - mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1552);
88 - else
89 - mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_2048);
90 -
91 - if (mcr_new != mcr_cur)
92 - mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id));
93 - }
94 -
95 + mtk_set_mcr_max_rx(mac, length);
96 dev->mtu = new_mtu;
97
98 return 0;