From: Rafał Miłecki Date: Mon, 1 Mar 2021 07:14:49 +0000 (+0100) Subject: bcm4908: backport Ethernet driver fixes from the 5.12 X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=67df3a829b33dfaa8068209d31246296985e9888;p=openwrt%2Fstaging%2F981213.git bcm4908: backport Ethernet driver fixes from the 5.12 The most noticeable one is fix for RX stopping on high traffic. Signed-off-by: Rafał Miłecki (cherry picked from commit acbea54bc29a22d8fb171bc9da0f1b16fb0ec233) --- diff --git a/target/linux/bcm4908/patches-5.4/073-v5.12-0009-net-broadcom-bcm4908_enet-set-MTU-on-open-on-request.patch b/target/linux/bcm4908/patches-5.4/073-v5.12-0009-net-broadcom-bcm4908_enet-set-MTU-on-open-on-request.patch new file mode 100644 index 0000000000..0201bfeda3 --- /dev/null +++ b/target/linux/bcm4908/patches-5.4/073-v5.12-0009-net-broadcom-bcm4908_enet-set-MTU-on-open-on-request.patch @@ -0,0 +1,119 @@ +From 14b3b46a67f78ade99eafcbf320105615e948569 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Fri, 12 Feb 2021 16:21:35 +0100 +Subject: [PATCH] net: broadcom: bcm4908_enet: set MTU on open & on request +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Hardware comes up with default max frame size set to 1518. When using it +with switch it results in actual Ethernet MTU 1492: +1518 - 14 (Ethernet header) - 4 (Broadcom's tag) - 4 (802.1q) - 4 (FCS) + +Above means hardware in its default state can't handle standard Ethernet +traffic (MTU 1500). + +Define maximum possible Ethernet overhead and always set MAC max frame +length accordingly. This change fixes handling Ethernet frames of length +1506 - 1514. + +Signed-off-by: Rafał Miłecki +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/broadcom/bcm4908_enet.c | 31 ++++++++++++++++---- + 1 file changed, 25 insertions(+), 6 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bcm4908_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm4908_enet.c +@@ -5,6 +5,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -29,9 +30,10 @@ + ENET_DMA_CH_CFG_INT_BUFF_DONE) + #define ENET_DMA_MAX_BURST_LEN 8 /* in 64 bit words */ + +-#define ENET_MTU_MIN 60 +-#define ENET_MTU_MAX 1500 /* Is it possible to support 2044? */ +-#define ENET_MTU_MAX_EXTRA_SIZE 32 /* L2 */ ++#define ENET_MTU_MAX ETH_DATA_LEN /* Is it possible to support 2044? */ ++#define BRCM_MAX_TAG_LEN 6 ++#define ENET_MAX_ETH_OVERHEAD (ETH_HLEN + BRCM_MAX_TAG_LEN + VLAN_HLEN + \ ++ ETH_FCS_LEN + 4) /* 32 */ + + struct bcm4908_enet_dma_ring_bd { + __le32 ctl; +@@ -135,6 +137,11 @@ static void bcm4908_enet_intrs_ack(struc + enet_write(enet, ENET_DMA_CH_RX_CFG + ENET_DMA_CH_CFG_INT_STAT, ENET_DMA_INT_DEFAULTS); + } + ++static void bcm4908_enet_set_mtu(struct bcm4908_enet *enet, int mtu) ++{ ++ enet_umac_write(enet, UMAC_MAX_FRAME_LEN, mtu + ENET_MAX_ETH_OVERHEAD); ++} ++ + /*** + * DMA + */ +@@ -246,7 +253,7 @@ static int bcm4908_enet_dma_alloc_rx_buf + u32 tmp; + int err; + +- slot->len = ENET_MTU_MAX + ENET_MTU_MAX_EXTRA_SIZE; ++ slot->len = ENET_MTU_MAX + ENET_MAX_ETH_OVERHEAD; + + slot->skb = netdev_alloc_skb(enet->netdev, slot->len); + if (!slot->skb) +@@ -374,6 +381,8 @@ static void bcm4908_enet_gmac_init(struc + { + u32 cmd; + ++ bcm4908_enet_set_mtu(enet, enet->netdev->mtu); ++ + cmd = enet_umac_read(enet, UMAC_CMD); + enet_umac_write(enet, UMAC_CMD, cmd | CMD_SW_RESET); + enet_umac_write(enet, UMAC_CMD, cmd & ~CMD_SW_RESET); +@@ -559,7 +568,7 @@ static int bcm4908_enet_poll(struct napi + + len = (ctl & DMA_CTL_LEN_DESC_BUFLENGTH) >> DMA_CTL_LEN_DESC_BUFLENGTH_SHIFT; + +- if (len < ENET_MTU_MIN || ++ if (len < ETH_ZLEN || + (ctl & (DMA_CTL_STATUS_SOP | DMA_CTL_STATUS_EOP)) != (DMA_CTL_STATUS_SOP | DMA_CTL_STATUS_EOP)) { + enet->netdev->stats.rx_dropped++; + break; +@@ -583,11 +592,21 @@ static int bcm4908_enet_poll(struct napi + return handled; + } + ++static int bcm4908_enet_change_mtu(struct net_device *netdev, int new_mtu) ++{ ++ struct bcm4908_enet *enet = netdev_priv(netdev); ++ ++ bcm4908_enet_set_mtu(enet, new_mtu); ++ ++ return 0; ++} ++ + static const struct net_device_ops bcm4908_enet_netdev_ops = { + .ndo_open = bcm4908_enet_open, + .ndo_stop = bcm4908_enet_stop, + .ndo_start_xmit = bcm4908_enet_start_xmit, + .ndo_set_mac_address = eth_mac_addr, ++ .ndo_change_mtu = bcm4908_enet_change_mtu, + }; + + static int bcm4908_enet_probe(struct platform_device *pdev) +@@ -625,7 +644,7 @@ static int bcm4908_enet_probe(struct pla + eth_hw_addr_random(netdev); + netdev->netdev_ops = &bcm4908_enet_netdev_ops; + netdev->min_mtu = ETH_ZLEN; +- netdev->mtu = ENET_MTU_MAX; ++ netdev->mtu = ETH_DATA_LEN; + netdev->max_mtu = ENET_MTU_MAX; + netif_napi_add(netdev, &enet->napi, bcm4908_enet_poll, 64); + diff --git a/target/linux/bcm4908/patches-5.4/073-v5.12-0010-net-broadcom-bcm4908_enet-fix-RX-path-possible-mem-l.patch b/target/linux/bcm4908/patches-5.4/073-v5.12-0010-net-broadcom-bcm4908_enet-fix-RX-path-possible-mem-l.patch new file mode 100644 index 0000000000..8a24324122 --- /dev/null +++ b/target/linux/bcm4908/patches-5.4/073-v5.12-0010-net-broadcom-bcm4908_enet-fix-RX-path-possible-mem-l.patch @@ -0,0 +1,30 @@ +From 4dc7f09b8becfa35a55430a49d95acf19f996e6b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Wed, 24 Feb 2021 16:18:41 +0100 +Subject: [PATCH] net: broadcom: bcm4908_enet: fix RX path possible mem leak +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +After filling RX ring slot with new skb it's required to free old skb. +Immediately on error or later in the net subsystem. + +Fixes: 4feffeadbcb2 ("net: broadcom: bcm4908enet: add BCM4908 controller driver") +Signed-off-by: Rafał Miłecki +Acked-by: Florian Fainelli +Link: https://lore.kernel.org/r/20210224151842.2419-1-zajec5@gmail.com +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/broadcom/bcm4908_enet.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/ethernet/broadcom/bcm4908_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm4908_enet.c +@@ -570,6 +570,7 @@ static int bcm4908_enet_poll(struct napi + + if (len < ETH_ZLEN || + (ctl & (DMA_CTL_STATUS_SOP | DMA_CTL_STATUS_EOP)) != (DMA_CTL_STATUS_SOP | DMA_CTL_STATUS_EOP)) { ++ kfree_skb(slot.skb); + enet->netdev->stats.rx_dropped++; + break; + } diff --git a/target/linux/bcm4908/patches-5.4/073-v5.12-0011-net-broadcom-bcm4908_enet-fix-NAPI-poll-returned-val.patch b/target/linux/bcm4908/patches-5.4/073-v5.12-0011-net-broadcom-bcm4908_enet-fix-NAPI-poll-returned-val.patch new file mode 100644 index 0000000000..d4cf84e4b6 --- /dev/null +++ b/target/linux/bcm4908/patches-5.4/073-v5.12-0011-net-broadcom-bcm4908_enet-fix-NAPI-poll-returned-val.patch @@ -0,0 +1,31 @@ +From 4d9274cee40b6a20dd6148c6c81c6733c2678cbc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Wed, 24 Feb 2021 16:18:42 +0100 +Subject: [PATCH] net: broadcom: bcm4908_enet: fix NAPI poll returned value +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Missing increment was resulting in poll function always returning 0 +instead of amount of processed packets. + +Fixes: 4feffeadbcb2 ("net: broadcom: bcm4908enet: add BCM4908 controller driver") +Signed-off-by: Rafał Miłecki +Acked-by: Florian Fainelli +Link: https://lore.kernel.org/r/20210224151842.2419-2-zajec5@gmail.com +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/broadcom/bcm4908_enet.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/ethernet/broadcom/bcm4908_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm4908_enet.c +@@ -583,6 +583,8 @@ static int bcm4908_enet_poll(struct napi + + enet->netdev->stats.rx_packets++; + enet->netdev->stats.rx_bytes += len; ++ ++ handled++; + } + + if (handled < weight) { diff --git a/target/linux/bcm4908/patches-5.4/073-v5.12-0012-net-broadcom-bcm4908_enet-enable-RX-after-processing.patch b/target/linux/bcm4908/patches-5.4/073-v5.12-0012-net-broadcom-bcm4908_enet-enable-RX-after-processing.patch new file mode 100644 index 0000000000..ad1bebf3ec --- /dev/null +++ b/target/linux/bcm4908/patches-5.4/073-v5.12-0012-net-broadcom-bcm4908_enet-enable-RX-after-processing.patch @@ -0,0 +1,34 @@ +From d313d16bbaea0f11a2e98f04a6c678b43c208915 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Fri, 26 Feb 2021 14:20:38 +0100 +Subject: [PATCH] net: broadcom: bcm4908_enet: enable RX after processing + packets +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When receiving a lot of packets hardware may run out of free +descriptiors and stop RX ring. Enable it every time after handling +received packets. + +Fixes: 4feffeadbcb2 ("net: broadcom: bcm4908enet: add BCM4908 controller driver") +Signed-off-by: Rafał Miłecki +Acked-by: Florian Fainelli +Link: https://lore.kernel.org/r/20210226132038.29849-1-zajec5@gmail.com +Signed-off-by: Jakub Kicinski +--- + drivers/net/ethernet/broadcom/bcm4908_enet.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/net/ethernet/broadcom/bcm4908_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm4908_enet.c +@@ -592,6 +592,9 @@ static int bcm4908_enet_poll(struct napi + bcm4908_enet_intrs_on(enet); + } + ++ /* Hardware could disable ring if it run out of descriptors */ ++ bcm4908_enet_dma_rx_ring_enable(enet, &enet->rx_ring); ++ + return handled; + } + diff --git a/target/linux/bcm4908/patches-5.4/170-net-broadcom-bcm4908_enet-set-MTU-on-open-on-request.patch b/target/linux/bcm4908/patches-5.4/170-net-broadcom-bcm4908_enet-set-MTU-on-open-on-request.patch deleted file mode 100644 index 87cb851034..0000000000 --- a/target/linux/bcm4908/patches-5.4/170-net-broadcom-bcm4908_enet-set-MTU-on-open-on-request.patch +++ /dev/null @@ -1,113 +0,0 @@ -From d7dfbcba0437955ccbe4c6db736526d528f27720 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Fri, 12 Feb 2021 16:06:00 +0100 -Subject: [PATCH] net: broadcom: bcm4908_enet: set MTU on open & on request - -Hardware comes up with default max frame size set to 1518. When using it -with switch it results in actual Ethernet MTU 1492: -1518 - 14 (Ethernet header) - 4 (Broadcom's tag) - 4 (802.1q) - 4 (FCS) - -Above means hardware in its default state can't handle standard Ethernet -traffic (MTU 1500). - -Define maximum possible Ethernet overhead and always set MAC max frame -length accordingly. This change fixes handling Ethernet frames of length -1506 - 1514. ---- - drivers/net/ethernet/broadcom/bcm4908_enet.c | 31 ++++++++++++++++---- - 1 file changed, 25 insertions(+), 6 deletions(-) - ---- a/drivers/net/ethernet/broadcom/bcm4908_enet.c -+++ b/drivers/net/ethernet/broadcom/bcm4908_enet.c -@@ -5,6 +5,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -29,9 +30,10 @@ - ENET_DMA_CH_CFG_INT_BUFF_DONE) - #define ENET_DMA_MAX_BURST_LEN 8 /* in 64 bit words */ - --#define ENET_MTU_MIN 60 --#define ENET_MTU_MAX 1500 /* Is it possible to support 2044? */ --#define ENET_MTU_MAX_EXTRA_SIZE 32 /* L2 */ -+#define ENET_MTU_MAX ETH_DATA_LEN /* Is it possible to support 2044? */ -+#define BRCM_MAX_TAG_LEN 6 -+#define ENET_MAX_ETH_OVERHEAD (ETH_HLEN + BRCM_MAX_TAG_LEN + VLAN_HLEN + \ -+ ETH_FCS_LEN + 4) /* 32 */ - - struct bcm4908_enet_dma_ring_bd { - __le32 ctl; -@@ -135,6 +137,11 @@ static void bcm4908_enet_intrs_ack(struc - enet_write(enet, ENET_DMA_CH_RX_CFG + ENET_DMA_CH_CFG_INT_STAT, ENET_DMA_INT_DEFAULTS); - } - -+static void bcm4908_enet_set_mtu(struct bcm4908_enet *enet, int mtu) -+{ -+ enet_umac_write(enet, UMAC_MAX_FRAME_LEN, mtu + ENET_MAX_ETH_OVERHEAD); -+} -+ - /*** - * DMA - */ -@@ -246,7 +253,7 @@ static int bcm4908_enet_dma_alloc_rx_buf - u32 tmp; - int err; - -- slot->len = ENET_MTU_MAX + ENET_MTU_MAX_EXTRA_SIZE; -+ slot->len = ENET_MTU_MAX + ENET_MAX_ETH_OVERHEAD; - - slot->skb = netdev_alloc_skb(enet->netdev, slot->len); - if (!slot->skb) -@@ -374,6 +381,8 @@ static void bcm4908_enet_gmac_init(struc - { - u32 cmd; - -+ bcm4908_enet_set_mtu(enet, enet->netdev->mtu); -+ - cmd = enet_umac_read(enet, UMAC_CMD); - enet_umac_write(enet, UMAC_CMD, cmd | CMD_SW_RESET); - enet_umac_write(enet, UMAC_CMD, cmd & ~CMD_SW_RESET); -@@ -559,7 +568,7 @@ static int bcm4908_enet_poll(struct napi - - len = (ctl & DMA_CTL_LEN_DESC_BUFLENGTH) >> DMA_CTL_LEN_DESC_BUFLENGTH_SHIFT; - -- if (len < ENET_MTU_MIN || -+ if (len < ETH_ZLEN || - (ctl & (DMA_CTL_STATUS_SOP | DMA_CTL_STATUS_EOP)) != (DMA_CTL_STATUS_SOP | DMA_CTL_STATUS_EOP)) { - enet->netdev->stats.rx_dropped++; - break; -@@ -583,11 +592,21 @@ static int bcm4908_enet_poll(struct napi - return handled; - } - -+static int bcm4908_enet_change_mtu(struct net_device *netdev, int new_mtu) -+{ -+ struct bcm4908_enet *enet = netdev_priv(netdev); -+ -+ bcm4908_enet_set_mtu(enet, new_mtu); -+ -+ return 0; -+} -+ - static const struct net_device_ops bcm4908_enet_netdev_ops = { - .ndo_open = bcm4908_enet_open, - .ndo_stop = bcm4908_enet_stop, - .ndo_start_xmit = bcm4908_enet_start_xmit, - .ndo_set_mac_address = eth_mac_addr, -+ .ndo_change_mtu = bcm4908_enet_change_mtu, - }; - - static int bcm4908_enet_probe(struct platform_device *pdev) -@@ -625,7 +644,7 @@ static int bcm4908_enet_probe(struct pla - eth_hw_addr_random(netdev); - netdev->netdev_ops = &bcm4908_enet_netdev_ops; - netdev->min_mtu = ETH_ZLEN; -- netdev->mtu = ENET_MTU_MAX; -+ netdev->mtu = ETH_DATA_LEN; - netdev->max_mtu = ENET_MTU_MAX; - netif_napi_add(netdev, &enet->napi, bcm4908_enet_poll, 64); -