|
|
@@ -0,0 +1,138 @@
|
|
|
+From 4fd59792097a6b2fb949d41264386a7ecade469e Mon Sep 17 00:00:00 2001
|
|
|
+From: DENG Qingfang <[email protected]>
|
|
|
+Date: Mon, 25 Jan 2021 12:20:46 +0800
|
|
|
+Subject: [PATCH] net: ethernet: mediatek: support setting MTU
|
|
|
+
|
|
|
+MT762x HW, except for MT7628, supports frame length up to 2048
|
|
|
+(maximum length on GDM), so allow setting MTU up to 2030.
|
|
|
+
|
|
|
+Also set the default frame length to the hardware default 1518.
|
|
|
+
|
|
|
+Signed-off-by: DENG Qingfang <[email protected]>
|
|
|
+Reviewed-by: Andrew Lunn <[email protected]>
|
|
|
+Link: https://lore.kernel.org/r/[email protected]
|
|
|
+Signed-off-by: Jakub Kicinski <[email protected]>
|
|
|
+---
|
|
|
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 43 ++++++++++++++++++---
|
|
|
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 12 ++++--
|
|
|
+ 2 files changed, 47 insertions(+), 8 deletions(-)
|
|
|
+
|
|
|
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
|
|
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
|
|
+@@ -355,7 +355,7 @@ static void mtk_mac_config(struct phylin
|
|
|
+ /* Setup gmac */
|
|
|
+ mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
|
|
|
+ mcr_new = mcr_cur;
|
|
|
+- mcr_new |= MAC_MCR_MAX_RX_1536 | MAC_MCR_IPG_CFG | MAC_MCR_FORCE_MODE |
|
|
|
++ mcr_new |= MAC_MCR_IPG_CFG | MAC_MCR_FORCE_MODE |
|
|
|
+ MAC_MCR_BACKOFF_EN | MAC_MCR_BACKPR_EN | MAC_MCR_FORCE_LINK;
|
|
|
+
|
|
|
+ /* Only update control register when needed! */
|
|
|
+@@ -782,8 +782,8 @@ static void mtk_get_stats64(struct net_d
|
|
|
+ static inline int mtk_max_frag_size(int mtu)
|
|
|
+ {
|
|
|
+ /* make sure buf_size will be at least MTK_MAX_RX_LENGTH */
|
|
|
+- if (mtu + MTK_RX_ETH_HLEN < MTK_MAX_RX_LENGTH)
|
|
|
+- mtu = MTK_MAX_RX_LENGTH - MTK_RX_ETH_HLEN;
|
|
|
++ if (mtu + MTK_RX_ETH_HLEN < MTK_MAX_RX_LENGTH_2K)
|
|
|
++ mtu = MTK_MAX_RX_LENGTH_2K - MTK_RX_ETH_HLEN;
|
|
|
+
|
|
|
+ return SKB_DATA_ALIGN(MTK_RX_HLEN + mtu) +
|
|
|
+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
|
|
|
+@@ -794,7 +794,7 @@ static inline int mtk_max_buf_size(int f
|
|
|
+ int buf_size = frag_size - NET_SKB_PAD - NET_IP_ALIGN -
|
|
|
+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
|
|
|
+
|
|
|
+- WARN_ON(buf_size < MTK_MAX_RX_LENGTH);
|
|
|
++ WARN_ON(buf_size < MTK_MAX_RX_LENGTH_2K);
|
|
|
+
|
|
|
+ return buf_size;
|
|
|
+ }
|
|
|
+@@ -2606,6 +2606,35 @@ static void mtk_uninit(struct net_device
|
|
|
+ mtk_rx_irq_disable(eth, ~0);
|
|
|
+ }
|
|
|
+
|
|
|
++static int mtk_change_mtu(struct net_device *dev, int new_mtu)
|
|
|
++{
|
|
|
++ int length = new_mtu + MTK_RX_ETH_HLEN;
|
|
|
++ struct mtk_mac *mac = netdev_priv(dev);
|
|
|
++ struct mtk_eth *eth = mac->hw;
|
|
|
++ u32 mcr_cur, mcr_new;
|
|
|
++
|
|
|
++ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) {
|
|
|
++ mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
|
|
|
++ mcr_new = mcr_cur & ~MAC_MCR_MAX_RX_MASK;
|
|
|
++
|
|
|
++ if (length <= 1518)
|
|
|
++ mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1518);
|
|
|
++ else if (length <= 1536)
|
|
|
++ mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1536);
|
|
|
++ else if (length <= 1552)
|
|
|
++ mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1552);
|
|
|
++ else
|
|
|
++ mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_2048);
|
|
|
++
|
|
|
++ if (mcr_new != mcr_cur)
|
|
|
++ mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id));
|
|
|
++ }
|
|
|
++
|
|
|
++ dev->mtu = new_mtu;
|
|
|
++
|
|
|
++ return 0;
|
|
|
++}
|
|
|
++
|
|
|
+ static int mtk_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
|
|
+ {
|
|
|
+ struct mtk_mac *mac = netdev_priv(dev);
|
|
|
+@@ -2902,6 +2931,7 @@ static const struct net_device_ops mtk_n
|
|
|
+ .ndo_set_mac_address = mtk_set_mac_address,
|
|
|
+ .ndo_validate_addr = eth_validate_addr,
|
|
|
+ .ndo_do_ioctl = mtk_do_ioctl,
|
|
|
++ .ndo_change_mtu = mtk_change_mtu,
|
|
|
+ .ndo_tx_timeout = mtk_tx_timeout,
|
|
|
+ .ndo_get_stats64 = mtk_get_stats64,
|
|
|
+ .ndo_fix_features = mtk_fix_features,
|
|
|
+@@ -3004,7 +3034,10 @@ static int mtk_add_mac(struct mtk_eth *e
|
|
|
+ eth->netdev[id]->irq = eth->irq[0];
|
|
|
+ eth->netdev[id]->dev.of_node = np;
|
|
|
+
|
|
|
+- eth->netdev[id]->max_mtu = MTK_MAX_RX_LENGTH - MTK_RX_ETH_HLEN;
|
|
|
++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
|
|
|
++ eth->netdev[id]->max_mtu = MTK_MAX_RX_LENGTH - MTK_RX_ETH_HLEN;
|
|
|
++ else
|
|
|
++ eth->netdev[id]->max_mtu = MTK_MAX_RX_LENGTH_2K - MTK_RX_ETH_HLEN;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+
|
|
|
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
|
|
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
|
|
+@@ -20,12 +20,13 @@
|
|
|
+ #include "mtk_ppe.h"
|
|
|
+
|
|
|
+ #define MTK_QDMA_PAGE_SIZE 2048
|
|
|
+-#define MTK_MAX_RX_LENGTH 1536
|
|
|
++#define MTK_MAX_RX_LENGTH 1536
|
|
|
++#define MTK_MAX_RX_LENGTH_2K 2048
|
|
|
+ #define MTK_TX_DMA_BUF_LEN 0x3fff
|
|
|
+ #define MTK_DMA_SIZE 512
|
|
|
+ #define MTK_NAPI_WEIGHT 64
|
|
|
+ #define MTK_MAC_COUNT 2
|
|
|
+-#define MTK_RX_ETH_HLEN (VLAN_ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN)
|
|
|
++#define MTK_RX_ETH_HLEN (ETH_HLEN + ETH_FCS_LEN)
|
|
|
+ #define MTK_RX_HLEN (NET_SKB_PAD + MTK_RX_ETH_HLEN + NET_IP_ALIGN)
|
|
|
+ #define MTK_DMA_DUMMY_DESC 0xffffffff
|
|
|
+ #define MTK_DEFAULT_MSG_ENABLE (NETIF_MSG_DRV | \
|
|
|
+@@ -352,7 +353,12 @@
|
|
|
+
|
|
|
+ /* Mac control registers */
|
|
|
+ #define MTK_MAC_MCR(x) (0x10100 + (x * 0x100))
|
|
|
+-#define MAC_MCR_MAX_RX_1536 BIT(24)
|
|
|
++#define MAC_MCR_MAX_RX_MASK GENMASK(25, 24)
|
|
|
++#define MAC_MCR_MAX_RX(_x) (MAC_MCR_MAX_RX_MASK & ((_x) << 24))
|
|
|
++#define MAC_MCR_MAX_RX_1518 0x0
|
|
|
++#define MAC_MCR_MAX_RX_1536 0x1
|
|
|
++#define MAC_MCR_MAX_RX_1552 0x2
|
|
|
++#define MAC_MCR_MAX_RX_2048 0x3
|
|
|
+ #define MAC_MCR_IPG_CFG (BIT(18) | BIT(16))
|
|
|
+ #define MAC_MCR_FORCE_MODE BIT(15)
|
|
|
+ #define MAC_MCR_TX_EN BIT(14)
|