]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/prodrive/p3mx/mv_eth.c
gic: fixed compilation error in GICv2 wait for interrupt macro
[karo-tx-uboot.git] / board / prodrive / p3mx / mv_eth.c
1 /*
2  * (C) Copyright 2003
3  * Ingo Assmus <ingo.assmus@keymile.com>
4  *
5  * based on - Driver for MV64460X ethernet ports
6  * Copyright (C) 2002 rabeeh@galileo.co.il
7  *
8  * SPDX-License-Identifier:     GPL-2.0+
9  */
10
11 /*
12  * mv_eth.c - header file for the polled mode GT ethernet driver
13  */
14 #include <common.h>
15 #include <net.h>
16 #include <malloc.h>
17 #include <miiphy.h>
18
19 #include "mv_eth.h"
20
21 /* enable Debug outputs */
22
23 #undef DEBUG_MV_ETH
24
25 #ifdef DEBUG_MV_ETH
26 #define DEBUG
27 #define DP(x) x
28 #else
29 #define DP(x)
30 #endif
31
32 /* PHY DFCDL Registers */
33 #define ETH_PHY_DFCDL_CONFIG0_REG       0x2100
34 #define ETH_PHY_DFCDL_CONFIG1_REG       0x2104
35 #define ETH_PHY_DFCDL_ADDR_REG          0x2110
36 #define ETH_PHY_DFCDL_DATA0_REG         0x2114
37
38 #define PHY_AUTONEGOTIATE_TIMEOUT       4000    /* 4000 ms autonegotiate timeout */
39 #define PHY_UPDATE_TIMEOUT              10000
40
41 #undef MV64460_CHECKSUM_OFFLOAD
42 /*************************************************************************
43 *  The first part is the high level driver of the gigE ethernet ports.   *
44 *************************************************************************/
45
46 /* Definition for configuring driver */
47 /* #define UPDATE_STATS_BY_SOFTWARE */
48 #undef MV64460_RX_QUEUE_FILL_ON_TASK
49
50 /* Constants */
51 #define MAGIC_ETH_RUNNING               8031971
52 #define MV64460_INTERNAL_SRAM_SIZE      _256K
53 #define EXTRA_BYTES 32
54 #define WRAP       ETH_HLEN + 2 + 4 + 16
55 #define BUFFER_MTU dev->mtu + WRAP
56 #define INT_CAUSE_UNMASK_ALL            0x0007ffff
57 #define INT_CAUSE_UNMASK_ALL_EXT        0x0011ffff
58 #ifdef MV64460_RX_FILL_ON_TASK
59 #define INT_CAUSE_MASK_ALL              0x00000000
60 #define INT_CAUSE_CHECK_BITS            INT_CAUSE_UNMASK_ALL
61 #define INT_CAUSE_CHECK_BITS_EXT        INT_CAUSE_UNMASK_ALL_EXT
62 #endif
63
64 /* Read/Write to/from MV64460 internal registers */
65 #define MV_REG_READ(offset) my_le32_to_cpu(* (volatile unsigned int *) (INTERNAL_REG_BASE_ADDR + offset))
66 #define MV_REG_WRITE(offset,data) *(volatile unsigned int *) (INTERNAL_REG_BASE_ADDR + offset) = my_cpu_to_le32 (data)
67 #define MV_SET_REG_BITS(regOffset,bits) ((*((volatile unsigned int*)((INTERNAL_REG_BASE_ADDR) + (regOffset)))) |= ((unsigned int)my_cpu_to_le32(bits)))
68 #define MV_RESET_REG_BITS(regOffset,bits) ((*((volatile unsigned int*)((INTERNAL_REG_BASE_ADDR) + (regOffset)))) &= ~((unsigned int)my_cpu_to_le32(bits)))
69
70 #define my_cpu_to_le32(x) my_le32_to_cpu((x))
71
72 /* Static function declarations */
73 static int mv64460_eth_real_open (struct eth_device *eth);
74 static int mv64460_eth_real_stop (struct eth_device *eth);
75 static struct net_device_stats *mv64460_eth_get_stats (struct eth_device
76                                                        *dev);
77 static void eth_port_init_mac_tables (ETH_PORT eth_port_num);
78 static void mv64460_eth_update_stat (struct eth_device *dev);
79 bool db64460_eth_start (struct eth_device *eth);
80 unsigned int eth_read_mib_counter (ETH_PORT eth_port_num,
81                                    unsigned int mib_offset);
82 int mv64460_eth_receive (struct eth_device *dev);
83
84 int mv64460_eth_xmit (struct eth_device *, volatile void *packet, int length);
85
86 int mv_miiphy_read(const char *devname, unsigned char phy_addr,
87                    unsigned char phy_reg, unsigned short *value);
88 int mv_miiphy_write(const char *devname, unsigned char phy_addr,
89                     unsigned char phy_reg, unsigned short value);
90
91 int phy_setup_aneg (char *devname, unsigned char addr);
92
93 #ifndef  UPDATE_STATS_BY_SOFTWARE
94 static void mv64460_eth_print_stat (struct eth_device *dev);
95 #endif
96
97 extern unsigned int INTERNAL_REG_BASE_ADDR;
98
99 unsigned long my_le32_to_cpu (unsigned long x)
100 {
101         return (((x & 0x000000ffU) << 24) |
102                 ((x & 0x0000ff00U) << 8) |
103                 ((x & 0x00ff0000U) >> 8) | ((x & 0xff000000U) >> 24));
104 }
105
106 /*************************************************
107  *Helper functions - used inside the driver only *
108  *************************************************/
109 #ifdef DEBUG_MV_ETH
110 void print_globals (struct eth_device *dev)
111 {
112         printf ("Ethernet PRINT_Globals-Debug function\n");
113         printf ("Base Address for ETH_PORT_INFO:        %08x\n",
114                 (unsigned int) dev->priv);
115         printf ("Base Address for mv64460_eth_priv:     %08x\n",
116                 (unsigned int) &(((ETH_PORT_INFO *) dev->priv)->
117                                  port_private));
118
119         printf ("GT Internal Base Address:      %08x\n",
120                 INTERNAL_REG_BASE_ADDR);
121         printf ("Base Address for TX-DESCs:     %08x    Number of allocated Buffers %d\n",
122                 (unsigned int) ((ETH_PORT_INFO *) dev->priv)->p_tx_desc_area_base[0], MV64460_TX_QUEUE_SIZE);
123         printf ("Base Address for RX-DESCs:     %08x    Number of allocated Buffers %d\n",
124                 (unsigned int) ((ETH_PORT_INFO *) dev->priv)->p_rx_desc_area_base[0], MV64460_RX_QUEUE_SIZE);
125         printf ("Base Address for RX-Buffer:    %08x    allocated Bytes %d\n",
126                 (unsigned int) ((ETH_PORT_INFO *) dev->priv)->
127                 p_rx_buffer_base[0],
128                 (MV64460_RX_QUEUE_SIZE * MV64460_RX_BUFFER_SIZE) + 32);
129         printf ("Base Address for TX-Buffer:    %08x    allocated Bytes %d\n",
130                 (unsigned int) ((ETH_PORT_INFO *) dev->priv)->
131                 p_tx_buffer_base[0],
132                 (MV64460_TX_QUEUE_SIZE * MV64460_TX_BUFFER_SIZE) + 32);
133 }
134 #endif
135
136 /**********************************************************************
137  * mv64460_eth_print_phy_status
138  *
139  * Prints gigabit ethenret phy status
140  *
141  * Input : pointer to ethernet interface network device structure
142  * Output : N/A
143  **********************************************************************/
144 void mv64460_eth_print_phy_status (struct eth_device *dev)
145 {
146         struct mv64460_eth_priv *port_private;
147         unsigned int port_num;
148         ETH_PORT_INFO *ethernet_private = (ETH_PORT_INFO *) dev->priv;
149         unsigned int port_status, phy_reg_data;
150
151         port_private =
152                 (struct mv64460_eth_priv *) ethernet_private->port_private;
153         port_num = port_private->port_num;
154
155         /* Check Link status on phy */
156         eth_port_read_smi_reg (port_num, 1, &phy_reg_data);
157         if (!(phy_reg_data & 0x20)) {
158                 printf ("Ethernet port changed link status to DOWN\n");
159         } else {
160                 port_status =
161                         MV_REG_READ (MV64460_ETH_PORT_STATUS_REG (port_num));
162                 printf ("Ethernet status port %d: Link up", port_num);
163                 printf (", %s",
164                         (port_status & BIT2) ? "Full Duplex" : "Half Duplex");
165                 if (port_status & BIT4)
166                         printf (", Speed 1 Gbps");
167                 else
168                         printf (", %s",
169                                 (port_status & BIT5) ? "Speed 100 Mbps" :
170                                 "Speed 10 Mbps");
171                 printf ("\n");
172         }
173 }
174
175 /**********************************************************************
176  * u-boot entry functions for mv64460_eth
177  *
178  **********************************************************************/
179 int db64460_eth_probe (struct eth_device *dev)
180 {
181         return ((int) db64460_eth_start (dev));
182 }
183
184 int db64460_eth_poll (struct eth_device *dev)
185 {
186         return mv64460_eth_receive (dev);
187 }
188
189 int db64460_eth_transmit(struct eth_device *dev, void *packet, int length)
190 {
191         mv64460_eth_xmit (dev, packet, length);
192         return 0;
193 }
194
195 void db64460_eth_disable (struct eth_device *dev)
196 {
197         mv64460_eth_stop (dev);
198 }
199
200 #define DFCDL(write,read)   ((write << 6) | read)
201 unsigned int  ethDfcdls[] = {
202         DFCDL(0,0),     DFCDL(1,1),     DFCDL(2,2),     DFCDL(3,3),
203         DFCDL(4,4),     DFCDL(5,5),     DFCDL(6,6),     DFCDL(7,7),
204         DFCDL(8,8),     DFCDL(9,9),     DFCDL(10,10),   DFCDL(11,11),
205         DFCDL(12,12),   DFCDL(13,13),   DFCDL(14,14),   DFCDL(15,15),
206         DFCDL(16,16),   DFCDL(17,17),   DFCDL(18,18),   DFCDL(19,19),
207         DFCDL(20,20),   DFCDL(21,21),   DFCDL(22,22),   DFCDL(23,23),
208         DFCDL(24,24),   DFCDL(25,25),   DFCDL(26,26),   DFCDL(27,27),
209         DFCDL(28,28),   DFCDL(29,29),   DFCDL(30,30),   DFCDL(31,31),
210         DFCDL(32,32),   DFCDL(33,33),   DFCDL(34,34),   DFCDL(35,35),
211         DFCDL(36,36),   DFCDL(37,37),   DFCDL(38,38),   DFCDL(39,39),
212         DFCDL(40,40),   DFCDL(41,41),   DFCDL(42,42),   DFCDL(43,43),
213         DFCDL(44,44),   DFCDL(45,45),   DFCDL(46,46),   DFCDL(47,47),
214         DFCDL(48,48),   DFCDL(49,49),   DFCDL(50,50),   DFCDL(51,51),
215         DFCDL(52,52),   DFCDL(53,53),   DFCDL(54,54),   DFCDL(55,55),
216         DFCDL(56,56),   DFCDL(57,57),   DFCDL(58,58),   DFCDL(59,59),
217         DFCDL(60,60),   DFCDL(61,61),   DFCDL(62,62),   DFCDL(63,63),
218 };
219
220 void mv_eth_phy_init (void)
221 {
222         int i;
223
224         MV_REG_WRITE (ETH_PHY_DFCDL_ADDR_REG, 0);
225
226         for (i = 0; i < 64; i++) {
227                 MV_REG_WRITE (ETH_PHY_DFCDL_DATA0_REG, ethDfcdls[i]);
228         }
229
230         MV_REG_WRITE (ETH_PHY_DFCDL_CONFIG0_REG, 0x300000);
231 }
232
233 void mv6446x_eth_initialize (bd_t * bis)
234 {
235         struct eth_device *dev;
236         ETH_PORT_INFO *ethernet_private;
237         struct mv64460_eth_priv *port_private;
238         int devnum, x, temp;
239         char *s, *e, buf[64];
240
241         /* P3M750 only
242          * Set RGMII clock drives strength
243          */
244         temp = MV_REG_READ(0x20A0);
245         temp |= 0x04000080;
246         MV_REG_WRITE(0x20A0, temp);
247
248         mv_eth_phy_init();
249
250         for (devnum = 0; devnum < MV_ETH_DEVS; devnum++) {
251                 dev = calloc (sizeof (*dev), 1);
252                 if (!dev) {
253                         printf ("%s: mv_enet%d allocation failure, %s\n",
254                                 __FUNCTION__, devnum, "eth_device structure");
255                         return;
256                 }
257
258                 /* must be less than sizeof(dev->name) */
259                 sprintf (dev->name, "mv_enet%d", devnum);
260
261 #ifdef DEBUG
262                 printf ("Initializing %s\n", dev->name);
263 #endif
264
265                 /* Extract the MAC address from the environment */
266                 switch (devnum) {
267                 case 0:
268                         s = "ethaddr";
269                         break;
270                 case 1:
271                         s = "eth1addr";
272                         break;
273                 case 2:
274                         s = "eth2addr";
275                         break;
276                 default:        /* this should never happen */
277                         printf ("%s: Invalid device number %d\n",
278                                 __FUNCTION__, devnum);
279                         return;
280                 }
281
282                 temp = getenv_f(s, buf, sizeof (buf));
283                 s = (temp > 0) ? buf : NULL;
284
285 #ifdef DEBUG
286                 printf ("Setting MAC %d to %s\n", devnum, s);
287 #endif
288                 for (x = 0; x < 6; ++x) {
289                         dev->enetaddr[x] = s ? simple_strtoul (s, &e, 16) : 0;
290                         if (s)
291                                 s = (*e) ? e + 1 : e;
292                 }
293                 /* ronen - set the MAC addr in the HW */
294                 eth_port_uc_addr_set (devnum, dev->enetaddr, 0);
295
296                 dev->init = (void *) db64460_eth_probe;
297                 dev->halt = (void *) ethernet_phy_reset;
298                 dev->send = (void *) db64460_eth_transmit;
299                 dev->recv = (void *) db64460_eth_poll;
300
301                 ethernet_private = calloc (sizeof (*ethernet_private), 1);
302                 dev->priv = (void *)ethernet_private;
303                 if (!ethernet_private) {
304                         printf ("%s: %s allocation failure, %s\n",
305                                 __FUNCTION__, dev->name,
306                                 "Private Device Structure");
307                         free (dev);
308                         return;
309                 }
310                 /* start with an zeroed ETH_PORT_INFO */
311                 memset (ethernet_private, 0, sizeof (ETH_PORT_INFO));
312                 memcpy (ethernet_private->port_mac_addr, dev->enetaddr, 6);
313
314                 /* set pointer to memory for stats data structure etc... */
315                 port_private = calloc (sizeof (*ethernet_private), 1);
316                 ethernet_private->port_private = (void *)port_private;
317                 if (!port_private) {
318                         printf ("%s: %s allocation failure, %s\n",
319                                 __FUNCTION__, dev->name,
320                                 "Port Private Device Structure");
321
322                         free (ethernet_private);
323                         free (dev);
324                         return;
325                 }
326
327                 port_private->stats =
328                         calloc (sizeof (struct net_device_stats), 1);
329                 if (!port_private->stats) {
330                         printf ("%s: %s allocation failure, %s\n",
331                                 __FUNCTION__, dev->name,
332                                 "Net stat Structure");
333
334                         free (port_private);
335                         free (ethernet_private);
336                         free (dev);
337                         return;
338                 }
339                 memset (ethernet_private->port_private, 0,
340                         sizeof (struct mv64460_eth_priv));
341                 switch (devnum) {
342                 case 0:
343                         ethernet_private->port_num = ETH_0;
344                         break;
345                 case 1:
346                         ethernet_private->port_num = ETH_1;
347                         break;
348                 case 2:
349                         ethernet_private->port_num = ETH_2;
350                         break;
351                 default:
352                         printf ("Invalid device number %d\n", devnum);
353                         break;
354                 };
355
356                 port_private->port_num = devnum;
357                 /*
358                  * Read MIB counter on the GT in order to reset them,
359                  * then zero all the stats fields in memory
360                  */
361                 mv64460_eth_update_stat (dev);
362                 memset (port_private->stats, 0,
363                         sizeof (struct net_device_stats));
364                 /* Extract the MAC address from the environment */
365                 switch (devnum) {
366                 case 0:
367                         s = "ethaddr";
368                         break;
369                 case 1:
370                         s = "eth1addr";
371                         break;
372                 case 2:
373                         s = "eth2addr";
374                         break;
375                 default:        /* this should never happen */
376                         printf ("%s: Invalid device number %d\n",
377                                 __FUNCTION__, devnum);
378                         return;
379                 }
380
381                 temp = getenv_f(s, buf, sizeof (buf));
382                 s = (temp > 0) ? buf : NULL;
383
384 #ifdef DEBUG
385                 printf ("Setting MAC %d to %s\n", devnum, s);
386 #endif
387                 for (x = 0; x < 6; ++x) {
388                         dev->enetaddr[x] = s ? simple_strtoul (s, &e, 16) : 0;
389                         if (s)
390                                 s = (*e) ? e + 1 : e;
391                 }
392
393                 DP (printf ("Allocating descriptor and buffer rings\n"));
394
395                 ethernet_private->p_rx_desc_area_base[0] =
396                         (ETH_RX_DESC *) memalign (16,
397                                                   RX_DESC_ALIGNED_SIZE *
398                                                   MV64460_RX_QUEUE_SIZE + 1);
399                 ethernet_private->p_tx_desc_area_base[0] =
400                         (ETH_TX_DESC *) memalign (16,
401                                                   TX_DESC_ALIGNED_SIZE *
402                                                   MV64460_TX_QUEUE_SIZE + 1);
403
404                 ethernet_private->p_rx_buffer_base[0] =
405                         (char *) memalign (16,
406                                            MV64460_RX_QUEUE_SIZE *
407                                            MV64460_TX_BUFFER_SIZE + 1);
408                 ethernet_private->p_tx_buffer_base[0] =
409                         (char *) memalign (16,
410                                            MV64460_RX_QUEUE_SIZE *
411                                            MV64460_TX_BUFFER_SIZE + 1);
412
413 #ifdef DEBUG_MV_ETH
414                 /* DEBUG OUTPUT prints adresses of globals */
415                 print_globals (dev);
416 #endif
417                 eth_register (dev);
418
419                 miiphy_register(dev->name, mv_miiphy_read, mv_miiphy_write);
420         }
421         DP (printf ("%s: exit\n", __FUNCTION__));
422
423 }
424
425 /**********************************************************************
426  * mv64460_eth_open
427  *
428  * This function is called when openning the network device. The function
429  * should initialize all the hardware, initialize cyclic Rx/Tx
430  * descriptors chain and buffers and allocate an IRQ to the network
431  * device.
432  *
433  * Input : a pointer to the network device structure
434  * / / ronen - changed the output to match  net/eth.c needs
435  * Output : nonzero of success , zero if fails.
436  * under construction
437  **********************************************************************/
438
439 int mv64460_eth_open (struct eth_device *dev)
440 {
441         return (mv64460_eth_real_open (dev));
442 }
443
444 /* Helper function for mv64460_eth_open */
445 static int mv64460_eth_real_open (struct eth_device *dev)
446 {
447
448         unsigned int queue;
449         ETH_PORT_INFO *ethernet_private;
450         struct mv64460_eth_priv *port_private;
451         unsigned int port_num;
452         ushort reg_short;
453         int speed;
454         int duplex;
455         int i;
456         int reg;
457
458         ethernet_private = (ETH_PORT_INFO *) dev->priv;
459         /* ronen - when we update the MAC env params we only update dev->enetaddr
460            see ./net/eth.c eth_set_enetaddr() */
461         memcpy (ethernet_private->port_mac_addr, dev->enetaddr, 6);
462
463         port_private = (struct mv64460_eth_priv *) ethernet_private->port_private;
464         port_num = port_private->port_num;
465
466         /* Stop RX Queues */
467         MV_REG_WRITE (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG (port_num), 0x0000ff00);
468
469         /* Clear the ethernet port interrupts */
470         MV_REG_WRITE (MV64460_ETH_INTERRUPT_CAUSE_REG (port_num), 0);
471         MV_REG_WRITE (MV64460_ETH_INTERRUPT_CAUSE_EXTEND_REG (port_num), 0);
472
473         /* Unmask RX buffer and TX end interrupt */
474         MV_REG_WRITE (MV64460_ETH_INTERRUPT_MASK_REG (port_num),
475                       INT_CAUSE_UNMASK_ALL);
476
477         /* Unmask phy and link status changes interrupts */
478         MV_REG_WRITE (MV64460_ETH_INTERRUPT_EXTEND_MASK_REG (port_num),
479                       INT_CAUSE_UNMASK_ALL_EXT);
480
481         /* Set phy address of the port */
482         ethernet_private->port_phy_addr = 0x1 + (port_num << 1);
483         reg = ethernet_private->port_phy_addr;
484
485         /* Activate the DMA channels etc */
486         eth_port_init (ethernet_private);
487
488         /* "Allocate" setup TX rings */
489
490         for (queue = 0; queue < MV64460_TX_QUEUE_NUM; queue++) {
491                 unsigned int size;
492
493                 port_private->tx_ring_size[queue] = MV64460_TX_QUEUE_SIZE;
494                 size = (port_private->tx_ring_size[queue] * TX_DESC_ALIGNED_SIZE);      /*size = no of DESCs times DESC-size */
495                 ethernet_private->tx_desc_area_size[queue] = size;
496
497                 /* first clear desc area completely */
498                 memset ((void *) ethernet_private->p_tx_desc_area_base[queue],
499                         0, ethernet_private->tx_desc_area_size[queue]);
500
501                 /* initialize tx desc ring with low level driver */
502                 if (ether_init_tx_desc_ring
503                     (ethernet_private, ETH_Q0,
504                      port_private->tx_ring_size[queue],
505                      MV64460_TX_BUFFER_SIZE /* Each Buffer is 1600 Byte */ ,
506                      (unsigned int) ethernet_private->
507                      p_tx_desc_area_base[queue],
508                      (unsigned int) ethernet_private->
509                      p_tx_buffer_base[queue]) == false)
510                         printf ("### Error initializing TX Ring\n");
511         }
512
513         /* "Allocate" setup RX rings */
514         for (queue = 0; queue < MV64460_RX_QUEUE_NUM; queue++) {
515                 unsigned int size;
516
517                 /* Meantime RX Ring are fixed - but must be configurable by user */
518                 port_private->rx_ring_size[queue] = MV64460_RX_QUEUE_SIZE;
519                 size = (port_private->rx_ring_size[queue] *
520                         RX_DESC_ALIGNED_SIZE);
521                 ethernet_private->rx_desc_area_size[queue] = size;
522
523                 /* first clear desc area completely */
524                 memset ((void *) ethernet_private->p_rx_desc_area_base[queue],
525                         0, ethernet_private->rx_desc_area_size[queue]);
526                 if ((ether_init_rx_desc_ring
527                      (ethernet_private, ETH_Q0,
528                       port_private->rx_ring_size[queue],
529                       MV64460_RX_BUFFER_SIZE /* Each Buffer is 1600 Byte */ ,
530                       (unsigned int) ethernet_private->
531                       p_rx_desc_area_base[queue],
532                       (unsigned int) ethernet_private->
533                       p_rx_buffer_base[queue])) == false)
534                         printf ("### Error initializing RX Ring\n");
535         }
536
537         eth_port_start (ethernet_private);
538
539         /* Set maximum receive buffer to 9700 bytes */
540         MV_REG_WRITE (MV64460_ETH_PORT_SERIAL_CONTROL_REG (port_num),
541                       (0x5 << 17) |
542                       (MV_REG_READ
543                        (MV64460_ETH_PORT_SERIAL_CONTROL_REG (port_num))
544                        & 0xfff1ffff));
545
546         /*
547          * Set ethernet MTU for leaky bucket mechanism to 0 - this will
548          * disable the leaky bucket mechanism .
549          */
550
551         MV_REG_WRITE (MV64460_ETH_MAXIMUM_TRANSMIT_UNIT (port_num), 0);
552         MV_REG_READ (MV64460_ETH_PORT_STATUS_REG (port_num));
553
554 #if defined(CONFIG_PHY_RESET)
555         /*
556          * Reset the phy, only if its the first time through
557          * otherwise, just check the speeds & feeds
558          */
559         if (port_private->first_init == 0) {
560                 port_private->first_init = 1;
561                 ethernet_phy_reset (port_num);
562
563                 /* Start/Restart autonegotiation */
564                 phy_setup_aneg (dev->name, reg);
565                 udelay (1000);
566         }
567 #endif /* defined(CONFIG_PHY_RESET) */
568
569         miiphy_read (dev->name, reg, MII_BMSR, &reg_short);
570
571         /*
572          * Wait if PHY is capable of autonegotiation and autonegotiation is not complete
573          */
574         if ((reg_short & BMSR_ANEGCAPABLE)
575             && !(reg_short & BMSR_ANEGCOMPLETE)) {
576                 puts ("Waiting for PHY auto negotiation to complete");
577                 i = 0;
578                 while (!(reg_short & BMSR_ANEGCOMPLETE)) {
579                         /*
580                          * Timeout reached ?
581                          */
582                         if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
583                                 puts (" TIMEOUT !\n");
584                                 break;
585                         }
586
587                         if ((i++ % 1000) == 0) {
588                                 putc ('.');
589                         }
590                         udelay (1000);  /* 1 ms */
591                         miiphy_read (dev->name, reg, MII_BMSR, &reg_short);
592
593                 }
594                 puts (" done\n");
595                 udelay (500000);        /* another 500 ms (results in faster booting) */
596         }
597
598         speed = miiphy_speed (dev->name, reg);
599         duplex = miiphy_duplex (dev->name, reg);
600
601         printf ("ENET Speed is %d Mbps - %s duplex connection\n",
602                 (int) speed, (duplex == HALF) ? "HALF" : "FULL");
603
604         port_private->eth_running = MAGIC_ETH_RUNNING;
605         return 1;
606 }
607
608 static int mv64460_eth_free_tx_rings (struct eth_device *dev)
609 {
610         unsigned int queue;
611         ETH_PORT_INFO *ethernet_private;
612         struct mv64460_eth_priv *port_private;
613         unsigned int port_num;
614         volatile ETH_TX_DESC *p_tx_curr_desc;
615
616         ethernet_private = (ETH_PORT_INFO *) dev->priv;
617         port_private =
618                 (struct mv64460_eth_priv *) ethernet_private->port_private;
619         port_num = port_private->port_num;
620
621         /* Stop Tx Queues */
622         MV_REG_WRITE (MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG (port_num),
623                       0x0000ff00);
624
625         /* Free TX rings */
626         DP (printf ("Clearing previously allocated TX queues... "));
627         for (queue = 0; queue < MV64460_TX_QUEUE_NUM; queue++) {
628                 /* Free on TX rings */
629                 for (p_tx_curr_desc =
630                      ethernet_private->p_tx_desc_area_base[queue];
631                      ((unsigned int) p_tx_curr_desc <= (unsigned int)
632                       ethernet_private->p_tx_desc_area_base[queue] +
633                       ethernet_private->tx_desc_area_size[queue]);
634                      p_tx_curr_desc =
635                      (ETH_TX_DESC *) ((unsigned int) p_tx_curr_desc +
636                                       TX_DESC_ALIGNED_SIZE)) {
637                         /* this is inside for loop */
638                         if (p_tx_curr_desc->return_info != 0) {
639                                 p_tx_curr_desc->return_info = 0;
640                                 DP (printf ("freed\n"));
641                         }
642                 }
643                 DP (printf ("Done\n"));
644         }
645         return 0;
646 }
647
648 static int mv64460_eth_free_rx_rings (struct eth_device *dev)
649 {
650         unsigned int queue;
651         ETH_PORT_INFO *ethernet_private;
652         struct mv64460_eth_priv *port_private;
653         unsigned int port_num;
654         volatile ETH_RX_DESC *p_rx_curr_desc;
655
656         ethernet_private = (ETH_PORT_INFO *) dev->priv;
657         port_private =
658                 (struct mv64460_eth_priv *) ethernet_private->port_private;
659         port_num = port_private->port_num;
660
661         /* Stop RX Queues */
662         MV_REG_WRITE (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG (port_num),
663                       0x0000ff00);
664
665         /* Free RX rings */
666         DP (printf ("Clearing previously allocated RX queues... "));
667         for (queue = 0; queue < MV64460_RX_QUEUE_NUM; queue++) {
668                 /* Free preallocated skb's on RX rings */
669                 for (p_rx_curr_desc =
670                      ethernet_private->p_rx_desc_area_base[queue];
671                      (((unsigned int) p_rx_curr_desc <
672                        ((unsigned int) ethernet_private->
673                         p_rx_desc_area_base[queue] +
674                         ethernet_private->rx_desc_area_size[queue])));
675                      p_rx_curr_desc =
676                      (ETH_RX_DESC *) ((unsigned int) p_rx_curr_desc +
677                                       RX_DESC_ALIGNED_SIZE)) {
678                         if (p_rx_curr_desc->return_info != 0) {
679                                 p_rx_curr_desc->return_info = 0;
680                                 DP (printf ("freed\n"));
681                         }
682                 }
683                 DP (printf ("Done\n"));
684         }
685         return 0;
686 }
687
688 /**********************************************************************
689  * mv64460_eth_stop
690  *
691  * This function is used when closing the network device.
692  * It updates the hardware,
693  * release all memory that holds buffers and descriptors and release the IRQ.
694  * Input : a pointer to the device structure
695  * Output : zero if success , nonzero if fails
696  *********************************************************************/
697
698 int mv64460_eth_stop (struct eth_device *dev)
699 {
700         /* Disable all gigE address decoder */
701         MV_REG_WRITE (MV64460_ETH_BASE_ADDR_ENABLE_REG, 0x3f);
702         DP (printf ("%s Ethernet stop called ... \n", __FUNCTION__));
703         mv64460_eth_real_stop (dev);
704
705         return 0;
706 };
707
708 /* Helper function for mv64460_eth_stop */
709
710 static int mv64460_eth_real_stop (struct eth_device *dev)
711 {
712         ETH_PORT_INFO *ethernet_private;
713         struct mv64460_eth_priv *port_private;
714         unsigned int port_num;
715
716         ethernet_private = (ETH_PORT_INFO *) dev->priv;
717         port_private =
718                 (struct mv64460_eth_priv *) ethernet_private->port_private;
719         port_num = port_private->port_num;
720
721         mv64460_eth_free_tx_rings (dev);
722         mv64460_eth_free_rx_rings (dev);
723
724         eth_port_reset (ethernet_private->port_num);
725         /* Disable ethernet port interrupts */
726         MV_REG_WRITE (MV64460_ETH_INTERRUPT_CAUSE_REG (port_num), 0);
727         MV_REG_WRITE (MV64460_ETH_INTERRUPT_CAUSE_EXTEND_REG (port_num), 0);
728         /* Mask RX buffer and TX end interrupt */
729         MV_REG_WRITE (MV64460_ETH_INTERRUPT_MASK_REG (port_num), 0);
730         /* Mask phy and link status changes interrupts */
731         MV_REG_WRITE (MV64460_ETH_INTERRUPT_EXTEND_MASK_REG (port_num), 0);
732         MV_RESET_REG_BITS (MV64460_CPU_INTERRUPT0_MASK_HIGH,
733                            BIT0 << port_num);
734         /* Print Network statistics */
735 #ifndef  UPDATE_STATS_BY_SOFTWARE
736         /*
737          * Print statistics (only if ethernet is running),
738          * then zero all the stats fields in memory
739          */
740         if (port_private->eth_running == MAGIC_ETH_RUNNING) {
741                 port_private->eth_running = 0;
742                 mv64460_eth_print_stat (dev);
743         }
744         memset (port_private->stats, 0, sizeof (struct net_device_stats));
745 #endif
746         DP (printf ("\nEthernet stopped ... \n"));
747         return 0;
748 }
749
750 /**********************************************************************
751  * mv64460_eth_start_xmit
752  *
753  * This function is queues a packet in the Tx descriptor for
754  * required port.
755  *
756  * Input : skb - a pointer to socket buffer
757  *         dev - a pointer to the required port
758  *
759  * Output : zero upon success
760  **********************************************************************/
761
762 int mv64460_eth_xmit (struct eth_device *dev, volatile void *dataPtr,
763                       int dataSize)
764 {
765         ETH_PORT_INFO *ethernet_private;
766         struct mv64460_eth_priv *port_private;
767         PKT_INFO pkt_info;
768         ETH_FUNC_RET_STATUS status;
769         struct net_device_stats *stats;
770         ETH_FUNC_RET_STATUS release_result;
771
772         ethernet_private = (ETH_PORT_INFO *) dev->priv;
773         port_private =
774                 (struct mv64460_eth_priv *) ethernet_private->port_private;
775
776         stats = port_private->stats;
777
778         /* Update packet info data structure */
779         pkt_info.cmd_sts = ETH_TX_FIRST_DESC | ETH_TX_LAST_DESC;        /* DMA owned, first last */
780         pkt_info.byte_cnt = dataSize;
781         pkt_info.buf_ptr = (unsigned int) dataPtr;
782         pkt_info.return_info = 0;
783
784         status = eth_port_send (ethernet_private, ETH_Q0, &pkt_info);
785         if ((status == ETH_ERROR) || (status == ETH_QUEUE_FULL)) {
786                 printf ("Error on transmitting packet ..");
787                 if (status == ETH_QUEUE_FULL)
788                         printf ("ETH Queue is full. \n");
789                 if (status == ETH_QUEUE_LAST_RESOURCE)
790                         printf ("ETH Queue: using last available resource. \n");
791                 return 1;
792         }
793
794         /* Update statistics and start of transmittion time */
795         stats->tx_bytes += dataSize;
796         stats->tx_packets++;
797
798         /* Check if packet(s) is(are) transmitted correctly (release everything) */
799         do {
800                 release_result =
801                         eth_tx_return_desc (ethernet_private, ETH_Q0,
802                                             &pkt_info);
803                 switch (release_result) {
804                 case ETH_OK:
805                         DP (printf ("descriptor released\n"));
806                         if (pkt_info.cmd_sts & BIT0) {
807                                 printf ("Error in TX\n");
808                                 stats->tx_errors++;
809                         }
810                         break;
811                 case ETH_RETRY:
812                         DP (printf ("transmission still in process\n"));
813                         break;
814
815                 case ETH_ERROR:
816                         printf ("routine can not access Tx desc ring\n");
817                         break;
818
819                 case ETH_END_OF_JOB:
820                         DP (printf ("the routine has nothing to release\n"));
821                         break;
822                 default:        /* should not happen */
823                         break;
824                 }
825         } while (release_result == ETH_OK);
826
827         return 0;       /* success */
828 }
829
830 /**********************************************************************
831  * mv64460_eth_receive
832  *
833  * This function is forward packets that are received from the port's
834  * queues toward kernel core or FastRoute them to another interface.
835  *
836  * Input : dev - a pointer to the required interface
837  *         max - maximum number to receive (0 means unlimted)
838  *
839  * Output : number of served packets
840  **********************************************************************/
841
842 int mv64460_eth_receive (struct eth_device *dev)
843 {
844         ETH_PORT_INFO *ethernet_private;
845         struct mv64460_eth_priv *port_private;
846         PKT_INFO pkt_info;
847         struct net_device_stats *stats;
848
849         ethernet_private = (ETH_PORT_INFO *) dev->priv;
850         port_private = (struct mv64460_eth_priv *) ethernet_private->port_private;
851         stats = port_private->stats;
852
853         while ((eth_port_receive (ethernet_private, ETH_Q0, &pkt_info) == ETH_OK)) {
854 #ifdef DEBUG_MV_ETH
855                 if (pkt_info.byte_cnt != 0) {
856                         printf ("%s: Received %d byte Packet @ 0x%x\n",
857                                 __FUNCTION__, pkt_info.byte_cnt,
858                                 pkt_info.buf_ptr);
859                         if(pkt_info.buf_ptr != 0){
860                                 for(i=0; i < pkt_info.byte_cnt; i++){
861                                         if((i % 4) == 0){
862                                                 printf("\n0x");
863                                         }
864                                         printf("%02x", ((char*)pkt_info.buf_ptr)[i]);
865                                 }
866                                 printf("\n");
867                         }
868                 }
869 #endif
870                 /* Update statistics. Note byte count includes 4 byte CRC count */
871                 stats->rx_packets++;
872                 stats->rx_bytes += pkt_info.byte_cnt;
873
874                 /*
875                  * In case received a packet without first / last bits on OR the error
876                  * summary bit is on, the packets needs to be dropeed.
877                  */
878                 if (((pkt_info.
879                       cmd_sts & (ETH_RX_FIRST_DESC | ETH_RX_LAST_DESC)) !=
880                      (ETH_RX_FIRST_DESC | ETH_RX_LAST_DESC))
881                     || (pkt_info.cmd_sts & ETH_ERROR_SUMMARY)) {
882                         stats->rx_dropped++;
883
884                         printf ("Received packet spread on multiple descriptors\n");
885
886                         /* Is this caused by an error ? */
887                         if (pkt_info.cmd_sts & ETH_ERROR_SUMMARY) {
888                                 stats->rx_errors++;
889                         }
890
891                         /* free these descriptors again without forwarding them to the higher layers */
892                         pkt_info.buf_ptr &= ~0x7;       /* realign buffer again */
893                         pkt_info.byte_cnt = 0x0000;     /* Reset Byte count */
894
895                         if (eth_rx_return_buff
896                             (ethernet_private, ETH_Q0, &pkt_info) != ETH_OK) {
897                                 printf ("Error while returning the RX Desc to Ring\n");
898                         } else {
899                                 DP (printf ("RX Desc returned to Ring\n"));
900                         }
901                         /* /free these descriptors again */
902                 } else {
903
904 /* !!! call higher layer processing */
905 #ifdef DEBUG_MV_ETH
906                         printf ("\nNow send it to upper layer protocols (NetReceive) ...\n");
907 #endif
908                         /* let the upper layer handle the packet */
909                         NetReceive ((uchar *) pkt_info.buf_ptr,
910                                     (int) pkt_info.byte_cnt);
911
912 /* **************************************************************** */
913 /* free descriptor  */
914                         pkt_info.buf_ptr &= ~0x7;       /* realign buffer again */
915                         pkt_info.byte_cnt = 0x0000;     /* Reset Byte count */
916                         DP (printf ("RX: pkt_info.buf_ptr =     %x\n", pkt_info.buf_ptr));
917                         if (eth_rx_return_buff
918                             (ethernet_private, ETH_Q0, &pkt_info) != ETH_OK) {
919                                 printf ("Error while returning the RX Desc to Ring\n");
920                         } else {
921                                 DP (printf ("RX: Desc returned to Ring\n"));
922                         }
923
924 /* **************************************************************** */
925
926                 }
927         }
928         mv64460_eth_get_stats (dev);    /* update statistics */
929         return 1;
930 }
931
932 /**********************************************************************
933  * mv64460_eth_get_stats
934  *
935  * Returns a pointer to the interface statistics.
936  *
937  * Input : dev - a pointer to the required interface
938  *
939  * Output : a pointer to the interface's statistics
940  **********************************************************************/
941
942 static struct net_device_stats *mv64460_eth_get_stats (struct eth_device *dev)
943 {
944         ETH_PORT_INFO *ethernet_private;
945         struct mv64460_eth_priv *port_private;
946
947         ethernet_private = (ETH_PORT_INFO *) dev->priv;
948         port_private =
949                 (struct mv64460_eth_priv *) ethernet_private->port_private;
950
951         mv64460_eth_update_stat (dev);
952
953         return port_private->stats;
954 }
955
956 /**********************************************************************
957  * mv64460_eth_update_stat
958  *
959  * Update the statistics structure in the private data structure
960  *
961  * Input : pointer to ethernet interface network device structure
962  * Output : N/A
963  **********************************************************************/
964
965 static void mv64460_eth_update_stat (struct eth_device *dev)
966 {
967         ETH_PORT_INFO *ethernet_private;
968         struct mv64460_eth_priv *port_private;
969         struct net_device_stats *stats;
970
971         ethernet_private = (ETH_PORT_INFO *) dev->priv;
972         port_private =
973                 (struct mv64460_eth_priv *) ethernet_private->port_private;
974         stats = port_private->stats;
975
976         /* These are false updates */
977         stats->rx_packets += (unsigned long)
978                 eth_read_mib_counter (ethernet_private->port_num,
979                                       ETH_MIB_GOOD_FRAMES_RECEIVED);
980         stats->tx_packets += (unsigned long)
981                 eth_read_mib_counter (ethernet_private->port_num,
982                                       ETH_MIB_GOOD_FRAMES_SENT);
983         stats->rx_bytes += (unsigned long)
984                 eth_read_mib_counter (ethernet_private->port_num,
985                                       ETH_MIB_GOOD_OCTETS_RECEIVED_LOW);
986         /*
987          * Ideally this should be as follows -
988          *
989          *   stats->rx_bytes   += stats->rx_bytes +
990          * ((unsigned long) ethReadMibCounter (ethernet_private->port_num ,
991          * ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH) << 32);
992          *
993          * But the unsigned long in PowerPC and MIPS are 32bit. So the next read
994          * is just a dummy read for proper work of the GigE port
995          */
996         (void)eth_read_mib_counter (ethernet_private->port_num,
997                                       ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH);
998         stats->tx_bytes += (unsigned long)
999                 eth_read_mib_counter (ethernet_private->port_num,
1000                                       ETH_MIB_GOOD_OCTETS_SENT_LOW);
1001         (void)eth_read_mib_counter (ethernet_private->port_num,
1002                                       ETH_MIB_GOOD_OCTETS_SENT_HIGH);
1003         stats->rx_errors += (unsigned long)
1004                 eth_read_mib_counter (ethernet_private->port_num,
1005                                       ETH_MIB_MAC_RECEIVE_ERROR);
1006
1007         /* Rx dropped is for received packet with CRC error */
1008         stats->rx_dropped +=
1009                 (unsigned long) eth_read_mib_counter (ethernet_private->
1010                                                       port_num,
1011                                                       ETH_MIB_BAD_CRC_EVENT);
1012         stats->multicast += (unsigned long)
1013                 eth_read_mib_counter (ethernet_private->port_num,
1014                                       ETH_MIB_MULTICAST_FRAMES_RECEIVED);
1015         stats->collisions +=
1016                 (unsigned long) eth_read_mib_counter (ethernet_private->
1017                                                       port_num,
1018                                                       ETH_MIB_COLLISION) +
1019                 (unsigned long) eth_read_mib_counter (ethernet_private->
1020                                                       port_num,
1021                                                       ETH_MIB_LATE_COLLISION);
1022         /* detailed rx errors */
1023         stats->rx_length_errors +=
1024                 (unsigned long) eth_read_mib_counter (ethernet_private->
1025                                                       port_num,
1026                                                       ETH_MIB_UNDERSIZE_RECEIVED)
1027                 +
1028                 (unsigned long) eth_read_mib_counter (ethernet_private->
1029                                                       port_num,
1030                                                       ETH_MIB_OVERSIZE_RECEIVED);
1031         /* detailed tx errors */
1032 }
1033
1034 #ifndef  UPDATE_STATS_BY_SOFTWARE
1035 /**********************************************************************
1036  * mv64460_eth_print_stat
1037  *
1038  * Update the statistics structure in the private data structure
1039  *
1040  * Input : pointer to ethernet interface network device structure
1041  * Output : N/A
1042  **********************************************************************/
1043
1044 static void mv64460_eth_print_stat (struct eth_device *dev)
1045 {
1046         ETH_PORT_INFO *ethernet_private;
1047         struct mv64460_eth_priv *port_private;
1048         struct net_device_stats *stats;
1049
1050         ethernet_private = (ETH_PORT_INFO *) dev->priv;
1051         port_private =
1052                 (struct mv64460_eth_priv *) ethernet_private->port_private;
1053         stats = port_private->stats;
1054
1055         /* These are false updates */
1056         printf ("\n### Network statistics: ###\n");
1057         printf ("--------------------------\n");
1058         printf (" Packets received:             %ld\n", stats->rx_packets);
1059         printf (" Packets send:                 %ld\n", stats->tx_packets);
1060         printf (" Received bytes:               %ld\n", stats->rx_bytes);
1061         printf (" Send bytes:                   %ld\n", stats->tx_bytes);
1062         if (stats->rx_errors != 0)
1063                 printf (" Rx Errors:                    %ld\n",
1064                         stats->rx_errors);
1065         if (stats->rx_dropped != 0)
1066                 printf (" Rx dropped (CRC Errors):      %ld\n",
1067                         stats->rx_dropped);
1068         if (stats->multicast != 0)
1069                 printf (" Rx mulicast frames:           %ld\n",
1070                         stats->multicast);
1071         if (stats->collisions != 0)
1072                 printf (" No. of collisions:            %ld\n",
1073                         stats->collisions);
1074         if (stats->rx_length_errors != 0)
1075                 printf (" Rx length errors:             %ld\n",
1076                         stats->rx_length_errors);
1077 }
1078 #endif
1079
1080 /**************************************************************************
1081  *network_start - Network Kick Off Routine UBoot
1082  *Inputs :
1083  *Outputs :
1084  **************************************************************************/
1085
1086 bool db64460_eth_start (struct eth_device *dev)
1087 {
1088         return (mv64460_eth_open (dev));        /* calls real open */
1089 }
1090
1091 /*************************************************************************
1092 **************************************************************************
1093 **************************************************************************
1094 *  The second part is the low level driver of the gigE ethernet ports.   *
1095 **************************************************************************
1096 **************************************************************************
1097 *************************************************************************/
1098 /*
1099  * based on Linux code
1100  * arch/powerpc/galileo/EVB64460/mv64460_eth.c - Driver for MV64460X ethernet ports
1101  * Copyright (C) 2002 rabeeh@galileo.co.il
1102
1103  * SPDX-License-Identifier:     GPL-2.0+
1104  */
1105
1106 /********************************************************************************
1107  * Marvell's Gigabit Ethernet controller low level driver
1108  *
1109  * DESCRIPTION:
1110  *       This file introduce low level API to Marvell's Gigabit Ethernet
1111  *              controller. This Gigabit Ethernet Controller driver API controls
1112  *              1) Operations (i.e. port init, start, reset etc').
1113  *              2) Data flow (i.e. port send, receive etc').
1114  *              Each Gigabit Ethernet port is controlled via ETH_PORT_INFO
1115  *              struct.
1116  *              This struct includes user configuration information as well as
1117  *              driver internal data needed for its operations.
1118  *
1119  *              Supported Features:
1120  *              - This low level driver is OS independent. Allocating memory for
1121  *                the descriptor rings and buffers are not within the scope of
1122  *                this driver.
1123  *              - The user is free from Rx/Tx queue managing.
1124  *              - This low level driver introduce functionality API that enable
1125  *                the to operate Marvell's Gigabit Ethernet Controller in a
1126  *                convenient way.
1127  *              - Simple Gigabit Ethernet port operation API.
1128  *              - Simple Gigabit Ethernet port data flow API.
1129  *              - Data flow and operation API support per queue functionality.
1130  *              - Support cached descriptors for better performance.
1131  *              - Enable access to all four DRAM banks and internal SRAM memory
1132  *                spaces.
1133  *              - PHY access and control API.
1134  *              - Port control register configuration API.
1135  *              - Full control over Unicast and Multicast MAC configurations.
1136  *
1137  *              Operation flow:
1138  *
1139  *              Initialization phase
1140  *              This phase complete the initialization of the ETH_PORT_INFO
1141  *              struct.
1142  *              User information regarding port configuration has to be set
1143  *              prior to calling the port initialization routine. For example,
1144  *              the user has to assign the port_phy_addr field which is board
1145  *              depended parameter.
1146  *              In this phase any port Tx/Rx activity is halted, MIB counters
1147  *              are cleared, PHY address is set according to user parameter and
1148  *              access to DRAM and internal SRAM memory spaces.
1149  *
1150  *              Driver ring initialization
1151  *              Allocating memory for the descriptor rings and buffers is not
1152  *              within the scope of this driver. Thus, the user is required to
1153  *              allocate memory for the descriptors ring and buffers. Those
1154  *              memory parameters are used by the Rx and Tx ring initialization
1155  *              routines in order to curve the descriptor linked list in a form
1156  *              of a ring.
1157  *              Note: Pay special attention to alignment issues when using
1158  *              cached descriptors/buffers. In this phase the driver store
1159  *              information in the ETH_PORT_INFO struct regarding each queue
1160  *              ring.
1161  *
1162  *              Driver start
1163  *              This phase prepares the Ethernet port for Rx and Tx activity.
1164  *              It uses the information stored in the ETH_PORT_INFO struct to
1165  *              initialize the various port registers.
1166  *
1167  *              Data flow:
1168  *              All packet references to/from the driver are done using PKT_INFO
1169  *              struct.
1170  *              This struct is a unified struct used with Rx and Tx operations.
1171  *              This way the user is not required to be familiar with neither
1172  *              Tx nor Rx descriptors structures.
1173  *              The driver's descriptors rings are management by indexes.
1174  *              Those indexes controls the ring resources and used to indicate
1175  *              a SW resource error:
1176  *              'current'
1177  *              This index points to the current available resource for use. For
1178  *              example in Rx process this index will point to the descriptor
1179  *              that will be passed to the user upon calling the receive routine.
1180  *              In Tx process, this index will point to the descriptor
1181  *              that will be assigned with the user packet info and transmitted.
1182  *              'used'
1183  *              This index points to the descriptor that need to restore its
1184  *              resources. For example in Rx process, using the Rx buffer return
1185  *              API will attach the buffer returned in packet info to the
1186  *              descriptor pointed by 'used'. In Tx process, using the Tx
1187  *              descriptor return will merely return the user packet info with
1188  *              the command status of  the transmitted buffer pointed by the
1189  *              'used' index. Nevertheless, it is essential to use this routine
1190  *              to update the 'used' index.
1191  *              'first'
1192  *              This index supports Tx Scatter-Gather. It points to the first
1193  *              descriptor of a packet assembled of multiple buffers. For example
1194  *              when in middle of Such packet we have a Tx resource error the
1195  *              'curr' index get the value of 'first' to indicate that the ring
1196  *              returned to its state before trying to transmit this packet.
1197  *
1198  *              Receive operation:
1199  *              The eth_port_receive API set the packet information struct,
1200  *              passed by the caller, with received information from the
1201  *              'current' SDMA descriptor.
1202  *              It is the user responsibility to return this resource back
1203  *              to the Rx descriptor ring to enable the reuse of this source.
1204  *              Return Rx resource is done using the eth_rx_return_buff API.
1205  *
1206  *              Transmit operation:
1207  *              The eth_port_send API supports Scatter-Gather which enables to
1208  *              send a packet spanned over multiple buffers. This means that
1209  *              for each packet info structure given by the user and put into
1210  *              the Tx descriptors ring, will be transmitted only if the 'LAST'
1211  *              bit will be set in the packet info command status field. This
1212  *              API also consider restriction regarding buffer alignments and
1213  *              sizes.
1214  *              The user must return a Tx resource after ensuring the buffer
1215  *              has been transmitted to enable the Tx ring indexes to update.
1216  *
1217  *              BOARD LAYOUT
1218  *              This device is on-board.  No jumper diagram is necessary.
1219  *
1220  *              EXTERNAL INTERFACE
1221  *
1222  *       Prior to calling the initialization routine eth_port_init() the user
1223  *       must set the following fields under ETH_PORT_INFO struct:
1224  *       port_num             User Ethernet port number.
1225  *       port_phy_addr              User PHY address of Ethernet port.
1226  *       port_mac_addr[6]           User defined port MAC address.
1227  *       port_config          User port configuration value.
1228  *       port_config_extend    User port config extend value.
1229  *       port_sdma_config      User port SDMA config value.
1230  *       port_serial_control   User port serial control value.
1231  *       *port_virt_to_phys ()  User function to cast virtual addr to CPU bus addr.
1232  *       *port_private        User scratch pad for user specific data structures.
1233  *
1234  *       This driver introduce a set of default values:
1235  *       PORT_CONFIG_VALUE           Default port configuration value
1236  *       PORT_CONFIG_EXTEND_VALUE    Default port extend configuration value
1237  *       PORT_SDMA_CONFIG_VALUE      Default sdma control value
1238  *       PORT_SERIAL_CONTROL_VALUE   Default port serial control value
1239  *
1240  *              This driver data flow is done using the PKT_INFO struct which is
1241  *              a unified struct for Rx and Tx operations:
1242  *              byte_cnt        Tx/Rx descriptor buffer byte count.
1243  *              l4i_chk         CPU provided TCP Checksum. For Tx operation only.
1244  *              cmd_sts         Tx/Rx descriptor command status.
1245  *              buf_ptr         Tx/Rx descriptor buffer pointer.
1246  *              return_info     Tx/Rx user resource return information.
1247  *
1248  *
1249  *              EXTERNAL SUPPORT REQUIREMENTS
1250  *
1251  *              This driver requires the following external support:
1252  *
1253  *              D_CACHE_FLUSH_LINE (address, address offset)
1254  *
1255  *              This macro applies assembly code to flush and invalidate cache
1256  *              line.
1257  *              address        - address base.
1258  *              address offset - address offset
1259  *
1260  *
1261  *              CPU_PIPE_FLUSH
1262  *
1263  *              This macro applies assembly code to flush the CPU pipeline.
1264  *
1265  *******************************************************************************/
1266 /* includes */
1267
1268 /* defines */
1269 /* SDMA command macros */
1270 #define ETH_ENABLE_TX_QUEUE(tx_queue, eth_port) \
1271  MV_REG_WRITE(MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG(eth_port), (1 << tx_queue))
1272
1273 #define ETH_DISABLE_TX_QUEUE(tx_queue, eth_port) \
1274  MV_REG_WRITE(MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG(eth_port),\
1275  (1 << (8 + tx_queue)))
1276
1277 #define ETH_ENABLE_RX_QUEUE(rx_queue, eth_port) \
1278 MV_REG_WRITE(MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG(eth_port), (1 << rx_queue))
1279
1280 #define ETH_DISABLE_RX_QUEUE(rx_queue, eth_port) \
1281 MV_REG_WRITE(MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG(eth_port), (1 << (8 + rx_queue)))
1282
1283 #define CURR_RFD_GET(p_curr_desc, queue) \
1284  ((p_curr_desc) = p_eth_port_ctrl->p_rx_curr_desc_q[queue])
1285
1286 #define CURR_RFD_SET(p_curr_desc, queue) \
1287  (p_eth_port_ctrl->p_rx_curr_desc_q[queue] = (p_curr_desc))
1288
1289 #define USED_RFD_GET(p_used_desc, queue) \
1290  ((p_used_desc) = p_eth_port_ctrl->p_rx_used_desc_q[queue])
1291
1292 #define USED_RFD_SET(p_used_desc, queue)\
1293 (p_eth_port_ctrl->p_rx_used_desc_q[queue] = (p_used_desc))
1294
1295
1296 #define CURR_TFD_GET(p_curr_desc, queue) \
1297  ((p_curr_desc) = p_eth_port_ctrl->p_tx_curr_desc_q[queue])
1298
1299 #define CURR_TFD_SET(p_curr_desc, queue) \
1300  (p_eth_port_ctrl->p_tx_curr_desc_q[queue] = (p_curr_desc))
1301
1302 #define USED_TFD_GET(p_used_desc, queue) \
1303  ((p_used_desc) = p_eth_port_ctrl->p_tx_used_desc_q[queue])
1304
1305 #define USED_TFD_SET(p_used_desc, queue) \
1306  (p_eth_port_ctrl->p_tx_used_desc_q[queue] = (p_used_desc))
1307
1308 #define FIRST_TFD_GET(p_first_desc, queue) \
1309  ((p_first_desc) = p_eth_port_ctrl->p_tx_first_desc_q[queue])
1310
1311 #define FIRST_TFD_SET(p_first_desc, queue) \
1312  (p_eth_port_ctrl->p_tx_first_desc_q[queue] = (p_first_desc))
1313
1314
1315 /* Macros that save access to desc in order to find next desc pointer  */
1316 #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])
1317
1318 #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])
1319
1320 #define LINK_UP_TIMEOUT         100000
1321 #define PHY_BUSY_TIMEOUT    10000000
1322
1323 /* locals */
1324
1325 /* PHY routines */
1326 static void ethernet_phy_set (ETH_PORT eth_port_num, int phy_addr);
1327 static int ethernet_phy_get (ETH_PORT eth_port_num);
1328
1329 /* Ethernet Port routines */
1330 static void eth_set_access_control (ETH_PORT eth_port_num,
1331                                     ETH_WIN_PARAM * param);
1332 static bool eth_port_uc_addr (ETH_PORT eth_port_num, unsigned char uc_nibble,
1333                               ETH_QUEUE queue, int option);
1334 #if 0                           /* FIXME */
1335 static bool eth_port_smc_addr (ETH_PORT eth_port_num,
1336                                unsigned char mc_byte,
1337                                ETH_QUEUE queue, int option);
1338 static bool eth_port_omc_addr (ETH_PORT eth_port_num,
1339                                unsigned char crc8,
1340                                ETH_QUEUE queue, int option);
1341 #endif
1342
1343 static void eth_b_copy (unsigned int src_addr, unsigned int dst_addr,
1344                         int byte_count);
1345
1346 void eth_dbg (ETH_PORT_INFO * p_eth_port_ctrl);
1347
1348
1349 typedef enum _memory_bank { BANK0, BANK1, BANK2, BANK3 } MEMORY_BANK;
1350 u32 mv_get_dram_bank_base_addr (MEMORY_BANK bank)
1351 {
1352         u32 result = 0;
1353         u32 enable = MV_REG_READ (MV64460_BASE_ADDR_ENABLE);
1354
1355         if (enable & (1 << bank))
1356                 return 0;
1357         if (bank == BANK0)
1358                 result = MV_REG_READ (MV64460_CS_0_BASE_ADDR);
1359         if (bank == BANK1)
1360                 result = MV_REG_READ (MV64460_CS_1_BASE_ADDR);
1361         if (bank == BANK2)
1362                 result = MV_REG_READ (MV64460_CS_2_BASE_ADDR);
1363         if (bank == BANK3)
1364                 result = MV_REG_READ (MV64460_CS_3_BASE_ADDR);
1365         result &= 0x0000ffff;
1366         result = result << 16;
1367         return result;
1368 }
1369
1370 u32 mv_get_dram_bank_size (MEMORY_BANK bank)
1371 {
1372         u32 result = 0;
1373         u32 enable = MV_REG_READ (MV64460_BASE_ADDR_ENABLE);
1374
1375         if (enable & (1 << bank))
1376                 return 0;
1377         if (bank == BANK0)
1378                 result = MV_REG_READ (MV64460_CS_0_SIZE);
1379         if (bank == BANK1)
1380                 result = MV_REG_READ (MV64460_CS_1_SIZE);
1381         if (bank == BANK2)
1382                 result = MV_REG_READ (MV64460_CS_2_SIZE);
1383         if (bank == BANK3)
1384                 result = MV_REG_READ (MV64460_CS_3_SIZE);
1385         result += 1;
1386         result &= 0x0000ffff;
1387         result = result << 16;
1388         return result;
1389 }
1390
1391 u32 mv_get_internal_sram_base (void)
1392 {
1393         u32 result;
1394
1395         result = MV_REG_READ (MV64460_INTEGRATED_SRAM_BASE_ADDR);
1396         result &= 0x0000ffff;
1397         result = result << 16;
1398         return result;
1399 }
1400
1401 /*******************************************************************************
1402 * eth_port_init - Initialize the Ethernet port driver
1403 *
1404 * DESCRIPTION:
1405 *       This function prepares the ethernet port to start its activity:
1406 *       1) Completes the ethernet port driver struct initialization toward port
1407 *           start routine.
1408 *       2) Resets the device to a quiescent state in case of warm reboot.
1409 *       3) Enable SDMA access to all four DRAM banks as well as internal SRAM.
1410 *       4) Clean MAC tables. The reset status of those tables is unknown.
1411 *       5) Set PHY address.
1412 *       Note: Call this routine prior to eth_port_start routine and after setting
1413 *       user values in the user fields of Ethernet port control struct (i.e.
1414 *       port_phy_addr).
1415 *
1416 * INPUT:
1417 *       ETH_PORT_INFO   *p_eth_port_ctrl       Ethernet port control struct
1418 *
1419 * OUTPUT:
1420 *       See description.
1421 *
1422 * RETURN:
1423 *       None.
1424 *
1425 *******************************************************************************/
1426 static void eth_port_init (ETH_PORT_INFO * p_eth_port_ctrl)
1427 {
1428         int queue;
1429         ETH_WIN_PARAM win_param;
1430
1431         p_eth_port_ctrl->port_config = PORT_CONFIG_VALUE;
1432         p_eth_port_ctrl->port_config_extend = PORT_CONFIG_EXTEND_VALUE;
1433         p_eth_port_ctrl->port_sdma_config = PORT_SDMA_CONFIG_VALUE;
1434         p_eth_port_ctrl->port_serial_control = PORT_SERIAL_CONTROL_VALUE;
1435
1436         p_eth_port_ctrl->port_rx_queue_command = 0;
1437         p_eth_port_ctrl->port_tx_queue_command = 0;
1438
1439         /* Zero out SW structs */
1440         for (queue = 0; queue < MAX_RX_QUEUE_NUM; queue++) {
1441                 CURR_RFD_SET ((ETH_RX_DESC *) 0x00000000, queue);
1442                 USED_RFD_SET ((ETH_RX_DESC *) 0x00000000, queue);
1443                 p_eth_port_ctrl->rx_resource_err[queue] = false;
1444         }
1445
1446         for (queue = 0; queue < MAX_TX_QUEUE_NUM; queue++) {
1447                 CURR_TFD_SET ((ETH_TX_DESC *) 0x00000000, queue);
1448                 USED_TFD_SET ((ETH_TX_DESC *) 0x00000000, queue);
1449                 FIRST_TFD_SET ((ETH_TX_DESC *) 0x00000000, queue);
1450                 p_eth_port_ctrl->tx_resource_err[queue] = false;
1451         }
1452
1453         eth_port_reset (p_eth_port_ctrl->port_num);
1454
1455         /* Set access parameters for DRAM bank 0 */
1456         win_param.win = ETH_WIN0;       /* Use Ethernet window 0 */
1457         win_param.target = ETH_TARGET_DRAM;     /* Window target - DDR  */
1458         win_param.attributes = EBAR_ATTR_DRAM_CS0;      /* Enable DRAM bank   */
1459 #ifndef CONFIG_NOT_COHERENT_CACHE
1460         win_param.attributes |= EBAR_ATTR_DRAM_CACHE_COHERENCY_WB;
1461 #endif
1462         win_param.high_addr = 0;
1463         /* Get bank base */
1464         win_param.base_addr = mv_get_dram_bank_base_addr (BANK0);
1465         win_param.size = mv_get_dram_bank_size (BANK0); /* Get bank size */
1466         if (win_param.size == 0)
1467                 win_param.enable = 0;
1468         else
1469                 win_param.enable = 1;   /* Enable the access */
1470         win_param.access_ctrl = EWIN_ACCESS_FULL;       /* Enable full access */
1471
1472         /* Set the access control for address window (EPAPR) READ & WRITE */
1473         eth_set_access_control (p_eth_port_ctrl->port_num, &win_param);
1474
1475         /* Set access parameters for DRAM bank 1 */
1476         win_param.win = ETH_WIN1;       /* Use Ethernet window 1 */
1477         win_param.target = ETH_TARGET_DRAM;     /* Window target - DDR */
1478         win_param.attributes = EBAR_ATTR_DRAM_CS1;      /* Enable DRAM bank */
1479 #ifndef CONFIG_NOT_COHERENT_CACHE
1480         win_param.attributes |= EBAR_ATTR_DRAM_CACHE_COHERENCY_WB;
1481 #endif
1482         win_param.high_addr = 0;
1483         /* Get bank base */
1484         win_param.base_addr = mv_get_dram_bank_base_addr (BANK1);
1485         win_param.size = mv_get_dram_bank_size (BANK1); /* Get bank size */
1486         if (win_param.size == 0)
1487                 win_param.enable = 0;
1488         else
1489                 win_param.enable = 1;   /* Enable the access */
1490         win_param.access_ctrl = EWIN_ACCESS_FULL;       /* Enable full access */
1491
1492         /* Set the access control for address window (EPAPR) READ & WRITE */
1493         eth_set_access_control (p_eth_port_ctrl->port_num, &win_param);
1494
1495         /* Set access parameters for DRAM bank 2 */
1496         win_param.win = ETH_WIN2;       /* Use Ethernet window 2 */
1497         win_param.target = ETH_TARGET_DRAM;     /* Window target - DDR */
1498         win_param.attributes = EBAR_ATTR_DRAM_CS2;      /* Enable DRAM bank */
1499 #ifndef CONFIG_NOT_COHERENT_CACHE
1500         win_param.attributes |= EBAR_ATTR_DRAM_CACHE_COHERENCY_WB;
1501 #endif
1502         win_param.high_addr = 0;
1503         /* Get bank base */
1504         win_param.base_addr = mv_get_dram_bank_base_addr (BANK2);
1505         win_param.size = mv_get_dram_bank_size (BANK2); /* Get bank size */
1506         if (win_param.size == 0)
1507                 win_param.enable = 0;
1508         else
1509                 win_param.enable = 1;   /* Enable the access */
1510         win_param.access_ctrl = EWIN_ACCESS_FULL;       /* Enable full access */
1511
1512         /* Set the access control for address window (EPAPR) READ & WRITE */
1513         eth_set_access_control (p_eth_port_ctrl->port_num, &win_param);
1514
1515         /* Set access parameters for DRAM bank 3 */
1516         win_param.win = ETH_WIN3;       /* Use Ethernet window 3 */
1517         win_param.target = ETH_TARGET_DRAM;     /* Window target - DDR */
1518         win_param.attributes = EBAR_ATTR_DRAM_CS3;      /* Enable DRAM bank */
1519 #ifndef CONFIG_NOT_COHERENT_CACHE
1520         win_param.attributes |= EBAR_ATTR_DRAM_CACHE_COHERENCY_WB;
1521 #endif
1522         win_param.high_addr = 0;
1523         /* Get bank base */
1524         win_param.base_addr = mv_get_dram_bank_base_addr (BANK3);
1525         win_param.size = mv_get_dram_bank_size (BANK3); /* Get bank size */
1526         if (win_param.size == 0)
1527                 win_param.enable = 0;
1528         else
1529                 win_param.enable = 1;   /* Enable the access */
1530         win_param.access_ctrl = EWIN_ACCESS_FULL;       /* Enable full access */
1531
1532         /* Set the access control for address window (EPAPR) READ & WRITE */
1533         eth_set_access_control (p_eth_port_ctrl->port_num, &win_param);
1534
1535         /* Set access parameters for Internal SRAM */
1536         win_param.win = ETH_WIN4;       /* Use Ethernet window 0 */
1537         win_param.target = EBAR_TARGET_CBS;     /* Target - Internal SRAM */
1538         win_param.attributes = EBAR_ATTR_CBS_SRAM | EBAR_ATTR_CBS_SRAM_BLOCK0;
1539         win_param.high_addr = 0;
1540         win_param.base_addr = mv_get_internal_sram_base ();     /* Get base addr */
1541         win_param.size = MV64460_INTERNAL_SRAM_SIZE;    /* Get bank size */
1542         win_param.enable = 1;   /* Enable the access */
1543         win_param.access_ctrl = EWIN_ACCESS_FULL;       /* Enable full access */
1544
1545         /* Set the access control for address window (EPAPR) READ & WRITE */
1546         eth_set_access_control (p_eth_port_ctrl->port_num, &win_param);
1547
1548         eth_port_init_mac_tables (p_eth_port_ctrl->port_num);
1549
1550         ethernet_phy_set (p_eth_port_ctrl->port_num,
1551                           p_eth_port_ctrl->port_phy_addr);
1552
1553         return;
1554
1555 }
1556
1557 /*******************************************************************************
1558 * eth_port_start - Start the Ethernet port activity.
1559 *
1560 * DESCRIPTION:
1561 *       This routine prepares the Ethernet port for Rx and Tx activity:
1562 *       1. Initialize Tx and Rx Current Descriptor Pointer for each queue that
1563 *           has been initialized a descriptor's ring (using ether_init_tx_desc_ring
1564 *           for Tx and ether_init_rx_desc_ring for Rx)
1565 *       2. Initialize and enable the Ethernet configuration port by writing to
1566 *           the port's configuration and command registers.
1567 *       3. Initialize and enable the SDMA by writing to the SDMA's
1568 *    configuration and command registers.
1569 *       After completing these steps, the ethernet port SDMA can starts to
1570 *       perform Rx and Tx activities.
1571 *
1572 *       Note: Each Rx and Tx queue descriptor's list must be initialized prior
1573 *       to calling this function (use ether_init_tx_desc_ring for Tx queues and
1574 *       ether_init_rx_desc_ring for Rx queues).
1575 *
1576 * INPUT:
1577 *       ETH_PORT_INFO   *p_eth_port_ctrl       Ethernet port control struct
1578 *
1579 * OUTPUT:
1580 *       Ethernet port is ready to receive and transmit.
1581 *
1582 * RETURN:
1583 *       false if the port PHY is not up.
1584 *       true otherwise.
1585 *
1586 *******************************************************************************/
1587 static bool eth_port_start (ETH_PORT_INFO * p_eth_port_ctrl)
1588 {
1589         int queue;
1590         volatile ETH_TX_DESC *p_tx_curr_desc;
1591         volatile ETH_RX_DESC *p_rx_curr_desc;
1592         unsigned int phy_reg_data;
1593         ETH_PORT eth_port_num = p_eth_port_ctrl->port_num;
1594
1595         /* Assignment of Tx CTRP of given queue */
1596         for (queue = 0; queue < MAX_TX_QUEUE_NUM; queue++) {
1597                 CURR_TFD_GET (p_tx_curr_desc, queue);
1598                 MV_REG_WRITE ((MV64460_ETH_TX_CURRENT_QUEUE_DESC_PTR_0
1599                                (eth_port_num)
1600                                + (4 * queue)),
1601                               ((unsigned int) p_tx_curr_desc));
1602
1603         }
1604
1605         /* Assignment of Rx CRDP of given queue */
1606         for (queue = 0; queue < MAX_RX_QUEUE_NUM; queue++) {
1607                 CURR_RFD_GET (p_rx_curr_desc, queue);
1608                 MV_REG_WRITE ((MV64460_ETH_RX_CURRENT_QUEUE_DESC_PTR_0
1609                                (eth_port_num)
1610                                + (4 * queue)),
1611                               ((unsigned int) p_rx_curr_desc));
1612
1613                 if (p_rx_curr_desc != NULL)
1614                         /* Add the assigned Ethernet address to the port's address table */
1615                         eth_port_uc_addr_set (p_eth_port_ctrl->port_num,
1616                                               p_eth_port_ctrl->port_mac_addr,
1617                                               queue);
1618         }
1619
1620         /* Assign port configuration and command. */
1621         MV_REG_WRITE (MV64460_ETH_PORT_CONFIG_REG (eth_port_num),
1622                       p_eth_port_ctrl->port_config);
1623
1624         MV_REG_WRITE (MV64460_ETH_PORT_CONFIG_EXTEND_REG (eth_port_num),
1625                       p_eth_port_ctrl->port_config_extend);
1626
1627         MV_REG_WRITE (MV64460_ETH_PORT_SERIAL_CONTROL_REG (eth_port_num),
1628                       p_eth_port_ctrl->port_serial_control);
1629
1630         MV_SET_REG_BITS (MV64460_ETH_PORT_SERIAL_CONTROL_REG (eth_port_num),
1631                          ETH_SERIAL_PORT_ENABLE);
1632
1633         /* Assign port SDMA configuration */
1634         MV_REG_WRITE (MV64460_ETH_SDMA_CONFIG_REG (eth_port_num),
1635                       p_eth_port_ctrl->port_sdma_config);
1636
1637         MV_REG_WRITE (MV64460_ETH_TX_QUEUE_0_TOKEN_BUCKET_COUNT
1638                       (eth_port_num), 0x3fffffff);
1639         MV_REG_WRITE (MV64460_ETH_TX_QUEUE_0_TOKEN_BUCKET_CONFIG
1640                       (eth_port_num), 0x03fffcff);
1641         /* Turn off the port/queue bandwidth limitation */
1642         MV_REG_WRITE (MV64460_ETH_MAXIMUM_TRANSMIT_UNIT (eth_port_num), 0x0);
1643
1644         /* Enable port Rx. */
1645         MV_REG_WRITE (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG (eth_port_num),
1646                       p_eth_port_ctrl->port_rx_queue_command);
1647
1648         /* Check if link is up */
1649         eth_port_read_smi_reg (eth_port_num, 1, &phy_reg_data);
1650
1651         if (!(phy_reg_data & 0x20))
1652                 return false;
1653
1654         return true;
1655 }
1656
1657 /*******************************************************************************
1658 * eth_port_uc_addr_set - This function Set the port Unicast address.
1659 *
1660 * DESCRIPTION:
1661 *               This function Set the port Ethernet MAC address.
1662 *
1663 * INPUT:
1664 *       ETH_PORT eth_port_num     Port number.
1665 *       char *        p_addr            Address to be set
1666 *       ETH_QUEUE         queue         Rx queue number for this MAC address.
1667 *
1668 * OUTPUT:
1669 *       Set MAC address low and high registers. also calls eth_port_uc_addr()
1670 *       To set the unicast table with the proper information.
1671 *
1672 * RETURN:
1673 *       N/A.
1674 *
1675 *******************************************************************************/
1676 static void eth_port_uc_addr_set (ETH_PORT eth_port_num,
1677                                   unsigned char *p_addr, ETH_QUEUE queue)
1678 {
1679         unsigned int mac_h;
1680         unsigned int mac_l;
1681
1682         mac_l = (p_addr[4] << 8) | (p_addr[5]);
1683         mac_h = (p_addr[0] << 24) | (p_addr[1] << 16) |
1684                 (p_addr[2] << 8) | (p_addr[3] << 0);
1685
1686         MV_REG_WRITE (MV64460_ETH_MAC_ADDR_LOW (eth_port_num), mac_l);
1687         MV_REG_WRITE (MV64460_ETH_MAC_ADDR_HIGH (eth_port_num), mac_h);
1688
1689         /* Accept frames of this address */
1690         eth_port_uc_addr (eth_port_num, p_addr[5], queue, ACCEPT_MAC_ADDR);
1691
1692         return;
1693 }
1694
1695 /*******************************************************************************
1696 * eth_port_uc_addr - This function Set the port unicast address table
1697 *
1698 * DESCRIPTION:
1699 *       This function locates the proper entry in the Unicast table for the
1700 *       specified MAC nibble and sets its properties according to function
1701 *       parameters.
1702 *
1703 * INPUT:
1704 *       ETH_PORT        eth_port_num      Port number.
1705 *       unsigned char uc_nibble         Unicast MAC Address last nibble.
1706 *       ETH_QUEUE                queue          Rx queue number for this MAC address.
1707 *       int                     option      0 = Add, 1 = remove address.
1708 *
1709 * OUTPUT:
1710 *       This function add/removes MAC addresses from the port unicast address
1711 *       table.
1712 *
1713 * RETURN:
1714 *       true is output succeeded.
1715 *       false if option parameter is invalid.
1716 *
1717 *******************************************************************************/
1718 static bool eth_port_uc_addr (ETH_PORT eth_port_num,
1719                               unsigned char uc_nibble,
1720                               ETH_QUEUE queue, int option)
1721 {
1722         unsigned int unicast_reg;
1723         unsigned int tbl_offset;
1724         unsigned int reg_offset;
1725
1726         /* Locate the Unicast table entry */
1727         uc_nibble = (0xf & uc_nibble);
1728         tbl_offset = (uc_nibble / 4) * 4;       /* Register offset from unicast table base */
1729         reg_offset = uc_nibble % 4;     /* Entry offset within the above register */
1730
1731         switch (option) {
1732         case REJECT_MAC_ADDR:
1733                 /* Clear accepts frame bit at specified unicast DA table entry */
1734                 unicast_reg =
1735                         MV_REG_READ ((MV64460_ETH_DA_FILTER_UNICAST_TABLE_BASE
1736                                       (eth_port_num)
1737                                       + tbl_offset));
1738
1739                 unicast_reg &= (0x0E << (8 * reg_offset));
1740
1741                 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_UNICAST_TABLE_BASE
1742                                (eth_port_num)
1743                                + tbl_offset), unicast_reg);
1744                 break;
1745
1746         case ACCEPT_MAC_ADDR:
1747                 /* Set accepts frame bit at unicast DA filter table entry */
1748                 unicast_reg =
1749                         MV_REG_READ ((MV64460_ETH_DA_FILTER_UNICAST_TABLE_BASE
1750                                       (eth_port_num)
1751                                       + tbl_offset));
1752
1753                 unicast_reg |= ((0x01 | queue) << (8 * reg_offset));
1754
1755                 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_UNICAST_TABLE_BASE
1756                                (eth_port_num)
1757                                + tbl_offset), unicast_reg);
1758
1759                 break;
1760
1761         default:
1762                 return false;
1763         }
1764         return true;
1765 }
1766
1767 #if 0                           /* FIXME */
1768 /*******************************************************************************
1769 * eth_port_mc_addr - Multicast address settings.
1770 *
1771 * DESCRIPTION:
1772 *       This API controls the MV device MAC multicast support.
1773 *       The MV device supports multicast using two tables:
1774 *       1) Special Multicast Table for MAC addresses of the form
1775 *          0x01-00-5E-00-00-XX (where XX is between 0x00 and 0x_fF).
1776 *          The MAC DA[7:0] bits are used as a pointer to the Special Multicast
1777 *          Table entries in the DA-Filter table.
1778 *          In this case, the function calls eth_port_smc_addr() routine to set the
1779 *          Special Multicast Table.
1780 *       2) Other Multicast Table for multicast of another type. A CRC-8bit
1781 *          is used as an index to the Other Multicast Table entries in the
1782 *          DA-Filter table.
1783 *          In this case, the function calculates the CRC-8bit value and calls
1784 *          eth_port_omc_addr() routine to set the Other Multicast Table.
1785 * INPUT:
1786 *       ETH_PORT        eth_port_num      Port number.
1787 *       unsigned char   *p_addr         Unicast MAC Address.
1788 *       ETH_QUEUE                queue          Rx queue number for this MAC address.
1789 *       int                     option      0 = Add, 1 = remove address.
1790 *
1791 * OUTPUT:
1792 *       See description.
1793 *
1794 * RETURN:
1795 *       true is output succeeded.
1796 *       false if add_address_table_entry( ) failed.
1797 *
1798 *******************************************************************************/
1799 static void eth_port_mc_addr (ETH_PORT eth_port_num,
1800                               unsigned char *p_addr,
1801                               ETH_QUEUE queue, int option)
1802 {
1803         unsigned int mac_h;
1804         unsigned int mac_l;
1805         unsigned char crc_result = 0;
1806         int mac_array[48];
1807         int crc[8];
1808         int i;
1809
1810         if ((p_addr[0] == 0x01) &&
1811             (p_addr[1] == 0x00) &&
1812             (p_addr[2] == 0x5E) && (p_addr[3] == 0x00) && (p_addr[4] == 0x00)) {
1813
1814                 eth_port_smc_addr (eth_port_num, p_addr[5], queue, option);
1815         } else {
1816                 /* Calculate CRC-8 out of the given address */
1817                 mac_h = (p_addr[0] << 8) | (p_addr[1]);
1818                 mac_l = (p_addr[2] << 24) | (p_addr[3] << 16) |
1819                         (p_addr[4] << 8) | (p_addr[5] << 0);
1820
1821                 for (i = 0; i < 32; i++)
1822                         mac_array[i] = (mac_l >> i) & 0x1;
1823                 for (i = 32; i < 48; i++)
1824                         mac_array[i] = (mac_h >> (i - 32)) & 0x1;
1825
1826                 crc[0] = mac_array[45] ^ mac_array[43] ^ mac_array[40] ^
1827                         mac_array[39] ^ mac_array[35] ^ mac_array[34] ^
1828                         mac_array[31] ^ mac_array[30] ^ mac_array[28] ^
1829                         mac_array[23] ^ mac_array[21] ^ mac_array[19] ^
1830                         mac_array[18] ^ mac_array[16] ^ mac_array[14] ^
1831                         mac_array[12] ^ mac_array[8] ^ mac_array[7] ^
1832                         mac_array[6] ^ mac_array[0];
1833
1834                 crc[1] = mac_array[46] ^ mac_array[45] ^ mac_array[44] ^
1835                         mac_array[43] ^ mac_array[41] ^ mac_array[39] ^
1836                         mac_array[36] ^ mac_array[34] ^ mac_array[32] ^
1837                         mac_array[30] ^ mac_array[29] ^ mac_array[28] ^
1838                         mac_array[24] ^ mac_array[23] ^ mac_array[22] ^
1839                         mac_array[21] ^ mac_array[20] ^ mac_array[18] ^
1840                         mac_array[17] ^ mac_array[16] ^ mac_array[15] ^
1841                         mac_array[14] ^ mac_array[13] ^ mac_array[12] ^
1842                         mac_array[9] ^ mac_array[6] ^ mac_array[1] ^
1843                         mac_array[0];
1844
1845                 crc[2] = mac_array[47] ^ mac_array[46] ^ mac_array[44] ^
1846                         mac_array[43] ^ mac_array[42] ^ mac_array[39] ^
1847                         mac_array[37] ^ mac_array[34] ^ mac_array[33] ^
1848                         mac_array[29] ^ mac_array[28] ^ mac_array[25] ^
1849                         mac_array[24] ^ mac_array[22] ^ mac_array[17] ^
1850                         mac_array[15] ^ mac_array[13] ^ mac_array[12] ^
1851                         mac_array[10] ^ mac_array[8] ^ mac_array[6] ^
1852                         mac_array[2] ^ mac_array[1] ^ mac_array[0];
1853
1854                 crc[3] = mac_array[47] ^ mac_array[45] ^ mac_array[44] ^
1855                         mac_array[43] ^ mac_array[40] ^ mac_array[38] ^
1856                         mac_array[35] ^ mac_array[34] ^ mac_array[30] ^
1857                         mac_array[29] ^ mac_array[26] ^ mac_array[25] ^
1858                         mac_array[23] ^ mac_array[18] ^ mac_array[16] ^
1859                         mac_array[14] ^ mac_array[13] ^ mac_array[11] ^
1860                         mac_array[9] ^ mac_array[7] ^ mac_array[3] ^
1861                         mac_array[2] ^ mac_array[1];
1862
1863                 crc[4] = mac_array[46] ^ mac_array[45] ^ mac_array[44] ^
1864                         mac_array[41] ^ mac_array[39] ^ mac_array[36] ^
1865                         mac_array[35] ^ mac_array[31] ^ mac_array[30] ^
1866                         mac_array[27] ^ mac_array[26] ^ mac_array[24] ^
1867                         mac_array[19] ^ mac_array[17] ^ mac_array[15] ^
1868                         mac_array[14] ^ mac_array[12] ^ mac_array[10] ^
1869                         mac_array[8] ^ mac_array[4] ^ mac_array[3] ^
1870                         mac_array[2];
1871
1872                 crc[5] = mac_array[47] ^ mac_array[46] ^ mac_array[45] ^
1873                         mac_array[42] ^ mac_array[40] ^ mac_array[37] ^
1874                         mac_array[36] ^ mac_array[32] ^ mac_array[31] ^
1875                         mac_array[28] ^ mac_array[27] ^ mac_array[25] ^
1876                         mac_array[20] ^ mac_array[18] ^ mac_array[16] ^
1877                         mac_array[15] ^ mac_array[13] ^ mac_array[11] ^
1878                         mac_array[9] ^ mac_array[5] ^ mac_array[4] ^
1879                         mac_array[3];
1880
1881                 crc[6] = mac_array[47] ^ mac_array[46] ^ mac_array[43] ^
1882                         mac_array[41] ^ mac_array[38] ^ mac_array[37] ^
1883                         mac_array[33] ^ mac_array[32] ^ mac_array[29] ^
1884                         mac_array[28] ^ mac_array[26] ^ mac_array[21] ^
1885                         mac_array[19] ^ mac_array[17] ^ mac_array[16] ^
1886                         mac_array[14] ^ mac_array[12] ^ mac_array[10] ^
1887                         mac_array[6] ^ mac_array[5] ^ mac_array[4];
1888
1889                 crc[7] = mac_array[47] ^ mac_array[44] ^ mac_array[42] ^
1890                         mac_array[39] ^ mac_array[38] ^ mac_array[34] ^
1891                         mac_array[33] ^ mac_array[30] ^ mac_array[29] ^
1892                         mac_array[27] ^ mac_array[22] ^ mac_array[20] ^
1893                         mac_array[18] ^ mac_array[17] ^ mac_array[15] ^
1894                         mac_array[13] ^ mac_array[11] ^ mac_array[7] ^
1895                         mac_array[6] ^ mac_array[5];
1896
1897                 for (i = 0; i < 8; i++)
1898                         crc_result = crc_result | (crc[i] << i);
1899
1900                 eth_port_omc_addr (eth_port_num, crc_result, queue, option);
1901         }
1902         return;
1903 }
1904
1905 /*******************************************************************************
1906 * eth_port_smc_addr - Special Multicast address settings.
1907 *
1908 * DESCRIPTION:
1909 *       This routine controls the MV device special MAC multicast support.
1910 *       The Special Multicast Table for MAC addresses supports MAC of the form
1911 *       0x01-00-5E-00-00-XX (where XX is between 0x00 and 0x_fF).
1912 *       The MAC DA[7:0] bits are used as a pointer to the Special Multicast
1913 *       Table entries in the DA-Filter table.
1914 *       This function set the Special Multicast Table appropriate entry
1915 *       according to the argument given.
1916 *
1917 * INPUT:
1918 *       ETH_PORT        eth_port_num      Port number.
1919 *       unsigned char   mc_byte         Multicast addr last byte (MAC DA[7:0] bits).
1920 *       ETH_QUEUE                queue          Rx queue number for this MAC address.
1921 *       int                     option      0 = Add, 1 = remove address.
1922 *
1923 * OUTPUT:
1924 *       See description.
1925 *
1926 * RETURN:
1927 *       true is output succeeded.
1928 *       false if option parameter is invalid.
1929 *
1930 *******************************************************************************/
1931 static bool eth_port_smc_addr (ETH_PORT eth_port_num,
1932                                unsigned char mc_byte,
1933                                ETH_QUEUE queue, int option)
1934 {
1935         unsigned int smc_table_reg;
1936         unsigned int tbl_offset;
1937         unsigned int reg_offset;
1938
1939         /* Locate the SMC table entry */
1940         tbl_offset = (mc_byte / 4) * 4; /* Register offset from SMC table base */
1941         reg_offset = mc_byte % 4;       /* Entry offset within the above register */
1942         queue &= 0x7;
1943
1944         switch (option) {
1945         case REJECT_MAC_ADDR:
1946                 /* Clear accepts frame bit at specified Special DA table entry */
1947                 smc_table_reg =
1948                         MV_REG_READ ((MV64460_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset));
1949                 smc_table_reg &= (0x0E << (8 * reg_offset));
1950
1951                 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset), smc_table_reg);
1952                 break;
1953
1954         case ACCEPT_MAC_ADDR:
1955                 /* Set accepts frame bit at specified Special DA table entry */
1956                 smc_table_reg =
1957                         MV_REG_READ ((MV64460_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset));
1958                 smc_table_reg |= ((0x01 | queue) << (8 * reg_offset));
1959
1960                 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset), smc_table_reg);
1961                 break;
1962
1963         default:
1964                 return false;
1965         }
1966         return true;
1967 }
1968
1969 /*******************************************************************************
1970 * eth_port_omc_addr - Multicast address settings.
1971 *
1972 * DESCRIPTION:
1973 *       This routine controls the MV device Other MAC multicast support.
1974 *       The Other Multicast Table is used for multicast of another type.
1975 *       A CRC-8bit is used as an index to the Other Multicast Table entries
1976 *       in the DA-Filter table.
1977 *       The function gets the CRC-8bit value from the calling routine and
1978 *      set the Other Multicast Table appropriate entry according to the
1979 *       CRC-8 argument given.
1980 *
1981 * INPUT:
1982 *       ETH_PORT        eth_port_num      Port number.
1983 *       unsigned char     crc8          A CRC-8bit (Polynomial: x^8+x^2+x^1+1).
1984 *       ETH_QUEUE                queue          Rx queue number for this MAC address.
1985 *       int                     option      0 = Add, 1 = remove address.
1986 *
1987 * OUTPUT:
1988 *       See description.
1989 *
1990 * RETURN:
1991 *       true is output succeeded.
1992 *       false if option parameter is invalid.
1993 *
1994 *******************************************************************************/
1995 static bool eth_port_omc_addr (ETH_PORT eth_port_num,
1996                                unsigned char crc8,
1997                                ETH_QUEUE queue, int option)
1998 {
1999         unsigned int omc_table_reg;
2000         unsigned int tbl_offset;
2001         unsigned int reg_offset;
2002
2003         /* Locate the OMC table entry */
2004         tbl_offset = (crc8 / 4) * 4;    /* Register offset from OMC table base */
2005         reg_offset = crc8 % 4;  /* Entry offset within the above register */
2006         queue &= 0x7;
2007
2008         switch (option) {
2009         case REJECT_MAC_ADDR:
2010                 /* Clear accepts frame bit at specified Other DA table entry */
2011                 omc_table_reg =
2012                         MV_REG_READ ((MV64460_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset));
2013                 omc_table_reg &= (0x0E << (8 * reg_offset));
2014
2015                 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset), omc_table_reg);
2016                 break;
2017
2018         case ACCEPT_MAC_ADDR:
2019                 /* Set accepts frame bit at specified Other DA table entry */
2020                 omc_table_reg =
2021                         MV_REG_READ ((MV64460_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset));
2022                 omc_table_reg |= ((0x01 | queue) << (8 * reg_offset));
2023
2024                 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset), omc_table_reg);
2025                 break;
2026
2027         default:
2028                 return false;
2029         }
2030         return true;
2031 }
2032 #endif
2033
2034 /*******************************************************************************
2035 * eth_port_init_mac_tables - Clear all entrance in the UC, SMC and OMC tables
2036 *
2037 * DESCRIPTION:
2038 *       Go through all the DA filter tables (Unicast, Special Multicast & Other
2039 *       Multicast) and set each entry to 0.
2040 *
2041 * INPUT:
2042 *       ETH_PORT    eth_port_num   Ethernet Port number. See ETH_PORT enum.
2043 *
2044 * OUTPUT:
2045 *       Multicast and Unicast packets are rejected.
2046 *
2047 * RETURN:
2048 *       None.
2049 *
2050 *******************************************************************************/
2051 static void eth_port_init_mac_tables (ETH_PORT eth_port_num)
2052 {
2053         int table_index;
2054
2055         /* Clear DA filter unicast table (Ex_dFUT) */
2056         for (table_index = 0; table_index <= 0xC; table_index += 4)
2057                 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_UNICAST_TABLE_BASE
2058                                (eth_port_num) + table_index), 0);
2059
2060         for (table_index = 0; table_index <= 0xFC; table_index += 4) {
2061                 /* Clear DA filter special multicast table (Ex_dFSMT) */
2062                 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE (eth_port_num) + table_index), 0);
2063                 /* Clear DA filter other multicast table (Ex_dFOMT) */
2064                 MV_REG_WRITE ((MV64460_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE (eth_port_num) + table_index), 0);
2065         }
2066 }
2067
2068 /*******************************************************************************
2069 * eth_clear_mib_counters - Clear all MIB counters
2070 *
2071 * DESCRIPTION:
2072 *       This function clears all MIB counters of a specific ethernet port.
2073 *       A read from the MIB counter will reset the counter.
2074 *
2075 * INPUT:
2076 *       ETH_PORT    eth_port_num   Ethernet Port number. See ETH_PORT enum.
2077 *
2078 * OUTPUT:
2079 *       After reading all MIB counters, the counters resets.
2080 *
2081 * RETURN:
2082 *       MIB counter value.
2083 *
2084 *******************************************************************************/
2085 static void eth_clear_mib_counters (ETH_PORT eth_port_num)
2086 {
2087         int i;
2088
2089         /* Perform dummy reads from MIB counters */
2090         for (i = ETH_MIB_GOOD_OCTETS_RECEIVED_LOW; i < ETH_MIB_LATE_COLLISION;
2091              i += 4) {
2092                 (void)MV_REG_READ ((MV64460_ETH_MIB_COUNTERS_BASE
2093                                       (eth_port_num) + i));
2094         }
2095
2096         return;
2097 }
2098
2099 /*******************************************************************************
2100 * eth_read_mib_counter - Read a MIB counter
2101 *
2102 * DESCRIPTION:
2103 *       This function reads a MIB counter of a specific ethernet port.
2104 *       NOTE - If read from ETH_MIB_GOOD_OCTETS_RECEIVED_LOW, then the
2105 *       following read must be from ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH
2106 *       register. The same applies for ETH_MIB_GOOD_OCTETS_SENT_LOW and
2107 *       ETH_MIB_GOOD_OCTETS_SENT_HIGH
2108 *
2109 * INPUT:
2110 *       ETH_PORT    eth_port_num   Ethernet Port number. See ETH_PORT enum.
2111 *       unsigned int mib_offset   MIB counter offset (use ETH_MIB_... macros).
2112 *
2113 * OUTPUT:
2114 *       After reading the MIB counter, the counter resets.
2115 *
2116 * RETURN:
2117 *       MIB counter value.
2118 *
2119 *******************************************************************************/
2120 unsigned int eth_read_mib_counter (ETH_PORT eth_port_num,
2121                                    unsigned int mib_offset)
2122 {
2123         return (MV_REG_READ (MV64460_ETH_MIB_COUNTERS_BASE (eth_port_num)
2124                              + mib_offset));
2125 }
2126
2127 /*******************************************************************************
2128 * ethernet_phy_set - Set the ethernet port PHY address.
2129 *
2130 * DESCRIPTION:
2131 *       This routine set the ethernet port PHY address according to given
2132 *       parameter.
2133 *
2134 * INPUT:
2135 *               ETH_PORT   eth_port_num   Ethernet Port number. See ETH_PORT enum.
2136 *
2137 * OUTPUT:
2138 *       Set PHY Address Register with given PHY address parameter.
2139 *
2140 * RETURN:
2141 *       None.
2142 *
2143 *******************************************************************************/
2144 static void ethernet_phy_set (ETH_PORT eth_port_num, int phy_addr)
2145 {
2146         unsigned int reg_data;
2147
2148         reg_data = MV_REG_READ (MV64460_ETH_PHY_ADDR_REG);
2149
2150         reg_data &= ~(0x1F << (5 * eth_port_num));
2151         reg_data |= (phy_addr << (5 * eth_port_num));
2152
2153         MV_REG_WRITE (MV64460_ETH_PHY_ADDR_REG, reg_data);
2154
2155         return;
2156 }
2157
2158 /*******************************************************************************
2159  * ethernet_phy_get - Get the ethernet port PHY address.
2160  *
2161  * DESCRIPTION:
2162  *       This routine returns the given ethernet port PHY address.
2163  *
2164  * INPUT:
2165  *              ETH_PORT   eth_port_num   Ethernet Port number. See ETH_PORT enum.
2166  *
2167  * OUTPUT:
2168  *       None.
2169  *
2170  * RETURN:
2171  *       PHY address.
2172  *
2173  *******************************************************************************/
2174 static int ethernet_phy_get (ETH_PORT eth_port_num)
2175 {
2176         unsigned int reg_data;
2177
2178         reg_data = MV_REG_READ (MV64460_ETH_PHY_ADDR_REG);
2179
2180         return ((reg_data >> (5 * eth_port_num)) & 0x1f);
2181 }
2182
2183 /***********************************************************/
2184 /* (Re)start autonegotiation                               */
2185 /***********************************************************/
2186 int phy_setup_aneg (char *devname, unsigned char addr)
2187 {
2188         unsigned short ctl, adv;
2189
2190         /* Setup standard advertise */
2191         miiphy_read (devname, addr, MII_ADVERTISE, &adv);
2192         adv |= (LPA_LPACK | LPA_RFAULT | LPA_100BASE4 |
2193                 LPA_100FULL | LPA_100HALF | LPA_10FULL |
2194                 LPA_10HALF);
2195         miiphy_write (devname, addr, MII_ADVERTISE, adv);
2196
2197         miiphy_read (devname, addr, MII_CTRL1000, &adv);
2198         adv |= (0x0300);
2199         miiphy_write (devname, addr, MII_CTRL1000, adv);
2200
2201         /* Start/Restart aneg */
2202         miiphy_read (devname, addr, MII_BMCR, &ctl);
2203         ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
2204         miiphy_write (devname, addr, MII_BMCR, ctl);
2205
2206         return 0;
2207 }
2208
2209 /*******************************************************************************
2210  * ethernet_phy_reset - Reset Ethernet port PHY.
2211  *
2212  * DESCRIPTION:
2213  *       This routine utilize the SMI interface to reset the ethernet port PHY.
2214  *       The routine waits until the link is up again or link up is timeout.
2215  *
2216  * INPUT:
2217  *      ETH_PORT   eth_port_num   Ethernet Port number. See ETH_PORT enum.
2218  *
2219  * OUTPUT:
2220  *       The ethernet port PHY renew its link.
2221  *
2222  * RETURN:
2223  *       None.
2224  *
2225  *******************************************************************************/
2226 static bool ethernet_phy_reset (ETH_PORT eth_port_num)
2227 {
2228         unsigned int time_out = 50;
2229         unsigned int phy_reg_data;
2230
2231         eth_port_read_smi_reg (eth_port_num, 20, &phy_reg_data);
2232         phy_reg_data |= 0x0083; /* Set bit 7 to 1 for different RGMII timing */
2233         eth_port_write_smi_reg (eth_port_num, 20, phy_reg_data);
2234
2235         /* Reset the PHY */
2236         eth_port_read_smi_reg (eth_port_num, 0, &phy_reg_data);
2237         phy_reg_data |= 0x8000; /* Set bit 15 to reset the PHY */
2238         eth_port_write_smi_reg (eth_port_num, 0, phy_reg_data);
2239
2240         /* Poll on the PHY LINK */
2241         do {
2242                 eth_port_read_smi_reg (eth_port_num, 1, &phy_reg_data);
2243
2244                 if (time_out-- == 0)
2245                         return false;
2246         }
2247         while (!(phy_reg_data & 0x20));
2248
2249         return true;
2250 }
2251
2252 /*******************************************************************************
2253  * eth_port_reset - Reset Ethernet port
2254  *
2255  * DESCRIPTION:
2256  *      This routine resets the chip by aborting any SDMA engine activity and
2257  *      clearing the MIB counters. The Receiver and the Transmit unit are in
2258  *      idle state after this command is performed and the port is disabled.
2259  *
2260  * INPUT:
2261  *      ETH_PORT   eth_port_num   Ethernet Port number. See ETH_PORT enum.
2262  *
2263  * OUTPUT:
2264  *       Channel activity is halted.
2265  *
2266  * RETURN:
2267  *       None.
2268  *
2269  *******************************************************************************/
2270 static void eth_port_reset (ETH_PORT eth_port_num)
2271 {
2272         unsigned int reg_data;
2273
2274         /* Stop Tx port activity. Check port Tx activity. */
2275         reg_data =
2276                 MV_REG_READ (MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG
2277                              (eth_port_num));
2278
2279         if (reg_data & 0xFF) {
2280                 /* Issue stop command for active channels only */
2281                 MV_REG_WRITE (MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG
2282                               (eth_port_num), (reg_data << 8));
2283
2284                 /* Wait for all Tx activity to terminate. */
2285                 do {
2286                         /* Check port cause register that all Tx queues are stopped */
2287                         reg_data =
2288                                 MV_REG_READ
2289                                 (MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG
2290                                  (eth_port_num));
2291                 }
2292                 while (reg_data & 0xFF);
2293         }
2294
2295         /* Stop Rx port activity. Check port Rx activity. */
2296         reg_data =
2297                 MV_REG_READ (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG
2298                              (eth_port_num));
2299
2300         if (reg_data & 0xFF) {
2301                 /* Issue stop command for active channels only */
2302                 MV_REG_WRITE (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG
2303                               (eth_port_num), (reg_data << 8));
2304
2305                 /* Wait for all Rx activity to terminate. */
2306                 do {
2307                         /* Check port cause register that all Rx queues are stopped */
2308                         reg_data =
2309                                 MV_REG_READ
2310                                 (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG
2311                                  (eth_port_num));
2312                 }
2313                 while (reg_data & 0xFF);
2314         }
2315
2316         /* Clear all MIB counters */
2317         eth_clear_mib_counters (eth_port_num);
2318
2319         /* Reset the Enable bit in the Configuration Register */
2320         reg_data =
2321                 MV_REG_READ (MV64460_ETH_PORT_SERIAL_CONTROL_REG
2322                              (eth_port_num));
2323         reg_data &= ~ETH_SERIAL_PORT_ENABLE;
2324         MV_REG_WRITE (MV64460_ETH_PORT_SERIAL_CONTROL_REG (eth_port_num),
2325                       reg_data);
2326
2327         return;
2328 }
2329
2330 #if 0                           /* Not needed here */
2331 /*******************************************************************************
2332  * ethernet_set_config_reg - Set specified bits in configuration register.
2333  *
2334  * DESCRIPTION:
2335  *       This function sets specified bits in the given ethernet
2336  *       configuration register.
2337  *
2338  * INPUT:
2339  *      ETH_PORT   eth_port_num   Ethernet Port number. See ETH_PORT enum.
2340  *      unsigned int    value   32 bit value.
2341  *
2342  * OUTPUT:
2343  *      The set bits in the value parameter are set in the configuration
2344  *      register.
2345  *
2346  * RETURN:
2347  *      None.
2348  *
2349  *******************************************************************************/
2350 static void ethernet_set_config_reg (ETH_PORT eth_port_num,
2351                                      unsigned int value)
2352 {
2353         unsigned int eth_config_reg;
2354
2355         eth_config_reg =
2356                 MV_REG_READ (MV64460_ETH_PORT_CONFIG_REG (eth_port_num));
2357         eth_config_reg |= value;
2358         MV_REG_WRITE (MV64460_ETH_PORT_CONFIG_REG (eth_port_num),
2359                       eth_config_reg);
2360
2361         return;
2362 }
2363 #endif
2364
2365 #if 0                           /* FIXME */
2366 /*******************************************************************************
2367  * ethernet_reset_config_reg - Reset specified bits in configuration register.
2368  *
2369  * DESCRIPTION:
2370  *       This function resets specified bits in the given Ethernet
2371  *       configuration register.
2372  *
2373  * INPUT:
2374  *      ETH_PORT   eth_port_num   Ethernet Port number. See ETH_PORT enum.
2375  *      unsigned int    value   32 bit value.
2376  *
2377  * OUTPUT:
2378  *      The set bits in the value parameter are reset in the configuration
2379  *      register.
2380  *
2381  * RETURN:
2382  *      None.
2383  *
2384  *******************************************************************************/
2385 static void ethernet_reset_config_reg (ETH_PORT eth_port_num,
2386                                        unsigned int value)
2387 {
2388         unsigned int eth_config_reg;
2389
2390         eth_config_reg = MV_REG_READ (MV64460_ETH_PORT_CONFIG_EXTEND_REG
2391                                       (eth_port_num));
2392         eth_config_reg &= ~value;
2393         MV_REG_WRITE (MV64460_ETH_PORT_CONFIG_EXTEND_REG (eth_port_num),
2394                       eth_config_reg);
2395
2396         return;
2397 }
2398 #endif
2399
2400 #if 0                           /* Not needed here */
2401 /*******************************************************************************
2402  * ethernet_get_config_reg - Get the port configuration register
2403  *
2404  * DESCRIPTION:
2405  *       This function returns the configuration register value of the given
2406  *       ethernet port.
2407  *
2408  * INPUT:
2409  *      ETH_PORT   eth_port_num   Ethernet Port number. See ETH_PORT enum.
2410  *
2411  * OUTPUT:
2412  *       None.
2413  *
2414  * RETURN:
2415  *       Port configuration register value.
2416  *
2417  *******************************************************************************/
2418 static unsigned int ethernet_get_config_reg (ETH_PORT eth_port_num)
2419 {
2420         unsigned int eth_config_reg;
2421
2422         eth_config_reg = MV_REG_READ (MV64460_ETH_PORT_CONFIG_EXTEND_REG
2423                                       (eth_port_num));
2424         return eth_config_reg;
2425 }
2426
2427 #endif
2428
2429 /*******************************************************************************
2430  * eth_port_read_smi_reg - Read PHY registers
2431  *
2432  * DESCRIPTION:
2433  *       This routine utilize the SMI interface to interact with the PHY in
2434  *       order to perform PHY register read.
2435  *
2436  * INPUT:
2437  *      ETH_PORT   eth_port_num   Ethernet Port number. See ETH_PORT enum.
2438  *       unsigned int   phy_reg   PHY register address offset.
2439  *       unsigned int   *value   Register value buffer.
2440  *
2441  * OUTPUT:
2442  *       Write the value of a specified PHY register into given buffer.
2443  *
2444  * RETURN:
2445  *       false if the PHY is busy or read data is not in valid state.
2446  *       true otherwise.
2447  *
2448  *******************************************************************************/
2449 static bool eth_port_read_smi_reg (ETH_PORT eth_port_num,
2450                                    unsigned int phy_reg, unsigned int *value)
2451 {
2452         unsigned int reg_value;
2453         unsigned int time_out = PHY_BUSY_TIMEOUT;
2454         int phy_addr;
2455
2456         phy_addr = ethernet_phy_get (eth_port_num);
2457
2458         /* first check that it is not busy */
2459         do {
2460                 reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
2461                 if (time_out-- == 0) {
2462                         return false;
2463                 }
2464         }
2465         while (reg_value & ETH_SMI_BUSY);
2466
2467         /* not busy */
2468
2469         MV_REG_WRITE (MV64460_ETH_SMI_REG,
2470                       (phy_addr << 16) | (phy_reg << 21) |
2471                       ETH_SMI_OPCODE_READ);
2472
2473         time_out = PHY_BUSY_TIMEOUT;    /* initialize the time out var again */
2474
2475         do {
2476                 reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
2477                 if (time_out-- == 0) {
2478                         return false;
2479                 }
2480         }
2481         while ((reg_value & ETH_SMI_READ_VALID) != ETH_SMI_READ_VALID); /* Bit set equ operation done */
2482
2483         /* Wait for the data to update in the SMI register */
2484 #define PHY_UPDATE_TIMEOUT      10000
2485         for (time_out = 0; time_out < PHY_UPDATE_TIMEOUT; time_out++);
2486
2487         reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
2488
2489         *value = reg_value & 0xffff;
2490
2491         return true;
2492 }
2493
2494 int mv_miiphy_read(const char *devname, unsigned char phy_addr,
2495                    unsigned char phy_reg, unsigned short *value)
2496 {
2497         unsigned int reg_value;
2498         unsigned int time_out = PHY_BUSY_TIMEOUT;
2499
2500         /* first check that it is not busy */
2501         do {
2502                 reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
2503                 if (time_out-- == 0) {
2504                         return false;
2505                 }
2506         }
2507         while (reg_value & ETH_SMI_BUSY);
2508
2509         /* not busy */
2510         MV_REG_WRITE (MV64460_ETH_SMI_REG,
2511                       (phy_addr << 16) | (phy_reg << 21) |
2512                       ETH_SMI_OPCODE_READ);
2513
2514         time_out = PHY_BUSY_TIMEOUT;    /* initialize the time out var again */
2515
2516         do {
2517                 reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
2518                 if (time_out-- == 0) {
2519                         return false;
2520                 }
2521         }
2522         while ((reg_value & ETH_SMI_READ_VALID) != ETH_SMI_READ_VALID); /* Bit set equ operation done */
2523
2524         /* Wait for the data to update in the SMI register */
2525         for (time_out = 0; time_out < PHY_UPDATE_TIMEOUT; time_out++);
2526
2527         reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
2528
2529         *value = reg_value & 0xffff;
2530
2531         return 0;
2532 }
2533
2534 /*******************************************************************************
2535  * eth_port_write_smi_reg - Write to PHY registers
2536  *
2537  * DESCRIPTION:
2538  *       This routine utilize the SMI interface to interact with the PHY in
2539  *       order to perform writes to PHY registers.
2540  *
2541  * INPUT:
2542  *      ETH_PORT   eth_port_num   Ethernet Port number. See ETH_PORT enum.
2543  *      unsigned int   phy_reg   PHY register address offset.
2544  *      unsigned int    value   Register value.
2545  *
2546  * OUTPUT:
2547  *      Write the given value to the specified PHY register.
2548  *
2549  * RETURN:
2550  *      false if the PHY is busy.
2551  *      true otherwise.
2552  *
2553  *******************************************************************************/
2554 static bool eth_port_write_smi_reg (ETH_PORT eth_port_num,
2555                                     unsigned int phy_reg, unsigned int value)
2556 {
2557         unsigned int reg_value;
2558         unsigned int time_out = PHY_BUSY_TIMEOUT;
2559         int phy_addr;
2560
2561         phy_addr = ethernet_phy_get (eth_port_num);
2562
2563         /* first check that it is not busy */
2564         do {
2565                 reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
2566                 if (time_out-- == 0) {
2567                         return false;
2568                 }
2569         }
2570         while (reg_value & ETH_SMI_BUSY);
2571
2572         /* not busy */
2573         MV_REG_WRITE (MV64460_ETH_SMI_REG,
2574                       (phy_addr << 16) | (phy_reg << 21) |
2575                       ETH_SMI_OPCODE_WRITE | (value & 0xffff));
2576         return true;
2577 }
2578
2579 int mv_miiphy_write(const char *devname, unsigned char phy_addr,
2580                     unsigned char phy_reg, unsigned short value)
2581 {
2582         unsigned int reg_value;
2583         unsigned int time_out = PHY_BUSY_TIMEOUT;
2584
2585         /* first check that it is not busy */
2586         do {
2587                 reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
2588                 if (time_out-- == 0) {
2589                         return false;
2590                 }
2591         }
2592         while (reg_value & ETH_SMI_BUSY);
2593
2594         /* not busy */
2595         MV_REG_WRITE (MV64460_ETH_SMI_REG,
2596                       (phy_addr << 16) | (phy_reg << 21) |
2597                       ETH_SMI_OPCODE_WRITE | (value & 0xffff));
2598         return 0;
2599 }
2600
2601 /*******************************************************************************
2602  * eth_set_access_control - Config address decode parameters for Ethernet unit
2603  *
2604  * DESCRIPTION:
2605  *       This function configures the address decode parameters for the Gigabit
2606  *       Ethernet Controller according the given parameters struct.
2607  *
2608  * INPUT:
2609  *      ETH_PORT   eth_port_num   Ethernet Port number. See ETH_PORT enum.
2610  *       ETH_WIN_PARAM  *param   Address decode parameter struct.
2611  *
2612  * OUTPUT:
2613  *       An access window is opened using the given access parameters.
2614  *
2615  * RETURN:
2616  *       None.
2617  *
2618  *******************************************************************************/
2619 static void eth_set_access_control (ETH_PORT eth_port_num,
2620                                     ETH_WIN_PARAM * param)
2621 {
2622         unsigned int access_prot_reg;
2623
2624         /* Set access control register */
2625         access_prot_reg = MV_REG_READ (MV64460_ETH_ACCESS_PROTECTION_REG
2626                                        (eth_port_num));
2627         access_prot_reg &= (~(3 << (param->win * 2)));  /* clear window permission */
2628         access_prot_reg |= (param->access_ctrl << (param->win * 2));
2629         MV_REG_WRITE (MV64460_ETH_ACCESS_PROTECTION_REG (eth_port_num),
2630                       access_prot_reg);
2631
2632         /* Set window Size reg (SR) */
2633         MV_REG_WRITE ((MV64460_ETH_SIZE_REG_0 +
2634                        (ETH_SIZE_REG_GAP * param->win)),
2635                       (((param->size / 0x10000) - 1) << 16));
2636
2637         /* Set window Base address reg (BA) */
2638         MV_REG_WRITE ((MV64460_ETH_BAR_0 + (ETH_BAR_GAP * param->win)),
2639                       (param->target | param->attributes | param->base_addr));
2640         /* High address remap reg (HARR) */
2641         if (param->win < 4)
2642                 MV_REG_WRITE ((MV64460_ETH_HIGH_ADDR_REMAP_REG_0 +
2643                                (ETH_HIGH_ADDR_REMAP_REG_GAP * param->win)),
2644                               param->high_addr);
2645
2646         /* Base address enable reg (BARER) */
2647         if (param->enable == 1)
2648                 MV_RESET_REG_BITS (MV64460_ETH_BASE_ADDR_ENABLE_REG,
2649                                    (1 << param->win));
2650         else
2651                 MV_SET_REG_BITS (MV64460_ETH_BASE_ADDR_ENABLE_REG,
2652                                  (1 << param->win));
2653 }
2654
2655 /*******************************************************************************
2656  * ether_init_rx_desc_ring - Curve a Rx chain desc list and buffer in memory.
2657  *
2658  * DESCRIPTION:
2659  *       This function prepares a Rx chained list of descriptors and packet
2660  *       buffers in a form of a ring. The routine must be called after port
2661  *       initialization routine and before port start routine.
2662  *       The Ethernet SDMA engine uses CPU bus addresses to access the various
2663  *       devices in the system (i.e. DRAM). This function uses the ethernet
2664  *       struct 'virtual to physical' routine (set by the user) to set the ring
2665  *       with physical addresses.
2666  *
2667  * INPUT:
2668  *      ETH_PORT_INFO   *p_eth_port_ctrl   Ethernet Port Control srtuct.
2669  *      ETH_QUEUE       rx_queue         Number of Rx queue.
2670  *      int                     rx_desc_num       Number of Rx descriptors
2671  *      int                     rx_buff_size      Size of Rx buffer
2672  *      unsigned int    rx_desc_base_addr  Rx descriptors memory area base addr.
2673  *      unsigned int    rx_buff_base_addr  Rx buffer memory area base addr.
2674  *
2675  * OUTPUT:
2676  *      The routine updates the Ethernet port control struct with information
2677  *      regarding the Rx descriptors and buffers.
2678  *
2679  * RETURN:
2680  *      false if the given descriptors memory area is not aligned according to
2681  *      Ethernet SDMA specifications.
2682  *      true otherwise.
2683  *
2684  *******************************************************************************/
2685 static bool ether_init_rx_desc_ring (ETH_PORT_INFO * p_eth_port_ctrl,
2686                                      ETH_QUEUE rx_queue,
2687                                      int rx_desc_num,
2688                                      int rx_buff_size,
2689                                      unsigned int rx_desc_base_addr,
2690                                      unsigned int rx_buff_base_addr)
2691 {
2692         ETH_RX_DESC *p_rx_desc;
2693         ETH_RX_DESC *p_rx_prev_desc;    /* pointer to link with the last descriptor */
2694         unsigned int buffer_addr;
2695         int ix;                 /* a counter */
2696
2697         p_rx_desc = (ETH_RX_DESC *) rx_desc_base_addr;
2698         p_rx_prev_desc = p_rx_desc;
2699         buffer_addr = rx_buff_base_addr;
2700
2701         /* Rx desc Must be 4LW aligned (i.e. Descriptor_Address[3:0]=0000). */
2702         if (rx_buff_base_addr & 0xF)
2703                 return false;
2704
2705         /* Rx buffers are limited to 64K bytes and Minimum size is 8 bytes  */
2706         if ((rx_buff_size < 8) || (rx_buff_size > RX_BUFFER_MAX_SIZE))
2707                 return false;
2708
2709         /* Rx buffers must be 64-bit aligned.       */
2710         if ((rx_buff_base_addr + rx_buff_size) & 0x7)
2711                 return false;
2712
2713         /* initialize the Rx descriptors ring */
2714         for (ix = 0; ix < rx_desc_num; ix++) {
2715                 p_rx_desc->buf_size = rx_buff_size;
2716                 p_rx_desc->byte_cnt = 0x0000;
2717                 p_rx_desc->cmd_sts =
2718                         ETH_BUFFER_OWNED_BY_DMA | ETH_RX_ENABLE_INTERRUPT;
2719                 p_rx_desc->next_desc_ptr =
2720                         ((unsigned int) p_rx_desc) + RX_DESC_ALIGNED_SIZE;
2721                 p_rx_desc->buf_ptr = buffer_addr;
2722                 p_rx_desc->return_info = 0x00000000;
2723                 D_CACHE_FLUSH_LINE (p_rx_desc, 0);
2724                 buffer_addr += rx_buff_size;
2725                 p_rx_prev_desc = p_rx_desc;
2726                 p_rx_desc = (ETH_RX_DESC *)
2727                         ((unsigned int) p_rx_desc + RX_DESC_ALIGNED_SIZE);
2728         }
2729
2730         /* Closing Rx descriptors ring */
2731         p_rx_prev_desc->next_desc_ptr = (rx_desc_base_addr);
2732         D_CACHE_FLUSH_LINE (p_rx_prev_desc, 0);
2733
2734         /* Save Rx desc pointer to driver struct. */
2735         CURR_RFD_SET ((ETH_RX_DESC *) rx_desc_base_addr, rx_queue);
2736         USED_RFD_SET ((ETH_RX_DESC *) rx_desc_base_addr, rx_queue);
2737
2738         p_eth_port_ctrl->p_rx_desc_area_base[rx_queue] =
2739                 (ETH_RX_DESC *) rx_desc_base_addr;
2740         p_eth_port_ctrl->rx_desc_area_size[rx_queue] =
2741                 rx_desc_num * RX_DESC_ALIGNED_SIZE;
2742
2743         p_eth_port_ctrl->port_rx_queue_command |= (1 << rx_queue);
2744
2745         return true;
2746 }
2747
2748 /*******************************************************************************
2749  * ether_init_tx_desc_ring - Curve a Tx chain desc list and buffer in memory.
2750  *
2751  * DESCRIPTION:
2752  *       This function prepares a Tx chained list of descriptors and packet
2753  *       buffers in a form of a ring. The routine must be called after port
2754  *       initialization routine and before port start routine.
2755  *       The Ethernet SDMA engine uses CPU bus addresses to access the various
2756  *       devices in the system (i.e. DRAM). This function uses the ethernet
2757  *       struct 'virtual to physical' routine (set by the user) to set the ring
2758  *       with physical addresses.
2759  *
2760  * INPUT:
2761  *      ETH_PORT_INFO   *p_eth_port_ctrl   Ethernet Port Control srtuct.
2762  *      ETH_QUEUE       tx_queue         Number of Tx queue.
2763  *      int                     tx_desc_num       Number of Tx descriptors
2764  *      int                     tx_buff_size      Size of Tx buffer
2765  *      unsigned int    tx_desc_base_addr  Tx descriptors memory area base addr.
2766  *      unsigned int    tx_buff_base_addr  Tx buffer memory area base addr.
2767  *
2768  * OUTPUT:
2769  *      The routine updates the Ethernet port control struct with information
2770  *      regarding the Tx descriptors and buffers.
2771  *
2772  * RETURN:
2773  *      false if the given descriptors memory area is not aligned according to
2774  *      Ethernet SDMA specifications.
2775  *      true otherwise.
2776  *
2777  *******************************************************************************/
2778 static bool ether_init_tx_desc_ring (ETH_PORT_INFO * p_eth_port_ctrl,
2779                                      ETH_QUEUE tx_queue,
2780                                      int tx_desc_num,
2781                                      int tx_buff_size,
2782                                      unsigned int tx_desc_base_addr,
2783                                      unsigned int tx_buff_base_addr)
2784 {
2785
2786         ETH_TX_DESC *p_tx_desc;
2787         ETH_TX_DESC *p_tx_prev_desc;
2788         unsigned int buffer_addr;
2789         int ix;                 /* a counter */
2790
2791         /* save the first desc pointer to link with the last descriptor */
2792         p_tx_desc = (ETH_TX_DESC *) tx_desc_base_addr;
2793         p_tx_prev_desc = p_tx_desc;
2794         buffer_addr = tx_buff_base_addr;
2795
2796         /* Tx desc Must be 4LW aligned (i.e. Descriptor_Address[3:0]=0000). */
2797         if (tx_buff_base_addr & 0xF)
2798                 return false;
2799
2800         /* Tx buffers are limited to 64K bytes and Minimum size is 8 bytes  */
2801         if ((tx_buff_size > TX_BUFFER_MAX_SIZE)
2802             || (tx_buff_size < TX_BUFFER_MIN_SIZE))
2803                 return false;
2804
2805         /* Initialize the Tx descriptors ring */
2806         for (ix = 0; ix < tx_desc_num; ix++) {
2807                 p_tx_desc->byte_cnt = 0x0000;
2808                 p_tx_desc->l4i_chk = 0x0000;
2809                 p_tx_desc->cmd_sts = 0x00000000;
2810                 p_tx_desc->next_desc_ptr =
2811                         ((unsigned int) p_tx_desc) + TX_DESC_ALIGNED_SIZE;
2812
2813                 p_tx_desc->buf_ptr = buffer_addr;
2814                 p_tx_desc->return_info = 0x00000000;
2815                 D_CACHE_FLUSH_LINE (p_tx_desc, 0);
2816                 buffer_addr += tx_buff_size;
2817                 p_tx_prev_desc = p_tx_desc;
2818                 p_tx_desc = (ETH_TX_DESC *)
2819                         ((unsigned int) p_tx_desc + TX_DESC_ALIGNED_SIZE);
2820
2821         }
2822         /* Closing Tx descriptors ring */
2823         p_tx_prev_desc->next_desc_ptr = tx_desc_base_addr;
2824         D_CACHE_FLUSH_LINE (p_tx_prev_desc, 0);
2825         /* Set Tx desc pointer in driver struct. */
2826         CURR_TFD_SET ((ETH_TX_DESC *) tx_desc_base_addr, tx_queue);
2827         USED_TFD_SET ((ETH_TX_DESC *) tx_desc_base_addr, tx_queue);
2828
2829         /* Init Tx ring base and size parameters */
2830         p_eth_port_ctrl->p_tx_desc_area_base[tx_queue] =
2831                 (ETH_TX_DESC *) tx_desc_base_addr;
2832         p_eth_port_ctrl->tx_desc_area_size[tx_queue] =
2833                 (tx_desc_num * TX_DESC_ALIGNED_SIZE);
2834
2835         /* Add the queue to the list of Tx queues of this port */
2836         p_eth_port_ctrl->port_tx_queue_command |= (1 << tx_queue);
2837
2838         return true;
2839 }
2840
2841 /*******************************************************************************
2842  * eth_port_send - Send an Ethernet packet
2843  *
2844  * DESCRIPTION:
2845  *      This routine send a given packet described by p_pktinfo parameter. It
2846  *      supports transmitting of a packet spaned over multiple buffers. The
2847  *      routine updates 'curr' and 'first' indexes according to the packet
2848  *      segment passed to the routine. In case the packet segment is first,
2849  *      the 'first' index is update. In any case, the 'curr' index is updated.
2850  *      If the routine get into Tx resource error it assigns 'curr' index as
2851  *      'first'. This way the function can abort Tx process of multiple
2852  *      descriptors per packet.
2853  *
2854  * INPUT:
2855  *      ETH_PORT_INFO   *p_eth_port_ctrl   Ethernet Port Control srtuct.
2856  *      ETH_QUEUE       tx_queue         Number of Tx queue.
2857  *      PKT_INFO        *p_pkt_info       User packet buffer.
2858  *
2859  * OUTPUT:
2860  *      Tx ring 'curr' and 'first' indexes are updated.
2861  *
2862  * RETURN:
2863  *      ETH_QUEUE_FULL in case of Tx resource error.
2864  *      ETH_ERROR in case the routine can not access Tx desc ring.
2865  *      ETH_QUEUE_LAST_RESOURCE if the routine uses the last Tx resource.
2866  *      ETH_OK otherwise.
2867  *
2868  *******************************************************************************/
2869 static ETH_FUNC_RET_STATUS eth_port_send (ETH_PORT_INFO * p_eth_port_ctrl,
2870                                           ETH_QUEUE tx_queue,
2871                                           PKT_INFO * p_pkt_info)
2872 {
2873         volatile ETH_TX_DESC *p_tx_desc_first;
2874         volatile ETH_TX_DESC *p_tx_desc_curr;
2875         volatile ETH_TX_DESC *p_tx_next_desc_curr;
2876         volatile ETH_TX_DESC *p_tx_desc_used;
2877         unsigned int command_status;
2878
2879         /* Do not process Tx ring in case of Tx ring resource error */
2880         if (p_eth_port_ctrl->tx_resource_err[tx_queue] == true)
2881                 return ETH_QUEUE_FULL;
2882
2883         /* Get the Tx Desc ring indexes */
2884         CURR_TFD_GET (p_tx_desc_curr, tx_queue);
2885         USED_TFD_GET (p_tx_desc_used, tx_queue);
2886
2887         if (p_tx_desc_curr == NULL)
2888                 return ETH_ERROR;
2889
2890         /* The following parameters are used to save readings from memory */
2891         p_tx_next_desc_curr = TX_NEXT_DESC_PTR (p_tx_desc_curr, tx_queue);
2892         command_status = p_pkt_info->cmd_sts | ETH_ZERO_PADDING | ETH_GEN_CRC;
2893
2894         if (command_status & (ETH_TX_FIRST_DESC)) {
2895                 /* Update first desc */
2896                 FIRST_TFD_SET (p_tx_desc_curr, tx_queue);
2897                 p_tx_desc_first = p_tx_desc_curr;
2898         } else {
2899                 FIRST_TFD_GET (p_tx_desc_first, tx_queue);
2900                 command_status |= ETH_BUFFER_OWNED_BY_DMA;
2901         }
2902
2903         /* Buffers with a payload smaller than 8 bytes must be aligned to 64-bit */
2904         /* boundary. We use the memory allocated for Tx descriptor. This memory  */
2905         /* located in TX_BUF_OFFSET_IN_DESC offset within the Tx descriptor. */
2906         if (p_pkt_info->byte_cnt <= 8) {
2907                 printf ("You have failed in the < 8 bytes errata - fixme\n");   /* RABEEH - TBD */
2908                 return ETH_ERROR;
2909
2910                 p_tx_desc_curr->buf_ptr =
2911                         (unsigned int) p_tx_desc_curr + TX_BUF_OFFSET_IN_DESC;
2912                 eth_b_copy (p_pkt_info->buf_ptr, p_tx_desc_curr->buf_ptr,
2913                             p_pkt_info->byte_cnt);
2914         } else
2915                 p_tx_desc_curr->buf_ptr = p_pkt_info->buf_ptr;
2916
2917         p_tx_desc_curr->byte_cnt = p_pkt_info->byte_cnt;
2918         p_tx_desc_curr->return_info = p_pkt_info->return_info;
2919
2920         if (p_pkt_info->cmd_sts & (ETH_TX_LAST_DESC)) {
2921                 /* Set last desc with DMA ownership and interrupt enable. */
2922                 p_tx_desc_curr->cmd_sts = command_status |
2923                         ETH_BUFFER_OWNED_BY_DMA | ETH_TX_ENABLE_INTERRUPT;
2924
2925                 if (p_tx_desc_curr != p_tx_desc_first)
2926                         p_tx_desc_first->cmd_sts |= ETH_BUFFER_OWNED_BY_DMA;
2927
2928                 /* Flush CPU pipe */
2929
2930                 D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_curr, 0);
2931                 D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_first, 0);
2932                 CPU_PIPE_FLUSH;
2933
2934                 /* Apply send command */
2935                 ETH_ENABLE_TX_QUEUE (tx_queue, p_eth_port_ctrl->port_num);
2936
2937                 /* Finish Tx packet. Update first desc in case of Tx resource error */
2938                 p_tx_desc_first = p_tx_next_desc_curr;
2939                 FIRST_TFD_SET (p_tx_desc_first, tx_queue);
2940
2941         } else {
2942                 p_tx_desc_curr->cmd_sts = command_status;
2943                 D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_curr, 0);
2944         }
2945
2946         /* Check for ring index overlap in the Tx desc ring */
2947         if (p_tx_next_desc_curr == p_tx_desc_used) {
2948                 /* Update the current descriptor */
2949                 CURR_TFD_SET (p_tx_desc_first, tx_queue);
2950
2951                 p_eth_port_ctrl->tx_resource_err[tx_queue] = true;
2952                 return ETH_QUEUE_LAST_RESOURCE;
2953         } else {
2954                 /* Update the current descriptor */
2955                 CURR_TFD_SET (p_tx_next_desc_curr, tx_queue);
2956                 return ETH_OK;
2957         }
2958 }
2959
2960 /*******************************************************************************
2961  * eth_tx_return_desc - Free all used Tx descriptors
2962  *
2963  * DESCRIPTION:
2964  *      This routine returns the transmitted packet information to the caller.
2965  *      It uses the 'first' index to support Tx desc return in case a transmit
2966  *      of a packet spanned over multiple buffer still in process.
2967  *      In case the Tx queue was in "resource error" condition, where there are
2968  *      no available Tx resources, the function resets the resource error flag.
2969  *
2970  * INPUT:
2971  *      ETH_PORT_INFO   *p_eth_port_ctrl   Ethernet Port Control srtuct.
2972  *      ETH_QUEUE       tx_queue         Number of Tx queue.
2973  *      PKT_INFO        *p_pkt_info       User packet buffer.
2974  *
2975  * OUTPUT:
2976  *      Tx ring 'first' and 'used' indexes are updated.
2977  *
2978  * RETURN:
2979  *      ETH_ERROR in case the routine can not access Tx desc ring.
2980  *      ETH_RETRY in case there is transmission in process.
2981  *      ETH_END_OF_JOB if the routine has nothing to release.
2982  *      ETH_OK otherwise.
2983  *
2984  *******************************************************************************/
2985 static ETH_FUNC_RET_STATUS eth_tx_return_desc (ETH_PORT_INFO *
2986                                                p_eth_port_ctrl,
2987                                                ETH_QUEUE tx_queue,
2988                                                PKT_INFO * p_pkt_info)
2989 {
2990         volatile ETH_TX_DESC *p_tx_desc_used = NULL;
2991         volatile ETH_TX_DESC *p_tx_desc_first = NULL;
2992         unsigned int command_status;
2993
2994         /* Get the Tx Desc ring indexes */
2995         USED_TFD_GET (p_tx_desc_used, tx_queue);
2996         FIRST_TFD_GET (p_tx_desc_first, tx_queue);
2997
2998         /* Sanity check */
2999         if (p_tx_desc_used == NULL)
3000                 return ETH_ERROR;
3001
3002         command_status = p_tx_desc_used->cmd_sts;
3003
3004         /* Still transmitting... */
3005         if (command_status & (ETH_BUFFER_OWNED_BY_DMA)) {
3006                 D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_used, 0);
3007                 return ETH_RETRY;
3008         }
3009
3010         /* Stop release. About to overlap the current available Tx descriptor */
3011         if ((p_tx_desc_used == p_tx_desc_first) &&
3012             (p_eth_port_ctrl->tx_resource_err[tx_queue] == false)) {
3013                 D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_used, 0);
3014                 return ETH_END_OF_JOB;
3015         }
3016
3017         /* Pass the packet information to the caller */
3018         p_pkt_info->cmd_sts = command_status;
3019         p_pkt_info->return_info = p_tx_desc_used->return_info;
3020         p_tx_desc_used->return_info = 0;
3021
3022         /* Update the next descriptor to release. */
3023         USED_TFD_SET (TX_NEXT_DESC_PTR (p_tx_desc_used, tx_queue), tx_queue);
3024
3025         /* Any Tx return cancels the Tx resource error status */
3026         if (p_eth_port_ctrl->tx_resource_err[tx_queue] == true)
3027                 p_eth_port_ctrl->tx_resource_err[tx_queue] = false;
3028
3029         D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_used, 0);
3030
3031         return ETH_OK;
3032
3033 }
3034
3035 /*******************************************************************************
3036  * eth_port_receive - Get received information from Rx ring.
3037  *
3038  * DESCRIPTION:
3039  *      This routine returns the received data to the caller. There is no
3040  *      data copying during routine operation. All information is returned
3041  *      using pointer to packet information struct passed from the caller.
3042  *      If the routine exhausts Rx ring resources then the resource error flag
3043  *      is set.
3044  *
3045  * INPUT:
3046  *      ETH_PORT_INFO   *p_eth_port_ctrl   Ethernet Port Control srtuct.
3047  *      ETH_QUEUE       rx_queue         Number of Rx queue.
3048  *      PKT_INFO        *p_pkt_info       User packet buffer.
3049  *
3050  * OUTPUT:
3051  *      Rx ring current and used indexes are updated.
3052  *
3053  * RETURN:
3054  *      ETH_ERROR in case the routine can not access Rx desc ring.
3055  *      ETH_QUEUE_FULL if Rx ring resources are exhausted.
3056  *      ETH_END_OF_JOB if there is no received data.
3057  *      ETH_OK otherwise.
3058  *
3059  *******************************************************************************/
3060 static ETH_FUNC_RET_STATUS eth_port_receive (ETH_PORT_INFO * p_eth_port_ctrl,
3061                                              ETH_QUEUE rx_queue,
3062                                              PKT_INFO * p_pkt_info)
3063 {
3064         volatile ETH_RX_DESC *p_rx_curr_desc;
3065         volatile ETH_RX_DESC *p_rx_next_curr_desc;
3066         volatile ETH_RX_DESC *p_rx_used_desc;
3067         unsigned int command_status;
3068
3069         /* Do not process Rx ring in case of Rx ring resource error */
3070         if (p_eth_port_ctrl->rx_resource_err[rx_queue] == true) {
3071                 printf ("\nRx Queue is full ...\n");
3072                 return ETH_QUEUE_FULL;
3073         }
3074
3075         /* Get the Rx Desc ring 'curr and 'used' indexes */
3076         CURR_RFD_GET (p_rx_curr_desc, rx_queue);
3077         USED_RFD_GET (p_rx_used_desc, rx_queue);
3078
3079         /* Sanity check */
3080         if (p_rx_curr_desc == NULL)
3081                 return ETH_ERROR;
3082
3083         /* The following parameters are used to save readings from memory */
3084         p_rx_next_curr_desc = RX_NEXT_DESC_PTR (p_rx_curr_desc, rx_queue);
3085         command_status = p_rx_curr_desc->cmd_sts;
3086
3087         /* Nothing to receive... */
3088         if (command_status & (ETH_BUFFER_OWNED_BY_DMA)) {
3089 /*      DP(printf("Rx: command_status: %08x\n", command_status)); */
3090                 D_CACHE_FLUSH_LINE ((unsigned int) p_rx_curr_desc, 0);
3091 /*      DP(printf("\nETH_END_OF_JOB ...\n"));*/
3092                 return ETH_END_OF_JOB;
3093         }
3094
3095         p_pkt_info->byte_cnt = (p_rx_curr_desc->byte_cnt) - RX_BUF_OFFSET;
3096         p_pkt_info->cmd_sts = command_status;
3097         p_pkt_info->buf_ptr = (p_rx_curr_desc->buf_ptr) + RX_BUF_OFFSET;
3098         p_pkt_info->return_info = p_rx_curr_desc->return_info;
3099         p_pkt_info->l4i_chk = p_rx_curr_desc->buf_size; /* IP fragment indicator */
3100
3101         /* Clean the return info field to indicate that the packet has been */
3102         /* moved to the upper layers                                        */
3103         p_rx_curr_desc->return_info = 0;
3104
3105         /* Update 'curr' in data structure */
3106         CURR_RFD_SET (p_rx_next_curr_desc, rx_queue);
3107
3108         /* Rx descriptors resource exhausted. Set the Rx ring resource error flag */
3109         if (p_rx_next_curr_desc == p_rx_used_desc)
3110                 p_eth_port_ctrl->rx_resource_err[rx_queue] = true;
3111
3112         D_CACHE_FLUSH_LINE ((unsigned int) p_rx_curr_desc, 0);
3113         CPU_PIPE_FLUSH;
3114
3115         return ETH_OK;
3116 }
3117
3118 /*******************************************************************************
3119  * eth_rx_return_buff - Returns a Rx buffer back to the Rx ring.
3120  *
3121  * DESCRIPTION:
3122  *      This routine returns a Rx buffer back to the Rx ring. It retrieves the
3123  *      next 'used' descriptor and attached the returned buffer to it.
3124  *      In case the Rx ring was in "resource error" condition, where there are
3125  *      no available Rx resources, the function resets the resource error flag.
3126  *
3127  * INPUT:
3128  *      ETH_PORT_INFO   *p_eth_port_ctrl   Ethernet Port Control srtuct.
3129  *      ETH_QUEUE       rx_queue         Number of Rx queue.
3130  *      PKT_INFO        *p_pkt_info       Information on the returned buffer.
3131  *
3132  * OUTPUT:
3133  *      New available Rx resource in Rx descriptor ring.
3134  *
3135  * RETURN:
3136  *      ETH_ERROR in case the routine can not access Rx desc ring.
3137  *      ETH_OK otherwise.
3138  *
3139  *******************************************************************************/
3140 static ETH_FUNC_RET_STATUS eth_rx_return_buff (ETH_PORT_INFO *
3141                                                p_eth_port_ctrl,
3142                                                ETH_QUEUE rx_queue,
3143                                                PKT_INFO * p_pkt_info)
3144 {
3145         volatile ETH_RX_DESC *p_used_rx_desc;   /* Where to return Rx resource */
3146
3147         /* Get 'used' Rx descriptor */
3148         USED_RFD_GET (p_used_rx_desc, rx_queue);
3149
3150         /* Sanity check */
3151         if (p_used_rx_desc == NULL)
3152                 return ETH_ERROR;
3153
3154         p_used_rx_desc->buf_ptr = p_pkt_info->buf_ptr;
3155         p_used_rx_desc->return_info = p_pkt_info->return_info;
3156         p_used_rx_desc->byte_cnt = p_pkt_info->byte_cnt;
3157         p_used_rx_desc->buf_size = MV64460_RX_BUFFER_SIZE;      /* Reset Buffer size */
3158
3159         /* Flush the write pipe */
3160         CPU_PIPE_FLUSH;
3161
3162         /* Return the descriptor to DMA ownership */
3163         p_used_rx_desc->cmd_sts =
3164                 ETH_BUFFER_OWNED_BY_DMA | ETH_RX_ENABLE_INTERRUPT;
3165
3166         /* Flush descriptor and CPU pipe */
3167         D_CACHE_FLUSH_LINE ((unsigned int) p_used_rx_desc, 0);
3168         CPU_PIPE_FLUSH;
3169
3170         /* Move the used descriptor pointer to the next descriptor */
3171         USED_RFD_SET (RX_NEXT_DESC_PTR (p_used_rx_desc, rx_queue), rx_queue);
3172
3173         /* Any Rx return cancels the Rx resource error status */
3174         if (p_eth_port_ctrl->rx_resource_err[rx_queue] == true)
3175                 p_eth_port_ctrl->rx_resource_err[rx_queue] = false;
3176
3177         return ETH_OK;
3178 }
3179
3180 /*******************************************************************************
3181  * eth_port_set_rx_coal - Sets coalescing interrupt mechanism on RX path
3182  *
3183  * DESCRIPTION:
3184  *      This routine sets the RX coalescing interrupt mechanism parameter.
3185  *      This parameter is a timeout counter, that counts in 64 t_clk
3186  *      chunks ; that when timeout event occurs a maskable interrupt
3187  *      occurs.
3188  *      The parameter is calculated using the tClk of the MV-643xx chip
3189  *      , and the required delay of the interrupt in usec.
3190  *
3191  * INPUT:
3192  *      ETH_PORT eth_port_num      Ethernet port number
3193  *      unsigned int t_clk        t_clk of the MV-643xx chip in HZ units
3194  *      unsigned int delay       Delay in usec
3195  *
3196  * OUTPUT:
3197  *      Interrupt coalescing mechanism value is set in MV-643xx chip.
3198  *
3199  * RETURN:
3200  *      The interrupt coalescing value set in the gigE port.
3201  *
3202  *******************************************************************************/
3203 #if 0                           /* FIXME */
3204 static unsigned int eth_port_set_rx_coal (ETH_PORT eth_port_num,
3205                                           unsigned int t_clk,
3206                                           unsigned int delay)
3207 {
3208         unsigned int coal;
3209
3210         coal = ((t_clk / 1000000) * delay) / 64;
3211         /* Set RX Coalescing mechanism */
3212         MV_REG_WRITE (MV64460_ETH_SDMA_CONFIG_REG (eth_port_num),
3213                       ((coal & 0x3fff) << 8) |
3214                       (MV_REG_READ
3215                        (MV64460_ETH_SDMA_CONFIG_REG (eth_port_num))
3216                        & 0xffc000ff));
3217         return coal;
3218 }
3219
3220 #endif
3221 /*******************************************************************************
3222  * eth_port_set_tx_coal - Sets coalescing interrupt mechanism on TX path
3223  *
3224  * DESCRIPTION:
3225  *      This routine sets the TX coalescing interrupt mechanism parameter.
3226  *      This parameter is a timeout counter, that counts in 64 t_clk
3227  *      chunks ; that when timeout event occurs a maskable interrupt
3228  *      occurs.
3229  *      The parameter is calculated using the t_cLK frequency of the
3230  *      MV-643xx chip and the required delay in the interrupt in uSec
3231  *
3232  * INPUT:
3233  *      ETH_PORT eth_port_num      Ethernet port number
3234  *      unsigned int t_clk        t_clk of the MV-643xx chip in HZ units
3235  *      unsigned int delay       Delay in uSeconds
3236  *
3237  * OUTPUT:
3238  *      Interrupt coalescing mechanism value is set in MV-643xx chip.
3239  *
3240  * RETURN:
3241  *      The interrupt coalescing value set in the gigE port.
3242  *
3243  *******************************************************************************/
3244 #if 0                           /* FIXME */
3245 static unsigned int eth_port_set_tx_coal (ETH_PORT eth_port_num,
3246                                           unsigned int t_clk,
3247                                           unsigned int delay)
3248 {
3249         unsigned int coal;
3250
3251         coal = ((t_clk / 1000000) * delay) / 64;
3252         /* Set TX Coalescing mechanism */
3253         MV_REG_WRITE (MV64460_ETH_TX_FIFO_URGENT_THRESHOLD_REG (eth_port_num),
3254                       coal << 4);
3255         return coal;
3256 }
3257 #endif
3258
3259 /*******************************************************************************
3260  * eth_b_copy - Copy bytes from source to destination
3261  *
3262  * DESCRIPTION:
3263  *       This function supports the eight bytes limitation on Tx buffer size.
3264  *       The routine will zero eight bytes starting from the destination address
3265  *       followed by copying bytes from the source address to the destination.
3266  *
3267  * INPUT:
3268  *       unsigned int src_addr    32 bit source address.
3269  *       unsigned int dst_addr    32 bit destination address.
3270  *       int        byte_count    Number of bytes to copy.
3271  *
3272  * OUTPUT:
3273  *       See description.
3274  *
3275  * RETURN:
3276  *       None.
3277  *
3278  *******************************************************************************/
3279 static void eth_b_copy (unsigned int src_addr, unsigned int dst_addr,
3280                         int byte_count)
3281 {
3282         /* Zero the dst_addr area */
3283         *(unsigned int *) dst_addr = 0x0;
3284
3285         while (byte_count != 0) {
3286                 *(char *) dst_addr = *(char *) src_addr;
3287                 dst_addr++;
3288                 src_addr++;
3289                 byte_count--;
3290         }
3291 }