diff options
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 12 | ||||
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 37 |
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); |
