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
30#include <common.h>
31#include <net.h>
32#include <malloc.h>
33
34#include "mv_eth.h"
35
36
37
38#undef DEBUG_MV_ETH
39
40#ifdef DEBUG_MV_ETH
41#define DEBUG
42#define DP(x) x
43#else
44#define DP(x)
45#endif
46
47#undef MV64460_CHECKSUM_OFFLOAD
48
49
50
51
52
53
54
55
56
57
58#undef MV64460_RX_QUEUE_FILL_ON_TASK
59
60
61
62#define MAGIC_ETH_RUNNING 8031971
63#define MV64460_INTERNAL_SRAM_SIZE _256K
64#define EXTRA_BYTES 32
65#define WRAP ETH_HLEN + 2 + 4 + 16
66#define BUFFER_MTU dev->mtu + WRAP
67#define INT_CAUSE_UNMASK_ALL 0x0007ffff
68#define INT_CAUSE_UNMASK_ALL_EXT 0x0011ffff
69#ifdef MV64460_RX_FILL_ON_TASK
70#define INT_CAUSE_MASK_ALL 0x00000000
71#define INT_CAUSE_CHECK_BITS INT_CAUSE_UNMASK_ALL
72#define INT_CAUSE_CHECK_BITS_EXT INT_CAUSE_UNMASK_ALL_EXT
73#endif
74
75
76#define MV_REG_READ(offset) my_le32_to_cpu(* (volatile unsigned int *) (INTERNAL_REG_BASE_ADDR + offset))
77#define MV_REG_WRITE(offset,data) *(volatile unsigned int *) (INTERNAL_REG_BASE_ADDR + offset) = my_cpu_to_le32 (data)
78#define MV_SET_REG_BITS(regOffset,bits) ((*((volatile unsigned int*)((INTERNAL_REG_BASE_ADDR) + (regOffset)))) |= ((unsigned int)my_cpu_to_le32(bits)))
79#define MV_RESET_REG_BITS(regOffset,bits) ((*((volatile unsigned int*)((INTERNAL_REG_BASE_ADDR) + (regOffset)))) &= ~((unsigned int)my_cpu_to_le32(bits)))
80
81
82static int mv64460_eth_real_open (struct eth_device *eth);
83static int mv64460_eth_real_stop (struct eth_device *eth);
84static struct net_device_stats *mv64460_eth_get_stats (struct eth_device
85 *dev);
86static void eth_port_init_mac_tables (ETH_PORT eth_port_num);
87static void mv64460_eth_update_stat (struct eth_device *dev);
88bool db64460_eth_start (struct eth_device *eth);
89unsigned int eth_read_mib_counter (ETH_PORT eth_port_num,
90 unsigned int mib_offset);
91int mv64460_eth_receive (struct eth_device *dev);
92
93int mv64460_eth_xmit (struct eth_device *, volatile void *packet, int length);
94
95#ifndef UPDATE_STATS_BY_SOFTWARE
96static void mv64460_eth_print_stat (struct eth_device *dev);
97#endif
98
99extern void NetReceive (volatile uchar *, int);
100
101extern unsigned int INTERNAL_REG_BASE_ADDR;
102
103
104
105
106#ifdef DEBUG_MV_ETH
107void print_globals (struct eth_device *dev)
108{
109 printf ("Ethernet PRINT_Globals-Debug function\n");
110 printf ("Base Address for ETH_PORT_INFO: %08x\n",
111 (unsigned int) dev->priv);
112 printf ("Base Address for mv64460_eth_priv: %08x\n",
113 (unsigned int) &(((ETH_PORT_INFO *) dev->priv)->
114 port_private));
115
116 printf ("GT Internal Base Address: %08x\n",
117 INTERNAL_REG_BASE_ADDR);
118 printf ("Base Address for TX-DESCs: %08x Number of allocated Buffers %d\n", (unsigned int) ((ETH_PORT_INFO *) dev->priv)->p_tx_desc_area_base[0], MV64460_TX_QUEUE_SIZE);
119 printf ("Base Address for RX-DESCs: %08x Number of allocated Buffers %d\n", (unsigned int) ((ETH_PORT_INFO *) dev->priv)->p_rx_desc_area_base[0], MV64460_RX_QUEUE_SIZE);
120 printf ("Base Address for RX-Buffer: %08x allocated Bytes %d\n",
121 (unsigned int) ((ETH_PORT_INFO *) dev->priv)->
122 p_rx_buffer_base[0],
123 (MV64460_RX_QUEUE_SIZE * MV64460_RX_BUFFER_SIZE) + 32);
124 printf ("Base Address for TX-Buffer: %08x allocated Bytes %d\n",
125 (unsigned int) ((ETH_PORT_INFO *) dev->priv)->
126 p_tx_buffer_base[0],
127 (MV64460_TX_QUEUE_SIZE * MV64460_TX_BUFFER_SIZE) + 32);
128}
129#endif
130
131#define my_cpu_to_le32(x) my_le32_to_cpu((x))
132
133unsigned long my_le32_to_cpu (unsigned long x)
134{
135 return (((x & 0x000000ffU) << 24) |
136 ((x & 0x0000ff00U) << 8) |
137 ((x & 0x00ff0000U) >> 8) | ((x & 0xff000000U) >> 24));
138}
139
140
141
142
143
144
145
146
147
148
149
150static void mv64460_eth_print_phy_status (struct eth_device *dev)
151{
152 struct mv64460_eth_priv *port_private;
153 unsigned int port_num;
154 ETH_PORT_INFO *ethernet_private = (ETH_PORT_INFO *) dev->priv;
155 unsigned int port_status, phy_reg_data;
156
157 port_private =
158 (struct mv64460_eth_priv *) ethernet_private->port_private;
159 port_num = port_private->port_num;
160
161
162 eth_port_read_smi_reg (port_num, 1, &phy_reg_data);
163 if (!(phy_reg_data & 0x20)) {
164 printf ("Ethernet port changed link status to DOWN\n");
165 } else {
166 port_status =
167 MV_REG_READ (MV64460_ETH_PORT_STATUS_REG (port_num));
168 printf ("Ethernet status port %d: Link up", port_num);
169 printf (", %s",
170 (port_status & BIT2) ? "Full Duplex" : "Half Duplex");
171 if (port_status & BIT4)
172 printf (", Speed 1 Gbps");
173 else
174 printf (", %s",
175 (port_status & BIT5) ? "Speed 100 Mbps" :
176 "Speed 10 Mbps");
177 printf ("\n");
178 }
179}
180
181
182
183
184
185int db64460_eth_probe (struct eth_device *dev)
186{
187 return ((int) db64460_eth_start (dev));
188}
189
190int db64460_eth_poll (struct eth_device *dev)
191{
192 return mv64460_eth_receive (dev);
193}
194
195int db64460_eth_transmit (struct eth_device *dev, volatile void *packet,
196 int length)
197{
198 mv64460_eth_xmit (dev, packet, length);
199 return 0;
200}
201
202void db64460_eth_disable (struct eth_device *dev)
203{
204 mv64460_eth_stop (dev);
205}
206
207
208void mv6446x_eth_initialize (bd_t * bis)
209{
210 struct eth_device *dev;
211 ETH_PORT_INFO *ethernet_private;
212 struct mv64460_eth_priv *port_private;
213 int devnum, x, temp;
214 char *s, *e, buf[64];
215
216 for (devnum = 0; devnum < MV_ETH_DEVS; devnum++) {
217 dev = calloc (sizeof (*dev), 1);
218 if (!dev) {
219 printf ("%s: mv_enet%d allocation failure, %s\n",
220 __FUNCTION__, devnum, "eth_device structure");
221 return;
222 }
223
224
225 sprintf (dev->name, "mv_enet%d", devnum);
226
227#ifdef DEBUG
228 printf ("Initializing %s\n", dev->name);
229#endif
230
231
232 switch (devnum) {
233 case 0:
234 s = "ethaddr";
235 break;
236
237 case 1:
238 s = "eth1addr";
239 break;
240
241 case 2:
242 s = "eth2addr";
243 break;
244
245 default:
246 printf ("%s: Invalid device number %d\n",
247 __FUNCTION__, devnum);
248 return;
249 }
250
251 temp = getenv_f(s, buf, sizeof (buf));
252 s = (temp > 0) ? buf : NULL;
253
254#ifdef DEBUG
255 printf ("Setting MAC %d to %s\n", devnum, s);
256#endif
257 for (x = 0; x < 6; ++x) {
258 dev->enetaddr[x] = s ? simple_strtoul (s, &e, 16) : 0;
259 if (s)
260 s = (*e) ? e + 1 : e;
261 }
262
263 eth_port_uc_addr_set (devnum, dev->enetaddr, 0);
264
265 dev->init = (void *) db64460_eth_probe;
266 dev->halt = (void *) ethernet_phy_reset;
267 dev->send = (void *) db64460_eth_transmit;
268 dev->recv = (void *) db64460_eth_poll;
269
270 ethernet_private = calloc (sizeof (*ethernet_private), 1);
271 dev->priv = (void *)ethernet_private;
272 if (!ethernet_private) {
273 printf ("%s: %s allocation failure, %s\n",
274 __FUNCTION__, dev->name,
275 "Private Device Structure");
276 free (dev);
277 return;
278 }
279
280 memset (ethernet_private, 0, sizeof (ETH_PORT_INFO));
281 memcpy (ethernet_private->port_mac_addr, dev->enetaddr, 6);
282
283
284 port_private = calloc (sizeof (*ethernet_private), 1);
285 ethernet_private->port_private = (void *)port_private;
286 if (!port_private) {
287 printf ("%s: %s allocation failure, %s\n",
288 __FUNCTION__, dev->name,
289 "Port Private Device Structure");
290
291 free (ethernet_private);
292 free (dev);
293 return;
294 }
295
296 port_private->stats =
297 calloc (sizeof (struct net_device_stats), 1);
298 if (!port_private->stats) {
299 printf ("%s: %s allocation failure, %s\n",
300 __FUNCTION__, dev->name,
301 "Net stat Structure");
302
303 free (port_private);
304 free (ethernet_private);
305 free (dev);
306 return;
307 }
308 memset (ethernet_private->port_private, 0,
309 sizeof (struct mv64460_eth_priv));
310 switch (devnum) {
311 case 0:
312 ethernet_private->port_num = ETH_0;
313 break;
314 case 1:
315 ethernet_private->port_num = ETH_1;
316 break;
317 case 2:
318 ethernet_private->port_num = ETH_2;
319 break;
320 default:
321 printf ("Invalid device number %d\n", devnum);
322 break;
323 };
324
325 port_private->port_num = devnum;
326
327
328
329
330 mv64460_eth_update_stat (dev);
331 memset (port_private->stats, 0,
332 sizeof (struct net_device_stats));
333
334 switch (devnum) {
335 case 0:
336 s = "ethaddr";
337 break;
338
339 case 1:
340 s = "eth1addr";
341 break;
342
343 case 2:
344 s = "eth2addr";
345 break;
346
347 default:
348 printf ("%s: Invalid device number %d\n",
349 __FUNCTION__, devnum);
350 return;
351 }
352
353 temp = getenv_f(s, buf, sizeof (buf));
354 s = (temp > 0) ? buf : NULL;
355
356#ifdef DEBUG
357 printf ("Setting MAC %d to %s\n", devnum, s);
358#endif
359 for (x = 0; x < 6; ++x) {
360 dev->enetaddr[x] = s ? simple_strtoul (s, &e, 16) : 0;
361 if (s)
362 s = (*e) ? e + 1 : e;
363 }
364
365 DP (printf ("Allocating descriptor and buffer rings\n"));
366
367 ethernet_private->p_rx_desc_area_base[0] =
368 (ETH_RX_DESC *) memalign (16,
369 RX_DESC_ALIGNED_SIZE *
370 MV64460_RX_QUEUE_SIZE + 1);
371 ethernet_private->p_tx_desc_area_base[0] =
372 (ETH_TX_DESC *) memalign (16,
373 TX_DESC_ALIGNED_SIZE *
374 MV64460_TX_QUEUE_SIZE + 1);
375
376 ethernet_private->p_rx_buffer_base[0] =
377 (char *) memalign (16,
378 MV64460_RX_QUEUE_SIZE *
379 MV64460_TX_BUFFER_SIZE + 1);
380 ethernet_private->p_tx_buffer_base[0] =
381 (char *) memalign (16,
382 MV64460_RX_QUEUE_SIZE *
383 MV64460_TX_BUFFER_SIZE + 1);
384
385#ifdef DEBUG_MV_ETH
386
387 print_globals (dev);
388#endif
389 eth_register (dev);
390
391 }
392 DP (printf ("%s: exit\n", __FUNCTION__));
393
394}
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410int mv64460_eth_open (struct eth_device *dev)
411{
412 return (mv64460_eth_real_open (dev));
413}
414
415
416static int mv64460_eth_real_open (struct eth_device *dev)
417{
418
419 unsigned int queue;
420 ETH_PORT_INFO *ethernet_private;
421 struct mv64460_eth_priv *port_private;
422 unsigned int port_num;
423 u32 phy_reg_data;
424
425 ethernet_private = (ETH_PORT_INFO *) dev->priv;
426
427
428 memcpy (ethernet_private->port_mac_addr, dev->enetaddr, 6);
429
430 port_private =
431 (struct mv64460_eth_priv *) ethernet_private->port_private;
432 port_num = port_private->port_num;
433
434
435 MV_REG_WRITE (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG (port_num),
436 0x0000ff00);
437
438
439 MV_REG_WRITE (MV64460_ETH_INTERRUPT_CAUSE_REG (port_num), 0);
440 MV_REG_WRITE (MV64460_ETH_INTERRUPT_CAUSE_EXTEND_REG (port_num), 0);
441
442
443 MV_REG_WRITE (MV64460_ETH_INTERRUPT_MASK_REG (port_num),
444 INT_CAUSE_UNMASK_ALL);
445
446
447 MV_REG_WRITE (MV64460_ETH_INTERRUPT_EXTEND_MASK_REG (port_num),
448 INT_CAUSE_UNMASK_ALL_EXT);
449
450
451 ethernet_private->port_phy_addr = 0x8 + port_num;
452
453
454 eth_port_init (ethernet_private);
455
456
457
458
459 for (queue = 0; queue < MV64460_TX_QUEUE_NUM; queue++) {
460 unsigned int size;
461
462 port_private->tx_ring_size[queue] = MV64460_TX_QUEUE_SIZE;
463 size = (port_private->tx_ring_size[queue] * TX_DESC_ALIGNED_SIZE);
464 ethernet_private->tx_desc_area_size[queue] = size;
465
466
467 memset ((void *) ethernet_private->p_tx_desc_area_base[queue],
468 0, ethernet_private->tx_desc_area_size[queue]);
469
470
471 if (ether_init_tx_desc_ring
472 (ethernet_private, ETH_Q0,
473 port_private->tx_ring_size[queue],
474 MV64460_TX_BUFFER_SIZE ,
475 (unsigned int) ethernet_private->
476 p_tx_desc_area_base[queue],
477 (unsigned int) ethernet_private->
478 p_tx_buffer_base[queue]) == false)
479 printf ("### Error initializing TX Ring\n");
480 }
481
482
483 for (queue = 0; queue < MV64460_RX_QUEUE_NUM; queue++) {
484 unsigned int size;
485
486
487 port_private->rx_ring_size[queue] = MV64460_RX_QUEUE_SIZE;
488 size = (port_private->rx_ring_size[queue] *
489 RX_DESC_ALIGNED_SIZE);
490 ethernet_private->rx_desc_area_size[queue] = size;
491
492
493 memset ((void *) ethernet_private->p_rx_desc_area_base[queue],
494 0, ethernet_private->rx_desc_area_size[queue]);
495 if ((ether_init_rx_desc_ring
496 (ethernet_private, ETH_Q0,
497 port_private->rx_ring_size[queue],
498 MV64460_RX_BUFFER_SIZE ,
499 (unsigned int) ethernet_private->
500 p_rx_desc_area_base[queue],
501 (unsigned int) ethernet_private->
502 p_rx_buffer_base[queue])) == false)
503 printf ("### Error initializing RX Ring\n");
504 }
505
506 eth_port_start (ethernet_private);
507
508
509 MV_REG_WRITE (MV64460_ETH_PORT_SERIAL_CONTROL_REG (port_num),
510 (0x5 << 17) |
511 (MV_REG_READ
512 (MV64460_ETH_PORT_SERIAL_CONTROL_REG (port_num))
513 & 0xfff1ffff));
514
515
516
517
518
519
520 MV_REG_WRITE (MV64460_ETH_MAXIMUM_TRANSMIT_UNIT (port_num), 0);
521 MV_REG_READ (MV64460_ETH_PORT_STATUS_REG (port_num));
522
523
524 eth_port_read_smi_reg (port_num, 1, &phy_reg_data);
525 if (!(phy_reg_data & 0x20)) {
526
527 if ((ethernet_phy_reset (port_num)) != true) {
528 printf ("$$ Warnning: No link on port %d \n",
529 port_num);
530 return 0;
531 } else {
532 eth_port_read_smi_reg (port_num, 1, &phy_reg_data);
533 if (!(phy_reg_data & 0x20)) {
534 printf ("### Error: Phy is not active\n");
535 return 0;
536 }
537 }
538 } else {
539 mv64460_eth_print_phy_status (dev);
540 }
541 port_private->eth_running = MAGIC_ETH_RUNNING;
542 return 1;
543}
544
545
546static int mv64460_eth_free_tx_rings (struct eth_device *dev)
547{
548 unsigned int queue;
549 ETH_PORT_INFO *ethernet_private;
550 struct mv64460_eth_priv *port_private;
551 unsigned int port_num;
552 volatile ETH_TX_DESC *p_tx_curr_desc;
553
554 ethernet_private = (ETH_PORT_INFO *) dev->priv;
555 port_private =
556 (struct mv64460_eth_priv *) ethernet_private->port_private;
557 port_num = port_private->port_num;
558
559
560 MV_REG_WRITE (MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG (port_num),
561 0x0000ff00);
562
563
564 DP (printf ("Clearing previously allocated TX queues... "));
565 for (queue = 0; queue < MV64460_TX_QUEUE_NUM; queue++) {
566
567 for (p_tx_curr_desc =
568 ethernet_private->p_tx_desc_area_base[queue];
569 ((unsigned int) p_tx_curr_desc <= (unsigned int)
570 ethernet_private->p_tx_desc_area_base[queue] +
571 ethernet_private->tx_desc_area_size[queue]);
572 p_tx_curr_desc =
573 (ETH_TX_DESC *) ((unsigned int) p_tx_curr_desc +
574 TX_DESC_ALIGNED_SIZE)) {
575
576 if (p_tx_curr_desc->return_info != 0) {
577 p_tx_curr_desc->return_info = 0;
578 DP (printf ("freed\n"));
579 }
580 }
581 DP (printf ("Done\n"));
582 }
583 return 0;
584}
585
586static int mv64460_eth_free_rx_rings (struct eth_device *dev)
587{
588 unsigned int queue;
589 ETH_PORT_INFO *ethernet_private;
590 struct mv64460_eth_priv *port_private;
591 unsigned int port_num;
592 volatile ETH_RX_DESC *p_rx_curr_desc;
593
594 ethernet_private = (ETH_PORT_INFO *) dev->priv;
595 port_private =
596 (struct mv64460_eth_priv *) ethernet_private->port_private;
597 port_num = port_private->port_num;
598
599
600
601 MV_REG_WRITE (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG (port_num),
602 0x0000ff00);
603
604
605 DP (printf ("Clearing previously allocated RX queues... "));
606 for (queue = 0; queue < MV64460_RX_QUEUE_NUM; queue++) {
607
608 for (p_rx_curr_desc =
609 ethernet_private->p_rx_desc_area_base[queue];
610 (((unsigned int) p_rx_curr_desc <
611 ((unsigned int) ethernet_private->
612 p_rx_desc_area_base[queue] +
613 ethernet_private->rx_desc_area_size[queue])));
614 p_rx_curr_desc =
615 (ETH_RX_DESC *) ((unsigned int) p_rx_curr_desc +
616 RX_DESC_ALIGNED_SIZE)) {
617 if (p_rx_curr_desc->return_info != 0) {
618 p_rx_curr_desc->return_info = 0;
619 DP (printf ("freed\n"));
620 }
621 }
622 DP (printf ("Done\n"));
623 }
624 return 0;
625}
626
627
628
629
630
631
632
633
634
635
636
637int mv64460_eth_stop (struct eth_device *dev)
638{
639
640 MV_REG_WRITE (MV64460_ETH_BASE_ADDR_ENABLE_REG, 0x3f);
641 DP (printf ("%s Ethernet stop called ... \n", __FUNCTION__));
642 mv64460_eth_real_stop (dev);
643
644 return 0;
645};
646
647
648
649static int mv64460_eth_real_stop (struct eth_device *dev)
650{
651 ETH_PORT_INFO *ethernet_private;
652 struct mv64460_eth_priv *port_private;
653 unsigned int port_num;
654
655 ethernet_private = (ETH_PORT_INFO *) dev->priv;
656 port_private =
657 (struct mv64460_eth_priv *) ethernet_private->port_private;
658 port_num = port_private->port_num;
659
660
661 mv64460_eth_free_tx_rings (dev);
662 mv64460_eth_free_rx_rings (dev);
663
664 eth_port_reset (ethernet_private->port_num);
665
666 MV_REG_WRITE (MV64460_ETH_INTERRUPT_CAUSE_REG (port_num), 0);
667 MV_REG_WRITE (MV64460_ETH_INTERRUPT_CAUSE_EXTEND_REG (port_num), 0);
668
669 MV_REG_WRITE (MV64460_ETH_INTERRUPT_MASK_REG (port_num), 0);
670
671 MV_REG_WRITE (MV64460_ETH_INTERRUPT_EXTEND_MASK_REG (port_num), 0);
672 MV_RESET_REG_BITS (MV64460_CPU_INTERRUPT0_MASK_HIGH,
673 BIT0 << port_num);
674
675#ifndef UPDATE_STATS_BY_SOFTWARE
676
677
678
679
680 if (port_private->eth_running == MAGIC_ETH_RUNNING) {
681 port_private->eth_running = 0;
682 mv64460_eth_print_stat (dev);
683 }
684 memset (port_private->stats, 0, sizeof (struct net_device_stats));
685#endif
686 DP (printf ("\nEthernet stopped ... \n"));
687 return 0;
688}
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703int mv64460_eth_xmit (struct eth_device *dev, volatile void *dataPtr,
704 int dataSize)
705{
706 ETH_PORT_INFO *ethernet_private;
707 struct mv64460_eth_priv *port_private;
708 PKT_INFO pkt_info;
709 ETH_FUNC_RET_STATUS status;
710 struct net_device_stats *stats;
711 ETH_FUNC_RET_STATUS release_result;
712
713 ethernet_private = (ETH_PORT_INFO *) dev->priv;
714 port_private =
715 (struct mv64460_eth_priv *) ethernet_private->port_private;
716
717 stats = port_private->stats;
718
719
720 pkt_info.cmd_sts = ETH_TX_FIRST_DESC | ETH_TX_LAST_DESC;
721 pkt_info.byte_cnt = dataSize;
722 pkt_info.buf_ptr = (unsigned int) dataPtr;
723 pkt_info.return_info = 0;
724
725 status = eth_port_send (ethernet_private, ETH_Q0, &pkt_info);
726 if ((status == ETH_ERROR) || (status == ETH_QUEUE_FULL)) {
727 printf ("Error on transmitting packet ..");
728 if (status == ETH_QUEUE_FULL)
729 printf ("ETH Queue is full. \n");
730 if (status == ETH_QUEUE_LAST_RESOURCE)
731 printf ("ETH Queue: using last available resource. \n");
732 goto error;
733 }
734
735
736 stats->tx_bytes += dataSize;
737 stats->tx_packets++;
738
739
740 do {
741 release_result =
742 eth_tx_return_desc (ethernet_private, ETH_Q0,
743 &pkt_info);
744 switch (release_result) {
745 case ETH_OK:
746 DP (printf ("descriptor released\n"));
747 if (pkt_info.cmd_sts & BIT0) {
748 printf ("Error in TX\n");
749 stats->tx_errors++;
750
751 }
752 break;
753 case ETH_RETRY:
754 DP (printf ("transmission still in process\n"));
755 break;
756
757 case ETH_ERROR:
758 printf ("routine can not access Tx desc ring\n");
759 break;
760
761 case ETH_END_OF_JOB:
762 DP (printf ("the routine has nothing to release\n"));
763 break;
764 default:
765 break;
766 }
767 } while (release_result == ETH_OK);
768
769
770 return 0;
771 error:
772 return 1;
773}
774
775
776
777
778
779
780
781
782
783
784
785
786
787int mv64460_eth_receive (struct eth_device *dev)
788{
789 ETH_PORT_INFO *ethernet_private;
790 struct mv64460_eth_priv *port_private;
791 PKT_INFO pkt_info;
792 struct net_device_stats *stats;
793
794 ethernet_private = (ETH_PORT_INFO *) dev->priv;
795 port_private =
796 (struct mv64460_eth_priv *) ethernet_private->port_private;
797 stats = port_private->stats;
798
799 while ((eth_port_receive (ethernet_private, ETH_Q0, &pkt_info) ==
800 ETH_OK)) {
801
802#ifdef DEBUG_MV_ETH
803 if (pkt_info.byte_cnt != 0) {
804 printf ("%s: Received %d byte Packet @ 0x%x\n",
805 __FUNCTION__, pkt_info.byte_cnt,
806 pkt_info.buf_ptr);
807 }
808#endif
809
810 stats->rx_packets++;
811 stats->rx_bytes += pkt_info.byte_cnt;
812
813
814
815
816
817 if (((pkt_info.
818 cmd_sts & (ETH_RX_FIRST_DESC | ETH_RX_LAST_DESC)) !=
819 (ETH_RX_FIRST_DESC | ETH_RX_LAST_DESC))
820 || (pkt_info.cmd_sts & ETH_ERROR_SUMMARY)) {
821 stats->rx_dropped++;
822
823 printf ("Received packet spread on multiple descriptors\n");
824
825
826 if (pkt_info.cmd_sts & ETH_ERROR_SUMMARY) {
827 stats->rx_errors++;
828 }
829
830
831 pkt_info.buf_ptr &= ~0x7;
832 pkt_info.byte_cnt = 0x0000;
833
834 if (eth_rx_return_buff
835 (ethernet_private, ETH_Q0, &pkt_info) != ETH_OK) {
836 printf ("Error while returning the RX Desc to Ring\n");
837 } else {
838 DP (printf ("RX Desc returned to Ring\n"));
839 }
840
841 } else {
842
843
844#ifdef DEBUG_MV_ETH
845 printf ("\nNow send it to upper layer protocols (NetReceive) ...\n");
846#endif
847
848 NetReceive ((uchar *) pkt_info.buf_ptr,
849 (int) pkt_info.byte_cnt);
850
851
852
853 pkt_info.buf_ptr &= ~0x7;
854 pkt_info.byte_cnt = 0x0000;
855 DP (printf
856 ("RX: pkt_info.buf_ptr = %x\n",
857 pkt_info.buf_ptr));
858 if (eth_rx_return_buff
859 (ethernet_private, ETH_Q0, &pkt_info) != ETH_OK) {
860 printf ("Error while returning the RX Desc to Ring\n");
861 } else {
862 DP (printf ("RX Desc returned to Ring\n"));
863 }
864
865
866
867 }
868 }
869 mv64460_eth_get_stats (dev);
870 return 1;
871}
872
873
874
875
876
877
878
879
880
881
882
883static struct net_device_stats *mv64460_eth_get_stats (struct eth_device *dev)
884{
885 ETH_PORT_INFO *ethernet_private;
886 struct mv64460_eth_priv *port_private;
887
888 ethernet_private = (ETH_PORT_INFO *) dev->priv;
889 port_private =
890 (struct mv64460_eth_priv *) ethernet_private->port_private;
891
892 mv64460_eth_update_stat (dev);
893
894 return port_private->stats;
895}
896
897
898
899
900
901
902
903
904
905
906
907static void mv64460_eth_update_stat (struct eth_device *dev)
908{
909 ETH_PORT_INFO *ethernet_private;
910 struct mv64460_eth_priv *port_private;
911 struct net_device_stats *stats;
912
913 ethernet_private = (ETH_PORT_INFO *) dev->priv;
914 port_private =
915 (struct mv64460_eth_priv *) ethernet_private->port_private;
916 stats = port_private->stats;
917
918
919 stats->rx_packets += (unsigned long)
920 eth_read_mib_counter (ethernet_private->port_num,
921 ETH_MIB_GOOD_FRAMES_RECEIVED);
922 stats->tx_packets += (unsigned long)
923 eth_read_mib_counter (ethernet_private->port_num,
924 ETH_MIB_GOOD_FRAMES_SENT);
925 stats->rx_bytes += (unsigned long)
926 eth_read_mib_counter (ethernet_private->port_num,
927 ETH_MIB_GOOD_OCTETS_RECEIVED_LOW);
928
929
930
931
932
933
934
935
936
937
938 eth_read_mib_counter (ethernet_private->port_num,
939 ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH);
940 stats->tx_bytes += (unsigned long)
941 eth_read_mib_counter (ethernet_private->port_num,
942 ETH_MIB_GOOD_OCTETS_SENT_LOW);
943 eth_read_mib_counter (ethernet_private->port_num,
944 ETH_MIB_GOOD_OCTETS_SENT_HIGH);
945 stats->rx_errors += (unsigned long)
946 eth_read_mib_counter (ethernet_private->port_num,
947 ETH_MIB_MAC_RECEIVE_ERROR);
948
949
950 stats->rx_dropped +=
951 (unsigned long) eth_read_mib_counter (ethernet_private->
952 port_num,
953 ETH_MIB_BAD_CRC_EVENT);
954 stats->multicast += (unsigned long)
955 eth_read_mib_counter (ethernet_private->port_num,
956 ETH_MIB_MULTICAST_FRAMES_RECEIVED);
957 stats->collisions +=
958 (unsigned long) eth_read_mib_counter (ethernet_private->
959 port_num,
960 ETH_MIB_COLLISION) +
961 (unsigned long) eth_read_mib_counter (ethernet_private->
962 port_num,
963 ETH_MIB_LATE_COLLISION);
964
965 stats->rx_length_errors +=
966 (unsigned long) eth_read_mib_counter (ethernet_private->
967 port_num,
968 ETH_MIB_UNDERSIZE_RECEIVED)
969 +
970 (unsigned long) eth_read_mib_counter (ethernet_private->
971 port_num,
972 ETH_MIB_OVERSIZE_RECEIVED);
973
974}
975
976#ifndef UPDATE_STATS_BY_SOFTWARE
977
978
979
980
981
982
983
984
985
986static void mv64460_eth_print_stat (struct eth_device *dev)
987{
988 ETH_PORT_INFO *ethernet_private;
989 struct mv64460_eth_priv *port_private;
990 struct net_device_stats *stats;
991
992 ethernet_private = (ETH_PORT_INFO *) dev->priv;
993 port_private =
994 (struct mv64460_eth_priv *) ethernet_private->port_private;
995 stats = port_private->stats;
996
997
998 printf ("\n### Network statistics: ###\n");
999 printf ("--------------------------\n");
1000 printf (" Packets received: %ld\n", stats->rx_packets);
1001 printf (" Packets send: %ld\n", stats->tx_packets);
1002 printf (" Received bytes: %ld\n", stats->rx_bytes);
1003 printf (" Send bytes: %ld\n", stats->tx_bytes);
1004 if (stats->rx_errors != 0)
1005 printf (" Rx Errors: %ld\n",
1006 stats->rx_errors);
1007 if (stats->rx_dropped != 0)
1008 printf (" Rx dropped (CRC Errors): %ld\n",
1009 stats->rx_dropped);
1010 if (stats->multicast != 0)
1011 printf (" Rx mulicast frames: %ld\n",
1012 stats->multicast);
1013 if (stats->collisions != 0)
1014 printf (" No. of collisions: %ld\n",
1015 stats->collisions);
1016 if (stats->rx_length_errors != 0)
1017 printf (" Rx length errors: %ld\n",
1018 stats->rx_length_errors);
1019}
1020#endif
1021
1022
1023
1024
1025
1026
1027
1028bool db64460_eth_start (struct eth_device *dev)
1029{
1030 return (mv64460_eth_open (dev));
1031}
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225#define ETH_ENABLE_TX_QUEUE(tx_queue, eth_port) \
1226 MV_REG_WRITE(MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG(eth_port), (1 << tx_queue))
1227
1228#define ETH_DISABLE_TX_QUEUE(tx_queue, eth_port) \
1229 MV_REG_WRITE(MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG(eth_port),\
1230 (1 << (8 + tx_queue)))
1231
1232#define ETH_ENABLE_RX_QUEUE(rx_queue, eth_port) \
1233MV_REG_WRITE(MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG(eth_port), (1 << rx_queue))
1234
1235#define ETH_DISABLE_RX_QUEUE(rx_queue, eth_port) \
1236MV_REG_WRITE(MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG(eth_port), (1 << (8 + rx_queue)))
1237
1238#define CURR_RFD_GET(p_curr_desc, queue) \
1239 ((p_curr_desc) = p_eth_port_ctrl->p_rx_curr_desc_q[queue])
1240
1241#define CURR_RFD_SET(p_curr_desc, queue) \
1242 (p_eth_port_ctrl->p_rx_curr_desc_q[queue] = (p_curr_desc))
1243
1244#define USED_RFD_GET(p_used_desc, queue) \
1245 ((p_used_desc) = p_eth_port_ctrl->p_rx_used_desc_q[queue])
1246
1247#define USED_RFD_SET(p_used_desc, queue)\
1248(p_eth_port_ctrl->p_rx_used_desc_q[queue] = (p_used_desc))
1249
1250
1251#define CURR_TFD_GET(p_curr_desc, queue) \
1252 ((p_curr_desc) = p_eth_port_ctrl->p_tx_curr_desc_q[queue])
1253
1254#define CURR_TFD_SET(p_curr_desc, queue) \
1255 (p_eth_port_ctrl->p_tx_curr_desc_q[queue] = (p_curr_desc))
1256
1257#define USED_TFD_GET(p_used_desc, queue) \
1258 ((p_used_desc) = p_eth_port_ctrl->p_tx_used_desc_q[queue])
1259
1260#define USED_TFD_SET(p_used_desc, queue) \
1261 (p_eth_port_ctrl->p_tx_used_desc_q[queue] = (p_used_desc))
1262
1263#define FIRST_TFD_GET(p_first_desc, queue) \
1264 ((p_first_desc) = p_eth_port_ctrl->p_tx_first_desc_q[queue])
1265
1266#define FIRST_TFD_SET(p_first_desc, queue) \
1267 (p_eth_port_ctrl->p_tx_first_desc_q[queue] = (p_first_desc))
1268
1269
1270
1271#define RX_NEXT_DESC_PTR(p_rx_desc, queue) (ETH_RX_DESC*)(((((unsigned int)p_rx_desc - (unsigned int)p_eth_port_ctrl->p_rx_desc_area_base[queue]) + RX_DESC_ALIGNED_SIZE) % p_eth_port_ctrl->rx_desc_area_size[queue]) + (unsigned int)p_eth_port_ctrl->p_rx_desc_area_base[queue])
1272
1273#define TX_NEXT_DESC_PTR(p_tx_desc, queue) (ETH_TX_DESC*)(((((unsigned int)p_tx_desc - (unsigned int)p_eth_port_ctrl->p_tx_desc_area_base[queue]) + TX_DESC_ALIGNED_SIZE) % p_eth_port_ctrl->tx_desc_area_size[queue]) + (unsigned int)p_eth_port_ctrl->p_tx_desc_area_base[queue])
1274
1275#define LINK_UP_TIMEOUT 100000
1276#define PHY_BUSY_TIMEOUT 10000000
1277
1278
1279
1280
1281static void ethernet_phy_set (ETH_PORT eth_port_num, int phy_addr);
1282static int ethernet_phy_get (ETH_PORT eth_port_num);
1283
1284
1285static void eth_set_access_control (ETH_PORT eth_port_num,
1286 ETH_WIN_PARAM * param);
1287static bool eth_port_uc_addr (ETH_PORT eth_port_num, unsigned char uc_nibble,
1288 ETH_QUEUE queue, int option);
1289#if 0
1290static bool eth_port_smc_addr (ETH_PORT eth_port_num,
1291 unsigned char mc_byte,
1292 ETH_QUEUE queue, int option);
1293static bool eth_port_omc_addr (ETH_PORT eth_port_num,
1294 unsigned char crc8,
1295 ETH_QUEUE queue, int option);
1296#endif
1297
1298static void eth_b_copy (unsigned int src_addr, unsigned int dst_addr,
1299 int byte_count);
1300
1301void eth_dbg (ETH_PORT_INFO * p_eth_port_ctrl);
1302
1303
1304typedef enum _memory_bank { BANK0, BANK1, BANK2, BANK3 } MEMORY_BANK;
1305u32 mv_get_dram_bank_base_addr (MEMORY_BANK bank)
1306{
1307 u32 result = 0;
1308 u32 enable = MV_REG_READ (MV64460_BASE_ADDR_ENABLE);
1309
1310 if (enable & (1 << bank))
1311 return 0;
1312 if (bank == BANK0)
1313 result = MV_REG_READ (MV64460_CS_0_BASE_ADDR);
1314 if (bank == BANK1)
1315 result = MV_REG_READ (MV64460_CS_1_BASE_ADDR);
1316 if (bank == BANK2)
1317 result = MV_REG_READ (MV64460_CS_2_BASE_ADDR);
1318 if (bank == BANK3)
1319 result = MV_REG_READ (MV64460_CS_3_BASE_ADDR);
1320 result &= 0x0000ffff;
1321 result = result << 16;
1322 return result;
1323}
1324
1325u32 mv_get_dram_bank_size (MEMORY_BANK bank)
1326{
1327 u32 result = 0;
1328 u32 enable = MV_REG_READ (MV64460_BASE_ADDR_ENABLE);
1329
1330 if (enable & (1 << bank))
1331 return 0;
1332 if (bank == BANK0)
1333 result = MV_REG_READ (MV64460_CS_0_SIZE);
1334 if (bank == BANK1)
1335 result = MV_REG_READ (MV64460_CS_1_SIZE);
1336 if (bank == BANK2)
1337 result = MV_REG_READ (MV64460_CS_2_SIZE);
1338 if (bank == BANK3)
1339 result = MV_REG_READ (MV64460_CS_3_SIZE);
1340 result += 1;
1341 result &= 0x0000ffff;
1342 result = result << 16;
1343 return result;
1344}
1345
1346u32 mv_get_internal_sram_base (void)
1347{
1348 u32 result;
1349
1350 result = MV_REG_READ (MV64460_INTEGRATED_SRAM_BASE_ADDR);
1351 result &= 0x0000ffff;
1352 result = result << 16;
1353 return result;
1354}
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381static void eth_port_init (ETH_PORT_INFO * p_eth_port_ctrl)
1382{
1383 int queue;
1384 ETH_WIN_PARAM win_param;
1385
1386 p_eth_port_ctrl->port_config = PORT_CONFIG_VALUE;
1387 p_eth_port_ctrl->port_config_extend = PORT_CONFIG_EXTEND_VALUE;
1388 p_eth_port_ctrl->port_sdma_config = PORT_SDMA_CONFIG_VALUE;
1389 p_eth_port_ctrl->port_serial_control = PORT_SERIAL_CONTROL_VALUE;
1390
1391 p_eth_port_ctrl->port_rx_queue_command = 0;
1392 p_eth_port_ctrl->port_tx_queue_command = 0;
1393
1394
1395 for (queue = 0; queue < MAX_RX_QUEUE_NUM; queue++) {
1396 CURR_RFD_SET ((ETH_RX_DESC *) 0x00000000, queue);
1397 USED_RFD_SET ((ETH_RX_DESC *) 0x00000000, queue);
1398 p_eth_port_ctrl->rx_resource_err[queue] = false;
1399 }
1400
1401 for (queue = 0; queue < MAX_TX_QUEUE_NUM; queue++) {
1402 CURR_TFD_SET ((ETH_TX_DESC *) 0x00000000, queue);
1403 USED_TFD_SET ((ETH_TX_DESC *) 0x00000000, queue);
1404 FIRST_TFD_SET ((ETH_TX_DESC *) 0x00000000, queue);
1405 p_eth_port_ctrl->tx_resource_err[queue] = false;
1406 }
1407
1408 eth_port_reset (p_eth_port_ctrl->port_num);
1409
1410
1411 win_param.win = ETH_WIN0;
1412 win_param.target = ETH_TARGET_DRAM;
1413 win_param.attributes = EBAR_ATTR_DRAM_CS0;
1414#ifndef CONFIG_NOT_COHERENT_CACHE
1415 win_param.attributes |= EBAR_ATTR_DRAM_CACHE_COHERENCY_WB;
1416#endif
1417 win_param.high_addr = 0;
1418
1419 win_param.base_addr = mv_get_dram_bank_base_addr (BANK0);
1420 win_param.size = mv_get_dram_bank_size (BANK0);
1421 if (win_param.size == 0)
1422 win_param.enable = 0;
1423 else
1424 win_param.enable = 1;
1425 win_param.access_ctrl = EWIN_ACCESS_FULL;
1426
1427
1428 eth_set_access_control (p_eth_port_ctrl->port_num, &win_param);
1429
1430
1431 win_param.win = ETH_WIN1;
1432 win_param.target = ETH_TARGET_DRAM;
1433 win_param.attributes = EBAR_ATTR_DRAM_CS1;
1434#ifndef CONFIG_NOT_COHERENT_CACHE
1435 win_param.attributes |= EBAR_ATTR_DRAM_CACHE_COHERENCY_WB;
1436#endif
1437 win_param.high_addr = 0;
1438
1439 win_param.base_addr = mv_get_dram_bank_base_addr (BANK1);
1440 win_param.size = mv_get_dram_bank_size (BANK1);
1441 if (win_param.size == 0)
1442 win_param.enable = 0;
1443 else
1444 win_param.enable = 1;
1445 win_param.access_ctrl = EWIN_ACCESS_FULL;
1446
1447
1448 eth_set_access_control (p_eth_port_ctrl->port_num, &win_param);
1449
1450
1451 win_param.win = ETH_WIN2;
1452 win_param.target = ETH_TARGET_DRAM;
1453 win_param.attributes = EBAR_ATTR_DRAM_CS2;
1454#ifndef CONFIG_NOT_COHERENT_CACHE
1455 win_param.attributes |= EBAR_ATTR_DRAM_CACHE_COHERENCY_WB;
1456#endif
1457 win_param.high_addr = 0;
1458
1459 win_param.base_addr = mv_get_dram_bank_base_addr (BANK2);
1460 win_param.size = mv_get_dram_bank_size (BANK2);
1461 if (win_param.size == 0)
1462 win_param.enable = 0;
1463 else
1464 win_param.enable = 1;
1465 win_param.access_ctrl = EWIN_ACCESS_FULL;
1466
1467
1468 eth_set_access_control (p_eth_port_ctrl->port_num, &win_param);
1469
1470
1471 win_param.win = ETH_WIN3;
1472 win_param.target = ETH_TARGET_DRAM;
1473 win_param.attributes = EBAR_ATTR_DRAM_CS3;
1474#ifndef CONFIG_NOT_COHERENT_CACHE
1475 win_param.attributes |= EBAR_ATTR_DRAM_CACHE_COHERENCY_WB;
1476#endif
1477 win_param.high_addr = 0;
1478
1479 win_param.base_addr = mv_get_dram_bank_base_addr (BANK3);
1480 win_param.size = mv_get_dram_bank_size (BANK3);
1481 if (win_param.size == 0)
1482 win_param.enable = 0;
1483 else
1484 win_param.enable = 1;
1485 win_param.access_ctrl = EWIN_ACCESS_FULL;
1486
1487
1488 eth_set_access_control (p_eth_port_ctrl->port_num, &win_param);
1489
1490
1491 win_param.win = ETH_WIN4;
1492 win_param.target = EBAR_TARGET_CBS;
1493 win_param.attributes = EBAR_ATTR_CBS_SRAM | EBAR_ATTR_CBS_SRAM_BLOCK0;
1494 win_param.high_addr = 0;
1495 win_param.base_addr = mv_get_internal_sram_base ();
1496 win_param.size = MV64460_INTERNAL_SRAM_SIZE;
1497 win_param.enable = 1;
1498 win_param.access_ctrl = EWIN_ACCESS_FULL;
1499
1500
1501 eth_set_access_control (p_eth_port_ctrl->port_num, &win_param);
1502
1503 eth_port_init_mac_tables (p_eth_port_ctrl->port_num);
1504
1505 ethernet_phy_set (p_eth_port_ctrl->port_num,
1506 p_eth_port_ctrl->port_phy_addr);
1507
1508 return;
1509
1510}
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542static bool eth_port_start (ETH_PORT_INFO * p_eth_port_ctrl)
1543{
1544 int queue;
1545 volatile ETH_TX_DESC *p_tx_curr_desc;
1546 volatile ETH_RX_DESC *p_rx_curr_desc;
1547 unsigned int phy_reg_data;
1548 ETH_PORT eth_port_num = p_eth_port_ctrl->port_num;
1549
1550
1551
1552 for (queue = 0; queue < MAX_TX_QUEUE_NUM; queue++) {
1553 CURR_TFD_GET (p_tx_curr_desc, queue);
1554 MV_REG_WRITE ((MV64460_ETH_TX_CURRENT_QUEUE_DESC_PTR_0
1555 (eth_port_num)
1556 + (4 * queue)),
1557 ((unsigned int) p_tx_curr_desc));
1558
1559 }
1560
1561
1562 for (queue = 0; queue < MAX_RX_QUEUE_NUM; queue++) {
1563 CURR_RFD_GET (p_rx_curr_desc, queue);
1564 MV_REG_WRITE ((MV64460_ETH_RX_CURRENT_QUEUE_DESC_PTR_0
1565 (eth_port_num)
1566 + (4 * queue)),
1567 ((unsigned int) p_rx_curr_desc));
1568
1569 if (p_rx_curr_desc != NULL)
1570
1571 eth_port_uc_addr_set (p_eth_port_ctrl->port_num,
1572 p_eth_port_ctrl->port_mac_addr,
1573 queue);
1574 }
1575
1576
1577 MV_REG_WRITE (MV64460_ETH_PORT_CONFIG_REG (eth_port_num),
1578 p_eth_port_ctrl->port_config);
1579
1580 MV_REG_WRITE (MV64460_ETH_PORT_CONFIG_EXTEND_REG (eth_port_num),
1581 p_eth_port_ctrl->port_config_extend);
1582
1583 MV_REG_WRITE (MV64460_ETH_PORT_SERIAL_CONTROL_REG (eth_port_num),
1584 p_eth_port_ctrl->port_serial_control);
1585
1586 MV_SET_REG_BITS (MV64460_ETH_PORT_SERIAL_CONTROL_REG (eth_port_num),
1587 ETH_SERIAL_PORT_ENABLE);
1588
1589
1590 MV_REG_WRITE (MV64460_ETH_SDMA_CONFIG_REG (eth_port_num),
1591 p_eth_port_ctrl->port_sdma_config);
1592
1593 MV_REG_WRITE (MV64460_ETH_TX_QUEUE_0_TOKEN_BUCKET_COUNT
1594 (eth_port_num), 0x3fffffff);
1595 MV_REG_WRITE (MV64460_ETH_TX_QUEUE_0_TOKEN_BUCKET_CONFIG
1596 (eth_port_num), 0x03fffcff);
1597
1598 MV_REG_WRITE (MV64460_ETH_MAXIMUM_TRANSMIT_UNIT (eth_port_num), 0x0);
1599
1600
1601 MV_REG_WRITE (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG (eth_port_num),
1602 p_eth_port_ctrl->port_rx_queue_command);
1603
1604
1605 eth_port_read_smi_reg (eth_port_num, 1, &phy_reg_data);
1606
1607 if (!(phy_reg_data & 0x20))
1608 return false;
1609
1610 return true;
1611}
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632static void eth_port_uc_addr_set (ETH_PORT eth_port_num,
1633 unsigned char *p_addr, ETH_QUEUE queue)
1634{
1635 unsigned int mac_h;
1636 unsigned int mac_l;
1637
1638 mac_l = (p_addr[4] << 8) | (p_addr[5]);
1639 mac_h = (p_addr[0] << 24) | (p_addr[1] << 16) |
1640 (p_addr[2] << 8) | (p_addr[3] << 0);
1641
1642 MV_REG_WRITE (MV64460_ETH_MAC_ADDR_LOW (eth_port_num), mac_l);
1643 MV_REG_WRITE (MV64460_ETH_MAC_ADDR_HIGH (eth_port_num), mac_h);
1644
1645
1646 eth_port_uc_addr (eth_port_num, p_addr[5], queue, ACCEPT_MAC_ADDR);
1647
1648 return;
1649}
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674static bool eth_port_uc_addr (ETH_PORT eth_port_num,
1675 unsigned char uc_nibble,
1676 ETH_QUEUE queue, int option)
1677{
1678 unsigned int unicast_reg;
1679 unsigned int tbl_offset;
1680 unsigned int reg_offset;
1681
1682
1683 uc_nibble = (0xf & uc_nibble);
1684 tbl_offset = (uc_nibble / 4) * 4;
1685 reg_offset = uc_nibble % 4;
1686
1687 switch (option) {
1688 case REJECT_MAC_ADDR:
1689
1690 unicast_reg =
1691 MV_REG_READ ((MV64460_ETH_DA_FILTER_UNICAST_TABLE_BASE
1692 (eth_port_num)
1693 + tbl_offset));
1694
1695 unicast_reg &= (0x0E << (8 * reg_offset));
1696
1697 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_UNICAST_TABLE_BASE
1698 (eth_port_num)
1699 + tbl_offset), unicast_reg);
1700 break;
1701
1702 case ACCEPT_MAC_ADDR:
1703
1704 unicast_reg =
1705 MV_REG_READ ((MV64460_ETH_DA_FILTER_UNICAST_TABLE_BASE
1706 (eth_port_num)
1707 + tbl_offset));
1708
1709 unicast_reg |= ((0x01 | queue) << (8 * reg_offset));
1710
1711 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_UNICAST_TABLE_BASE
1712 (eth_port_num)
1713 + tbl_offset), unicast_reg);
1714
1715 break;
1716
1717 default:
1718 return false;
1719 }
1720 return true;
1721}
1722
1723#if 0
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755static void eth_port_mc_addr (ETH_PORT eth_port_num,
1756 unsigned char *p_addr,
1757 ETH_QUEUE queue, int option)
1758{
1759 unsigned int mac_h;
1760 unsigned int mac_l;
1761 unsigned char crc_result = 0;
1762 int mac_array[48];
1763 int crc[8];
1764 int i;
1765
1766
1767 if ((p_addr[0] == 0x01) &&
1768 (p_addr[1] == 0x00) &&
1769 (p_addr[2] == 0x5E) && (p_addr[3] == 0x00) && (p_addr[4] == 0x00))
1770
1771 eth_port_smc_addr (eth_port_num, p_addr[5], queue, option);
1772 else {
1773
1774 mac_h = (p_addr[0] << 8) | (p_addr[1]);
1775 mac_l = (p_addr[2] << 24) | (p_addr[3] << 16) |
1776 (p_addr[4] << 8) | (p_addr[5] << 0);
1777
1778 for (i = 0; i < 32; i++)
1779 mac_array[i] = (mac_l >> i) & 0x1;
1780 for (i = 32; i < 48; i++)
1781 mac_array[i] = (mac_h >> (i - 32)) & 0x1;
1782
1783
1784 crc[0] = mac_array[45] ^ mac_array[43] ^ mac_array[40] ^
1785 mac_array[39] ^ mac_array[35] ^ mac_array[34] ^
1786 mac_array[31] ^ mac_array[30] ^ mac_array[28] ^
1787 mac_array[23] ^ mac_array[21] ^ mac_array[19] ^
1788 mac_array[18] ^ mac_array[16] ^ mac_array[14] ^
1789 mac_array[12] ^ mac_array[8] ^ mac_array[7] ^
1790 mac_array[6] ^ mac_array[0];
1791
1792 crc[1] = mac_array[46] ^ mac_array[45] ^ mac_array[44] ^
1793 mac_array[43] ^ mac_array[41] ^ mac_array[39] ^
1794 mac_array[36] ^ mac_array[34] ^ mac_array[32] ^
1795 mac_array[30] ^ mac_array[29] ^ mac_array[28] ^
1796 mac_array[24] ^ mac_array[23] ^ mac_array[22] ^
1797 mac_array[21] ^ mac_array[20] ^ mac_array[18] ^
1798 mac_array[17] ^ mac_array[16] ^ mac_array[15] ^
1799 mac_array[14] ^ mac_array[13] ^ mac_array[12] ^
1800 mac_array[9] ^ mac_array[6] ^ mac_array[1] ^
1801 mac_array[0];
1802
1803 crc[2] = mac_array[47] ^ mac_array[46] ^ mac_array[44] ^
1804 mac_array[43] ^ mac_array[42] ^ mac_array[39] ^
1805 mac_array[37] ^ mac_array[34] ^ mac_array[33] ^
1806 mac_array[29] ^ mac_array[28] ^ mac_array[25] ^
1807 mac_array[24] ^ mac_array[22] ^ mac_array[17] ^
1808 mac_array[15] ^ mac_array[13] ^ mac_array[12] ^
1809 mac_array[10] ^ mac_array[8] ^ mac_array[6] ^
1810 mac_array[2] ^ mac_array[1] ^ mac_array[0];
1811
1812 crc[3] = mac_array[47] ^ mac_array[45] ^ mac_array[44] ^
1813 mac_array[43] ^ mac_array[40] ^ mac_array[38] ^
1814 mac_array[35] ^ mac_array[34] ^ mac_array[30] ^
1815 mac_array[29] ^ mac_array[26] ^ mac_array[25] ^
1816 mac_array[23] ^ mac_array[18] ^ mac_array[16] ^
1817 mac_array[14] ^ mac_array[13] ^ mac_array[11] ^
1818 mac_array[9] ^ mac_array[7] ^ mac_array[3] ^
1819 mac_array[2] ^ mac_array[1];
1820
1821 crc[4] = mac_array[46] ^ mac_array[45] ^ mac_array[44] ^
1822 mac_array[41] ^ mac_array[39] ^ mac_array[36] ^
1823 mac_array[35] ^ mac_array[31] ^ mac_array[30] ^
1824 mac_array[27] ^ mac_array[26] ^ mac_array[24] ^
1825 mac_array[19] ^ mac_array[17] ^ mac_array[15] ^
1826 mac_array[14] ^ mac_array[12] ^ mac_array[10] ^
1827 mac_array[8] ^ mac_array[4] ^ mac_array[3] ^
1828 mac_array[2];
1829
1830 crc[5] = mac_array[47] ^ mac_array[46] ^ mac_array[45] ^
1831 mac_array[42] ^ mac_array[40] ^ mac_array[37] ^
1832 mac_array[36] ^ mac_array[32] ^ mac_array[31] ^
1833 mac_array[28] ^ mac_array[27] ^ mac_array[25] ^
1834 mac_array[20] ^ mac_array[18] ^ mac_array[16] ^
1835 mac_array[15] ^ mac_array[13] ^ mac_array[11] ^
1836 mac_array[9] ^ mac_array[5] ^ mac_array[4] ^
1837 mac_array[3];
1838
1839 crc[6] = mac_array[47] ^ mac_array[46] ^ mac_array[43] ^
1840 mac_array[41] ^ mac_array[38] ^ mac_array[37] ^
1841 mac_array[33] ^ mac_array[32] ^ mac_array[29] ^
1842 mac_array[28] ^ mac_array[26] ^ mac_array[21] ^
1843 mac_array[19] ^ mac_array[17] ^ mac_array[16] ^
1844 mac_array[14] ^ mac_array[12] ^ mac_array[10] ^
1845 mac_array[6] ^ mac_array[5] ^ mac_array[4];
1846
1847 crc[7] = mac_array[47] ^ mac_array[44] ^ mac_array[42] ^
1848 mac_array[39] ^ mac_array[38] ^ mac_array[34] ^
1849 mac_array[33] ^ mac_array[30] ^ mac_array[29] ^
1850 mac_array[27] ^ mac_array[22] ^ mac_array[20] ^
1851 mac_array[18] ^ mac_array[17] ^ mac_array[15] ^
1852 mac_array[13] ^ mac_array[11] ^ mac_array[7] ^
1853 mac_array[6] ^ mac_array[5];
1854
1855 for (i = 0; i < 8; i++)
1856 crc_result = crc_result | (crc[i] << i);
1857
1858 eth_port_omc_addr (eth_port_num, crc_result, queue, option);
1859 }
1860 return;
1861}
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889static bool eth_port_smc_addr (ETH_PORT eth_port_num,
1890 unsigned char mc_byte,
1891 ETH_QUEUE queue, int option)
1892{
1893 unsigned int smc_table_reg;
1894 unsigned int tbl_offset;
1895 unsigned int reg_offset;
1896
1897
1898 tbl_offset = (mc_byte / 4) * 4;
1899 reg_offset = mc_byte % 4;
1900 queue &= 0x7;
1901
1902 switch (option) {
1903 case REJECT_MAC_ADDR:
1904
1905 smc_table_reg =
1906 MV_REG_READ ((MV64460_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset));
1907 smc_table_reg &= (0x0E << (8 * reg_offset));
1908
1909 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset), smc_table_reg);
1910 break;
1911
1912 case ACCEPT_MAC_ADDR:
1913
1914 smc_table_reg =
1915 MV_REG_READ ((MV64460_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset));
1916 smc_table_reg |= ((0x01 | queue) << (8 * reg_offset));
1917
1918 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset), smc_table_reg);
1919 break;
1920
1921 default:
1922 return false;
1923 }
1924 return true;
1925}
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953static bool eth_port_omc_addr (ETH_PORT eth_port_num,
1954 unsigned char crc8,
1955 ETH_QUEUE queue, int option)
1956{
1957 unsigned int omc_table_reg;
1958 unsigned int tbl_offset;
1959 unsigned int reg_offset;
1960
1961
1962 tbl_offset = (crc8 / 4) * 4;
1963 reg_offset = crc8 % 4;
1964 queue &= 0x7;
1965
1966 switch (option) {
1967 case REJECT_MAC_ADDR:
1968
1969 omc_table_reg =
1970 MV_REG_READ ((MV64460_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset));
1971 omc_table_reg &= (0x0E << (8 * reg_offset));
1972
1973 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset), omc_table_reg);
1974 break;
1975
1976 case ACCEPT_MAC_ADDR:
1977
1978 omc_table_reg =
1979 MV_REG_READ ((MV64460_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset));
1980 omc_table_reg |= ((0x01 | queue) << (8 * reg_offset));
1981
1982 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset), omc_table_reg);
1983 break;
1984
1985 default:
1986 return false;
1987 }
1988 return true;
1989}
1990#endif
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009static void eth_port_init_mac_tables (ETH_PORT eth_port_num)
2010{
2011 int table_index;
2012
2013
2014 for (table_index = 0; table_index <= 0xC; table_index += 4)
2015 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_UNICAST_TABLE_BASE
2016 (eth_port_num) + table_index), 0);
2017
2018 for (table_index = 0; table_index <= 0xFC; table_index += 4) {
2019
2020 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE (eth_port_num) + table_index), 0);
2021
2022 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE (eth_port_num) + table_index), 0);
2023 }
2024}
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043static void eth_clear_mib_counters (ETH_PORT eth_port_num)
2044{
2045 int i;
2046
2047
2048 for (i = ETH_MIB_GOOD_OCTETS_RECEIVED_LOW; i < ETH_MIB_LATE_COLLISION;
2049 i += 4)
2050 MV_REG_READ((MV64460_ETH_MIB_COUNTERS_BASE(eth_port_num) + i));
2051
2052 return;
2053}
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076unsigned int eth_read_mib_counter (ETH_PORT eth_port_num,
2077 unsigned int mib_offset)
2078{
2079 return (MV_REG_READ (MV64460_ETH_MIB_COUNTERS_BASE (eth_port_num)
2080 + mib_offset));
2081}
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100static void ethernet_phy_set (ETH_PORT eth_port_num, int phy_addr)
2101{
2102 unsigned int reg_data;
2103
2104 reg_data = MV_REG_READ (MV64460_ETH_PHY_ADDR_REG);
2105
2106 reg_data &= ~(0x1F << (5 * eth_port_num));
2107 reg_data |= (phy_addr << (5 * eth_port_num));
2108
2109 MV_REG_WRITE (MV64460_ETH_PHY_ADDR_REG, reg_data);
2110
2111 return;
2112}
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130static int ethernet_phy_get (ETH_PORT eth_port_num)
2131{
2132 unsigned int reg_data;
2133
2134 reg_data = MV_REG_READ (MV64460_ETH_PHY_ADDR_REG);
2135
2136 return ((reg_data >> (5 * eth_port_num)) & 0x1f);
2137}
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156static bool ethernet_phy_reset (ETH_PORT eth_port_num)
2157{
2158 unsigned int time_out = 50;
2159 unsigned int phy_reg_data;
2160
2161
2162 eth_port_read_smi_reg (eth_port_num, 0, &phy_reg_data);
2163 phy_reg_data |= 0x8000;
2164 eth_port_write_smi_reg (eth_port_num, 0, phy_reg_data);
2165
2166
2167 do {
2168 eth_port_read_smi_reg (eth_port_num, 1, &phy_reg_data);
2169
2170 if (time_out-- == 0)
2171 return false;
2172 }
2173 while (!(phy_reg_data & 0x20));
2174
2175 return true;
2176}
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196static void eth_port_reset (ETH_PORT eth_port_num)
2197{
2198 unsigned int reg_data;
2199
2200
2201 reg_data =
2202 MV_REG_READ (MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG
2203 (eth_port_num));
2204
2205 if (reg_data & 0xFF) {
2206
2207 MV_REG_WRITE (MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG
2208 (eth_port_num), (reg_data << 8));
2209
2210
2211 do {
2212
2213 reg_data =
2214 MV_REG_READ
2215 (MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG
2216 (eth_port_num));
2217 }
2218 while (reg_data & 0xFF);
2219 }
2220
2221
2222 reg_data =
2223 MV_REG_READ (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG
2224 (eth_port_num));
2225
2226 if (reg_data & 0xFF) {
2227
2228 MV_REG_WRITE (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG
2229 (eth_port_num), (reg_data << 8));
2230
2231
2232 do {
2233
2234 reg_data =
2235 MV_REG_READ
2236 (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG
2237 (eth_port_num));
2238 }
2239 while (reg_data & 0xFF);
2240 }
2241
2242
2243
2244 eth_clear_mib_counters (eth_port_num);
2245
2246
2247 reg_data =
2248 MV_REG_READ (MV64460_ETH_PORT_SERIAL_CONTROL_REG
2249 (eth_port_num));
2250 reg_data &= ~ETH_SERIAL_PORT_ENABLE;
2251 MV_REG_WRITE (MV64460_ETH_PORT_SERIAL_CONTROL_REG (eth_port_num),
2252 reg_data);
2253
2254 return;
2255}
2256
2257#if 0
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277static void ethernet_set_config_reg (ETH_PORT eth_port_num,
2278 unsigned int value)
2279{
2280 unsigned int eth_config_reg;
2281
2282 eth_config_reg =
2283 MV_REG_READ (MV64460_ETH_PORT_CONFIG_REG (eth_port_num));
2284 eth_config_reg |= value;
2285 MV_REG_WRITE (MV64460_ETH_PORT_CONFIG_REG (eth_port_num),
2286 eth_config_reg);
2287
2288 return;
2289}
2290#endif
2291
2292#if 0
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312static void ethernet_reset_config_reg (ETH_PORT eth_port_num,
2313 unsigned int value)
2314{
2315 unsigned int eth_config_reg;
2316
2317 eth_config_reg = MV_REG_READ (MV64460_ETH_PORT_CONFIG_EXTEND_REG
2318 (eth_port_num));
2319 eth_config_reg &= ~value;
2320 MV_REG_WRITE (MV64460_ETH_PORT_CONFIG_EXTEND_REG (eth_port_num),
2321 eth_config_reg);
2322
2323 return;
2324}
2325#endif
2326
2327#if 0
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345static unsigned int ethernet_get_config_reg (ETH_PORT eth_port_num)
2346{
2347 unsigned int eth_config_reg;
2348
2349 eth_config_reg = MV_REG_READ (MV64460_ETH_PORT_CONFIG_EXTEND_REG
2350 (eth_port_num));
2351 return eth_config_reg;
2352}
2353
2354#endif
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376static bool eth_port_read_smi_reg (ETH_PORT eth_port_num,
2377 unsigned int phy_reg, unsigned int *value)
2378{
2379 unsigned int reg_value;
2380 unsigned int time_out = PHY_BUSY_TIMEOUT;
2381 int phy_addr;
2382
2383 phy_addr = ethernet_phy_get (eth_port_num);
2384
2385
2386
2387 do {
2388 reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
2389 if (time_out-- == 0) {
2390 return false;
2391 }
2392 }
2393 while (reg_value & ETH_SMI_BUSY);
2394
2395
2396
2397 MV_REG_WRITE (MV64460_ETH_SMI_REG,
2398 (phy_addr << 16) | (phy_reg << 21) |
2399 ETH_SMI_OPCODE_READ);
2400
2401 time_out = PHY_BUSY_TIMEOUT;
2402
2403 do {
2404 reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
2405 if (time_out-- == 0) {
2406 return false;
2407 }
2408 }
2409 while ((reg_value & ETH_SMI_READ_VALID) != ETH_SMI_READ_VALID);
2410
2411
2412#define PHY_UPDATE_TIMEOUT 10000
2413 for (time_out = 0; time_out < PHY_UPDATE_TIMEOUT; time_out++);
2414
2415 reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
2416
2417 *value = reg_value & 0xffff;
2418
2419 return true;
2420}
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442static bool eth_port_write_smi_reg (ETH_PORT eth_port_num,
2443 unsigned int phy_reg, unsigned int value)
2444{
2445 unsigned int reg_value;
2446 unsigned int time_out = PHY_BUSY_TIMEOUT;
2447 int phy_addr;
2448
2449 phy_addr = ethernet_phy_get (eth_port_num);
2450
2451
2452 do {
2453 reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
2454 if (time_out-- == 0) {
2455 return false;
2456 }
2457 }
2458 while (reg_value & ETH_SMI_BUSY);
2459
2460
2461 MV_REG_WRITE (MV64460_ETH_SMI_REG,
2462 (phy_addr << 16) | (phy_reg << 21) |
2463 ETH_SMI_OPCODE_WRITE | (value & 0xffff));
2464 return true;
2465}
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485static void eth_set_access_control (ETH_PORT eth_port_num,
2486 ETH_WIN_PARAM * param)
2487{
2488 unsigned int access_prot_reg;
2489
2490
2491 access_prot_reg = MV_REG_READ (MV64460_ETH_ACCESS_PROTECTION_REG
2492 (eth_port_num));
2493 access_prot_reg &= (~(3 << (param->win * 2)));
2494 access_prot_reg |= (param->access_ctrl << (param->win * 2));
2495 MV_REG_WRITE (MV64460_ETH_ACCESS_PROTECTION_REG (eth_port_num),
2496 access_prot_reg);
2497
2498
2499 MV_REG_WRITE ((MV64460_ETH_SIZE_REG_0 +
2500 (ETH_SIZE_REG_GAP * param->win)),
2501 (((param->size / 0x10000) - 1) << 16));
2502
2503
2504 MV_REG_WRITE ((MV64460_ETH_BAR_0 + (ETH_BAR_GAP * param->win)),
2505 (param->target | param->attributes | param->base_addr));
2506
2507 if (param->win < 4)
2508 MV_REG_WRITE ((MV64460_ETH_HIGH_ADDR_REMAP_REG_0 +
2509 (ETH_HIGH_ADDR_REMAP_REG_GAP * param->win)),
2510 param->high_addr);
2511
2512
2513 if (param->enable == 1)
2514 MV_RESET_REG_BITS (MV64460_ETH_BASE_ADDR_ENABLE_REG,
2515 (1 << param->win));
2516 else
2517 MV_SET_REG_BITS (MV64460_ETH_BASE_ADDR_ENABLE_REG,
2518 (1 << param->win));
2519}
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551static bool ether_init_rx_desc_ring (ETH_PORT_INFO * p_eth_port_ctrl,
2552 ETH_QUEUE rx_queue,
2553 int rx_desc_num,
2554 int rx_buff_size,
2555 unsigned int rx_desc_base_addr,
2556 unsigned int rx_buff_base_addr)
2557{
2558 ETH_RX_DESC *p_rx_desc;
2559 ETH_RX_DESC *p_rx_prev_desc;
2560 unsigned int buffer_addr;
2561 int ix;
2562
2563
2564 p_rx_desc = (ETH_RX_DESC *) rx_desc_base_addr;
2565 p_rx_prev_desc = p_rx_desc;
2566 buffer_addr = rx_buff_base_addr;
2567
2568
2569 if (rx_buff_base_addr & 0xF)
2570 return false;
2571
2572
2573 if ((rx_buff_size < 8) || (rx_buff_size > RX_BUFFER_MAX_SIZE))
2574 return false;
2575
2576
2577 if ((rx_buff_base_addr + rx_buff_size) & 0x7)
2578 return false;
2579
2580
2581 for (ix = 0; ix < rx_desc_num; ix++) {
2582 p_rx_desc->buf_size = rx_buff_size;
2583 p_rx_desc->byte_cnt = 0x0000;
2584 p_rx_desc->cmd_sts =
2585 ETH_BUFFER_OWNED_BY_DMA | ETH_RX_ENABLE_INTERRUPT;
2586 p_rx_desc->next_desc_ptr =
2587 ((unsigned int) p_rx_desc) + RX_DESC_ALIGNED_SIZE;
2588 p_rx_desc->buf_ptr = buffer_addr;
2589 p_rx_desc->return_info = 0x00000000;
2590 D_CACHE_FLUSH_LINE (p_rx_desc, 0);
2591 buffer_addr += rx_buff_size;
2592 p_rx_prev_desc = p_rx_desc;
2593 p_rx_desc = (ETH_RX_DESC *)
2594 ((unsigned int) p_rx_desc + RX_DESC_ALIGNED_SIZE);
2595 }
2596
2597
2598 p_rx_prev_desc->next_desc_ptr = (rx_desc_base_addr);
2599 D_CACHE_FLUSH_LINE (p_rx_prev_desc, 0);
2600
2601
2602 CURR_RFD_SET ((ETH_RX_DESC *) rx_desc_base_addr, rx_queue);
2603 USED_RFD_SET ((ETH_RX_DESC *) rx_desc_base_addr, rx_queue);
2604
2605 p_eth_port_ctrl->p_rx_desc_area_base[rx_queue] =
2606 (ETH_RX_DESC *) rx_desc_base_addr;
2607 p_eth_port_ctrl->rx_desc_area_size[rx_queue] =
2608 rx_desc_num * RX_DESC_ALIGNED_SIZE;
2609
2610 p_eth_port_ctrl->port_rx_queue_command |= (1 << rx_queue);
2611
2612 return true;
2613}
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645static bool ether_init_tx_desc_ring (ETH_PORT_INFO * p_eth_port_ctrl,
2646 ETH_QUEUE tx_queue,
2647 int tx_desc_num,
2648 int tx_buff_size,
2649 unsigned int tx_desc_base_addr,
2650 unsigned int tx_buff_base_addr)
2651{
2652
2653 ETH_TX_DESC *p_tx_desc;
2654 ETH_TX_DESC *p_tx_prev_desc;
2655 unsigned int buffer_addr;
2656 int ix;
2657
2658
2659
2660 p_tx_desc = (ETH_TX_DESC *) tx_desc_base_addr;
2661 p_tx_prev_desc = p_tx_desc;
2662 buffer_addr = tx_buff_base_addr;
2663
2664
2665 if (tx_buff_base_addr & 0xF)
2666 return false;
2667
2668
2669 if ((tx_buff_size > TX_BUFFER_MAX_SIZE)
2670 || (tx_buff_size < TX_BUFFER_MIN_SIZE))
2671 return false;
2672
2673
2674 for (ix = 0; ix < tx_desc_num; ix++) {
2675 p_tx_desc->byte_cnt = 0x0000;
2676 p_tx_desc->l4i_chk = 0x0000;
2677 p_tx_desc->cmd_sts = 0x00000000;
2678 p_tx_desc->next_desc_ptr =
2679 ((unsigned int) p_tx_desc) + TX_DESC_ALIGNED_SIZE;
2680
2681 p_tx_desc->buf_ptr = buffer_addr;
2682 p_tx_desc->return_info = 0x00000000;
2683 D_CACHE_FLUSH_LINE (p_tx_desc, 0);
2684 buffer_addr += tx_buff_size;
2685 p_tx_prev_desc = p_tx_desc;
2686 p_tx_desc = (ETH_TX_DESC *)
2687 ((unsigned int) p_tx_desc + TX_DESC_ALIGNED_SIZE);
2688
2689 }
2690
2691 p_tx_prev_desc->next_desc_ptr = tx_desc_base_addr;
2692 D_CACHE_FLUSH_LINE (p_tx_prev_desc, 0);
2693
2694 CURR_TFD_SET ((ETH_TX_DESC *) tx_desc_base_addr, tx_queue);
2695 USED_TFD_SET ((ETH_TX_DESC *) tx_desc_base_addr, tx_queue);
2696
2697
2698 p_eth_port_ctrl->p_tx_desc_area_base[tx_queue] =
2699 (ETH_TX_DESC *) tx_desc_base_addr;
2700 p_eth_port_ctrl->tx_desc_area_size[tx_queue] =
2701 (tx_desc_num * TX_DESC_ALIGNED_SIZE);
2702
2703
2704 p_eth_port_ctrl->port_tx_queue_command |= (1 << tx_queue);
2705
2706 return true;
2707}
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737static ETH_FUNC_RET_STATUS eth_port_send (ETH_PORT_INFO * p_eth_port_ctrl,
2738 ETH_QUEUE tx_queue,
2739 PKT_INFO * p_pkt_info)
2740{
2741 volatile ETH_TX_DESC *p_tx_desc_first;
2742 volatile ETH_TX_DESC *p_tx_desc_curr;
2743 volatile ETH_TX_DESC *p_tx_next_desc_curr;
2744 volatile ETH_TX_DESC *p_tx_desc_used;
2745 unsigned int command_status;
2746
2747
2748 if (p_eth_port_ctrl->tx_resource_err[tx_queue] == true)
2749 return ETH_QUEUE_FULL;
2750
2751
2752 CURR_TFD_GET (p_tx_desc_curr, tx_queue);
2753 USED_TFD_GET (p_tx_desc_used, tx_queue);
2754
2755 if (p_tx_desc_curr == NULL)
2756 return ETH_ERROR;
2757
2758
2759 p_tx_next_desc_curr = TX_NEXT_DESC_PTR (p_tx_desc_curr, tx_queue);
2760 command_status = p_pkt_info->cmd_sts | ETH_ZERO_PADDING | ETH_GEN_CRC;
2761
2762 if (command_status & (ETH_TX_FIRST_DESC)) {
2763
2764 FIRST_TFD_SET (p_tx_desc_curr, tx_queue);
2765 p_tx_desc_first = p_tx_desc_curr;
2766 } else {
2767 FIRST_TFD_GET (p_tx_desc_first, tx_queue);
2768 command_status |= ETH_BUFFER_OWNED_BY_DMA;
2769 }
2770
2771
2772
2773
2774 if (p_pkt_info->byte_cnt <= 8) {
2775 printf ("You have failed in the < 8 bytes errata - fixme\n");
2776 return ETH_ERROR;
2777
2778 p_tx_desc_curr->buf_ptr =
2779 (unsigned int) p_tx_desc_curr + TX_BUF_OFFSET_IN_DESC;
2780 eth_b_copy (p_pkt_info->buf_ptr, p_tx_desc_curr->buf_ptr,
2781 p_pkt_info->byte_cnt);
2782 } else
2783 p_tx_desc_curr->buf_ptr = p_pkt_info->buf_ptr;
2784
2785 p_tx_desc_curr->byte_cnt = p_pkt_info->byte_cnt;
2786 p_tx_desc_curr->return_info = p_pkt_info->return_info;
2787
2788 if (p_pkt_info->cmd_sts & (ETH_TX_LAST_DESC)) {
2789
2790 p_tx_desc_curr->cmd_sts = command_status |
2791 ETH_BUFFER_OWNED_BY_DMA | ETH_TX_ENABLE_INTERRUPT;
2792
2793 if (p_tx_desc_curr != p_tx_desc_first)
2794 p_tx_desc_first->cmd_sts |= ETH_BUFFER_OWNED_BY_DMA;
2795
2796
2797
2798 D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_curr, 0);
2799 D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_first, 0);
2800 CPU_PIPE_FLUSH;
2801
2802
2803 ETH_ENABLE_TX_QUEUE (tx_queue, p_eth_port_ctrl->port_num);
2804
2805
2806 p_tx_desc_first = p_tx_next_desc_curr;
2807 FIRST_TFD_SET (p_tx_desc_first, tx_queue);
2808
2809 } else {
2810 p_tx_desc_curr->cmd_sts = command_status;
2811 D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_curr, 0);
2812 }
2813
2814
2815 if (p_tx_next_desc_curr == p_tx_desc_used) {
2816
2817 CURR_TFD_SET (p_tx_desc_first, tx_queue);
2818
2819 p_eth_port_ctrl->tx_resource_err[tx_queue] = true;
2820 return ETH_QUEUE_LAST_RESOURCE;
2821 } else {
2822
2823 CURR_TFD_SET (p_tx_next_desc_curr, tx_queue);
2824 return ETH_OK;
2825 }
2826}
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853static ETH_FUNC_RET_STATUS eth_tx_return_desc (ETH_PORT_INFO *
2854 p_eth_port_ctrl,
2855 ETH_QUEUE tx_queue,
2856 PKT_INFO * p_pkt_info)
2857{
2858 volatile ETH_TX_DESC *p_tx_desc_used = NULL;
2859 volatile ETH_TX_DESC *p_tx_desc_first = NULL;
2860 unsigned int command_status;
2861
2862
2863
2864 USED_TFD_GET (p_tx_desc_used, tx_queue);
2865 FIRST_TFD_GET (p_tx_desc_first, tx_queue);
2866
2867
2868
2869 if (p_tx_desc_used == NULL)
2870 return ETH_ERROR;
2871
2872 command_status = p_tx_desc_used->cmd_sts;
2873
2874
2875 if (command_status & (ETH_BUFFER_OWNED_BY_DMA)) {
2876 D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_used, 0);
2877 return ETH_RETRY;
2878 }
2879
2880
2881 if ((p_tx_desc_used == p_tx_desc_first) &&
2882 (p_eth_port_ctrl->tx_resource_err[tx_queue] == false)) {
2883 D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_used, 0);
2884 return ETH_END_OF_JOB;
2885 }
2886
2887
2888 p_pkt_info->cmd_sts = command_status;
2889 p_pkt_info->return_info = p_tx_desc_used->return_info;
2890 p_tx_desc_used->return_info = 0;
2891
2892
2893 USED_TFD_SET (TX_NEXT_DESC_PTR (p_tx_desc_used, tx_queue), tx_queue);
2894
2895
2896 if (p_eth_port_ctrl->tx_resource_err[tx_queue] == true)
2897 p_eth_port_ctrl->tx_resource_err[tx_queue] = false;
2898
2899 D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_used, 0);
2900
2901 return ETH_OK;
2902
2903}
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930static ETH_FUNC_RET_STATUS eth_port_receive (ETH_PORT_INFO * p_eth_port_ctrl,
2931 ETH_QUEUE rx_queue,
2932 PKT_INFO * p_pkt_info)
2933{
2934 volatile ETH_RX_DESC *p_rx_curr_desc;
2935 volatile ETH_RX_DESC *p_rx_next_curr_desc;
2936 volatile ETH_RX_DESC *p_rx_used_desc;
2937 unsigned int command_status;
2938
2939
2940 if (p_eth_port_ctrl->rx_resource_err[rx_queue] == true) {
2941 printf ("\nRx Queue is full ...\n");
2942 return ETH_QUEUE_FULL;
2943 }
2944
2945
2946 CURR_RFD_GET (p_rx_curr_desc, rx_queue);
2947 USED_RFD_GET (p_rx_used_desc, rx_queue);
2948
2949
2950 if (p_rx_curr_desc == NULL)
2951 return ETH_ERROR;
2952
2953
2954 p_rx_next_curr_desc = RX_NEXT_DESC_PTR (p_rx_curr_desc, rx_queue);
2955 command_status = p_rx_curr_desc->cmd_sts;
2956
2957
2958 if (command_status & (ETH_BUFFER_OWNED_BY_DMA)) {
2959
2960 D_CACHE_FLUSH_LINE ((unsigned int) p_rx_curr_desc, 0);
2961
2962 return ETH_END_OF_JOB;
2963 }
2964
2965 p_pkt_info->byte_cnt = (p_rx_curr_desc->byte_cnt) - RX_BUF_OFFSET;
2966 p_pkt_info->cmd_sts = command_status;
2967 p_pkt_info->buf_ptr = (p_rx_curr_desc->buf_ptr) + RX_BUF_OFFSET;
2968 p_pkt_info->return_info = p_rx_curr_desc->return_info;
2969 p_pkt_info->l4i_chk = p_rx_curr_desc->buf_size;
2970
2971
2972
2973 p_rx_curr_desc->return_info = 0;
2974
2975
2976 CURR_RFD_SET (p_rx_next_curr_desc, rx_queue);
2977
2978
2979 if (p_rx_next_curr_desc == p_rx_used_desc)
2980 p_eth_port_ctrl->rx_resource_err[rx_queue] = true;
2981
2982 D_CACHE_FLUSH_LINE ((unsigned int) p_rx_curr_desc, 0);
2983 CPU_PIPE_FLUSH;
2984 return ETH_OK;
2985}
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009static ETH_FUNC_RET_STATUS eth_rx_return_buff (ETH_PORT_INFO *
3010 p_eth_port_ctrl,
3011 ETH_QUEUE rx_queue,
3012 PKT_INFO * p_pkt_info)
3013{
3014 volatile ETH_RX_DESC *p_used_rx_desc;
3015
3016
3017 USED_RFD_GET (p_used_rx_desc, rx_queue);
3018
3019
3020 if (p_used_rx_desc == NULL)
3021 return ETH_ERROR;
3022
3023 p_used_rx_desc->buf_ptr = p_pkt_info->buf_ptr;
3024 p_used_rx_desc->return_info = p_pkt_info->return_info;
3025 p_used_rx_desc->byte_cnt = p_pkt_info->byte_cnt;
3026 p_used_rx_desc->buf_size = MV64460_RX_BUFFER_SIZE;
3027
3028
3029 CPU_PIPE_FLUSH;
3030
3031
3032 p_used_rx_desc->cmd_sts =
3033 ETH_BUFFER_OWNED_BY_DMA | ETH_RX_ENABLE_INTERRUPT;
3034
3035
3036 D_CACHE_FLUSH_LINE ((unsigned int) p_used_rx_desc, 0);
3037 CPU_PIPE_FLUSH;
3038
3039
3040 USED_RFD_SET (RX_NEXT_DESC_PTR (p_used_rx_desc, rx_queue), rx_queue);
3041
3042
3043 if (p_eth_port_ctrl->rx_resource_err[rx_queue] == true)
3044 p_eth_port_ctrl->rx_resource_err[rx_queue] = false;
3045
3046 return ETH_OK;
3047}
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072#if 0
3073static unsigned int eth_port_set_rx_coal (ETH_PORT eth_port_num,
3074 unsigned int t_clk,
3075 unsigned int delay)
3076{
3077 unsigned int coal;
3078
3079 coal = ((t_clk / 1000000) * delay) / 64;
3080
3081 MV_REG_WRITE (MV64460_ETH_SDMA_CONFIG_REG (eth_port_num),
3082 ((coal & 0x3fff) << 8) |
3083 (MV_REG_READ
3084 (MV64460_ETH_SDMA_CONFIG_REG (eth_port_num))
3085 & 0xffc000ff));
3086 return coal;
3087}
3088
3089#endif
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113#if 0
3114static unsigned int eth_port_set_tx_coal (ETH_PORT eth_port_num,
3115 unsigned int t_clk,
3116 unsigned int delay)
3117{
3118 unsigned int coal;
3119
3120 coal = ((t_clk / 1000000) * delay) / 64;
3121
3122 MV_REG_WRITE (MV64460_ETH_TX_FIFO_URGENT_THRESHOLD_REG (eth_port_num),
3123 coal << 4);
3124 return coal;
3125}
3126#endif
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148static void eth_b_copy (unsigned int src_addr, unsigned int dst_addr,
3149 int byte_count)
3150{
3151
3152 *(unsigned int *) dst_addr = 0x0;
3153
3154 while (byte_count != 0) {
3155 *(char *) dst_addr = *(char *) src_addr;
3156 dst_addr++;
3157 src_addr++;
3158 byte_count--;
3159 }
3160}
3161