Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec...
[linux-2.6-block.git] / drivers / net / ethernet / stmicro / stmmac / dwmac4_core.c
CommitLineData
477286b5
AT
1/*
2 * This is the driver for the GMAC on-chip Ethernet controller for ST SoCs.
3 * DWC Ether MAC version 4.00 has been used for developing this code.
4 *
5 * This only implements the mac core functions for this chip.
6 *
7 * Copyright (C) 2015 STMicroelectronics Ltd
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms and conditions of the GNU General Public License,
11 * version 2, as published by the Free Software Foundation.
12 *
13 * Author: Alexandre Torgue <alexandre.torgue@st.com>
14 */
15
16#include <linux/crc32.h>
17#include <linux/slab.h>
18#include <linux/ethtool.h>
19#include <linux/io.h>
70523e63 20#include "stmmac_pcs.h"
477286b5
AT
21#include "dwmac4.h"
22
23static void dwmac4_core_init(struct mac_device_info *hw, int mtu)
24{
25 void __iomem *ioaddr = hw->pcsr;
26 u32 value = readl(ioaddr + GMAC_CONFIG);
27
28 value |= GMAC_CORE_INIT;
29
30 if (mtu > 1500)
31 value |= GMAC_CONFIG_2K;
32 if (mtu > 2000)
33 value |= GMAC_CONFIG_JE;
34
02e57b9d
GC
35 if (hw->ps) {
36 value |= GMAC_CONFIG_TE;
37
38 if (hw->ps == SPEED_1000) {
39 value &= ~GMAC_CONFIG_PS;
40 } else {
41 value |= GMAC_CONFIG_PS;
42
43 if (hw->ps == SPEED_10)
44 value &= ~GMAC_CONFIG_FES;
45 else
46 value |= GMAC_CONFIG_FES;
47 }
48 }
49
477286b5
AT
50 writel(value, ioaddr + GMAC_CONFIG);
51
52 /* Mask GMAC interrupts */
3fe5cadb
GC
53 value = GMAC_INT_DEFAULT_MASK;
54 if (hw->pmt)
55 value |= GMAC_INT_PMT_EN;
56 if (hw->pcs)
57 value |= GMAC_PCS_IRQ_DEFAULT;
58
59 writel(value, ioaddr + GMAC_INT_EN);
477286b5
AT
60}
61
9eb12474 62static void dwmac4_rx_queue_enable(struct mac_device_info *hw, u32 queue)
63{
64 void __iomem *ioaddr = hw->pcsr;
65 u32 value = readl(ioaddr + GMAC_RXQ_CTRL0);
66
67 value &= GMAC_RX_QUEUE_CLEAR(queue);
68 value |= GMAC_RX_AV_QUEUE_ENABLE(queue);
69
70 writel(value, ioaddr + GMAC_RXQ_CTRL0);
71}
72
477286b5
AT
73static void dwmac4_dump_regs(struct mac_device_info *hw)
74{
75 void __iomem *ioaddr = hw->pcsr;
76 int i;
77
78 pr_debug("\tDWMAC4 regs (base addr = 0x%p)\n", ioaddr);
79
80 for (i = 0; i < GMAC_REG_NUM; i++) {
81 int offset = i * 4;
82
83 pr_debug("\tReg No. %d (offset 0x%x): 0x%08x\n", i,
84 offset, readl(ioaddr + offset));
85 }
86}
87
88static int dwmac4_rx_ipc_enable(struct mac_device_info *hw)
89{
90 void __iomem *ioaddr = hw->pcsr;
91 u32 value = readl(ioaddr + GMAC_CONFIG);
92
93 if (hw->rx_csum)
94 value |= GMAC_CONFIG_IPC;
95 else
96 value &= ~GMAC_CONFIG_IPC;
97
98 writel(value, ioaddr + GMAC_CONFIG);
99
100 value = readl(ioaddr + GMAC_CONFIG);
101
102 return !!(value & GMAC_CONFIG_IPC);
103}
104
105static void dwmac4_pmt(struct mac_device_info *hw, unsigned long mode)
106{
107 void __iomem *ioaddr = hw->pcsr;
108 unsigned int pmt = 0;
109
110 if (mode & WAKE_MAGIC) {
111 pr_debug("GMAC: WOL Magic frame\n");
112 pmt |= power_down | magic_pkt_en;
113 }
114 if (mode & WAKE_UCAST) {
115 pr_debug("GMAC: WOL on global unicast\n");
19cd1203 116 pmt |= power_down | global_unicast | wake_up_frame_en;
477286b5
AT
117 }
118
119 writel(pmt, ioaddr + GMAC_PMT);
120}
121
122static void dwmac4_set_umac_addr(struct mac_device_info *hw,
123 unsigned char *addr, unsigned int reg_n)
124{
125 void __iomem *ioaddr = hw->pcsr;
126
127 stmmac_dwmac4_set_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
128 GMAC_ADDR_LOW(reg_n));
129}
130
131static void dwmac4_get_umac_addr(struct mac_device_info *hw,
132 unsigned char *addr, unsigned int reg_n)
133{
134 void __iomem *ioaddr = hw->pcsr;
135
136 stmmac_dwmac4_get_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
137 GMAC_ADDR_LOW(reg_n));
138}
139
b4b7b772 140static void dwmac4_set_eee_mode(struct mac_device_info *hw,
141 bool en_tx_lpi_clockgating)
afbb1674 142{
143 void __iomem *ioaddr = hw->pcsr;
144 u32 value;
145
146 /* Enable the link status receive on RGMII, SGMII ore SMII
147 * receive path and instruct the transmit to enter in LPI
148 * state.
149 */
150 value = readl(ioaddr + GMAC4_LPI_CTRL_STATUS);
151 value |= GMAC4_LPI_CTRL_STATUS_LPIEN | GMAC4_LPI_CTRL_STATUS_LPITXA;
152
b4b7b772 153 if (en_tx_lpi_clockgating)
154 value |= GMAC4_LPI_CTRL_STATUS_LPITCSE;
155
afbb1674 156 writel(value, ioaddr + GMAC4_LPI_CTRL_STATUS);
157}
158
159static void dwmac4_reset_eee_mode(struct mac_device_info *hw)
160{
161 void __iomem *ioaddr = hw->pcsr;
162 u32 value;
163
164 value = readl(ioaddr + GMAC4_LPI_CTRL_STATUS);
165 value &= ~(GMAC4_LPI_CTRL_STATUS_LPIEN | GMAC4_LPI_CTRL_STATUS_LPITXA);
166 writel(value, ioaddr + GMAC4_LPI_CTRL_STATUS);
167}
168
169static void dwmac4_set_eee_pls(struct mac_device_info *hw, int link)
170{
171 void __iomem *ioaddr = hw->pcsr;
172 u32 value;
173
174 value = readl(ioaddr + GMAC4_LPI_CTRL_STATUS);
175
176 if (link)
177 value |= GMAC4_LPI_CTRL_STATUS_PLS;
178 else
179 value &= ~GMAC4_LPI_CTRL_STATUS_PLS;
180
181 writel(value, ioaddr + GMAC4_LPI_CTRL_STATUS);
182}
183
184static void dwmac4_set_eee_timer(struct mac_device_info *hw, int ls, int tw)
185{
186 void __iomem *ioaddr = hw->pcsr;
f4ec6064 187 int value = ((tw & 0xffff)) | ((ls & 0x3ff) << 16);
afbb1674 188
189 /* Program the timers in the LPI timer control register:
190 * LS: minimum time (ms) for which the link
191 * status from PHY should be ok before transmitting
192 * the LPI pattern.
193 * TW: minimum time (us) for which the core waits
194 * after it has stopped transmitting the LPI pattern.
195 */
196 writel(value, ioaddr + GMAC4_LPI_TIMER_CTRL);
197}
198
477286b5
AT
199static void dwmac4_set_filter(struct mac_device_info *hw,
200 struct net_device *dev)
201{
202 void __iomem *ioaddr = (void __iomem *)dev->base_addr;
203 unsigned int value = 0;
204
205 if (dev->flags & IFF_PROMISC) {
206 value = GMAC_PACKET_FILTER_PR;
207 } else if ((dev->flags & IFF_ALLMULTI) ||
208 (netdev_mc_count(dev) > HASH_TABLE_SIZE)) {
209 /* Pass all multi */
210 value = GMAC_PACKET_FILTER_PM;
211 /* Set the 64 bits of the HASH tab. To be updated if taller
212 * hash table is used
213 */
214 writel(0xffffffff, ioaddr + GMAC_HASH_TAB_0_31);
215 writel(0xffffffff, ioaddr + GMAC_HASH_TAB_32_63);
216 } else if (!netdev_mc_empty(dev)) {
217 u32 mc_filter[2];
218 struct netdev_hw_addr *ha;
219
220 /* Hash filter for multicast */
221 value = GMAC_PACKET_FILTER_HMC;
222
223 memset(mc_filter, 0, sizeof(mc_filter));
224 netdev_for_each_mc_addr(ha, dev) {
225 /* The upper 6 bits of the calculated CRC are used to
226 * index the content of the Hash Table Reg 0 and 1.
227 */
228 int bit_nr =
229 (bitrev32(~crc32_le(~0, ha->addr, 6)) >> 26);
230 /* The most significant bit determines the register
231 * to use while the other 5 bits determines the bit
232 * within the selected register
233 */
234 mc_filter[bit_nr >> 5] |= (1 << (bit_nr & 0x1F));
235 }
236 writel(mc_filter[0], ioaddr + GMAC_HASH_TAB_0_31);
237 writel(mc_filter[1], ioaddr + GMAC_HASH_TAB_32_63);
238 }
239
240 /* Handle multiple unicast addresses */
241 if (netdev_uc_count(dev) > GMAC_MAX_PERFECT_ADDRESSES) {
242 /* Switch to promiscuous mode if more than 128 addrs
243 * are required
244 */
245 value |= GMAC_PACKET_FILTER_PR;
246 } else if (!netdev_uc_empty(dev)) {
247 int reg = 1;
248 struct netdev_hw_addr *ha;
249
250 netdev_for_each_uc_addr(ha, dev) {
ca8bdaf1 251 dwmac4_set_umac_addr(hw, ha->addr, reg);
477286b5
AT
252 reg++;
253 }
254 }
255
256 writel(value, ioaddr + GMAC_PACKET_FILTER);
257}
258
259static void dwmac4_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
260 unsigned int fc, unsigned int pause_time)
261{
262 void __iomem *ioaddr = hw->pcsr;
263 u32 channel = STMMAC_CHAN0; /* FIXME */
264 unsigned int flow = 0;
265
266 pr_debug("GMAC Flow-Control:\n");
267 if (fc & FLOW_RX) {
268 pr_debug("\tReceive Flow-Control ON\n");
269 flow |= GMAC_RX_FLOW_CTRL_RFE;
270 writel(flow, ioaddr + GMAC_RX_FLOW_CTRL);
271 }
272 if (fc & FLOW_TX) {
273 pr_debug("\tTransmit Flow-Control ON\n");
274 flow |= GMAC_TX_FLOW_CTRL_TFE;
275 writel(flow, ioaddr + GMAC_QX_TX_FLOW_CTRL(channel));
276
277 if (duplex) {
278 pr_debug("\tduplex mode: PAUSE %d\n", pause_time);
279 flow |= (pause_time << GMAC_TX_FLOW_CTRL_PT_SHIFT);
280 writel(flow, ioaddr + GMAC_QX_TX_FLOW_CTRL(channel));
281 }
282 }
283}
284
70523e63
GC
285static void dwmac4_ctrl_ane(void __iomem *ioaddr, bool ane, bool srgmi_ral,
286 bool loopback)
477286b5 287{
70523e63
GC
288 dwmac_ctrl_ane(ioaddr, GMAC_PCS_BASE, ane, srgmi_ral, loopback);
289}
477286b5 290
70523e63
GC
291static void dwmac4_rane(void __iomem *ioaddr, bool restart)
292{
293 dwmac_rane(ioaddr, GMAC_PCS_BASE, restart);
294}
477286b5 295
70523e63
GC
296static void dwmac4_get_adv_lp(void __iomem *ioaddr, struct rgmii_adv *adv)
297{
298 dwmac_get_adv_lp(ioaddr, GMAC_PCS_BASE, adv);
477286b5
AT
299}
300
70523e63
GC
301/* RGMII or SMII interface */
302static void dwmac4_phystatus(void __iomem *ioaddr, struct stmmac_extra_stats *x)
477286b5 303{
70523e63 304 u32 status;
477286b5 305
70523e63
GC
306 status = readl(ioaddr + GMAC_PHYIF_CONTROL_STATUS);
307 x->irq_rgmii_n++;
477286b5 308
70523e63
GC
309 /* Check the link status */
310 if (status & GMAC_PHYIF_CTRLSTATUS_LNKSTS) {
311 int speed_value;
477286b5 312
70523e63 313 x->pcs_link = 1;
477286b5 314
70523e63
GC
315 speed_value = ((status & GMAC_PHYIF_CTRLSTATUS_SPEED) >>
316 GMAC_PHYIF_CTRLSTATUS_SPEED_SHIFT);
317 if (speed_value == GMAC_PHYIF_CTRLSTATUS_SPEED_125)
318 x->pcs_speed = SPEED_1000;
319 else if (speed_value == GMAC_PHYIF_CTRLSTATUS_SPEED_25)
320 x->pcs_speed = SPEED_100;
321 else
322 x->pcs_speed = SPEED_10;
323
324 x->pcs_duplex = (status & GMAC_PHYIF_CTRLSTATUS_LNKMOD_MASK);
477286b5 325
70523e63
GC
326 pr_info("Link is Up - %d/%s\n", (int)x->pcs_speed,
327 x->pcs_duplex ? "Full" : "Half");
328 } else {
329 x->pcs_link = 0;
330 pr_info("Link is Down\n");
331 }
477286b5
AT
332}
333
334static int dwmac4_irq_status(struct mac_device_info *hw,
335 struct stmmac_extra_stats *x)
336{
337 void __iomem *ioaddr = hw->pcsr;
338 u32 mtl_int_qx_status;
339 u32 intr_status;
340 int ret = 0;
341
342 intr_status = readl(ioaddr + GMAC_INT_STATUS);
343
344 /* Not used events (e.g. MMC interrupts) are not handled. */
345 if ((intr_status & mmc_tx_irq))
346 x->mmc_tx_irq_n++;
347 if (unlikely(intr_status & mmc_rx_irq))
348 x->mmc_rx_irq_n++;
349 if (unlikely(intr_status & mmc_rx_csum_offload_irq))
350 x->mmc_rx_csum_offload_irq_n++;
351 /* Clear the PMT bits 5 and 6 by reading the PMT status reg */
352 if (unlikely(intr_status & pmt_irq)) {
353 readl(ioaddr + GMAC_PMT);
354 x->irq_receive_pmt_irq_n++;
355 }
356
477286b5
AT
357 mtl_int_qx_status = readl(ioaddr + MTL_INT_STATUS);
358 /* Check MTL Interrupt: Currently only one queue is used: Q0. */
359 if (mtl_int_qx_status & MTL_INT_Q0) {
360 /* read Queue 0 Interrupt status */
361 u32 status = readl(ioaddr + MTL_CHAN_INT_CTRL(STMMAC_CHAN0));
362
363 if (status & MTL_RX_OVERFLOW_INT) {
364 /* clear Interrupt */
365 writel(status | MTL_RX_OVERFLOW_INT,
366 ioaddr + MTL_CHAN_INT_CTRL(STMMAC_CHAN0));
367 ret = CORE_IRQ_MTL_RX_OVERFLOW;
368 }
369 }
370
70523e63
GC
371 dwmac_pcs_isr(ioaddr, GMAC_PCS_BASE, intr_status, x);
372 if (intr_status & PCS_RGSMIIIS_IRQ)
373 dwmac4_phystatus(ioaddr, x);
374
477286b5
AT
375 return ret;
376}
377
378static void dwmac4_debug(void __iomem *ioaddr, struct stmmac_extra_stats *x)
379{
380 u32 value;
381
382 /* Currently only channel 0 is supported */
383 value = readl(ioaddr + MTL_CHAN_TX_DEBUG(STMMAC_CHAN0));
384
385 if (value & MTL_DEBUG_TXSTSFSTS)
386 x->mtl_tx_status_fifo_full++;
387 if (value & MTL_DEBUG_TXFSTS)
388 x->mtl_tx_fifo_not_empty++;
389 if (value & MTL_DEBUG_TWCSTS)
390 x->mmtl_fifo_ctrl++;
391 if (value & MTL_DEBUG_TRCSTS_MASK) {
392 u32 trcsts = (value & MTL_DEBUG_TRCSTS_MASK)
393 >> MTL_DEBUG_TRCSTS_SHIFT;
394 if (trcsts == MTL_DEBUG_TRCSTS_WRITE)
395 x->mtl_tx_fifo_read_ctrl_write++;
396 else if (trcsts == MTL_DEBUG_TRCSTS_TXW)
397 x->mtl_tx_fifo_read_ctrl_wait++;
398 else if (trcsts == MTL_DEBUG_TRCSTS_READ)
399 x->mtl_tx_fifo_read_ctrl_read++;
400 else
401 x->mtl_tx_fifo_read_ctrl_idle++;
402 }
403 if (value & MTL_DEBUG_TXPAUSED)
404 x->mac_tx_in_pause++;
405
406 value = readl(ioaddr + MTL_CHAN_RX_DEBUG(STMMAC_CHAN0));
407
408 if (value & MTL_DEBUG_RXFSTS_MASK) {
409 u32 rxfsts = (value & MTL_DEBUG_RXFSTS_MASK)
410 >> MTL_DEBUG_RRCSTS_SHIFT;
411
412 if (rxfsts == MTL_DEBUG_RXFSTS_FULL)
413 x->mtl_rx_fifo_fill_level_full++;
414 else if (rxfsts == MTL_DEBUG_RXFSTS_AT)
415 x->mtl_rx_fifo_fill_above_thresh++;
416 else if (rxfsts == MTL_DEBUG_RXFSTS_BT)
417 x->mtl_rx_fifo_fill_below_thresh++;
418 else
419 x->mtl_rx_fifo_fill_level_empty++;
420 }
421 if (value & MTL_DEBUG_RRCSTS_MASK) {
422 u32 rrcsts = (value & MTL_DEBUG_RRCSTS_MASK) >>
423 MTL_DEBUG_RRCSTS_SHIFT;
424
425 if (rrcsts == MTL_DEBUG_RRCSTS_FLUSH)
426 x->mtl_rx_fifo_read_ctrl_flush++;
427 else if (rrcsts == MTL_DEBUG_RRCSTS_RSTAT)
428 x->mtl_rx_fifo_read_ctrl_read_data++;
429 else if (rrcsts == MTL_DEBUG_RRCSTS_RDATA)
430 x->mtl_rx_fifo_read_ctrl_status++;
431 else
432 x->mtl_rx_fifo_read_ctrl_idle++;
433 }
434 if (value & MTL_DEBUG_RWCSTS)
435 x->mtl_rx_fifo_ctrl_active++;
436
437 /* GMAC debug */
438 value = readl(ioaddr + GMAC_DEBUG);
439
440 if (value & GMAC_DEBUG_TFCSTS_MASK) {
441 u32 tfcsts = (value & GMAC_DEBUG_TFCSTS_MASK)
442 >> GMAC_DEBUG_TFCSTS_SHIFT;
443
444 if (tfcsts == GMAC_DEBUG_TFCSTS_XFER)
445 x->mac_tx_frame_ctrl_xfer++;
446 else if (tfcsts == GMAC_DEBUG_TFCSTS_GEN_PAUSE)
447 x->mac_tx_frame_ctrl_pause++;
448 else if (tfcsts == GMAC_DEBUG_TFCSTS_WAIT)
449 x->mac_tx_frame_ctrl_wait++;
450 else
451 x->mac_tx_frame_ctrl_idle++;
452 }
453 if (value & GMAC_DEBUG_TPESTS)
454 x->mac_gmii_tx_proto_engine++;
455 if (value & GMAC_DEBUG_RFCFCSTS_MASK)
456 x->mac_rx_frame_ctrl_fifo = (value & GMAC_DEBUG_RFCFCSTS_MASK)
457 >> GMAC_DEBUG_RFCFCSTS_SHIFT;
458 if (value & GMAC_DEBUG_RPESTS)
459 x->mac_gmii_rx_proto_engine++;
460}
461
462static const struct stmmac_ops dwmac4_ops = {
463 .core_init = dwmac4_core_init,
464 .rx_ipc = dwmac4_rx_ipc_enable,
9eb12474 465 .rx_queue_enable = dwmac4_rx_queue_enable,
477286b5
AT
466 .dump_regs = dwmac4_dump_regs,
467 .host_irq_status = dwmac4_irq_status,
468 .flow_ctrl = dwmac4_flow_ctrl,
469 .pmt = dwmac4_pmt,
470 .set_umac_addr = dwmac4_set_umac_addr,
471 .get_umac_addr = dwmac4_get_umac_addr,
afbb1674 472 .set_eee_mode = dwmac4_set_eee_mode,
473 .reset_eee_mode = dwmac4_reset_eee_mode,
474 .set_eee_timer = dwmac4_set_eee_timer,
475 .set_eee_pls = dwmac4_set_eee_pls,
70523e63
GC
476 .pcs_ctrl_ane = dwmac4_ctrl_ane,
477 .pcs_rane = dwmac4_rane,
478 .pcs_get_adv_lp = dwmac4_get_adv_lp,
477286b5
AT
479 .debug = dwmac4_debug,
480 .set_filter = dwmac4_set_filter,
481};
482
483struct mac_device_info *dwmac4_setup(void __iomem *ioaddr, int mcbins,
484 int perfect_uc_entries, int *synopsys_id)
485{
486 struct mac_device_info *mac;
487 u32 hwid = readl(ioaddr + GMAC_VERSION);
488
489 mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
490 if (!mac)
491 return NULL;
492
493 mac->pcsr = ioaddr;
494 mac->multicast_filter_bins = mcbins;
495 mac->unicast_filter_entries = perfect_uc_entries;
496 mac->mcast_bits_log2 = 0;
497
498 if (mac->multicast_filter_bins)
499 mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
500
501 mac->mac = &dwmac4_ops;
502
503 mac->link.port = GMAC_CONFIG_PS;
504 mac->link.duplex = GMAC_CONFIG_DM;
505 mac->link.speed = GMAC_CONFIG_FES;
506 mac->mii.addr = GMAC_MDIO_ADDR;
507 mac->mii.data = GMAC_MDIO_DATA;
b91dce4c
LC
508 mac->mii.addr_shift = 21;
509 mac->mii.addr_mask = GENMASK(25, 21);
510 mac->mii.reg_shift = 16;
511 mac->mii.reg_mask = GENMASK(20, 16);
512 mac->mii.clk_csr_shift = 8;
513 mac->mii.clk_csr_mask = GENMASK(11, 8);
477286b5
AT
514
515 /* Get and dump the chip ID */
516 *synopsys_id = stmmac_get_synopsys_id(hwid);
517
518 if (*synopsys_id > DWMAC_CORE_4_00)
519 mac->dma = &dwmac410_dma_ops;
520 else
521 mac->dma = &dwmac4_dma_ops;
522
523 return mac;
524}