summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac4.h12
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c37
2 files changed, 44 insertions, 5 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
index e58194fd0c0b..53ac45b50e22 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
@@ -16,6 +16,7 @@
#define GMAC_CONFIG 0x00000000
#define GMAC_EXT_CONFIG 0x00000004
#define GMAC_PACKET_FILTER 0x00000008
+#define GMAC_WDT 0x0000000c
#define GMAC_HASH_TAB(x) (0x10 + (x) * 4)
#define GMAC_RX_FLOW_CTRL 0x00000090
#define GMAC_QX_TX_FLOW_CTRL(x) (0x70 + x * 4)
@@ -77,6 +78,10 @@
#define GMAC_MAX_PERFECT_ADDRESSES 128
+/* MAC Watchdog timeout for received frames */
+#define GMAC_WDT_PWE BIT(8)
+#define GMAC_WDT_WTO GENMASK(3, 0)
+
/* MAC RX Queue Enable */
#define GMAC_RX_QUEUE_CLEAR(queue) ~(GENMASK(1, 0) << ((queue) * 2))
#define GMAC_RX_AV_QUEUE_ENABLE(queue) BIT((queue) * 2)
@@ -155,9 +160,11 @@ enum power_event {
#define GMAC_CONFIG_SARC GENMASK(30, 28)
#define GMAC_CONFIG_IPC BIT(27)
#define GMAC_CONFIG_IPG GENMASK(26, 24)
+#define GMAC_CONFIG_GPSLCE BIT(23)
#define GMAC_CONFIG_2K BIT(22)
#define GMAC_CONFIG_CST BIT(21)
#define GMAC_CONFIG_ACS BIT(20)
+#define GMAC_CONFIG_WD BIT(19)
#define GMAC_CONFIG_BE BIT(18)
#define GMAC_CONFIG_JD BIT(17)
#define GMAC_CONFIG_JE BIT(16)
@@ -174,6 +181,7 @@ enum power_event {
#define GMAC_CONFIG_EIPG_EN BIT(24)
#define GMAC_CONFIG_HDSMS GENMASK(22, 20)
#define GMAC_CONFIG_HDSMS_256 FIELD_PREP_CONST(GMAC_CONFIG_HDSMS, 0x2)
+#define GMAC_CONFIG_GPSL GENMASK(13, 0)
/* MAC HW features0 bitmap */
#define GMAC_HW_FEAT_SAVLANINS BIT(27)
@@ -472,9 +480,7 @@ static inline u32 mtl_low_credx_base_addr(const struct dwmac4_addrs *addrs,
#define MTL_INT_DEFAULT_ENABLE (MTL_RX_OVERFLOW_INT | MTL_TX_UNDERFLOW_INT)
/* Default operating mode of the MAC */
-#define GMAC_CORE_INIT (GMAC_CONFIG_JD | GMAC_CONFIG_PS | \
- GMAC_CONFIG_BE | GMAC_CONFIG_DCRS | \
- GMAC_CONFIG_JE)
+#define GMAC_CORE_INIT (GMAC_CONFIG_PS | GMAC_CONFIG_BE | GMAC_CONFIG_DCRS)
/* To dump the core regs excluding the Address Registers */
#define GMAC_REG_NUM 132
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
index 9f53a79aa70c..4d07f421e7af 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
@@ -37,10 +37,43 @@ static void dwmac4_core_init(struct mac_device_info *hw,
struct stmmac_priv *priv = netdev_priv(dev);
void __iomem *ioaddr = hw->pcsr;
unsigned long clk_rate;
- u32 value;
+ int mtu = dev->mtu;
+ u32 value, gps;
value = readl(ioaddr + GMAC_CONFIG);
- writel(value | GMAC_CORE_INIT, ioaddr + GMAC_CONFIG);
+ value |= GMAC_CORE_INIT;
+
+ /* Frame length limits (giant status reported or dropped) */
+ gps = ETH_HLEN + ETH_FCS_LEN;
+ if (mtu > 16357) { /* Rx <= 16375 (+C/SVLAN headers) && Tx <= 16383 */
+ gps += 16357;
+ value |= GMAC_CONFIG_GPSLCE | GMAC_CONFIG_JD;
+ } else if (mtu > 2022) { /* Rx <= MTU + Eth (+C/SVLAN headers) && Tx <= 16383 */
+ gps += mtu;
+ value |= GMAC_CONFIG_GPSLCE | GMAC_CONFIG_JD;
+ } else if (mtu > 1500) { /* Rx <= MTU + Eth (+C/SVLAN headers) && Tx <= 2048 */
+ gps += mtu;
+ value |= GMAC_CONFIG_GPSLCE;
+ } else { /* Rx <= 1500 + Eth (+C/SVLAN headers) && Tx <= 2048 */
+ gps = 1500 + ETH_HLEN + ETH_FCS_LEN;
+ }
+
+ writel(value, ioaddr + GMAC_CONFIG);
+
+ value = readl(ioaddr + GMAC_EXT_CONFIG);
+ value |= FIELD_PREP(GMAC_CONFIG_GPSL, gps);
+ writel(value, ioaddr + GMAC_EXT_CONFIG);
+
+ /* Over 2K, 3K, ..., 16K-1 frames will be truncated on Rx */
+ gps = ALIGN(gps + 2 * VLAN_HLEN, SZ_1K);
+ if (gps >= SZ_2K)
+ gps = gps / SZ_1K - 2;
+ else
+ gps = 0;
+
+ /* Over giant frame watchdog fine-tuning */
+ value = FIELD_PREP(GMAC_WDT_WTO, gps) | GMAC_WDT_PWE;
+ writel(value, ioaddr + GMAC_WDT);
/* Configure LPI 1us counter to number of CSR clock ticks in 1us - 1 */
clk_rate = clk_get_rate(priv->plat->stmmac_clk);