3 * Ingo Assmus <ingo.assmus@keymile.com>
5 * based on - Driver for MV64460X ethernet ports
6 * Copyright (C) 2002 rabeeh@galileo.co.il
8 * See file CREDITS for list of people who contributed to this
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of
14 3 the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
28 * mv_eth.c - header file for the polled mode GT ethernet driver
37 /* enable Debug outputs */
48 /* PHY DFCDL Registers */
49 #define ETH_PHY_DFCDL_CONFIG0_REG 0x2100
50 #define ETH_PHY_DFCDL_CONFIG1_REG 0x2104
51 #define ETH_PHY_DFCDL_ADDR_REG 0x2110
52 #define ETH_PHY_DFCDL_DATA0_REG 0x2114
54 #define PHY_AUTONEGOTIATE_TIMEOUT 4000 /* 4000 ms autonegotiate timeout */
55 #define PHY_UPDATE_TIMEOUT 10000
57 #undef MV64460_CHECKSUM_OFFLOAD
58 /*************************************************************************
59 * The first part is the high level driver of the gigE ethernet ports. *
60 *************************************************************************/
62 /* Definition for configuring driver */
63 /* #define UPDATE_STATS_BY_SOFTWARE */
64 #undef MV64460_RX_QUEUE_FILL_ON_TASK
67 #define MAGIC_ETH_RUNNING 8031971
68 #define MV64460_INTERNAL_SRAM_SIZE _256K
69 #define EXTRA_BYTES 32
70 #define WRAP ETH_HLEN + 2 + 4 + 16
71 #define BUFFER_MTU dev->mtu + WRAP
72 #define INT_CAUSE_UNMASK_ALL 0x0007ffff
73 #define INT_CAUSE_UNMASK_ALL_EXT 0x0011ffff
74 #ifdef MV64460_RX_FILL_ON_TASK
75 #define INT_CAUSE_MASK_ALL 0x00000000
76 #define INT_CAUSE_CHECK_BITS INT_CAUSE_UNMASK_ALL
77 #define INT_CAUSE_CHECK_BITS_EXT INT_CAUSE_UNMASK_ALL_EXT
80 /* Read/Write to/from MV64460 internal registers */
81 #define MV_REG_READ(offset) my_le32_to_cpu(* (volatile unsigned int *) (INTERNAL_REG_BASE_ADDR + offset))
82 #define MV_REG_WRITE(offset,data) *(volatile unsigned int *) (INTERNAL_REG_BASE_ADDR + offset) = my_cpu_to_le32 (data)
83 #define MV_SET_REG_BITS(regOffset,bits) ((*((volatile unsigned int*)((INTERNAL_REG_BASE_ADDR) + (regOffset)))) |= ((unsigned int)my_cpu_to_le32(bits)))
84 #define MV_RESET_REG_BITS(regOffset,bits) ((*((volatile unsigned int*)((INTERNAL_REG_BASE_ADDR) + (regOffset)))) &= ~((unsigned int)my_cpu_to_le32(bits)))
86 #define my_cpu_to_le32(x) my_le32_to_cpu((x))
88 /* Static function declarations */
89 static int mv64460_eth_real_open (struct eth_device *eth);
90 static int mv64460_eth_real_stop (struct eth_device *eth);
91 static struct net_device_stats *mv64460_eth_get_stats (struct eth_device
93 static void eth_port_init_mac_tables (ETH_PORT eth_port_num);
94 static void mv64460_eth_update_stat (struct eth_device *dev);
95 bool db64460_eth_start (struct eth_device *eth);
96 unsigned int eth_read_mib_counter (ETH_PORT eth_port_num,
97 unsigned int mib_offset);
98 int mv64460_eth_receive (struct eth_device *dev);
100 int mv64460_eth_xmit (struct eth_device *, volatile void *packet, int length);
102 int mv_miiphy_read(const char *devname, unsigned char phy_addr,
103 unsigned char phy_reg, unsigned short *value);
104 int mv_miiphy_write(const char *devname, unsigned char phy_addr,
105 unsigned char phy_reg, unsigned short value);
107 int phy_setup_aneg (char *devname, unsigned char addr);
109 #ifndef UPDATE_STATS_BY_SOFTWARE
110 static void mv64460_eth_print_stat (struct eth_device *dev);
112 /* Processes a received packet */
113 extern void NetReceive (volatile uchar *, int);
115 extern unsigned int INTERNAL_REG_BASE_ADDR;
117 unsigned long my_le32_to_cpu (unsigned long x)
119 return (((x & 0x000000ffU) << 24) |
120 ((x & 0x0000ff00U) << 8) |
121 ((x & 0x00ff0000U) >> 8) | ((x & 0xff000000U) >> 24));
124 /*************************************************
125 *Helper functions - used inside the driver only *
126 *************************************************/
128 void print_globals (struct eth_device *dev)
130 printf ("Ethernet PRINT_Globals-Debug function\n");
131 printf ("Base Address for ETH_PORT_INFO: %08x\n",
132 (unsigned int) dev->priv);
133 printf ("Base Address for mv64460_eth_priv: %08x\n",
134 (unsigned int) &(((ETH_PORT_INFO *) dev->priv)->
137 printf ("GT Internal Base Address: %08x\n",
138 INTERNAL_REG_BASE_ADDR);
139 printf ("Base Address for TX-DESCs: %08x Number of allocated Buffers %d\n",
140 (unsigned int) ((ETH_PORT_INFO *) dev->priv)->p_tx_desc_area_base[0], MV64460_TX_QUEUE_SIZE);
141 printf ("Base Address for RX-DESCs: %08x Number of allocated Buffers %d\n",
142 (unsigned int) ((ETH_PORT_INFO *) dev->priv)->p_rx_desc_area_base[0], MV64460_RX_QUEUE_SIZE);
143 printf ("Base Address for RX-Buffer: %08x allocated Bytes %d\n",
144 (unsigned int) ((ETH_PORT_INFO *) dev->priv)->
146 (MV64460_RX_QUEUE_SIZE * MV64460_RX_BUFFER_SIZE) + 32);
147 printf ("Base Address for TX-Buffer: %08x allocated Bytes %d\n",
148 (unsigned int) ((ETH_PORT_INFO *) dev->priv)->
150 (MV64460_TX_QUEUE_SIZE * MV64460_TX_BUFFER_SIZE) + 32);
154 /**********************************************************************
155 * mv64460_eth_print_phy_status
157 * Prints gigabit ethenret phy status
159 * Input : pointer to ethernet interface network device structure
161 **********************************************************************/
162 void mv64460_eth_print_phy_status (struct eth_device *dev)
164 struct mv64460_eth_priv *port_private;
165 unsigned int port_num;
166 ETH_PORT_INFO *ethernet_private = (ETH_PORT_INFO *) dev->priv;
167 unsigned int port_status, phy_reg_data;
170 (struct mv64460_eth_priv *) ethernet_private->port_private;
171 port_num = port_private->port_num;
173 /* Check Link status on phy */
174 eth_port_read_smi_reg (port_num, 1, &phy_reg_data);
175 if (!(phy_reg_data & 0x20)) {
176 printf ("Ethernet port changed link status to DOWN\n");
179 MV_REG_READ (MV64460_ETH_PORT_STATUS_REG (port_num));
180 printf ("Ethernet status port %d: Link up", port_num);
182 (port_status & BIT2) ? "Full Duplex" : "Half Duplex");
183 if (port_status & BIT4)
184 printf (", Speed 1 Gbps");
187 (port_status & BIT5) ? "Speed 100 Mbps" :
193 /**********************************************************************
194 * u-boot entry functions for mv64460_eth
196 **********************************************************************/
197 int db64460_eth_probe (struct eth_device *dev)
199 return ((int) db64460_eth_start (dev));
202 int db64460_eth_poll (struct eth_device *dev)
204 return mv64460_eth_receive (dev);
207 int db64460_eth_transmit (struct eth_device *dev, volatile void *packet,
210 mv64460_eth_xmit (dev, packet, length);
214 void db64460_eth_disable (struct eth_device *dev)
216 mv64460_eth_stop (dev);
219 #define DFCDL(write,read) ((write << 6) | read)
220 unsigned int ethDfcdls[] = {
221 DFCDL(0,0), DFCDL(1,1), DFCDL(2,2), DFCDL(3,3),
222 DFCDL(4,4), DFCDL(5,5), DFCDL(6,6), DFCDL(7,7),
223 DFCDL(8,8), DFCDL(9,9), DFCDL(10,10), DFCDL(11,11),
224 DFCDL(12,12), DFCDL(13,13), DFCDL(14,14), DFCDL(15,15),
225 DFCDL(16,16), DFCDL(17,17), DFCDL(18,18), DFCDL(19,19),
226 DFCDL(20,20), DFCDL(21,21), DFCDL(22,22), DFCDL(23,23),
227 DFCDL(24,24), DFCDL(25,25), DFCDL(26,26), DFCDL(27,27),
228 DFCDL(28,28), DFCDL(29,29), DFCDL(30,30), DFCDL(31,31),
229 DFCDL(32,32), DFCDL(33,33), DFCDL(34,34), DFCDL(35,35),
230 DFCDL(36,36), DFCDL(37,37), DFCDL(38,38), DFCDL(39,39),
231 DFCDL(40,40), DFCDL(41,41), DFCDL(42,42), DFCDL(43,43),
232 DFCDL(44,44), DFCDL(45,45), DFCDL(46,46), DFCDL(47,47),
233 DFCDL(48,48), DFCDL(49,49), DFCDL(50,50), DFCDL(51,51),
234 DFCDL(52,52), DFCDL(53,53), DFCDL(54,54), DFCDL(55,55),
235 DFCDL(56,56), DFCDL(57,57), DFCDL(58,58), DFCDL(59,59),
236 DFCDL(60,60), DFCDL(61,61), DFCDL(62,62), DFCDL(63,63),
239 void mv_eth_phy_init (void)
243 MV_REG_WRITE (ETH_PHY_DFCDL_ADDR_REG, 0);
245 for (i = 0; i < 64; i++) {
246 MV_REG_WRITE (ETH_PHY_DFCDL_DATA0_REG, ethDfcdls[i]);
249 MV_REG_WRITE (ETH_PHY_DFCDL_CONFIG0_REG, 0x300000);
252 void mv6446x_eth_initialize (bd_t * bis)
254 struct eth_device *dev;
255 ETH_PORT_INFO *ethernet_private;
256 struct mv64460_eth_priv *port_private;
258 char *s, *e, buf[64];
261 * Set RGMII clock drives strength
263 temp = MV_REG_READ(0x20A0);
265 MV_REG_WRITE(0x20A0, temp);
269 for (devnum = 0; devnum < MV_ETH_DEVS; devnum++) {
270 dev = calloc (sizeof (*dev), 1);
272 printf ("%s: mv_enet%d allocation failure, %s\n",
273 __FUNCTION__, devnum, "eth_device structure");
277 /* must be less than NAMESIZE (16) */
278 sprintf (dev->name, "mv_enet%d", devnum);
281 printf ("Initializing %s\n", dev->name);
284 /* Extract the MAC address from the environment */
295 default: /* this should never happen */
296 printf ("%s: Invalid device number %d\n",
297 __FUNCTION__, devnum);
301 temp = getenv_f(s, buf, sizeof (buf));
302 s = (temp > 0) ? buf : NULL;
305 printf ("Setting MAC %d to %s\n", devnum, s);
307 for (x = 0; x < 6; ++x) {
308 dev->enetaddr[x] = s ? simple_strtoul (s, &e, 16) : 0;
310 s = (*e) ? e + 1 : e;
312 /* ronen - set the MAC addr in the HW */
313 eth_port_uc_addr_set (devnum, dev->enetaddr, 0);
315 dev->init = (void *) db64460_eth_probe;
316 dev->halt = (void *) ethernet_phy_reset;
317 dev->send = (void *) db64460_eth_transmit;
318 dev->recv = (void *) db64460_eth_poll;
320 ethernet_private = calloc (sizeof (*ethernet_private), 1);
321 dev->priv = (void *)ethernet_private;
322 if (!ethernet_private) {
323 printf ("%s: %s allocation failure, %s\n",
324 __FUNCTION__, dev->name,
325 "Private Device Structure");
329 /* start with an zeroed ETH_PORT_INFO */
330 memset (ethernet_private, 0, sizeof (ETH_PORT_INFO));
331 memcpy (ethernet_private->port_mac_addr, dev->enetaddr, 6);
333 /* set pointer to memory for stats data structure etc... */
334 port_private = calloc (sizeof (*ethernet_private), 1);
335 ethernet_private->port_private = (void *)port_private;
337 printf ("%s: %s allocation failure, %s\n",
338 __FUNCTION__, dev->name,
339 "Port Private Device Structure");
341 free (ethernet_private);
346 port_private->stats =
347 calloc (sizeof (struct net_device_stats), 1);
348 if (!port_private->stats) {
349 printf ("%s: %s allocation failure, %s\n",
350 __FUNCTION__, dev->name,
351 "Net stat Structure");
354 free (ethernet_private);
358 memset (ethernet_private->port_private, 0,
359 sizeof (struct mv64460_eth_priv));
362 ethernet_private->port_num = ETH_0;
365 ethernet_private->port_num = ETH_1;
368 ethernet_private->port_num = ETH_2;
371 printf ("Invalid device number %d\n", devnum);
375 port_private->port_num = devnum;
377 * Read MIB counter on the GT in order to reset them,
378 * then zero all the stats fields in memory
380 mv64460_eth_update_stat (dev);
381 memset (port_private->stats, 0,
382 sizeof (struct net_device_stats));
383 /* Extract the MAC address from the environment */
394 default: /* this should never happen */
395 printf ("%s: Invalid device number %d\n",
396 __FUNCTION__, devnum);
400 temp = getenv_f(s, buf, sizeof (buf));
401 s = (temp > 0) ? buf : NULL;
404 printf ("Setting MAC %d to %s\n", devnum, s);
406 for (x = 0; x < 6; ++x) {
407 dev->enetaddr[x] = s ? simple_strtoul (s, &e, 16) : 0;
409 s = (*e) ? e + 1 : e;
412 DP (printf ("Allocating descriptor and buffer rings\n"));
414 ethernet_private->p_rx_desc_area_base[0] =
415 (ETH_RX_DESC *) memalign (16,
416 RX_DESC_ALIGNED_SIZE *
417 MV64460_RX_QUEUE_SIZE + 1);
418 ethernet_private->p_tx_desc_area_base[0] =
419 (ETH_TX_DESC *) memalign (16,
420 TX_DESC_ALIGNED_SIZE *
421 MV64460_TX_QUEUE_SIZE + 1);
423 ethernet_private->p_rx_buffer_base[0] =
424 (char *) memalign (16,
425 MV64460_RX_QUEUE_SIZE *
426 MV64460_TX_BUFFER_SIZE + 1);
427 ethernet_private->p_tx_buffer_base[0] =
428 (char *) memalign (16,
429 MV64460_RX_QUEUE_SIZE *
430 MV64460_TX_BUFFER_SIZE + 1);
433 /* DEBUG OUTPUT prints adresses of globals */
438 miiphy_register(dev->name, mv_miiphy_read, mv_miiphy_write);
440 DP (printf ("%s: exit\n", __FUNCTION__));
444 /**********************************************************************
447 * This function is called when openning the network device. The function
448 * should initialize all the hardware, initialize cyclic Rx/Tx
449 * descriptors chain and buffers and allocate an IRQ to the network
452 * Input : a pointer to the network device structure
453 * / / ronen - changed the output to match net/eth.c needs
454 * Output : nonzero of success , zero if fails.
456 **********************************************************************/
458 int mv64460_eth_open (struct eth_device *dev)
460 return (mv64460_eth_real_open (dev));
463 /* Helper function for mv64460_eth_open */
464 static int mv64460_eth_real_open (struct eth_device *dev)
468 ETH_PORT_INFO *ethernet_private;
469 struct mv64460_eth_priv *port_private;
470 unsigned int port_num;
477 ethernet_private = (ETH_PORT_INFO *) dev->priv;
478 /* ronen - when we update the MAC env params we only update dev->enetaddr
479 see ./net/eth.c eth_set_enetaddr() */
480 memcpy (ethernet_private->port_mac_addr, dev->enetaddr, 6);
482 port_private = (struct mv64460_eth_priv *) ethernet_private->port_private;
483 port_num = port_private->port_num;
486 MV_REG_WRITE (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG (port_num), 0x0000ff00);
488 /* Clear the ethernet port interrupts */
489 MV_REG_WRITE (MV64460_ETH_INTERRUPT_CAUSE_REG (port_num), 0);
490 MV_REG_WRITE (MV64460_ETH_INTERRUPT_CAUSE_EXTEND_REG (port_num), 0);
492 /* Unmask RX buffer and TX end interrupt */
493 MV_REG_WRITE (MV64460_ETH_INTERRUPT_MASK_REG (port_num),
494 INT_CAUSE_UNMASK_ALL);
496 /* Unmask phy and link status changes interrupts */
497 MV_REG_WRITE (MV64460_ETH_INTERRUPT_EXTEND_MASK_REG (port_num),
498 INT_CAUSE_UNMASK_ALL_EXT);
500 /* Set phy address of the port */
501 ethernet_private->port_phy_addr = 0x1 + (port_num << 1);
502 reg = ethernet_private->port_phy_addr;
504 /* Activate the DMA channels etc */
505 eth_port_init (ethernet_private);
507 /* "Allocate" setup TX rings */
509 for (queue = 0; queue < MV64460_TX_QUEUE_NUM; queue++) {
512 port_private->tx_ring_size[queue] = MV64460_TX_QUEUE_SIZE;
513 size = (port_private->tx_ring_size[queue] * TX_DESC_ALIGNED_SIZE); /*size = no of DESCs times DESC-size */
514 ethernet_private->tx_desc_area_size[queue] = size;
516 /* first clear desc area completely */
517 memset ((void *) ethernet_private->p_tx_desc_area_base[queue],
518 0, ethernet_private->tx_desc_area_size[queue]);
520 /* initialize tx desc ring with low level driver */
521 if (ether_init_tx_desc_ring
522 (ethernet_private, ETH_Q0,
523 port_private->tx_ring_size[queue],
524 MV64460_TX_BUFFER_SIZE /* Each Buffer is 1600 Byte */ ,
525 (unsigned int) ethernet_private->
526 p_tx_desc_area_base[queue],
527 (unsigned int) ethernet_private->
528 p_tx_buffer_base[queue]) == false)
529 printf ("### Error initializing TX Ring\n");
532 /* "Allocate" setup RX rings */
533 for (queue = 0; queue < MV64460_RX_QUEUE_NUM; queue++) {
536 /* Meantime RX Ring are fixed - but must be configurable by user */
537 port_private->rx_ring_size[queue] = MV64460_RX_QUEUE_SIZE;
538 size = (port_private->rx_ring_size[queue] *
539 RX_DESC_ALIGNED_SIZE);
540 ethernet_private->rx_desc_area_size[queue] = size;
542 /* first clear desc area completely */
543 memset ((void *) ethernet_private->p_rx_desc_area_base[queue],
544 0, ethernet_private->rx_desc_area_size[queue]);
545 if ((ether_init_rx_desc_ring
546 (ethernet_private, ETH_Q0,
547 port_private->rx_ring_size[queue],
548 MV64460_RX_BUFFER_SIZE /* Each Buffer is 1600 Byte */ ,
549 (unsigned int) ethernet_private->
550 p_rx_desc_area_base[queue],
551 (unsigned int) ethernet_private->
552 p_rx_buffer_base[queue])) == false)
553 printf ("### Error initializing RX Ring\n");
556 eth_port_start (ethernet_private);
558 /* Set maximum receive buffer to 9700 bytes */
559 MV_REG_WRITE (MV64460_ETH_PORT_SERIAL_CONTROL_REG (port_num),
562 (MV64460_ETH_PORT_SERIAL_CONTROL_REG (port_num))
566 * Set ethernet MTU for leaky bucket mechanism to 0 - this will
567 * disable the leaky bucket mechanism .
570 MV_REG_WRITE (MV64460_ETH_MAXIMUM_TRANSMIT_UNIT (port_num), 0);
571 MV_REG_READ (MV64460_ETH_PORT_STATUS_REG (port_num));
573 #if defined(CONFIG_PHY_RESET)
575 * Reset the phy, only if its the first time through
576 * otherwise, just check the speeds & feeds
578 if (port_private->first_init == 0) {
579 port_private->first_init = 1;
580 ethernet_phy_reset (port_num);
582 /* Start/Restart autonegotiation */
583 phy_setup_aneg (dev->name, reg);
586 #endif /* defined(CONFIG_PHY_RESET) */
588 miiphy_read (dev->name, reg, MII_BMSR, ®_short);
591 * Wait if PHY is capable of autonegotiation and autonegotiation is not complete
593 if ((reg_short & BMSR_ANEGCAPABLE)
594 && !(reg_short & BMSR_ANEGCOMPLETE)) {
595 puts ("Waiting for PHY auto negotiation to complete");
597 while (!(reg_short & BMSR_ANEGCOMPLETE)) {
601 if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
602 puts (" TIMEOUT !\n");
606 if ((i++ % 1000) == 0) {
609 udelay (1000); /* 1 ms */
610 miiphy_read (dev->name, reg, MII_BMSR, ®_short);
614 udelay (500000); /* another 500 ms (results in faster booting) */
617 speed = miiphy_speed (dev->name, reg);
618 duplex = miiphy_duplex (dev->name, reg);
620 printf ("ENET Speed is %d Mbps - %s duplex connection\n",
621 (int) speed, (duplex == HALF) ? "HALF" : "FULL");
623 port_private->eth_running = MAGIC_ETH_RUNNING;
627 static int mv64460_eth_free_tx_rings (struct eth_device *dev)
630 ETH_PORT_INFO *ethernet_private;
631 struct mv64460_eth_priv *port_private;
632 unsigned int port_num;
633 volatile ETH_TX_DESC *p_tx_curr_desc;
635 ethernet_private = (ETH_PORT_INFO *) dev->priv;
637 (struct mv64460_eth_priv *) ethernet_private->port_private;
638 port_num = port_private->port_num;
641 MV_REG_WRITE (MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG (port_num),
645 DP (printf ("Clearing previously allocated TX queues... "));
646 for (queue = 0; queue < MV64460_TX_QUEUE_NUM; queue++) {
647 /* Free on TX rings */
648 for (p_tx_curr_desc =
649 ethernet_private->p_tx_desc_area_base[queue];
650 ((unsigned int) p_tx_curr_desc <= (unsigned int)
651 ethernet_private->p_tx_desc_area_base[queue] +
652 ethernet_private->tx_desc_area_size[queue]);
654 (ETH_TX_DESC *) ((unsigned int) p_tx_curr_desc +
655 TX_DESC_ALIGNED_SIZE)) {
656 /* this is inside for loop */
657 if (p_tx_curr_desc->return_info != 0) {
658 p_tx_curr_desc->return_info = 0;
659 DP (printf ("freed\n"));
662 DP (printf ("Done\n"));
667 static int mv64460_eth_free_rx_rings (struct eth_device *dev)
670 ETH_PORT_INFO *ethernet_private;
671 struct mv64460_eth_priv *port_private;
672 unsigned int port_num;
673 volatile ETH_RX_DESC *p_rx_curr_desc;
675 ethernet_private = (ETH_PORT_INFO *) dev->priv;
677 (struct mv64460_eth_priv *) ethernet_private->port_private;
678 port_num = port_private->port_num;
681 MV_REG_WRITE (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG (port_num),
685 DP (printf ("Clearing previously allocated RX queues... "));
686 for (queue = 0; queue < MV64460_RX_QUEUE_NUM; queue++) {
687 /* Free preallocated skb's on RX rings */
688 for (p_rx_curr_desc =
689 ethernet_private->p_rx_desc_area_base[queue];
690 (((unsigned int) p_rx_curr_desc <
691 ((unsigned int) ethernet_private->
692 p_rx_desc_area_base[queue] +
693 ethernet_private->rx_desc_area_size[queue])));
695 (ETH_RX_DESC *) ((unsigned int) p_rx_curr_desc +
696 RX_DESC_ALIGNED_SIZE)) {
697 if (p_rx_curr_desc->return_info != 0) {
698 p_rx_curr_desc->return_info = 0;
699 DP (printf ("freed\n"));
702 DP (printf ("Done\n"));
707 /**********************************************************************
710 * This function is used when closing the network device.
711 * It updates the hardware,
712 * release all memory that holds buffers and descriptors and release the IRQ.
713 * Input : a pointer to the device structure
714 * Output : zero if success , nonzero if fails
715 *********************************************************************/
717 int mv64460_eth_stop (struct eth_device *dev)
719 /* Disable all gigE address decoder */
720 MV_REG_WRITE (MV64460_ETH_BASE_ADDR_ENABLE_REG, 0x3f);
721 DP (printf ("%s Ethernet stop called ... \n", __FUNCTION__));
722 mv64460_eth_real_stop (dev);
727 /* Helper function for mv64460_eth_stop */
729 static int mv64460_eth_real_stop (struct eth_device *dev)
731 ETH_PORT_INFO *ethernet_private;
732 struct mv64460_eth_priv *port_private;
733 unsigned int port_num;
735 ethernet_private = (ETH_PORT_INFO *) dev->priv;
737 (struct mv64460_eth_priv *) ethernet_private->port_private;
738 port_num = port_private->port_num;
740 mv64460_eth_free_tx_rings (dev);
741 mv64460_eth_free_rx_rings (dev);
743 eth_port_reset (ethernet_private->port_num);
744 /* Disable ethernet port interrupts */
745 MV_REG_WRITE (MV64460_ETH_INTERRUPT_CAUSE_REG (port_num), 0);
746 MV_REG_WRITE (MV64460_ETH_INTERRUPT_CAUSE_EXTEND_REG (port_num), 0);
747 /* Mask RX buffer and TX end interrupt */
748 MV_REG_WRITE (MV64460_ETH_INTERRUPT_MASK_REG (port_num), 0);
749 /* Mask phy and link status changes interrupts */
750 MV_REG_WRITE (MV64460_ETH_INTERRUPT_EXTEND_MASK_REG (port_num), 0);
751 MV_RESET_REG_BITS (MV64460_CPU_INTERRUPT0_MASK_HIGH,
753 /* Print Network statistics */
754 #ifndef UPDATE_STATS_BY_SOFTWARE
756 * Print statistics (only if ethernet is running),
757 * then zero all the stats fields in memory
759 if (port_private->eth_running == MAGIC_ETH_RUNNING) {
760 port_private->eth_running = 0;
761 mv64460_eth_print_stat (dev);
763 memset (port_private->stats, 0, sizeof (struct net_device_stats));
765 DP (printf ("\nEthernet stopped ... \n"));
769 /**********************************************************************
770 * mv64460_eth_start_xmit
772 * This function is queues a packet in the Tx descriptor for
775 * Input : skb - a pointer to socket buffer
776 * dev - a pointer to the required port
778 * Output : zero upon success
779 **********************************************************************/
781 int mv64460_eth_xmit (struct eth_device *dev, volatile void *dataPtr,
784 ETH_PORT_INFO *ethernet_private;
785 struct mv64460_eth_priv *port_private;
787 ETH_FUNC_RET_STATUS status;
788 struct net_device_stats *stats;
789 ETH_FUNC_RET_STATUS release_result;
791 ethernet_private = (ETH_PORT_INFO *) dev->priv;
793 (struct mv64460_eth_priv *) ethernet_private->port_private;
795 stats = port_private->stats;
797 /* Update packet info data structure */
798 pkt_info.cmd_sts = ETH_TX_FIRST_DESC | ETH_TX_LAST_DESC; /* DMA owned, first last */
799 pkt_info.byte_cnt = dataSize;
800 pkt_info.buf_ptr = (unsigned int) dataPtr;
801 pkt_info.return_info = 0;
803 status = eth_port_send (ethernet_private, ETH_Q0, &pkt_info);
804 if ((status == ETH_ERROR) || (status == ETH_QUEUE_FULL)) {
805 printf ("Error on transmitting packet ..");
806 if (status == ETH_QUEUE_FULL)
807 printf ("ETH Queue is full. \n");
808 if (status == ETH_QUEUE_LAST_RESOURCE)
809 printf ("ETH Queue: using last available resource. \n");
813 /* Update statistics and start of transmittion time */
814 stats->tx_bytes += dataSize;
817 /* Check if packet(s) is(are) transmitted correctly (release everything) */
820 eth_tx_return_desc (ethernet_private, ETH_Q0,
822 switch (release_result) {
824 DP (printf ("descriptor released\n"));
825 if (pkt_info.cmd_sts & BIT0) {
826 printf ("Error in TX\n");
831 DP (printf ("transmission still in process\n"));
835 printf ("routine can not access Tx desc ring\n");
839 DP (printf ("the routine has nothing to release\n"));
841 default: /* should not happen */
844 } while (release_result == ETH_OK);
846 return 0; /* success */
849 /**********************************************************************
850 * mv64460_eth_receive
852 * This function is forward packets that are received from the port's
853 * queues toward kernel core or FastRoute them to another interface.
855 * Input : dev - a pointer to the required interface
856 * max - maximum number to receive (0 means unlimted)
858 * Output : number of served packets
859 **********************************************************************/
861 int mv64460_eth_receive (struct eth_device *dev)
863 ETH_PORT_INFO *ethernet_private;
864 struct mv64460_eth_priv *port_private;
866 struct net_device_stats *stats;
868 ethernet_private = (ETH_PORT_INFO *) dev->priv;
869 port_private = (struct mv64460_eth_priv *) ethernet_private->port_private;
870 stats = port_private->stats;
872 while ((eth_port_receive (ethernet_private, ETH_Q0, &pkt_info) == ETH_OK)) {
874 if (pkt_info.byte_cnt != 0) {
875 printf ("%s: Received %d byte Packet @ 0x%x\n",
876 __FUNCTION__, pkt_info.byte_cnt,
878 if(pkt_info.buf_ptr != 0){
879 for(i=0; i < pkt_info.byte_cnt; i++){
883 printf("%02x", ((char*)pkt_info.buf_ptr)[i]);
889 /* Update statistics. Note byte count includes 4 byte CRC count */
891 stats->rx_bytes += pkt_info.byte_cnt;
894 * In case received a packet without first / last bits on OR the error
895 * summary bit is on, the packets needs to be dropeed.
898 cmd_sts & (ETH_RX_FIRST_DESC | ETH_RX_LAST_DESC)) !=
899 (ETH_RX_FIRST_DESC | ETH_RX_LAST_DESC))
900 || (pkt_info.cmd_sts & ETH_ERROR_SUMMARY)) {
903 printf ("Received packet spread on multiple descriptors\n");
905 /* Is this caused by an error ? */
906 if (pkt_info.cmd_sts & ETH_ERROR_SUMMARY) {
910 /* free these descriptors again without forwarding them to the higher layers */
911 pkt_info.buf_ptr &= ~0x7; /* realign buffer again */
912 pkt_info.byte_cnt = 0x0000; /* Reset Byte count */
914 if (eth_rx_return_buff
915 (ethernet_private, ETH_Q0, &pkt_info) != ETH_OK) {
916 printf ("Error while returning the RX Desc to Ring\n");
918 DP (printf ("RX Desc returned to Ring\n"));
920 /* /free these descriptors again */
923 /* !!! call higher layer processing */
925 printf ("\nNow send it to upper layer protocols (NetReceive) ...\n");
927 /* let the upper layer handle the packet */
928 NetReceive ((uchar *) pkt_info.buf_ptr,
929 (int) pkt_info.byte_cnt);
931 /* **************************************************************** */
932 /* free descriptor */
933 pkt_info.buf_ptr &= ~0x7; /* realign buffer again */
934 pkt_info.byte_cnt = 0x0000; /* Reset Byte count */
935 DP (printf ("RX: pkt_info.buf_ptr = %x\n", pkt_info.buf_ptr));
936 if (eth_rx_return_buff
937 (ethernet_private, ETH_Q0, &pkt_info) != ETH_OK) {
938 printf ("Error while returning the RX Desc to Ring\n");
940 DP (printf ("RX: Desc returned to Ring\n"));
943 /* **************************************************************** */
947 mv64460_eth_get_stats (dev); /* update statistics */
951 /**********************************************************************
952 * mv64460_eth_get_stats
954 * Returns a pointer to the interface statistics.
956 * Input : dev - a pointer to the required interface
958 * Output : a pointer to the interface's statistics
959 **********************************************************************/
961 static struct net_device_stats *mv64460_eth_get_stats (struct eth_device *dev)
963 ETH_PORT_INFO *ethernet_private;
964 struct mv64460_eth_priv *port_private;
966 ethernet_private = (ETH_PORT_INFO *) dev->priv;
968 (struct mv64460_eth_priv *) ethernet_private->port_private;
970 mv64460_eth_update_stat (dev);
972 return port_private->stats;
975 /**********************************************************************
976 * mv64460_eth_update_stat
978 * Update the statistics structure in the private data structure
980 * Input : pointer to ethernet interface network device structure
982 **********************************************************************/
984 static void mv64460_eth_update_stat (struct eth_device *dev)
986 ETH_PORT_INFO *ethernet_private;
987 struct mv64460_eth_priv *port_private;
988 struct net_device_stats *stats;
990 ethernet_private = (ETH_PORT_INFO *) dev->priv;
992 (struct mv64460_eth_priv *) ethernet_private->port_private;
993 stats = port_private->stats;
995 /* These are false updates */
996 stats->rx_packets += (unsigned long)
997 eth_read_mib_counter (ethernet_private->port_num,
998 ETH_MIB_GOOD_FRAMES_RECEIVED);
999 stats->tx_packets += (unsigned long)
1000 eth_read_mib_counter (ethernet_private->port_num,
1001 ETH_MIB_GOOD_FRAMES_SENT);
1002 stats->rx_bytes += (unsigned long)
1003 eth_read_mib_counter (ethernet_private->port_num,
1004 ETH_MIB_GOOD_OCTETS_RECEIVED_LOW);
1006 * Ideally this should be as follows -
1008 * stats->rx_bytes += stats->rx_bytes +
1009 * ((unsigned long) ethReadMibCounter (ethernet_private->port_num ,
1010 * ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH) << 32);
1012 * But the unsigned long in PowerPC and MIPS are 32bit. So the next read
1013 * is just a dummy read for proper work of the GigE port
1015 (void)eth_read_mib_counter (ethernet_private->port_num,
1016 ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH);
1017 stats->tx_bytes += (unsigned long)
1018 eth_read_mib_counter (ethernet_private->port_num,
1019 ETH_MIB_GOOD_OCTETS_SENT_LOW);
1020 (void)eth_read_mib_counter (ethernet_private->port_num,
1021 ETH_MIB_GOOD_OCTETS_SENT_HIGH);
1022 stats->rx_errors += (unsigned long)
1023 eth_read_mib_counter (ethernet_private->port_num,
1024 ETH_MIB_MAC_RECEIVE_ERROR);
1026 /* Rx dropped is for received packet with CRC error */
1027 stats->rx_dropped +=
1028 (unsigned long) eth_read_mib_counter (ethernet_private->
1030 ETH_MIB_BAD_CRC_EVENT);
1031 stats->multicast += (unsigned long)
1032 eth_read_mib_counter (ethernet_private->port_num,
1033 ETH_MIB_MULTICAST_FRAMES_RECEIVED);
1034 stats->collisions +=
1035 (unsigned long) eth_read_mib_counter (ethernet_private->
1037 ETH_MIB_COLLISION) +
1038 (unsigned long) eth_read_mib_counter (ethernet_private->
1040 ETH_MIB_LATE_COLLISION);
1041 /* detailed rx errors */
1042 stats->rx_length_errors +=
1043 (unsigned long) eth_read_mib_counter (ethernet_private->
1045 ETH_MIB_UNDERSIZE_RECEIVED)
1047 (unsigned long) eth_read_mib_counter (ethernet_private->
1049 ETH_MIB_OVERSIZE_RECEIVED);
1050 /* detailed tx errors */
1053 #ifndef UPDATE_STATS_BY_SOFTWARE
1054 /**********************************************************************
1055 * mv64460_eth_print_stat
1057 * Update the statistics structure in the private data structure
1059 * Input : pointer to ethernet interface network device structure
1061 **********************************************************************/
1063 static void mv64460_eth_print_stat (struct eth_device *dev)
1065 ETH_PORT_INFO *ethernet_private;
1066 struct mv64460_eth_priv *port_private;
1067 struct net_device_stats *stats;
1069 ethernet_private = (ETH_PORT_INFO *) dev->priv;
1071 (struct mv64460_eth_priv *) ethernet_private->port_private;
1072 stats = port_private->stats;
1074 /* These are false updates */
1075 printf ("\n### Network statistics: ###\n");
1076 printf ("--------------------------\n");
1077 printf (" Packets received: %ld\n", stats->rx_packets);
1078 printf (" Packets send: %ld\n", stats->tx_packets);
1079 printf (" Received bytes: %ld\n", stats->rx_bytes);
1080 printf (" Send bytes: %ld\n", stats->tx_bytes);
1081 if (stats->rx_errors != 0)
1082 printf (" Rx Errors: %ld\n",
1084 if (stats->rx_dropped != 0)
1085 printf (" Rx dropped (CRC Errors): %ld\n",
1087 if (stats->multicast != 0)
1088 printf (" Rx mulicast frames: %ld\n",
1090 if (stats->collisions != 0)
1091 printf (" No. of collisions: %ld\n",
1093 if (stats->rx_length_errors != 0)
1094 printf (" Rx length errors: %ld\n",
1095 stats->rx_length_errors);
1099 /**************************************************************************
1100 *network_start - Network Kick Off Routine UBoot
1103 **************************************************************************/
1105 bool db64460_eth_start (struct eth_device *dev)
1107 return (mv64460_eth_open (dev)); /* calls real open */
1110 /*************************************************************************
1111 **************************************************************************
1112 **************************************************************************
1113 * The second part is the low level driver of the gigE ethernet ports. *
1114 **************************************************************************
1115 **************************************************************************
1116 *************************************************************************/
1118 * based on Linux code
1119 * arch/powerpc/galileo/EVB64460/mv64460_eth.c - Driver for MV64460X ethernet ports
1120 * Copyright (C) 2002 rabeeh@galileo.co.il
1122 * This program is free software; you can redistribute it and/or
1123 * modify it under the terms of the GNU General Public License
1124 * as published by the Free Software Foundation; either version 2
1125 * of the License, or (at your option) any later version.
1127 * This program is distributed in the hope that it will be useful,
1128 * but WITHOUT ANY WARRANTY; without even the implied warranty of
1129 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1130 * GNU General Public License for more details.
1132 * You should have received a copy of the GNU General Public License
1133 * along with this program; if not, write to the Free Software
1134 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1138 /********************************************************************************
1139 * Marvell's Gigabit Ethernet controller low level driver
1142 * This file introduce low level API to Marvell's Gigabit Ethernet
1143 * controller. This Gigabit Ethernet Controller driver API controls
1144 * 1) Operations (i.e. port init, start, reset etc').
1145 * 2) Data flow (i.e. port send, receive etc').
1146 * Each Gigabit Ethernet port is controlled via ETH_PORT_INFO
1148 * This struct includes user configuration information as well as
1149 * driver internal data needed for its operations.
1151 * Supported Features:
1152 * - This low level driver is OS independent. Allocating memory for
1153 * the descriptor rings and buffers are not within the scope of
1155 * - The user is free from Rx/Tx queue managing.
1156 * - This low level driver introduce functionality API that enable
1157 * the to operate Marvell's Gigabit Ethernet Controller in a
1159 * - Simple Gigabit Ethernet port operation API.
1160 * - Simple Gigabit Ethernet port data flow API.
1161 * - Data flow and operation API support per queue functionality.
1162 * - Support cached descriptors for better performance.
1163 * - Enable access to all four DRAM banks and internal SRAM memory
1165 * - PHY access and control API.
1166 * - Port control register configuration API.
1167 * - Full control over Unicast and Multicast MAC configurations.
1171 * Initialization phase
1172 * This phase complete the initialization of the ETH_PORT_INFO
1174 * User information regarding port configuration has to be set
1175 * prior to calling the port initialization routine. For example,
1176 * the user has to assign the port_phy_addr field which is board
1177 * depended parameter.
1178 * In this phase any port Tx/Rx activity is halted, MIB counters
1179 * are cleared, PHY address is set according to user parameter and
1180 * access to DRAM and internal SRAM memory spaces.
1182 * Driver ring initialization
1183 * Allocating memory for the descriptor rings and buffers is not
1184 * within the scope of this driver. Thus, the user is required to
1185 * allocate memory for the descriptors ring and buffers. Those
1186 * memory parameters are used by the Rx and Tx ring initialization
1187 * routines in order to curve the descriptor linked list in a form
1189 * Note: Pay special attention to alignment issues when using
1190 * cached descriptors/buffers. In this phase the driver store
1191 * information in the ETH_PORT_INFO struct regarding each queue
1195 * This phase prepares the Ethernet port for Rx and Tx activity.
1196 * It uses the information stored in the ETH_PORT_INFO struct to
1197 * initialize the various port registers.
1200 * All packet references to/from the driver are done using PKT_INFO
1202 * This struct is a unified struct used with Rx and Tx operations.
1203 * This way the user is not required to be familiar with neither
1204 * Tx nor Rx descriptors structures.
1205 * The driver's descriptors rings are management by indexes.
1206 * Those indexes controls the ring resources and used to indicate
1207 * a SW resource error:
1209 * This index points to the current available resource for use. For
1210 * example in Rx process this index will point to the descriptor
1211 * that will be passed to the user upon calling the receive routine.
1212 * In Tx process, this index will point to the descriptor
1213 * that will be assigned with the user packet info and transmitted.
1215 * This index points to the descriptor that need to restore its
1216 * resources. For example in Rx process, using the Rx buffer return
1217 * API will attach the buffer returned in packet info to the
1218 * descriptor pointed by 'used'. In Tx process, using the Tx
1219 * descriptor return will merely return the user packet info with
1220 * the command status of the transmitted buffer pointed by the
1221 * 'used' index. Nevertheless, it is essential to use this routine
1222 * to update the 'used' index.
1224 * This index supports Tx Scatter-Gather. It points to the first
1225 * descriptor of a packet assembled of multiple buffers. For example
1226 * when in middle of Such packet we have a Tx resource error the
1227 * 'curr' index get the value of 'first' to indicate that the ring
1228 * returned to its state before trying to transmit this packet.
1230 * Receive operation:
1231 * The eth_port_receive API set the packet information struct,
1232 * passed by the caller, with received information from the
1233 * 'current' SDMA descriptor.
1234 * It is the user responsibility to return this resource back
1235 * to the Rx descriptor ring to enable the reuse of this source.
1236 * Return Rx resource is done using the eth_rx_return_buff API.
1238 * Transmit operation:
1239 * The eth_port_send API supports Scatter-Gather which enables to
1240 * send a packet spanned over multiple buffers. This means that
1241 * for each packet info structure given by the user and put into
1242 * the Tx descriptors ring, will be transmitted only if the 'LAST'
1243 * bit will be set in the packet info command status field. This
1244 * API also consider restriction regarding buffer alignments and
1246 * The user must return a Tx resource after ensuring the buffer
1247 * has been transmitted to enable the Tx ring indexes to update.
1250 * This device is on-board. No jumper diagram is necessary.
1252 * EXTERNAL INTERFACE
1254 * Prior to calling the initialization routine eth_port_init() the user
1255 * must set the following fields under ETH_PORT_INFO struct:
1256 * port_num User Ethernet port number.
1257 * port_phy_addr User PHY address of Ethernet port.
1258 * port_mac_addr[6] User defined port MAC address.
1259 * port_config User port configuration value.
1260 * port_config_extend User port config extend value.
1261 * port_sdma_config User port SDMA config value.
1262 * port_serial_control User port serial control value.
1263 * *port_virt_to_phys () User function to cast virtual addr to CPU bus addr.
1264 * *port_private User scratch pad for user specific data structures.
1266 * This driver introduce a set of default values:
1267 * PORT_CONFIG_VALUE Default port configuration value
1268 * PORT_CONFIG_EXTEND_VALUE Default port extend configuration value
1269 * PORT_SDMA_CONFIG_VALUE Default sdma control value
1270 * PORT_SERIAL_CONTROL_VALUE Default port serial control value
1272 * This driver data flow is done using the PKT_INFO struct which is
1273 * a unified struct for Rx and Tx operations:
1274 * byte_cnt Tx/Rx descriptor buffer byte count.
1275 * l4i_chk CPU provided TCP Checksum. For Tx operation only.
1276 * cmd_sts Tx/Rx descriptor command status.
1277 * buf_ptr Tx/Rx descriptor buffer pointer.
1278 * return_info Tx/Rx user resource return information.
1281 * EXTERNAL SUPPORT REQUIREMENTS
1283 * This driver requires the following external support:
1285 * D_CACHE_FLUSH_LINE (address, address offset)
1287 * This macro applies assembly code to flush and invalidate cache
1289 * address - address base.
1290 * address offset - address offset
1295 * This macro applies assembly code to flush the CPU pipeline.
1297 *******************************************************************************/
1301 /* SDMA command macros */
1302 #define ETH_ENABLE_TX_QUEUE(tx_queue, eth_port) \
1303 MV_REG_WRITE(MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG(eth_port), (1 << tx_queue))
1305 #define ETH_DISABLE_TX_QUEUE(tx_queue, eth_port) \
1306 MV_REG_WRITE(MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG(eth_port),\
1307 (1 << (8 + tx_queue)))
1309 #define ETH_ENABLE_RX_QUEUE(rx_queue, eth_port) \
1310 MV_REG_WRITE(MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG(eth_port), (1 << rx_queue))
1312 #define ETH_DISABLE_RX_QUEUE(rx_queue, eth_port) \
1313 MV_REG_WRITE(MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG(eth_port), (1 << (8 + rx_queue)))
1315 #define CURR_RFD_GET(p_curr_desc, queue) \
1316 ((p_curr_desc) = p_eth_port_ctrl->p_rx_curr_desc_q[queue])
1318 #define CURR_RFD_SET(p_curr_desc, queue) \
1319 (p_eth_port_ctrl->p_rx_curr_desc_q[queue] = (p_curr_desc))
1321 #define USED_RFD_GET(p_used_desc, queue) \
1322 ((p_used_desc) = p_eth_port_ctrl->p_rx_used_desc_q[queue])
1324 #define USED_RFD_SET(p_used_desc, queue)\
1325 (p_eth_port_ctrl->p_rx_used_desc_q[queue] = (p_used_desc))
1328 #define CURR_TFD_GET(p_curr_desc, queue) \
1329 ((p_curr_desc) = p_eth_port_ctrl->p_tx_curr_desc_q[queue])
1331 #define CURR_TFD_SET(p_curr_desc, queue) \
1332 (p_eth_port_ctrl->p_tx_curr_desc_q[queue] = (p_curr_desc))
1334 #define USED_TFD_GET(p_used_desc, queue) \
1335 ((p_used_desc) = p_eth_port_ctrl->p_tx_used_desc_q[queue])
1337 #define USED_TFD_SET(p_used_desc, queue) \
1338 (p_eth_port_ctrl->p_tx_used_desc_q[queue] = (p_used_desc))
1340 #define FIRST_TFD_GET(p_first_desc, queue) \
1341 ((p_first_desc) = p_eth_port_ctrl->p_tx_first_desc_q[queue])
1343 #define FIRST_TFD_SET(p_first_desc, queue) \
1344 (p_eth_port_ctrl->p_tx_first_desc_q[queue] = (p_first_desc))
1347 /* Macros that save access to desc in order to find next desc pointer */
1348 #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])
1350 #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])
1352 #define LINK_UP_TIMEOUT 100000
1353 #define PHY_BUSY_TIMEOUT 10000000
1358 static void ethernet_phy_set (ETH_PORT eth_port_num, int phy_addr);
1359 static int ethernet_phy_get (ETH_PORT eth_port_num);
1361 /* Ethernet Port routines */
1362 static void eth_set_access_control (ETH_PORT eth_port_num,
1363 ETH_WIN_PARAM * param);
1364 static bool eth_port_uc_addr (ETH_PORT eth_port_num, unsigned char uc_nibble,
1365 ETH_QUEUE queue, int option);
1367 static bool eth_port_smc_addr (ETH_PORT eth_port_num,
1368 unsigned char mc_byte,
1369 ETH_QUEUE queue, int option);
1370 static bool eth_port_omc_addr (ETH_PORT eth_port_num,
1372 ETH_QUEUE queue, int option);
1375 static void eth_b_copy (unsigned int src_addr, unsigned int dst_addr,
1378 void eth_dbg (ETH_PORT_INFO * p_eth_port_ctrl);
1381 typedef enum _memory_bank { BANK0, BANK1, BANK2, BANK3 } MEMORY_BANK;
1382 u32 mv_get_dram_bank_base_addr (MEMORY_BANK bank)
1385 u32 enable = MV_REG_READ (MV64460_BASE_ADDR_ENABLE);
1387 if (enable & (1 << bank))
1390 result = MV_REG_READ (MV64460_CS_0_BASE_ADDR);
1392 result = MV_REG_READ (MV64460_CS_1_BASE_ADDR);
1394 result = MV_REG_READ (MV64460_CS_2_BASE_ADDR);
1396 result = MV_REG_READ (MV64460_CS_3_BASE_ADDR);
1397 result &= 0x0000ffff;
1398 result = result << 16;
1402 u32 mv_get_dram_bank_size (MEMORY_BANK bank)
1405 u32 enable = MV_REG_READ (MV64460_BASE_ADDR_ENABLE);
1407 if (enable & (1 << bank))
1410 result = MV_REG_READ (MV64460_CS_0_SIZE);
1412 result = MV_REG_READ (MV64460_CS_1_SIZE);
1414 result = MV_REG_READ (MV64460_CS_2_SIZE);
1416 result = MV_REG_READ (MV64460_CS_3_SIZE);
1418 result &= 0x0000ffff;
1419 result = result << 16;
1423 u32 mv_get_internal_sram_base (void)
1427 result = MV_REG_READ (MV64460_INTEGRATED_SRAM_BASE_ADDR);
1428 result &= 0x0000ffff;
1429 result = result << 16;
1433 /*******************************************************************************
1434 * eth_port_init - Initialize the Ethernet port driver
1437 * This function prepares the ethernet port to start its activity:
1438 * 1) Completes the ethernet port driver struct initialization toward port
1440 * 2) Resets the device to a quiescent state in case of warm reboot.
1441 * 3) Enable SDMA access to all four DRAM banks as well as internal SRAM.
1442 * 4) Clean MAC tables. The reset status of those tables is unknown.
1443 * 5) Set PHY address.
1444 * Note: Call this routine prior to eth_port_start routine and after setting
1445 * user values in the user fields of Ethernet port control struct (i.e.
1449 * ETH_PORT_INFO *p_eth_port_ctrl Ethernet port control struct
1457 *******************************************************************************/
1458 static void eth_port_init (ETH_PORT_INFO * p_eth_port_ctrl)
1461 ETH_WIN_PARAM win_param;
1463 p_eth_port_ctrl->port_config = PORT_CONFIG_VALUE;
1464 p_eth_port_ctrl->port_config_extend = PORT_CONFIG_EXTEND_VALUE;
1465 p_eth_port_ctrl->port_sdma_config = PORT_SDMA_CONFIG_VALUE;
1466 p_eth_port_ctrl->port_serial_control = PORT_SERIAL_CONTROL_VALUE;
1468 p_eth_port_ctrl->port_rx_queue_command = 0;
1469 p_eth_port_ctrl->port_tx_queue_command = 0;
1471 /* Zero out SW structs */
1472 for (queue = 0; queue < MAX_RX_QUEUE_NUM; queue++) {
1473 CURR_RFD_SET ((ETH_RX_DESC *) 0x00000000, queue);
1474 USED_RFD_SET ((ETH_RX_DESC *) 0x00000000, queue);
1475 p_eth_port_ctrl->rx_resource_err[queue] = false;
1478 for (queue = 0; queue < MAX_TX_QUEUE_NUM; queue++) {
1479 CURR_TFD_SET ((ETH_TX_DESC *) 0x00000000, queue);
1480 USED_TFD_SET ((ETH_TX_DESC *) 0x00000000, queue);
1481 FIRST_TFD_SET ((ETH_TX_DESC *) 0x00000000, queue);
1482 p_eth_port_ctrl->tx_resource_err[queue] = false;
1485 eth_port_reset (p_eth_port_ctrl->port_num);
1487 /* Set access parameters for DRAM bank 0 */
1488 win_param.win = ETH_WIN0; /* Use Ethernet window 0 */
1489 win_param.target = ETH_TARGET_DRAM; /* Window target - DDR */
1490 win_param.attributes = EBAR_ATTR_DRAM_CS0; /* Enable DRAM bank */
1491 #ifndef CONFIG_NOT_COHERENT_CACHE
1492 win_param.attributes |= EBAR_ATTR_DRAM_CACHE_COHERENCY_WB;
1494 win_param.high_addr = 0;
1496 win_param.base_addr = mv_get_dram_bank_base_addr (BANK0);
1497 win_param.size = mv_get_dram_bank_size (BANK0); /* Get bank size */
1498 if (win_param.size == 0)
1499 win_param.enable = 0;
1501 win_param.enable = 1; /* Enable the access */
1502 win_param.access_ctrl = EWIN_ACCESS_FULL; /* Enable full access */
1504 /* Set the access control for address window (EPAPR) READ & WRITE */
1505 eth_set_access_control (p_eth_port_ctrl->port_num, &win_param);
1507 /* Set access parameters for DRAM bank 1 */
1508 win_param.win = ETH_WIN1; /* Use Ethernet window 1 */
1509 win_param.target = ETH_TARGET_DRAM; /* Window target - DDR */
1510 win_param.attributes = EBAR_ATTR_DRAM_CS1; /* Enable DRAM bank */
1511 #ifndef CONFIG_NOT_COHERENT_CACHE
1512 win_param.attributes |= EBAR_ATTR_DRAM_CACHE_COHERENCY_WB;
1514 win_param.high_addr = 0;
1516 win_param.base_addr = mv_get_dram_bank_base_addr (BANK1);
1517 win_param.size = mv_get_dram_bank_size (BANK1); /* Get bank size */
1518 if (win_param.size == 0)
1519 win_param.enable = 0;
1521 win_param.enable = 1; /* Enable the access */
1522 win_param.access_ctrl = EWIN_ACCESS_FULL; /* Enable full access */
1524 /* Set the access control for address window (EPAPR) READ & WRITE */
1525 eth_set_access_control (p_eth_port_ctrl->port_num, &win_param);
1527 /* Set access parameters for DRAM bank 2 */
1528 win_param.win = ETH_WIN2; /* Use Ethernet window 2 */
1529 win_param.target = ETH_TARGET_DRAM; /* Window target - DDR */
1530 win_param.attributes = EBAR_ATTR_DRAM_CS2; /* Enable DRAM bank */
1531 #ifndef CONFIG_NOT_COHERENT_CACHE
1532 win_param.attributes |= EBAR_ATTR_DRAM_CACHE_COHERENCY_WB;
1534 win_param.high_addr = 0;
1536 win_param.base_addr = mv_get_dram_bank_base_addr (BANK2);
1537 win_param.size = mv_get_dram_bank_size (BANK2); /* Get bank size */
1538 if (win_param.size == 0)
1539 win_param.enable = 0;
1541 win_param.enable = 1; /* Enable the access */
1542 win_param.access_ctrl = EWIN_ACCESS_FULL; /* Enable full access */
1544 /* Set the access control for address window (EPAPR) READ & WRITE */
1545 eth_set_access_control (p_eth_port_ctrl->port_num, &win_param);
1547 /* Set access parameters for DRAM bank 3 */
1548 win_param.win = ETH_WIN3; /* Use Ethernet window 3 */
1549 win_param.target = ETH_TARGET_DRAM; /* Window target - DDR */
1550 win_param.attributes = EBAR_ATTR_DRAM_CS3; /* Enable DRAM bank */
1551 #ifndef CONFIG_NOT_COHERENT_CACHE
1552 win_param.attributes |= EBAR_ATTR_DRAM_CACHE_COHERENCY_WB;
1554 win_param.high_addr = 0;
1556 win_param.base_addr = mv_get_dram_bank_base_addr (BANK3);
1557 win_param.size = mv_get_dram_bank_size (BANK3); /* Get bank size */
1558 if (win_param.size == 0)
1559 win_param.enable = 0;
1561 win_param.enable = 1; /* Enable the access */
1562 win_param.access_ctrl = EWIN_ACCESS_FULL; /* Enable full access */
1564 /* Set the access control for address window (EPAPR) READ & WRITE */
1565 eth_set_access_control (p_eth_port_ctrl->port_num, &win_param);
1567 /* Set access parameters for Internal SRAM */
1568 win_param.win = ETH_WIN4; /* Use Ethernet window 0 */
1569 win_param.target = EBAR_TARGET_CBS; /* Target - Internal SRAM */
1570 win_param.attributes = EBAR_ATTR_CBS_SRAM | EBAR_ATTR_CBS_SRAM_BLOCK0;
1571 win_param.high_addr = 0;
1572 win_param.base_addr = mv_get_internal_sram_base (); /* Get base addr */
1573 win_param.size = MV64460_INTERNAL_SRAM_SIZE; /* Get bank size */
1574 win_param.enable = 1; /* Enable the access */
1575 win_param.access_ctrl = EWIN_ACCESS_FULL; /* Enable full access */
1577 /* Set the access control for address window (EPAPR) READ & WRITE */
1578 eth_set_access_control (p_eth_port_ctrl->port_num, &win_param);
1580 eth_port_init_mac_tables (p_eth_port_ctrl->port_num);
1582 ethernet_phy_set (p_eth_port_ctrl->port_num,
1583 p_eth_port_ctrl->port_phy_addr);
1589 /*******************************************************************************
1590 * eth_port_start - Start the Ethernet port activity.
1593 * This routine prepares the Ethernet port for Rx and Tx activity:
1594 * 1. Initialize Tx and Rx Current Descriptor Pointer for each queue that
1595 * has been initialized a descriptor's ring (using ether_init_tx_desc_ring
1596 * for Tx and ether_init_rx_desc_ring for Rx)
1597 * 2. Initialize and enable the Ethernet configuration port by writing to
1598 * the port's configuration and command registers.
1599 * 3. Initialize and enable the SDMA by writing to the SDMA's
1600 * configuration and command registers.
1601 * After completing these steps, the ethernet port SDMA can starts to
1602 * perform Rx and Tx activities.
1604 * Note: Each Rx and Tx queue descriptor's list must be initialized prior
1605 * to calling this function (use ether_init_tx_desc_ring for Tx queues and
1606 * ether_init_rx_desc_ring for Rx queues).
1609 * ETH_PORT_INFO *p_eth_port_ctrl Ethernet port control struct
1612 * Ethernet port is ready to receive and transmit.
1615 * false if the port PHY is not up.
1618 *******************************************************************************/
1619 static bool eth_port_start (ETH_PORT_INFO * p_eth_port_ctrl)
1622 volatile ETH_TX_DESC *p_tx_curr_desc;
1623 volatile ETH_RX_DESC *p_rx_curr_desc;
1624 unsigned int phy_reg_data;
1625 ETH_PORT eth_port_num = p_eth_port_ctrl->port_num;
1627 /* Assignment of Tx CTRP of given queue */
1628 for (queue = 0; queue < MAX_TX_QUEUE_NUM; queue++) {
1629 CURR_TFD_GET (p_tx_curr_desc, queue);
1630 MV_REG_WRITE ((MV64460_ETH_TX_CURRENT_QUEUE_DESC_PTR_0
1633 ((unsigned int) p_tx_curr_desc));
1637 /* Assignment of Rx CRDP of given queue */
1638 for (queue = 0; queue < MAX_RX_QUEUE_NUM; queue++) {
1639 CURR_RFD_GET (p_rx_curr_desc, queue);
1640 MV_REG_WRITE ((MV64460_ETH_RX_CURRENT_QUEUE_DESC_PTR_0
1643 ((unsigned int) p_rx_curr_desc));
1645 if (p_rx_curr_desc != NULL)
1646 /* Add the assigned Ethernet address to the port's address table */
1647 eth_port_uc_addr_set (p_eth_port_ctrl->port_num,
1648 p_eth_port_ctrl->port_mac_addr,
1652 /* Assign port configuration and command. */
1653 MV_REG_WRITE (MV64460_ETH_PORT_CONFIG_REG (eth_port_num),
1654 p_eth_port_ctrl->port_config);
1656 MV_REG_WRITE (MV64460_ETH_PORT_CONFIG_EXTEND_REG (eth_port_num),
1657 p_eth_port_ctrl->port_config_extend);
1659 MV_REG_WRITE (MV64460_ETH_PORT_SERIAL_CONTROL_REG (eth_port_num),
1660 p_eth_port_ctrl->port_serial_control);
1662 MV_SET_REG_BITS (MV64460_ETH_PORT_SERIAL_CONTROL_REG (eth_port_num),
1663 ETH_SERIAL_PORT_ENABLE);
1665 /* Assign port SDMA configuration */
1666 MV_REG_WRITE (MV64460_ETH_SDMA_CONFIG_REG (eth_port_num),
1667 p_eth_port_ctrl->port_sdma_config);
1669 MV_REG_WRITE (MV64460_ETH_TX_QUEUE_0_TOKEN_BUCKET_COUNT
1670 (eth_port_num), 0x3fffffff);
1671 MV_REG_WRITE (MV64460_ETH_TX_QUEUE_0_TOKEN_BUCKET_CONFIG
1672 (eth_port_num), 0x03fffcff);
1673 /* Turn off the port/queue bandwidth limitation */
1674 MV_REG_WRITE (MV64460_ETH_MAXIMUM_TRANSMIT_UNIT (eth_port_num), 0x0);
1676 /* Enable port Rx. */
1677 MV_REG_WRITE (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG (eth_port_num),
1678 p_eth_port_ctrl->port_rx_queue_command);
1680 /* Check if link is up */
1681 eth_port_read_smi_reg (eth_port_num, 1, &phy_reg_data);
1683 if (!(phy_reg_data & 0x20))
1689 /*******************************************************************************
1690 * eth_port_uc_addr_set - This function Set the port Unicast address.
1693 * This function Set the port Ethernet MAC address.
1696 * ETH_PORT eth_port_num Port number.
1697 * char * p_addr Address to be set
1698 * ETH_QUEUE queue Rx queue number for this MAC address.
1701 * Set MAC address low and high registers. also calls eth_port_uc_addr()
1702 * To set the unicast table with the proper information.
1707 *******************************************************************************/
1708 static void eth_port_uc_addr_set (ETH_PORT eth_port_num,
1709 unsigned char *p_addr, ETH_QUEUE queue)
1714 mac_l = (p_addr[4] << 8) | (p_addr[5]);
1715 mac_h = (p_addr[0] << 24) | (p_addr[1] << 16) |
1716 (p_addr[2] << 8) | (p_addr[3] << 0);
1718 MV_REG_WRITE (MV64460_ETH_MAC_ADDR_LOW (eth_port_num), mac_l);
1719 MV_REG_WRITE (MV64460_ETH_MAC_ADDR_HIGH (eth_port_num), mac_h);
1721 /* Accept frames of this address */
1722 eth_port_uc_addr (eth_port_num, p_addr[5], queue, ACCEPT_MAC_ADDR);
1727 /*******************************************************************************
1728 * eth_port_uc_addr - This function Set the port unicast address table
1731 * This function locates the proper entry in the Unicast table for the
1732 * specified MAC nibble and sets its properties according to function
1736 * ETH_PORT eth_port_num Port number.
1737 * unsigned char uc_nibble Unicast MAC Address last nibble.
1738 * ETH_QUEUE queue Rx queue number for this MAC address.
1739 * int option 0 = Add, 1 = remove address.
1742 * This function add/removes MAC addresses from the port unicast address
1746 * true is output succeeded.
1747 * false if option parameter is invalid.
1749 *******************************************************************************/
1750 static bool eth_port_uc_addr (ETH_PORT eth_port_num,
1751 unsigned char uc_nibble,
1752 ETH_QUEUE queue, int option)
1754 unsigned int unicast_reg;
1755 unsigned int tbl_offset;
1756 unsigned int reg_offset;
1758 /* Locate the Unicast table entry */
1759 uc_nibble = (0xf & uc_nibble);
1760 tbl_offset = (uc_nibble / 4) * 4; /* Register offset from unicast table base */
1761 reg_offset = uc_nibble % 4; /* Entry offset within the above register */
1764 case REJECT_MAC_ADDR:
1765 /* Clear accepts frame bit at specified unicast DA table entry */
1767 MV_REG_READ ((MV64460_ETH_DA_FILTER_UNICAST_TABLE_BASE
1771 unicast_reg &= (0x0E << (8 * reg_offset));
1773 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_UNICAST_TABLE_BASE
1775 + tbl_offset), unicast_reg);
1778 case ACCEPT_MAC_ADDR:
1779 /* Set accepts frame bit at unicast DA filter table entry */
1781 MV_REG_READ ((MV64460_ETH_DA_FILTER_UNICAST_TABLE_BASE
1785 unicast_reg |= ((0x01 | queue) << (8 * reg_offset));
1787 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_UNICAST_TABLE_BASE
1789 + tbl_offset), unicast_reg);
1800 /*******************************************************************************
1801 * eth_port_mc_addr - Multicast address settings.
1804 * This API controls the MV device MAC multicast support.
1805 * The MV device supports multicast using two tables:
1806 * 1) Special Multicast Table for MAC addresses of the form
1807 * 0x01-00-5E-00-00-XX (where XX is between 0x00 and 0x_fF).
1808 * The MAC DA[7:0] bits are used as a pointer to the Special Multicast
1809 * Table entries in the DA-Filter table.
1810 * In this case, the function calls eth_port_smc_addr() routine to set the
1811 * Special Multicast Table.
1812 * 2) Other Multicast Table for multicast of another type. A CRC-8bit
1813 * is used as an index to the Other Multicast Table entries in the
1815 * In this case, the function calculates the CRC-8bit value and calls
1816 * eth_port_omc_addr() routine to set the Other Multicast Table.
1818 * ETH_PORT eth_port_num Port number.
1819 * unsigned char *p_addr Unicast MAC Address.
1820 * ETH_QUEUE queue Rx queue number for this MAC address.
1821 * int option 0 = Add, 1 = remove address.
1827 * true is output succeeded.
1828 * false if add_address_table_entry( ) failed.
1830 *******************************************************************************/
1831 static void eth_port_mc_addr (ETH_PORT eth_port_num,
1832 unsigned char *p_addr,
1833 ETH_QUEUE queue, int option)
1837 unsigned char crc_result = 0;
1842 if ((p_addr[0] == 0x01) &&
1843 (p_addr[1] == 0x00) &&
1844 (p_addr[2] == 0x5E) && (p_addr[3] == 0x00) && (p_addr[4] == 0x00)) {
1846 eth_port_smc_addr (eth_port_num, p_addr[5], queue, option);
1848 /* Calculate CRC-8 out of the given address */
1849 mac_h = (p_addr[0] << 8) | (p_addr[1]);
1850 mac_l = (p_addr[2] << 24) | (p_addr[3] << 16) |
1851 (p_addr[4] << 8) | (p_addr[5] << 0);
1853 for (i = 0; i < 32; i++)
1854 mac_array[i] = (mac_l >> i) & 0x1;
1855 for (i = 32; i < 48; i++)
1856 mac_array[i] = (mac_h >> (i - 32)) & 0x1;
1858 crc[0] = mac_array[45] ^ mac_array[43] ^ mac_array[40] ^
1859 mac_array[39] ^ mac_array[35] ^ mac_array[34] ^
1860 mac_array[31] ^ mac_array[30] ^ mac_array[28] ^
1861 mac_array[23] ^ mac_array[21] ^ mac_array[19] ^
1862 mac_array[18] ^ mac_array[16] ^ mac_array[14] ^
1863 mac_array[12] ^ mac_array[8] ^ mac_array[7] ^
1864 mac_array[6] ^ mac_array[0];
1866 crc[1] = mac_array[46] ^ mac_array[45] ^ mac_array[44] ^
1867 mac_array[43] ^ mac_array[41] ^ mac_array[39] ^
1868 mac_array[36] ^ mac_array[34] ^ mac_array[32] ^
1869 mac_array[30] ^ mac_array[29] ^ mac_array[28] ^
1870 mac_array[24] ^ mac_array[23] ^ mac_array[22] ^
1871 mac_array[21] ^ mac_array[20] ^ mac_array[18] ^
1872 mac_array[17] ^ mac_array[16] ^ mac_array[15] ^
1873 mac_array[14] ^ mac_array[13] ^ mac_array[12] ^
1874 mac_array[9] ^ mac_array[6] ^ mac_array[1] ^
1877 crc[2] = mac_array[47] ^ mac_array[46] ^ mac_array[44] ^
1878 mac_array[43] ^ mac_array[42] ^ mac_array[39] ^
1879 mac_array[37] ^ mac_array[34] ^ mac_array[33] ^
1880 mac_array[29] ^ mac_array[28] ^ mac_array[25] ^
1881 mac_array[24] ^ mac_array[22] ^ mac_array[17] ^
1882 mac_array[15] ^ mac_array[13] ^ mac_array[12] ^
1883 mac_array[10] ^ mac_array[8] ^ mac_array[6] ^
1884 mac_array[2] ^ mac_array[1] ^ mac_array[0];
1886 crc[3] = mac_array[47] ^ mac_array[45] ^ mac_array[44] ^
1887 mac_array[43] ^ mac_array[40] ^ mac_array[38] ^
1888 mac_array[35] ^ mac_array[34] ^ mac_array[30] ^
1889 mac_array[29] ^ mac_array[26] ^ mac_array[25] ^
1890 mac_array[23] ^ mac_array[18] ^ mac_array[16] ^
1891 mac_array[14] ^ mac_array[13] ^ mac_array[11] ^
1892 mac_array[9] ^ mac_array[7] ^ mac_array[3] ^
1893 mac_array[2] ^ mac_array[1];
1895 crc[4] = mac_array[46] ^ mac_array[45] ^ mac_array[44] ^
1896 mac_array[41] ^ mac_array[39] ^ mac_array[36] ^
1897 mac_array[35] ^ mac_array[31] ^ mac_array[30] ^
1898 mac_array[27] ^ mac_array[26] ^ mac_array[24] ^
1899 mac_array[19] ^ mac_array[17] ^ mac_array[15] ^
1900 mac_array[14] ^ mac_array[12] ^ mac_array[10] ^
1901 mac_array[8] ^ mac_array[4] ^ mac_array[3] ^
1904 crc[5] = mac_array[47] ^ mac_array[46] ^ mac_array[45] ^
1905 mac_array[42] ^ mac_array[40] ^ mac_array[37] ^
1906 mac_array[36] ^ mac_array[32] ^ mac_array[31] ^
1907 mac_array[28] ^ mac_array[27] ^ mac_array[25] ^
1908 mac_array[20] ^ mac_array[18] ^ mac_array[16] ^
1909 mac_array[15] ^ mac_array[13] ^ mac_array[11] ^
1910 mac_array[9] ^ mac_array[5] ^ mac_array[4] ^
1913 crc[6] = mac_array[47] ^ mac_array[46] ^ mac_array[43] ^
1914 mac_array[41] ^ mac_array[38] ^ mac_array[37] ^
1915 mac_array[33] ^ mac_array[32] ^ mac_array[29] ^
1916 mac_array[28] ^ mac_array[26] ^ mac_array[21] ^
1917 mac_array[19] ^ mac_array[17] ^ mac_array[16] ^
1918 mac_array[14] ^ mac_array[12] ^ mac_array[10] ^
1919 mac_array[6] ^ mac_array[5] ^ mac_array[4];
1921 crc[7] = mac_array[47] ^ mac_array[44] ^ mac_array[42] ^
1922 mac_array[39] ^ mac_array[38] ^ mac_array[34] ^
1923 mac_array[33] ^ mac_array[30] ^ mac_array[29] ^
1924 mac_array[27] ^ mac_array[22] ^ mac_array[20] ^
1925 mac_array[18] ^ mac_array[17] ^ mac_array[15] ^
1926 mac_array[13] ^ mac_array[11] ^ mac_array[7] ^
1927 mac_array[6] ^ mac_array[5];
1929 for (i = 0; i < 8; i++)
1930 crc_result = crc_result | (crc[i] << i);
1932 eth_port_omc_addr (eth_port_num, crc_result, queue, option);
1937 /*******************************************************************************
1938 * eth_port_smc_addr - Special Multicast address settings.
1941 * This routine controls the MV device special MAC multicast support.
1942 * The Special Multicast Table for MAC addresses supports MAC of the form
1943 * 0x01-00-5E-00-00-XX (where XX is between 0x00 and 0x_fF).
1944 * The MAC DA[7:0] bits are used as a pointer to the Special Multicast
1945 * Table entries in the DA-Filter table.
1946 * This function set the Special Multicast Table appropriate entry
1947 * according to the argument given.
1950 * ETH_PORT eth_port_num Port number.
1951 * unsigned char mc_byte Multicast addr last byte (MAC DA[7:0] bits).
1952 * ETH_QUEUE queue Rx queue number for this MAC address.
1953 * int option 0 = Add, 1 = remove address.
1959 * true is output succeeded.
1960 * false if option parameter is invalid.
1962 *******************************************************************************/
1963 static bool eth_port_smc_addr (ETH_PORT eth_port_num,
1964 unsigned char mc_byte,
1965 ETH_QUEUE queue, int option)
1967 unsigned int smc_table_reg;
1968 unsigned int tbl_offset;
1969 unsigned int reg_offset;
1971 /* Locate the SMC table entry */
1972 tbl_offset = (mc_byte / 4) * 4; /* Register offset from SMC table base */
1973 reg_offset = mc_byte % 4; /* Entry offset within the above register */
1977 case REJECT_MAC_ADDR:
1978 /* Clear accepts frame bit at specified Special DA table entry */
1980 MV_REG_READ ((MV64460_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset));
1981 smc_table_reg &= (0x0E << (8 * reg_offset));
1983 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset), smc_table_reg);
1986 case ACCEPT_MAC_ADDR:
1987 /* Set accepts frame bit at specified Special DA table entry */
1989 MV_REG_READ ((MV64460_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset));
1990 smc_table_reg |= ((0x01 | queue) << (8 * reg_offset));
1992 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset), smc_table_reg);
2001 /*******************************************************************************
2002 * eth_port_omc_addr - Multicast address settings.
2005 * This routine controls the MV device Other MAC multicast support.
2006 * The Other Multicast Table is used for multicast of another type.
2007 * A CRC-8bit is used as an index to the Other Multicast Table entries
2008 * in the DA-Filter table.
2009 * The function gets the CRC-8bit value from the calling routine and
2010 * set the Other Multicast Table appropriate entry according to the
2011 * CRC-8 argument given.
2014 * ETH_PORT eth_port_num Port number.
2015 * unsigned char crc8 A CRC-8bit (Polynomial: x^8+x^2+x^1+1).
2016 * ETH_QUEUE queue Rx queue number for this MAC address.
2017 * int option 0 = Add, 1 = remove address.
2023 * true is output succeeded.
2024 * false if option parameter is invalid.
2026 *******************************************************************************/
2027 static bool eth_port_omc_addr (ETH_PORT eth_port_num,
2029 ETH_QUEUE queue, int option)
2031 unsigned int omc_table_reg;
2032 unsigned int tbl_offset;
2033 unsigned int reg_offset;
2035 /* Locate the OMC table entry */
2036 tbl_offset = (crc8 / 4) * 4; /* Register offset from OMC table base */
2037 reg_offset = crc8 % 4; /* Entry offset within the above register */
2041 case REJECT_MAC_ADDR:
2042 /* Clear accepts frame bit at specified Other DA table entry */
2044 MV_REG_READ ((MV64460_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset));
2045 omc_table_reg &= (0x0E << (8 * reg_offset));
2047 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset), omc_table_reg);
2050 case ACCEPT_MAC_ADDR:
2051 /* Set accepts frame bit at specified Other DA table entry */
2053 MV_REG_READ ((MV64460_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset));
2054 omc_table_reg |= ((0x01 | queue) << (8 * reg_offset));
2056 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset), omc_table_reg);
2066 /*******************************************************************************
2067 * eth_port_init_mac_tables - Clear all entrance in the UC, SMC and OMC tables
2070 * Go through all the DA filter tables (Unicast, Special Multicast & Other
2071 * Multicast) and set each entry to 0.
2074 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
2077 * Multicast and Unicast packets are rejected.
2082 *******************************************************************************/
2083 static void eth_port_init_mac_tables (ETH_PORT eth_port_num)
2087 /* Clear DA filter unicast table (Ex_dFUT) */
2088 for (table_index = 0; table_index <= 0xC; table_index += 4)
2089 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_UNICAST_TABLE_BASE
2090 (eth_port_num) + table_index), 0);
2092 for (table_index = 0; table_index <= 0xFC; table_index += 4) {
2093 /* Clear DA filter special multicast table (Ex_dFSMT) */
2094 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE (eth_port_num) + table_index), 0);
2095 /* Clear DA filter other multicast table (Ex_dFOMT) */
2096 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE (eth_port_num) + table_index), 0);
2100 /*******************************************************************************
2101 * eth_clear_mib_counters - Clear all MIB counters
2104 * This function clears all MIB counters of a specific ethernet port.
2105 * A read from the MIB counter will reset the counter.
2108 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
2111 * After reading all MIB counters, the counters resets.
2114 * MIB counter value.
2116 *******************************************************************************/
2117 static void eth_clear_mib_counters (ETH_PORT eth_port_num)
2121 /* Perform dummy reads from MIB counters */
2122 for (i = ETH_MIB_GOOD_OCTETS_RECEIVED_LOW; i < ETH_MIB_LATE_COLLISION;
2124 (void)MV_REG_READ ((MV64460_ETH_MIB_COUNTERS_BASE
2125 (eth_port_num) + i));
2131 /*******************************************************************************
2132 * eth_read_mib_counter - Read a MIB counter
2135 * This function reads a MIB counter of a specific ethernet port.
2136 * NOTE - If read from ETH_MIB_GOOD_OCTETS_RECEIVED_LOW, then the
2137 * following read must be from ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH
2138 * register. The same applies for ETH_MIB_GOOD_OCTETS_SENT_LOW and
2139 * ETH_MIB_GOOD_OCTETS_SENT_HIGH
2142 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
2143 * unsigned int mib_offset MIB counter offset (use ETH_MIB_... macros).
2146 * After reading the MIB counter, the counter resets.
2149 * MIB counter value.
2151 *******************************************************************************/
2152 unsigned int eth_read_mib_counter (ETH_PORT eth_port_num,
2153 unsigned int mib_offset)
2155 return (MV_REG_READ (MV64460_ETH_MIB_COUNTERS_BASE (eth_port_num)
2159 /*******************************************************************************
2160 * ethernet_phy_set - Set the ethernet port PHY address.
2163 * This routine set the ethernet port PHY address according to given
2167 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
2170 * Set PHY Address Register with given PHY address parameter.
2175 *******************************************************************************/
2176 static void ethernet_phy_set (ETH_PORT eth_port_num, int phy_addr)
2178 unsigned int reg_data;
2180 reg_data = MV_REG_READ (MV64460_ETH_PHY_ADDR_REG);
2182 reg_data &= ~(0x1F << (5 * eth_port_num));
2183 reg_data |= (phy_addr << (5 * eth_port_num));
2185 MV_REG_WRITE (MV64460_ETH_PHY_ADDR_REG, reg_data);
2190 /*******************************************************************************
2191 * ethernet_phy_get - Get the ethernet port PHY address.
2194 * This routine returns the given ethernet port PHY address.
2197 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
2205 *******************************************************************************/
2206 static int ethernet_phy_get (ETH_PORT eth_port_num)
2208 unsigned int reg_data;
2210 reg_data = MV_REG_READ (MV64460_ETH_PHY_ADDR_REG);
2212 return ((reg_data >> (5 * eth_port_num)) & 0x1f);
2215 /***********************************************************/
2216 /* (Re)start autonegotiation */
2217 /***********************************************************/
2218 int phy_setup_aneg (char *devname, unsigned char addr)
2220 unsigned short ctl, adv;
2222 /* Setup standard advertise */
2223 miiphy_read (devname, addr, MII_ADVERTISE, &adv);
2224 adv |= (LPA_LPACK | LPA_RFAULT | LPA_100BASE4 |
2225 LPA_100FULL | LPA_100HALF | LPA_10FULL |
2227 miiphy_write (devname, addr, MII_ADVERTISE, adv);
2229 miiphy_read (devname, addr, MII_CTRL1000, &adv);
2231 miiphy_write (devname, addr, MII_CTRL1000, adv);
2233 /* Start/Restart aneg */
2234 miiphy_read (devname, addr, MII_BMCR, &ctl);
2235 ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
2236 miiphy_write (devname, addr, MII_BMCR, ctl);
2241 /*******************************************************************************
2242 * ethernet_phy_reset - Reset Ethernet port PHY.
2245 * This routine utilize the SMI interface to reset the ethernet port PHY.
2246 * The routine waits until the link is up again or link up is timeout.
2249 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
2252 * The ethernet port PHY renew its link.
2257 *******************************************************************************/
2258 static bool ethernet_phy_reset (ETH_PORT eth_port_num)
2260 unsigned int time_out = 50;
2261 unsigned int phy_reg_data;
2263 eth_port_read_smi_reg (eth_port_num, 20, &phy_reg_data);
2264 phy_reg_data |= 0x0083; /* Set bit 7 to 1 for different RGMII timing */
2265 eth_port_write_smi_reg (eth_port_num, 20, phy_reg_data);
2268 eth_port_read_smi_reg (eth_port_num, 0, &phy_reg_data);
2269 phy_reg_data |= 0x8000; /* Set bit 15 to reset the PHY */
2270 eth_port_write_smi_reg (eth_port_num, 0, phy_reg_data);
2272 /* Poll on the PHY LINK */
2274 eth_port_read_smi_reg (eth_port_num, 1, &phy_reg_data);
2276 if (time_out-- == 0)
2279 while (!(phy_reg_data & 0x20));
2284 /*******************************************************************************
2285 * eth_port_reset - Reset Ethernet port
2288 * This routine resets the chip by aborting any SDMA engine activity and
2289 * clearing the MIB counters. The Receiver and the Transmit unit are in
2290 * idle state after this command is performed and the port is disabled.
2293 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
2296 * Channel activity is halted.
2301 *******************************************************************************/
2302 static void eth_port_reset (ETH_PORT eth_port_num)
2304 unsigned int reg_data;
2306 /* Stop Tx port activity. Check port Tx activity. */
2308 MV_REG_READ (MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG
2311 if (reg_data & 0xFF) {
2312 /* Issue stop command for active channels only */
2313 MV_REG_WRITE (MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG
2314 (eth_port_num), (reg_data << 8));
2316 /* Wait for all Tx activity to terminate. */
2318 /* Check port cause register that all Tx queues are stopped */
2321 (MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG
2324 while (reg_data & 0xFF);
2327 /* Stop Rx port activity. Check port Rx activity. */
2329 MV_REG_READ (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG
2332 if (reg_data & 0xFF) {
2333 /* Issue stop command for active channels only */
2334 MV_REG_WRITE (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG
2335 (eth_port_num), (reg_data << 8));
2337 /* Wait for all Rx activity to terminate. */
2339 /* Check port cause register that all Rx queues are stopped */
2342 (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG
2345 while (reg_data & 0xFF);
2348 /* Clear all MIB counters */
2349 eth_clear_mib_counters (eth_port_num);
2351 /* Reset the Enable bit in the Configuration Register */
2353 MV_REG_READ (MV64460_ETH_PORT_SERIAL_CONTROL_REG
2355 reg_data &= ~ETH_SERIAL_PORT_ENABLE;
2356 MV_REG_WRITE (MV64460_ETH_PORT_SERIAL_CONTROL_REG (eth_port_num),
2362 #if 0 /* Not needed here */
2363 /*******************************************************************************
2364 * ethernet_set_config_reg - Set specified bits in configuration register.
2367 * This function sets specified bits in the given ethernet
2368 * configuration register.
2371 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
2372 * unsigned int value 32 bit value.
2375 * The set bits in the value parameter are set in the configuration
2381 *******************************************************************************/
2382 static void ethernet_set_config_reg (ETH_PORT eth_port_num,
2385 unsigned int eth_config_reg;
2388 MV_REG_READ (MV64460_ETH_PORT_CONFIG_REG (eth_port_num));
2389 eth_config_reg |= value;
2390 MV_REG_WRITE (MV64460_ETH_PORT_CONFIG_REG (eth_port_num),
2398 /*******************************************************************************
2399 * ethernet_reset_config_reg - Reset specified bits in configuration register.
2402 * This function resets specified bits in the given Ethernet
2403 * configuration register.
2406 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
2407 * unsigned int value 32 bit value.
2410 * The set bits in the value parameter are reset in the configuration
2416 *******************************************************************************/
2417 static void ethernet_reset_config_reg (ETH_PORT eth_port_num,
2420 unsigned int eth_config_reg;
2422 eth_config_reg = MV_REG_READ (MV64460_ETH_PORT_CONFIG_EXTEND_REG
2424 eth_config_reg &= ~value;
2425 MV_REG_WRITE (MV64460_ETH_PORT_CONFIG_EXTEND_REG (eth_port_num),
2432 #if 0 /* Not needed here */
2433 /*******************************************************************************
2434 * ethernet_get_config_reg - Get the port configuration register
2437 * This function returns the configuration register value of the given
2441 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
2447 * Port configuration register value.
2449 *******************************************************************************/
2450 static unsigned int ethernet_get_config_reg (ETH_PORT eth_port_num)
2452 unsigned int eth_config_reg;
2454 eth_config_reg = MV_REG_READ (MV64460_ETH_PORT_CONFIG_EXTEND_REG
2456 return eth_config_reg;
2461 /*******************************************************************************
2462 * eth_port_read_smi_reg - Read PHY registers
2465 * This routine utilize the SMI interface to interact with the PHY in
2466 * order to perform PHY register read.
2469 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
2470 * unsigned int phy_reg PHY register address offset.
2471 * unsigned int *value Register value buffer.
2474 * Write the value of a specified PHY register into given buffer.
2477 * false if the PHY is busy or read data is not in valid state.
2480 *******************************************************************************/
2481 static bool eth_port_read_smi_reg (ETH_PORT eth_port_num,
2482 unsigned int phy_reg, unsigned int *value)
2484 unsigned int reg_value;
2485 unsigned int time_out = PHY_BUSY_TIMEOUT;
2488 phy_addr = ethernet_phy_get (eth_port_num);
2490 /* first check that it is not busy */
2492 reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
2493 if (time_out-- == 0) {
2497 while (reg_value & ETH_SMI_BUSY);
2501 MV_REG_WRITE (MV64460_ETH_SMI_REG,
2502 (phy_addr << 16) | (phy_reg << 21) |
2503 ETH_SMI_OPCODE_READ);
2505 time_out = PHY_BUSY_TIMEOUT; /* initialize the time out var again */
2508 reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
2509 if (time_out-- == 0) {
2513 while ((reg_value & ETH_SMI_READ_VALID) != ETH_SMI_READ_VALID); /* Bit set equ operation done */
2515 /* Wait for the data to update in the SMI register */
2516 #define PHY_UPDATE_TIMEOUT 10000
2517 for (time_out = 0; time_out < PHY_UPDATE_TIMEOUT; time_out++);
2519 reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
2521 *value = reg_value & 0xffff;
2526 int mv_miiphy_read(const char *devname, unsigned char phy_addr,
2527 unsigned char phy_reg, unsigned short *value)
2529 unsigned int reg_value;
2530 unsigned int time_out = PHY_BUSY_TIMEOUT;
2532 /* first check that it is not busy */
2534 reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
2535 if (time_out-- == 0) {
2539 while (reg_value & ETH_SMI_BUSY);
2542 MV_REG_WRITE (MV64460_ETH_SMI_REG,
2543 (phy_addr << 16) | (phy_reg << 21) |
2544 ETH_SMI_OPCODE_READ);
2546 time_out = PHY_BUSY_TIMEOUT; /* initialize the time out var again */
2549 reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
2550 if (time_out-- == 0) {
2554 while ((reg_value & ETH_SMI_READ_VALID) != ETH_SMI_READ_VALID); /* Bit set equ operation done */
2556 /* Wait for the data to update in the SMI register */
2557 for (time_out = 0; time_out < PHY_UPDATE_TIMEOUT; time_out++);
2559 reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
2561 *value = reg_value & 0xffff;
2566 /*******************************************************************************
2567 * eth_port_write_smi_reg - Write to PHY registers
2570 * This routine utilize the SMI interface to interact with the PHY in
2571 * order to perform writes to PHY registers.
2574 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
2575 * unsigned int phy_reg PHY register address offset.
2576 * unsigned int value Register value.
2579 * Write the given value to the specified PHY register.
2582 * false if the PHY is busy.
2585 *******************************************************************************/
2586 static bool eth_port_write_smi_reg (ETH_PORT eth_port_num,
2587 unsigned int phy_reg, unsigned int value)
2589 unsigned int reg_value;
2590 unsigned int time_out = PHY_BUSY_TIMEOUT;
2593 phy_addr = ethernet_phy_get (eth_port_num);
2595 /* first check that it is not busy */
2597 reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
2598 if (time_out-- == 0) {
2602 while (reg_value & ETH_SMI_BUSY);
2605 MV_REG_WRITE (MV64460_ETH_SMI_REG,
2606 (phy_addr << 16) | (phy_reg << 21) |
2607 ETH_SMI_OPCODE_WRITE | (value & 0xffff));
2611 int mv_miiphy_write(const char *devname, unsigned char phy_addr,
2612 unsigned char phy_reg, unsigned short value)
2614 unsigned int reg_value;
2615 unsigned int time_out = PHY_BUSY_TIMEOUT;
2617 /* first check that it is not busy */
2619 reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
2620 if (time_out-- == 0) {
2624 while (reg_value & ETH_SMI_BUSY);
2627 MV_REG_WRITE (MV64460_ETH_SMI_REG,
2628 (phy_addr << 16) | (phy_reg << 21) |
2629 ETH_SMI_OPCODE_WRITE | (value & 0xffff));
2633 /*******************************************************************************
2634 * eth_set_access_control - Config address decode parameters for Ethernet unit
2637 * This function configures the address decode parameters for the Gigabit
2638 * Ethernet Controller according the given parameters struct.
2641 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
2642 * ETH_WIN_PARAM *param Address decode parameter struct.
2645 * An access window is opened using the given access parameters.
2650 *******************************************************************************/
2651 static void eth_set_access_control (ETH_PORT eth_port_num,
2652 ETH_WIN_PARAM * param)
2654 unsigned int access_prot_reg;
2656 /* Set access control register */
2657 access_prot_reg = MV_REG_READ (MV64460_ETH_ACCESS_PROTECTION_REG
2659 access_prot_reg &= (~(3 << (param->win * 2))); /* clear window permission */
2660 access_prot_reg |= (param->access_ctrl << (param->win * 2));
2661 MV_REG_WRITE (MV64460_ETH_ACCESS_PROTECTION_REG (eth_port_num),
2664 /* Set window Size reg (SR) */
2665 MV_REG_WRITE ((MV64460_ETH_SIZE_REG_0 +
2666 (ETH_SIZE_REG_GAP * param->win)),
2667 (((param->size / 0x10000) - 1) << 16));
2669 /* Set window Base address reg (BA) */
2670 MV_REG_WRITE ((MV64460_ETH_BAR_0 + (ETH_BAR_GAP * param->win)),
2671 (param->target | param->attributes | param->base_addr));
2672 /* High address remap reg (HARR) */
2674 MV_REG_WRITE ((MV64460_ETH_HIGH_ADDR_REMAP_REG_0 +
2675 (ETH_HIGH_ADDR_REMAP_REG_GAP * param->win)),
2678 /* Base address enable reg (BARER) */
2679 if (param->enable == 1)
2680 MV_RESET_REG_BITS (MV64460_ETH_BASE_ADDR_ENABLE_REG,
2683 MV_SET_REG_BITS (MV64460_ETH_BASE_ADDR_ENABLE_REG,
2687 /*******************************************************************************
2688 * ether_init_rx_desc_ring - Curve a Rx chain desc list and buffer in memory.
2691 * This function prepares a Rx chained list of descriptors and packet
2692 * buffers in a form of a ring. The routine must be called after port
2693 * initialization routine and before port start routine.
2694 * The Ethernet SDMA engine uses CPU bus addresses to access the various
2695 * devices in the system (i.e. DRAM). This function uses the ethernet
2696 * struct 'virtual to physical' routine (set by the user) to set the ring
2697 * with physical addresses.
2700 * ETH_PORT_INFO *p_eth_port_ctrl Ethernet Port Control srtuct.
2701 * ETH_QUEUE rx_queue Number of Rx queue.
2702 * int rx_desc_num Number of Rx descriptors
2703 * int rx_buff_size Size of Rx buffer
2704 * unsigned int rx_desc_base_addr Rx descriptors memory area base addr.
2705 * unsigned int rx_buff_base_addr Rx buffer memory area base addr.
2708 * The routine updates the Ethernet port control struct with information
2709 * regarding the Rx descriptors and buffers.
2712 * false if the given descriptors memory area is not aligned according to
2713 * Ethernet SDMA specifications.
2716 *******************************************************************************/
2717 static bool ether_init_rx_desc_ring (ETH_PORT_INFO * p_eth_port_ctrl,
2721 unsigned int rx_desc_base_addr,
2722 unsigned int rx_buff_base_addr)
2724 ETH_RX_DESC *p_rx_desc;
2725 ETH_RX_DESC *p_rx_prev_desc; /* pointer to link with the last descriptor */
2726 unsigned int buffer_addr;
2727 int ix; /* a counter */
2729 p_rx_desc = (ETH_RX_DESC *) rx_desc_base_addr;
2730 p_rx_prev_desc = p_rx_desc;
2731 buffer_addr = rx_buff_base_addr;
2733 /* Rx desc Must be 4LW aligned (i.e. Descriptor_Address[3:0]=0000). */
2734 if (rx_buff_base_addr & 0xF)
2737 /* Rx buffers are limited to 64K bytes and Minimum size is 8 bytes */
2738 if ((rx_buff_size < 8) || (rx_buff_size > RX_BUFFER_MAX_SIZE))
2741 /* Rx buffers must be 64-bit aligned. */
2742 if ((rx_buff_base_addr + rx_buff_size) & 0x7)
2745 /* initialize the Rx descriptors ring */
2746 for (ix = 0; ix < rx_desc_num; ix++) {
2747 p_rx_desc->buf_size = rx_buff_size;
2748 p_rx_desc->byte_cnt = 0x0000;
2749 p_rx_desc->cmd_sts =
2750 ETH_BUFFER_OWNED_BY_DMA | ETH_RX_ENABLE_INTERRUPT;
2751 p_rx_desc->next_desc_ptr =
2752 ((unsigned int) p_rx_desc) + RX_DESC_ALIGNED_SIZE;
2753 p_rx_desc->buf_ptr = buffer_addr;
2754 p_rx_desc->return_info = 0x00000000;
2755 D_CACHE_FLUSH_LINE (p_rx_desc, 0);
2756 buffer_addr += rx_buff_size;
2757 p_rx_prev_desc = p_rx_desc;
2758 p_rx_desc = (ETH_RX_DESC *)
2759 ((unsigned int) p_rx_desc + RX_DESC_ALIGNED_SIZE);
2762 /* Closing Rx descriptors ring */
2763 p_rx_prev_desc->next_desc_ptr = (rx_desc_base_addr);
2764 D_CACHE_FLUSH_LINE (p_rx_prev_desc, 0);
2766 /* Save Rx desc pointer to driver struct. */
2767 CURR_RFD_SET ((ETH_RX_DESC *) rx_desc_base_addr, rx_queue);
2768 USED_RFD_SET ((ETH_RX_DESC *) rx_desc_base_addr, rx_queue);
2770 p_eth_port_ctrl->p_rx_desc_area_base[rx_queue] =
2771 (ETH_RX_DESC *) rx_desc_base_addr;
2772 p_eth_port_ctrl->rx_desc_area_size[rx_queue] =
2773 rx_desc_num * RX_DESC_ALIGNED_SIZE;
2775 p_eth_port_ctrl->port_rx_queue_command |= (1 << rx_queue);
2780 /*******************************************************************************
2781 * ether_init_tx_desc_ring - Curve a Tx chain desc list and buffer in memory.
2784 * This function prepares a Tx chained list of descriptors and packet
2785 * buffers in a form of a ring. The routine must be called after port
2786 * initialization routine and before port start routine.
2787 * The Ethernet SDMA engine uses CPU bus addresses to access the various
2788 * devices in the system (i.e. DRAM). This function uses the ethernet
2789 * struct 'virtual to physical' routine (set by the user) to set the ring
2790 * with physical addresses.
2793 * ETH_PORT_INFO *p_eth_port_ctrl Ethernet Port Control srtuct.
2794 * ETH_QUEUE tx_queue Number of Tx queue.
2795 * int tx_desc_num Number of Tx descriptors
2796 * int tx_buff_size Size of Tx buffer
2797 * unsigned int tx_desc_base_addr Tx descriptors memory area base addr.
2798 * unsigned int tx_buff_base_addr Tx buffer memory area base addr.
2801 * The routine updates the Ethernet port control struct with information
2802 * regarding the Tx descriptors and buffers.
2805 * false if the given descriptors memory area is not aligned according to
2806 * Ethernet SDMA specifications.
2809 *******************************************************************************/
2810 static bool ether_init_tx_desc_ring (ETH_PORT_INFO * p_eth_port_ctrl,
2814 unsigned int tx_desc_base_addr,
2815 unsigned int tx_buff_base_addr)
2818 ETH_TX_DESC *p_tx_desc;
2819 ETH_TX_DESC *p_tx_prev_desc;
2820 unsigned int buffer_addr;
2821 int ix; /* a counter */
2823 /* save the first desc pointer to link with the last descriptor */
2824 p_tx_desc = (ETH_TX_DESC *) tx_desc_base_addr;
2825 p_tx_prev_desc = p_tx_desc;
2826 buffer_addr = tx_buff_base_addr;
2828 /* Tx desc Must be 4LW aligned (i.e. Descriptor_Address[3:0]=0000). */
2829 if (tx_buff_base_addr & 0xF)
2832 /* Tx buffers are limited to 64K bytes and Minimum size is 8 bytes */
2833 if ((tx_buff_size > TX_BUFFER_MAX_SIZE)
2834 || (tx_buff_size < TX_BUFFER_MIN_SIZE))
2837 /* Initialize the Tx descriptors ring */
2838 for (ix = 0; ix < tx_desc_num; ix++) {
2839 p_tx_desc->byte_cnt = 0x0000;
2840 p_tx_desc->l4i_chk = 0x0000;
2841 p_tx_desc->cmd_sts = 0x00000000;
2842 p_tx_desc->next_desc_ptr =
2843 ((unsigned int) p_tx_desc) + TX_DESC_ALIGNED_SIZE;
2845 p_tx_desc->buf_ptr = buffer_addr;
2846 p_tx_desc->return_info = 0x00000000;
2847 D_CACHE_FLUSH_LINE (p_tx_desc, 0);
2848 buffer_addr += tx_buff_size;
2849 p_tx_prev_desc = p_tx_desc;
2850 p_tx_desc = (ETH_TX_DESC *)
2851 ((unsigned int) p_tx_desc + TX_DESC_ALIGNED_SIZE);
2854 /* Closing Tx descriptors ring */
2855 p_tx_prev_desc->next_desc_ptr = tx_desc_base_addr;
2856 D_CACHE_FLUSH_LINE (p_tx_prev_desc, 0);
2857 /* Set Tx desc pointer in driver struct. */
2858 CURR_TFD_SET ((ETH_TX_DESC *) tx_desc_base_addr, tx_queue);
2859 USED_TFD_SET ((ETH_TX_DESC *) tx_desc_base_addr, tx_queue);
2861 /* Init Tx ring base and size parameters */
2862 p_eth_port_ctrl->p_tx_desc_area_base[tx_queue] =
2863 (ETH_TX_DESC *) tx_desc_base_addr;
2864 p_eth_port_ctrl->tx_desc_area_size[tx_queue] =
2865 (tx_desc_num * TX_DESC_ALIGNED_SIZE);
2867 /* Add the queue to the list of Tx queues of this port */
2868 p_eth_port_ctrl->port_tx_queue_command |= (1 << tx_queue);
2873 /*******************************************************************************
2874 * eth_port_send - Send an Ethernet packet
2877 * This routine send a given packet described by p_pktinfo parameter. It
2878 * supports transmitting of a packet spaned over multiple buffers. The
2879 * routine updates 'curr' and 'first' indexes according to the packet
2880 * segment passed to the routine. In case the packet segment is first,
2881 * the 'first' index is update. In any case, the 'curr' index is updated.
2882 * If the routine get into Tx resource error it assigns 'curr' index as
2883 * 'first'. This way the function can abort Tx process of multiple
2884 * descriptors per packet.
2887 * ETH_PORT_INFO *p_eth_port_ctrl Ethernet Port Control srtuct.
2888 * ETH_QUEUE tx_queue Number of Tx queue.
2889 * PKT_INFO *p_pkt_info User packet buffer.
2892 * Tx ring 'curr' and 'first' indexes are updated.
2895 * ETH_QUEUE_FULL in case of Tx resource error.
2896 * ETH_ERROR in case the routine can not access Tx desc ring.
2897 * ETH_QUEUE_LAST_RESOURCE if the routine uses the last Tx resource.
2900 *******************************************************************************/
2901 static ETH_FUNC_RET_STATUS eth_port_send (ETH_PORT_INFO * p_eth_port_ctrl,
2903 PKT_INFO * p_pkt_info)
2905 volatile ETH_TX_DESC *p_tx_desc_first;
2906 volatile ETH_TX_DESC *p_tx_desc_curr;
2907 volatile ETH_TX_DESC *p_tx_next_desc_curr;
2908 volatile ETH_TX_DESC *p_tx_desc_used;
2909 unsigned int command_status;
2911 /* Do not process Tx ring in case of Tx ring resource error */
2912 if (p_eth_port_ctrl->tx_resource_err[tx_queue] == true)
2913 return ETH_QUEUE_FULL;
2915 /* Get the Tx Desc ring indexes */
2916 CURR_TFD_GET (p_tx_desc_curr, tx_queue);
2917 USED_TFD_GET (p_tx_desc_used, tx_queue);
2919 if (p_tx_desc_curr == NULL)
2922 /* The following parameters are used to save readings from memory */
2923 p_tx_next_desc_curr = TX_NEXT_DESC_PTR (p_tx_desc_curr, tx_queue);
2924 command_status = p_pkt_info->cmd_sts | ETH_ZERO_PADDING | ETH_GEN_CRC;
2926 if (command_status & (ETH_TX_FIRST_DESC)) {
2927 /* Update first desc */
2928 FIRST_TFD_SET (p_tx_desc_curr, tx_queue);
2929 p_tx_desc_first = p_tx_desc_curr;
2931 FIRST_TFD_GET (p_tx_desc_first, tx_queue);
2932 command_status |= ETH_BUFFER_OWNED_BY_DMA;
2935 /* Buffers with a payload smaller than 8 bytes must be aligned to 64-bit */
2936 /* boundary. We use the memory allocated for Tx descriptor. This memory */
2937 /* located in TX_BUF_OFFSET_IN_DESC offset within the Tx descriptor. */
2938 if (p_pkt_info->byte_cnt <= 8) {
2939 printf ("You have failed in the < 8 bytes errata - fixme\n"); /* RABEEH - TBD */
2942 p_tx_desc_curr->buf_ptr =
2943 (unsigned int) p_tx_desc_curr + TX_BUF_OFFSET_IN_DESC;
2944 eth_b_copy (p_pkt_info->buf_ptr, p_tx_desc_curr->buf_ptr,
2945 p_pkt_info->byte_cnt);
2947 p_tx_desc_curr->buf_ptr = p_pkt_info->buf_ptr;
2949 p_tx_desc_curr->byte_cnt = p_pkt_info->byte_cnt;
2950 p_tx_desc_curr->return_info = p_pkt_info->return_info;
2952 if (p_pkt_info->cmd_sts & (ETH_TX_LAST_DESC)) {
2953 /* Set last desc with DMA ownership and interrupt enable. */
2954 p_tx_desc_curr->cmd_sts = command_status |
2955 ETH_BUFFER_OWNED_BY_DMA | ETH_TX_ENABLE_INTERRUPT;
2957 if (p_tx_desc_curr != p_tx_desc_first)
2958 p_tx_desc_first->cmd_sts |= ETH_BUFFER_OWNED_BY_DMA;
2960 /* Flush CPU pipe */
2962 D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_curr, 0);
2963 D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_first, 0);
2966 /* Apply send command */
2967 ETH_ENABLE_TX_QUEUE (tx_queue, p_eth_port_ctrl->port_num);
2969 /* Finish Tx packet. Update first desc in case of Tx resource error */
2970 p_tx_desc_first = p_tx_next_desc_curr;
2971 FIRST_TFD_SET (p_tx_desc_first, tx_queue);
2974 p_tx_desc_curr->cmd_sts = command_status;
2975 D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_curr, 0);
2978 /* Check for ring index overlap in the Tx desc ring */
2979 if (p_tx_next_desc_curr == p_tx_desc_used) {
2980 /* Update the current descriptor */
2981 CURR_TFD_SET (p_tx_desc_first, tx_queue);
2983 p_eth_port_ctrl->tx_resource_err[tx_queue] = true;
2984 return ETH_QUEUE_LAST_RESOURCE;
2986 /* Update the current descriptor */
2987 CURR_TFD_SET (p_tx_next_desc_curr, tx_queue);
2992 /*******************************************************************************
2993 * eth_tx_return_desc - Free all used Tx descriptors
2996 * This routine returns the transmitted packet information to the caller.
2997 * It uses the 'first' index to support Tx desc return in case a transmit
2998 * of a packet spanned over multiple buffer still in process.
2999 * In case the Tx queue was in "resource error" condition, where there are
3000 * no available Tx resources, the function resets the resource error flag.
3003 * ETH_PORT_INFO *p_eth_port_ctrl Ethernet Port Control srtuct.
3004 * ETH_QUEUE tx_queue Number of Tx queue.
3005 * PKT_INFO *p_pkt_info User packet buffer.
3008 * Tx ring 'first' and 'used' indexes are updated.
3011 * ETH_ERROR in case the routine can not access Tx desc ring.
3012 * ETH_RETRY in case there is transmission in process.
3013 * ETH_END_OF_JOB if the routine has nothing to release.
3016 *******************************************************************************/
3017 static ETH_FUNC_RET_STATUS eth_tx_return_desc (ETH_PORT_INFO *
3020 PKT_INFO * p_pkt_info)
3022 volatile ETH_TX_DESC *p_tx_desc_used = NULL;
3023 volatile ETH_TX_DESC *p_tx_desc_first = NULL;
3024 unsigned int command_status;
3026 /* Get the Tx Desc ring indexes */
3027 USED_TFD_GET (p_tx_desc_used, tx_queue);
3028 FIRST_TFD_GET (p_tx_desc_first, tx_queue);
3031 if (p_tx_desc_used == NULL)
3034 command_status = p_tx_desc_used->cmd_sts;
3036 /* Still transmitting... */
3037 if (command_status & (ETH_BUFFER_OWNED_BY_DMA)) {
3038 D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_used, 0);
3042 /* Stop release. About to overlap the current available Tx descriptor */
3043 if ((p_tx_desc_used == p_tx_desc_first) &&
3044 (p_eth_port_ctrl->tx_resource_err[tx_queue] == false)) {
3045 D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_used, 0);
3046 return ETH_END_OF_JOB;
3049 /* Pass the packet information to the caller */
3050 p_pkt_info->cmd_sts = command_status;
3051 p_pkt_info->return_info = p_tx_desc_used->return_info;
3052 p_tx_desc_used->return_info = 0;
3054 /* Update the next descriptor to release. */
3055 USED_TFD_SET (TX_NEXT_DESC_PTR (p_tx_desc_used, tx_queue), tx_queue);
3057 /* Any Tx return cancels the Tx resource error status */
3058 if (p_eth_port_ctrl->tx_resource_err[tx_queue] == true)
3059 p_eth_port_ctrl->tx_resource_err[tx_queue] = false;
3061 D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_used, 0);
3067 /*******************************************************************************
3068 * eth_port_receive - Get received information from Rx ring.
3071 * This routine returns the received data to the caller. There is no
3072 * data copying during routine operation. All information is returned
3073 * using pointer to packet information struct passed from the caller.
3074 * If the routine exhausts Rx ring resources then the resource error flag
3078 * ETH_PORT_INFO *p_eth_port_ctrl Ethernet Port Control srtuct.
3079 * ETH_QUEUE rx_queue Number of Rx queue.
3080 * PKT_INFO *p_pkt_info User packet buffer.
3083 * Rx ring current and used indexes are updated.
3086 * ETH_ERROR in case the routine can not access Rx desc ring.
3087 * ETH_QUEUE_FULL if Rx ring resources are exhausted.
3088 * ETH_END_OF_JOB if there is no received data.
3091 *******************************************************************************/
3092 static ETH_FUNC_RET_STATUS eth_port_receive (ETH_PORT_INFO * p_eth_port_ctrl,
3094 PKT_INFO * p_pkt_info)
3096 volatile ETH_RX_DESC *p_rx_curr_desc;
3097 volatile ETH_RX_DESC *p_rx_next_curr_desc;
3098 volatile ETH_RX_DESC *p_rx_used_desc;
3099 unsigned int command_status;
3101 /* Do not process Rx ring in case of Rx ring resource error */
3102 if (p_eth_port_ctrl->rx_resource_err[rx_queue] == true) {
3103 printf ("\nRx Queue is full ...\n");
3104 return ETH_QUEUE_FULL;
3107 /* Get the Rx Desc ring 'curr and 'used' indexes */
3108 CURR_RFD_GET (p_rx_curr_desc, rx_queue);
3109 USED_RFD_GET (p_rx_used_desc, rx_queue);
3112 if (p_rx_curr_desc == NULL)
3115 /* The following parameters are used to save readings from memory */
3116 p_rx_next_curr_desc = RX_NEXT_DESC_PTR (p_rx_curr_desc, rx_queue);
3117 command_status = p_rx_curr_desc->cmd_sts;
3119 /* Nothing to receive... */
3120 if (command_status & (ETH_BUFFER_OWNED_BY_DMA)) {
3121 /* DP(printf("Rx: command_status: %08x\n", command_status)); */
3122 D_CACHE_FLUSH_LINE ((unsigned int) p_rx_curr_desc, 0);
3123 /* DP(printf("\nETH_END_OF_JOB ...\n"));*/
3124 return ETH_END_OF_JOB;
3127 p_pkt_info->byte_cnt = (p_rx_curr_desc->byte_cnt) - RX_BUF_OFFSET;
3128 p_pkt_info->cmd_sts = command_status;
3129 p_pkt_info->buf_ptr = (p_rx_curr_desc->buf_ptr) + RX_BUF_OFFSET;
3130 p_pkt_info->return_info = p_rx_curr_desc->return_info;
3131 p_pkt_info->l4i_chk = p_rx_curr_desc->buf_size; /* IP fragment indicator */
3133 /* Clean the return info field to indicate that the packet has been */
3134 /* moved to the upper layers */
3135 p_rx_curr_desc->return_info = 0;
3137 /* Update 'curr' in data structure */
3138 CURR_RFD_SET (p_rx_next_curr_desc, rx_queue);
3140 /* Rx descriptors resource exhausted. Set the Rx ring resource error flag */
3141 if (p_rx_next_curr_desc == p_rx_used_desc)
3142 p_eth_port_ctrl->rx_resource_err[rx_queue] = true;
3144 D_CACHE_FLUSH_LINE ((unsigned int) p_rx_curr_desc, 0);
3150 /*******************************************************************************
3151 * eth_rx_return_buff - Returns a Rx buffer back to the Rx ring.
3154 * This routine returns a Rx buffer back to the Rx ring. It retrieves the
3155 * next 'used' descriptor and attached the returned buffer to it.
3156 * In case the Rx ring was in "resource error" condition, where there are
3157 * no available Rx resources, the function resets the resource error flag.
3160 * ETH_PORT_INFO *p_eth_port_ctrl Ethernet Port Control srtuct.
3161 * ETH_QUEUE rx_queue Number of Rx queue.
3162 * PKT_INFO *p_pkt_info Information on the returned buffer.
3165 * New available Rx resource in Rx descriptor ring.
3168 * ETH_ERROR in case the routine can not access Rx desc ring.
3171 *******************************************************************************/
3172 static ETH_FUNC_RET_STATUS eth_rx_return_buff (ETH_PORT_INFO *
3175 PKT_INFO * p_pkt_info)
3177 volatile ETH_RX_DESC *p_used_rx_desc; /* Where to return Rx resource */
3179 /* Get 'used' Rx descriptor */
3180 USED_RFD_GET (p_used_rx_desc, rx_queue);
3183 if (p_used_rx_desc == NULL)
3186 p_used_rx_desc->buf_ptr = p_pkt_info->buf_ptr;
3187 p_used_rx_desc->return_info = p_pkt_info->return_info;
3188 p_used_rx_desc->byte_cnt = p_pkt_info->byte_cnt;
3189 p_used_rx_desc->buf_size = MV64460_RX_BUFFER_SIZE; /* Reset Buffer size */
3191 /* Flush the write pipe */
3194 /* Return the descriptor to DMA ownership */
3195 p_used_rx_desc->cmd_sts =
3196 ETH_BUFFER_OWNED_BY_DMA | ETH_RX_ENABLE_INTERRUPT;
3198 /* Flush descriptor and CPU pipe */
3199 D_CACHE_FLUSH_LINE ((unsigned int) p_used_rx_desc, 0);
3202 /* Move the used descriptor pointer to the next descriptor */
3203 USED_RFD_SET (RX_NEXT_DESC_PTR (p_used_rx_desc, rx_queue), rx_queue);
3205 /* Any Rx return cancels the Rx resource error status */
3206 if (p_eth_port_ctrl->rx_resource_err[rx_queue] == true)
3207 p_eth_port_ctrl->rx_resource_err[rx_queue] = false;
3212 /*******************************************************************************
3213 * eth_port_set_rx_coal - Sets coalescing interrupt mechanism on RX path
3216 * This routine sets the RX coalescing interrupt mechanism parameter.
3217 * This parameter is a timeout counter, that counts in 64 t_clk
3218 * chunks ; that when timeout event occurs a maskable interrupt
3220 * The parameter is calculated using the tClk of the MV-643xx chip
3221 * , and the required delay of the interrupt in usec.
3224 * ETH_PORT eth_port_num Ethernet port number
3225 * unsigned int t_clk t_clk of the MV-643xx chip in HZ units
3226 * unsigned int delay Delay in usec
3229 * Interrupt coalescing mechanism value is set in MV-643xx chip.
3232 * The interrupt coalescing value set in the gigE port.
3234 *******************************************************************************/
3236 static unsigned int eth_port_set_rx_coal (ETH_PORT eth_port_num,
3242 coal = ((t_clk / 1000000) * delay) / 64;
3243 /* Set RX Coalescing mechanism */
3244 MV_REG_WRITE (MV64460_ETH_SDMA_CONFIG_REG (eth_port_num),
3245 ((coal & 0x3fff) << 8) |
3247 (MV64460_ETH_SDMA_CONFIG_REG (eth_port_num))
3253 /*******************************************************************************
3254 * eth_port_set_tx_coal - Sets coalescing interrupt mechanism on TX path
3257 * This routine sets the TX coalescing interrupt mechanism parameter.
3258 * This parameter is a timeout counter, that counts in 64 t_clk
3259 * chunks ; that when timeout event occurs a maskable interrupt
3261 * The parameter is calculated using the t_cLK frequency of the
3262 * MV-643xx chip and the required delay in the interrupt in uSec
3265 * ETH_PORT eth_port_num Ethernet port number
3266 * unsigned int t_clk t_clk of the MV-643xx chip in HZ units
3267 * unsigned int delay Delay in uSeconds
3270 * Interrupt coalescing mechanism value is set in MV-643xx chip.
3273 * The interrupt coalescing value set in the gigE port.
3275 *******************************************************************************/
3277 static unsigned int eth_port_set_tx_coal (ETH_PORT eth_port_num,
3283 coal = ((t_clk / 1000000) * delay) / 64;
3284 /* Set TX Coalescing mechanism */
3285 MV_REG_WRITE (MV64460_ETH_TX_FIFO_URGENT_THRESHOLD_REG (eth_port_num),
3291 /*******************************************************************************
3292 * eth_b_copy - Copy bytes from source to destination
3295 * This function supports the eight bytes limitation on Tx buffer size.
3296 * The routine will zero eight bytes starting from the destination address
3297 * followed by copying bytes from the source address to the destination.
3300 * unsigned int src_addr 32 bit source address.
3301 * unsigned int dst_addr 32 bit destination address.
3302 * int byte_count Number of bytes to copy.
3310 *******************************************************************************/
3311 static void eth_b_copy (unsigned int src_addr, unsigned int dst_addr,
3314 /* Zero the dst_addr area */
3315 *(unsigned int *) dst_addr = 0x0;
3317 while (byte_count != 0) {
3318 *(char *) dst_addr = *(char *) src_addr;