mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-16 18:36:46 +07:00
net: stmmac: Add MAC related callbacks for XGMAC2
Add the MAC related callbacks for the new IP block XGMAC2. Signed-off-by: Jose Abreu <joabreu@synopsys.com> Cc: David S. Miller <davem@davemloft.net> Cc: Joao Pinto <jpinto@synopsys.com> Cc: Giuseppe Cavallaro <peppe.cavallaro@st.com> Cc: Alexandre Torgue <alexandre.torgue@st.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
48ae5554a0
commit
2142754f8b
@ -5,7 +5,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \
|
|||||||
dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \
|
dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \
|
||||||
mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o \
|
mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o \
|
||||||
dwmac4_dma.o dwmac4_lib.o dwmac4_core.o dwmac5.o hwif.o \
|
dwmac4_dma.o dwmac4_lib.o dwmac4_core.o dwmac5.o hwif.o \
|
||||||
stmmac_tc.o $(stmmac-y)
|
stmmac_tc.o dwxgmac2_core.o $(stmmac-y)
|
||||||
|
|
||||||
# Ordering matters. Generic driver must be last.
|
# Ordering matters. Generic driver must be last.
|
||||||
obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o
|
obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o
|
||||||
|
@ -400,6 +400,8 @@ struct mac_link {
|
|||||||
u32 speed10;
|
u32 speed10;
|
||||||
u32 speed100;
|
u32 speed100;
|
||||||
u32 speed1000;
|
u32 speed1000;
|
||||||
|
u32 speed2500;
|
||||||
|
u32 speed10000;
|
||||||
u32 duplex;
|
u32 duplex;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -441,6 +443,7 @@ struct stmmac_rx_routing {
|
|||||||
int dwmac100_setup(struct stmmac_priv *priv);
|
int dwmac100_setup(struct stmmac_priv *priv);
|
||||||
int dwmac1000_setup(struct stmmac_priv *priv);
|
int dwmac1000_setup(struct stmmac_priv *priv);
|
||||||
int dwmac4_setup(struct stmmac_priv *priv);
|
int dwmac4_setup(struct stmmac_priv *priv);
|
||||||
|
int dwxgmac2_setup(struct stmmac_priv *priv);
|
||||||
|
|
||||||
void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6],
|
void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6],
|
||||||
unsigned int high, unsigned int low);
|
unsigned int high, unsigned int low);
|
||||||
|
141
drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
Normal file
141
drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 Synopsys, Inc. and/or its affiliates.
|
||||||
|
* stmmac XGMAC definitions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __STMMAC_DWXGMAC2_H__
|
||||||
|
#define __STMMAC_DWXGMAC2_H__
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
/* Misc */
|
||||||
|
#define XGMAC_JUMBO_LEN 16368
|
||||||
|
|
||||||
|
/* MAC Registers */
|
||||||
|
#define XGMAC_TX_CONFIG 0x00000000
|
||||||
|
#define XGMAC_CONFIG_SS_OFF 29
|
||||||
|
#define XGMAC_CONFIG_SS_MASK GENMASK(30, 29)
|
||||||
|
#define XGMAC_CONFIG_SS_10000 (0x0 << XGMAC_CONFIG_SS_OFF)
|
||||||
|
#define XGMAC_CONFIG_SS_2500 (0x2 << XGMAC_CONFIG_SS_OFF)
|
||||||
|
#define XGMAC_CONFIG_SS_1000 (0x3 << XGMAC_CONFIG_SS_OFF)
|
||||||
|
#define XGMAC_CONFIG_SARC GENMASK(22, 20)
|
||||||
|
#define XGMAC_CONFIG_SARC_SHIFT 20
|
||||||
|
#define XGMAC_CONFIG_JD BIT(16)
|
||||||
|
#define XGMAC_CONFIG_TE BIT(0)
|
||||||
|
#define XGMAC_CORE_INIT_TX (XGMAC_CONFIG_JD)
|
||||||
|
#define XGMAC_RX_CONFIG 0x00000004
|
||||||
|
#define XGMAC_CONFIG_ARPEN BIT(31)
|
||||||
|
#define XGMAC_CONFIG_GPSL GENMASK(29, 16)
|
||||||
|
#define XGMAC_CONFIG_GPSL_SHIFT 16
|
||||||
|
#define XGMAC_CONFIG_S2KP BIT(11)
|
||||||
|
#define XGMAC_CONFIG_IPC BIT(9)
|
||||||
|
#define XGMAC_CONFIG_JE BIT(8)
|
||||||
|
#define XGMAC_CONFIG_WD BIT(7)
|
||||||
|
#define XGMAC_CONFIG_GPSLCE BIT(6)
|
||||||
|
#define XGMAC_CONFIG_CST BIT(2)
|
||||||
|
#define XGMAC_CONFIG_ACS BIT(1)
|
||||||
|
#define XGMAC_CONFIG_RE BIT(0)
|
||||||
|
#define XGMAC_CORE_INIT_RX 0
|
||||||
|
#define XGMAC_PACKET_FILTER 0x00000008
|
||||||
|
#define XGMAC_FILTER_RA BIT(31)
|
||||||
|
#define XGMAC_FILTER_PM BIT(4)
|
||||||
|
#define XGMAC_FILTER_HMC BIT(2)
|
||||||
|
#define XGMAC_FILTER_PR BIT(0)
|
||||||
|
#define XGMAC_HASH_TABLE(x) (0x00000010 + (x) * 4)
|
||||||
|
#define XGMAC_RXQ_CTRL0 0x000000a0
|
||||||
|
#define XGMAC_RXQEN(x) GENMASK((x) * 2 + 1, (x) * 2)
|
||||||
|
#define XGMAC_RXQEN_SHIFT(x) ((x) * 2)
|
||||||
|
#define XGMAC_RXQ_CTRL2 0x000000a8
|
||||||
|
#define XGMAC_RXQ_CTRL3 0x000000ac
|
||||||
|
#define XGMAC_PSRQ(x) GENMASK((x) * 8 + 7, (x) * 8)
|
||||||
|
#define XGMAC_PSRQ_SHIFT(x) ((x) * 8)
|
||||||
|
#define XGMAC_INT_STATUS 0x000000b0
|
||||||
|
#define XGMAC_PMTIS BIT(4)
|
||||||
|
#define XGMAC_INT_EN 0x000000b4
|
||||||
|
#define XGMAC_TSIE BIT(12)
|
||||||
|
#define XGMAC_LPIIE BIT(5)
|
||||||
|
#define XGMAC_PMTIE BIT(4)
|
||||||
|
#define XGMAC_INT_DEFAULT_EN (XGMAC_LPIIE | XGMAC_PMTIE | XGMAC_TSIE)
|
||||||
|
#define XGMAC_Qx_TX_FLOW_CTRL(x) (0x00000070 + (x) * 4)
|
||||||
|
#define XGMAC_PT GENMASK(31, 16)
|
||||||
|
#define XGMAC_PT_SHIFT 16
|
||||||
|
#define XGMAC_TFE BIT(1)
|
||||||
|
#define XGMAC_RX_FLOW_CTRL 0x00000090
|
||||||
|
#define XGMAC_RFE BIT(0)
|
||||||
|
#define XGMAC_PMT 0x000000c0
|
||||||
|
#define XGMAC_GLBLUCAST BIT(9)
|
||||||
|
#define XGMAC_RWKPKTEN BIT(2)
|
||||||
|
#define XGMAC_MGKPKTEN BIT(1)
|
||||||
|
#define XGMAC_PWRDWN BIT(0)
|
||||||
|
#define XGMAC_HW_FEATURE0 0x0000011c
|
||||||
|
#define XGMAC_HWFEAT_SAVLANINS BIT(27)
|
||||||
|
#define XGMAC_HWFEAT_RXCOESEL BIT(16)
|
||||||
|
#define XGMAC_HWFEAT_TXCOESEL BIT(14)
|
||||||
|
#define XGMAC_HWFEAT_TSSEL BIT(12)
|
||||||
|
#define XGMAC_HWFEAT_AVSEL BIT(11)
|
||||||
|
#define XGMAC_HWFEAT_RAVSEL BIT(10)
|
||||||
|
#define XGMAC_HWFEAT_ARPOFFSEL BIT(9)
|
||||||
|
#define XGMAC_HWFEAT_MGKSEL BIT(7)
|
||||||
|
#define XGMAC_HWFEAT_RWKSEL BIT(6)
|
||||||
|
#define XGMAC_HWFEAT_GMIISEL BIT(1)
|
||||||
|
#define XGMAC_HW_FEATURE1 0x00000120
|
||||||
|
#define XGMAC_HWFEAT_TSOEN BIT(18)
|
||||||
|
#define XGMAC_HWFEAT_TXFIFOSIZE GENMASK(10, 6)
|
||||||
|
#define XGMAC_HWFEAT_RXFIFOSIZE GENMASK(4, 0)
|
||||||
|
#define XGMAC_HW_FEATURE2 0x00000124
|
||||||
|
#define XGMAC_HWFEAT_PPSOUTNUM GENMASK(26, 24)
|
||||||
|
#define XGMAC_HWFEAT_TXCHCNT GENMASK(21, 18)
|
||||||
|
#define XGMAC_HWFEAT_RXCHCNT GENMASK(15, 12)
|
||||||
|
#define XGMAC_HWFEAT_TXQCNT GENMASK(9, 6)
|
||||||
|
#define XGMAC_HWFEAT_RXQCNT GENMASK(3, 0)
|
||||||
|
#define XGMAC_MDIO_ADDR 0x00000200
|
||||||
|
#define XGMAC_MDIO_DATA 0x00000204
|
||||||
|
#define XGMAC_MDIO_C22P 0x00000220
|
||||||
|
#define XGMAC_ADDR0_HIGH 0x00000300
|
||||||
|
#define XGMAC_AE BIT(31)
|
||||||
|
#define XGMAC_DCS GENMASK(19, 16)
|
||||||
|
#define XGMAC_DCS_SHIFT 16
|
||||||
|
#define XGMAC_ADDR0_LOW 0x00000304
|
||||||
|
#define XGMAC_ARP_ADDR 0x00000c10
|
||||||
|
#define XGMAC_TIMESTAMP_STATUS 0x00000d20
|
||||||
|
#define XGMAC_TXTSC BIT(15)
|
||||||
|
#define XGMAC_TXTIMESTAMP_NSEC 0x00000d30
|
||||||
|
#define XGMAC_TXTSSTSLO GENMASK(30, 0)
|
||||||
|
#define XGMAC_TXTIMESTAMP_SEC 0x00000d34
|
||||||
|
|
||||||
|
/* MTL Registers */
|
||||||
|
#define XGMAC_MTL_OPMODE 0x00001000
|
||||||
|
#define XGMAC_ETSALG GENMASK(6, 5)
|
||||||
|
#define XGMAC_WRR (0x0 << 5)
|
||||||
|
#define XGMAC_WFQ (0x1 << 5)
|
||||||
|
#define XGMAC_DWRR (0x2 << 5)
|
||||||
|
#define XGMAC_RAA BIT(2)
|
||||||
|
#define XGMAC_MTL_INT_STATUS 0x00001020
|
||||||
|
#define XGMAC_MTL_RXQ_DMA_MAP0 0x00001030
|
||||||
|
#define XGMAC_MTL_RXQ_DMA_MAP1 0x00001034
|
||||||
|
#define XGMAC_QxMDMACH(x) GENMASK((x) * 8 + 3, (x) * 8)
|
||||||
|
#define XGMAC_QxMDMACH_SHIFT(x) ((x) * 8)
|
||||||
|
#define XGMAC_MTL_TXQ_OPMODE(x) (0x00001100 + (0x80 * (x)))
|
||||||
|
#define XGMAC_TQS GENMASK(25, 16)
|
||||||
|
#define XGMAC_TQS_SHIFT 16
|
||||||
|
#define XGMAC_TTC GENMASK(6, 4)
|
||||||
|
#define XGMAC_TTC_SHIFT 4
|
||||||
|
#define XGMAC_TXQEN GENMASK(3, 2)
|
||||||
|
#define XGMAC_TXQEN_SHIFT 2
|
||||||
|
#define XGMAC_TSF BIT(1)
|
||||||
|
#define XGMAC_MTL_RXQ_OPMODE(x) (0x00001140 + (0x80 * (x)))
|
||||||
|
#define XGMAC_RQS GENMASK(25, 16)
|
||||||
|
#define XGMAC_RQS_SHIFT 16
|
||||||
|
#define XGMAC_EHFC BIT(7)
|
||||||
|
#define XGMAC_RSF BIT(5)
|
||||||
|
#define XGMAC_RTC GENMASK(1, 0)
|
||||||
|
#define XGMAC_RTC_SHIFT 0
|
||||||
|
#define XGMAC_MTL_QINTEN(x) (0x00001170 + (0x80 * (x)))
|
||||||
|
#define XGMAC_RXOIE BIT(16)
|
||||||
|
#define XGMAC_MTL_QINT_STATUS(x) (0x00001174 + (0x80 * (x)))
|
||||||
|
#define XGMAC_RXOVFIS BIT(16)
|
||||||
|
#define XGMAC_ABPSIS BIT(1)
|
||||||
|
#define XGMAC_TXUNFIS BIT(0)
|
||||||
|
|
||||||
|
#endif /* __STMMAC_DWXGMAC2_H__ */
|
371
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
Normal file
371
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
Normal file
@ -0,0 +1,371 @@
|
|||||||
|
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 Synopsys, Inc. and/or its affiliates.
|
||||||
|
* stmmac XGMAC support.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stmmac.h"
|
||||||
|
#include "dwxgmac2.h"
|
||||||
|
|
||||||
|
static void dwxgmac2_core_init(struct mac_device_info *hw,
|
||||||
|
struct net_device *dev)
|
||||||
|
{
|
||||||
|
void __iomem *ioaddr = hw->pcsr;
|
||||||
|
int mtu = dev->mtu;
|
||||||
|
u32 tx, rx;
|
||||||
|
|
||||||
|
tx = readl(ioaddr + XGMAC_TX_CONFIG);
|
||||||
|
rx = readl(ioaddr + XGMAC_RX_CONFIG);
|
||||||
|
|
||||||
|
tx |= XGMAC_CORE_INIT_TX;
|
||||||
|
rx |= XGMAC_CORE_INIT_RX;
|
||||||
|
|
||||||
|
if (mtu >= 9000) {
|
||||||
|
rx |= XGMAC_CONFIG_GPSLCE;
|
||||||
|
rx |= XGMAC_JUMBO_LEN << XGMAC_CONFIG_GPSL_SHIFT;
|
||||||
|
rx |= XGMAC_CONFIG_WD;
|
||||||
|
} else if (mtu > 2000) {
|
||||||
|
rx |= XGMAC_CONFIG_JE;
|
||||||
|
} else if (mtu > 1500) {
|
||||||
|
rx |= XGMAC_CONFIG_S2KP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hw->ps) {
|
||||||
|
tx |= XGMAC_CONFIG_TE;
|
||||||
|
tx &= ~hw->link.speed_mask;
|
||||||
|
|
||||||
|
switch (hw->ps) {
|
||||||
|
case SPEED_10000:
|
||||||
|
tx |= hw->link.speed10000;
|
||||||
|
break;
|
||||||
|
case SPEED_2500:
|
||||||
|
tx |= hw->link.speed2500;
|
||||||
|
break;
|
||||||
|
case SPEED_1000:
|
||||||
|
default:
|
||||||
|
tx |= hw->link.speed1000;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writel(tx, ioaddr + XGMAC_TX_CONFIG);
|
||||||
|
writel(rx, ioaddr + XGMAC_RX_CONFIG);
|
||||||
|
writel(XGMAC_INT_DEFAULT_EN, ioaddr + XGMAC_INT_EN);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dwxgmac2_set_mac(void __iomem *ioaddr, bool enable)
|
||||||
|
{
|
||||||
|
u32 tx = readl(ioaddr + XGMAC_TX_CONFIG);
|
||||||
|
u32 rx = readl(ioaddr + XGMAC_RX_CONFIG);
|
||||||
|
|
||||||
|
if (enable) {
|
||||||
|
tx |= XGMAC_CONFIG_TE;
|
||||||
|
rx |= XGMAC_CONFIG_RE;
|
||||||
|
} else {
|
||||||
|
tx &= ~XGMAC_CONFIG_TE;
|
||||||
|
rx &= ~XGMAC_CONFIG_RE;
|
||||||
|
}
|
||||||
|
|
||||||
|
writel(tx, ioaddr + XGMAC_TX_CONFIG);
|
||||||
|
writel(rx, ioaddr + XGMAC_RX_CONFIG);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dwxgmac2_rx_ipc(struct mac_device_info *hw)
|
||||||
|
{
|
||||||
|
void __iomem *ioaddr = hw->pcsr;
|
||||||
|
u32 value;
|
||||||
|
|
||||||
|
value = readl(ioaddr + XGMAC_RX_CONFIG);
|
||||||
|
if (hw->rx_csum)
|
||||||
|
value |= XGMAC_CONFIG_IPC;
|
||||||
|
else
|
||||||
|
value &= ~XGMAC_CONFIG_IPC;
|
||||||
|
writel(value, ioaddr + XGMAC_RX_CONFIG);
|
||||||
|
|
||||||
|
return !!(readl(ioaddr + XGMAC_RX_CONFIG) & XGMAC_CONFIG_IPC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dwxgmac2_rx_queue_enable(struct mac_device_info *hw, u8 mode,
|
||||||
|
u32 queue)
|
||||||
|
{
|
||||||
|
void __iomem *ioaddr = hw->pcsr;
|
||||||
|
u32 value;
|
||||||
|
|
||||||
|
value = readl(ioaddr + XGMAC_RXQ_CTRL0) & ~XGMAC_RXQEN(queue);
|
||||||
|
if (mode == MTL_QUEUE_AVB)
|
||||||
|
value |= 0x1 << XGMAC_RXQEN_SHIFT(queue);
|
||||||
|
else if (mode == MTL_QUEUE_DCB)
|
||||||
|
value |= 0x2 << XGMAC_RXQEN_SHIFT(queue);
|
||||||
|
writel(value, ioaddr + XGMAC_RXQ_CTRL0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dwxgmac2_rx_queue_prio(struct mac_device_info *hw, u32 prio,
|
||||||
|
u32 queue)
|
||||||
|
{
|
||||||
|
void __iomem *ioaddr = hw->pcsr;
|
||||||
|
u32 value, reg;
|
||||||
|
|
||||||
|
reg = (queue < 4) ? XGMAC_RXQ_CTRL2 : XGMAC_RXQ_CTRL3;
|
||||||
|
|
||||||
|
value = readl(ioaddr + reg);
|
||||||
|
value &= ~XGMAC_PSRQ(queue);
|
||||||
|
value |= (prio << XGMAC_PSRQ_SHIFT(queue)) & XGMAC_PSRQ(queue);
|
||||||
|
|
||||||
|
writel(value, ioaddr + reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dwxgmac2_prog_mtl_rx_algorithms(struct mac_device_info *hw,
|
||||||
|
u32 rx_alg)
|
||||||
|
{
|
||||||
|
void __iomem *ioaddr = hw->pcsr;
|
||||||
|
u32 value;
|
||||||
|
|
||||||
|
value = readl(ioaddr + XGMAC_MTL_OPMODE);
|
||||||
|
value &= ~XGMAC_RAA;
|
||||||
|
|
||||||
|
switch (rx_alg) {
|
||||||
|
case MTL_RX_ALGORITHM_SP:
|
||||||
|
break;
|
||||||
|
case MTL_RX_ALGORITHM_WSP:
|
||||||
|
value |= XGMAC_RAA;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
writel(value, ioaddr + XGMAC_MTL_OPMODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dwxgmac2_prog_mtl_tx_algorithms(struct mac_device_info *hw,
|
||||||
|
u32 tx_alg)
|
||||||
|
{
|
||||||
|
void __iomem *ioaddr = hw->pcsr;
|
||||||
|
u32 value;
|
||||||
|
|
||||||
|
value = readl(ioaddr + XGMAC_MTL_OPMODE);
|
||||||
|
value &= ~XGMAC_ETSALG;
|
||||||
|
|
||||||
|
switch (tx_alg) {
|
||||||
|
case MTL_TX_ALGORITHM_WRR:
|
||||||
|
value |= XGMAC_WRR;
|
||||||
|
break;
|
||||||
|
case MTL_TX_ALGORITHM_WFQ:
|
||||||
|
value |= XGMAC_WFQ;
|
||||||
|
break;
|
||||||
|
case MTL_TX_ALGORITHM_DWRR:
|
||||||
|
value |= XGMAC_DWRR;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
writel(value, ioaddr + XGMAC_MTL_OPMODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dwxgmac2_map_mtl_to_dma(struct mac_device_info *hw, u32 queue,
|
||||||
|
u32 chan)
|
||||||
|
{
|
||||||
|
void __iomem *ioaddr = hw->pcsr;
|
||||||
|
u32 value, reg;
|
||||||
|
|
||||||
|
reg = (queue < 4) ? XGMAC_MTL_RXQ_DMA_MAP0 : XGMAC_MTL_RXQ_DMA_MAP1;
|
||||||
|
|
||||||
|
value = readl(ioaddr + reg);
|
||||||
|
value &= ~XGMAC_QxMDMACH(queue);
|
||||||
|
value |= (chan << XGMAC_QxMDMACH_SHIFT(queue)) & XGMAC_QxMDMACH(queue);
|
||||||
|
|
||||||
|
writel(value, ioaddr + reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dwxgmac2_host_irq_status(struct mac_device_info *hw,
|
||||||
|
struct stmmac_extra_stats *x)
|
||||||
|
{
|
||||||
|
void __iomem *ioaddr = hw->pcsr;
|
||||||
|
u32 stat, en;
|
||||||
|
|
||||||
|
en = readl(ioaddr + XGMAC_INT_EN);
|
||||||
|
stat = readl(ioaddr + XGMAC_INT_STATUS);
|
||||||
|
|
||||||
|
stat &= en;
|
||||||
|
|
||||||
|
if (stat & XGMAC_PMTIS) {
|
||||||
|
x->irq_receive_pmt_irq_n++;
|
||||||
|
readl(ioaddr + XGMAC_PMT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dwxgmac2_host_mtl_irq_status(struct mac_device_info *hw, u32 chan)
|
||||||
|
{
|
||||||
|
void __iomem *ioaddr = hw->pcsr;
|
||||||
|
int ret = 0;
|
||||||
|
u32 status;
|
||||||
|
|
||||||
|
status = readl(ioaddr + XGMAC_MTL_INT_STATUS);
|
||||||
|
if (status & BIT(chan)) {
|
||||||
|
u32 chan_status = readl(ioaddr + XGMAC_MTL_QINT_STATUS(chan));
|
||||||
|
|
||||||
|
if (chan_status & XGMAC_RXOVFIS)
|
||||||
|
ret |= CORE_IRQ_MTL_RX_OVERFLOW;
|
||||||
|
|
||||||
|
writel(~0x0, ioaddr + XGMAC_MTL_QINT_STATUS(chan));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dwxgmac2_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
|
||||||
|
unsigned int fc, unsigned int pause_time,
|
||||||
|
u32 tx_cnt)
|
||||||
|
{
|
||||||
|
void __iomem *ioaddr = hw->pcsr;
|
||||||
|
u32 i;
|
||||||
|
|
||||||
|
if (fc & FLOW_RX)
|
||||||
|
writel(XGMAC_RFE, ioaddr + XGMAC_RX_FLOW_CTRL);
|
||||||
|
if (fc & FLOW_TX) {
|
||||||
|
for (i = 0; i < tx_cnt; i++) {
|
||||||
|
u32 value = XGMAC_TFE;
|
||||||
|
|
||||||
|
if (duplex)
|
||||||
|
value |= pause_time << XGMAC_PT_SHIFT;
|
||||||
|
|
||||||
|
writel(value, ioaddr + XGMAC_Qx_TX_FLOW_CTRL(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dwxgmac2_pmt(struct mac_device_info *hw, unsigned long mode)
|
||||||
|
{
|
||||||
|
void __iomem *ioaddr = hw->pcsr;
|
||||||
|
u32 val = 0x0;
|
||||||
|
|
||||||
|
if (mode & WAKE_MAGIC)
|
||||||
|
val |= XGMAC_PWRDWN | XGMAC_MGKPKTEN;
|
||||||
|
if (mode & WAKE_UCAST)
|
||||||
|
val |= XGMAC_PWRDWN | XGMAC_GLBLUCAST | XGMAC_RWKPKTEN;
|
||||||
|
if (val) {
|
||||||
|
u32 cfg = readl(ioaddr + XGMAC_RX_CONFIG);
|
||||||
|
cfg |= XGMAC_CONFIG_RE;
|
||||||
|
writel(cfg, ioaddr + XGMAC_RX_CONFIG);
|
||||||
|
}
|
||||||
|
|
||||||
|
writel(val, ioaddr + XGMAC_PMT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dwxgmac2_set_umac_addr(struct mac_device_info *hw,
|
||||||
|
unsigned char *addr, unsigned int reg_n)
|
||||||
|
{
|
||||||
|
void __iomem *ioaddr = hw->pcsr;
|
||||||
|
u32 value;
|
||||||
|
|
||||||
|
value = (addr[5] << 8) | addr[4];
|
||||||
|
writel(value | XGMAC_AE, ioaddr + XGMAC_ADDR0_HIGH);
|
||||||
|
|
||||||
|
value = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0];
|
||||||
|
writel(value, ioaddr + XGMAC_ADDR0_LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dwxgmac2_get_umac_addr(struct mac_device_info *hw,
|
||||||
|
unsigned char *addr, unsigned int reg_n)
|
||||||
|
{
|
||||||
|
void __iomem *ioaddr = hw->pcsr;
|
||||||
|
u32 hi_addr, lo_addr;
|
||||||
|
|
||||||
|
/* Read the MAC address from the hardware */
|
||||||
|
hi_addr = readl(ioaddr + XGMAC_ADDR0_HIGH);
|
||||||
|
lo_addr = readl(ioaddr + XGMAC_ADDR0_LOW);
|
||||||
|
|
||||||
|
/* Extract the MAC address from the high and low words */
|
||||||
|
addr[0] = lo_addr & 0xff;
|
||||||
|
addr[1] = (lo_addr >> 8) & 0xff;
|
||||||
|
addr[2] = (lo_addr >> 16) & 0xff;
|
||||||
|
addr[3] = (lo_addr >> 24) & 0xff;
|
||||||
|
addr[4] = hi_addr & 0xff;
|
||||||
|
addr[5] = (hi_addr >> 8) & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dwxgmac2_set_filter(struct mac_device_info *hw,
|
||||||
|
struct net_device *dev)
|
||||||
|
{
|
||||||
|
void __iomem *ioaddr = (void __iomem *)dev->base_addr;
|
||||||
|
u32 value = XGMAC_FILTER_RA;
|
||||||
|
|
||||||
|
if (dev->flags & IFF_PROMISC) {
|
||||||
|
value |= XGMAC_FILTER_PR;
|
||||||
|
} else if ((dev->flags & IFF_ALLMULTI) ||
|
||||||
|
(netdev_mc_count(dev) > HASH_TABLE_SIZE)) {
|
||||||
|
value |= XGMAC_FILTER_PM;
|
||||||
|
writel(~0x0, ioaddr + XGMAC_HASH_TABLE(0));
|
||||||
|
writel(~0x0, ioaddr + XGMAC_HASH_TABLE(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
writel(value, ioaddr + XGMAC_PACKET_FILTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct stmmac_ops dwxgmac210_ops = {
|
||||||
|
.core_init = dwxgmac2_core_init,
|
||||||
|
.set_mac = dwxgmac2_set_mac,
|
||||||
|
.rx_ipc = dwxgmac2_rx_ipc,
|
||||||
|
.rx_queue_enable = dwxgmac2_rx_queue_enable,
|
||||||
|
.rx_queue_prio = dwxgmac2_rx_queue_prio,
|
||||||
|
.tx_queue_prio = NULL,
|
||||||
|
.rx_queue_routing = NULL,
|
||||||
|
.prog_mtl_rx_algorithms = dwxgmac2_prog_mtl_rx_algorithms,
|
||||||
|
.prog_mtl_tx_algorithms = dwxgmac2_prog_mtl_tx_algorithms,
|
||||||
|
.set_mtl_tx_queue_weight = NULL,
|
||||||
|
.map_mtl_to_dma = dwxgmac2_map_mtl_to_dma,
|
||||||
|
.config_cbs = NULL,
|
||||||
|
.dump_regs = NULL,
|
||||||
|
.host_irq_status = dwxgmac2_host_irq_status,
|
||||||
|
.host_mtl_irq_status = dwxgmac2_host_mtl_irq_status,
|
||||||
|
.flow_ctrl = dwxgmac2_flow_ctrl,
|
||||||
|
.pmt = dwxgmac2_pmt,
|
||||||
|
.set_umac_addr = dwxgmac2_set_umac_addr,
|
||||||
|
.get_umac_addr = dwxgmac2_get_umac_addr,
|
||||||
|
.set_eee_mode = NULL,
|
||||||
|
.reset_eee_mode = NULL,
|
||||||
|
.set_eee_timer = NULL,
|
||||||
|
.set_eee_pls = NULL,
|
||||||
|
.pcs_ctrl_ane = NULL,
|
||||||
|
.pcs_rane = NULL,
|
||||||
|
.pcs_get_adv_lp = NULL,
|
||||||
|
.debug = NULL,
|
||||||
|
.set_filter = dwxgmac2_set_filter,
|
||||||
|
};
|
||||||
|
|
||||||
|
int dwxgmac2_setup(struct stmmac_priv *priv)
|
||||||
|
{
|
||||||
|
struct mac_device_info *mac = priv->hw;
|
||||||
|
|
||||||
|
dev_info(priv->device, "\tXGMAC2\n");
|
||||||
|
|
||||||
|
priv->dev->priv_flags |= IFF_UNICAST_FLT;
|
||||||
|
mac->pcsr = priv->ioaddr;
|
||||||
|
mac->multicast_filter_bins = priv->plat->multicast_filter_bins;
|
||||||
|
mac->unicast_filter_entries = priv->plat->unicast_filter_entries;
|
||||||
|
mac->mcast_bits_log2 = 0;
|
||||||
|
|
||||||
|
if (mac->multicast_filter_bins)
|
||||||
|
mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
|
||||||
|
|
||||||
|
mac->link.duplex = 0;
|
||||||
|
mac->link.speed10 = 0;
|
||||||
|
mac->link.speed100 = 0;
|
||||||
|
mac->link.speed1000 = XGMAC_CONFIG_SS_1000;
|
||||||
|
mac->link.speed2500 = XGMAC_CONFIG_SS_2500;
|
||||||
|
mac->link.speed10000 = XGMAC_CONFIG_SS_10000;
|
||||||
|
mac->link.speed_mask = XGMAC_CONFIG_SS_MASK;
|
||||||
|
|
||||||
|
mac->mii.addr = XGMAC_MDIO_ADDR;
|
||||||
|
mac->mii.data = XGMAC_MDIO_DATA;
|
||||||
|
mac->mii.addr_shift = 16;
|
||||||
|
mac->mii.addr_mask = GENMASK(20, 16);
|
||||||
|
mac->mii.reg_shift = 0;
|
||||||
|
mac->mii.reg_mask = GENMASK(15, 0);
|
||||||
|
mac->mii.clk_csr_shift = 19;
|
||||||
|
mac->mii.clk_csr_mask = GENMASK(21, 19);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -198,11 +198,11 @@ static const struct stmmac_hwif_entry {
|
|||||||
},
|
},
|
||||||
.desc = NULL,
|
.desc = NULL,
|
||||||
.dma = NULL,
|
.dma = NULL,
|
||||||
.mac = NULL,
|
.mac = &dwxgmac210_ops,
|
||||||
.hwtimestamp = NULL,
|
.hwtimestamp = NULL,
|
||||||
.mode = NULL,
|
.mode = NULL,
|
||||||
.tc = NULL,
|
.tc = NULL,
|
||||||
.setup = NULL,
|
.setup = dwxgmac2_setup,
|
||||||
.quirks = NULL,
|
.quirks = NULL,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -479,6 +479,7 @@ extern const struct stmmac_ops dwmac410_ops;
|
|||||||
extern const struct stmmac_dma_ops dwmac410_dma_ops;
|
extern const struct stmmac_dma_ops dwmac410_dma_ops;
|
||||||
extern const struct stmmac_ops dwmac510_ops;
|
extern const struct stmmac_ops dwmac510_ops;
|
||||||
extern const struct stmmac_tc_ops dwmac510_tc_ops;
|
extern const struct stmmac_tc_ops dwmac510_tc_ops;
|
||||||
|
extern const struct stmmac_ops dwxgmac210_ops;
|
||||||
|
|
||||||
#define GMAC_VERSION 0x00000020 /* GMAC CORE Version */
|
#define GMAC_VERSION 0x00000020 /* GMAC CORE Version */
|
||||||
#define GMAC4_VERSION 0x00000110 /* GMAC4+ CORE Version */
|
#define GMAC4_VERSION 0x00000110 /* GMAC4+ CORE Version */
|
||||||
|
Loading…
Reference in New Issue
Block a user