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);
113 extern unsigned int INTERNAL_REG_BASE_ADDR;
115 unsigned long my_le32_to_cpu (unsigned long x)
117 return (((x & 0x000000ffU) << 24) |
118 ((x & 0x0000ff00U) << 8) |
119 ((x & 0x00ff0000U) >> 8) | ((x & 0xff000000U) >> 24));
122 /*************************************************
123 *Helper functions - used inside the driver only *
124 *************************************************/
126 void print_globals (struct eth_device *dev)
128 printf ("Ethernet PRINT_Globals-Debug function\n");
129 printf ("Base Address for ETH_PORT_INFO: %08x\n",
130 (unsigned int) dev->priv);
131 printf ("Base Address for mv64460_eth_priv: %08x\n",
132 (unsigned int) &(((ETH_PORT_INFO *) dev->priv)->
135 printf ("GT Internal Base Address: %08x\n",
136 INTERNAL_REG_BASE_ADDR);
137 printf ("Base Address for TX-DESCs: %08x Number of allocated Buffers %d\n",
138 (unsigned int) ((ETH_PORT_INFO *) dev->priv)->p_tx_desc_area_base[0], MV64460_TX_QUEUE_SIZE);
139 printf ("Base Address for RX-DESCs: %08x Number of allocated Buffers %d\n",
140 (unsigned int) ((ETH_PORT_INFO *) dev->priv)->p_rx_desc_area_base[0], MV64460_RX_QUEUE_SIZE);
141 printf ("Base Address for RX-Buffer: %08x allocated Bytes %d\n",
142 (unsigned int) ((ETH_PORT_INFO *) dev->priv)->
144 (MV64460_RX_QUEUE_SIZE * MV64460_RX_BUFFER_SIZE) + 32);
145 printf ("Base Address for TX-Buffer: %08x allocated Bytes %d\n",
146 (unsigned int) ((ETH_PORT_INFO *) dev->priv)->
148 (MV64460_TX_QUEUE_SIZE * MV64460_TX_BUFFER_SIZE) + 32);
152 /**********************************************************************
153 * mv64460_eth_print_phy_status
155 * Prints gigabit ethenret phy status
157 * Input : pointer to ethernet interface network device structure
159 **********************************************************************/
160 void mv64460_eth_print_phy_status (struct eth_device *dev)
162 struct mv64460_eth_priv *port_private;
163 unsigned int port_num;
164 ETH_PORT_INFO *ethernet_private = (ETH_PORT_INFO *) dev->priv;
165 unsigned int port_status, phy_reg_data;
168 (struct mv64460_eth_priv *) ethernet_private->port_private;
169 port_num = port_private->port_num;
171 /* Check Link status on phy */
172 eth_port_read_smi_reg (port_num, 1, &phy_reg_data);
173 if (!(phy_reg_data & 0x20)) {
174 printf ("Ethernet port changed link status to DOWN\n");
177 MV_REG_READ (MV64460_ETH_PORT_STATUS_REG (port_num));
178 printf ("Ethernet status port %d: Link up", port_num);
180 (port_status & BIT2) ? "Full Duplex" : "Half Duplex");
181 if (port_status & BIT4)
182 printf (", Speed 1 Gbps");
185 (port_status & BIT5) ? "Speed 100 Mbps" :
191 /**********************************************************************
192 * u-boot entry functions for mv64460_eth
194 **********************************************************************/
195 int db64460_eth_probe (struct eth_device *dev)
197 return ((int) db64460_eth_start (dev));
200 int db64460_eth_poll (struct eth_device *dev)
202 return mv64460_eth_receive (dev);
205 int db64460_eth_transmit(struct eth_device *dev, void *packet, int length)
207 mv64460_eth_xmit (dev, packet, length);
211 void db64460_eth_disable (struct eth_device *dev)
213 mv64460_eth_stop (dev);
216 #define DFCDL(write,read) ((write << 6) | read)
217 unsigned int ethDfcdls[] = {
218 DFCDL(0,0), DFCDL(1,1), DFCDL(2,2), DFCDL(3,3),
219 DFCDL(4,4), DFCDL(5,5), DFCDL(6,6), DFCDL(7,7),
220 DFCDL(8,8), DFCDL(9,9), DFCDL(10,10), DFCDL(11,11),
221 DFCDL(12,12), DFCDL(13,13), DFCDL(14,14), DFCDL(15,15),
222 DFCDL(16,16), DFCDL(17,17), DFCDL(18,18), DFCDL(19,19),
223 DFCDL(20,20), DFCDL(21,21), DFCDL(22,22), DFCDL(23,23),
224 DFCDL(24,24), DFCDL(25,25), DFCDL(26,26), DFCDL(27,27),
225 DFCDL(28,28), DFCDL(29,29), DFCDL(30,30), DFCDL(31,31),
226 DFCDL(32,32), DFCDL(33,33), DFCDL(34,34), DFCDL(35,35),
227 DFCDL(36,36), DFCDL(37,37), DFCDL(38,38), DFCDL(39,39),
228 DFCDL(40,40), DFCDL(41,41), DFCDL(42,42), DFCDL(43,43),
229 DFCDL(44,44), DFCDL(45,45), DFCDL(46,46), DFCDL(47,47),
230 DFCDL(48,48), DFCDL(49,49), DFCDL(50,50), DFCDL(51,51),
231 DFCDL(52,52), DFCDL(53,53), DFCDL(54,54), DFCDL(55,55),
232 DFCDL(56,56), DFCDL(57,57), DFCDL(58,58), DFCDL(59,59),
233 DFCDL(60,60), DFCDL(61,61), DFCDL(62,62), DFCDL(63,63),
236 void mv_eth_phy_init (void)
240 MV_REG_WRITE (ETH_PHY_DFCDL_ADDR_REG, 0);
242 for (i = 0; i < 64; i++) {
243 MV_REG_WRITE (ETH_PHY_DFCDL_DATA0_REG, ethDfcdls[i]);
246 MV_REG_WRITE (ETH_PHY_DFCDL_CONFIG0_REG, 0x300000);
249 void mv6446x_eth_initialize (bd_t * bis)
251 struct eth_device *dev;
252 ETH_PORT_INFO *ethernet_private;
253 struct mv64460_eth_priv *port_private;
255 char *s, *e, buf[64];
258 * Set RGMII clock drives strength
260 temp = MV_REG_READ(0x20A0);
262 MV_REG_WRITE(0x20A0, temp);
266 for (devnum = 0; devnum < MV_ETH_DEVS; devnum++) {
267 dev = calloc (sizeof (*dev), 1);
269 printf ("%s: mv_enet%d allocation failure, %s\n",
270 __FUNCTION__, devnum, "eth_device structure");
274 /* must be less than sizeof(dev->name) */
275 sprintf (dev->name, "mv_enet%d", devnum);
278 printf ("Initializing %s\n", dev->name);
281 /* Extract the MAC address from the environment */
292 default: /* this should never happen */
293 printf ("%s: Invalid device number %d\n",
294 __FUNCTION__, devnum);
298 temp = getenv_f(s, buf, sizeof (buf));
299 s = (temp > 0) ? buf : NULL;
302 printf ("Setting MAC %d to %s\n", devnum, s);
304 for (x = 0; x < 6; ++x) {
305 dev->enetaddr[x] = s ? simple_strtoul (s, &e, 16) : 0;
307 s = (*e) ? e + 1 : e;
309 /* ronen - set the MAC addr in the HW */
310 eth_port_uc_addr_set (devnum, dev->enetaddr, 0);
312 dev->init = (void *) db64460_eth_probe;
313 dev->halt = (void *) ethernet_phy_reset;
314 dev->send = (void *) db64460_eth_transmit;
315 dev->recv = (void *) db64460_eth_poll;
317 ethernet_private = calloc (sizeof (*ethernet_private), 1);
318 dev->priv = (void *)ethernet_private;
319 if (!ethernet_private) {
320 printf ("%s: %s allocation failure, %s\n",
321 __FUNCTION__, dev->name,
322 "Private Device Structure");
326 /* start with an zeroed ETH_PORT_INFO */
327 memset (ethernet_private, 0, sizeof (ETH_PORT_INFO));
328 memcpy (ethernet_private->port_mac_addr, dev->enetaddr, 6);
330 /* set pointer to memory for stats data structure etc... */
331 port_private = calloc (sizeof (*ethernet_private), 1);
332 ethernet_private->port_private = (void *)port_private;
334 printf ("%s: %s allocation failure, %s\n",
335 __FUNCTION__, dev->name,
336 "Port Private Device Structure");
338 free (ethernet_private);
343 port_private->stats =
344 calloc (sizeof (struct net_device_stats), 1);
345 if (!port_private->stats) {
346 printf ("%s: %s allocation failure, %s\n",
347 __FUNCTION__, dev->name,
348 "Net stat Structure");
351 free (ethernet_private);
355 memset (ethernet_private->port_private, 0,
356 sizeof (struct mv64460_eth_priv));
359 ethernet_private->port_num = ETH_0;
362 ethernet_private->port_num = ETH_1;
365 ethernet_private->port_num = ETH_2;
368 printf ("Invalid device number %d\n", devnum);
372 port_private->port_num = devnum;
374 * Read MIB counter on the GT in order to reset them,
375 * then zero all the stats fields in memory
377 mv64460_eth_update_stat (dev);
378 memset (port_private->stats, 0,
379 sizeof (struct net_device_stats));
380 /* Extract the MAC address from the environment */
391 default: /* this should never happen */
392 printf ("%s: Invalid device number %d\n",
393 __FUNCTION__, devnum);
397 temp = getenv_f(s, buf, sizeof (buf));
398 s = (temp > 0) ? buf : NULL;
401 printf ("Setting MAC %d to %s\n", devnum, s);
403 for (x = 0; x < 6; ++x) {
404 dev->enetaddr[x] = s ? simple_strtoul (s, &e, 16) : 0;
406 s = (*e) ? e + 1 : e;
409 DP (printf ("Allocating descriptor and buffer rings\n"));
411 ethernet_private->p_rx_desc_area_base[0] =
412 (ETH_RX_DESC *) memalign (16,
413 RX_DESC_ALIGNED_SIZE *
414 MV64460_RX_QUEUE_SIZE + 1);
415 ethernet_private->p_tx_desc_area_base[0] =
416 (ETH_TX_DESC *) memalign (16,
417 TX_DESC_ALIGNED_SIZE *
418 MV64460_TX_QUEUE_SIZE + 1);
420 ethernet_private->p_rx_buffer_base[0] =
421 (char *) memalign (16,
422 MV64460_RX_QUEUE_SIZE *
423 MV64460_TX_BUFFER_SIZE + 1);
424 ethernet_private->p_tx_buffer_base[0] =
425 (char *) memalign (16,
426 MV64460_RX_QUEUE_SIZE *
427 MV64460_TX_BUFFER_SIZE + 1);
430 /* DEBUG OUTPUT prints adresses of globals */
435 miiphy_register(dev->name, mv_miiphy_read, mv_miiphy_write);
437 DP (printf ("%s: exit\n", __FUNCTION__));
441 /**********************************************************************
444 * This function is called when openning the network device. The function
445 * should initialize all the hardware, initialize cyclic Rx/Tx
446 * descriptors chain and buffers and allocate an IRQ to the network
449 * Input : a pointer to the network device structure
450 * / / ronen - changed the output to match net/eth.c needs
451 * Output : nonzero of success , zero if fails.
453 **********************************************************************/
455 int mv64460_eth_open (struct eth_device *dev)
457 return (mv64460_eth_real_open (dev));
460 /* Helper function for mv64460_eth_open */
461 static int mv64460_eth_real_open (struct eth_device *dev)
465 ETH_PORT_INFO *ethernet_private;
466 struct mv64460_eth_priv *port_private;
467 unsigned int port_num;
474 ethernet_private = (ETH_PORT_INFO *) dev->priv;
475 /* ronen - when we update the MAC env params we only update dev->enetaddr
476 see ./net/eth.c eth_set_enetaddr() */
477 memcpy (ethernet_private->port_mac_addr, dev->enetaddr, 6);
479 port_private = (struct mv64460_eth_priv *) ethernet_private->port_private;
480 port_num = port_private->port_num;
483 MV_REG_WRITE (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG (port_num), 0x0000ff00);
485 /* Clear the ethernet port interrupts */
486 MV_REG_WRITE (MV64460_ETH_INTERRUPT_CAUSE_REG (port_num), 0);
487 MV_REG_WRITE (MV64460_ETH_INTERRUPT_CAUSE_EXTEND_REG (port_num), 0);
489 /* Unmask RX buffer and TX end interrupt */
490 MV_REG_WRITE (MV64460_ETH_INTERRUPT_MASK_REG (port_num),
491 INT_CAUSE_UNMASK_ALL);
493 /* Unmask phy and link status changes interrupts */
494 MV_REG_WRITE (MV64460_ETH_INTERRUPT_EXTEND_MASK_REG (port_num),
495 INT_CAUSE_UNMASK_ALL_EXT);
497 /* Set phy address of the port */
498 ethernet_private->port_phy_addr = 0x1 + (port_num << 1);
499 reg = ethernet_private->port_phy_addr;
501 /* Activate the DMA channels etc */
502 eth_port_init (ethernet_private);
504 /* "Allocate" setup TX rings */
506 for (queue = 0; queue < MV64460_TX_QUEUE_NUM; queue++) {
509 port_private->tx_ring_size[queue] = MV64460_TX_QUEUE_SIZE;
510 size = (port_private->tx_ring_size[queue] * TX_DESC_ALIGNED_SIZE); /*size = no of DESCs times DESC-size */
511 ethernet_private->tx_desc_area_size[queue] = size;
513 /* first clear desc area completely */
514 memset ((void *) ethernet_private->p_tx_desc_area_base[queue],
515 0, ethernet_private->tx_desc_area_size[queue]);
517 /* initialize tx desc ring with low level driver */
518 if (ether_init_tx_desc_ring
519 (ethernet_private, ETH_Q0,
520 port_private->tx_ring_size[queue],
521 MV64460_TX_BUFFER_SIZE /* Each Buffer is 1600 Byte */ ,
522 (unsigned int) ethernet_private->
523 p_tx_desc_area_base[queue],
524 (unsigned int) ethernet_private->
525 p_tx_buffer_base[queue]) == false)
526 printf ("### Error initializing TX Ring\n");
529 /* "Allocate" setup RX rings */
530 for (queue = 0; queue < MV64460_RX_QUEUE_NUM; queue++) {
533 /* Meantime RX Ring are fixed - but must be configurable by user */
534 port_private->rx_ring_size[queue] = MV64460_RX_QUEUE_SIZE;
535 size = (port_private->rx_ring_size[queue] *
536 RX_DESC_ALIGNED_SIZE);
537 ethernet_private->rx_desc_area_size[queue] = size;
539 /* first clear desc area completely */
540 memset ((void *) ethernet_private->p_rx_desc_area_base[queue],
541 0, ethernet_private->rx_desc_area_size[queue]);
542 if ((ether_init_rx_desc_ring
543 (ethernet_private, ETH_Q0,
544 port_private->rx_ring_size[queue],
545 MV64460_RX_BUFFER_SIZE /* Each Buffer is 1600 Byte */ ,
546 (unsigned int) ethernet_private->
547 p_rx_desc_area_base[queue],
548 (unsigned int) ethernet_private->
549 p_rx_buffer_base[queue])) == false)
550 printf ("### Error initializing RX Ring\n");
553 eth_port_start (ethernet_private);
555 /* Set maximum receive buffer to 9700 bytes */
556 MV_REG_WRITE (MV64460_ETH_PORT_SERIAL_CONTROL_REG (port_num),
559 (MV64460_ETH_PORT_SERIAL_CONTROL_REG (port_num))
563 * Set ethernet MTU for leaky bucket mechanism to 0 - this will
564 * disable the leaky bucket mechanism .
567 MV_REG_WRITE (MV64460_ETH_MAXIMUM_TRANSMIT_UNIT (port_num), 0);
568 MV_REG_READ (MV64460_ETH_PORT_STATUS_REG (port_num));
570 #if defined(CONFIG_PHY_RESET)
572 * Reset the phy, only if its the first time through
573 * otherwise, just check the speeds & feeds
575 if (port_private->first_init == 0) {
576 port_private->first_init = 1;
577 ethernet_phy_reset (port_num);
579 /* Start/Restart autonegotiation */
580 phy_setup_aneg (dev->name, reg);
583 #endif /* defined(CONFIG_PHY_RESET) */
585 miiphy_read (dev->name, reg, MII_BMSR, ®_short);
588 * Wait if PHY is capable of autonegotiation and autonegotiation is not complete
590 if ((reg_short & BMSR_ANEGCAPABLE)
591 && !(reg_short & BMSR_ANEGCOMPLETE)) {
592 puts ("Waiting for PHY auto negotiation to complete");
594 while (!(reg_short & BMSR_ANEGCOMPLETE)) {
598 if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
599 puts (" TIMEOUT !\n");
603 if ((i++ % 1000) == 0) {
606 udelay (1000); /* 1 ms */
607 miiphy_read (dev->name, reg, MII_BMSR, ®_short);
611 udelay (500000); /* another 500 ms (results in faster booting) */
614 speed = miiphy_speed (dev->name, reg);
615 duplex = miiphy_duplex (dev->name, reg);
617 printf ("ENET Speed is %d Mbps - %s duplex connection\n",
618 (int) speed, (duplex == HALF) ? "HALF" : "FULL");
620 port_private->eth_running = MAGIC_ETH_RUNNING;
624 static int mv64460_eth_free_tx_rings (struct eth_device *dev)
627 ETH_PORT_INFO *ethernet_private;
628 struct mv64460_eth_priv *port_private;
629 unsigned int port_num;
630 volatile ETH_TX_DESC *p_tx_curr_desc;
632 ethernet_private = (ETH_PORT_INFO *) dev->priv;
634 (struct mv64460_eth_priv *) ethernet_private->port_private;
635 port_num = port_private->port_num;
638 MV_REG_WRITE (MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG (port_num),
642 DP (printf ("Clearing previously allocated TX queues... "));
643 for (queue = 0; queue < MV64460_TX_QUEUE_NUM; queue++) {
644 /* Free on TX rings */
645 for (p_tx_curr_desc =
646 ethernet_private->p_tx_desc_area_base[queue];
647 ((unsigned int) p_tx_curr_desc <= (unsigned int)
648 ethernet_private->p_tx_desc_area_base[queue] +
649 ethernet_private->tx_desc_area_size[queue]);
651 (ETH_TX_DESC *) ((unsigned int) p_tx_curr_desc +
652 TX_DESC_ALIGNED_SIZE)) {
653 /* this is inside for loop */
654 if (p_tx_curr_desc->return_info != 0) {
655 p_tx_curr_desc->return_info = 0;
656 DP (printf ("freed\n"));
659 DP (printf ("Done\n"));
664 static int mv64460_eth_free_rx_rings (struct eth_device *dev)
667 ETH_PORT_INFO *ethernet_private;
668 struct mv64460_eth_priv *port_private;
669 unsigned int port_num;
670 volatile ETH_RX_DESC *p_rx_curr_desc;
672 ethernet_private = (ETH_PORT_INFO *) dev->priv;
674 (struct mv64460_eth_priv *) ethernet_private->port_private;
675 port_num = port_private->port_num;
678 MV_REG_WRITE (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG (port_num),
682 DP (printf ("Clearing previously allocated RX queues... "));
683 for (queue = 0; queue < MV64460_RX_QUEUE_NUM; queue++) {
684 /* Free preallocated skb's on RX rings */
685 for (p_rx_curr_desc =
686 ethernet_private->p_rx_desc_area_base[queue];
687 (((unsigned int) p_rx_curr_desc <
688 ((unsigned int) ethernet_private->
689 p_rx_desc_area_base[queue] +
690 ethernet_private->rx_desc_area_size[queue])));
692 (ETH_RX_DESC *) ((unsigned int) p_rx_curr_desc +
693 RX_DESC_ALIGNED_SIZE)) {
694 if (p_rx_curr_desc->return_info != 0) {
695 p_rx_curr_desc->return_info = 0;
696 DP (printf ("freed\n"));
699 DP (printf ("Done\n"));
704 /**********************************************************************
707 * This function is used when closing the network device.
708 * It updates the hardware,
709 * release all memory that holds buffers and descriptors and release the IRQ.
710 * Input : a pointer to the device structure
711 * Output : zero if success , nonzero if fails
712 *********************************************************************/
714 int mv64460_eth_stop (struct eth_device *dev)
716 /* Disable all gigE address decoder */
717 MV_REG_WRITE (MV64460_ETH_BASE_ADDR_ENABLE_REG, 0x3f);
718 DP (printf ("%s Ethernet stop called ... \n", __FUNCTION__));
719 mv64460_eth_real_stop (dev);
724 /* Helper function for mv64460_eth_stop */
726 static int mv64460_eth_real_stop (struct eth_device *dev)
728 ETH_PORT_INFO *ethernet_private;
729 struct mv64460_eth_priv *port_private;
730 unsigned int port_num;
732 ethernet_private = (ETH_PORT_INFO *) dev->priv;
734 (struct mv64460_eth_priv *) ethernet_private->port_private;
735 port_num = port_private->port_num;
737 mv64460_eth_free_tx_rings (dev);
738 mv64460_eth_free_rx_rings (dev);
740 eth_port_reset (ethernet_private->port_num);
741 /* Disable ethernet port interrupts */
742 MV_REG_WRITE (MV64460_ETH_INTERRUPT_CAUSE_REG (port_num), 0);
743 MV_REG_WRITE (MV64460_ETH_INTERRUPT_CAUSE_EXTEND_REG (port_num), 0);
744 /* Mask RX buffer and TX end interrupt */
745 MV_REG_WRITE (MV64460_ETH_INTERRUPT_MASK_REG (port_num), 0);
746 /* Mask phy and link status changes interrupts */
747 MV_REG_WRITE (MV64460_ETH_INTERRUPT_EXTEND_MASK_REG (port_num), 0);
748 MV_RESET_REG_BITS (MV64460_CPU_INTERRUPT0_MASK_HIGH,
750 /* Print Network statistics */
751 #ifndef UPDATE_STATS_BY_SOFTWARE
753 * Print statistics (only if ethernet is running),
754 * then zero all the stats fields in memory
756 if (port_private->eth_running == MAGIC_ETH_RUNNING) {
757 port_private->eth_running = 0;
758 mv64460_eth_print_stat (dev);
760 memset (port_private->stats, 0, sizeof (struct net_device_stats));
762 DP (printf ("\nEthernet stopped ... \n"));
766 /**********************************************************************
767 * mv64460_eth_start_xmit
769 * This function is queues a packet in the Tx descriptor for
772 * Input : skb - a pointer to socket buffer
773 * dev - a pointer to the required port
775 * Output : zero upon success
776 **********************************************************************/
778 int mv64460_eth_xmit (struct eth_device *dev, volatile void *dataPtr,
781 ETH_PORT_INFO *ethernet_private;
782 struct mv64460_eth_priv *port_private;
784 ETH_FUNC_RET_STATUS status;
785 struct net_device_stats *stats;
786 ETH_FUNC_RET_STATUS release_result;
788 ethernet_private = (ETH_PORT_INFO *) dev->priv;
790 (struct mv64460_eth_priv *) ethernet_private->port_private;
792 stats = port_private->stats;
794 /* Update packet info data structure */
795 pkt_info.cmd_sts = ETH_TX_FIRST_DESC | ETH_TX_LAST_DESC; /* DMA owned, first last */
796 pkt_info.byte_cnt = dataSize;
797 pkt_info.buf_ptr = (unsigned int) dataPtr;
798 pkt_info.return_info = 0;
800 status = eth_port_send (ethernet_private, ETH_Q0, &pkt_info);
801 if ((status == ETH_ERROR) || (status == ETH_QUEUE_FULL)) {
802 printf ("Error on transmitting packet ..");
803 if (status == ETH_QUEUE_FULL)
804 printf ("ETH Queue is full. \n");
805 if (status == ETH_QUEUE_LAST_RESOURCE)
806 printf ("ETH Queue: using last available resource. \n");
810 /* Update statistics and start of transmittion time */
811 stats->tx_bytes += dataSize;
814 /* Check if packet(s) is(are) transmitted correctly (release everything) */
817 eth_tx_return_desc (ethernet_private, ETH_Q0,
819 switch (release_result) {
821 DP (printf ("descriptor released\n"));
822 if (pkt_info.cmd_sts & BIT0) {
823 printf ("Error in TX\n");
828 DP (printf ("transmission still in process\n"));
832 printf ("routine can not access Tx desc ring\n");
836 DP (printf ("the routine has nothing to release\n"));
838 default: /* should not happen */
841 } while (release_result == ETH_OK);
843 return 0; /* success */
846 /**********************************************************************
847 * mv64460_eth_receive
849 * This function is forward packets that are received from the port's
850 * queues toward kernel core or FastRoute them to another interface.
852 * Input : dev - a pointer to the required interface
853 * max - maximum number to receive (0 means unlimted)
855 * Output : number of served packets
856 **********************************************************************/
858 int mv64460_eth_receive (struct eth_device *dev)
860 ETH_PORT_INFO *ethernet_private;
861 struct mv64460_eth_priv *port_private;
863 struct net_device_stats *stats;
865 ethernet_private = (ETH_PORT_INFO *) dev->priv;
866 port_private = (struct mv64460_eth_priv *) ethernet_private->port_private;
867 stats = port_private->stats;
869 while ((eth_port_receive (ethernet_private, ETH_Q0, &pkt_info) == ETH_OK)) {
871 if (pkt_info.byte_cnt != 0) {
872 printf ("%s: Received %d byte Packet @ 0x%x\n",
873 __FUNCTION__, pkt_info.byte_cnt,
875 if(pkt_info.buf_ptr != 0){
876 for(i=0; i < pkt_info.byte_cnt; i++){
880 printf("%02x", ((char*)pkt_info.buf_ptr)[i]);
886 /* Update statistics. Note byte count includes 4 byte CRC count */
888 stats->rx_bytes += pkt_info.byte_cnt;
891 * In case received a packet without first / last bits on OR the error
892 * summary bit is on, the packets needs to be dropeed.
895 cmd_sts & (ETH_RX_FIRST_DESC | ETH_RX_LAST_DESC)) !=
896 (ETH_RX_FIRST_DESC | ETH_RX_LAST_DESC))
897 || (pkt_info.cmd_sts & ETH_ERROR_SUMMARY)) {
900 printf ("Received packet spread on multiple descriptors\n");
902 /* Is this caused by an error ? */
903 if (pkt_info.cmd_sts & ETH_ERROR_SUMMARY) {
907 /* free these descriptors again without forwarding them to the higher layers */
908 pkt_info.buf_ptr &= ~0x7; /* realign buffer again */
909 pkt_info.byte_cnt = 0x0000; /* Reset Byte count */
911 if (eth_rx_return_buff
912 (ethernet_private, ETH_Q0, &pkt_info) != ETH_OK) {
913 printf ("Error while returning the RX Desc to Ring\n");
915 DP (printf ("RX Desc returned to Ring\n"));
917 /* /free these descriptors again */
920 /* !!! call higher layer processing */
922 printf ("\nNow send it to upper layer protocols (NetReceive) ...\n");
924 /* let the upper layer handle the packet */
925 NetReceive ((uchar *) pkt_info.buf_ptr,
926 (int) pkt_info.byte_cnt);
928 /* **************************************************************** */
929 /* free descriptor */
930 pkt_info.buf_ptr &= ~0x7; /* realign buffer again */
931 pkt_info.byte_cnt = 0x0000; /* Reset Byte count */
932 DP (printf ("RX: pkt_info.buf_ptr = %x\n", pkt_info.buf_ptr));
933 if (eth_rx_return_buff
934 (ethernet_private, ETH_Q0, &pkt_info) != ETH_OK) {
935 printf ("Error while returning the RX Desc to Ring\n");
937 DP (printf ("RX: Desc returned to Ring\n"));
940 /* **************************************************************** */
944 mv64460_eth_get_stats (dev); /* update statistics */
948 /**********************************************************************
949 * mv64460_eth_get_stats
951 * Returns a pointer to the interface statistics.
953 * Input : dev - a pointer to the required interface
955 * Output : a pointer to the interface's statistics
956 **********************************************************************/
958 static struct net_device_stats *mv64460_eth_get_stats (struct eth_device *dev)
960 ETH_PORT_INFO *ethernet_private;
961 struct mv64460_eth_priv *port_private;
963 ethernet_private = (ETH_PORT_INFO *) dev->priv;
965 (struct mv64460_eth_priv *) ethernet_private->port_private;
967 mv64460_eth_update_stat (dev);
969 return port_private->stats;
972 /**********************************************************************
973 * mv64460_eth_update_stat
975 * Update the statistics structure in the private data structure
977 * Input : pointer to ethernet interface network device structure
979 **********************************************************************/
981 static void mv64460_eth_update_stat (struct eth_device *dev)
983 ETH_PORT_INFO *ethernet_private;
984 struct mv64460_eth_priv *port_private;
985 struct net_device_stats *stats;
987 ethernet_private = (ETH_PORT_INFO *) dev->priv;
989 (struct mv64460_eth_priv *) ethernet_private->port_private;
990 stats = port_private->stats;
992 /* These are false updates */
993 stats->rx_packets += (unsigned long)
994 eth_read_mib_counter (ethernet_private->port_num,
995 ETH_MIB_GOOD_FRAMES_RECEIVED);
996 stats->tx_packets += (unsigned long)
997 eth_read_mib_counter (ethernet_private->port_num,
998 ETH_MIB_GOOD_FRAMES_SENT);
999 stats->rx_bytes += (unsigned long)
1000 eth_read_mib_counter (ethernet_private->port_num,
1001 ETH_MIB_GOOD_OCTETS_RECEIVED_LOW);
1003 * Ideally this should be as follows -
1005 * stats->rx_bytes += stats->rx_bytes +
1006 * ((unsigned long) ethReadMibCounter (ethernet_private->port_num ,
1007 * ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH) << 32);
1009 * But the unsigned long in PowerPC and MIPS are 32bit. So the next read
1010 * is just a dummy read for proper work of the GigE port
1012 (void)eth_read_mib_counter (ethernet_private->port_num,
1013 ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH);
1014 stats->tx_bytes += (unsigned long)
1015 eth_read_mib_counter (ethernet_private->port_num,
1016 ETH_MIB_GOOD_OCTETS_SENT_LOW);
1017 (void)eth_read_mib_counter (ethernet_private->port_num,
1018 ETH_MIB_GOOD_OCTETS_SENT_HIGH);
1019 stats->rx_errors += (unsigned long)
1020 eth_read_mib_counter (ethernet_private->port_num,
1021 ETH_MIB_MAC_RECEIVE_ERROR);
1023 /* Rx dropped is for received packet with CRC error */
1024 stats->rx_dropped +=
1025 (unsigned long) eth_read_mib_counter (ethernet_private->
1027 ETH_MIB_BAD_CRC_EVENT);
1028 stats->multicast += (unsigned long)
1029 eth_read_mib_counter (ethernet_private->port_num,
1030 ETH_MIB_MULTICAST_FRAMES_RECEIVED);
1031 stats->collisions +=
1032 (unsigned long) eth_read_mib_counter (ethernet_private->
1034 ETH_MIB_COLLISION) +
1035 (unsigned long) eth_read_mib_counter (ethernet_private->
1037 ETH_MIB_LATE_COLLISION);
1038 /* detailed rx errors */
1039 stats->rx_length_errors +=
1040 (unsigned long) eth_read_mib_counter (ethernet_private->
1042 ETH_MIB_UNDERSIZE_RECEIVED)
1044 (unsigned long) eth_read_mib_counter (ethernet_private->
1046 ETH_MIB_OVERSIZE_RECEIVED);
1047 /* detailed tx errors */
1050 #ifndef UPDATE_STATS_BY_SOFTWARE
1051 /**********************************************************************
1052 * mv64460_eth_print_stat
1054 * Update the statistics structure in the private data structure
1056 * Input : pointer to ethernet interface network device structure
1058 **********************************************************************/
1060 static void mv64460_eth_print_stat (struct eth_device *dev)
1062 ETH_PORT_INFO *ethernet_private;
1063 struct mv64460_eth_priv *port_private;
1064 struct net_device_stats *stats;
1066 ethernet_private = (ETH_PORT_INFO *) dev->priv;
1068 (struct mv64460_eth_priv *) ethernet_private->port_private;
1069 stats = port_private->stats;
1071 /* These are false updates */
1072 printf ("\n### Network statistics: ###\n");
1073 printf ("--------------------------\n");
1074 printf (" Packets received: %ld\n", stats->rx_packets);
1075 printf (" Packets send: %ld\n", stats->tx_packets);
1076 printf (" Received bytes: %ld\n", stats->rx_bytes);
1077 printf (" Send bytes: %ld\n", stats->tx_bytes);
1078 if (stats->rx_errors != 0)
1079 printf (" Rx Errors: %ld\n",
1081 if (stats->rx_dropped != 0)
1082 printf (" Rx dropped (CRC Errors): %ld\n",
1084 if (stats->multicast != 0)
1085 printf (" Rx mulicast frames: %ld\n",
1087 if (stats->collisions != 0)
1088 printf (" No. of collisions: %ld\n",
1090 if (stats->rx_length_errors != 0)
1091 printf (" Rx length errors: %ld\n",
1092 stats->rx_length_errors);
1096 /**************************************************************************
1097 *network_start - Network Kick Off Routine UBoot
1100 **************************************************************************/
1102 bool db64460_eth_start (struct eth_device *dev)
1104 return (mv64460_eth_open (dev)); /* calls real open */
1107 /*************************************************************************
1108 **************************************************************************
1109 **************************************************************************
1110 * The second part is the low level driver of the gigE ethernet ports. *
1111 **************************************************************************
1112 **************************************************************************
1113 *************************************************************************/
1115 * based on Linux code
1116 * arch/powerpc/galileo/EVB64460/mv64460_eth.c - Driver for MV64460X ethernet ports
1117 * Copyright (C) 2002 rabeeh@galileo.co.il
1119 * This program is free software; you can redistribute it and/or
1120 * modify it under the terms of the GNU General Public License
1121 * as published by the Free Software Foundation; either version 2
1122 * of the License, or (at your option) any later version.
1124 * This program is distributed in the hope that it will be useful,
1125 * but WITHOUT ANY WARRANTY; without even the implied warranty of
1126 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1127 * GNU General Public License for more details.
1129 * You should have received a copy of the GNU General Public License
1130 * along with this program; if not, write to the Free Software
1131 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1135 /********************************************************************************
1136 * Marvell's Gigabit Ethernet controller low level driver
1139 * This file introduce low level API to Marvell's Gigabit Ethernet
1140 * controller. This Gigabit Ethernet Controller driver API controls
1141 * 1) Operations (i.e. port init, start, reset etc').
1142 * 2) Data flow (i.e. port send, receive etc').
1143 * Each Gigabit Ethernet port is controlled via ETH_PORT_INFO
1145 * This struct includes user configuration information as well as
1146 * driver internal data needed for its operations.
1148 * Supported Features:
1149 * - This low level driver is OS independent. Allocating memory for
1150 * the descriptor rings and buffers are not within the scope of
1152 * - The user is free from Rx/Tx queue managing.
1153 * - This low level driver introduce functionality API that enable
1154 * the to operate Marvell's Gigabit Ethernet Controller in a
1156 * - Simple Gigabit Ethernet port operation API.
1157 * - Simple Gigabit Ethernet port data flow API.
1158 * - Data flow and operation API support per queue functionality.
1159 * - Support cached descriptors for better performance.
1160 * - Enable access to all four DRAM banks and internal SRAM memory
1162 * - PHY access and control API.
1163 * - Port control register configuration API.
1164 * - Full control over Unicast and Multicast MAC configurations.
1168 * Initialization phase
1169 * This phase complete the initialization of the ETH_PORT_INFO
1171 * User information regarding port configuration has to be set
1172 * prior to calling the port initialization routine. For example,
1173 * the user has to assign the port_phy_addr field which is board
1174 * depended parameter.
1175 * In this phase any port Tx/Rx activity is halted, MIB counters
1176 * are cleared, PHY address is set according to user parameter and
1177 * access to DRAM and internal SRAM memory spaces.
1179 * Driver ring initialization
1180 * Allocating memory for the descriptor rings and buffers is not
1181 * within the scope of this driver. Thus, the user is required to
1182 * allocate memory for the descriptors ring and buffers. Those
1183 * memory parameters are used by the Rx and Tx ring initialization
1184 * routines in order to curve the descriptor linked list in a form
1186 * Note: Pay special attention to alignment issues when using
1187 * cached descriptors/buffers. In this phase the driver store
1188 * information in the ETH_PORT_INFO struct regarding each queue
1192 * This phase prepares the Ethernet port for Rx and Tx activity.
1193 * It uses the information stored in the ETH_PORT_INFO struct to
1194 * initialize the various port registers.
1197 * All packet references to/from the driver are done using PKT_INFO
1199 * This struct is a unified struct used with Rx and Tx operations.
1200 * This way the user is not required to be familiar with neither
1201 * Tx nor Rx descriptors structures.
1202 * The driver's descriptors rings are management by indexes.
1203 * Those indexes controls the ring resources and used to indicate
1204 * a SW resource error:
1206 * This index points to the current available resource for use. For
1207 * example in Rx process this index will point to the descriptor
1208 * that will be passed to the user upon calling the receive routine.
1209 * In Tx process, this index will point to the descriptor
1210 * that will be assigned with the user packet info and transmitted.
1212 * This index points to the descriptor that need to restore its
1213 * resources. For example in Rx process, using the Rx buffer return
1214 * API will attach the buffer returned in packet info to the
1215 * descriptor pointed by 'used'. In Tx process, using the Tx
1216 * descriptor return will merely return the user packet info with
1217 * the command status of the transmitted buffer pointed by the
1218 * 'used' index. Nevertheless, it is essential to use this routine
1219 * to update the 'used' index.
1221 * This index supports Tx Scatter-Gather. It points to the first
1222 * descriptor of a packet assembled of multiple buffers. For example
1223 * when in middle of Such packet we have a Tx resource error the
1224 * 'curr' index get the value of 'first' to indicate that the ring
1225 * returned to its state before trying to transmit this packet.
1227 * Receive operation:
1228 * The eth_port_receive API set the packet information struct,
1229 * passed by the caller, with received information from the
1230 * 'current' SDMA descriptor.
1231 * It is the user responsibility to return this resource back
1232 * to the Rx descriptor ring to enable the reuse of this source.
1233 * Return Rx resource is done using the eth_rx_return_buff API.
1235 * Transmit operation:
1236 * The eth_port_send API supports Scatter-Gather which enables to
1237 * send a packet spanned over multiple buffers. This means that
1238 * for each packet info structure given by the user and put into
1239 * the Tx descriptors ring, will be transmitted only if the 'LAST'
1240 * bit will be set in the packet info command status field. This
1241 * API also consider restriction regarding buffer alignments and
1243 * The user must return a Tx resource after ensuring the buffer
1244 * has been transmitted to enable the Tx ring indexes to update.
1247 * This device is on-board. No jumper diagram is necessary.
1249 * EXTERNAL INTERFACE
1251 * Prior to calling the initialization routine eth_port_init() the user
1252 * must set the following fields under ETH_PORT_INFO struct:
1253 * port_num User Ethernet port number.
1254 * port_phy_addr User PHY address of Ethernet port.
1255 * port_mac_addr[6] User defined port MAC address.
1256 * port_config User port configuration value.
1257 * port_config_extend User port config extend value.
1258 * port_sdma_config User port SDMA config value.
1259 * port_serial_control User port serial control value.
1260 * *port_virt_to_phys () User function to cast virtual addr to CPU bus addr.
1261 * *port_private User scratch pad for user specific data structures.
1263 * This driver introduce a set of default values:
1264 * PORT_CONFIG_VALUE Default port configuration value
1265 * PORT_CONFIG_EXTEND_VALUE Default port extend configuration value
1266 * PORT_SDMA_CONFIG_VALUE Default sdma control value
1267 * PORT_SERIAL_CONTROL_VALUE Default port serial control value
1269 * This driver data flow is done using the PKT_INFO struct which is
1270 * a unified struct for Rx and Tx operations:
1271 * byte_cnt Tx/Rx descriptor buffer byte count.
1272 * l4i_chk CPU provided TCP Checksum. For Tx operation only.
1273 * cmd_sts Tx/Rx descriptor command status.
1274 * buf_ptr Tx/Rx descriptor buffer pointer.
1275 * return_info Tx/Rx user resource return information.
1278 * EXTERNAL SUPPORT REQUIREMENTS
1280 * This driver requires the following external support:
1282 * D_CACHE_FLUSH_LINE (address, address offset)
1284 * This macro applies assembly code to flush and invalidate cache
1286 * address - address base.
1287 * address offset - address offset
1292 * This macro applies assembly code to flush the CPU pipeline.
1294 *******************************************************************************/
1298 /* SDMA command macros */
1299 #define ETH_ENABLE_TX_QUEUE(tx_queue, eth_port) \
1300 MV_REG_WRITE(MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG(eth_port), (1 << tx_queue))
1302 #define ETH_DISABLE_TX_QUEUE(tx_queue, eth_port) \
1303 MV_REG_WRITE(MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG(eth_port),\
1304 (1 << (8 + tx_queue)))
1306 #define ETH_ENABLE_RX_QUEUE(rx_queue, eth_port) \
1307 MV_REG_WRITE(MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG(eth_port), (1 << rx_queue))
1309 #define ETH_DISABLE_RX_QUEUE(rx_queue, eth_port) \
1310 MV_REG_WRITE(MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG(eth_port), (1 << (8 + rx_queue)))
1312 #define CURR_RFD_GET(p_curr_desc, queue) \
1313 ((p_curr_desc) = p_eth_port_ctrl->p_rx_curr_desc_q[queue])
1315 #define CURR_RFD_SET(p_curr_desc, queue) \
1316 (p_eth_port_ctrl->p_rx_curr_desc_q[queue] = (p_curr_desc))
1318 #define USED_RFD_GET(p_used_desc, queue) \
1319 ((p_used_desc) = p_eth_port_ctrl->p_rx_used_desc_q[queue])
1321 #define USED_RFD_SET(p_used_desc, queue)\
1322 (p_eth_port_ctrl->p_rx_used_desc_q[queue] = (p_used_desc))
1325 #define CURR_TFD_GET(p_curr_desc, queue) \
1326 ((p_curr_desc) = p_eth_port_ctrl->p_tx_curr_desc_q[queue])
1328 #define CURR_TFD_SET(p_curr_desc, queue) \
1329 (p_eth_port_ctrl->p_tx_curr_desc_q[queue] = (p_curr_desc))
1331 #define USED_TFD_GET(p_used_desc, queue) \
1332 ((p_used_desc) = p_eth_port_ctrl->p_tx_used_desc_q[queue])
1334 #define USED_TFD_SET(p_used_desc, queue) \
1335 (p_eth_port_ctrl->p_tx_used_desc_q[queue] = (p_used_desc))
1337 #define FIRST_TFD_GET(p_first_desc, queue) \
1338 ((p_first_desc) = p_eth_port_ctrl->p_tx_first_desc_q[queue])
1340 #define FIRST_TFD_SET(p_first_desc, queue) \
1341 (p_eth_port_ctrl->p_tx_first_desc_q[queue] = (p_first_desc))
1344 /* Macros that save access to desc in order to find next desc pointer */
1345 #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])
1347 #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])
1349 #define LINK_UP_TIMEOUT 100000
1350 #define PHY_BUSY_TIMEOUT 10000000
1355 static void ethernet_phy_set (ETH_PORT eth_port_num, int phy_addr);
1356 static int ethernet_phy_get (ETH_PORT eth_port_num);
1358 /* Ethernet Port routines */
1359 static void eth_set_access_control (ETH_PORT eth_port_num,
1360 ETH_WIN_PARAM * param);
1361 static bool eth_port_uc_addr (ETH_PORT eth_port_num, unsigned char uc_nibble,
1362 ETH_QUEUE queue, int option);
1364 static bool eth_port_smc_addr (ETH_PORT eth_port_num,
1365 unsigned char mc_byte,
1366 ETH_QUEUE queue, int option);
1367 static bool eth_port_omc_addr (ETH_PORT eth_port_num,
1369 ETH_QUEUE queue, int option);
1372 static void eth_b_copy (unsigned int src_addr, unsigned int dst_addr,
1375 void eth_dbg (ETH_PORT_INFO * p_eth_port_ctrl);
1378 typedef enum _memory_bank { BANK0, BANK1, BANK2, BANK3 } MEMORY_BANK;
1379 u32 mv_get_dram_bank_base_addr (MEMORY_BANK bank)
1382 u32 enable = MV_REG_READ (MV64460_BASE_ADDR_ENABLE);
1384 if (enable & (1 << bank))
1387 result = MV_REG_READ (MV64460_CS_0_BASE_ADDR);
1389 result = MV_REG_READ (MV64460_CS_1_BASE_ADDR);
1391 result = MV_REG_READ (MV64460_CS_2_BASE_ADDR);
1393 result = MV_REG_READ (MV64460_CS_3_BASE_ADDR);
1394 result &= 0x0000ffff;
1395 result = result << 16;
1399 u32 mv_get_dram_bank_size (MEMORY_BANK bank)
1402 u32 enable = MV_REG_READ (MV64460_BASE_ADDR_ENABLE);
1404 if (enable & (1 << bank))
1407 result = MV_REG_READ (MV64460_CS_0_SIZE);
1409 result = MV_REG_READ (MV64460_CS_1_SIZE);
1411 result = MV_REG_READ (MV64460_CS_2_SIZE);
1413 result = MV_REG_READ (MV64460_CS_3_SIZE);
1415 result &= 0x0000ffff;
1416 result = result << 16;
1420 u32 mv_get_internal_sram_base (void)
1424 result = MV_REG_READ (MV64460_INTEGRATED_SRAM_BASE_ADDR);
1425 result &= 0x0000ffff;
1426 result = result << 16;
1430 /*******************************************************************************
1431 * eth_port_init - Initialize the Ethernet port driver
1434 * This function prepares the ethernet port to start its activity:
1435 * 1) Completes the ethernet port driver struct initialization toward port
1437 * 2) Resets the device to a quiescent state in case of warm reboot.
1438 * 3) Enable SDMA access to all four DRAM banks as well as internal SRAM.
1439 * 4) Clean MAC tables. The reset status of those tables is unknown.
1440 * 5) Set PHY address.
1441 * Note: Call this routine prior to eth_port_start routine and after setting
1442 * user values in the user fields of Ethernet port control struct (i.e.
1446 * ETH_PORT_INFO *p_eth_port_ctrl Ethernet port control struct
1454 *******************************************************************************/
1455 static void eth_port_init (ETH_PORT_INFO * p_eth_port_ctrl)
1458 ETH_WIN_PARAM win_param;
1460 p_eth_port_ctrl->port_config = PORT_CONFIG_VALUE;
1461 p_eth_port_ctrl->port_config_extend = PORT_CONFIG_EXTEND_VALUE;
1462 p_eth_port_ctrl->port_sdma_config = PORT_SDMA_CONFIG_VALUE;
1463 p_eth_port_ctrl->port_serial_control = PORT_SERIAL_CONTROL_VALUE;
1465 p_eth_port_ctrl->port_rx_queue_command = 0;
1466 p_eth_port_ctrl->port_tx_queue_command = 0;
1468 /* Zero out SW structs */
1469 for (queue = 0; queue < MAX_RX_QUEUE_NUM; queue++) {
1470 CURR_RFD_SET ((ETH_RX_DESC *) 0x00000000, queue);
1471 USED_RFD_SET ((ETH_RX_DESC *) 0x00000000, queue);
1472 p_eth_port_ctrl->rx_resource_err[queue] = false;
1475 for (queue = 0; queue < MAX_TX_QUEUE_NUM; queue++) {
1476 CURR_TFD_SET ((ETH_TX_DESC *) 0x00000000, queue);
1477 USED_TFD_SET ((ETH_TX_DESC *) 0x00000000, queue);
1478 FIRST_TFD_SET ((ETH_TX_DESC *) 0x00000000, queue);
1479 p_eth_port_ctrl->tx_resource_err[queue] = false;
1482 eth_port_reset (p_eth_port_ctrl->port_num);
1484 /* Set access parameters for DRAM bank 0 */
1485 win_param.win = ETH_WIN0; /* Use Ethernet window 0 */
1486 win_param.target = ETH_TARGET_DRAM; /* Window target - DDR */
1487 win_param.attributes = EBAR_ATTR_DRAM_CS0; /* Enable DRAM bank */
1488 #ifndef CONFIG_NOT_COHERENT_CACHE
1489 win_param.attributes |= EBAR_ATTR_DRAM_CACHE_COHERENCY_WB;
1491 win_param.high_addr = 0;
1493 win_param.base_addr = mv_get_dram_bank_base_addr (BANK0);
1494 win_param.size = mv_get_dram_bank_size (BANK0); /* Get bank size */
1495 if (win_param.size == 0)
1496 win_param.enable = 0;
1498 win_param.enable = 1; /* Enable the access */
1499 win_param.access_ctrl = EWIN_ACCESS_FULL; /* Enable full access */
1501 /* Set the access control for address window (EPAPR) READ & WRITE */
1502 eth_set_access_control (p_eth_port_ctrl->port_num, &win_param);
1504 /* Set access parameters for DRAM bank 1 */
1505 win_param.win = ETH_WIN1; /* Use Ethernet window 1 */
1506 win_param.target = ETH_TARGET_DRAM; /* Window target - DDR */
1507 win_param.attributes = EBAR_ATTR_DRAM_CS1; /* Enable DRAM bank */
1508 #ifndef CONFIG_NOT_COHERENT_CACHE
1509 win_param.attributes |= EBAR_ATTR_DRAM_CACHE_COHERENCY_WB;
1511 win_param.high_addr = 0;
1513 win_param.base_addr = mv_get_dram_bank_base_addr (BANK1);
1514 win_param.size = mv_get_dram_bank_size (BANK1); /* Get bank size */
1515 if (win_param.size == 0)
1516 win_param.enable = 0;
1518 win_param.enable = 1; /* Enable the access */
1519 win_param.access_ctrl = EWIN_ACCESS_FULL; /* Enable full access */
1521 /* Set the access control for address window (EPAPR) READ & WRITE */
1522 eth_set_access_control (p_eth_port_ctrl->port_num, &win_param);
1524 /* Set access parameters for DRAM bank 2 */
1525 win_param.win = ETH_WIN2; /* Use Ethernet window 2 */
1526 win_param.target = ETH_TARGET_DRAM; /* Window target - DDR */
1527 win_param.attributes = EBAR_ATTR_DRAM_CS2; /* Enable DRAM bank */
1528 #ifndef CONFIG_NOT_COHERENT_CACHE
1529 win_param.attributes |= EBAR_ATTR_DRAM_CACHE_COHERENCY_WB;
1531 win_param.high_addr = 0;
1533 win_param.base_addr = mv_get_dram_bank_base_addr (BANK2);
1534 win_param.size = mv_get_dram_bank_size (BANK2); /* Get bank size */
1535 if (win_param.size == 0)
1536 win_param.enable = 0;
1538 win_param.enable = 1; /* Enable the access */
1539 win_param.access_ctrl = EWIN_ACCESS_FULL; /* Enable full access */
1541 /* Set the access control for address window (EPAPR) READ & WRITE */
1542 eth_set_access_control (p_eth_port_ctrl->port_num, &win_param);
1544 /* Set access parameters for DRAM bank 3 */
1545 win_param.win = ETH_WIN3; /* Use Ethernet window 3 */
1546 win_param.target = ETH_TARGET_DRAM; /* Window target - DDR */
1547 win_param.attributes = EBAR_ATTR_DRAM_CS3; /* Enable DRAM bank */
1548 #ifndef CONFIG_NOT_COHERENT_CACHE
1549 win_param.attributes |= EBAR_ATTR_DRAM_CACHE_COHERENCY_WB;
1551 win_param.high_addr = 0;
1553 win_param.base_addr = mv_get_dram_bank_base_addr (BANK3);
1554 win_param.size = mv_get_dram_bank_size (BANK3); /* Get bank size */
1555 if (win_param.size == 0)
1556 win_param.enable = 0;
1558 win_param.enable = 1; /* Enable the access */
1559 win_param.access_ctrl = EWIN_ACCESS_FULL; /* Enable full access */
1561 /* Set the access control for address window (EPAPR) READ & WRITE */
1562 eth_set_access_control (p_eth_port_ctrl->port_num, &win_param);
1564 /* Set access parameters for Internal SRAM */
1565 win_param.win = ETH_WIN4; /* Use Ethernet window 0 */
1566 win_param.target = EBAR_TARGET_CBS; /* Target - Internal SRAM */
1567 win_param.attributes = EBAR_ATTR_CBS_SRAM | EBAR_ATTR_CBS_SRAM_BLOCK0;
1568 win_param.high_addr = 0;
1569 win_param.base_addr = mv_get_internal_sram_base (); /* Get base addr */
1570 win_param.size = MV64460_INTERNAL_SRAM_SIZE; /* Get bank size */
1571 win_param.enable = 1; /* Enable the access */
1572 win_param.access_ctrl = EWIN_ACCESS_FULL; /* Enable full access */
1574 /* Set the access control for address window (EPAPR) READ & WRITE */
1575 eth_set_access_control (p_eth_port_ctrl->port_num, &win_param);
1577 eth_port_init_mac_tables (p_eth_port_ctrl->port_num);
1579 ethernet_phy_set (p_eth_port_ctrl->port_num,
1580 p_eth_port_ctrl->port_phy_addr);
1586 /*******************************************************************************
1587 * eth_port_start - Start the Ethernet port activity.
1590 * This routine prepares the Ethernet port for Rx and Tx activity:
1591 * 1. Initialize Tx and Rx Current Descriptor Pointer for each queue that
1592 * has been initialized a descriptor's ring (using ether_init_tx_desc_ring
1593 * for Tx and ether_init_rx_desc_ring for Rx)
1594 * 2. Initialize and enable the Ethernet configuration port by writing to
1595 * the port's configuration and command registers.
1596 * 3. Initialize and enable the SDMA by writing to the SDMA's
1597 * configuration and command registers.
1598 * After completing these steps, the ethernet port SDMA can starts to
1599 * perform Rx and Tx activities.
1601 * Note: Each Rx and Tx queue descriptor's list must be initialized prior
1602 * to calling this function (use ether_init_tx_desc_ring for Tx queues and
1603 * ether_init_rx_desc_ring for Rx queues).
1606 * ETH_PORT_INFO *p_eth_port_ctrl Ethernet port control struct
1609 * Ethernet port is ready to receive and transmit.
1612 * false if the port PHY is not up.
1615 *******************************************************************************/
1616 static bool eth_port_start (ETH_PORT_INFO * p_eth_port_ctrl)
1619 volatile ETH_TX_DESC *p_tx_curr_desc;
1620 volatile ETH_RX_DESC *p_rx_curr_desc;
1621 unsigned int phy_reg_data;
1622 ETH_PORT eth_port_num = p_eth_port_ctrl->port_num;
1624 /* Assignment of Tx CTRP of given queue */
1625 for (queue = 0; queue < MAX_TX_QUEUE_NUM; queue++) {
1626 CURR_TFD_GET (p_tx_curr_desc, queue);
1627 MV_REG_WRITE ((MV64460_ETH_TX_CURRENT_QUEUE_DESC_PTR_0
1630 ((unsigned int) p_tx_curr_desc));
1634 /* Assignment of Rx CRDP of given queue */
1635 for (queue = 0; queue < MAX_RX_QUEUE_NUM; queue++) {
1636 CURR_RFD_GET (p_rx_curr_desc, queue);
1637 MV_REG_WRITE ((MV64460_ETH_RX_CURRENT_QUEUE_DESC_PTR_0
1640 ((unsigned int) p_rx_curr_desc));
1642 if (p_rx_curr_desc != NULL)
1643 /* Add the assigned Ethernet address to the port's address table */
1644 eth_port_uc_addr_set (p_eth_port_ctrl->port_num,
1645 p_eth_port_ctrl->port_mac_addr,
1649 /* Assign port configuration and command. */
1650 MV_REG_WRITE (MV64460_ETH_PORT_CONFIG_REG (eth_port_num),
1651 p_eth_port_ctrl->port_config);
1653 MV_REG_WRITE (MV64460_ETH_PORT_CONFIG_EXTEND_REG (eth_port_num),
1654 p_eth_port_ctrl->port_config_extend);
1656 MV_REG_WRITE (MV64460_ETH_PORT_SERIAL_CONTROL_REG (eth_port_num),
1657 p_eth_port_ctrl->port_serial_control);
1659 MV_SET_REG_BITS (MV64460_ETH_PORT_SERIAL_CONTROL_REG (eth_port_num),
1660 ETH_SERIAL_PORT_ENABLE);
1662 /* Assign port SDMA configuration */
1663 MV_REG_WRITE (MV64460_ETH_SDMA_CONFIG_REG (eth_port_num),
1664 p_eth_port_ctrl->port_sdma_config);
1666 MV_REG_WRITE (MV64460_ETH_TX_QUEUE_0_TOKEN_BUCKET_COUNT
1667 (eth_port_num), 0x3fffffff);
1668 MV_REG_WRITE (MV64460_ETH_TX_QUEUE_0_TOKEN_BUCKET_CONFIG
1669 (eth_port_num), 0x03fffcff);
1670 /* Turn off the port/queue bandwidth limitation */
1671 MV_REG_WRITE (MV64460_ETH_MAXIMUM_TRANSMIT_UNIT (eth_port_num), 0x0);
1673 /* Enable port Rx. */
1674 MV_REG_WRITE (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG (eth_port_num),
1675 p_eth_port_ctrl->port_rx_queue_command);
1677 /* Check if link is up */
1678 eth_port_read_smi_reg (eth_port_num, 1, &phy_reg_data);
1680 if (!(phy_reg_data & 0x20))
1686 /*******************************************************************************
1687 * eth_port_uc_addr_set - This function Set the port Unicast address.
1690 * This function Set the port Ethernet MAC address.
1693 * ETH_PORT eth_port_num Port number.
1694 * char * p_addr Address to be set
1695 * ETH_QUEUE queue Rx queue number for this MAC address.
1698 * Set MAC address low and high registers. also calls eth_port_uc_addr()
1699 * To set the unicast table with the proper information.
1704 *******************************************************************************/
1705 static void eth_port_uc_addr_set (ETH_PORT eth_port_num,
1706 unsigned char *p_addr, ETH_QUEUE queue)
1711 mac_l = (p_addr[4] << 8) | (p_addr[5]);
1712 mac_h = (p_addr[0] << 24) | (p_addr[1] << 16) |
1713 (p_addr[2] << 8) | (p_addr[3] << 0);
1715 MV_REG_WRITE (MV64460_ETH_MAC_ADDR_LOW (eth_port_num), mac_l);
1716 MV_REG_WRITE (MV64460_ETH_MAC_ADDR_HIGH (eth_port_num), mac_h);
1718 /* Accept frames of this address */
1719 eth_port_uc_addr (eth_port_num, p_addr[5], queue, ACCEPT_MAC_ADDR);
1724 /*******************************************************************************
1725 * eth_port_uc_addr - This function Set the port unicast address table
1728 * This function locates the proper entry in the Unicast table for the
1729 * specified MAC nibble and sets its properties according to function
1733 * ETH_PORT eth_port_num Port number.
1734 * unsigned char uc_nibble Unicast MAC Address last nibble.
1735 * ETH_QUEUE queue Rx queue number for this MAC address.
1736 * int option 0 = Add, 1 = remove address.
1739 * This function add/removes MAC addresses from the port unicast address
1743 * true is output succeeded.
1744 * false if option parameter is invalid.
1746 *******************************************************************************/
1747 static bool eth_port_uc_addr (ETH_PORT eth_port_num,
1748 unsigned char uc_nibble,
1749 ETH_QUEUE queue, int option)
1751 unsigned int unicast_reg;
1752 unsigned int tbl_offset;
1753 unsigned int reg_offset;
1755 /* Locate the Unicast table entry */
1756 uc_nibble = (0xf & uc_nibble);
1757 tbl_offset = (uc_nibble / 4) * 4; /* Register offset from unicast table base */
1758 reg_offset = uc_nibble % 4; /* Entry offset within the above register */
1761 case REJECT_MAC_ADDR:
1762 /* Clear accepts frame bit at specified unicast DA table entry */
1764 MV_REG_READ ((MV64460_ETH_DA_FILTER_UNICAST_TABLE_BASE
1768 unicast_reg &= (0x0E << (8 * reg_offset));
1770 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_UNICAST_TABLE_BASE
1772 + tbl_offset), unicast_reg);
1775 case ACCEPT_MAC_ADDR:
1776 /* Set accepts frame bit at unicast DA filter table entry */
1778 MV_REG_READ ((MV64460_ETH_DA_FILTER_UNICAST_TABLE_BASE
1782 unicast_reg |= ((0x01 | queue) << (8 * reg_offset));
1784 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_UNICAST_TABLE_BASE
1786 + tbl_offset), unicast_reg);
1797 /*******************************************************************************
1798 * eth_port_mc_addr - Multicast address settings.
1801 * This API controls the MV device MAC multicast support.
1802 * The MV device supports multicast using two tables:
1803 * 1) Special Multicast Table for MAC addresses of the form
1804 * 0x01-00-5E-00-00-XX (where XX is between 0x00 and 0x_fF).
1805 * The MAC DA[7:0] bits are used as a pointer to the Special Multicast
1806 * Table entries in the DA-Filter table.
1807 * In this case, the function calls eth_port_smc_addr() routine to set the
1808 * Special Multicast Table.
1809 * 2) Other Multicast Table for multicast of another type. A CRC-8bit
1810 * is used as an index to the Other Multicast Table entries in the
1812 * In this case, the function calculates the CRC-8bit value and calls
1813 * eth_port_omc_addr() routine to set the Other Multicast Table.
1815 * ETH_PORT eth_port_num Port number.
1816 * unsigned char *p_addr Unicast MAC Address.
1817 * ETH_QUEUE queue Rx queue number for this MAC address.
1818 * int option 0 = Add, 1 = remove address.
1824 * true is output succeeded.
1825 * false if add_address_table_entry( ) failed.
1827 *******************************************************************************/
1828 static void eth_port_mc_addr (ETH_PORT eth_port_num,
1829 unsigned char *p_addr,
1830 ETH_QUEUE queue, int option)
1834 unsigned char crc_result = 0;
1839 if ((p_addr[0] == 0x01) &&
1840 (p_addr[1] == 0x00) &&
1841 (p_addr[2] == 0x5E) && (p_addr[3] == 0x00) && (p_addr[4] == 0x00)) {
1843 eth_port_smc_addr (eth_port_num, p_addr[5], queue, option);
1845 /* Calculate CRC-8 out of the given address */
1846 mac_h = (p_addr[0] << 8) | (p_addr[1]);
1847 mac_l = (p_addr[2] << 24) | (p_addr[3] << 16) |
1848 (p_addr[4] << 8) | (p_addr[5] << 0);
1850 for (i = 0; i < 32; i++)
1851 mac_array[i] = (mac_l >> i) & 0x1;
1852 for (i = 32; i < 48; i++)
1853 mac_array[i] = (mac_h >> (i - 32)) & 0x1;
1855 crc[0] = mac_array[45] ^ mac_array[43] ^ mac_array[40] ^
1856 mac_array[39] ^ mac_array[35] ^ mac_array[34] ^
1857 mac_array[31] ^ mac_array[30] ^ mac_array[28] ^
1858 mac_array[23] ^ mac_array[21] ^ mac_array[19] ^
1859 mac_array[18] ^ mac_array[16] ^ mac_array[14] ^
1860 mac_array[12] ^ mac_array[8] ^ mac_array[7] ^
1861 mac_array[6] ^ mac_array[0];
1863 crc[1] = mac_array[46] ^ mac_array[45] ^ mac_array[44] ^
1864 mac_array[43] ^ mac_array[41] ^ mac_array[39] ^
1865 mac_array[36] ^ mac_array[34] ^ mac_array[32] ^
1866 mac_array[30] ^ mac_array[29] ^ mac_array[28] ^
1867 mac_array[24] ^ mac_array[23] ^ mac_array[22] ^
1868 mac_array[21] ^ mac_array[20] ^ mac_array[18] ^
1869 mac_array[17] ^ mac_array[16] ^ mac_array[15] ^
1870 mac_array[14] ^ mac_array[13] ^ mac_array[12] ^
1871 mac_array[9] ^ mac_array[6] ^ mac_array[1] ^
1874 crc[2] = mac_array[47] ^ mac_array[46] ^ mac_array[44] ^
1875 mac_array[43] ^ mac_array[42] ^ mac_array[39] ^
1876 mac_array[37] ^ mac_array[34] ^ mac_array[33] ^
1877 mac_array[29] ^ mac_array[28] ^ mac_array[25] ^
1878 mac_array[24] ^ mac_array[22] ^ mac_array[17] ^
1879 mac_array[15] ^ mac_array[13] ^ mac_array[12] ^
1880 mac_array[10] ^ mac_array[8] ^ mac_array[6] ^
1881 mac_array[2] ^ mac_array[1] ^ mac_array[0];
1883 crc[3] = mac_array[47] ^ mac_array[45] ^ mac_array[44] ^
1884 mac_array[43] ^ mac_array[40] ^ mac_array[38] ^
1885 mac_array[35] ^ mac_array[34] ^ mac_array[30] ^
1886 mac_array[29] ^ mac_array[26] ^ mac_array[25] ^
1887 mac_array[23] ^ mac_array[18] ^ mac_array[16] ^
1888 mac_array[14] ^ mac_array[13] ^ mac_array[11] ^
1889 mac_array[9] ^ mac_array[7] ^ mac_array[3] ^
1890 mac_array[2] ^ mac_array[1];
1892 crc[4] = mac_array[46] ^ mac_array[45] ^ mac_array[44] ^
1893 mac_array[41] ^ mac_array[39] ^ mac_array[36] ^
1894 mac_array[35] ^ mac_array[31] ^ mac_array[30] ^
1895 mac_array[27] ^ mac_array[26] ^ mac_array[24] ^
1896 mac_array[19] ^ mac_array[17] ^ mac_array[15] ^
1897 mac_array[14] ^ mac_array[12] ^ mac_array[10] ^
1898 mac_array[8] ^ mac_array[4] ^ mac_array[3] ^
1901 crc[5] = mac_array[47] ^ mac_array[46] ^ mac_array[45] ^
1902 mac_array[42] ^ mac_array[40] ^ mac_array[37] ^
1903 mac_array[36] ^ mac_array[32] ^ mac_array[31] ^
1904 mac_array[28] ^ mac_array[27] ^ mac_array[25] ^
1905 mac_array[20] ^ mac_array[18] ^ mac_array[16] ^
1906 mac_array[15] ^ mac_array[13] ^ mac_array[11] ^
1907 mac_array[9] ^ mac_array[5] ^ mac_array[4] ^
1910 crc[6] = mac_array[47] ^ mac_array[46] ^ mac_array[43] ^
1911 mac_array[41] ^ mac_array[38] ^ mac_array[37] ^
1912 mac_array[33] ^ mac_array[32] ^ mac_array[29] ^
1913 mac_array[28] ^ mac_array[26] ^ mac_array[21] ^
1914 mac_array[19] ^ mac_array[17] ^ mac_array[16] ^
1915 mac_array[14] ^ mac_array[12] ^ mac_array[10] ^
1916 mac_array[6] ^ mac_array[5] ^ mac_array[4];
1918 crc[7] = mac_array[47] ^ mac_array[44] ^ mac_array[42] ^
1919 mac_array[39] ^ mac_array[38] ^ mac_array[34] ^
1920 mac_array[33] ^ mac_array[30] ^ mac_array[29] ^
1921 mac_array[27] ^ mac_array[22] ^ mac_array[20] ^
1922 mac_array[18] ^ mac_array[17] ^ mac_array[15] ^
1923 mac_array[13] ^ mac_array[11] ^ mac_array[7] ^
1924 mac_array[6] ^ mac_array[5];
1926 for (i = 0; i < 8; i++)
1927 crc_result = crc_result | (crc[i] << i);
1929 eth_port_omc_addr (eth_port_num, crc_result, queue, option);
1934 /*******************************************************************************
1935 * eth_port_smc_addr - Special Multicast address settings.
1938 * This routine controls the MV device special MAC multicast support.
1939 * The Special Multicast Table for MAC addresses supports MAC of the form
1940 * 0x01-00-5E-00-00-XX (where XX is between 0x00 and 0x_fF).
1941 * The MAC DA[7:0] bits are used as a pointer to the Special Multicast
1942 * Table entries in the DA-Filter table.
1943 * This function set the Special Multicast Table appropriate entry
1944 * according to the argument given.
1947 * ETH_PORT eth_port_num Port number.
1948 * unsigned char mc_byte Multicast addr last byte (MAC DA[7:0] bits).
1949 * ETH_QUEUE queue Rx queue number for this MAC address.
1950 * int option 0 = Add, 1 = remove address.
1956 * true is output succeeded.
1957 * false if option parameter is invalid.
1959 *******************************************************************************/
1960 static bool eth_port_smc_addr (ETH_PORT eth_port_num,
1961 unsigned char mc_byte,
1962 ETH_QUEUE queue, int option)
1964 unsigned int smc_table_reg;
1965 unsigned int tbl_offset;
1966 unsigned int reg_offset;
1968 /* Locate the SMC table entry */
1969 tbl_offset = (mc_byte / 4) * 4; /* Register offset from SMC table base */
1970 reg_offset = mc_byte % 4; /* Entry offset within the above register */
1974 case REJECT_MAC_ADDR:
1975 /* Clear accepts frame bit at specified Special DA table entry */
1977 MV_REG_READ ((MV64460_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset));
1978 smc_table_reg &= (0x0E << (8 * reg_offset));
1980 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset), smc_table_reg);
1983 case ACCEPT_MAC_ADDR:
1984 /* Set accepts frame bit at specified Special DA table entry */
1986 MV_REG_READ ((MV64460_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset));
1987 smc_table_reg |= ((0x01 | queue) << (8 * reg_offset));
1989 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset), smc_table_reg);
1998 /*******************************************************************************
1999 * eth_port_omc_addr - Multicast address settings.
2002 * This routine controls the MV device Other MAC multicast support.
2003 * The Other Multicast Table is used for multicast of another type.
2004 * A CRC-8bit is used as an index to the Other Multicast Table entries
2005 * in the DA-Filter table.
2006 * The function gets the CRC-8bit value from the calling routine and
2007 * set the Other Multicast Table appropriate entry according to the
2008 * CRC-8 argument given.
2011 * ETH_PORT eth_port_num Port number.
2012 * unsigned char crc8 A CRC-8bit (Polynomial: x^8+x^2+x^1+1).
2013 * ETH_QUEUE queue Rx queue number for this MAC address.
2014 * int option 0 = Add, 1 = remove address.
2020 * true is output succeeded.
2021 * false if option parameter is invalid.
2023 *******************************************************************************/
2024 static bool eth_port_omc_addr (ETH_PORT eth_port_num,
2026 ETH_QUEUE queue, int option)
2028 unsigned int omc_table_reg;
2029 unsigned int tbl_offset;
2030 unsigned int reg_offset;
2032 /* Locate the OMC table entry */
2033 tbl_offset = (crc8 / 4) * 4; /* Register offset from OMC table base */
2034 reg_offset = crc8 % 4; /* Entry offset within the above register */
2038 case REJECT_MAC_ADDR:
2039 /* Clear accepts frame bit at specified Other DA table entry */
2041 MV_REG_READ ((MV64460_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset));
2042 omc_table_reg &= (0x0E << (8 * reg_offset));
2044 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset), omc_table_reg);
2047 case ACCEPT_MAC_ADDR:
2048 /* Set accepts frame bit at specified Other DA table entry */
2050 MV_REG_READ ((MV64460_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset));
2051 omc_table_reg |= ((0x01 | queue) << (8 * reg_offset));
2053 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset), omc_table_reg);
2063 /*******************************************************************************
2064 * eth_port_init_mac_tables - Clear all entrance in the UC, SMC and OMC tables
2067 * Go through all the DA filter tables (Unicast, Special Multicast & Other
2068 * Multicast) and set each entry to 0.
2071 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
2074 * Multicast and Unicast packets are rejected.
2079 *******************************************************************************/
2080 static void eth_port_init_mac_tables (ETH_PORT eth_port_num)
2084 /* Clear DA filter unicast table (Ex_dFUT) */
2085 for (table_index = 0; table_index <= 0xC; table_index += 4)
2086 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_UNICAST_TABLE_BASE
2087 (eth_port_num) + table_index), 0);
2089 for (table_index = 0; table_index <= 0xFC; table_index += 4) {
2090 /* Clear DA filter special multicast table (Ex_dFSMT) */
2091 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE (eth_port_num) + table_index), 0);
2092 /* Clear DA filter other multicast table (Ex_dFOMT) */
2093 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE (eth_port_num) + table_index), 0);
2097 /*******************************************************************************
2098 * eth_clear_mib_counters - Clear all MIB counters
2101 * This function clears all MIB counters of a specific ethernet port.
2102 * A read from the MIB counter will reset the counter.
2105 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
2108 * After reading all MIB counters, the counters resets.
2111 * MIB counter value.
2113 *******************************************************************************/
2114 static void eth_clear_mib_counters (ETH_PORT eth_port_num)
2118 /* Perform dummy reads from MIB counters */
2119 for (i = ETH_MIB_GOOD_OCTETS_RECEIVED_LOW; i < ETH_MIB_LATE_COLLISION;
2121 (void)MV_REG_READ ((MV64460_ETH_MIB_COUNTERS_BASE
2122 (eth_port_num) + i));
2128 /*******************************************************************************
2129 * eth_read_mib_counter - Read a MIB counter
2132 * This function reads a MIB counter of a specific ethernet port.
2133 * NOTE - If read from ETH_MIB_GOOD_OCTETS_RECEIVED_LOW, then the
2134 * following read must be from ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH
2135 * register. The same applies for ETH_MIB_GOOD_OCTETS_SENT_LOW and
2136 * ETH_MIB_GOOD_OCTETS_SENT_HIGH
2139 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
2140 * unsigned int mib_offset MIB counter offset (use ETH_MIB_... macros).
2143 * After reading the MIB counter, the counter resets.
2146 * MIB counter value.
2148 *******************************************************************************/
2149 unsigned int eth_read_mib_counter (ETH_PORT eth_port_num,
2150 unsigned int mib_offset)
2152 return (MV_REG_READ (MV64460_ETH_MIB_COUNTERS_BASE (eth_port_num)
2156 /*******************************************************************************
2157 * ethernet_phy_set - Set the ethernet port PHY address.
2160 * This routine set the ethernet port PHY address according to given
2164 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
2167 * Set PHY Address Register with given PHY address parameter.
2172 *******************************************************************************/
2173 static void ethernet_phy_set (ETH_PORT eth_port_num, int phy_addr)
2175 unsigned int reg_data;
2177 reg_data = MV_REG_READ (MV64460_ETH_PHY_ADDR_REG);
2179 reg_data &= ~(0x1F << (5 * eth_port_num));
2180 reg_data |= (phy_addr << (5 * eth_port_num));
2182 MV_REG_WRITE (MV64460_ETH_PHY_ADDR_REG, reg_data);
2187 /*******************************************************************************
2188 * ethernet_phy_get - Get the ethernet port PHY address.
2191 * This routine returns the given ethernet port PHY address.
2194 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
2202 *******************************************************************************/
2203 static int ethernet_phy_get (ETH_PORT eth_port_num)
2205 unsigned int reg_data;
2207 reg_data = MV_REG_READ (MV64460_ETH_PHY_ADDR_REG);
2209 return ((reg_data >> (5 * eth_port_num)) & 0x1f);
2212 /***********************************************************/
2213 /* (Re)start autonegotiation */
2214 /***********************************************************/
2215 int phy_setup_aneg (char *devname, unsigned char addr)
2217 unsigned short ctl, adv;
2219 /* Setup standard advertise */
2220 miiphy_read (devname, addr, MII_ADVERTISE, &adv);
2221 adv |= (LPA_LPACK | LPA_RFAULT | LPA_100BASE4 |
2222 LPA_100FULL | LPA_100HALF | LPA_10FULL |
2224 miiphy_write (devname, addr, MII_ADVERTISE, adv);
2226 miiphy_read (devname, addr, MII_CTRL1000, &adv);
2228 miiphy_write (devname, addr, MII_CTRL1000, adv);
2230 /* Start/Restart aneg */
2231 miiphy_read (devname, addr, MII_BMCR, &ctl);
2232 ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
2233 miiphy_write (devname, addr, MII_BMCR, ctl);
2238 /*******************************************************************************
2239 * ethernet_phy_reset - Reset Ethernet port PHY.
2242 * This routine utilize the SMI interface to reset the ethernet port PHY.
2243 * The routine waits until the link is up again or link up is timeout.
2246 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
2249 * The ethernet port PHY renew its link.
2254 *******************************************************************************/
2255 static bool ethernet_phy_reset (ETH_PORT eth_port_num)
2257 unsigned int time_out = 50;
2258 unsigned int phy_reg_data;
2260 eth_port_read_smi_reg (eth_port_num, 20, &phy_reg_data);
2261 phy_reg_data |= 0x0083; /* Set bit 7 to 1 for different RGMII timing */
2262 eth_port_write_smi_reg (eth_port_num, 20, phy_reg_data);
2265 eth_port_read_smi_reg (eth_port_num, 0, &phy_reg_data);
2266 phy_reg_data |= 0x8000; /* Set bit 15 to reset the PHY */
2267 eth_port_write_smi_reg (eth_port_num, 0, phy_reg_data);
2269 /* Poll on the PHY LINK */
2271 eth_port_read_smi_reg (eth_port_num, 1, &phy_reg_data);
2273 if (time_out-- == 0)
2276 while (!(phy_reg_data & 0x20));
2281 /*******************************************************************************
2282 * eth_port_reset - Reset Ethernet port
2285 * This routine resets the chip by aborting any SDMA engine activity and
2286 * clearing the MIB counters. The Receiver and the Transmit unit are in
2287 * idle state after this command is performed and the port is disabled.
2290 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
2293 * Channel activity is halted.
2298 *******************************************************************************/
2299 static void eth_port_reset (ETH_PORT eth_port_num)
2301 unsigned int reg_data;
2303 /* Stop Tx port activity. Check port Tx activity. */
2305 MV_REG_READ (MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG
2308 if (reg_data & 0xFF) {
2309 /* Issue stop command for active channels only */
2310 MV_REG_WRITE (MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG
2311 (eth_port_num), (reg_data << 8));
2313 /* Wait for all Tx activity to terminate. */
2315 /* Check port cause register that all Tx queues are stopped */
2318 (MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG
2321 while (reg_data & 0xFF);
2324 /* Stop Rx port activity. Check port Rx activity. */
2326 MV_REG_READ (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG
2329 if (reg_data & 0xFF) {
2330 /* Issue stop command for active channels only */
2331 MV_REG_WRITE (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG
2332 (eth_port_num), (reg_data << 8));
2334 /* Wait for all Rx activity to terminate. */
2336 /* Check port cause register that all Rx queues are stopped */
2339 (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG
2342 while (reg_data & 0xFF);
2345 /* Clear all MIB counters */
2346 eth_clear_mib_counters (eth_port_num);
2348 /* Reset the Enable bit in the Configuration Register */
2350 MV_REG_READ (MV64460_ETH_PORT_SERIAL_CONTROL_REG
2352 reg_data &= ~ETH_SERIAL_PORT_ENABLE;
2353 MV_REG_WRITE (MV64460_ETH_PORT_SERIAL_CONTROL_REG (eth_port_num),
2359 #if 0 /* Not needed here */
2360 /*******************************************************************************
2361 * ethernet_set_config_reg - Set specified bits in configuration register.
2364 * This function sets specified bits in the given ethernet
2365 * configuration register.
2368 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
2369 * unsigned int value 32 bit value.
2372 * The set bits in the value parameter are set in the configuration
2378 *******************************************************************************/
2379 static void ethernet_set_config_reg (ETH_PORT eth_port_num,
2382 unsigned int eth_config_reg;
2385 MV_REG_READ (MV64460_ETH_PORT_CONFIG_REG (eth_port_num));
2386 eth_config_reg |= value;
2387 MV_REG_WRITE (MV64460_ETH_PORT_CONFIG_REG (eth_port_num),
2395 /*******************************************************************************
2396 * ethernet_reset_config_reg - Reset specified bits in configuration register.
2399 * This function resets specified bits in the given Ethernet
2400 * configuration register.
2403 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
2404 * unsigned int value 32 bit value.
2407 * The set bits in the value parameter are reset in the configuration
2413 *******************************************************************************/
2414 static void ethernet_reset_config_reg (ETH_PORT eth_port_num,
2417 unsigned int eth_config_reg;
2419 eth_config_reg = MV_REG_READ (MV64460_ETH_PORT_CONFIG_EXTEND_REG
2421 eth_config_reg &= ~value;
2422 MV_REG_WRITE (MV64460_ETH_PORT_CONFIG_EXTEND_REG (eth_port_num),
2429 #if 0 /* Not needed here */
2430 /*******************************************************************************
2431 * ethernet_get_config_reg - Get the port configuration register
2434 * This function returns the configuration register value of the given
2438 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
2444 * Port configuration register value.
2446 *******************************************************************************/
2447 static unsigned int ethernet_get_config_reg (ETH_PORT eth_port_num)
2449 unsigned int eth_config_reg;
2451 eth_config_reg = MV_REG_READ (MV64460_ETH_PORT_CONFIG_EXTEND_REG
2453 return eth_config_reg;
2458 /*******************************************************************************
2459 * eth_port_read_smi_reg - Read PHY registers
2462 * This routine utilize the SMI interface to interact with the PHY in
2463 * order to perform PHY register read.
2466 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
2467 * unsigned int phy_reg PHY register address offset.
2468 * unsigned int *value Register value buffer.
2471 * Write the value of a specified PHY register into given buffer.
2474 * false if the PHY is busy or read data is not in valid state.
2477 *******************************************************************************/
2478 static bool eth_port_read_smi_reg (ETH_PORT eth_port_num,
2479 unsigned int phy_reg, unsigned int *value)
2481 unsigned int reg_value;
2482 unsigned int time_out = PHY_BUSY_TIMEOUT;
2485 phy_addr = ethernet_phy_get (eth_port_num);
2487 /* first check that it is not busy */
2489 reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
2490 if (time_out-- == 0) {
2494 while (reg_value & ETH_SMI_BUSY);
2498 MV_REG_WRITE (MV64460_ETH_SMI_REG,
2499 (phy_addr << 16) | (phy_reg << 21) |
2500 ETH_SMI_OPCODE_READ);
2502 time_out = PHY_BUSY_TIMEOUT; /* initialize the time out var again */
2505 reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
2506 if (time_out-- == 0) {
2510 while ((reg_value & ETH_SMI_READ_VALID) != ETH_SMI_READ_VALID); /* Bit set equ operation done */
2512 /* Wait for the data to update in the SMI register */
2513 #define PHY_UPDATE_TIMEOUT 10000
2514 for (time_out = 0; time_out < PHY_UPDATE_TIMEOUT; time_out++);
2516 reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
2518 *value = reg_value & 0xffff;
2523 int mv_miiphy_read(const char *devname, unsigned char phy_addr,
2524 unsigned char phy_reg, unsigned short *value)
2526 unsigned int reg_value;
2527 unsigned int time_out = PHY_BUSY_TIMEOUT;
2529 /* first check that it is not busy */
2531 reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
2532 if (time_out-- == 0) {
2536 while (reg_value & ETH_SMI_BUSY);
2539 MV_REG_WRITE (MV64460_ETH_SMI_REG,
2540 (phy_addr << 16) | (phy_reg << 21) |
2541 ETH_SMI_OPCODE_READ);
2543 time_out = PHY_BUSY_TIMEOUT; /* initialize the time out var again */
2546 reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
2547 if (time_out-- == 0) {
2551 while ((reg_value & ETH_SMI_READ_VALID) != ETH_SMI_READ_VALID); /* Bit set equ operation done */
2553 /* Wait for the data to update in the SMI register */
2554 for (time_out = 0; time_out < PHY_UPDATE_TIMEOUT; time_out++);
2556 reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
2558 *value = reg_value & 0xffff;
2563 /*******************************************************************************
2564 * eth_port_write_smi_reg - Write to PHY registers
2567 * This routine utilize the SMI interface to interact with the PHY in
2568 * order to perform writes to PHY registers.
2571 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
2572 * unsigned int phy_reg PHY register address offset.
2573 * unsigned int value Register value.
2576 * Write the given value to the specified PHY register.
2579 * false if the PHY is busy.
2582 *******************************************************************************/
2583 static bool eth_port_write_smi_reg (ETH_PORT eth_port_num,
2584 unsigned int phy_reg, unsigned int value)
2586 unsigned int reg_value;
2587 unsigned int time_out = PHY_BUSY_TIMEOUT;
2590 phy_addr = ethernet_phy_get (eth_port_num);
2592 /* first check that it is not busy */
2594 reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
2595 if (time_out-- == 0) {
2599 while (reg_value & ETH_SMI_BUSY);
2602 MV_REG_WRITE (MV64460_ETH_SMI_REG,
2603 (phy_addr << 16) | (phy_reg << 21) |
2604 ETH_SMI_OPCODE_WRITE | (value & 0xffff));
2608 int mv_miiphy_write(const char *devname, unsigned char phy_addr,
2609 unsigned char phy_reg, unsigned short value)
2611 unsigned int reg_value;
2612 unsigned int time_out = PHY_BUSY_TIMEOUT;
2614 /* first check that it is not busy */
2616 reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
2617 if (time_out-- == 0) {
2621 while (reg_value & ETH_SMI_BUSY);
2624 MV_REG_WRITE (MV64460_ETH_SMI_REG,
2625 (phy_addr << 16) | (phy_reg << 21) |
2626 ETH_SMI_OPCODE_WRITE | (value & 0xffff));
2630 /*******************************************************************************
2631 * eth_set_access_control - Config address decode parameters for Ethernet unit
2634 * This function configures the address decode parameters for the Gigabit
2635 * Ethernet Controller according the given parameters struct.
2638 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
2639 * ETH_WIN_PARAM *param Address decode parameter struct.
2642 * An access window is opened using the given access parameters.
2647 *******************************************************************************/
2648 static void eth_set_access_control (ETH_PORT eth_port_num,
2649 ETH_WIN_PARAM * param)
2651 unsigned int access_prot_reg;
2653 /* Set access control register */
2654 access_prot_reg = MV_REG_READ (MV64460_ETH_ACCESS_PROTECTION_REG
2656 access_prot_reg &= (~(3 << (param->win * 2))); /* clear window permission */
2657 access_prot_reg |= (param->access_ctrl << (param->win * 2));
2658 MV_REG_WRITE (MV64460_ETH_ACCESS_PROTECTION_REG (eth_port_num),
2661 /* Set window Size reg (SR) */
2662 MV_REG_WRITE ((MV64460_ETH_SIZE_REG_0 +
2663 (ETH_SIZE_REG_GAP * param->win)),
2664 (((param->size / 0x10000) - 1) << 16));
2666 /* Set window Base address reg (BA) */
2667 MV_REG_WRITE ((MV64460_ETH_BAR_0 + (ETH_BAR_GAP * param->win)),
2668 (param->target | param->attributes | param->base_addr));
2669 /* High address remap reg (HARR) */
2671 MV_REG_WRITE ((MV64460_ETH_HIGH_ADDR_REMAP_REG_0 +
2672 (ETH_HIGH_ADDR_REMAP_REG_GAP * param->win)),
2675 /* Base address enable reg (BARER) */
2676 if (param->enable == 1)
2677 MV_RESET_REG_BITS (MV64460_ETH_BASE_ADDR_ENABLE_REG,
2680 MV_SET_REG_BITS (MV64460_ETH_BASE_ADDR_ENABLE_REG,
2684 /*******************************************************************************
2685 * ether_init_rx_desc_ring - Curve a Rx chain desc list and buffer in memory.
2688 * This function prepares a Rx chained list of descriptors and packet
2689 * buffers in a form of a ring. The routine must be called after port
2690 * initialization routine and before port start routine.
2691 * The Ethernet SDMA engine uses CPU bus addresses to access the various
2692 * devices in the system (i.e. DRAM). This function uses the ethernet
2693 * struct 'virtual to physical' routine (set by the user) to set the ring
2694 * with physical addresses.
2697 * ETH_PORT_INFO *p_eth_port_ctrl Ethernet Port Control srtuct.
2698 * ETH_QUEUE rx_queue Number of Rx queue.
2699 * int rx_desc_num Number of Rx descriptors
2700 * int rx_buff_size Size of Rx buffer
2701 * unsigned int rx_desc_base_addr Rx descriptors memory area base addr.
2702 * unsigned int rx_buff_base_addr Rx buffer memory area base addr.
2705 * The routine updates the Ethernet port control struct with information
2706 * regarding the Rx descriptors and buffers.
2709 * false if the given descriptors memory area is not aligned according to
2710 * Ethernet SDMA specifications.
2713 *******************************************************************************/
2714 static bool ether_init_rx_desc_ring (ETH_PORT_INFO * p_eth_port_ctrl,
2718 unsigned int rx_desc_base_addr,
2719 unsigned int rx_buff_base_addr)
2721 ETH_RX_DESC *p_rx_desc;
2722 ETH_RX_DESC *p_rx_prev_desc; /* pointer to link with the last descriptor */
2723 unsigned int buffer_addr;
2724 int ix; /* a counter */
2726 p_rx_desc = (ETH_RX_DESC *) rx_desc_base_addr;
2727 p_rx_prev_desc = p_rx_desc;
2728 buffer_addr = rx_buff_base_addr;
2730 /* Rx desc Must be 4LW aligned (i.e. Descriptor_Address[3:0]=0000). */
2731 if (rx_buff_base_addr & 0xF)
2734 /* Rx buffers are limited to 64K bytes and Minimum size is 8 bytes */
2735 if ((rx_buff_size < 8) || (rx_buff_size > RX_BUFFER_MAX_SIZE))
2738 /* Rx buffers must be 64-bit aligned. */
2739 if ((rx_buff_base_addr + rx_buff_size) & 0x7)
2742 /* initialize the Rx descriptors ring */
2743 for (ix = 0; ix < rx_desc_num; ix++) {
2744 p_rx_desc->buf_size = rx_buff_size;
2745 p_rx_desc->byte_cnt = 0x0000;
2746 p_rx_desc->cmd_sts =
2747 ETH_BUFFER_OWNED_BY_DMA | ETH_RX_ENABLE_INTERRUPT;
2748 p_rx_desc->next_desc_ptr =
2749 ((unsigned int) p_rx_desc) + RX_DESC_ALIGNED_SIZE;
2750 p_rx_desc->buf_ptr = buffer_addr;
2751 p_rx_desc->return_info = 0x00000000;
2752 D_CACHE_FLUSH_LINE (p_rx_desc, 0);
2753 buffer_addr += rx_buff_size;
2754 p_rx_prev_desc = p_rx_desc;
2755 p_rx_desc = (ETH_RX_DESC *)
2756 ((unsigned int) p_rx_desc + RX_DESC_ALIGNED_SIZE);
2759 /* Closing Rx descriptors ring */
2760 p_rx_prev_desc->next_desc_ptr = (rx_desc_base_addr);
2761 D_CACHE_FLUSH_LINE (p_rx_prev_desc, 0);
2763 /* Save Rx desc pointer to driver struct. */
2764 CURR_RFD_SET ((ETH_RX_DESC *) rx_desc_base_addr, rx_queue);
2765 USED_RFD_SET ((ETH_RX_DESC *) rx_desc_base_addr, rx_queue);
2767 p_eth_port_ctrl->p_rx_desc_area_base[rx_queue] =
2768 (ETH_RX_DESC *) rx_desc_base_addr;
2769 p_eth_port_ctrl->rx_desc_area_size[rx_queue] =
2770 rx_desc_num * RX_DESC_ALIGNED_SIZE;
2772 p_eth_port_ctrl->port_rx_queue_command |= (1 << rx_queue);
2777 /*******************************************************************************
2778 * ether_init_tx_desc_ring - Curve a Tx chain desc list and buffer in memory.
2781 * This function prepares a Tx chained list of descriptors and packet
2782 * buffers in a form of a ring. The routine must be called after port
2783 * initialization routine and before port start routine.
2784 * The Ethernet SDMA engine uses CPU bus addresses to access the various
2785 * devices in the system (i.e. DRAM). This function uses the ethernet
2786 * struct 'virtual to physical' routine (set by the user) to set the ring
2787 * with physical addresses.
2790 * ETH_PORT_INFO *p_eth_port_ctrl Ethernet Port Control srtuct.
2791 * ETH_QUEUE tx_queue Number of Tx queue.
2792 * int tx_desc_num Number of Tx descriptors
2793 * int tx_buff_size Size of Tx buffer
2794 * unsigned int tx_desc_base_addr Tx descriptors memory area base addr.
2795 * unsigned int tx_buff_base_addr Tx buffer memory area base addr.
2798 * The routine updates the Ethernet port control struct with information
2799 * regarding the Tx descriptors and buffers.
2802 * false if the given descriptors memory area is not aligned according to
2803 * Ethernet SDMA specifications.
2806 *******************************************************************************/
2807 static bool ether_init_tx_desc_ring (ETH_PORT_INFO * p_eth_port_ctrl,
2811 unsigned int tx_desc_base_addr,
2812 unsigned int tx_buff_base_addr)
2815 ETH_TX_DESC *p_tx_desc;
2816 ETH_TX_DESC *p_tx_prev_desc;
2817 unsigned int buffer_addr;
2818 int ix; /* a counter */
2820 /* save the first desc pointer to link with the last descriptor */
2821 p_tx_desc = (ETH_TX_DESC *) tx_desc_base_addr;
2822 p_tx_prev_desc = p_tx_desc;
2823 buffer_addr = tx_buff_base_addr;
2825 /* Tx desc Must be 4LW aligned (i.e. Descriptor_Address[3:0]=0000). */
2826 if (tx_buff_base_addr & 0xF)
2829 /* Tx buffers are limited to 64K bytes and Minimum size is 8 bytes */
2830 if ((tx_buff_size > TX_BUFFER_MAX_SIZE)
2831 || (tx_buff_size < TX_BUFFER_MIN_SIZE))
2834 /* Initialize the Tx descriptors ring */
2835 for (ix = 0; ix < tx_desc_num; ix++) {
2836 p_tx_desc->byte_cnt = 0x0000;
2837 p_tx_desc->l4i_chk = 0x0000;
2838 p_tx_desc->cmd_sts = 0x00000000;
2839 p_tx_desc->next_desc_ptr =
2840 ((unsigned int) p_tx_desc) + TX_DESC_ALIGNED_SIZE;
2842 p_tx_desc->buf_ptr = buffer_addr;
2843 p_tx_desc->return_info = 0x00000000;
2844 D_CACHE_FLUSH_LINE (p_tx_desc, 0);
2845 buffer_addr += tx_buff_size;
2846 p_tx_prev_desc = p_tx_desc;
2847 p_tx_desc = (ETH_TX_DESC *)
2848 ((unsigned int) p_tx_desc + TX_DESC_ALIGNED_SIZE);
2851 /* Closing Tx descriptors ring */
2852 p_tx_prev_desc->next_desc_ptr = tx_desc_base_addr;
2853 D_CACHE_FLUSH_LINE (p_tx_prev_desc, 0);
2854 /* Set Tx desc pointer in driver struct. */
2855 CURR_TFD_SET ((ETH_TX_DESC *) tx_desc_base_addr, tx_queue);
2856 USED_TFD_SET ((ETH_TX_DESC *) tx_desc_base_addr, tx_queue);
2858 /* Init Tx ring base and size parameters */
2859 p_eth_port_ctrl->p_tx_desc_area_base[tx_queue] =
2860 (ETH_TX_DESC *) tx_desc_base_addr;
2861 p_eth_port_ctrl->tx_desc_area_size[tx_queue] =
2862 (tx_desc_num * TX_DESC_ALIGNED_SIZE);
2864 /* Add the queue to the list of Tx queues of this port */
2865 p_eth_port_ctrl->port_tx_queue_command |= (1 << tx_queue);
2870 /*******************************************************************************
2871 * eth_port_send - Send an Ethernet packet
2874 * This routine send a given packet described by p_pktinfo parameter. It
2875 * supports transmitting of a packet spaned over multiple buffers. The
2876 * routine updates 'curr' and 'first' indexes according to the packet
2877 * segment passed to the routine. In case the packet segment is first,
2878 * the 'first' index is update. In any case, the 'curr' index is updated.
2879 * If the routine get into Tx resource error it assigns 'curr' index as
2880 * 'first'. This way the function can abort Tx process of multiple
2881 * descriptors per packet.
2884 * ETH_PORT_INFO *p_eth_port_ctrl Ethernet Port Control srtuct.
2885 * ETH_QUEUE tx_queue Number of Tx queue.
2886 * PKT_INFO *p_pkt_info User packet buffer.
2889 * Tx ring 'curr' and 'first' indexes are updated.
2892 * ETH_QUEUE_FULL in case of Tx resource error.
2893 * ETH_ERROR in case the routine can not access Tx desc ring.
2894 * ETH_QUEUE_LAST_RESOURCE if the routine uses the last Tx resource.
2897 *******************************************************************************/
2898 static ETH_FUNC_RET_STATUS eth_port_send (ETH_PORT_INFO * p_eth_port_ctrl,
2900 PKT_INFO * p_pkt_info)
2902 volatile ETH_TX_DESC *p_tx_desc_first;
2903 volatile ETH_TX_DESC *p_tx_desc_curr;
2904 volatile ETH_TX_DESC *p_tx_next_desc_curr;
2905 volatile ETH_TX_DESC *p_tx_desc_used;
2906 unsigned int command_status;
2908 /* Do not process Tx ring in case of Tx ring resource error */
2909 if (p_eth_port_ctrl->tx_resource_err[tx_queue] == true)
2910 return ETH_QUEUE_FULL;
2912 /* Get the Tx Desc ring indexes */
2913 CURR_TFD_GET (p_tx_desc_curr, tx_queue);
2914 USED_TFD_GET (p_tx_desc_used, tx_queue);
2916 if (p_tx_desc_curr == NULL)
2919 /* The following parameters are used to save readings from memory */
2920 p_tx_next_desc_curr = TX_NEXT_DESC_PTR (p_tx_desc_curr, tx_queue);
2921 command_status = p_pkt_info->cmd_sts | ETH_ZERO_PADDING | ETH_GEN_CRC;
2923 if (command_status & (ETH_TX_FIRST_DESC)) {
2924 /* Update first desc */
2925 FIRST_TFD_SET (p_tx_desc_curr, tx_queue);
2926 p_tx_desc_first = p_tx_desc_curr;
2928 FIRST_TFD_GET (p_tx_desc_first, tx_queue);
2929 command_status |= ETH_BUFFER_OWNED_BY_DMA;
2932 /* Buffers with a payload smaller than 8 bytes must be aligned to 64-bit */
2933 /* boundary. We use the memory allocated for Tx descriptor. This memory */
2934 /* located in TX_BUF_OFFSET_IN_DESC offset within the Tx descriptor. */
2935 if (p_pkt_info->byte_cnt <= 8) {
2936 printf ("You have failed in the < 8 bytes errata - fixme\n"); /* RABEEH - TBD */
2939 p_tx_desc_curr->buf_ptr =
2940 (unsigned int) p_tx_desc_curr + TX_BUF_OFFSET_IN_DESC;
2941 eth_b_copy (p_pkt_info->buf_ptr, p_tx_desc_curr->buf_ptr,
2942 p_pkt_info->byte_cnt);
2944 p_tx_desc_curr->buf_ptr = p_pkt_info->buf_ptr;
2946 p_tx_desc_curr->byte_cnt = p_pkt_info->byte_cnt;
2947 p_tx_desc_curr->return_info = p_pkt_info->return_info;
2949 if (p_pkt_info->cmd_sts & (ETH_TX_LAST_DESC)) {
2950 /* Set last desc with DMA ownership and interrupt enable. */
2951 p_tx_desc_curr->cmd_sts = command_status |
2952 ETH_BUFFER_OWNED_BY_DMA | ETH_TX_ENABLE_INTERRUPT;
2954 if (p_tx_desc_curr != p_tx_desc_first)
2955 p_tx_desc_first->cmd_sts |= ETH_BUFFER_OWNED_BY_DMA;
2957 /* Flush CPU pipe */
2959 D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_curr, 0);
2960 D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_first, 0);
2963 /* Apply send command */
2964 ETH_ENABLE_TX_QUEUE (tx_queue, p_eth_port_ctrl->port_num);
2966 /* Finish Tx packet. Update first desc in case of Tx resource error */
2967 p_tx_desc_first = p_tx_next_desc_curr;
2968 FIRST_TFD_SET (p_tx_desc_first, tx_queue);
2971 p_tx_desc_curr->cmd_sts = command_status;
2972 D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_curr, 0);
2975 /* Check for ring index overlap in the Tx desc ring */
2976 if (p_tx_next_desc_curr == p_tx_desc_used) {
2977 /* Update the current descriptor */
2978 CURR_TFD_SET (p_tx_desc_first, tx_queue);
2980 p_eth_port_ctrl->tx_resource_err[tx_queue] = true;
2981 return ETH_QUEUE_LAST_RESOURCE;
2983 /* Update the current descriptor */
2984 CURR_TFD_SET (p_tx_next_desc_curr, tx_queue);
2989 /*******************************************************************************
2990 * eth_tx_return_desc - Free all used Tx descriptors
2993 * This routine returns the transmitted packet information to the caller.
2994 * It uses the 'first' index to support Tx desc return in case a transmit
2995 * of a packet spanned over multiple buffer still in process.
2996 * In case the Tx queue was in "resource error" condition, where there are
2997 * no available Tx resources, the function resets the resource error flag.
3000 * ETH_PORT_INFO *p_eth_port_ctrl Ethernet Port Control srtuct.
3001 * ETH_QUEUE tx_queue Number of Tx queue.
3002 * PKT_INFO *p_pkt_info User packet buffer.
3005 * Tx ring 'first' and 'used' indexes are updated.
3008 * ETH_ERROR in case the routine can not access Tx desc ring.
3009 * ETH_RETRY in case there is transmission in process.
3010 * ETH_END_OF_JOB if the routine has nothing to release.
3013 *******************************************************************************/
3014 static ETH_FUNC_RET_STATUS eth_tx_return_desc (ETH_PORT_INFO *
3017 PKT_INFO * p_pkt_info)
3019 volatile ETH_TX_DESC *p_tx_desc_used = NULL;
3020 volatile ETH_TX_DESC *p_tx_desc_first = NULL;
3021 unsigned int command_status;
3023 /* Get the Tx Desc ring indexes */
3024 USED_TFD_GET (p_tx_desc_used, tx_queue);
3025 FIRST_TFD_GET (p_tx_desc_first, tx_queue);
3028 if (p_tx_desc_used == NULL)
3031 command_status = p_tx_desc_used->cmd_sts;
3033 /* Still transmitting... */
3034 if (command_status & (ETH_BUFFER_OWNED_BY_DMA)) {
3035 D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_used, 0);
3039 /* Stop release. About to overlap the current available Tx descriptor */
3040 if ((p_tx_desc_used == p_tx_desc_first) &&
3041 (p_eth_port_ctrl->tx_resource_err[tx_queue] == false)) {
3042 D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_used, 0);
3043 return ETH_END_OF_JOB;
3046 /* Pass the packet information to the caller */
3047 p_pkt_info->cmd_sts = command_status;
3048 p_pkt_info->return_info = p_tx_desc_used->return_info;
3049 p_tx_desc_used->return_info = 0;
3051 /* Update the next descriptor to release. */
3052 USED_TFD_SET (TX_NEXT_DESC_PTR (p_tx_desc_used, tx_queue), tx_queue);
3054 /* Any Tx return cancels the Tx resource error status */
3055 if (p_eth_port_ctrl->tx_resource_err[tx_queue] == true)
3056 p_eth_port_ctrl->tx_resource_err[tx_queue] = false;
3058 D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_used, 0);
3064 /*******************************************************************************
3065 * eth_port_receive - Get received information from Rx ring.
3068 * This routine returns the received data to the caller. There is no
3069 * data copying during routine operation. All information is returned
3070 * using pointer to packet information struct passed from the caller.
3071 * If the routine exhausts Rx ring resources then the resource error flag
3075 * ETH_PORT_INFO *p_eth_port_ctrl Ethernet Port Control srtuct.
3076 * ETH_QUEUE rx_queue Number of Rx queue.
3077 * PKT_INFO *p_pkt_info User packet buffer.
3080 * Rx ring current and used indexes are updated.
3083 * ETH_ERROR in case the routine can not access Rx desc ring.
3084 * ETH_QUEUE_FULL if Rx ring resources are exhausted.
3085 * ETH_END_OF_JOB if there is no received data.
3088 *******************************************************************************/
3089 static ETH_FUNC_RET_STATUS eth_port_receive (ETH_PORT_INFO * p_eth_port_ctrl,
3091 PKT_INFO * p_pkt_info)
3093 volatile ETH_RX_DESC *p_rx_curr_desc;
3094 volatile ETH_RX_DESC *p_rx_next_curr_desc;
3095 volatile ETH_RX_DESC *p_rx_used_desc;
3096 unsigned int command_status;
3098 /* Do not process Rx ring in case of Rx ring resource error */
3099 if (p_eth_port_ctrl->rx_resource_err[rx_queue] == true) {
3100 printf ("\nRx Queue is full ...\n");
3101 return ETH_QUEUE_FULL;
3104 /* Get the Rx Desc ring 'curr and 'used' indexes */
3105 CURR_RFD_GET (p_rx_curr_desc, rx_queue);
3106 USED_RFD_GET (p_rx_used_desc, rx_queue);
3109 if (p_rx_curr_desc == NULL)
3112 /* The following parameters are used to save readings from memory */
3113 p_rx_next_curr_desc = RX_NEXT_DESC_PTR (p_rx_curr_desc, rx_queue);
3114 command_status = p_rx_curr_desc->cmd_sts;
3116 /* Nothing to receive... */
3117 if (command_status & (ETH_BUFFER_OWNED_BY_DMA)) {
3118 /* DP(printf("Rx: command_status: %08x\n", command_status)); */
3119 D_CACHE_FLUSH_LINE ((unsigned int) p_rx_curr_desc, 0);
3120 /* DP(printf("\nETH_END_OF_JOB ...\n"));*/
3121 return ETH_END_OF_JOB;
3124 p_pkt_info->byte_cnt = (p_rx_curr_desc->byte_cnt) - RX_BUF_OFFSET;
3125 p_pkt_info->cmd_sts = command_status;
3126 p_pkt_info->buf_ptr = (p_rx_curr_desc->buf_ptr) + RX_BUF_OFFSET;
3127 p_pkt_info->return_info = p_rx_curr_desc->return_info;
3128 p_pkt_info->l4i_chk = p_rx_curr_desc->buf_size; /* IP fragment indicator */
3130 /* Clean the return info field to indicate that the packet has been */
3131 /* moved to the upper layers */
3132 p_rx_curr_desc->return_info = 0;
3134 /* Update 'curr' in data structure */
3135 CURR_RFD_SET (p_rx_next_curr_desc, rx_queue);
3137 /* Rx descriptors resource exhausted. Set the Rx ring resource error flag */
3138 if (p_rx_next_curr_desc == p_rx_used_desc)
3139 p_eth_port_ctrl->rx_resource_err[rx_queue] = true;
3141 D_CACHE_FLUSH_LINE ((unsigned int) p_rx_curr_desc, 0);
3147 /*******************************************************************************
3148 * eth_rx_return_buff - Returns a Rx buffer back to the Rx ring.
3151 * This routine returns a Rx buffer back to the Rx ring. It retrieves the
3152 * next 'used' descriptor and attached the returned buffer to it.
3153 * In case the Rx ring was in "resource error" condition, where there are
3154 * no available Rx resources, the function resets the resource error flag.
3157 * ETH_PORT_INFO *p_eth_port_ctrl Ethernet Port Control srtuct.
3158 * ETH_QUEUE rx_queue Number of Rx queue.
3159 * PKT_INFO *p_pkt_info Information on the returned buffer.
3162 * New available Rx resource in Rx descriptor ring.
3165 * ETH_ERROR in case the routine can not access Rx desc ring.
3168 *******************************************************************************/
3169 static ETH_FUNC_RET_STATUS eth_rx_return_buff (ETH_PORT_INFO *
3172 PKT_INFO * p_pkt_info)
3174 volatile ETH_RX_DESC *p_used_rx_desc; /* Where to return Rx resource */
3176 /* Get 'used' Rx descriptor */
3177 USED_RFD_GET (p_used_rx_desc, rx_queue);
3180 if (p_used_rx_desc == NULL)
3183 p_used_rx_desc->buf_ptr = p_pkt_info->buf_ptr;
3184 p_used_rx_desc->return_info = p_pkt_info->return_info;
3185 p_used_rx_desc->byte_cnt = p_pkt_info->byte_cnt;
3186 p_used_rx_desc->buf_size = MV64460_RX_BUFFER_SIZE; /* Reset Buffer size */
3188 /* Flush the write pipe */
3191 /* Return the descriptor to DMA ownership */
3192 p_used_rx_desc->cmd_sts =
3193 ETH_BUFFER_OWNED_BY_DMA | ETH_RX_ENABLE_INTERRUPT;
3195 /* Flush descriptor and CPU pipe */
3196 D_CACHE_FLUSH_LINE ((unsigned int) p_used_rx_desc, 0);
3199 /* Move the used descriptor pointer to the next descriptor */
3200 USED_RFD_SET (RX_NEXT_DESC_PTR (p_used_rx_desc, rx_queue), rx_queue);
3202 /* Any Rx return cancels the Rx resource error status */
3203 if (p_eth_port_ctrl->rx_resource_err[rx_queue] == true)
3204 p_eth_port_ctrl->rx_resource_err[rx_queue] = false;
3209 /*******************************************************************************
3210 * eth_port_set_rx_coal - Sets coalescing interrupt mechanism on RX path
3213 * This routine sets the RX coalescing interrupt mechanism parameter.
3214 * This parameter is a timeout counter, that counts in 64 t_clk
3215 * chunks ; that when timeout event occurs a maskable interrupt
3217 * The parameter is calculated using the tClk of the MV-643xx chip
3218 * , and the required delay of the interrupt in usec.
3221 * ETH_PORT eth_port_num Ethernet port number
3222 * unsigned int t_clk t_clk of the MV-643xx chip in HZ units
3223 * unsigned int delay Delay in usec
3226 * Interrupt coalescing mechanism value is set in MV-643xx chip.
3229 * The interrupt coalescing value set in the gigE port.
3231 *******************************************************************************/
3233 static unsigned int eth_port_set_rx_coal (ETH_PORT eth_port_num,
3239 coal = ((t_clk / 1000000) * delay) / 64;
3240 /* Set RX Coalescing mechanism */
3241 MV_REG_WRITE (MV64460_ETH_SDMA_CONFIG_REG (eth_port_num),
3242 ((coal & 0x3fff) << 8) |
3244 (MV64460_ETH_SDMA_CONFIG_REG (eth_port_num))
3250 /*******************************************************************************
3251 * eth_port_set_tx_coal - Sets coalescing interrupt mechanism on TX path
3254 * This routine sets the TX coalescing interrupt mechanism parameter.
3255 * This parameter is a timeout counter, that counts in 64 t_clk
3256 * chunks ; that when timeout event occurs a maskable interrupt
3258 * The parameter is calculated using the t_cLK frequency of the
3259 * MV-643xx chip and the required delay in the interrupt in uSec
3262 * ETH_PORT eth_port_num Ethernet port number
3263 * unsigned int t_clk t_clk of the MV-643xx chip in HZ units
3264 * unsigned int delay Delay in uSeconds
3267 * Interrupt coalescing mechanism value is set in MV-643xx chip.
3270 * The interrupt coalescing value set in the gigE port.
3272 *******************************************************************************/
3274 static unsigned int eth_port_set_tx_coal (ETH_PORT eth_port_num,
3280 coal = ((t_clk / 1000000) * delay) / 64;
3281 /* Set TX Coalescing mechanism */
3282 MV_REG_WRITE (MV64460_ETH_TX_FIFO_URGENT_THRESHOLD_REG (eth_port_num),
3288 /*******************************************************************************
3289 * eth_b_copy - Copy bytes from source to destination
3292 * This function supports the eight bytes limitation on Tx buffer size.
3293 * The routine will zero eight bytes starting from the destination address
3294 * followed by copying bytes from the source address to the destination.
3297 * unsigned int src_addr 32 bit source address.
3298 * unsigned int dst_addr 32 bit destination address.
3299 * int byte_count Number of bytes to copy.
3307 *******************************************************************************/
3308 static void eth_b_copy (unsigned int src_addr, unsigned int dst_addr,
3311 /* Zero the dst_addr area */
3312 *(unsigned int *) dst_addr = 0x0;
3314 while (byte_count != 0) {
3315 *(char *) dst_addr = *(char *) src_addr;