1 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
3 * Copyright (c) 2018 Synopsys, Inc. and/or its affiliates.
4 * stmmac XGMAC support.
10 static void dwxgmac2_core_init(struct mac_device_info *hw,
11 struct net_device *dev)
13 void __iomem *ioaddr = hw->pcsr;
17 tx = readl(ioaddr + XGMAC_TX_CONFIG);
18 rx = readl(ioaddr + XGMAC_RX_CONFIG);
20 tx |= XGMAC_CORE_INIT_TX;
21 rx |= XGMAC_CORE_INIT_RX;
24 rx |= XGMAC_CONFIG_GPSLCE;
25 rx |= XGMAC_JUMBO_LEN << XGMAC_CONFIG_GPSL_SHIFT;
26 rx |= XGMAC_CONFIG_WD;
27 } else if (mtu > 2000) {
28 rx |= XGMAC_CONFIG_JE;
29 } else if (mtu > 1500) {
30 rx |= XGMAC_CONFIG_S2KP;
34 tx |= XGMAC_CONFIG_TE;
35 tx &= ~hw->link.speed_mask;
39 tx |= hw->link.xgmii.speed10000;
42 tx |= hw->link.speed2500;
46 tx |= hw->link.speed1000;
51 writel(tx, ioaddr + XGMAC_TX_CONFIG);
52 writel(rx, ioaddr + XGMAC_RX_CONFIG);
53 writel(XGMAC_INT_DEFAULT_EN, ioaddr + XGMAC_INT_EN);
56 static void dwxgmac2_set_mac(void __iomem *ioaddr, bool enable)
58 u32 tx = readl(ioaddr + XGMAC_TX_CONFIG);
59 u32 rx = readl(ioaddr + XGMAC_RX_CONFIG);
62 tx |= XGMAC_CONFIG_TE;
63 rx |= XGMAC_CONFIG_RE;
65 tx &= ~XGMAC_CONFIG_TE;
66 rx &= ~XGMAC_CONFIG_RE;
69 writel(tx, ioaddr + XGMAC_TX_CONFIG);
70 writel(rx, ioaddr + XGMAC_RX_CONFIG);
73 static int dwxgmac2_rx_ipc(struct mac_device_info *hw)
75 void __iomem *ioaddr = hw->pcsr;
78 value = readl(ioaddr + XGMAC_RX_CONFIG);
80 value |= XGMAC_CONFIG_IPC;
82 value &= ~XGMAC_CONFIG_IPC;
83 writel(value, ioaddr + XGMAC_RX_CONFIG);
85 return !!(readl(ioaddr + XGMAC_RX_CONFIG) & XGMAC_CONFIG_IPC);
88 static void dwxgmac2_rx_queue_enable(struct mac_device_info *hw, u8 mode,
91 void __iomem *ioaddr = hw->pcsr;
94 value = readl(ioaddr + XGMAC_RXQ_CTRL0) & ~XGMAC_RXQEN(queue);
95 if (mode == MTL_QUEUE_AVB)
96 value |= 0x1 << XGMAC_RXQEN_SHIFT(queue);
97 else if (mode == MTL_QUEUE_DCB)
98 value |= 0x2 << XGMAC_RXQEN_SHIFT(queue);
99 writel(value, ioaddr + XGMAC_RXQ_CTRL0);
102 static void dwxgmac2_rx_queue_prio(struct mac_device_info *hw, u32 prio,
105 void __iomem *ioaddr = hw->pcsr;
108 reg = (queue < 4) ? XGMAC_RXQ_CTRL2 : XGMAC_RXQ_CTRL3;
110 value = readl(ioaddr + reg);
111 value &= ~XGMAC_PSRQ(queue);
112 value |= (prio << XGMAC_PSRQ_SHIFT(queue)) & XGMAC_PSRQ(queue);
114 writel(value, ioaddr + reg);
117 static void dwxgmac2_prog_mtl_rx_algorithms(struct mac_device_info *hw,
120 void __iomem *ioaddr = hw->pcsr;
123 value = readl(ioaddr + XGMAC_MTL_OPMODE);
127 case MTL_RX_ALGORITHM_SP:
129 case MTL_RX_ALGORITHM_WSP:
136 writel(value, ioaddr + XGMAC_MTL_OPMODE);
139 static void dwxgmac2_prog_mtl_tx_algorithms(struct mac_device_info *hw,
142 void __iomem *ioaddr = hw->pcsr;
145 value = readl(ioaddr + XGMAC_MTL_OPMODE);
146 value &= ~XGMAC_ETSALG;
149 case MTL_TX_ALGORITHM_WRR:
152 case MTL_TX_ALGORITHM_WFQ:
155 case MTL_TX_ALGORITHM_DWRR:
162 writel(value, ioaddr + XGMAC_MTL_OPMODE);
165 static void dwxgmac2_map_mtl_to_dma(struct mac_device_info *hw, u32 queue,
168 void __iomem *ioaddr = hw->pcsr;
171 reg = (queue < 4) ? XGMAC_MTL_RXQ_DMA_MAP0 : XGMAC_MTL_RXQ_DMA_MAP1;
173 value = readl(ioaddr + reg);
174 value &= ~XGMAC_QxMDMACH(queue);
175 value |= (chan << XGMAC_QxMDMACH_SHIFT(queue)) & XGMAC_QxMDMACH(queue);
177 writel(value, ioaddr + reg);
180 static void dwxgmac2_config_cbs(struct mac_device_info *hw,
181 u32 send_slope, u32 idle_slope,
182 u32 high_credit, u32 low_credit, u32 queue)
184 void __iomem *ioaddr = hw->pcsr;
187 writel(send_slope, ioaddr + XGMAC_MTL_TCx_SENDSLOPE(queue));
188 writel(idle_slope, ioaddr + XGMAC_MTL_TCx_QUANTUM_WEIGHT(queue));
189 writel(high_credit, ioaddr + XGMAC_MTL_TCx_HICREDIT(queue));
190 writel(low_credit, ioaddr + XGMAC_MTL_TCx_LOCREDIT(queue));
192 value = readl(ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(queue));
193 value |= XGMAC_CC | XGMAC_CBS;
194 writel(value, ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(queue));
197 static int dwxgmac2_host_irq_status(struct mac_device_info *hw,
198 struct stmmac_extra_stats *x)
200 void __iomem *ioaddr = hw->pcsr;
203 en = readl(ioaddr + XGMAC_INT_EN);
204 stat = readl(ioaddr + XGMAC_INT_STATUS);
208 if (stat & XGMAC_PMTIS) {
209 x->irq_receive_pmt_irq_n++;
210 readl(ioaddr + XGMAC_PMT);
216 static int dwxgmac2_host_mtl_irq_status(struct mac_device_info *hw, u32 chan)
218 void __iomem *ioaddr = hw->pcsr;
222 status = readl(ioaddr + XGMAC_MTL_INT_STATUS);
223 if (status & BIT(chan)) {
224 u32 chan_status = readl(ioaddr + XGMAC_MTL_QINT_STATUS(chan));
226 if (chan_status & XGMAC_RXOVFIS)
227 ret |= CORE_IRQ_MTL_RX_OVERFLOW;
229 writel(~0x0, ioaddr + XGMAC_MTL_QINT_STATUS(chan));
235 static void dwxgmac2_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
236 unsigned int fc, unsigned int pause_time,
239 void __iomem *ioaddr = hw->pcsr;
243 writel(XGMAC_RFE, ioaddr + XGMAC_RX_FLOW_CTRL);
245 for (i = 0; i < tx_cnt; i++) {
246 u32 value = XGMAC_TFE;
249 value |= pause_time << XGMAC_PT_SHIFT;
251 writel(value, ioaddr + XGMAC_Qx_TX_FLOW_CTRL(i));
256 static void dwxgmac2_pmt(struct mac_device_info *hw, unsigned long mode)
258 void __iomem *ioaddr = hw->pcsr;
261 if (mode & WAKE_MAGIC)
262 val |= XGMAC_PWRDWN | XGMAC_MGKPKTEN;
263 if (mode & WAKE_UCAST)
264 val |= XGMAC_PWRDWN | XGMAC_GLBLUCAST | XGMAC_RWKPKTEN;
266 u32 cfg = readl(ioaddr + XGMAC_RX_CONFIG);
267 cfg |= XGMAC_CONFIG_RE;
268 writel(cfg, ioaddr + XGMAC_RX_CONFIG);
271 writel(val, ioaddr + XGMAC_PMT);
274 static void dwxgmac2_set_umac_addr(struct mac_device_info *hw,
275 unsigned char *addr, unsigned int reg_n)
277 void __iomem *ioaddr = hw->pcsr;
280 value = (addr[5] << 8) | addr[4];
281 writel(value | XGMAC_AE, ioaddr + XGMAC_ADDR0_HIGH);
283 value = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0];
284 writel(value, ioaddr + XGMAC_ADDR0_LOW);
287 static void dwxgmac2_get_umac_addr(struct mac_device_info *hw,
288 unsigned char *addr, unsigned int reg_n)
290 void __iomem *ioaddr = hw->pcsr;
291 u32 hi_addr, lo_addr;
293 /* Read the MAC address from the hardware */
294 hi_addr = readl(ioaddr + XGMAC_ADDR0_HIGH);
295 lo_addr = readl(ioaddr + XGMAC_ADDR0_LOW);
297 /* Extract the MAC address from the high and low words */
298 addr[0] = lo_addr & 0xff;
299 addr[1] = (lo_addr >> 8) & 0xff;
300 addr[2] = (lo_addr >> 16) & 0xff;
301 addr[3] = (lo_addr >> 24) & 0xff;
302 addr[4] = hi_addr & 0xff;
303 addr[5] = (hi_addr >> 8) & 0xff;
306 static void dwxgmac2_set_filter(struct mac_device_info *hw,
307 struct net_device *dev)
309 void __iomem *ioaddr = (void __iomem *)dev->base_addr;
310 u32 value = XGMAC_FILTER_RA;
312 if (dev->flags & IFF_PROMISC) {
313 value |= XGMAC_FILTER_PR | XGMAC_FILTER_PCF;
314 } else if ((dev->flags & IFF_ALLMULTI) ||
315 (netdev_mc_count(dev) > HASH_TABLE_SIZE)) {
316 value |= XGMAC_FILTER_PM;
317 writel(~0x0, ioaddr + XGMAC_HASH_TABLE(0));
318 writel(~0x0, ioaddr + XGMAC_HASH_TABLE(1));
321 writel(value, ioaddr + XGMAC_PACKET_FILTER);
324 static void dwxgmac2_set_mac_loopback(void __iomem *ioaddr, bool enable)
326 u32 value = readl(ioaddr + XGMAC_RX_CONFIG);
329 value |= XGMAC_CONFIG_LM;
331 value &= ~XGMAC_CONFIG_LM;
333 writel(value, ioaddr + XGMAC_RX_CONFIG);
336 const struct stmmac_ops dwxgmac210_ops = {
337 .core_init = dwxgmac2_core_init,
338 .set_mac = dwxgmac2_set_mac,
339 .rx_ipc = dwxgmac2_rx_ipc,
340 .rx_queue_enable = dwxgmac2_rx_queue_enable,
341 .rx_queue_prio = dwxgmac2_rx_queue_prio,
342 .tx_queue_prio = NULL,
343 .rx_queue_routing = NULL,
344 .prog_mtl_rx_algorithms = dwxgmac2_prog_mtl_rx_algorithms,
345 .prog_mtl_tx_algorithms = dwxgmac2_prog_mtl_tx_algorithms,
346 .set_mtl_tx_queue_weight = NULL,
347 .map_mtl_to_dma = dwxgmac2_map_mtl_to_dma,
348 .config_cbs = dwxgmac2_config_cbs,
350 .host_irq_status = dwxgmac2_host_irq_status,
351 .host_mtl_irq_status = dwxgmac2_host_mtl_irq_status,
352 .flow_ctrl = dwxgmac2_flow_ctrl,
354 .set_umac_addr = dwxgmac2_set_umac_addr,
355 .get_umac_addr = dwxgmac2_get_umac_addr,
356 .set_eee_mode = NULL,
357 .reset_eee_mode = NULL,
358 .set_eee_timer = NULL,
360 .pcs_ctrl_ane = NULL,
362 .pcs_get_adv_lp = NULL,
364 .set_filter = dwxgmac2_set_filter,
365 .set_mac_loopback = dwxgmac2_set_mac_loopback,
368 int dwxgmac2_setup(struct stmmac_priv *priv)
370 struct mac_device_info *mac = priv->hw;
372 dev_info(priv->device, "\tXGMAC2\n");
374 priv->dev->priv_flags |= IFF_UNICAST_FLT;
375 mac->pcsr = priv->ioaddr;
376 mac->multicast_filter_bins = priv->plat->multicast_filter_bins;
377 mac->unicast_filter_entries = priv->plat->unicast_filter_entries;
378 mac->mcast_bits_log2 = 0;
380 if (mac->multicast_filter_bins)
381 mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
383 mac->link.duplex = 0;
384 mac->link.speed10 = XGMAC_CONFIG_SS_10_MII;
385 mac->link.speed100 = XGMAC_CONFIG_SS_100_MII;
386 mac->link.speed1000 = XGMAC_CONFIG_SS_1000_GMII;
387 mac->link.speed2500 = XGMAC_CONFIG_SS_2500_GMII;
388 mac->link.xgmii.speed2500 = XGMAC_CONFIG_SS_2500;
389 mac->link.xgmii.speed5000 = XGMAC_CONFIG_SS_5000;
390 mac->link.xgmii.speed10000 = XGMAC_CONFIG_SS_10000;
391 mac->link.speed_mask = XGMAC_CONFIG_SS_MASK;
393 mac->mii.addr = XGMAC_MDIO_ADDR;
394 mac->mii.data = XGMAC_MDIO_DATA;
395 mac->mii.addr_shift = 16;
396 mac->mii.addr_mask = GENMASK(20, 16);
397 mac->mii.reg_shift = 0;
398 mac->mii.reg_mask = GENMASK(15, 0);
399 mac->mii.clk_csr_shift = 19;
400 mac->mii.clk_csr_mask = GENMASK(21, 19);