MT7530/7531 has a global RX packet length register, which can be used
to set MTU.

Signed-off-by: DENG Qingfang <dqf...@gmail.com>
---
 drivers/net/dsa/mt7530.c | 36 ++++++++++++++++++++++++++++++++++++
 drivers/net/dsa/mt7530.h | 12 ++++++++++++
 2 files changed, 48 insertions(+)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index de7692b763d8..7764c66a47c9 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -1021,6 +1021,40 @@ mt7530_port_disable(struct dsa_switch *ds, int port)
        mutex_unlock(&priv->reg_mutex);
 }
 
+static int
+mt7530_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
+{
+       struct mt7530_priv *priv = ds->priv;
+       int length;
+
+       /* When a new MTU is set, DSA always set the CPU port's MTU to the 
largest MTU
+        * of the slave ports. Because the switch only has a global RX length 
register,
+        * only allowing CPU port here is enough.
+        */
+       if (!dsa_is_cpu_port(ds, port))
+               return 0;
+
+       /* RX length also includes Ethernet header, MTK tag, and FCS length */
+       length = new_mtu + ETH_HLEN + MTK_HDR_LEN + ETH_FCS_LEN;
+       if (length <= 1522)
+               mt7530_rmw(priv, MT7530_GMACCR, MAX_RX_PKT_LEN_MASK, 
MAX_RX_PKT_LEN_1522);
+       else if (length <= 1536)
+               mt7530_rmw(priv, MT7530_GMACCR, MAX_RX_PKT_LEN_MASK, 
MAX_RX_PKT_LEN_1536);
+       else if (length <= 1552)
+               mt7530_rmw(priv, MT7530_GMACCR, MAX_RX_PKT_LEN_MASK, 
MAX_RX_PKT_LEN_1552);
+       else
+               mt7530_rmw(priv, MT7530_GMACCR, MAX_RX_JUMBO_MASK | 
MAX_RX_PKT_LEN_MASK,
+                       MAX_RX_JUMBO(DIV_ROUND_UP(length, 1024)) | 
MAX_RX_PKT_LEN_JUMBO);
+
+       return 0;
+}
+
+static int
+mt7530_port_max_mtu(struct dsa_switch *ds, int port)
+{
+       return MT7530_MAX_MTU;
+}
+
 static void
 mt7530_stp_state_set(struct dsa_switch *ds, int port, u8 state)
 {
@@ -2519,6 +2553,8 @@ static const struct dsa_switch_ops mt7530_switch_ops = {
        .get_sset_count         = mt7530_get_sset_count,
        .port_enable            = mt7530_port_enable,
        .port_disable           = mt7530_port_disable,
+       .port_change_mtu        = mt7530_port_change_mtu,
+       .port_max_mtu           = mt7530_port_max_mtu,
        .port_stp_state_set     = mt7530_stp_state_set,
        .port_bridge_join       = mt7530_port_bridge_join,
        .port_bridge_leave      = mt7530_port_bridge_leave,
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index 9278a8e3d04e..77a6222d2635 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -11,6 +11,9 @@
 #define MT7530_NUM_FDB_RECORDS         2048
 #define MT7530_ALL_MEMBERS             0xff
 
+#define MTK_HDR_LEN                    4
+#define MT7530_MAX_MTU                 (15 * 1024 - ETH_HLEN - ETH_FCS_LEN - 
MTK_HDR_LEN)
+
 enum mt753x_id {
        ID_MT7530 = 0,
        ID_MT7621 = 1,
@@ -289,6 +292,15 @@ enum mt7530_vlan_port_attr {
 #define MT7531_DBG_CNT(x)              (0x3018 + (x) * 0x100)
 #define  MT7531_DIS_CLR                        BIT(31)
 
+#define MT7530_GMACCR                  0x30e0
+#define  MAX_RX_JUMBO(x)               ((x) << 2)
+#define  MAX_RX_JUMBO_MASK             GENMASK(5, 2)
+#define  MAX_RX_PKT_LEN_MASK           GENMASK(1, 0)
+#define  MAX_RX_PKT_LEN_1522           0x0
+#define  MAX_RX_PKT_LEN_1536           0x1
+#define  MAX_RX_PKT_LEN_1552           0x2
+#define  MAX_RX_PKT_LEN_JUMBO          0x3
+
 /* Register for MIB */
 #define MT7530_PORT_MIB_COUNTER(x)     (0x4000 + (x) * 0x100)
 #define MT7530_MIB_CCR                 0x4fe0
-- 
2.25.1

Reply via email to