Add Broadcom / Netgear changes from RAXE 1.0.0.48
[project/bcm63xx/u-boot.git] / arch / arm / mach-bcmbca / rdp / unimac_drv_impl1.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 Copyright (c) 2013 Broadcom Corporation
4 All Rights Reserved
5
6
7 */
8
9
10
11 /******************************************************************************/
12 /* */
13 /* File Description: */
14 /* */
15 /* This file contains the implementation of the HwApiMac for unimac */
16 /* */
17 /******************************************************************************/
18
19
20
21 /*****************************************************************************/
22 /* */
23 /* Include files */
24 /* */
25 /*****************************************************************************/
26 #include "unimac_drv.h"
27 #if defined(__UBOOT__) && !defined(CONFIG_BCM6856) && !defined(CONFIG_BCM6878)
28 static void get_rdp_freq(uint32_t *rdp_freq) { }
29 #else
30 #include "clk_rst.h"
31 #endif
32
33 #if defined(CONFIG_BCM63138) || defined(CONFIG_BCM63148)
34 #include "rdp_drv_bbh.h"
35 #endif
36
37 /******************************************************************************/
38 /* */
39 /* Types and values definitions */
40 /* */
41 /******************************************************************************/
42 #define UNIMAC_SWRESET_ON 1
43 #define UNIMAC_SWRESET_OFF 0
44 #define UNIMAC_DEFAULT_IPG 12
45 #define UNIMAC_DEFAULT_PAUSE_QUANTA 0xffff
46 #define UNIMAC_DEFAULT_PAUSE_TIMER 0x1ffff
47 #define UNIMAC_MAX_FRAME_LENGHT 0xffff
48
49 #ifdef __UBOOT__
50 #define mac_unlikely(a) a
51 #else
52 #define mac_unlikely(a) unlikely(a)
53 #endif
54
55 #define UNIMAC_NUMBER_OF_SPEEDS ( UNIMAC_SPEED_2500 + 1 )
56 #define UNIMAC_NUMBER_OF_DUPLEXES ( UNIMAC_DUPLEX_FULL + 1 )
57
58 static uint32_t ipgSpeedTable[UNIMAC_NUMBER_OF_SPEEDS][UNIMAC_NUMBER_OF_DUPLEXES] =
59 {
60 {0x000a,0x000a},
61 {0x000a,0x000a},
62 {0x0005,0x0005},
63 {0x0005,0x0005}
64 };
65
66 static uint32_t enabled_emac;
67
68 #if defined(CONFIG_BCM4908)
69 #include "bcm_map_part.h"
70 uint8_t *soc_base_address; // used by DEVICE_ADDRESS()
71 #endif
72
73 /******************************************************************************/
74 /* */
75 /* Name: */
76 /* */
77 /* mac_hwapi_get_configuration */
78 /* */
79 /* Title: */
80 /* */
81 /* MAC Driver - get configuration */
82 /* */
83 /* Abstract: */
84 /* */
85 /* get the configuratin of a mac port ,note that current status of emac */
86 /* might be different than configuration when working in autoneg */
87 /* to get the current status use mac_hwapi_get_mac_status API */
88 /* */
89 /* Input: */
90 /* */
91 /* emacNum - emac Port index */
92 /* */
93 /* */
94 /* Output: */
95 /* emac_cfg - structure holds the current configuration of the mac port */
96 /* */
97 /******************************************************************************/
98 void mac_hwapi_get_configuration(rdpa_emac emacNum,rdpa_emac_cfg_t *emac_cfg)
99 {
100 S_UNIMAC_CMD_REG mCfgReg;
101
102 if (!(enabled_emac & (1 << emacNum)))
103 return;
104
105 UNIMAC_READ32_REG(emacNum,CMD,mCfgReg);
106 emac_cfg->allow_too_long = 0;//no such
107 emac_cfg->back2back_gap = 0;//no such
108 emac_cfg->check_length = !mCfgReg.no_lgth_check;
109 emac_cfg->full_duplex = !mCfgReg.hd_ena;
110 emac_cfg->generate_crc = 0;
111 emac_cfg->loopback = mCfgReg.rmt_loop_ena;
112 emac_cfg->non_back2back_gap = 0;//no such
113 emac_cfg->pad_short = 0;//no such
114 emac_cfg->rate = mCfgReg.eth_speed;
115 emac_cfg->rx_flow_control = !mCfgReg.rx_pause_ignore;
116 emac_cfg->tx_flow_control = !mCfgReg.tx_pause_ignore;
117
118 UNIMAC_READ_FIELD(emacNum,HD_BKP_CNTL,ipg_config_rx,emac_cfg->min_interframe_gap);
119 UNIMAC_READ_FIELD(emacNum,TX_IPG_LEN,tx_ipg_len,emac_cfg->preamble_length);
120 }
121 EXPORT_SYMBOL(mac_hwapi_get_configuration);
122 /******************************************************************************/
123 /* */
124 /* Name: */
125 /* */
126 /* mac_hwapi_set_configuration */
127 /* */
128 /* Title: */
129 /* */
130 /* MAC Driver - set configuration */
131 /* */
132 /* Abstract: */
133 /* */
134 /* set the configuratin of a mac port */
135 /* Input: */
136 /* */
137 /* emacNum - emac Port index */
138 /* emac_cfg - structure holds the current configuration of the mac port */
139 /* */
140 /* Output: */
141 /* */
142 /* */
143 /******************************************************************************/
144 void mac_hwapi_set_configuration(rdpa_emac emacNum,rdpa_emac_cfg_t *emac_cfg)
145 {
146 S_UNIMAC_CMD_REG mCfgReg;
147
148 if (!(enabled_emac & (1 << emacNum)))
149 return;
150
151 /*first put the mac in reset to enable config change*/
152 UNIMAC_WRITE_FIELD(emacNum,CMD,sw_reset,1);
153
154
155 UNIMAC_READ32_REG(emacNum,CMD,mCfgReg);
156
157 /*now mac configuration can be changed */
158 if(!mCfgReg.ena_ext_config) /* Change only if auto_config is not set */
159 {
160 mCfgReg.eth_speed = emac_cfg->rate;
161 mCfgReg.hd_ena = !emac_cfg->full_duplex;
162 mCfgReg.rx_pause_ignore = !emac_cfg->rx_flow_control;
163 mCfgReg.tx_pause_ignore = !emac_cfg->tx_flow_control;
164 /*set the interframe gap*/
165 UNIMAC_WRITE_FIELD(emacNum,HD_BKP_CNTL,ipg_config_rx,ipgSpeedTable[emac_cfg->rate][(unsigned)emac_cfg->full_duplex]);
166 }
167 else
168 {
169 /*set the interframe gap*/
170 UNIMAC_WRITE_FIELD(emacNum,HD_BKP_CNTL,ipg_config_rx,emac_cfg->min_interframe_gap);
171 }
172
173 mCfgReg.no_lgth_check = !emac_cfg->check_length;
174 mCfgReg.pad_en = emac_cfg->pad_short;
175 mCfgReg.rmt_loop_ena = emac_cfg->loopback;
176
177
178 UNIMAC_WRITE32_REG(emacNum,CMD,mCfgReg);
179
180
181 /* set the preamble length */
182 UNIMAC_WRITE_FIELD(emacNum,TX_IPG_LEN,tx_ipg_len,emac_cfg->preamble_length);
183
184 /* when link up at 10M, hold unimac reset longer per ASIC team */
185 if (emac_cfg->rate == rdpa_emac_rate_10m)
186 udelay(1000);
187
188 /*release the sw_reset bit*/
189 UNIMAC_WRITE_FIELD(emacNum,CMD,sw_reset,0);
190 }
191 EXPORT_SYMBOL(mac_hwapi_set_configuration);
192
193 /******************************************************************************/
194 /* */
195 /* Name: */
196 /* */
197 /* mac_hwapi_get_duplex */
198 /* */
199 /* Title: */
200 /* */
201 /* MAC Driver - get port duplex */
202 /* */
203 /* Abstract: */
204 /* */
205 /* get the dulplex of a port */
206 /* */
207 /* Input: */
208 /* */
209 /* emacNum - emac Port index */
210 /* */
211 /* */
212 /* Output: */
213 /* full_duples : 1 = full dulplex,0 = half_duplex */
214 /* */
215 /******************************************************************************/
216 void mac_hwapi_get_duplex(rdpa_emac emacNum,int32_t *full_duplex)
217 {
218 /*read field and reverse polarity*/
219 int32_t fieldData;
220
221 if (!(enabled_emac & (1 << emacNum)))
222 return;
223
224 UNIMAC_READ_FIELD(emacNum,CMD,hd_ena,fieldData);
225 *full_duplex = !fieldData;
226 }
227 EXPORT_SYMBOL(mac_hwapi_get_duplex);
228
229 /******************************************************************************/
230 /* */
231 /* Name: */
232 /* */
233 /* mac_hwapi_set_duplex */
234 /* */
235 /* Title: */
236 /* */
237 /* MAC Driver - set port duplex */
238 /* */
239 /* Abstract: */
240 /* */
241 /* set the dulplex of a port */
242 /* */
243 /* Input: */
244 /* */
245 /* emacNum - emac Port index */
246 /* */
247 /* */
248 /* Output: */
249 /* full_duples : 1 = full dulplex,0 = half_duplex */
250 /* */
251 /******************************************************************************/
252 void mac_hwapi_set_duplex(rdpa_emac emacNum,int32_t full_duplex)
253 {
254 S_UNIMAC_CMD_REG mCfgReg;
255
256 if (!(enabled_emac & (1 << emacNum)))
257 return;
258
259 UNIMAC_READ32_REG(emacNum,CMD,mCfgReg);
260 if (!mCfgReg.ena_ext_config) /* Change only if auto_config is not set */
261 {
262 /*write the dulplex field in reverse polarity,must be set in sw_reset state*/
263 S_HWAPI_MAC_STATUS macMode;
264
265 UNIMAC_READ32_REG(emacNum,MODE,macMode);
266
267 UNIMAC_WRITE_FIELD(emacNum,CMD,sw_reset,UNIMAC_SWRESET_ON);
268
269 UNIMAC_WRITE_FIELD(emacNum,CMD,hd_ena,full_duplex ? 0 : 1);
270
271 /*when setting the duplex we have to set new IPG value*/
272 //UNIMAC_WRITE_FIELD(emacNum,TX_IPG_LEN ,tx_ipg_len,ipgSpeedTable[macMode.mac_speed][macMode.mac_duplex]);
273
274 /*take the mac out of sw_reset*/
275 UNIMAC_WRITE_FIELD(emacNum,CMD,sw_reset,UNIMAC_SWRESET_OFF);
276 }
277 }
278 EXPORT_SYMBOL(mac_hwapi_set_duplex);
279
280
281
282
283 /******************************************************************************/
284 /* */
285 /* Name: */
286 /* */
287 /* mac_hwapi_get_speed */
288 /* */
289 /* Title: */
290 /* */
291 /* MAC Driver - get port speed rate */
292 /* */
293 /* Abstract: */
294 /* */
295 /* get the speed of a port */
296 /* */
297 /* Input: */
298 /* */
299 /* emacNum - emac Port index */
300 /* */
301 /* */
302 /* Output: */
303 /* rate - enum of the speed */
304 /******************************************************************************/
305 void mac_hwapi_get_speed(rdpa_emac emacNum,rdpa_emac_rate *rate)
306 {
307 if (!(enabled_emac & (1 << emacNum)))
308 return;
309
310 /*read the speed field*/
311 UNIMAC_READ_FIELD(emacNum,CMD,eth_speed,*rate);
312 }
313 EXPORT_SYMBOL(mac_hwapi_get_speed);
314
315
316
317
318 /******************************************************************************/
319 /* */
320 /* Name: */
321 /* */
322 /* mac_hwapi_set_speed */
323 /* */
324 /* Title: */
325 /* */
326 /* MAC Driver - set port speed rate */
327 /* */
328 /* Abstract: */
329 /* */
330 /* set the speed of a port */
331 /* */
332 /* Input: */
333 /* */
334 /* emacNum - emac Port index */
335 /* rate - enum of the speed */
336 /* */
337 /* Output: */
338 /* */
339 /******************************************************************************/
340
341 void mac_hwapi_set_speed(rdpa_emac emacNum,rdpa_emac_rate rate)
342 {
343 S_UNIMAC_CMD_REG mCfgReg;
344
345 if (!(enabled_emac & (1 << emacNum)))
346 return;
347
348 UNIMAC_READ32_REG(emacNum,CMD,mCfgReg);
349 if (!mCfgReg.ena_ext_config) /* Change only if auto_config is not set */
350 {
351 UNIMAC_WRITE_FIELD(emacNum,CMD,sw_reset,UNIMAC_SWRESET_ON);
352
353 UNIMAC_WRITE_FIELD(emacNum,CMD,eth_speed,rate);
354
355
356 UNIMAC_WRITE_FIELD(emacNum,HD_BKP_CNTL,ipg_config_rx,ipgSpeedTable[rate][0]);
357
358
359 UNIMAC_WRITE_FIELD(emacNum,CMD,sw_reset,UNIMAC_SWRESET_OFF);
360 }
361 }
362 EXPORT_SYMBOL(mac_hwapi_set_speed);
363
364 void mac_hwapi_set_external_conf(rdpa_emac emacNum, int enable)
365 {
366 S_UNIMAC_CMD_REG mCfgReg;
367
368 if (!(enabled_emac & (1 << emacNum)))
369 return;
370
371 UNIMAC_READ32_REG(emacNum,CMD,mCfgReg);
372 mCfgReg.ena_ext_config = enable;
373 UNIMAC_WRITE32_REG(emacNum,CMD,mCfgReg);
374 }
375 EXPORT_SYMBOL(mac_hwapi_set_external_conf);
376
377 /******************************************************************************/
378 /* */
379 /* Name: */
380 /* */
381 /* mac_hwapi_get_rxtx_enable */
382 /* */
383 /* Title: */
384 /* */
385 /* MAC Driver - set tx and rx enable */
386 /* */
387 /* Abstract: */
388 /* */
389 /* get tx and rx enable */
390 /* */
391 /* Input: */
392 /* */
393 /* emacNum - emac Port index */
394 /* */
395 /* */
396 /* Output: */
397 /* rxtxEnable - boolean enable */
398 /******************************************************************************/
399 void mac_hwapi_get_rxtx_enable(rdpa_emac emacNum,int32_t *rxEnable,int32_t *txEnable)
400 {
401 if (!(enabled_emac & (1 << emacNum)))
402 return;
403
404 UNIMAC_READ_FIELD(emacNum,CMD,tx_ena,*txEnable);
405 UNIMAC_READ_FIELD(emacNum,CMD,rx_ena,*rxEnable);
406 }
407 EXPORT_SYMBOL(mac_hwapi_get_rxtx_enable);
408
409
410
411
412
413 /******************************************************************************/
414 /* */
415 /* Name: */
416 /* */
417 /* mac_hwapi_set_rxtx_enable */
418 /* */
419 /* Title: */
420 /* */
421 /* MAC Driver - set tx and rx enable */
422 /* */
423 /* Abstract: */
424 /* */
425 /* set tx and rx enable */
426 /* */
427 /* Input: */
428 /* */
429 /* emacNum - emac Port index */
430 /* rxtxEnable - boolean enable */
431 /* */
432 /* Output: */
433 /* */
434 /******************************************************************************/
435 void mac_hwapi_set_rxtx_enable(rdpa_emac emacNum,int32_t rxEnable,int32_t txEnable)
436 {
437 if (!(enabled_emac & (1 << emacNum)))
438 return;
439
440 UNIMAC_WRITE_FIELD(emacNum,CMD,tx_ena,txEnable);
441 UNIMAC_WRITE_FIELD(emacNum,CMD,rx_ena,rxEnable);
442 }
443 EXPORT_SYMBOL(mac_hwapi_set_rxtx_enable);
444
445
446
447
448 /******************************************************************************/
449 /* */
450 /* Name: */
451 /* */
452 /* mac_hwapi_get_sw_reset */
453 /* */
454 /* Title: */
455 /* */
456 /* MAC Driver - get port software reset */
457 /* */
458 /* Abstract: */
459 /* */
460 /* get the sw reset bit of emac port */
461 /* */
462 /* Input: */
463 /* */
464 /* emacNum - emac Port index */
465 /* */
466 /* */
467 /* Output: */
468 /* swReset : 1 = reset,0 = not reset */
469 /* */
470 /******************************************************************************/
471 void mac_hwapi_get_sw_reset(rdpa_emac emacNum,int32_t *swReset)
472 {
473 if (!(enabled_emac & (1 << emacNum)))
474 return;
475
476 UNIMAC_READ_FIELD(emacNum,CMD,sw_reset,*swReset);
477 }
478 EXPORT_SYMBOL(mac_hwapi_get_sw_reset);
479
480
481
482
483 /******************************************************************************/
484 /* */
485 /* Name: */
486 /* */
487 /* mac_hwapi_set_sw_reset */
488 /* */
489 /* Title: */
490 /* */
491 /* MAC Driver - set port software reset */
492 /* */
493 /* Abstract: */
494 /* */
495 /* set the sw reset bit of emac port */
496 /* */
497 /* Input: */
498 /* */
499 /* emacNum - emac Port index */
500 /* swReset : 1 = reset,0 = not reset */
501 /* */
502 /* Output: */
503 /* */
504 /* */
505 /******************************************************************************/
506 void mac_hwapi_set_sw_reset(rdpa_emac emacNum,int32_t swReset)
507 {
508 if (!(enabled_emac & (1 << emacNum)))
509 return;
510
511 UNIMAC_WRITE_FIELD(emacNum,CMD,sw_reset,swReset);
512 }
513 EXPORT_SYMBOL(mac_hwapi_set_sw_reset);
514
515
516 /******************************************************************************/
517 /* */
518 /* Name: */
519 /* */
520 /* mac_hwapi_get_tx_min_pkt_size */
521 /* */
522 /* Title: */
523 /* */
524 /* MAC Driver - get tx minimum packet size */
525 /* */
526 /* Abstract: */
527 /* */
528 /* Get the unimac configuration for minimum tx packet size */
529 /* */
530 /* Input: */
531 /* */
532 /* emacNum - emac Port index */
533 /* */
534 /* */
535 /* Output: */
536 /* min_pkt_size : 14...125 */
537 /* */
538 /******************************************************************************/
539 void mac_hwapi_get_tx_min_pkt_size(rdpa_emac emacNum,int32_t *min_pkt_size)
540 {
541 if (!(enabled_emac & (1 << emacNum)))
542 return;
543
544 UNIMAC_READ_FIELD(emacNum,TX_IPG_LEN,tx_min_pkt_size,*min_pkt_size);
545 }
546 EXPORT_SYMBOL(mac_hwapi_get_tx_min_pkt_size);
547
548
549
550
551 /******************************************************************************/
552 /* */
553 /* Name: */
554 /* */
555 /* mac_hwapi_set_tx_min_pkt_size */
556 /* */
557 /* Title: */
558 /* */
559 /* MAC Driver - set tx minimum packet size */
560 /* */
561 /* Abstract: */
562 /* */
563 /* Set the unimac configuration for minimum tx packet size */
564 /* */
565 /* Input: */
566 /* */
567 /* emacNum - emac Port index */
568 /* min_pkt_size : 14...125 */
569 /* */
570 /* Output: */
571 /* */
572 /* */
573 /******************************************************************************/
574 void mac_hwapi_set_tx_min_pkt_size(rdpa_emac emacNum,int32_t min_pkt_size)
575 {
576 if (!(enabled_emac & (1 << emacNum)))
577 return;
578
579 #if defined(CONFIG_BCM4908) || defined(CONFIG_BCM63158) || defined(CONFIG_BCM47622)
580 UNIMAC_WRITE_FIELD(emacNum,TX_IPG_LEN,tx_min_pkt_size,min_pkt_size);
581 #endif
582 }
583 EXPORT_SYMBOL(mac_hwapi_set_tx_min_pkt_size);
584
585
586 /******************************************************************************/
587 /* */
588 /* Name: */
589 /* */
590 /* mac_hwapi_get_tx_max_frame_len */
591 /* */
592 /* Title: */
593 /* */
594 /* MAC Driver - get port TX MTU */
595 /* */
596 /* Abstract: */
597 /* */
598 /* get the port maximum transmit unit size in bytes */
599 /* */
600 /* Input: */
601 /* */
602 /* emacNum - emac Port index */
603 /* */
604 /* */
605 /* Output: */
606 /* maxTxFrameLen - size of frame in bytes */
607 /* */
608 /******************************************************************************/
609 #if defined(CONFIG_BCM47622)
610 void mac_hwapi_get_tx_max_frame_len(rdpa_emac emacNum,uint32_t *maxTxFrameLen )
611 {
612 S_UNIMAC_TOPCTRL_MAX_PKT_SZ_REG cfgreg;
613 uintptr_t address = (uintptr_t)UNIMAC_TOPCTRL_MIB_MAX_PKT_SIZE + UNIMAC_TOPCTRL_INSTANCE_OFFSET(emacNum);
614
615 if (!(enabled_emac & (1 << emacNum)))
616 return;
617
618 READ_32(address,cfgreg);
619
620 *maxTxFrameLen = cfgreg.max_pkt_size;
621 }
622 #else //!47622
623 void mac_hwapi_get_tx_max_frame_len(rdpa_emac emacNum,uint32_t *maxTxFrameLen )
624 {
625 S_UNIMAC_TOP_CFG1_REG cfgreg;
626 uintptr_t address = (uintptr_t)UNIMAC_TOP_UNIMAC_MISC_UNIMAC_EXT_CFG1 + UNIMAC_MISC_INSTANCE_OFFSET(emacNum);
627
628 if (!(enabled_emac & (1 << emacNum)))
629 return;
630
631 READ_32(address,cfgreg);
632
633 *maxTxFrameLen = cfgreg.max_pkt_size;
634 }
635 #endif //!47622
636 EXPORT_SYMBOL(mac_hwapi_get_tx_max_frame_len);
637
638
639
640
641 /******************************************************************************/
642 /* */
643 /* Name: */
644 /* */
645 /* mac_hwapi_set_tx_max_frame_len */
646 /* */
647 /* Title: */
648 /* */
649 /* MAC Driver - set port TX MTU */
650 /* */
651 /* Abstract: */
652 /* */
653 /* set the port maximum transmit unit size in bytes */
654 /* */
655 /* Input: */
656 /* */
657 /* emacNum - emac Port index */
658 /* maxTxFrameLen - size of frame in bytes */
659 /* */
660 /* Output: */
661 /* */
662 /* */
663 /******************************************************************************/
664 #if defined(CONFIG_BCM47622)
665 void mac_hwapi_set_tx_max_frame_len(rdpa_emac emacNum,uint32_t maxTxFrameLen )
666 {
667
668 S_UNIMAC_TOPCTRL_MAX_PKT_SZ_REG cfgreg;
669 uintptr_t address = (uintptr_t)UNIMAC_TOPCTRL_MIB_MAX_PKT_SIZE + UNIMAC_TOPCTRL_INSTANCE_OFFSET(emacNum);
670
671 if (!(enabled_emac & (1 << emacNum)))
672 return;
673
674 /*put emac in sw reset state*/
675 UNIMAC_WRITE_FIELD(emacNum,CMD,sw_reset,UNIMAC_SWRESET_ON );
676
677 READ_32(address,cfgreg);
678 cfgreg.max_pkt_size = maxTxFrameLen;
679 WRITE_32(address,cfgreg);
680
681 UNIMAC_WRITE_FIELD(emacNum,FRM_LEN,frame_length,UNIMAC_MAX_FRAME_LENGHT);
682
683 UNIMAC_WRITE_FIELD(emacNum,CMD,sw_reset,UNIMAC_SWRESET_OFF );
684 }
685 #else //!47622
686 void mac_hwapi_set_tx_max_frame_len(rdpa_emac emacNum,uint32_t maxTxFrameLen )
687 {
688
689 S_UNIMAC_TOP_CFG1_REG cfgreg;
690 uintptr_t address = (uintptr_t)UNIMAC_TOP_UNIMAC_MISC_UNIMAC_EXT_CFG1 + UNIMAC_MISC_INSTANCE_OFFSET(emacNum);
691
692 if (!(enabled_emac & (1 << emacNum)))
693 return;
694
695 /*put emac in sw reset state*/
696 UNIMAC_WRITE_FIELD(emacNum,CMD,sw_reset,UNIMAC_SWRESET_ON );
697
698 READ_32(address,cfgreg);
699 cfgreg.max_pkt_size = maxTxFrameLen;
700 WRITE_32(address,cfgreg);
701
702 UNIMAC_WRITE_FIELD(emacNum,FRM_LEN,frame_length,UNIMAC_MAX_FRAME_LENGHT);
703
704 UNIMAC_WRITE_FIELD(emacNum,CMD,sw_reset,UNIMAC_SWRESET_OFF );
705 }
706 #endif //!47622
707 EXPORT_SYMBOL(mac_hwapi_set_tx_max_frame_len);
708
709
710
711 /******************************************************************************/
712 /* */
713 /* Name: */
714 /* */
715 /* mac_hwapi_get_rx_max_frame_len */
716 /* */
717 /* Title: */
718 /* */
719 /* MAC Driver - get port RX MTU */
720 /* */
721 /* Abstract: */
722 /* */
723 /* get the port maximum receive unit size in bytes */
724 /* */
725 /* Input: */
726 /* */
727 /* emacNum - emac Port index */
728 /* */
729 /* */
730 /* Output: */
731 /* maxRxFrameLen - size of current MRU */
732 /* */
733 /******************************************************************************/
734 #if defined(CONFIG_BCM47622)
735 void mac_hwapi_get_rx_max_frame_len(rdpa_emac emacNum,uint32_t *maxRxFrameLen )
736 {
737 if (!(enabled_emac & (1 << emacNum)))
738 return;
739
740 UNIMAC_READ_FIELD(emacNum,FRM_LEN,frame_length,*maxRxFrameLen );
741 }
742 #else //!47622
743 void mac_hwapi_get_rx_max_frame_len(rdpa_emac emacNum,uint32_t *maxRxFrameLen )
744 {
745 if (!(enabled_emac & (1 << emacNum)))
746 return;
747
748 UNIMAC_READ_FIELD(emacNum,RX_MAX_PKT_SIZE,max_pkt_size,*maxRxFrameLen );
749 }
750 #endif //!47622
751 EXPORT_SYMBOL(mac_hwapi_get_rx_max_frame_len);
752
753
754
755 /******************************************************************************/
756 /* */
757 /* Name: */
758 /* */
759 /* mac_hwapi_set_rx_max_frame_len */
760 /* */
761 /* Title: */
762 /* */
763 /* MAC Driver - set port RX MTU */
764 /* */
765 /* Abstract: */
766 /* */
767 /* set the port maximum receive unit size in bytes */
768 /* */
769 /* Input: */
770 /* */
771 /* emacNum - emac Port index */
772 /* maxRxFrameLen - size of current MRU */
773 /* */
774 /* Output: */
775 /* */
776 /* */
777 /******************************************************************************/
778 #if defined(CONFIG_BCM47622)
779 void mac_hwapi_set_rx_max_frame_len(rdpa_emac emacNum,uint32_t maxRxFrameLen )
780 {
781 S_UNIMAC_TOPCTRL_MAX_PKT_SZ_REG cfgreg;
782 uintptr_t address = (uintptr_t)UNIMAC_TOPCTRL_MIB_MAX_PKT_SIZE + UNIMAC_TOPCTRL_INSTANCE_OFFSET(emacNum);
783
784 if (!(enabled_emac & (1 << emacNum)))
785 return;
786
787 /*put emac in sw reset state*/
788 UNIMAC_WRITE_FIELD(emacNum,CMD,sw_reset,UNIMAC_SWRESET_ON );
789
790 READ_32(address,cfgreg);
791 cfgreg.max_pkt_size = maxRxFrameLen;
792 WRITE_32(address,cfgreg);
793
794 UNIMAC_WRITE_FIELD(emacNum,FRM_LEN,frame_length,maxRxFrameLen);
795
796 UNIMAC_WRITE_FIELD(emacNum,CMD,sw_reset,UNIMAC_SWRESET_OFF );
797 }
798 #else //!47622
799 void mac_hwapi_set_rx_max_frame_len(rdpa_emac emacNum,uint32_t maxRxFrameLen )
800 {
801 S_UNIMAC_TOP_CFG1_REG cfgreg;
802 uintptr_t address = (uintptr_t)UNIMAC_TOP_UNIMAC_MISC_UNIMAC_EXT_CFG1 + UNIMAC_MISC_INSTANCE_OFFSET(emacNum);
803
804 if (!(enabled_emac & (1 << emacNum)))
805 return;
806
807 /*put emac in sw reset state*/
808 UNIMAC_WRITE_FIELD(emacNum,CMD,sw_reset,UNIMAC_SWRESET_ON );
809
810 READ_32(address,cfgreg);
811 cfgreg.max_pkt_size = maxRxFrameLen;
812 WRITE_32(address,cfgreg);
813
814 UNIMAC_WRITE_FIELD(emacNum,RX_MAX_PKT_SIZE,max_pkt_size,maxRxFrameLen);
815
816 /*put emac out sw reset state*/
817 UNIMAC_WRITE_FIELD(emacNum,CMD,sw_reset,UNIMAC_SWRESET_OFF );
818 }
819 #endif //!47622
820 EXPORT_SYMBOL(mac_hwapi_set_rx_max_frame_len);
821
822
823
824 /******************************************************************************/
825 /* */
826 /* Name: */
827 /* */
828 /* mac_hwapi_set_tx_igp_len */
829 /* */
830 /* Title: */
831 /* */
832 /* MAC Driver - set port inter frame gap */
833 /* */
834 /* Abstract: */
835 /* */
836 /* set the inter frame gap size in bytes */
837 /* */
838 /* Input: */
839 /* */
840 /* emacNum - emac Port index */
841 /* txIpgLen - length in bytes */
842 /* */
843 /* Output: */
844 /* */
845 /* */
846 /******************************************************************************/
847 void mac_hwapi_set_tx_igp_len(rdpa_emac emacNum,uint32_t txIpgLen )
848 {
849 /*we assume that txIpgLen called with bits time resolution*/
850 uint32_t newIpg;
851
852 if (!(enabled_emac & (1 << emacNum)))
853 return;
854
855 /*put emac in sw reset state*/
856 UNIMAC_WRITE_FIELD(emacNum,CMD,sw_reset,UNIMAC_SWRESET_ON );
857
858 txIpgLen += 7;
859 newIpg = txIpgLen / 8;
860
861 if (newIpg < 8)
862 {
863 newIpg = 8;
864 } else if (newIpg > 27)
865 {
866 newIpg = 27;
867 }
868 UNIMAC_WRITE_FIELD(emacNum,TX_IPG_LEN,tx_ipg_len,newIpg );
869
870 /*put emac out sw reset state*/
871 UNIMAC_WRITE_FIELD(emacNum,CMD,sw_reset,UNIMAC_SWRESET_OFF );
872
873 }
874 EXPORT_SYMBOL(mac_hwapi_set_tx_igp_len);
875
876
877
878 /******************************************************************************/
879 /* */
880 /* Name: */
881 /* */
882 /* mac_hwapi_get_tx_igp_len */
883 /* */
884 /* Title: */
885 /* */
886 /* MAC Driver - get port inter frame gap */
887 /* */
888 /* Abstract: */
889 /* */
890 /* get the inter frame gap size in bytes */
891 /* */
892 /* Input: */
893 /* */
894 /* emacNum - emac Port index */
895 /* */
896 /* */
897 /* Output: */
898 /* txIpgLen - length in bytes */
899 /* */
900 /******************************************************************************/
901 void mac_hwapi_get_tx_igp_len(rdpa_emac emacNum,uint32_t *txIpgLen )
902 {
903 if (!(enabled_emac & (1 << emacNum)))
904 return;
905
906 UNIMAC_READ_FIELD(emacNum,TX_IPG_LEN,tx_ipg_len,*txIpgLen );
907
908 }
909 EXPORT_SYMBOL(mac_hwapi_get_tx_igp_len);
910
911
912
913
914 /******************************************************************************/
915 /* */
916 /* Name: */
917 /* */
918 /* mac_hwapi_get_mac_status */
919 /* */
920 /* Title: */
921 /* */
922 /* MAC Driver - set port status */
923 /* */
924 /* Abstract: */
925 /* */
926 /* set the status of mac */
927 /* */
928 /* Input: */
929 /* */
930 /* emacNum - emac Port index */
931 /* */
932 /* */
933 /* Output: */
934 /* macStatus : */
935 /* */
936 /******************************************************************************/
937 void mac_hwapi_get_mac_status(rdpa_emac emacNum,S_HWAPI_MAC_STATUS *macStatus)
938 {
939
940 }
941 EXPORT_SYMBOL(mac_hwapi_get_mac_status);
942
943
944
945
946
947 /******************************************************************************/
948 /* */
949 /* Name: */
950 /* */
951 /* mac_hwapi_get_flow_control */
952 /* */
953 /* Title: */
954 /* */
955 /* MAC Driver - get port flow control */
956 /* */
957 /* Abstract: */
958 /* */
959 /* get the flow control of a port */
960 /* */
961 /* Input: */
962 /* */
963 /* emacNum - emac Port index */
964 /* */
965 /* */
966 /* Output: */
967 /* flowControl - structure with parameters of tx and rx flow control */
968 /* */
969 /******************************************************************************/
970 #if defined(CONFIG_BCM47622)
971 void mac_hwapi_get_flow_control(rdpa_emac emacNum,S_MAC_HWAPI_FLOW_CTRL *flowControl)
972 {
973 uint32_t rxFlow, txFlow;
974
975 if (!(enabled_emac & (1 << emacNum)))
976 return;
977
978 UNIMAC_READ_FIELD(emacNum,CMD,rx_pause_ignore,rxFlow);
979 UNIMAC_READ_FIELD(emacNum,CMD,tx_pause_ignore,txFlow);
980 flowControl->rxFlowEnable = !rxFlow;
981 flowControl->txFlowEnable = !txFlow;
982 }
983 #else //!47622
984 void mac_hwapi_get_flow_control(rdpa_emac emacNum,S_MAC_HWAPI_FLOW_CTRL *flowControl)
985 {
986 uint32_t rxFlow, txFlow, value;
987 uintptr_t misc_top_address;
988
989 if (!(enabled_emac & (1 << emacNum)))
990 return;
991
992 misc_top_address = (uintptr_t)UNIMAC_TOP_UNIMAC_MISC_UNIMAC_EXT_CFG2 + UNIMAC_MISC_INSTANCE_OFFSET(emacNum);
993 READ_32(misc_top_address, value);
994
995
996 if(value & UNIMAC_TOP_UNIMAC_MISC_UNIMAC_EXT_CFG2_BACKPRESSURE_ENABLE_INT)
997 {
998 UNIMAC_READ_FIELD(emacNum,CMD,rx_pause_ignore,rxFlow);
999 UNIMAC_READ_FIELD(emacNum,CMD,tx_pause_ignore,txFlow);
1000 flowControl->rxFlowEnable = !rxFlow;
1001 flowControl->txFlowEnable = !txFlow;
1002 }
1003 else
1004 {
1005 flowControl->rxFlowEnable = 0;
1006 flowControl->txFlowEnable = 0;
1007 }
1008 }
1009 #endif //!47622
1010 EXPORT_SYMBOL(mac_hwapi_get_flow_control);
1011 /******************************************************************************/
1012 /* */
1013 /* Name: */
1014 /* */
1015 /* mac_hwapi_set_pause_params */
1016 /* */
1017 /* Title: */
1018 /* */
1019 /* MAC Driver - set port flow control */
1020 /* */
1021 /* Abstract: */
1022 /* */
1023 /* set the flow control of a port */
1024 /* */
1025 /* Input: */
1026 /* */
1027 /* emacNum - emac Port index */
1028 /* flowControl - structure with parameters of tx and rx flow control */
1029 /* */
1030 /* Output: */
1031 /* */
1032 /* */
1033 /******************************************************************************/
1034 void mac_hwapi_set_pause_params(rdpa_emac emacNum,int32_t pauseCtrlEnable,uint32_t pauseTimer,uint32_t pauseQuanta)
1035 {
1036 if (!(enabled_emac & (1 << emacNum)))
1037 return;
1038
1039 UNIMAC_WRITE_FIELD(emacNum,PAUSE_CNTRL,pause_control_en,pauseCtrlEnable );
1040 UNIMAC_WRITE_FIELD(emacNum,PAUSE_CNTRL,pause_timer,pauseTimer );
1041 UNIMAC_WRITE_FIELD(emacNum,PAUSE_QUNAT,pause_quant,pauseQuanta );
1042 }
1043 EXPORT_SYMBOL(mac_hwapi_set_pause_params);
1044
1045
1046 /******************************************************************************/
1047 /* */
1048 /* Name: */
1049 /* */
1050 /* mac_hwapi_set_flow_control */
1051 /* */
1052 /* Title: */
1053 /* */
1054 /* MAC Driver - set port flow control */
1055 /* */
1056 /* Abstract: */
1057 /* */
1058 /* set the flow control of a port */
1059 /* */
1060 /* Input: */
1061 /* */
1062 /* emacNum - emac Port index */
1063 /* flowControl - structure with parameters of tx and rx flow control */
1064 /* */
1065 /* Output: */
1066 /* */
1067 /* */
1068 /******************************************************************************/
1069 #if defined(CONFIG_BCM47622)
1070 void mac_hwapi_set_flow_control(rdpa_emac emacNum,S_MAC_HWAPI_FLOW_CTRL *flowControl)
1071 {
1072 if (!(enabled_emac & (1 << emacNum)))
1073 return;
1074
1075 UNIMAC_WRITE_FIELD(emacNum,CMD,sw_override_rx, 1);
1076 UNIMAC_WRITE_FIELD(emacNum,CMD,sw_override_tx, 1);
1077
1078 UNIMAC_WRITE_FIELD(emacNum,CMD,rx_pause_ignore, !flowControl->rxFlowEnable);
1079 UNIMAC_WRITE_FIELD(emacNum,CMD,tx_pause_ignore, !flowControl->txFlowEnable);
1080 }
1081 #else //!47622
1082 void mac_hwapi_set_flow_control(rdpa_emac emacNum,S_MAC_HWAPI_FLOW_CTRL *flowControl)
1083 {
1084 uintptr_t misc_top_address;
1085 uint32_t value;
1086
1087 if (!(enabled_emac & (1 << emacNum)))
1088 return;
1089
1090 UNIMAC_WRITE_FIELD(emacNum,CMD,rx_pause_ignore, !flowControl->rxFlowEnable);
1091 UNIMAC_WRITE_FIELD(emacNum,CMD,tx_pause_ignore, !flowControl->txFlowEnable);
1092 misc_top_address = (uintptr_t)UNIMAC_TOP_UNIMAC_MISC_UNIMAC_EXT_CFG2 + UNIMAC_MISC_INSTANCE_OFFSET(emacNum);
1093 READ_32(misc_top_address, value);
1094
1095 if(flowControl->rxFlowEnable || flowControl->txFlowEnable)
1096 value |= UNIMAC_TOP_UNIMAC_MISC_UNIMAC_EXT_CFG2_BACKPRESSURE_ENABLE_INT;
1097 else
1098 value &= ~UNIMAC_TOP_UNIMAC_MISC_UNIMAC_EXT_CFG2_BACKPRESSURE_ENABLE_INT;
1099
1100 WRITE_32(misc_top_address, value);
1101 }
1102 #endif //!47622
1103 EXPORT_SYMBOL(mac_hwapi_set_flow_control);
1104
1105
1106 static rdpa_emac_rx_stat_t rxCountersLast[MAX_NUM_OF_EMACS];
1107 #define UNIMAC_CURRENT_RX_COUNTERS(emacNum, rxCounters, param) \
1108 do{\
1109 uint32_t paramCurrent = rxCounters->param; \
1110 if(mac_unlikely(rxCounters->param < rxCountersLast[emacNum].param)){ \
1111 rxCounters->param += (0xFFFFFFFF-rxCountersLast[emacNum].param)+1; \
1112 }else{ \
1113 rxCounters->param -= rxCountersLast[emacNum].param; \
1114 } \
1115 rxCountersLast[emacNum].param = paramCurrent; \
1116 }while(0)
1117
1118 /******************************************************************************/
1119 /* */
1120 /* Name: */
1121 /* */
1122 /* mac_hwapi_get_rx_counters */
1123 /* */
1124 /* Title: */
1125 /* */
1126 /* MAC Driver - get the rx counters of port */
1127 /* */
1128 /* Abstract: */
1129 /* */
1130 /* get the rx counters of port */
1131 /* */
1132 /* Input: */
1133 /* */
1134 /* emacNum - emac Port index */
1135 /* */
1136 /* */
1137 /* Output: */
1138 /* rxCounters : structure filled with counters */
1139 /* */
1140 /******************************************************************************/
1141 void mac_hwapi_get_rx_counters(rdpa_emac emacNum,rdpa_emac_rx_stat_t *rxCounters)
1142 {
1143 uint32_t tempVal;
1144
1145 if (!(enabled_emac & (1 << emacNum)))
1146 {
1147 memset(rxCounters, 0, sizeof(rdpa_emac_rx_stat_t));
1148 return;
1149 }
1150
1151 UNIMAC_READ32_MIB(emacNum,GRALN,rxCounters->alignment_error);
1152 UNIMAC_READ32_MIB(emacNum,GRBCA,rxCounters->broadcast_packet);
1153 UNIMAC_READ32_MIB(emacNum,GRUC, rxCounters->unicast_packet);
1154 UNIMAC_READ32_MIB(emacNum,GRBYT,rxCounters->byte);
1155 UNIMAC_READ32_MIB(emacNum,RRBYT,tempVal);
1156 rxCounters->byte += tempVal;
1157 UNIMAC_READ32_MIB(emacNum,GRFCR,rxCounters->carrier_sense_error);
1158 UNIMAC_READ32_MIB(emacNum,GRCDE,rxCounters->code_error);
1159 UNIMAC_READ32_MIB(emacNum,GRXCF,rxCounters->control_frame);
1160 UNIMAC_READ32_MIB(emacNum,GRFCS,rxCounters->fcs_error);
1161 rxCounters->fragments = 0;//?????
1162 UNIMAC_READ32_MIB(emacNum,GR255,rxCounters->frame_128_255);
1163 UNIMAC_READ32_MIB(emacNum,GR2047,tempVal);
1164 rxCounters->frame_1519_mtu = tempVal;
1165 UNIMAC_READ32_MIB(emacNum,GR4095,tempVal);
1166 rxCounters->frame_1519_mtu += tempVal;
1167 UNIMAC_READ32_MIB(emacNum,GR9216,tempVal);
1168 rxCounters->frame_1519_mtu += tempVal;
1169
1170 UNIMAC_READ32_MIB(emacNum,GR511,rxCounters->frame_256_511);
1171
1172 UNIMAC_READ32_MIB(emacNum,GR1023,rxCounters->frame_512_1023);
1173
1174 UNIMAC_READ32_MIB(emacNum,GR1518,rxCounters->frame_1024_1518);
1175
1176 UNIMAC_READ32_MIB(emacNum,GR64,rxCounters->frame_64);
1177
1178 UNIMAC_READ32_MIB(emacNum,GR127,rxCounters->frame_65_127);
1179
1180 UNIMAC_READ32_MIB(emacNum,GRFLR,rxCounters->frame_length_error);
1181
1182 UNIMAC_READ32_MIB(emacNum,GRJBR,rxCounters->jabber);
1183
1184 UNIMAC_READ32_MIB(emacNum,GRMCA,rxCounters->multicast_packet);
1185
1186 rxCounters->overflow = 0;//no matched counter
1187 UNIMAC_READ32_MIB(emacNum,GROVR,rxCounters->oversize_packet);
1188
1189 UNIMAC_READ32_MIB(emacNum,RRPKT,rxCounters->undersize_packet);
1190
1191 UNIMAC_READ32_MIB(emacNum,GRPKT,rxCounters->packet);
1192
1193 UNIMAC_READ32_MIB(emacNum,GRXPF,rxCounters->pause_control_frame);
1194
1195 UNIMAC_READ32_MIB(emacNum,GRXUO,rxCounters->unknown_opcode);
1196
1197 UNIMAC_CURRENT_RX_COUNTERS(emacNum, rxCounters, alignment_error);
1198 UNIMAC_CURRENT_RX_COUNTERS(emacNum, rxCounters, broadcast_packet);
1199 UNIMAC_CURRENT_RX_COUNTERS(emacNum, rxCounters, unicast_packet);
1200 UNIMAC_CURRENT_RX_COUNTERS(emacNum, rxCounters, byte);
1201 UNIMAC_CURRENT_RX_COUNTERS(emacNum, rxCounters, carrier_sense_error);
1202 UNIMAC_CURRENT_RX_COUNTERS(emacNum, rxCounters, code_error);
1203 UNIMAC_CURRENT_RX_COUNTERS(emacNum, rxCounters, control_frame);
1204 UNIMAC_CURRENT_RX_COUNTERS(emacNum, rxCounters, fcs_error);
1205 UNIMAC_CURRENT_RX_COUNTERS(emacNum, rxCounters, frame_64);
1206 UNIMAC_CURRENT_RX_COUNTERS(emacNum, rxCounters, frame_65_127);
1207 UNIMAC_CURRENT_RX_COUNTERS(emacNum, rxCounters, frame_128_255);
1208 UNIMAC_CURRENT_RX_COUNTERS(emacNum, rxCounters, frame_256_511);
1209 UNIMAC_CURRENT_RX_COUNTERS(emacNum, rxCounters, frame_512_1023);
1210 UNIMAC_CURRENT_RX_COUNTERS(emacNum, rxCounters, frame_1024_1518);
1211 UNIMAC_CURRENT_RX_COUNTERS(emacNum, rxCounters, frame_1519_mtu);
1212 UNIMAC_CURRENT_RX_COUNTERS(emacNum, rxCounters, frame_length_error);
1213 UNIMAC_CURRENT_RX_COUNTERS(emacNum, rxCounters, jabber);
1214 UNIMAC_CURRENT_RX_COUNTERS(emacNum, rxCounters, multicast_packet);
1215 UNIMAC_CURRENT_RX_COUNTERS(emacNum, rxCounters, oversize_packet);
1216 UNIMAC_CURRENT_RX_COUNTERS(emacNum, rxCounters, undersize_packet);
1217 UNIMAC_CURRENT_RX_COUNTERS(emacNum, rxCounters, packet);
1218 UNIMAC_CURRENT_RX_COUNTERS(emacNum, rxCounters, pause_control_frame);
1219 UNIMAC_CURRENT_RX_COUNTERS(emacNum, rxCounters, unknown_opcode);
1220 }
1221 EXPORT_SYMBOL(mac_hwapi_get_rx_counters);
1222
1223
1224 static rdpa_emac_tx_stat_t txCountersLast[MAX_NUM_OF_EMACS];
1225 #define UNIMAC_CURRENT_TX_COUNTERS(emacNum, txCounters, param) \
1226 do{\
1227 uint32_t paramCurrent = txCounters->param; \
1228 if(mac_unlikely(txCounters->param < txCountersLast[emacNum].param)){ \
1229 txCounters->param += (0xFFFFFFFF-txCountersLast[emacNum].param)+1; \
1230 }else{ \
1231 txCounters->param -= txCountersLast[emacNum].param; \
1232 } \
1233 txCountersLast[emacNum].param = paramCurrent; \
1234 }while(0)
1235
1236
1237 /******************************************************************************/
1238 /* */
1239 /* Name: */
1240 /* */
1241 /* mac_hwapi_get_tx_counters */
1242 /* */
1243 /* Title: */
1244 /* */
1245 /* MAC Driver - get the tx counters of port */
1246 /* */
1247 /* Abstract: */
1248 /* */
1249 /* get the tx counters of port */
1250 /* */
1251 /* Input: */
1252 /* */
1253 /* emacNum - emac Port index */
1254 /* */
1255 /* */
1256 /* Output: */
1257 /* txCounters : structure filled with counters */
1258 /* */
1259 /******************************************************************************/
1260 void mac_hwapi_get_tx_counters(rdpa_emac emacNum,rdpa_emac_tx_stat_t *txCounters)
1261 {
1262 /*fill the rdpa counters structure*/
1263 uint32_t tempVal;
1264
1265 if (!(enabled_emac & (1 << emacNum)))
1266 {
1267 memset(txCounters, 0, sizeof(rdpa_emac_tx_stat_t));
1268 return;
1269 }
1270
1271 UNIMAC_READ32_MIB(emacNum,GTBYT,txCounters->byte);
1272
1273 UNIMAC_READ32_MIB(emacNum,GTBCA,txCounters->broadcast_packet);
1274
1275 UNIMAC_READ32_MIB(emacNum,GTMCA, txCounters->multicast_packet);
1276
1277 UNIMAC_READ32_MIB(emacNum,GTUC, txCounters->unicast_packet);
1278
1279 UNIMAC_READ32_MIB(emacNum,GTXCF,txCounters->control_frame);
1280
1281 UNIMAC_READ32_MIB(emacNum,GTDRF,txCounters->deferral_packet);
1282
1283
1284 UNIMAC_READ32_MIB(emacNum,GTNCL,tempVal);
1285 txCounters->error = tempVal;
1286 UNIMAC_READ32_MIB(emacNum,GTOVR,tempVal);
1287 txCounters->error += tempVal;
1288 UNIMAC_READ32_MIB(emacNum,GTFCS,tempVal);
1289 txCounters->error += tempVal;
1290 UNIMAC_READ32_MIB(emacNum,GTEDF,txCounters->excessive_deferral_packet);
1291
1292 UNIMAC_READ32_MIB(emacNum,GTFCS,txCounters->fcs_error );
1293
1294 UNIMAC_READ32_MIB(emacNum,GTFRG,txCounters->fragments_frame);
1295
1296 UNIMAC_READ32_MIB(emacNum,TR1518,txCounters->frame_1024_1518);
1297
1298 UNIMAC_READ32_MIB(emacNum,TR255, txCounters->frame_128_255);
1299
1300 UNIMAC_READ32_MIB(emacNum,TR2047, tempVal);
1301 txCounters->frame_1519_mtu = tempVal;
1302 UNIMAC_READ32_MIB(emacNum,TR4095, tempVal);
1303 txCounters->frame_1519_mtu += tempVal;
1304 UNIMAC_READ32_MIB(emacNum,TR9216, tempVal);
1305 txCounters->frame_1519_mtu += tempVal;
1306 UNIMAC_READ32_MIB(emacNum,TR511, txCounters->frame_256_511);
1307
1308 UNIMAC_READ32_MIB(emacNum,TR1023, txCounters->frame_512_1023);
1309
1310 UNIMAC_READ32_MIB(emacNum,TR64,txCounters->frame_64);
1311
1312 UNIMAC_READ32_MIB(emacNum,TR127, txCounters->frame_65_127);
1313
1314 UNIMAC_READ32_MIB(emacNum,GTJBR, txCounters->jabber_frame);
1315
1316 UNIMAC_READ32_MIB(emacNum,GTLCL, txCounters->late_collision);
1317
1318 UNIMAC_READ32_MIB(emacNum,GTMCL, txCounters->multiple_collision);
1319
1320 UNIMAC_READ32_MIB(emacNum,GTOVR,txCounters->oversize_frame);
1321
1322 UNIMAC_READ32_MIB(emacNum,GTPOK, txCounters->packet);
1323
1324 UNIMAC_READ32_MIB(emacNum,GTXPF, txCounters->pause_control_frame);
1325
1326 UNIMAC_READ32_MIB(emacNum,GTSCL, txCounters->single_collision);
1327
1328 UNIMAC_READ32_MIB(emacNum,GTNCL, txCounters->total_collision);
1329
1330 UNIMAC_READ32_MIB(emacNum,GTXCL, txCounters->excessive_collision);
1331
1332 txCounters->underrun = 0;
1333 txCounters->undersize_frame = 0;
1334
1335 UNIMAC_CURRENT_TX_COUNTERS(emacNum, txCounters, byte);
1336 UNIMAC_CURRENT_TX_COUNTERS(emacNum, txCounters, packet);
1337 UNIMAC_CURRENT_TX_COUNTERS(emacNum, txCounters, broadcast_packet);
1338 UNIMAC_CURRENT_TX_COUNTERS(emacNum, txCounters, multicast_packet);
1339 UNIMAC_CURRENT_TX_COUNTERS(emacNum, txCounters, unicast_packet);
1340 UNIMAC_CURRENT_TX_COUNTERS(emacNum, txCounters, deferral_packet);
1341 UNIMAC_CURRENT_TX_COUNTERS(emacNum, txCounters, excessive_deferral_packet);
1342 UNIMAC_CURRENT_TX_COUNTERS(emacNum, txCounters, control_frame);
1343 UNIMAC_CURRENT_TX_COUNTERS(emacNum, txCounters, jabber_frame);
1344 UNIMAC_CURRENT_TX_COUNTERS(emacNum, txCounters, oversize_frame);
1345 UNIMAC_CURRENT_TX_COUNTERS(emacNum, txCounters, pause_control_frame);
1346 UNIMAC_CURRENT_TX_COUNTERS(emacNum, txCounters, fragments_frame);
1347 UNIMAC_CURRENT_TX_COUNTERS(emacNum, txCounters, error);
1348 UNIMAC_CURRENT_TX_COUNTERS(emacNum, txCounters, fcs_error);
1349 UNIMAC_CURRENT_TX_COUNTERS(emacNum, txCounters, frame_64);
1350 UNIMAC_CURRENT_TX_COUNTERS(emacNum, txCounters, frame_65_127);
1351 UNIMAC_CURRENT_TX_COUNTERS(emacNum, txCounters, frame_128_255);
1352 UNIMAC_CURRENT_TX_COUNTERS(emacNum, txCounters, frame_256_511);
1353 UNIMAC_CURRENT_TX_COUNTERS(emacNum, txCounters, frame_512_1023);
1354 UNIMAC_CURRENT_TX_COUNTERS(emacNum, txCounters, frame_1024_1518);
1355 UNIMAC_CURRENT_TX_COUNTERS(emacNum, txCounters, frame_1519_mtu);
1356 UNIMAC_CURRENT_TX_COUNTERS(emacNum, txCounters, single_collision);
1357 UNIMAC_CURRENT_TX_COUNTERS(emacNum, txCounters, total_collision);
1358 UNIMAC_CURRENT_TX_COUNTERS(emacNum, txCounters, late_collision);
1359 UNIMAC_CURRENT_TX_COUNTERS(emacNum, txCounters, multiple_collision);
1360 UNIMAC_CURRENT_TX_COUNTERS(emacNum, txCounters, excessive_collision);
1361 }
1362 EXPORT_SYMBOL(mac_hwapi_get_tx_counters);
1363 /******************************************************************************/
1364 /* */
1365 /* Name: */
1366 /* */
1367 /* mac_hwapi_init_emac */
1368 /* */
1369 /* Title: */
1370 /* */
1371 /* MAC Driver - init the emac to well known state */
1372 /* */
1373 /* Abstract: */
1374 /* */
1375 /* initialized the emac port */
1376 /* */
1377 /* Input: */
1378 /* */
1379 /* emacNum - emac Port index */
1380 /* */
1381 /* */
1382 /* Output: */
1383 /* */
1384 /******************************************************************************/
1385 void mac_hwapi_init_emac(rdpa_emac emacNum)
1386 {
1387 /*configure the emac and put it in automatic speed mode*/
1388 S_UNIMAC_CMD_REG mCfgReg;
1389 uint32_t max_frame_length = UNIMAC_MAX_FRAME_LENGHT;
1390
1391 #if defined(CONFIG_BCM4908)
1392 soc_base_address = RDP_BASE;
1393 #endif
1394
1395 /*before calling this function make sure you pull out of reset the emac */
1396
1397 /*put the emac in sw_reset state*/
1398 //UNIMAC_WRITE_FIELD(emacNum,CMD,sw_reset,UNIMAC_SWRESET_ON);
1399
1400 UNIMAC_READ32_REG(emacNum,CMD,mCfgReg);
1401 /* Do the initialization */
1402 #ifndef CONFIG_BRCM_QEMU
1403 mCfgReg.tx_ena = 0;
1404 mCfgReg.rx_ena = 0;
1405 #else
1406 printk("%s RX TX Enable no PHY EXIST\n",__FUNCTION__);
1407 mCfgReg.tx_ena = 1;
1408 mCfgReg.rx_ena = 1;
1409
1410 #endif
1411 /* for 63138 - even though the EMAC_1 is connected to SF2 @ 2Gbps, we still set the link to 1G.
1412 * Actual speed of the link is derived from SF2 based on the speed set for IMP port#8. */
1413 mCfgReg.eth_speed = UNIMAC_SPEED_1000;
1414 mCfgReg.promis_en = 1;
1415 mCfgReg.pad_en = 0;
1416 mCfgReg.pause_fwd = 1;
1417 mCfgReg.crc_fwd = 1;
1418 mCfgReg.ena_ext_config = 0;
1419 mCfgReg.rx_pause_ignore = 0;
1420 mCfgReg.tx_pause_ignore = 0;
1421 mCfgReg.tx_addr_ins = 0;
1422 mCfgReg.lcl_loop_ena = 0;
1423 mCfgReg.cntl_frm_ena = 1;
1424 mCfgReg.no_lgth_check = 1;
1425 mCfgReg.rmt_loop_ena = 0;
1426 mCfgReg.rx_err_disc = 0;
1427 mCfgReg.prbl_ena = 0;
1428 mCfgReg.cntl_frm_ena = 1;
1429
1430 /*write the configuration */
1431 UNIMAC_WRITE32_REG(emacNum,CMD,mCfgReg);
1432 UNIMAC_WRITE32_REG(emacNum,FRM_LEN, max_frame_length);
1433
1434 /*take out the emac from sw_reset state*/
1435 //UNIMAC_WRITE_FIELD(emacNum,CMD,sw_reset,UNIMAC_SWRESET_OFF);
1436 #if 0
1437 /*configure the pause control*/
1438 UNIMAC_WRITE_FIELD(emacNum,PAUSE_CNTRL,pause_timer,UNIMAC_DEFAULT_PAUSE_TIMER);
1439 UNIMAC_WRITE_FIELD(emacNum,PAUSE_CNTRL,pause_control_en,1);
1440
1441 /*configure the pause quanta*/
1442 UNIMAC_WRITE_FIELD(emacNum,PAUSE_QUNAT,pause_quant,UNIMAC_DEFAULT_PAUSE_QUANTA);
1443
1444 /*write default ipg*/
1445 UNIMAC_WRITE_FIELD(emacNum,TX_IPG_LEN,tx_ipg_len,UNIMAC_DEFAULT_IPG);
1446 #endif
1447 memset(&rxCountersLast, 0, MAX_NUM_OF_EMACS*sizeof(rdpa_emac_rx_stat_t));
1448 memset(&txCountersLast, 0, MAX_NUM_OF_EMACS*sizeof(rdpa_emac_tx_stat_t));
1449
1450 enabled_emac |= (1 << emacNum);
1451
1452 /*emac is ready to go!*/
1453 }
1454 EXPORT_SYMBOL(mac_hwapi_init_emac);
1455 /******************************************************************************/
1456 /* */
1457 /* Name: */
1458 /* */
1459 /* mac_hwapi_get_loopback */
1460 /* */
1461 /* Title: */
1462 /* */
1463 /* MAC Driver - init the emac to well known state */
1464 /* */
1465 /* Abstract: */
1466 /* */
1467 /* initialized the emac port */
1468 /* */
1469 /* Input: */
1470 /* */
1471 /* emacNum - emac Port index */
1472 /* */
1473 /* */
1474 /* Output: */
1475 /* */
1476 /******************************************************************************/
1477 void mac_hwapi_get_loopback(rdpa_emac emacNum,MAC_LPBK *loopback)
1478 {
1479 S_UNIMAC_CMD_REG mCmdReg;
1480
1481 if (!(enabled_emac & (1 << emacNum)))
1482 return;
1483
1484 UNIMAC_READ32_REG(emacNum,CMD,mCmdReg);
1485
1486 if (mCmdReg.lcl_loop_ena && mCmdReg.rmt_loop_ena)
1487 {
1488 *loopback = MAC_LPBK_BOTH;
1489 }
1490 else if (mCmdReg.lcl_loop_ena)
1491 {
1492 *loopback = MAC_LPBK_LOCAL;
1493 }
1494 else if (mCmdReg.rmt_loop_ena)
1495 {
1496 *loopback = MAC_LPBK_REMOTE;
1497 }
1498 else
1499 {
1500 *loopback = MAC_LPBK_NONE;
1501 }
1502
1503 }
1504 EXPORT_SYMBOL(mac_hwapi_get_loopback);
1505
1506
1507 /******************************************************************************/
1508 /* */
1509 /* Name: */
1510 /* */
1511 /* mac_hwapi_set_loopback */
1512 /* */
1513 /* Title: */
1514 /* */
1515 /* MAC Driver - set loopback type of the mac */
1516 /* */
1517 /* Abstract: */
1518 /* */
1519 /* initialized the emac port */
1520 /* */
1521 /* Input: */
1522 /* */
1523 /* emacNum - emac Port index */
1524 /* */
1525 /* */
1526 /* Output: */
1527 /* */
1528 /******************************************************************************/
1529 void mac_hwapi_set_loopback(rdpa_emac emacNum,MAC_LPBK loopback)
1530 {
1531 if (!(enabled_emac & (1 << emacNum)))
1532 return;
1533
1534 /*put the emac in sw_reset state*/
1535 UNIMAC_WRITE_FIELD(emacNum,CMD,sw_reset,UNIMAC_SWRESET_ON);
1536
1537 switch(loopback)
1538 {
1539 case MAC_LPBK_BOTH:
1540 UNIMAC_WRITE_FIELD(emacNum,CMD,rmt_loop_ena,1);
1541 UNIMAC_WRITE_FIELD(emacNum,CMD, lcl_loop_ena,1);
1542 break;
1543 case MAC_LPBK_LOCAL:
1544 UNIMAC_WRITE_FIELD(emacNum,CMD, lcl_loop_ena,1);
1545 break;
1546 case MAC_LPBK_REMOTE:
1547 UNIMAC_WRITE_FIELD(emacNum,CMD,rmt_loop_ena,1);
1548 break;
1549 case MAC_LPBK_NONE:
1550 UNIMAC_WRITE_FIELD(emacNum,CMD,rmt_loop_ena,0);
1551 UNIMAC_WRITE_FIELD(emacNum,CMD, lcl_loop_ena,0);
1552 break;
1553 default:
1554
1555 break;
1556 }
1557 /* take out the emac from sw_reset state*/
1558 UNIMAC_WRITE_FIELD(emacNum,CMD,sw_reset,UNIMAC_SWRESET_OFF);
1559
1560 }
1561 EXPORT_SYMBOL(mac_hwapi_set_loopback);
1562
1563 #if !defined(CONFIG_BCM47622)
1564 void mac_hwapi_set_unimac_cfg(rdpa_emac emacNum, int32_t enabled)
1565 {
1566 S_UNIMAC_CFG_REG cfgreg;
1567 uintptr_t address = (uintptr_t)UNIMAC_TOP_UNIMAC_MISC_UNIMAC_CFG + UNIMAC_MISC_INSTANCE_OFFSET(emacNum);
1568
1569 if (!(enabled_emac & (1 << emacNum)))
1570 return;
1571
1572 READ_32(address,cfgreg);
1573 cfgreg.gmii_direct = enabled ? 1 : 0;
1574 WRITE_32(address,cfgreg);
1575 }
1576 EXPORT_SYMBOL(mac_hwapi_set_unimac_cfg);
1577 #endif //!47622
1578
1579 void mac_hwapi_modify_flow_control_pause_pkt_addr ( rdpa_emac emacNum,bdmf_mac_t mac)
1580 {
1581 uint32_t value = *(uint32_t*)(&(mac.b[4])) >> 16 ;
1582 uintptr_t mac_address = (uintptr_t)UNIMAC_CONFIGURATION_UMAC_0_RDP_MAC0 + UNIMAC_CONF_INSTANCE_OFFSET(emacNum);
1583
1584 if (!(enabled_emac & (1 << emacNum)))
1585 return;
1586
1587 WRITE_32(mac_address, *(uint32_t*)mac.b);
1588
1589 mac_address = (uintptr_t)UNIMAC_CONFIGURATION_UMAC_0_RDP_MAC1 + UNIMAC_CONF_INSTANCE_OFFSET(emacNum);
1590 WRITE_32(mac_address, value);
1591
1592 }
1593 EXPORT_SYMBOL(mac_hwapi_modify_flow_control_pause_pkt_addr);
1594
1595 #if !defined(CONFIG_BCM47622)
1596 void mac_hwapi_set_backpressure_ext(rdpa_emac emacNum,int32_t enable)
1597 {
1598 #if defined(CONFIG_BCM63138) || defined(CONFIG_BCM63148) || defined(CONFIG_BCM4908) || defined(CONFIG_BCM63158)
1599 S_UNIMAC_TOP_CFG2_REG cfgreg;
1600 uintptr_t misc_top_address = (uintptr_t)UNIMAC_TOP_UNIMAC_MISC_UNIMAC_EXT_CFG2 + UNIMAC_MISC_INSTANCE_OFFSET(emacNum);
1601
1602 if (!(enabled_emac & (1 << emacNum)))
1603 return;
1604
1605 READ_32(misc_top_address,cfgreg);
1606 cfgreg.backpressure_enable_ext = (enable ? 1 : 0);
1607 WRITE_32(misc_top_address,cfgreg);
1608 #endif
1609 }
1610 EXPORT_SYMBOL(mac_hwapi_set_backpressure_ext);
1611 #endif //!47622
1612
1613 void mac_hwapi_set_eee(rdpa_emac emacNum, int32_t enable)
1614 {
1615 uint32_t eee_ref_count = 0;
1616 uint32_t eee_wake_timer = 0;
1617 uint32_t eee_lpi_timer = 0;
1618
1619 S_UNIMAC_EEE_CTRL_REG eee_ctrl;
1620 S_HWAPI_MAC_STATUS mac_mode;
1621
1622 /* Determine EEE timers only when EEE is enabled */
1623 if (enable)
1624 {
1625 #if defined(CONFIG_BCM63158) || defined(CONFIG_BCM6856) || defined(CONFIG_BCM47622) || defined(CONFIG_BCM6878)
1626 eee_ref_count = 0xfa; /* 250 Mhz */;
1627 #else
1628 get_rdp_freq(&eee_ref_count);
1629 eee_ref_count /= 2;
1630 #endif
1631
1632 /* Read actual mac speed */
1633 UNIMAC_READ32_REG(emacNum, MODE, mac_mode);
1634
1635 switch (mac_mode.mac_speed) {
1636 case rdpa_emac_rate_100m: /* 100Mbps */
1637 {
1638 eee_lpi_timer = 0x3c; /* 60 uS */
1639 eee_wake_timer = 0x1e; /* 30 uS */
1640 break;
1641 }
1642 case rdpa_emac_rate_1g: /* 1000Mbps */
1643 {
1644 eee_lpi_timer = 0x22; /* 34 uS */
1645 eee_wake_timer = 0x11; /* 17 uS */
1646 break;
1647 }
1648 case rdpa_emac_rate_2_5g: /* 2500Mbps */
1649 {
1650 eee_lpi_timer = 0x3c; /* 60 uS */
1651 eee_wake_timer = 0x1e; /* 30 uS */
1652 break;
1653 }
1654 default:
1655 break;
1656 }
1657 }
1658
1659 UNIMAC_READ32_REG(emacNum, EEE_CTRL, eee_ctrl);
1660 eee_ctrl.eee_en = enable ? 1 : 0;
1661 UNIMAC_WRITE32_REG(emacNum, EEE_CTRL, eee_ctrl);
1662 UNIMAC_WRITE32_REG(emacNum, EEE_REF_COUNT, eee_ref_count);
1663
1664 #if defined(CONFIG_BCM6856)
1665 if (mac_mode.mac_speed == rdpa_emac_rate_100m)
1666 {
1667 UNIMAC_WRITE32_REG(emacNum, EEE_MII_LPI_TIMER, eee_lpi_timer);
1668 UNIMAC_WRITE32_REG(emacNum, EEE_MII_WAKE_TIMER, eee_wake_timer);
1669 }
1670 else
1671 {
1672 UNIMAC_WRITE32_REG(emacNum, EEE_GMII_LPI_TIMER, eee_lpi_timer);
1673 UNIMAC_WRITE32_REG(emacNum, EEE_GMII_WAKE_TIMER, eee_wake_timer);
1674 }
1675 #else
1676 UNIMAC_WRITE32_REG(emacNum, EEE_LPI_TIMER, eee_lpi_timer);
1677 UNIMAC_WRITE32_REG(emacNum, EEE_WAKE_TIMER, eee_wake_timer);
1678 #endif
1679 }
1680 EXPORT_SYMBOL(mac_hwapi_set_eee);