Merge tag 'tag-chrome-platform-fixes-for-v5.3-rc6' of git://git.kernel.org/pub/scm...
[sfrench/cifs-2.6.git] / drivers / net / ethernet / stmicro / stmmac / dwxgmac2_core.c
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 <linux/bitrev.h>
8 #include <linux/crc32.h>
9 #include "stmmac.h"
10 #include "dwxgmac2.h"
11
12 static void dwxgmac2_core_init(struct mac_device_info *hw,
13                                struct net_device *dev)
14 {
15         void __iomem *ioaddr = hw->pcsr;
16         int mtu = dev->mtu;
17         u32 tx, rx;
18
19         tx = readl(ioaddr + XGMAC_TX_CONFIG);
20         rx = readl(ioaddr + XGMAC_RX_CONFIG);
21
22         tx |= XGMAC_CORE_INIT_TX;
23         rx |= XGMAC_CORE_INIT_RX;
24
25         if (mtu >= 9000) {
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;
33         }
34
35         if (hw->ps) {
36                 tx |= XGMAC_CONFIG_TE;
37                 tx &= ~hw->link.speed_mask;
38
39                 switch (hw->ps) {
40                 case SPEED_10000:
41                         tx |= hw->link.xgmii.speed10000;
42                         break;
43                 case SPEED_2500:
44                         tx |= hw->link.speed2500;
45                         break;
46                 case SPEED_1000:
47                 default:
48                         tx |= hw->link.speed1000;
49                         break;
50                 }
51         }
52
53         writel(tx, ioaddr + XGMAC_TX_CONFIG);
54         writel(rx, ioaddr + XGMAC_RX_CONFIG);
55         writel(XGMAC_INT_DEFAULT_EN, ioaddr + XGMAC_INT_EN);
56 }
57
58 static void dwxgmac2_set_mac(void __iomem *ioaddr, bool enable)
59 {
60         u32 tx = readl(ioaddr + XGMAC_TX_CONFIG);
61         u32 rx = readl(ioaddr + XGMAC_RX_CONFIG);
62
63         if (enable) {
64                 tx |= XGMAC_CONFIG_TE;
65                 rx |= XGMAC_CONFIG_RE;
66         } else {
67                 tx &= ~XGMAC_CONFIG_TE;
68                 rx &= ~XGMAC_CONFIG_RE;
69         }
70
71         writel(tx, ioaddr + XGMAC_TX_CONFIG);
72         writel(rx, ioaddr + XGMAC_RX_CONFIG);
73 }
74
75 static int dwxgmac2_rx_ipc(struct mac_device_info *hw)
76 {
77         void __iomem *ioaddr = hw->pcsr;
78         u32 value;
79
80         value = readl(ioaddr + XGMAC_RX_CONFIG);
81         if (hw->rx_csum)
82                 value |= XGMAC_CONFIG_IPC;
83         else
84                 value &= ~XGMAC_CONFIG_IPC;
85         writel(value, ioaddr + XGMAC_RX_CONFIG);
86
87         return !!(readl(ioaddr + XGMAC_RX_CONFIG) & XGMAC_CONFIG_IPC);
88 }
89
90 static void dwxgmac2_rx_queue_enable(struct mac_device_info *hw, u8 mode,
91                                      u32 queue)
92 {
93         void __iomem *ioaddr = hw->pcsr;
94         u32 value;
95
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);
102 }
103
104 static void dwxgmac2_rx_queue_prio(struct mac_device_info *hw, u32 prio,
105                                    u32 queue)
106 {
107         void __iomem *ioaddr = hw->pcsr;
108         u32 value, reg;
109
110         reg = (queue < 4) ? XGMAC_RXQ_CTRL2 : XGMAC_RXQ_CTRL3;
111         if (queue >= 4)
112                 queue -= 4;
113
114         value = readl(ioaddr + reg);
115         value &= ~XGMAC_PSRQ(queue);
116         value |= (prio << XGMAC_PSRQ_SHIFT(queue)) & XGMAC_PSRQ(queue);
117
118         writel(value, ioaddr + reg);
119 }
120
121 static void dwxgmac2_prog_mtl_rx_algorithms(struct mac_device_info *hw,
122                                             u32 rx_alg)
123 {
124         void __iomem *ioaddr = hw->pcsr;
125         u32 value;
126
127         value = readl(ioaddr + XGMAC_MTL_OPMODE);
128         value &= ~XGMAC_RAA;
129
130         switch (rx_alg) {
131         case MTL_RX_ALGORITHM_SP:
132                 break;
133         case MTL_RX_ALGORITHM_WSP:
134                 value |= XGMAC_RAA;
135                 break;
136         default:
137                 break;
138         }
139
140         writel(value, ioaddr + XGMAC_MTL_OPMODE);
141 }
142
143 static void dwxgmac2_prog_mtl_tx_algorithms(struct mac_device_info *hw,
144                                             u32 tx_alg)
145 {
146         void __iomem *ioaddr = hw->pcsr;
147         u32 value;
148
149         value = readl(ioaddr + XGMAC_MTL_OPMODE);
150         value &= ~XGMAC_ETSALG;
151
152         switch (tx_alg) {
153         case MTL_TX_ALGORITHM_WRR:
154                 value |= XGMAC_WRR;
155                 break;
156         case MTL_TX_ALGORITHM_WFQ:
157                 value |= XGMAC_WFQ;
158                 break;
159         case MTL_TX_ALGORITHM_DWRR:
160                 value |= XGMAC_DWRR;
161                 break;
162         default:
163                 break;
164         }
165
166         writel(value, ioaddr + XGMAC_MTL_OPMODE);
167 }
168
169 static void dwxgmac2_map_mtl_to_dma(struct mac_device_info *hw, u32 queue,
170                                     u32 chan)
171 {
172         void __iomem *ioaddr = hw->pcsr;
173         u32 value, reg;
174
175         reg = (queue < 4) ? XGMAC_MTL_RXQ_DMA_MAP0 : XGMAC_MTL_RXQ_DMA_MAP1;
176         if (queue >= 4)
177                 queue -= 4;
178
179         value = readl(ioaddr + reg);
180         value &= ~XGMAC_QxMDMACH(queue);
181         value |= (chan << XGMAC_QxMDMACH_SHIFT(queue)) & XGMAC_QxMDMACH(queue);
182
183         writel(value, ioaddr + reg);
184 }
185
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)
189 {
190         void __iomem *ioaddr = hw->pcsr;
191         u32 value;
192
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));
197
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));
201 }
202
203 static int dwxgmac2_host_irq_status(struct mac_device_info *hw,
204                                     struct stmmac_extra_stats *x)
205 {
206         void __iomem *ioaddr = hw->pcsr;
207         u32 stat, en;
208
209         en = readl(ioaddr + XGMAC_INT_EN);
210         stat = readl(ioaddr + XGMAC_INT_STATUS);
211
212         stat &= en;
213
214         if (stat & XGMAC_PMTIS) {
215                 x->irq_receive_pmt_irq_n++;
216                 readl(ioaddr + XGMAC_PMT);
217         }
218
219         return 0;
220 }
221
222 static int dwxgmac2_host_mtl_irq_status(struct mac_device_info *hw, u32 chan)
223 {
224         void __iomem *ioaddr = hw->pcsr;
225         int ret = 0;
226         u32 status;
227
228         status = readl(ioaddr + XGMAC_MTL_INT_STATUS);
229         if (status & BIT(chan)) {
230                 u32 chan_status = readl(ioaddr + XGMAC_MTL_QINT_STATUS(chan));
231
232                 if (chan_status & XGMAC_RXOVFIS)
233                         ret |= CORE_IRQ_MTL_RX_OVERFLOW;
234
235                 writel(~0x0, ioaddr + XGMAC_MTL_QINT_STATUS(chan));
236         }
237
238         return ret;
239 }
240
241 static void dwxgmac2_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
242                                unsigned int fc, unsigned int pause_time,
243                                u32 tx_cnt)
244 {
245         void __iomem *ioaddr = hw->pcsr;
246         u32 i;
247
248         if (fc & FLOW_RX)
249                 writel(XGMAC_RFE, ioaddr + XGMAC_RX_FLOW_CTRL);
250         if (fc & FLOW_TX) {
251                 for (i = 0; i < tx_cnt; i++) {
252                         u32 value = XGMAC_TFE;
253
254                         if (duplex)
255                                 value |= pause_time << XGMAC_PT_SHIFT;
256
257                         writel(value, ioaddr + XGMAC_Qx_TX_FLOW_CTRL(i));
258                 }
259         }
260 }
261
262 static void dwxgmac2_pmt(struct mac_device_info *hw, unsigned long mode)
263 {
264         void __iomem *ioaddr = hw->pcsr;
265         u32 val = 0x0;
266
267         if (mode & WAKE_MAGIC)
268                 val |= XGMAC_PWRDWN | XGMAC_MGKPKTEN;
269         if (mode & WAKE_UCAST)
270                 val |= XGMAC_PWRDWN | XGMAC_GLBLUCAST | XGMAC_RWKPKTEN;
271         if (val) {
272                 u32 cfg = readl(ioaddr + XGMAC_RX_CONFIG);
273                 cfg |= XGMAC_CONFIG_RE;
274                 writel(cfg, ioaddr + XGMAC_RX_CONFIG);
275         }
276
277         writel(val, ioaddr + XGMAC_PMT);
278 }
279
280 static void dwxgmac2_set_umac_addr(struct mac_device_info *hw,
281                                    unsigned char *addr, unsigned int reg_n)
282 {
283         void __iomem *ioaddr = hw->pcsr;
284         u32 value;
285
286         value = (addr[5] << 8) | addr[4];
287         writel(value | XGMAC_AE, ioaddr + XGMAC_ADDRx_HIGH(reg_n));
288
289         value = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0];
290         writel(value, ioaddr + XGMAC_ADDRx_LOW(reg_n));
291 }
292
293 static void dwxgmac2_get_umac_addr(struct mac_device_info *hw,
294                                    unsigned char *addr, unsigned int reg_n)
295 {
296         void __iomem *ioaddr = hw->pcsr;
297         u32 hi_addr, lo_addr;
298
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));
302
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;
310 }
311
312 static void dwxgmac2_set_mchash(void __iomem *ioaddr, u32 *mcfilterbits,
313                                 int mcbitslog2)
314 {
315         int numhashregs, regs;
316
317         switch (mcbitslog2) {
318         case 6:
319                 numhashregs = 2;
320                 break;
321         case 7:
322                 numhashregs = 4;
323                 break;
324         case 8:
325                 numhashregs = 8;
326                 break;
327         default:
328                 return;
329         }
330
331         for (regs = 0; regs < numhashregs; regs++)
332                 writel(mcfilterbits[regs], ioaddr + XGMAC_HASH_TABLE(regs));
333 }
334
335 static void dwxgmac2_set_filter(struct mac_device_info *hw,
336                                 struct net_device *dev)
337 {
338         void __iomem *ioaddr = (void __iomem *)dev->base_addr;
339         u32 value = readl(ioaddr + XGMAC_PACKET_FILTER);
340         int mcbitslog2 = hw->mcast_bits_log2;
341         u32 mc_filter[8];
342         int i;
343
344         value &= ~(XGMAC_FILTER_PR | XGMAC_FILTER_HMC | XGMAC_FILTER_PM);
345         value |= XGMAC_FILTER_HPF;
346
347         memset(mc_filter, 0, sizeof(mc_filter));
348
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;
355
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;
360
361                 value |= XGMAC_FILTER_HMC;
362
363                 netdev_for_each_mc_addr(ha, dev) {
364                         int nr = (bitrev32(~crc32_le(~0, ha->addr, 6)) >>
365                                         (32 - mcbitslog2));
366                         mc_filter[nr >> 5] |= (1 << (nr & 0x1F));
367                 }
368         }
369
370         dwxgmac2_set_mchash(ioaddr, mc_filter, mcbitslog2);
371
372         /* Handle multiple unicast addresses */
373         if (netdev_uc_count(dev) > XGMAC_ADDR_MAX) {
374                 value |= XGMAC_FILTER_PR;
375         } else {
376                 struct netdev_hw_addr *ha;
377                 int reg = 1;
378
379                 netdev_for_each_uc_addr(ha, dev) {
380                         dwxgmac2_set_umac_addr(hw, ha->addr, reg);
381                         reg++;
382                 }
383
384                 for ( ; reg < XGMAC_ADDR_MAX; reg++) {
385                         writel(0, ioaddr + XGMAC_ADDRx_HIGH(reg));
386                         writel(0, ioaddr + XGMAC_ADDRx_LOW(reg));
387                 }
388         }
389
390         writel(value, ioaddr + XGMAC_PACKET_FILTER);
391 }
392
393 static void dwxgmac2_set_mac_loopback(void __iomem *ioaddr, bool enable)
394 {
395         u32 value = readl(ioaddr + XGMAC_RX_CONFIG);
396
397         if (enable)
398                 value |= XGMAC_CONFIG_LM;
399         else
400                 value &= ~XGMAC_CONFIG_LM;
401
402         writel(value, ioaddr + XGMAC_RX_CONFIG);
403 }
404
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,
418         .dump_regs = NULL,
419         .host_irq_status = dwxgmac2_host_irq_status,
420         .host_mtl_irq_status = dwxgmac2_host_mtl_irq_status,
421         .flow_ctrl = dwxgmac2_flow_ctrl,
422         .pmt = dwxgmac2_pmt,
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,
428         .set_eee_pls = NULL,
429         .pcs_ctrl_ane = NULL,
430         .pcs_rane = NULL,
431         .pcs_get_adv_lp = NULL,
432         .debug = NULL,
433         .set_filter = dwxgmac2_set_filter,
434         .set_mac_loopback = dwxgmac2_set_mac_loopback,
435 };
436
437 int dwxgmac2_setup(struct stmmac_priv *priv)
438 {
439         struct mac_device_info *mac = priv->hw;
440
441         dev_info(priv->device, "\tXGMAC2\n");
442
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;
448
449         if (mac->multicast_filter_bins)
450                 mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
451
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;
461
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);
470
471         return 0;
472 }