1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29#include <linux/crc32.h>
30#include <linux/slab.h>
31#include <linux/ethtool.h>
32#include <asm/io.h>
33#include "stmmac_pcs.h"
34#include "dwmac1000.h"
35
36static void dwmac1000_core_init(struct mac_device_info *hw, int mtu)
37{
38 void __iomem *ioaddr = hw->pcsr;
39 u32 value = readl(ioaddr + GMAC_CONTROL);
40
41
42 value |= GMAC_CORE_INIT;
43
44 if (mtu > 1500)
45 value |= GMAC_CONTROL_2K;
46 if (mtu > 2000)
47 value |= GMAC_CONTROL_JE;
48
49 if (hw->ps) {
50 value |= GMAC_CONTROL_TE;
51
52 if (hw->ps == SPEED_1000) {
53 value &= ~GMAC_CONTROL_PS;
54 } else {
55 value |= GMAC_CONTROL_PS;
56
57 if (hw->ps == SPEED_10)
58 value &= ~GMAC_CONTROL_FES;
59 else
60 value |= GMAC_CONTROL_FES;
61 }
62 }
63
64 writel(value, ioaddr + GMAC_CONTROL);
65
66
67 value = GMAC_INT_DEFAULT_MASK;
68
69 if (hw->pmt)
70 value &= ~GMAC_INT_DISABLE_PMT;
71 if (hw->pcs)
72 value &= ~GMAC_INT_DISABLE_PCS;
73
74 writel(value, ioaddr + GMAC_INT_MASK);
75
76#ifdef STMMAC_VLAN_TAG_USED
77
78 writel(0x0, ioaddr + GMAC_VLAN_TAG);
79#endif
80}
81
82static int dwmac1000_rx_ipc_enable(struct mac_device_info *hw)
83{
84 void __iomem *ioaddr = hw->pcsr;
85 u32 value = readl(ioaddr + GMAC_CONTROL);
86
87 if (hw->rx_csum)
88 value |= GMAC_CONTROL_IPC;
89 else
90 value &= ~GMAC_CONTROL_IPC;
91
92 writel(value, ioaddr + GMAC_CONTROL);
93
94 value = readl(ioaddr + GMAC_CONTROL);
95
96 return !!(value & GMAC_CONTROL_IPC);
97}
98
99static void dwmac1000_dump_regs(struct mac_device_info *hw)
100{
101 void __iomem *ioaddr = hw->pcsr;
102 int i;
103 pr_info("\tDWMAC1000 regs (base addr = 0x%p)\n", ioaddr);
104
105 for (i = 0; i < 55; i++) {
106 int offset = i * 4;
107 pr_info("\tReg No. %d (offset 0x%x): 0x%08x\n", i,
108 offset, readl(ioaddr + offset));
109 }
110}
111
112static void dwmac1000_set_umac_addr(struct mac_device_info *hw,
113 unsigned char *addr,
114 unsigned int reg_n)
115{
116 void __iomem *ioaddr = hw->pcsr;
117 stmmac_set_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
118 GMAC_ADDR_LOW(reg_n));
119}
120
121static void dwmac1000_get_umac_addr(struct mac_device_info *hw,
122 unsigned char *addr,
123 unsigned int reg_n)
124{
125 void __iomem *ioaddr = hw->pcsr;
126 stmmac_get_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
127 GMAC_ADDR_LOW(reg_n));
128}
129
130static void dwmac1000_set_mchash(void __iomem *ioaddr, u32 *mcfilterbits,
131 int mcbitslog2)
132{
133 int numhashregs, regs;
134
135 switch (mcbitslog2) {
136 case 6:
137 writel(mcfilterbits[0], ioaddr + GMAC_HASH_LOW);
138 writel(mcfilterbits[1], ioaddr + GMAC_HASH_HIGH);
139 return;
140 break;
141 case 7:
142 numhashregs = 4;
143 break;
144 case 8:
145 numhashregs = 8;
146 break;
147 default:
148 pr_debug("STMMAC: err in setting multicast filter\n");
149 return;
150 break;
151 }
152 for (regs = 0; regs < numhashregs; regs++)
153 writel(mcfilterbits[regs],
154 ioaddr + GMAC_EXTHASH_BASE + regs * 4);
155}
156
157static void dwmac1000_set_filter(struct mac_device_info *hw,
158 struct net_device *dev)
159{
160 void __iomem *ioaddr = (void __iomem *)dev->base_addr;
161 unsigned int value = 0;
162 unsigned int perfect_addr_number = hw->unicast_filter_entries;
163 u32 mc_filter[8];
164 int mcbitslog2 = hw->mcast_bits_log2;
165
166 pr_debug("%s: # mcasts %d, # unicast %d\n", __func__,
167 netdev_mc_count(dev), netdev_uc_count(dev));
168
169 memset(mc_filter, 0, sizeof(mc_filter));
170
171 if (dev->flags & IFF_PROMISC) {
172 value = GMAC_FRAME_FILTER_PR;
173 } else if (dev->flags & IFF_ALLMULTI) {
174 value = GMAC_FRAME_FILTER_PM;
175 } else if (!netdev_mc_empty(dev)) {
176 struct netdev_hw_addr *ha;
177
178
179 value = GMAC_FRAME_FILTER_HMC;
180
181 netdev_for_each_mc_addr(ha, dev) {
182
183
184
185
186
187 int bit_nr = bitrev32(~crc32_le(~0, ha->addr,
188 ETH_ALEN)) >>
189 (32 - mcbitslog2);
190
191
192
193
194 mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
195 }
196 }
197
198 dwmac1000_set_mchash(ioaddr, mc_filter, mcbitslog2);
199
200
201 if (netdev_uc_count(dev) > perfect_addr_number)
202
203
204
205 value |= GMAC_FRAME_FILTER_PR;
206 else {
207 int reg = 1;
208 struct netdev_hw_addr *ha;
209
210 netdev_for_each_uc_addr(ha, dev) {
211 stmmac_set_mac_addr(ioaddr, ha->addr,
212 GMAC_ADDR_HIGH(reg),
213 GMAC_ADDR_LOW(reg));
214 reg++;
215 }
216 }
217
218#ifdef FRAME_FILTER_DEBUG
219
220 value |= GMAC_FRAME_FILTER_RA;
221#endif
222 writel(value, ioaddr + GMAC_FRAME_FILTER);
223}
224
225
226static void dwmac1000_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
227 unsigned int fc, unsigned int pause_time)
228{
229 void __iomem *ioaddr = hw->pcsr;
230
231
232
233 unsigned int flow = GMAC_FLOW_CTRL_UP;
234
235 pr_debug("GMAC Flow-Control:\n");
236 if (fc & FLOW_RX) {
237 pr_debug("\tReceive Flow-Control ON\n");
238 flow |= GMAC_FLOW_CTRL_RFE;
239 }
240 if (fc & FLOW_TX) {
241 pr_debug("\tTransmit Flow-Control ON\n");
242 flow |= GMAC_FLOW_CTRL_TFE;
243 }
244
245 if (duplex) {
246 pr_debug("\tduplex mode: PAUSE %d\n", pause_time);
247 flow |= (pause_time << GMAC_FLOW_CTRL_PT_SHIFT);
248 }
249
250 writel(flow, ioaddr + GMAC_FLOW_CTRL);
251}
252
253static void dwmac1000_pmt(struct mac_device_info *hw, unsigned long mode)
254{
255 void __iomem *ioaddr = hw->pcsr;
256 unsigned int pmt = 0;
257
258 if (mode & WAKE_MAGIC) {
259 pr_debug("GMAC: WOL Magic frame\n");
260 pmt |= power_down | magic_pkt_en;
261 }
262 if (mode & WAKE_UCAST) {
263 pr_debug("GMAC: WOL on global unicast\n");
264 pmt |= power_down | global_unicast | wake_up_frame_en;
265 }
266
267 writel(pmt, ioaddr + GMAC_PMT);
268}
269
270
271static void dwmac1000_rgsmii(void __iomem *ioaddr, struct stmmac_extra_stats *x)
272{
273 u32 status;
274
275 status = readl(ioaddr + GMAC_RGSMIIIS);
276 x->irq_rgmii_n++;
277
278
279 if (status & GMAC_RGSMIIIS_LNKSTS) {
280 int speed_value;
281
282 x->pcs_link = 1;
283
284 speed_value = ((status & GMAC_RGSMIIIS_SPEED) >>
285 GMAC_RGSMIIIS_SPEED_SHIFT);
286 if (speed_value == GMAC_RGSMIIIS_SPEED_125)
287 x->pcs_speed = SPEED_1000;
288 else if (speed_value == GMAC_RGSMIIIS_SPEED_25)
289 x->pcs_speed = SPEED_100;
290 else
291 x->pcs_speed = SPEED_10;
292
293 x->pcs_duplex = (status & GMAC_RGSMIIIS_LNKMOD_MASK);
294
295 pr_info("Link is Up - %d/%s\n", (int)x->pcs_speed,
296 x->pcs_duplex ? "Full" : "Half");
297 } else {
298 x->pcs_link = 0;
299 pr_info("Link is Down\n");
300 }
301}
302
303static int dwmac1000_irq_status(struct mac_device_info *hw,
304 struct stmmac_extra_stats *x)
305{
306 void __iomem *ioaddr = hw->pcsr;
307 u32 intr_status = readl(ioaddr + GMAC_INT_STATUS);
308 int ret = 0;
309
310
311 if ((intr_status & GMAC_INT_STATUS_MMCTIS))
312 x->mmc_tx_irq_n++;
313 if (unlikely(intr_status & GMAC_INT_STATUS_MMCRIS))
314 x->mmc_rx_irq_n++;
315 if (unlikely(intr_status & GMAC_INT_STATUS_MMCCSUM))
316 x->mmc_rx_csum_offload_irq_n++;
317 if (unlikely(intr_status & GMAC_INT_DISABLE_PMT)) {
318
319 readl(ioaddr + GMAC_PMT);
320 x->irq_receive_pmt_irq_n++;
321 }
322
323
324 if (intr_status & GMAC_INT_STATUS_LPIIS) {
325
326 ret = readl(ioaddr + LPI_CTRL_STATUS);
327
328 if (ret & LPI_CTRL_STATUS_TLPIEN)
329 x->irq_tx_path_in_lpi_mode_n++;
330 if (ret & LPI_CTRL_STATUS_TLPIEX)
331 x->irq_tx_path_exit_lpi_mode_n++;
332 if (ret & LPI_CTRL_STATUS_RLPIEN)
333 x->irq_rx_path_in_lpi_mode_n++;
334 if (ret & LPI_CTRL_STATUS_RLPIEX)
335 x->irq_rx_path_exit_lpi_mode_n++;
336 }
337
338 dwmac_pcs_isr(ioaddr, GMAC_PCS_BASE, intr_status, x);
339
340 if (intr_status & PCS_RGSMIIIS_IRQ)
341 dwmac1000_rgsmii(ioaddr, x);
342
343 return ret;
344}
345
346static void dwmac1000_set_eee_mode(struct mac_device_info *hw)
347{
348 void __iomem *ioaddr = hw->pcsr;
349 u32 value;
350
351
352
353
354
355 value = readl(ioaddr + LPI_CTRL_STATUS);
356 value |= LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA;
357 writel(value, ioaddr + LPI_CTRL_STATUS);
358}
359
360static void dwmac1000_reset_eee_mode(struct mac_device_info *hw)
361{
362 void __iomem *ioaddr = hw->pcsr;
363 u32 value;
364
365 value = readl(ioaddr + LPI_CTRL_STATUS);
366 value &= ~(LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA);
367 writel(value, ioaddr + LPI_CTRL_STATUS);
368}
369
370static void dwmac1000_set_eee_pls(struct mac_device_info *hw, int link)
371{
372 void __iomem *ioaddr = hw->pcsr;
373 u32 value;
374
375 value = readl(ioaddr + LPI_CTRL_STATUS);
376
377 if (link)
378 value |= LPI_CTRL_STATUS_PLS;
379 else
380 value &= ~LPI_CTRL_STATUS_PLS;
381
382 writel(value, ioaddr + LPI_CTRL_STATUS);
383}
384
385static void dwmac1000_set_eee_timer(struct mac_device_info *hw, int ls, int tw)
386{
387 void __iomem *ioaddr = hw->pcsr;
388 int value = ((tw & 0xffff)) | ((ls & 0x7ff) << 16);
389
390
391
392
393
394
395
396
397 writel(value, ioaddr + LPI_TIMER_CTRL);
398}
399
400static void dwmac1000_ctrl_ane(void __iomem *ioaddr, bool ane, bool srgmi_ral,
401 bool loopback)
402{
403 dwmac_ctrl_ane(ioaddr, GMAC_PCS_BASE, ane, srgmi_ral, loopback);
404}
405
406static void dwmac1000_rane(void __iomem *ioaddr, bool restart)
407{
408 dwmac_rane(ioaddr, GMAC_PCS_BASE, restart);
409}
410
411static void dwmac1000_get_adv_lp(void __iomem *ioaddr, struct rgmii_adv *adv)
412{
413 dwmac_get_adv_lp(ioaddr, GMAC_PCS_BASE, adv);
414}
415
416static void dwmac1000_debug(void __iomem *ioaddr, struct stmmac_extra_stats *x)
417{
418 u32 value = readl(ioaddr + GMAC_DEBUG);
419
420 if (value & GMAC_DEBUG_TXSTSFSTS)
421 x->mtl_tx_status_fifo_full++;
422 if (value & GMAC_DEBUG_TXFSTS)
423 x->mtl_tx_fifo_not_empty++;
424 if (value & GMAC_DEBUG_TWCSTS)
425 x->mmtl_fifo_ctrl++;
426 if (value & GMAC_DEBUG_TRCSTS_MASK) {
427 u32 trcsts = (value & GMAC_DEBUG_TRCSTS_MASK)
428 >> GMAC_DEBUG_TRCSTS_SHIFT;
429 if (trcsts == GMAC_DEBUG_TRCSTS_WRITE)
430 x->mtl_tx_fifo_read_ctrl_write++;
431 else if (trcsts == GMAC_DEBUG_TRCSTS_TXW)
432 x->mtl_tx_fifo_read_ctrl_wait++;
433 else if (trcsts == GMAC_DEBUG_TRCSTS_READ)
434 x->mtl_tx_fifo_read_ctrl_read++;
435 else
436 x->mtl_tx_fifo_read_ctrl_idle++;
437 }
438 if (value & GMAC_DEBUG_TXPAUSED)
439 x->mac_tx_in_pause++;
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_RXFSTS_MASK) {
456 u32 rxfsts = (value & GMAC_DEBUG_RXFSTS_MASK)
457 >> GMAC_DEBUG_RRCSTS_SHIFT;
458
459 if (rxfsts == GMAC_DEBUG_RXFSTS_FULL)
460 x->mtl_rx_fifo_fill_level_full++;
461 else if (rxfsts == GMAC_DEBUG_RXFSTS_AT)
462 x->mtl_rx_fifo_fill_above_thresh++;
463 else if (rxfsts == GMAC_DEBUG_RXFSTS_BT)
464 x->mtl_rx_fifo_fill_below_thresh++;
465 else
466 x->mtl_rx_fifo_fill_level_empty++;
467 }
468 if (value & GMAC_DEBUG_RRCSTS_MASK) {
469 u32 rrcsts = (value & GMAC_DEBUG_RRCSTS_MASK) >>
470 GMAC_DEBUG_RRCSTS_SHIFT;
471
472 if (rrcsts == GMAC_DEBUG_RRCSTS_FLUSH)
473 x->mtl_rx_fifo_read_ctrl_flush++;
474 else if (rrcsts == GMAC_DEBUG_RRCSTS_RSTAT)
475 x->mtl_rx_fifo_read_ctrl_read_data++;
476 else if (rrcsts == GMAC_DEBUG_RRCSTS_RDATA)
477 x->mtl_rx_fifo_read_ctrl_status++;
478 else
479 x->mtl_rx_fifo_read_ctrl_idle++;
480 }
481 if (value & GMAC_DEBUG_RWCSTS)
482 x->mtl_rx_fifo_ctrl_active++;
483 if (value & GMAC_DEBUG_RFCFCSTS_MASK)
484 x->mac_rx_frame_ctrl_fifo = (value & GMAC_DEBUG_RFCFCSTS_MASK)
485 >> GMAC_DEBUG_RFCFCSTS_SHIFT;
486 if (value & GMAC_DEBUG_RPESTS)
487 x->mac_gmii_rx_proto_engine++;
488}
489
490static const struct stmmac_ops dwmac1000_ops = {
491 .core_init = dwmac1000_core_init,
492 .rx_ipc = dwmac1000_rx_ipc_enable,
493 .dump_regs = dwmac1000_dump_regs,
494 .host_irq_status = dwmac1000_irq_status,
495 .set_filter = dwmac1000_set_filter,
496 .flow_ctrl = dwmac1000_flow_ctrl,
497 .pmt = dwmac1000_pmt,
498 .set_umac_addr = dwmac1000_set_umac_addr,
499 .get_umac_addr = dwmac1000_get_umac_addr,
500 .set_eee_mode = dwmac1000_set_eee_mode,
501 .reset_eee_mode = dwmac1000_reset_eee_mode,
502 .set_eee_timer = dwmac1000_set_eee_timer,
503 .set_eee_pls = dwmac1000_set_eee_pls,
504 .debug = dwmac1000_debug,
505 .pcs_ctrl_ane = dwmac1000_ctrl_ane,
506 .pcs_rane = dwmac1000_rane,
507 .pcs_get_adv_lp = dwmac1000_get_adv_lp,
508};
509
510struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins,
511 int perfect_uc_entries,
512 int *synopsys_id)
513{
514 struct mac_device_info *mac;
515 u32 hwid = readl(ioaddr + GMAC_VERSION);
516
517 mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
518 if (!mac)
519 return NULL;
520
521 mac->pcsr = ioaddr;
522 mac->multicast_filter_bins = mcbins;
523 mac->unicast_filter_entries = perfect_uc_entries;
524 mac->mcast_bits_log2 = 0;
525
526 if (mac->multicast_filter_bins)
527 mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
528
529 mac->mac = &dwmac1000_ops;
530 mac->dma = &dwmac1000_dma_ops;
531
532 mac->link.port = GMAC_CONTROL_PS;
533 mac->link.duplex = GMAC_CONTROL_DM;
534 mac->link.speed = GMAC_CONTROL_FES;
535 mac->mii.addr = GMAC_MII_ADDR;
536 mac->mii.data = GMAC_MII_DATA;
537
538
539 *synopsys_id = stmmac_get_synopsys_id(hwid);
540
541 return mac;
542}
543