source: SVN/rincon/u-boot/board/prodrive/p3mx/mv_eth.c @ 55

Last change on this file since 55 was 55, checked in by Tim Harvey, 3 years ago

rincon: added latest u-boot source

restored form server backup

Signed-off-by: Tim Harvey <tharvey@…>

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