1 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
3 * Copyright (c) 2018 Synopsys, Inc. and/or its affiliates.
4 * stmmac XGMAC support.
7 #include <linux/bitrev.h>
8 #include <linux/crc32.h>
12 static void dwxgmac2_core_init(struct mac_device_info *hw,
13 struct net_device *dev)
15 void __iomem *ioaddr = hw->pcsr;
19 tx = readl(ioaddr + XGMAC_TX_CONFIG);
20 rx = readl(ioaddr + XGMAC_RX_CONFIG);
22 tx |= XGMAC_CORE_INIT_TX;
23 rx |= XGMAC_CORE_INIT_RX;
26 rx |= XGMAC_CONFIG_GPSLCE;
27 rx |= XGMAC_JUMBO_LEN << XGMAC_CONFIG_GPSL_SHIFT;
28 rx |= XGMAC_CONFIG_WD;
29 } else if (mtu > 2000) {
30 rx |= XGMAC_CONFIG_JE;
31 } else if (mtu > 1500) {
32 rx |= XGMAC_CONFIG_S2KP;
36 tx |= XGMAC_CONFIG_TE;
37 tx &= ~hw->link.speed_mask;
41 tx |= hw->link.xgmii.speed10000;
44 tx |= hw->link.speed2500;
48 tx |= hw->link.speed1000;
53 writel(tx, ioaddr + XGMAC_TX_CONFIG);
54 writel(rx, ioaddr + XGMAC_RX_CONFIG);
55 writel(XGMAC_INT_DEFAULT_EN, ioaddr + XGMAC_INT_EN);
58 static void dwxgmac2_set_mac(void __iomem *ioaddr, bool enable)
60 u32 tx = readl(ioaddr + XGMAC_TX_CONFIG);
61 u32 rx = readl(ioaddr + XGMAC_RX_CONFIG);
64 tx |= XGMAC_CONFIG_TE;
65 rx |= XGMAC_CONFIG_RE;
67 tx &= ~XGMAC_CONFIG_TE;
68 rx &= ~XGMAC_CONFIG_RE;
71 writel(tx, ioaddr + XGMAC_TX_CONFIG);
72 writel(rx, ioaddr + XGMAC_RX_CONFIG);
75 static int dwxgmac2_rx_ipc(struct mac_device_info *hw)
77 void __iomem *ioaddr = hw->pcsr;
80 value = readl(ioaddr + XGMAC_RX_CONFIG);
82 value |= XGMAC_CONFIG_IPC;
84 value &= ~XGMAC_CONFIG_IPC;
85 writel(value, ioaddr + XGMAC_RX_CONFIG);
87 return !!(readl(ioaddr + XGMAC_RX_CONFIG) & XGMAC_CONFIG_IPC);
90 static void dwxgmac2_rx_queue_enable(struct mac_device_info *hw, u8 mode,
93 void __iomem *ioaddr = hw->pcsr;
96 value = readl(ioaddr + XGMAC_RXQ_CTRL0) & ~XGMAC_RXQEN(queue);
97 if (mode == MTL_QUEUE_AVB)
98 value |= 0x1 << XGMAC_RXQEN_SHIFT(queue);
99 else if (mode == MTL_QUEUE_DCB)
100 value |= 0x2 << XGMAC_RXQEN_SHIFT(queue);
101 writel(value, ioaddr + XGMAC_RXQ_CTRL0);
104 static void dwxgmac2_rx_queue_prio(struct mac_device_info *hw, u32 prio,
107 void __iomem *ioaddr = hw->pcsr;
110 reg = (queue < 4) ? XGMAC_RXQ_CTRL2 : XGMAC_RXQ_CTRL3;
114 value = readl(ioaddr + reg);
115 value &= ~XGMAC_PSRQ(queue);
116 value |= (prio << XGMAC_PSRQ_SHIFT(queue)) & XGMAC_PSRQ(queue);
118 writel(value, ioaddr + reg);
121 static void dwxgmac2_prog_mtl_rx_algorithms(struct mac_device_info *hw,
124 void __iomem *ioaddr = hw->pcsr;
127 value = readl(ioaddr + XGMAC_MTL_OPMODE);
131 case MTL_RX_ALGORITHM_SP:
133 case MTL_RX_ALGORITHM_WSP:
140 writel(value, ioaddr + XGMAC_MTL_OPMODE);
143 static void dwxgmac2_prog_mtl_tx_algorithms(struct mac_device_info *hw,
146 void __iomem *ioaddr = hw->pcsr;
149 value = readl(ioaddr + XGMAC_MTL_OPMODE);
150 value &= ~XGMAC_ETSALG;
153 case MTL_TX_ALGORITHM_WRR:
156 case MTL_TX_ALGORITHM_WFQ:
159 case MTL_TX_ALGORITHM_DWRR:
166 writel(value, ioaddr + XGMAC_MTL_OPMODE);
169 static void dwxgmac2_map_mtl_to_dma(struct mac_device_info *hw, u32 queue,
172 void __iomem *ioaddr = hw->pcsr;
175 reg = (queue < 4) ? XGMAC_MTL_RXQ_DMA_MAP0 : XGMAC_MTL_RXQ_DMA_MAP1;
179 value = readl(ioaddr + reg);
180 value &= ~XGMAC_QxMDMACH(queue);
181 value |= (chan << XGMAC_QxMDMACH_SHIFT(queue)) & XGMAC_QxMDMACH(queue);
183 writel(value, ioaddr + reg);
186 static void dwxgmac2_config_cbs(struct mac_device_info *hw,
187 u32 send_slope, u32 idle_slope,
188 u32 high_credit, u32 low_credit, u32 queue)
190 void __iomem *ioaddr = hw->pcsr;
193 writel(send_slope, ioaddr + XGMAC_MTL_TCx_SENDSLOPE(queue));
194 writel(idle_slope, ioaddr + XGMAC_MTL_TCx_QUANTUM_WEIGHT(queue));
195 writel(high_credit, ioaddr + XGMAC_MTL_TCx_HICREDIT(queue));
196 writel(low_credit, ioaddr + XGMAC_MTL_TCx_LOCREDIT(queue));
198 value = readl(ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(queue));
199 value |= XGMAC_CC | XGMAC_CBS;
200 writel(value, ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(queue));
203 static int dwxgmac2_host_irq_status(struct mac_device_info *hw,
204 struct stmmac_extra_stats *x)
206 void __iomem *ioaddr = hw->pcsr;
209 en = readl(ioaddr + XGMAC_INT_EN);
210 stat = readl(ioaddr + XGMAC_INT_STATUS);
214 if (stat & XGMAC_PMTIS) {
215 x->irq_receive_pmt_irq_n++;
216 readl(ioaddr + XGMAC_PMT);
222 static int dwxgmac2_host_mtl_irq_status(struct mac_device_info *hw, u32 chan)
224 void __iomem *ioaddr = hw->pcsr;
228 status = readl(ioaddr + XGMAC_MTL_INT_STATUS);
229 if (status & BIT(chan)) {
230 u32 chan_status = readl(ioaddr + XGMAC_MTL_QINT_STATUS(chan));
232 if (chan_status & XGMAC_RXOVFIS)
233 ret |= CORE_IRQ_MTL_RX_OVERFLOW;
235 writel(~0x0, ioaddr + XGMAC_MTL_QINT_STATUS(chan));
241 static void dwxgmac2_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
242 unsigned int fc, unsigned int pause_time,
245 void __iomem *ioaddr = hw->pcsr;
249 writel(XGMAC_RFE, ioaddr + XGMAC_RX_FLOW_CTRL);
251 for (i = 0; i < tx_cnt; i++) {
252 u32 value = XGMAC_TFE;
255 value |= pause_time << XGMAC_PT_SHIFT;
257 writel(value, ioaddr + XGMAC_Qx_TX_FLOW_CTRL(i));
262 static void dwxgmac2_pmt(struct mac_device_info *hw, unsigned long mode)
264 void __iomem *ioaddr = hw->pcsr;
267 if (mode & WAKE_MAGIC)
268 val |= XGMAC_PWRDWN | XGMAC_MGKPKTEN;
269 if (mode & WAKE_UCAST)
270 val |= XGMAC_PWRDWN | XGMAC_GLBLUCAST | XGMAC_RWKPKTEN;
272 u32 cfg = readl(ioaddr + XGMAC_RX_CONFIG);
273 cfg |= XGMAC_CONFIG_RE;
274 writel(cfg, ioaddr + XGMAC_RX_CONFIG);
277 writel(val, ioaddr + XGMAC_PMT);
280 static void dwxgmac2_set_umac_addr(struct mac_device_info *hw,
281 unsigned char *addr, unsigned int reg_n)
283 void __iomem *ioaddr = hw->pcsr;
286 value = (addr[5] << 8) | addr[4];
287 writel(value | XGMAC_AE, ioaddr + XGMAC_ADDRx_HIGH(reg_n));
289 value = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0];
290 writel(value, ioaddr + XGMAC_ADDRx_LOW(reg_n));
293 static void dwxgmac2_get_umac_addr(struct mac_device_info *hw,
294 unsigned char *addr, unsigned int reg_n)
296 void __iomem *ioaddr = hw->pcsr;
297 u32 hi_addr, lo_addr;
299 /* Read the MAC address from the hardware */
300 hi_addr = readl(ioaddr + XGMAC_ADDRx_HIGH(reg_n));
301 lo_addr = readl(ioaddr + XGMAC_ADDRx_LOW(reg_n));
303 /* Extract the MAC address from the high and low words */
304 addr[0] = lo_addr & 0xff;
305 addr[1] = (lo_addr >> 8) & 0xff;
306 addr[2] = (lo_addr >> 16) & 0xff;
307 addr[3] = (lo_addr >> 24) & 0xff;
308 addr[4] = hi_addr & 0xff;
309 addr[5] = (hi_addr >> 8) & 0xff;
312 static void dwxgmac2_set_mchash(void __iomem *ioaddr, u32 *mcfilterbits,
315 int numhashregs, regs;
317 switch (mcbitslog2) {
331 for (regs = 0; regs < numhashregs; regs++)
332 writel(mcfilterbits[regs], ioaddr + XGMAC_HASH_TABLE(regs));
335 static void dwxgmac2_set_filter(struct mac_device_info *hw,
336 struct net_device *dev)
338 void __iomem *ioaddr = (void __iomem *)dev->base_addr;
339 u32 value = readl(ioaddr + XGMAC_PACKET_FILTER);
340 int mcbitslog2 = hw->mcast_bits_log2;
344 value &= ~(XGMAC_FILTER_PR | XGMAC_FILTER_HMC | XGMAC_FILTER_PM);
345 value |= XGMAC_FILTER_HPF;
347 memset(mc_filter, 0, sizeof(mc_filter));
349 if (dev->flags & IFF_PROMISC) {
350 value |= XGMAC_FILTER_PR;
351 value |= XGMAC_FILTER_PCF;
352 } else if ((dev->flags & IFF_ALLMULTI) ||
353 (netdev_mc_count(dev) > hw->multicast_filter_bins)) {
354 value |= XGMAC_FILTER_PM;
356 for (i = 0; i < XGMAC_MAX_HASH_TABLE; i++)
357 writel(~0x0, ioaddr + XGMAC_HASH_TABLE(i));
358 } else if (!netdev_mc_empty(dev)) {
359 struct netdev_hw_addr *ha;
361 value |= XGMAC_FILTER_HMC;
363 netdev_for_each_mc_addr(ha, dev) {
364 int nr = (bitrev32(~crc32_le(~0, ha->addr, 6)) >>
366 mc_filter[nr >> 5] |= (1 << (nr & 0x1F));
370 dwxgmac2_set_mchash(ioaddr, mc_filter, mcbitslog2);
372 /* Handle multiple unicast addresses */
373 if (netdev_uc_count(dev) > XGMAC_ADDR_MAX) {
374 value |= XGMAC_FILTER_PR;
376 struct netdev_hw_addr *ha;
379 netdev_for_each_uc_addr(ha, dev) {
380 dwxgmac2_set_umac_addr(hw, ha->addr, reg);
384 for ( ; reg < XGMAC_ADDR_MAX; reg++) {
385 writel(0, ioaddr + XGMAC_ADDRx_HIGH(reg));
386 writel(0, ioaddr + XGMAC_ADDRx_LOW(reg));
390 writel(value, ioaddr + XGMAC_PACKET_FILTER);
393 static void dwxgmac2_set_mac_loopback(void __iomem *ioaddr, bool enable)
395 u32 value = readl(ioaddr + XGMAC_RX_CONFIG);
398 value |= XGMAC_CONFIG_LM;
400 value &= ~XGMAC_CONFIG_LM;
402 writel(value, ioaddr + XGMAC_RX_CONFIG);
405 const struct stmmac_ops dwxgmac210_ops = {
406 .core_init = dwxgmac2_core_init,
407 .set_mac = dwxgmac2_set_mac,
408 .rx_ipc = dwxgmac2_rx_ipc,
409 .rx_queue_enable = dwxgmac2_rx_queue_enable,
410 .rx_queue_prio = dwxgmac2_rx_queue_prio,
411 .tx_queue_prio = NULL,
412 .rx_queue_routing = NULL,
413 .prog_mtl_rx_algorithms = dwxgmac2_prog_mtl_rx_algorithms,
414 .prog_mtl_tx_algorithms = dwxgmac2_prog_mtl_tx_algorithms,
415 .set_mtl_tx_queue_weight = NULL,
416 .map_mtl_to_dma = dwxgmac2_map_mtl_to_dma,
417 .config_cbs = dwxgmac2_config_cbs,
419 .host_irq_status = dwxgmac2_host_irq_status,
420 .host_mtl_irq_status = dwxgmac2_host_mtl_irq_status,
421 .flow_ctrl = dwxgmac2_flow_ctrl,
423 .set_umac_addr = dwxgmac2_set_umac_addr,
424 .get_umac_addr = dwxgmac2_get_umac_addr,
425 .set_eee_mode = NULL,
426 .reset_eee_mode = NULL,
427 .set_eee_timer = NULL,
429 .pcs_ctrl_ane = NULL,
431 .pcs_get_adv_lp = NULL,
433 .set_filter = dwxgmac2_set_filter,
434 .set_mac_loopback = dwxgmac2_set_mac_loopback,
437 int dwxgmac2_setup(struct stmmac_priv *priv)
439 struct mac_device_info *mac = priv->hw;
441 dev_info(priv->device, "\tXGMAC2\n");
443 priv->dev->priv_flags |= IFF_UNICAST_FLT;
444 mac->pcsr = priv->ioaddr;
445 mac->multicast_filter_bins = priv->plat->multicast_filter_bins;
446 mac->unicast_filter_entries = priv->plat->unicast_filter_entries;
447 mac->mcast_bits_log2 = 0;
449 if (mac->multicast_filter_bins)
450 mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
452 mac->link.duplex = 0;
453 mac->link.speed10 = XGMAC_CONFIG_SS_10_MII;
454 mac->link.speed100 = XGMAC_CONFIG_SS_100_MII;
455 mac->link.speed1000 = XGMAC_CONFIG_SS_1000_GMII;
456 mac->link.speed2500 = XGMAC_CONFIG_SS_2500_GMII;
457 mac->link.xgmii.speed2500 = XGMAC_CONFIG_SS_2500;
458 mac->link.xgmii.speed5000 = XGMAC_CONFIG_SS_5000;
459 mac->link.xgmii.speed10000 = XGMAC_CONFIG_SS_10000;
460 mac->link.speed_mask = XGMAC_CONFIG_SS_MASK;
462 mac->mii.addr = XGMAC_MDIO_ADDR;
463 mac->mii.data = XGMAC_MDIO_DATA;
464 mac->mii.addr_shift = 16;
465 mac->mii.addr_mask = GENMASK(20, 16);
466 mac->mii.reg_shift = 0;
467 mac->mii.reg_mask = GENMASK(15, 0);
468 mac->mii.clk_csr_shift = 19;
469 mac->mii.clk_csr_mask = GENMASK(21, 19);