1 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
2 /*
3 * Copyright (c) 2018 Synopsys, Inc. and/or its affiliates.
4 * stmmac XGMAC support.
5 */
6
7 #include "stmmac.h"
8 #include "dwxgmac2.h"
9
dwxgmac2_core_init(struct mac_device_info * hw,struct net_device * dev)10 static void dwxgmac2_core_init(struct mac_device_info *hw,
11 struct net_device *dev)
12 {
13 void __iomem *ioaddr = hw->pcsr;
14 int mtu = dev->mtu;
15 u32 tx, rx;
16
17 tx = readl(ioaddr + XGMAC_TX_CONFIG);
18 rx = readl(ioaddr + XGMAC_RX_CONFIG);
19
20 tx |= XGMAC_CORE_INIT_TX;
21 rx |= XGMAC_CORE_INIT_RX;
22
23 if (mtu >= 9000) {
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;
31 }
32
33 if (hw->ps) {
34 tx |= XGMAC_CONFIG_TE;
35 tx &= ~hw->link.speed_mask;
36
37 switch (hw->ps) {
38 case SPEED_10000:
39 tx |= hw->link.speed10000;
40 break;
41 case SPEED_2500:
42 tx |= hw->link.speed2500;
43 break;
44 case SPEED_1000:
45 default:
46 tx |= hw->link.speed1000;
47 break;
48 }
49 }
50
51 writel(tx, ioaddr + XGMAC_TX_CONFIG);
52 writel(rx, ioaddr + XGMAC_RX_CONFIG);
53 writel(XGMAC_INT_DEFAULT_EN, ioaddr + XGMAC_INT_EN);
54 }
55
dwxgmac2_set_mac(void __iomem * ioaddr,bool enable)56 static void dwxgmac2_set_mac(void __iomem *ioaddr, bool enable)
57 {
58 u32 tx = readl(ioaddr + XGMAC_TX_CONFIG);
59 u32 rx = readl(ioaddr + XGMAC_RX_CONFIG);
60
61 if (enable) {
62 tx |= XGMAC_CONFIG_TE;
63 rx |= XGMAC_CONFIG_RE;
64 } else {
65 tx &= ~XGMAC_CONFIG_TE;
66 rx &= ~XGMAC_CONFIG_RE;
67 }
68
69 writel(tx, ioaddr + XGMAC_TX_CONFIG);
70 writel(rx, ioaddr + XGMAC_RX_CONFIG);
71 }
72
dwxgmac2_rx_ipc(struct mac_device_info * hw)73 static int dwxgmac2_rx_ipc(struct mac_device_info *hw)
74 {
75 void __iomem *ioaddr = hw->pcsr;
76 u32 value;
77
78 value = readl(ioaddr + XGMAC_RX_CONFIG);
79 if (hw->rx_csum)
80 value |= XGMAC_CONFIG_IPC;
81 else
82 value &= ~XGMAC_CONFIG_IPC;
83 writel(value, ioaddr + XGMAC_RX_CONFIG);
84
85 return !!(readl(ioaddr + XGMAC_RX_CONFIG) & XGMAC_CONFIG_IPC);
86 }
87
dwxgmac2_rx_queue_enable(struct mac_device_info * hw,u8 mode,u32 queue)88 static void dwxgmac2_rx_queue_enable(struct mac_device_info *hw, u8 mode,
89 u32 queue)
90 {
91 void __iomem *ioaddr = hw->pcsr;
92 u32 value;
93
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);
100 }
101
dwxgmac2_rx_queue_prio(struct mac_device_info * hw,u32 prio,u32 queue)102 static void dwxgmac2_rx_queue_prio(struct mac_device_info *hw, u32 prio,
103 u32 queue)
104 {
105 void __iomem *ioaddr = hw->pcsr;
106 u32 value, reg;
107
108 reg = (queue < 4) ? XGMAC_RXQ_CTRL2 : XGMAC_RXQ_CTRL3;
109
110 value = readl(ioaddr + reg);
111 value &= ~XGMAC_PSRQ(queue);
112 value |= (prio << XGMAC_PSRQ_SHIFT(queue)) & XGMAC_PSRQ(queue);
113
114 writel(value, ioaddr + reg);
115 }
116
dwxgmac2_prog_mtl_rx_algorithms(struct mac_device_info * hw,u32 rx_alg)117 static void dwxgmac2_prog_mtl_rx_algorithms(struct mac_device_info *hw,
118 u32 rx_alg)
119 {
120 void __iomem *ioaddr = hw->pcsr;
121 u32 value;
122
123 value = readl(ioaddr + XGMAC_MTL_OPMODE);
124 value &= ~XGMAC_RAA;
125
126 switch (rx_alg) {
127 case MTL_RX_ALGORITHM_SP:
128 break;
129 case MTL_RX_ALGORITHM_WSP:
130 value |= XGMAC_RAA;
131 break;
132 default:
133 break;
134 }
135
136 writel(value, ioaddr + XGMAC_MTL_OPMODE);
137 }
138
dwxgmac2_prog_mtl_tx_algorithms(struct mac_device_info * hw,u32 tx_alg)139 static void dwxgmac2_prog_mtl_tx_algorithms(struct mac_device_info *hw,
140 u32 tx_alg)
141 {
142 void __iomem *ioaddr = hw->pcsr;
143 u32 value;
144
145 value = readl(ioaddr + XGMAC_MTL_OPMODE);
146 value &= ~XGMAC_ETSALG;
147
148 switch (tx_alg) {
149 case MTL_TX_ALGORITHM_WRR:
150 value |= XGMAC_WRR;
151 break;
152 case MTL_TX_ALGORITHM_WFQ:
153 value |= XGMAC_WFQ;
154 break;
155 case MTL_TX_ALGORITHM_DWRR:
156 value |= XGMAC_DWRR;
157 break;
158 default:
159 break;
160 }
161
162 writel(value, ioaddr + XGMAC_MTL_OPMODE);
163 }
164
dwxgmac2_map_mtl_to_dma(struct mac_device_info * hw,u32 queue,u32 chan)165 static void dwxgmac2_map_mtl_to_dma(struct mac_device_info *hw, u32 queue,
166 u32 chan)
167 {
168 void __iomem *ioaddr = hw->pcsr;
169 u32 value, reg;
170
171 reg = (queue < 4) ? XGMAC_MTL_RXQ_DMA_MAP0 : XGMAC_MTL_RXQ_DMA_MAP1;
172
173 value = readl(ioaddr + reg);
174 value &= ~XGMAC_QxMDMACH(queue);
175 value |= (chan << XGMAC_QxMDMACH_SHIFT(queue)) & XGMAC_QxMDMACH(queue);
176
177 writel(value, ioaddr + reg);
178 }
179
dwxgmac2_host_irq_status(struct mac_device_info * hw,struct stmmac_extra_stats * x)180 static int dwxgmac2_host_irq_status(struct mac_device_info *hw,
181 struct stmmac_extra_stats *x)
182 {
183 void __iomem *ioaddr = hw->pcsr;
184 u32 stat, en;
185
186 en = readl(ioaddr + XGMAC_INT_EN);
187 stat = readl(ioaddr + XGMAC_INT_STATUS);
188
189 stat &= en;
190
191 if (stat & XGMAC_PMTIS) {
192 x->irq_receive_pmt_irq_n++;
193 readl(ioaddr + XGMAC_PMT);
194 }
195
196 return 0;
197 }
198
dwxgmac2_host_mtl_irq_status(struct mac_device_info * hw,u32 chan)199 static int dwxgmac2_host_mtl_irq_status(struct mac_device_info *hw, u32 chan)
200 {
201 void __iomem *ioaddr = hw->pcsr;
202 int ret = 0;
203 u32 status;
204
205 status = readl(ioaddr + XGMAC_MTL_INT_STATUS);
206 if (status & BIT(chan)) {
207 u32 chan_status = readl(ioaddr + XGMAC_MTL_QINT_STATUS(chan));
208
209 if (chan_status & XGMAC_RXOVFIS)
210 ret |= CORE_IRQ_MTL_RX_OVERFLOW;
211
212 writel(~0x0, ioaddr + XGMAC_MTL_QINT_STATUS(chan));
213 }
214
215 return ret;
216 }
217
dwxgmac2_flow_ctrl(struct mac_device_info * hw,unsigned int duplex,unsigned int fc,unsigned int pause_time,u32 tx_cnt)218 static void dwxgmac2_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
219 unsigned int fc, unsigned int pause_time,
220 u32 tx_cnt)
221 {
222 void __iomem *ioaddr = hw->pcsr;
223 u32 i;
224
225 if (fc & FLOW_RX)
226 writel(XGMAC_RFE, ioaddr + XGMAC_RX_FLOW_CTRL);
227 if (fc & FLOW_TX) {
228 for (i = 0; i < tx_cnt; i++) {
229 u32 value = XGMAC_TFE;
230
231 if (duplex)
232 value |= pause_time << XGMAC_PT_SHIFT;
233
234 writel(value, ioaddr + XGMAC_Qx_TX_FLOW_CTRL(i));
235 }
236 }
237 }
238
dwxgmac2_pmt(struct mac_device_info * hw,unsigned long mode)239 static void dwxgmac2_pmt(struct mac_device_info *hw, unsigned long mode)
240 {
241 void __iomem *ioaddr = hw->pcsr;
242 u32 val = 0x0;
243
244 if (mode & WAKE_MAGIC)
245 val |= XGMAC_PWRDWN | XGMAC_MGKPKTEN;
246 if (mode & WAKE_UCAST)
247 val |= XGMAC_PWRDWN | XGMAC_GLBLUCAST | XGMAC_RWKPKTEN;
248 if (val) {
249 u32 cfg = readl(ioaddr + XGMAC_RX_CONFIG);
250 cfg |= XGMAC_CONFIG_RE;
251 writel(cfg, ioaddr + XGMAC_RX_CONFIG);
252 }
253
254 writel(val, ioaddr + XGMAC_PMT);
255 }
256
dwxgmac2_set_umac_addr(struct mac_device_info * hw,unsigned char * addr,unsigned int reg_n)257 static void dwxgmac2_set_umac_addr(struct mac_device_info *hw,
258 unsigned char *addr, unsigned int reg_n)
259 {
260 void __iomem *ioaddr = hw->pcsr;
261 u32 value;
262
263 value = (addr[5] << 8) | addr[4];
264 writel(value | XGMAC_AE, ioaddr + XGMAC_ADDR0_HIGH);
265
266 value = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0];
267 writel(value, ioaddr + XGMAC_ADDR0_LOW);
268 }
269
dwxgmac2_get_umac_addr(struct mac_device_info * hw,unsigned char * addr,unsigned int reg_n)270 static void dwxgmac2_get_umac_addr(struct mac_device_info *hw,
271 unsigned char *addr, unsigned int reg_n)
272 {
273 void __iomem *ioaddr = hw->pcsr;
274 u32 hi_addr, lo_addr;
275
276 /* Read the MAC address from the hardware */
277 hi_addr = readl(ioaddr + XGMAC_ADDR0_HIGH);
278 lo_addr = readl(ioaddr + XGMAC_ADDR0_LOW);
279
280 /* Extract the MAC address from the high and low words */
281 addr[0] = lo_addr & 0xff;
282 addr[1] = (lo_addr >> 8) & 0xff;
283 addr[2] = (lo_addr >> 16) & 0xff;
284 addr[3] = (lo_addr >> 24) & 0xff;
285 addr[4] = hi_addr & 0xff;
286 addr[5] = (hi_addr >> 8) & 0xff;
287 }
288
dwxgmac2_set_filter(struct mac_device_info * hw,struct net_device * dev)289 static void dwxgmac2_set_filter(struct mac_device_info *hw,
290 struct net_device *dev)
291 {
292 void __iomem *ioaddr = (void __iomem *)dev->base_addr;
293 u32 value = XGMAC_FILTER_RA;
294
295 if (dev->flags & IFF_PROMISC) {
296 value |= XGMAC_FILTER_PR;
297 } else if ((dev->flags & IFF_ALLMULTI) ||
298 (netdev_mc_count(dev) > HASH_TABLE_SIZE)) {
299 value |= XGMAC_FILTER_PM;
300 writel(~0x0, ioaddr + XGMAC_HASH_TABLE(0));
301 writel(~0x0, ioaddr + XGMAC_HASH_TABLE(1));
302 }
303
304 writel(value, ioaddr + XGMAC_PACKET_FILTER);
305 }
306
307 const struct stmmac_ops dwxgmac210_ops = {
308 .core_init = dwxgmac2_core_init,
309 .set_mac = dwxgmac2_set_mac,
310 .rx_ipc = dwxgmac2_rx_ipc,
311 .rx_queue_enable = dwxgmac2_rx_queue_enable,
312 .rx_queue_prio = dwxgmac2_rx_queue_prio,
313 .tx_queue_prio = NULL,
314 .rx_queue_routing = NULL,
315 .prog_mtl_rx_algorithms = dwxgmac2_prog_mtl_rx_algorithms,
316 .prog_mtl_tx_algorithms = dwxgmac2_prog_mtl_tx_algorithms,
317 .set_mtl_tx_queue_weight = NULL,
318 .map_mtl_to_dma = dwxgmac2_map_mtl_to_dma,
319 .config_cbs = NULL,
320 .dump_regs = NULL,
321 .host_irq_status = dwxgmac2_host_irq_status,
322 .host_mtl_irq_status = dwxgmac2_host_mtl_irq_status,
323 .flow_ctrl = dwxgmac2_flow_ctrl,
324 .pmt = dwxgmac2_pmt,
325 .set_umac_addr = dwxgmac2_set_umac_addr,
326 .get_umac_addr = dwxgmac2_get_umac_addr,
327 .set_eee_mode = NULL,
328 .reset_eee_mode = NULL,
329 .set_eee_timer = NULL,
330 .set_eee_pls = NULL,
331 .pcs_ctrl_ane = NULL,
332 .pcs_rane = NULL,
333 .pcs_get_adv_lp = NULL,
334 .debug = NULL,
335 .set_filter = dwxgmac2_set_filter,
336 };
337
dwxgmac2_setup(struct stmmac_priv * priv)338 int dwxgmac2_setup(struct stmmac_priv *priv)
339 {
340 struct mac_device_info *mac = priv->hw;
341
342 dev_info(priv->device, "\tXGMAC2\n");
343
344 priv->dev->priv_flags |= IFF_UNICAST_FLT;
345 mac->pcsr = priv->ioaddr;
346 mac->multicast_filter_bins = priv->plat->multicast_filter_bins;
347 mac->unicast_filter_entries = priv->plat->unicast_filter_entries;
348 mac->mcast_bits_log2 = 0;
349
350 if (mac->multicast_filter_bins)
351 mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
352
353 mac->link.duplex = 0;
354 mac->link.speed10 = 0;
355 mac->link.speed100 = 0;
356 mac->link.speed1000 = XGMAC_CONFIG_SS_1000;
357 mac->link.speed2500 = XGMAC_CONFIG_SS_2500;
358 mac->link.speed10000 = XGMAC_CONFIG_SS_10000;
359 mac->link.speed_mask = XGMAC_CONFIG_SS_MASK;
360
361 mac->mii.addr = XGMAC_MDIO_ADDR;
362 mac->mii.data = XGMAC_MDIO_DATA;
363 mac->mii.addr_shift = 16;
364 mac->mii.addr_mask = GENMASK(20, 16);
365 mac->mii.reg_shift = 0;
366 mac->mii.reg_mask = GENMASK(15, 0);
367 mac->mii.clk_csr_shift = 19;
368 mac->mii.clk_csr_mask = GENMASK(21, 19);
369
370 return 0;
371 }
372