Merge tag '4.3-rc-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6
[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 "stmmac.h"
8 #include "dwxgmac2.h"
9
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.xgmii.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
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
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
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
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
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
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
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
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)
183 {
184         void __iomem *ioaddr = hw->pcsr;
185         u32 value;
186
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));
191
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));
195 }
196
197 static int dwxgmac2_host_irq_status(struct mac_device_info *hw,
198                                     struct stmmac_extra_stats *x)
199 {
200         void __iomem *ioaddr = hw->pcsr;
201         u32 stat, en;
202
203         en = readl(ioaddr + XGMAC_INT_EN);
204         stat = readl(ioaddr + XGMAC_INT_STATUS);
205
206         stat &= en;
207
208         if (stat & XGMAC_PMTIS) {
209                 x->irq_receive_pmt_irq_n++;
210                 readl(ioaddr + XGMAC_PMT);
211         }
212
213         return 0;
214 }
215
216 static int dwxgmac2_host_mtl_irq_status(struct mac_device_info *hw, u32 chan)
217 {
218         void __iomem *ioaddr = hw->pcsr;
219         int ret = 0;
220         u32 status;
221
222         status = readl(ioaddr + XGMAC_MTL_INT_STATUS);
223         if (status & BIT(chan)) {
224                 u32 chan_status = readl(ioaddr + XGMAC_MTL_QINT_STATUS(chan));
225
226                 if (chan_status & XGMAC_RXOVFIS)
227                         ret |= CORE_IRQ_MTL_RX_OVERFLOW;
228
229                 writel(~0x0, ioaddr + XGMAC_MTL_QINT_STATUS(chan));
230         }
231
232         return ret;
233 }
234
235 static void dwxgmac2_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
236                                unsigned int fc, unsigned int pause_time,
237                                u32 tx_cnt)
238 {
239         void __iomem *ioaddr = hw->pcsr;
240         u32 i;
241
242         if (fc & FLOW_RX)
243                 writel(XGMAC_RFE, ioaddr + XGMAC_RX_FLOW_CTRL);
244         if (fc & FLOW_TX) {
245                 for (i = 0; i < tx_cnt; i++) {
246                         u32 value = XGMAC_TFE;
247
248                         if (duplex)
249                                 value |= pause_time << XGMAC_PT_SHIFT;
250
251                         writel(value, ioaddr + XGMAC_Qx_TX_FLOW_CTRL(i));
252                 }
253         }
254 }
255
256 static void dwxgmac2_pmt(struct mac_device_info *hw, unsigned long mode)
257 {
258         void __iomem *ioaddr = hw->pcsr;
259         u32 val = 0x0;
260
261         if (mode & WAKE_MAGIC)
262                 val |= XGMAC_PWRDWN | XGMAC_MGKPKTEN;
263         if (mode & WAKE_UCAST)
264                 val |= XGMAC_PWRDWN | XGMAC_GLBLUCAST | XGMAC_RWKPKTEN;
265         if (val) {
266                 u32 cfg = readl(ioaddr + XGMAC_RX_CONFIG);
267                 cfg |= XGMAC_CONFIG_RE;
268                 writel(cfg, ioaddr + XGMAC_RX_CONFIG);
269         }
270
271         writel(val, ioaddr + XGMAC_PMT);
272 }
273
274 static void dwxgmac2_set_umac_addr(struct mac_device_info *hw,
275                                    unsigned char *addr, unsigned int reg_n)
276 {
277         void __iomem *ioaddr = hw->pcsr;
278         u32 value;
279
280         value = (addr[5] << 8) | addr[4];
281         writel(value | XGMAC_AE, ioaddr + XGMAC_ADDR0_HIGH);
282
283         value = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0];
284         writel(value, ioaddr + XGMAC_ADDR0_LOW);
285 }
286
287 static void dwxgmac2_get_umac_addr(struct mac_device_info *hw,
288                                    unsigned char *addr, unsigned int reg_n)
289 {
290         void __iomem *ioaddr = hw->pcsr;
291         u32 hi_addr, lo_addr;
292
293         /* Read the MAC address from the hardware */
294         hi_addr = readl(ioaddr + XGMAC_ADDR0_HIGH);
295         lo_addr = readl(ioaddr + XGMAC_ADDR0_LOW);
296
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;
304 }
305
306 static void dwxgmac2_set_filter(struct mac_device_info *hw,
307                                 struct net_device *dev)
308 {
309         void __iomem *ioaddr = (void __iomem *)dev->base_addr;
310         u32 value = XGMAC_FILTER_RA;
311
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));
319         }
320
321         writel(value, ioaddr + XGMAC_PACKET_FILTER);
322 }
323
324 static void dwxgmac2_set_mac_loopback(void __iomem *ioaddr, bool enable)
325 {
326         u32 value = readl(ioaddr + XGMAC_RX_CONFIG);
327
328         if (enable)
329                 value |= XGMAC_CONFIG_LM;
330         else
331                 value &= ~XGMAC_CONFIG_LM;
332
333         writel(value, ioaddr + XGMAC_RX_CONFIG);
334 }
335
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,
349         .dump_regs = NULL,
350         .host_irq_status = dwxgmac2_host_irq_status,
351         .host_mtl_irq_status = dwxgmac2_host_mtl_irq_status,
352         .flow_ctrl = dwxgmac2_flow_ctrl,
353         .pmt = dwxgmac2_pmt,
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,
359         .set_eee_pls = NULL,
360         .pcs_ctrl_ane = NULL,
361         .pcs_rane = NULL,
362         .pcs_get_adv_lp = NULL,
363         .debug = NULL,
364         .set_filter = dwxgmac2_set_filter,
365         .set_mac_loopback = dwxgmac2_set_mac_loopback,
366 };
367
368 int dwxgmac2_setup(struct stmmac_priv *priv)
369 {
370         struct mac_device_info *mac = priv->hw;
371
372         dev_info(priv->device, "\tXGMAC2\n");
373
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;
379
380         if (mac->multicast_filter_bins)
381                 mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
382
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;
392
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);
401
402         return 0;
403 }