[openwrt/openwrt] bcm4908: fix handling Ethernet frames of size 1506 - 1514

LEDE Commits lede-commits at lists.infradead.org
Fri Feb 12 10:30:45 EST 2021


rmilecki pushed a commit to openwrt/openwrt.git, branch master:
https://git.openwrt.org/d8afae0be8f0a2a4a26e303dd5212e2a2f8d69a3

commit d8afae0be8f0a2a4a26e303dd5212e2a2f8d69a3
Author: Rafał Miłecki <rafal at milecki.pl>
AuthorDate: Fri Feb 12 16:28:57 2021 +0100

    bcm4908: fix handling Ethernet frames of size 1506 - 1514
    
    MTU needs to be explicitly set as default value is too low.
    
    Signed-off-by: Rafał Miłecki <rafal at milecki.pl>
---
 ...m-bcm4908_enet-set-MTU-on-open-on-request.patch | 113 +++++++++++++++++++++
 1 file changed, 113 insertions(+)

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
new file mode 100644
index 0000000000..87cb851034
--- /dev/null
+++ b/target/linux/bcm4908/patches-5.4/170-net-broadcom-bcm4908_enet-set-MTU-on-open-on-request.patch
@@ -0,0 +1,113 @@
+From d7dfbcba0437955ccbe4c6db736526d528f27720 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal at milecki.pl>
+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 <linux/delay.h>
+ #include <linux/etherdevice.h>
++#include <linux/if_vlan.h>
+ #include <linux/interrupt.h>
+ #include <linux/module.h>
+ #include <linux/of.h>
+@@ -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);
+ 



More information about the lede-commits mailing list