I've been working on this for a while. Apparently the embedded
5-port
gigabit switch is able to handle packets with size up to 15KB.
On the
contrary, the GMAC, to which the switch is attached, has a limit
of
2KB. The following is a patch that changes the max recv frame
length
to 2KB and allows to set the MTU up to that value. It is based on
kernel 4.4.7.
Signed-off-by: Gaetano Catalli <gaetano.cata...@gmail.com>
---
drivers/net/ethernet/mediatek/gsw_mt7620.h | 6 +++++
drivers/net/ethernet/mediatek/gsw_mt7621.c | 13 +++++++----
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 36
++++++++++++++++++-----------
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 +
drivers/net/ethernet/mediatek/soc_mt7621.c | 2 +-
5 files changed, 39 insertions(+), 19 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/gsw_mt7620.h
b/drivers/net/ethernet/mediatek/gsw_mt7620.h
index dcef9a8..ce3cd10 100644
--- a/drivers/net/ethernet/mediatek/gsw_mt7620.h
+++ b/drivers/net/ethernet/mediatek/gsw_mt7620.h
@@ -45,6 +45,12 @@
#define GSW_REG_ISR 0x700c
#define GSW_REG_GPC1 0x7014
+#define GSW_REG_MAC_P0_MCR 0x100
+#define GSW_REG_MAC_P1_MCR 0x200
+
+// Global MAC control register
+#define GSW_REG_GMACCR 0x30E0
+
#define SYSC_REG_CHIP_REV_ID 0x0c
#define SYSC_REG_CFG1 0x14
#define RST_CTRL_MCM BIT(2)
diff --git a/drivers/net/ethernet/mediatek/gsw_mt7621.c
b/drivers/net/ethernet/mediatek/gsw_mt7621.c
index 96280b4..db5d56d 100644
--- a/drivers/net/ethernet/mediatek/gsw_mt7621.c
+++ b/drivers/net/ethernet/mediatek/gsw_mt7621.c
@@ -99,17 +99,20 @@ static void mt7621_hw_init(struct mt7620_gsw
*gsw,
struct device_node *np)
usleep_range(10, 20);
if ((rt_sysc_r32(SYSC_REG_CHIP_REV_ID) & 0xFFFF) == 0x0101) {
- /* (GE1, Force 1000M/FD, FC ON, MAX_RX_LENGTH 1536) */
- mtk_switch_w32(gsw, 0x2105e30b, 0x100);
+ /* (GE1, Force 1000M/FD, FC ON, MAX_RX_LENGTH 2k) */
+ mtk_switch_w32(gsw, 0x2305e30b, GSW_REG_MAC_P0_MCR);
mt7530_mdio_w32(gsw, 0x3600, 0x5e30b);
} else {
- /* (GE1, Force 1000M/FD, FC ON, MAX_RX_LENGTH 1536) */
- mtk_switch_w32(gsw, 0x2105e33b, 0x100);
+ /* (GE1, Force 1000M/FD, FC ON, MAX_RX_LENGTH 2k) */
+ mtk_switch_w32(gsw, 0x2305e33b, GSW_REG_MAC_P0_MCR);
mt7530_mdio_w32(gsw, 0x3600, 0x5e33b);
}
/* (GE2, Link down) */
- mtk_switch_w32(gsw, 0x8000, 0x200);
+ mtk_switch_w32(gsw, 0x8000, GSW_REG_MAC_P1_MCR);
+
+ /* Set switch max RX frame length to 2k */
+ mt7530_mdio_w32(gsw, GSW_REG_GMACCR, 0x3F0B);
/* Enable Port 6, P5 as GMAC5, P5 disable */
val = mt7530_mdio_r32(gsw, 0x7804);
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 48eda44..5edafa6 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -37,7 +37,7 @@
#include "mdio.h"
#include "ethtool.h"
-#define MAX_RX_LENGTH 1536
+#define MAX_RX_LENGTH 2048
#define FE_RX_ETH_HLEN (VLAN_ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN)
#define FE_RX_HLEN (NET_SKB_PAD + FE_RX_ETH_HLEN + NET_IP_ALIGN)
#define DMA_DUMMY_DESC 0xffffffff
@@ -1358,11 +1358,29 @@ static int fe_do_ioctl(struct net_device
*dev,
struct ifreq *ifr, int cmd)
return -EOPNOTSUPP;
}
+static int fe_set_mtu(struct fe_priv* priv, int new_mtu)
+{
+ int frag_size = fe_max_frag_size(new_mtu);
+ u32 fwd_cfg;
+
+ fe_stop(priv->netdev);
+ fwd_cfg = fe_r32(FE_GDMA1_FWD_CFG);
+ if (new_mtu <= ETH_DATA_LEN) {
+ fwd_cfg &= ~FE_GDM1_JMB_EN;
+ } else {
+ fwd_cfg &= ~(FE_GDM1_JMB_LEN_MASK << FE_GDM1_JMB_LEN_SHIFT);
+ fwd_cfg |= (DIV_ROUND_UP(frag_size, 1024) <<
+ FE_GDM1_JMB_LEN_SHIFT) | FE_GDM1_JMB_EN;
+ }
+ fe_w32(fwd_cfg, FE_GDMA1_FWD_CFG);
+
+ return fe_open(priv->netdev);
+}
+
static int fe_change_mtu(struct net_device *dev, int new_mtu)
{
struct fe_priv *priv = netdev_priv(dev);
int frag_size, old_mtu;
- u32 fwd_cfg;
if (!(priv->flags & FE_FLAG_JUMBO_FRAME))
return eth_change_mtu(dev, new_mtu);
@@ -1389,18 +1407,10 @@ static int fe_change_mtu(struct
net_device
*dev, int new_mtu)
if (!netif_running(dev))
return 0;
- fe_stop(dev);
- fwd_cfg = fe_r32(FE_GDMA1_FWD_CFG);
- if (new_mtu <= ETH_DATA_LEN) {
- fwd_cfg &= ~FE_GDM1_JMB_EN;
- } else {
- fwd_cfg &= ~(FE_GDM1_JMB_LEN_MASK << FE_GDM1_JMB_LEN_SHIFT);
- fwd_cfg |= (DIV_ROUND_UP(frag_size, 1024) <<
- FE_GDM1_JMB_LEN_SHIFT) | FE_GDM1_JMB_EN;
- }
- fe_w32(fwd_cfg, FE_GDMA1_FWD_CFG);
+ if (priv->soc->set_mtu)
+ return priv->soc->set_mtu(priv, new_mtu);
- return fe_open(dev);
+ return fe_set_mtu(priv, new_mtu);
}
static const struct net_device_ops fe_netdev_ops = {
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index d5f8b87..3acc2c1 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -381,6 +381,7 @@ struct fe_soc_data {
void (*reset_fe)(void);
void (*set_mac)(struct fe_priv *priv, unsigned char *mac);
int (*fwd_config)(struct fe_priv *priv);
+ int (*set_mtu)(struct fe_priv *priv, int new_mtu);
void (*tx_dma)(struct fe_tx_dma *txd);
int (*switch_init)(struct fe_priv *priv);
int (*switch_config)(struct fe_priv *priv);
diff --git a/drivers/net/ethernet/mediatek/soc_mt7621.c
b/drivers/net/ethernet/mediatek/soc_mt7621.c
index 1609a3e..f95c354 100644
--- a/drivers/net/ethernet/mediatek/soc_mt7621.c
+++ b/drivers/net/ethernet/mediatek/soc_mt7621.c
@@ -140,7 +140,7 @@ static void mt7621_init_data(struct
fe_soc_data *data,
priv->flags = FE_FLAG_PADDING_64B | FE_FLAG_RX_2B_OFFSET |
FE_FLAG_RX_SG_DMA | FE_FLAG_NAPI_WEIGHT |
- FE_FLAG_HAS_SWITCH;
+ FE_FLAG_HAS_SWITCH | FE_FLAG_JUMBO_FRAME;
netdev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_SG | NETIF_F_TSO |
--
2.7.4
On Mon, Apr 10, 2017 at 9:21 AM, Jaap Buurman
<jaapbuur...@gmail.com> wrote:
I am able to test this on my DIR-860l. I could try to compile
my own
build to test this, but I am no C programmer myself. Am I
correct in
the following post about how to set the flag to allow for jumbo
frames
to be set?:
https://forum.lede-project.org/t/build-for-the-d-link-dir-860l/948/40?u=mushoz
If so, I will be able to apply the patch myself and test it. I
could
then send a PR if the tests are successful.
Yours sincerely,
Jaap Buurman
On Mon, Apr 10, 2017 at 9:16 AM, Milan Kočvara
<milankocv...@gmail.com> wrote:
Hello all,
if someone do a testing patch for jumboFrames, I can lend a
helping
hand with testing on EdgeRouter X. I think MT7621 know
JumboFrames,
because of Ubiquiti FMW allow to set MTU 1536B
2017-04-10 2:06 GMT+02:00 <ros...@gmail.com>:
Probably was not in the interest of the driver writers. Based
on the
copyrights though, it's mostly LEDE/OpenWRT developers. Try
modifying
the code to test if jumbo frames work.
On Sun, 2017-04-09 at 21:20 +0200, Jaap Buurman wrote:
Hello all,
I found the message below in a conversation from back in
August, 2016
in this mailinglist. I did not find a reply to this
question. Has
there ever been one? Or does anyone else happen to know the
answer to
this question? Thank you very much in advance.
Yours sincerely,
Jaap Buurman
August, 2016 message:
Hi all,
in the MT7621 ethernet driver code
(drivers/net/ethernet/mediatek/soc_mt7621.c) the
FE_FLAG_JUMBO_FRAME
flag is not during the device initialization. This prevents
the user
to set an MTU greater than 1500. Is this correct? Does
MT7621 support
jumbo frames?
Thanks.
_______________________________________________
Lede-dev mailing list
Lede-dev@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/lede-dev
--
gaetano catalli