| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- From 9470174e7581e75a8ebd78964997314dfc2e706c Mon Sep 17 00:00:00 2001
- From: DENG Qingfang <[email protected]>
- Date: Tue, 3 Nov 2020 13:06:18 +0800
- Subject: [PATCH] net: dsa: mt7530: support setting MTU
- MT7530/7531 has a global RX packet length register, which can be used
- to set MTU.
- Supported packet length values are 1522 (1518 if untagged), 1536,
- 1552, and multiple of 1024 (from 2048 to 15360).
- Signed-off-by: DENG Qingfang <[email protected]>
- Link: https://lore.kernel.org/r/[email protected]
- Signed-off-by: Jakub Kicinski <[email protected]>
- ---
- drivers/net/dsa/mt7530.c | 49 ++++++++++++++++++++++++++++++++++++++++
- drivers/net/dsa/mt7530.h | 12 ++++++++++
- 2 files changed, 61 insertions(+)
- --- a/drivers/net/dsa/mt7530.c
- +++ b/drivers/net/dsa/mt7530.c
- @@ -1015,6 +1015,53 @@ mt7530_port_disable(struct dsa_switch *d
- 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;
- + struct mii_bus *bus = priv->bus;
- + int length;
- + u32 val;
- +
- + /* 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;
- +
- + mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
- +
- + val = mt7530_mii_read(priv, MT7530_GMACCR);
- + val &= ~MAX_RX_PKT_LEN_MASK;
- +
- + /* 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) {
- + val |= MAX_RX_PKT_LEN_1522;
- + } else if (length <= 1536) {
- + val |= MAX_RX_PKT_LEN_1536;
- + } else if (length <= 1552) {
- + val |= MAX_RX_PKT_LEN_1552;
- + } else {
- + val &= ~MAX_RX_JUMBO_MASK;
- + val |= MAX_RX_JUMBO(DIV_ROUND_UP(length, 1024));
- + val |= MAX_RX_PKT_LEN_JUMBO;
- + }
- +
- + mt7530_mii_write(priv, MT7530_GMACCR, val);
- +
- + mutex_unlock(&bus->mdio_lock);
- +
- + 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)
- {
- @@ -2647,6 +2694,8 @@ static const struct dsa_switch_ops mt753
- .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,
- --- 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,
- @@ -301,6 +304,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
|