blob: e67596bd1a3e45deb37bae2047c5015f557798dd [file] [log] [blame]
Stefan Roese45993ea2006-11-29 15:42:37 +01001/*
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
Wolfgang Denkdd314e02006-11-30 01:54:07 +010018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Stefan Roese45993ea2006-11-29 15:42:37 +010019 * 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 */
Wolfgang Denkdd314e02006-11-30 01:54:07 +010049#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
Stefan Roese45993ea2006-11-29 15:42:37 +010053
Wolfgang Denkdd314e02006-11-30 01:54:07 +010054#define PHY_AUTONEGOTIATE_TIMEOUT 4000 /* 4000 ms autonegotiate timeout */
55#define PHY_UPDATE_TIMEOUT 10000
Stefan Roese45993ea2006-11-29 15:42:37 +010056
57#undef MV64460_CHECKSUM_OFFLOAD
58/*************************************************************************
Wolfgang Denkdd314e02006-11-30 01:54:07 +010059* The first part is the high level driver of the gigE ethernet ports. *
Stefan Roese45993ea2006-11-29 15:42:37 +010060*************************************************************************/
61
62/* Definition for configuring driver */
63/* #define UPDATE_STATS_BY_SOFTWARE */
64#undef MV64460_RX_QUEUE_FILL_ON_TASK
65
Stefan Roese45993ea2006-11-29 15:42:37 +010066/* Constants */
67#define MAGIC_ETH_RUNNING 8031971
Wolfgang Denkdd314e02006-11-30 01:54:07 +010068#define MV64460_INTERNAL_SRAM_SIZE _256K
Stefan Roese45993ea2006-11-29 15:42:37 +010069#define EXTRA_BYTES 32
Wolfgang Denkdd314e02006-11-30 01:54:07 +010070#define WRAP ETH_HLEN + 2 + 4 + 16
Stefan Roese45993ea2006-11-29 15:42:37 +010071#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
Wolfgang Denkdd314e02006-11-30 01:54:07 +0100109#ifndef UPDATE_STATS_BY_SOFTWARE
Stefan Roese45993ea2006-11-29 15:42:37 +0100110static 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);
Wolfgang Denkdd314e02006-11-30 01:54:07 +0100139 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);
Stefan Roese45993ea2006-11-29 15:42:37 +0100143 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
Stefan Roese45993ea2006-11-29 15:42:37 +0100154/**********************************************************************
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
Stefan Roese45993ea2006-11-29 15:42:37 +0100219#define DFCDL(write,read) ((write << 6) | read)
Wolfgang Denkdd314e02006-11-30 01:54:07 +0100220unsigned 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};
Stefan Roese45993ea2006-11-29 15:42:37 +0100238
Wolfgang Denkdd314e02006-11-30 01:54:07 +0100239void mv_eth_phy_init (void)
Stefan Roese45993ea2006-11-29 15:42:37 +0100240{
Wolfgang Denkdd314e02006-11-30 01:54:07 +0100241 int i;
Stefan Roese45993ea2006-11-29 15:42:37 +0100242
Wolfgang Denkdd314e02006-11-30 01:54:07 +0100243 MV_REG_WRITE (ETH_PHY_DFCDL_ADDR_REG, 0);
Stefan Roese45993ea2006-11-29 15:42:37 +0100244
Wolfgang Denkdd314e02006-11-30 01:54:07 +0100245 for (i = 0; i < 64; i++) {
246 MV_REG_WRITE (ETH_PHY_DFCDL_DATA0_REG, ethDfcdls[i]);
247 }
Stefan Roese45993ea2006-11-29 15:42:37 +0100248
Wolfgang Denkdd314e02006-11-30 01:54:07 +0100249 MV_REG_WRITE (ETH_PHY_DFCDL_CONFIG0_REG, 0x300000);
Stefan Roese45993ea2006-11-29 15:42:37 +0100250}
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
Wolfgang Denkdd314e02006-11-30 01:54:07 +0100260 /* P3M750 only
261 * Set RGMII clock drives strength
262 */
Stefan Roese45993ea2006-11-29 15:42:37 +0100263 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;
Stefan Roese45993ea2006-11-29 15:42:37 +0100289 case 1:
290 s = "eth1addr";
291 break;
Stefan Roese45993ea2006-11-29 15:42:37 +0100292 case 2:
293 s = "eth2addr";
294 break;
Stefan Roese45993ea2006-11-29 15:42:37 +0100295 default: /* this should never happen */
296 printf ("%s: Invalid device number %d\n",
297 __FUNCTION__, devnum);
298 return;
299 }
300
Wolfgang Denk76af2782010-07-24 21:55:43 +0200301 temp = getenv_f(s, buf, sizeof (buf));
Stefan Roese45993ea2006-11-29 15:42:37 +0100302 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;
Stefan Roese45993ea2006-11-29 15:42:37 +0100388 case 1:
389 s = "eth1addr";
390 break;
Stefan Roese45993ea2006-11-29 15:42:37 +0100391 case 2:
392 s = "eth2addr";
393 break;
Stefan Roese45993ea2006-11-29 15:42:37 +0100394 default: /* this should never happen */
395 printf ("%s: Invalid device number %d\n",
396 __FUNCTION__, devnum);
397 return;
398 }
399
Wolfgang Denk76af2782010-07-24 21:55:43 +0200400 temp = getenv_f(s, buf, sizeof (buf));
Stefan Roese45993ea2006-11-29 15:42:37 +0100401 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
Wolfgang Denkdd314e02006-11-30 01:54:07 +0100483 port_private = (struct mv64460_eth_priv *) ethernet_private->port_private;
Stefan Roese45993ea2006-11-29 15:42:37 +0100484 port_num = port_private->port_num;
485
486 /* Stop RX Queues */
Wolfgang Denkdd314e02006-11-30 01:54:07 +0100487 MV_REG_WRITE (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG (port_num), 0x0000ff00);
Stefan Roese45993ea2006-11-29 15:42:37 +0100488
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
Stefan Roese45993ea2006-11-29 15:42:37 +0100628static 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
Stefan Roese45993ea2006-11-29 15:42:37 +0100681 /* 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 */
Wolfgang Denkdd314e02006-11-30 01:54:07 +0100764#ifndef UPDATE_STATS_BY_SOFTWARE
Stefan Roese45993ea2006-11-29 15:42:37 +0100765 /*
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
Stefan Roese45993ea2006-11-29 15:42:37 +0100779/**********************************************************************
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
Wolfgang Denkdd314e02006-11-30 01:54:07 +0100786 * dev - a pointer to the required port
Stefan Roese45993ea2006-11-29 15:42:37 +0100787 *
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");
Wolfgang Denkdd314e02006-11-30 01:54:07 +0100822 return 1;
Stefan Roese45993ea2006-11-29 15:42:37 +0100823 }
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
Wolfgang Denkdd314e02006-11-30 01:54:07 +0100858 return 0; /* success */
Stefan Roese45993ea2006-11-29 15:42:37 +0100859}
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
Wolfgang Denkdd314e02006-11-30 01:54:07 +0100868 * max - maximum number to receive (0 means unlimted)
Stefan Roese45993ea2006-11-29 15:42:37 +0100869 *
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
Stefan Roese45993ea2006-11-29 15:42:37 +0100991/**********************************************************************
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
Wolfgang Denkdd314e02006-11-30 01:54:07 +01001072#ifndef UPDATE_STATS_BY_SOFTWARE
Stefan Roese45993ea2006-11-29 15:42:37 +01001073/**********************************************************************
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**************************************************************************
Wolfgang Denkdd314e02006-11-30 01:54:07 +01001134* The second part is the low level driver of the gigE ethernet ports. *
Stefan Roese45993ea2006-11-29 15:42:37 +01001135**************************************************************************
1136**************************************************************************
1137*************************************************************************/
1138/*
1139 * based on Linux code
Stefan Roese88fbf932010-04-15 16:07:28 +02001140 * arch/powerpc/galileo/EVB64460/mv64460_eth.c - Driver for MV64460X ethernet ports
Stefan Roese45993ea2006-11-29 15:42:37 +01001141 * 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
Wolfgang Denkdd314e02006-11-30 01:54:07 +01001150 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Stefan Roese45993ea2006-11-29 15:42:37 +01001151 * 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:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01001163 * This file introduce low level API to Marvell's Gigabit Ethernet
Stefan Roese45993ea2006-11-29 15:42:37 +01001164 * 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 *
Wolfgang Denkdd314e02006-11-30 01:54:07 +01001275 * Prior to calling the initialization routine eth_port_init() the user
Stefan Roese45993ea2006-11-29 15:42:37 +01001276 * must set the following fields under ETH_PORT_INFO struct:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01001277 * 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.
Stefan Roese45993ea2006-11-29 15:42:37 +01001286 *
Wolfgang Denkdd314e02006-11-30 01:54:07 +01001287 * 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
Stefan Roese45993ea2006-11-29 15:42:37 +01001292 *
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.
Wolfgang Denkdd314e02006-11-30 01:54:07 +01001310 * address - address base.
Stefan Roese45993ea2006-11-29 15:42:37 +01001311 * 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:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01001458* 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).
Stefan Roese45993ea2006-11-29 15:42:37 +01001468*
1469* INPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01001470* ETH_PORT_INFO *p_eth_port_ctrl Ethernet port control struct
Stefan Roese45993ea2006-11-29 15:42:37 +01001471*
1472* OUTPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01001473* See description.
Stefan Roese45993ea2006-11-29 15:42:37 +01001474*
1475* RETURN:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01001476* None.
Stefan Roese45993ea2006-11-29 15:42:37 +01001477*
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 */
Wolfgang Denkdd314e02006-11-30 01:54:07 +01001510 win_param.target = ETH_TARGET_DRAM; /* Window target - DDR */
Stefan Roese45993ea2006-11-29 15:42:37 +01001511 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);
Wolfgang Denkdd314e02006-11-30 01:54:07 +01001518 win_param.size = mv_get_dram_bank_size (BANK0); /* Get bank size */
Stefan Roese45993ea2006-11-29 15:42:37 +01001519 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);
Wolfgang Denkdd314e02006-11-30 01:54:07 +01001538 win_param.size = mv_get_dram_bank_size (BANK1); /* Get bank size */
Stefan Roese45993ea2006-11-29 15:42:37 +01001539 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);
Wolfgang Denkdd314e02006-11-30 01:54:07 +01001558 win_param.size = mv_get_dram_bank_size (BANK2); /* Get bank size */
Stefan Roese45993ea2006-11-29 15:42:37 +01001559 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);
Wolfgang Denkdd314e02006-11-30 01:54:07 +01001578 win_param.size = mv_get_dram_bank_size (BANK3); /* Get bank size */
Stefan Roese45993ea2006-11-29 15:42:37 +01001579 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:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01001614* 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
Stefan Roese45993ea2006-11-29 15:42:37 +01001621* configuration and command registers.
Wolfgang Denkdd314e02006-11-30 01:54:07 +01001622* After completing these steps, the ethernet port SDMA can starts to
1623* perform Rx and Tx activities.
Stefan Roese45993ea2006-11-29 15:42:37 +01001624*
Wolfgang Denkdd314e02006-11-30 01:54:07 +01001625* 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).
Stefan Roese45993ea2006-11-29 15:42:37 +01001628*
1629* INPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01001630* ETH_PORT_INFO *p_eth_port_ctrl Ethernet port control struct
Stefan Roese45993ea2006-11-29 15:42:37 +01001631*
1632* OUTPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01001633* Ethernet port is ready to receive and transmit.
Stefan Roese45993ea2006-11-29 15:42:37 +01001634*
1635* RETURN:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01001636* false if the port PHY is not up.
1637* true otherwise.
Stefan Roese45993ea2006-11-29 15:42:37 +01001638*
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
Stefan Roese45993ea2006-11-29 15:42:37 +01001648 /* 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:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01001717* 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.
Stefan Roese45993ea2006-11-29 15:42:37 +01001720*
1721* OUTPUT:
1722* Set MAC address low and high registers. also calls eth_port_uc_addr()
Wolfgang Denkdd314e02006-11-30 01:54:07 +01001723* To set the unicast table with the proper information.
Stefan Roese45993ea2006-11-29 15:42:37 +01001724*
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:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01001757* ETH_PORT eth_port_num Port number.
Stefan Roese45993ea2006-11-29 15:42:37 +01001758* unsigned char uc_nibble Unicast MAC Address last nibble.
Wolfgang Denkdd314e02006-11-30 01:54:07 +01001759* ETH_QUEUE queue Rx queue number for this MAC address.
1760* int option 0 = Add, 1 = remove address.
Stefan Roese45993ea2006-11-29 15:42:37 +01001761*
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:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01001839* 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.
Stefan Roese45993ea2006-11-29 15:42:37 +01001843*
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
Stefan Roese45993ea2006-11-29 15:42:37 +01001863 if ((p_addr[0] == 0x01) &&
1864 (p_addr[1] == 0x00) &&
Wolfgang Denkdd314e02006-11-30 01:54:07 +01001865 (p_addr[2] == 0x5E) && (p_addr[3] == 0x00) && (p_addr[4] == 0x00)) {
Stefan Roese45993ea2006-11-29 15:42:37 +01001866
1867 eth_port_smc_addr (eth_port_num, p_addr[5], queue, option);
Wolfgang Denkdd314e02006-11-30 01:54:07 +01001868 } else {
Stefan Roese45993ea2006-11-29 15:42:37 +01001869 /* 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
Stefan Roese45993ea2006-11-29 15:42:37 +01001879 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:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01001971* 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.
Stefan Roese45993ea2006-11-29 15:42:37 +01001975*
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 */
Wolfgang Denkdd314e02006-11-30 01:54:07 +01001993 tbl_offset = (mc_byte / 4) * 4; /* Register offset from SMC table base */
Stefan Roese45993ea2006-11-29 15:42:37 +01001994 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:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002035* 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.
Stefan Roese45993ea2006-11-29 15:42:37 +01002039*
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:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002091* Go through all the DA filter tables (Unicast, Special Multicast & Other
2092* Multicast) and set each entry to 0.
Stefan Roese45993ea2006-11-29 15:42:37 +01002093*
2094* INPUT:
2095* ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
2096*
2097* OUTPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002098* Multicast and Unicast packets are rejected.
Stefan Roese45993ea2006-11-29 15:42:37 +01002099*
2100* RETURN:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002101* None.
Stefan Roese45993ea2006-11-29 15:42:37 +01002102*
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:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002125* This function clears all MIB counters of a specific ethernet port.
2126* A read from the MIB counter will reset the counter.
Stefan Roese45993ea2006-11-29 15:42:37 +01002127*
2128* INPUT:
2129* ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
2130*
2131* OUTPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002132* After reading all MIB counters, the counters resets.
Stefan Roese45993ea2006-11-29 15:42:37 +01002133*
2134* RETURN:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002135* MIB counter value.
Stefan Roese45993ea2006-11-29 15:42:37 +01002136*
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:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002156* 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
Stefan Roese45993ea2006-11-29 15:42:37 +01002161*
2162* INPUT:
2163* ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002164* unsigned int mib_offset MIB counter offset (use ETH_MIB_... macros).
Stefan Roese45993ea2006-11-29 15:42:37 +01002165*
2166* OUTPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002167* After reading the MIB counter, the counter resets.
Stefan Roese45993ea2006-11-29 15:42:37 +01002168*
2169* RETURN:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002170* MIB counter value.
Stefan Roese45993ea2006-11-29 15:42:37 +01002171*
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:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002184* This routine set the ethernet port PHY address according to given
2185* parameter.
Stefan Roese45993ea2006-11-29 15:42:37 +01002186*
2187* INPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002188* ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
Stefan Roese45993ea2006-11-29 15:42:37 +01002189*
2190* OUTPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002191* Set PHY Address Register with given PHY address parameter.
Stefan Roese45993ea2006-11-29 15:42:37 +01002192*
2193* RETURN:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002194* None.
Stefan Roese45993ea2006-11-29 15:42:37 +01002195*
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:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002215 * This routine returns the given ethernet port PHY address.
Stefan Roese45993ea2006-11-29 15:42:37 +01002216 *
2217 * INPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002218 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
Stefan Roese45993ea2006-11-29 15:42:37 +01002219 *
2220 * OUTPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002221 * None.
Stefan Roese45993ea2006-11-29 15:42:37 +01002222 *
2223 * RETURN:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002224 * PHY address.
Stefan Roese45993ea2006-11-29 15:42:37 +01002225 *
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:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002266 * 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.
Stefan Roese45993ea2006-11-29 15:42:37 +01002268 *
2269 * INPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002270 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
Stefan Roese45993ea2006-11-29 15:42:37 +01002271 *
2272 * OUTPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002273 * The ethernet port PHY renew its link.
Stefan Roese45993ea2006-11-29 15:42:37 +01002274 *
2275 * RETURN:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002276 * None.
Stefan Roese45993ea2006-11-29 15:42:37 +01002277 *
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);
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002285 phy_reg_data |= 0x0083; /* Set bit 7 to 1 for different RGMII timing */
Stefan Roese45993ea2006-11-29 15:42:37 +01002286 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);
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002290 phy_reg_data |= 0x8000; /* Set bit 15 to reset the PHY */
Stefan Roese45993ea2006-11-29 15:42:37 +01002291 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:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002309 * 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.
Stefan Roese45993ea2006-11-29 15:42:37 +01002312 *
2313 * INPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002314 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
Stefan Roese45993ea2006-11-29 15:42:37 +01002315 *
2316 * OUTPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002317 * Channel activity is halted.
Stefan Roese45993ea2006-11-29 15:42:37 +01002318 *
2319 * RETURN:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002320 * None.
Stefan Roese45993ea2006-11-29 15:42:37 +01002321 *
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:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002388 * This function sets specified bits in the given ethernet
2389 * configuration register.
Stefan Roese45993ea2006-11-29 15:42:37 +01002390 *
2391 * INPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002392 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
2393 * unsigned int value 32 bit value.
Stefan Roese45993ea2006-11-29 15:42:37 +01002394 *
2395 * OUTPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002396 * The set bits in the value parameter are set in the configuration
2397 * register.
Stefan Roese45993ea2006-11-29 15:42:37 +01002398 *
2399 * RETURN:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002400 * None.
Stefan Roese45993ea2006-11-29 15:42:37 +01002401 *
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:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002423 * This function resets specified bits in the given Ethernet
2424 * configuration register.
Stefan Roese45993ea2006-11-29 15:42:37 +01002425 *
2426 * INPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002427 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
2428 * unsigned int value 32 bit value.
Stefan Roese45993ea2006-11-29 15:42:37 +01002429 *
2430 * OUTPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002431 * The set bits in the value parameter are reset in the configuration
2432 * register.
Stefan Roese45993ea2006-11-29 15:42:37 +01002433 *
2434 * RETURN:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002435 * None.
Stefan Roese45993ea2006-11-29 15:42:37 +01002436 *
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:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002458 * This function returns the configuration register value of the given
2459 * ethernet port.
Stefan Roese45993ea2006-11-29 15:42:37 +01002460 *
2461 * INPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002462 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
Stefan Roese45993ea2006-11-29 15:42:37 +01002463 *
2464 * OUTPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002465 * None.
Stefan Roese45993ea2006-11-29 15:42:37 +01002466 *
2467 * RETURN:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002468 * Port configuration register value.
Stefan Roese45993ea2006-11-29 15:42:37 +01002469 *
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:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002486 * This routine utilize the SMI interface to interact with the PHY in
2487 * order to perform PHY register read.
Stefan Roese45993ea2006-11-29 15:42:37 +01002488 *
2489 * INPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002490 * 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.
Stefan Roese45993ea2006-11-29 15:42:37 +01002493 *
2494 * OUTPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002495 * Write the value of a specified PHY register into given buffer.
Stefan Roese45993ea2006-11-29 15:42:37 +01002496 *
2497 * RETURN:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002498 * false if the PHY is busy or read data is not in valid state.
2499 * true otherwise.
Stefan Roese45993ea2006-11-29 15:42:37 +01002500 *
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 }
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002534 while ((reg_value & ETH_SMI_READ_VALID) != ETH_SMI_READ_VALID); /* Bit set equ operation done */
Stefan Roese45993ea2006-11-29 15:42:37 +01002535
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 }
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002575 while ((reg_value & ETH_SMI_READ_VALID) != ETH_SMI_READ_VALID); /* Bit set equ operation done */
Stefan Roese45993ea2006-11-29 15:42:37 +01002576
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:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002591 * This routine utilize the SMI interface to interact with the PHY in
2592 * order to perform writes to PHY registers.
Stefan Roese45993ea2006-11-29 15:42:37 +01002593 *
2594 * INPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002595 * 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.
Stefan Roese45993ea2006-11-29 15:42:37 +01002598 *
2599 * OUTPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002600 * Write the given value to the specified PHY register.
Stefan Roese45993ea2006-11-29 15:42:37 +01002601 *
2602 * RETURN:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002603 * false if the PHY is busy.
2604 * true otherwise.
Stefan Roese45993ea2006-11-29 15:42:37 +01002605 *
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:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002658 * This function configures the address decode parameters for the Gigabit
2659 * Ethernet Controller according the given parameters struct.
Stefan Roese45993ea2006-11-29 15:42:37 +01002660 *
2661 * INPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002662 * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
2663 * ETH_WIN_PARAM *param Address decode parameter struct.
Stefan Roese45993ea2006-11-29 15:42:37 +01002664 *
2665 * OUTPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002666 * An access window is opened using the given access parameters.
Stefan Roese45993ea2006-11-29 15:42:37 +01002667 *
2668 * RETURN:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002669 * None.
Stefan Roese45993ea2006-11-29 15:42:37 +01002670 *
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:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002712 * 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.
Stefan Roese45993ea2006-11-29 15:42:37 +01002719 *
2720 * INPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002721 * 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.
Stefan Roese45993ea2006-11-29 15:42:37 +01002727 *
2728 * OUTPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002729 * The routine updates the Ethernet port control struct with information
2730 * regarding the Rx descriptors and buffers.
Stefan Roese45993ea2006-11-29 15:42:37 +01002731 *
2732 * RETURN:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002733 * false if the given descriptors memory area is not aligned according to
2734 * Ethernet SDMA specifications.
2735 * true otherwise.
Stefan Roese45993ea2006-11-29 15:42:37 +01002736 *
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
Stefan Roese45993ea2006-11-29 15:42:37 +01002750 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
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002762 /* Rx buffers must be 64-bit aligned. */
Stefan Roese45993ea2006-11-29 15:42:37 +01002763 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:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002805 * 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.
Stefan Roese45993ea2006-11-29 15:42:37 +01002812 *
2813 * INPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002814 * 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.
Stefan Roese45993ea2006-11-29 15:42:37 +01002820 *
2821 * OUTPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002822 * The routine updates the Ethernet port control struct with information
2823 * regarding the Tx descriptors and buffers.
Stefan Roese45993ea2006-11-29 15:42:37 +01002824 *
2825 * RETURN:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002826 * false if the given descriptors memory area is not aligned according to
2827 * Ethernet SDMA specifications.
2828 * true otherwise.
Stefan Roese45993ea2006-11-29 15:42:37 +01002829 *
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
Stefan Roese45993ea2006-11-29 15:42:37 +01002844 /* 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
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002899 * 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.
Stefan Roese45993ea2006-11-29 15:42:37 +01002906 *
2907 * INPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002908 * 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.
Stefan Roese45993ea2006-11-29 15:42:37 +01002911 *
2912 * OUTPUT:
2913 * Tx ring 'curr' and 'first' indexes are updated.
2914 *
2915 * RETURN:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002916 * ETH_QUEUE_FULL in case of Tx resource error.
Stefan Roese45993ea2006-11-29 15:42:37 +01002917 * 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.
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002919 * ETH_OK otherwise.
Stefan Roese45993ea2006-11-29 15:42:37 +01002920 *
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 */
Wolfgang Denkdd314e02006-11-30 01:54:07 +01002957 /* boundary. We use the memory allocated for Tx descriptor. This memory */
Stefan Roese45993ea2006-11-29 15:42:37 +01002958 /* 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.
Wolfgang Denkdd314e02006-11-30 01:54:07 +01003018 * 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.
Stefan Roese45993ea2006-11-29 15:42:37 +01003022 *
3023 * INPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01003024 * 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.
Stefan Roese45993ea2006-11-29 15:42:37 +01003027 *
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.
Wolfgang Denkdd314e02006-11-30 01:54:07 +01003033 * ETH_RETRY in case there is transmission in process.
Stefan Roese45993ea2006-11-29 15:42:37 +01003034 * ETH_END_OF_JOB if the routine has nothing to release.
Wolfgang Denkdd314e02006-11-30 01:54:07 +01003035 * ETH_OK otherwise.
Stefan Roese45993ea2006-11-29 15:42:37 +01003036 *
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
Stefan Roese45993ea2006-11-29 15:42:37 +01003047 /* 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
Stefan Roese45993ea2006-11-29 15:42:37 +01003051 /* 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:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01003092 * This routine returns the received data to the caller. There is no
Stefan Roese45993ea2006-11-29 15:42:37 +01003093 * data copying during routine operation. All information is returned
3094 * using pointer to packet information struct passed from the caller.
Wolfgang Denkdd314e02006-11-30 01:54:07 +01003095 * If the routine exhausts Rx ring resources then the resource error flag
3096 * is set.
Stefan Roese45993ea2006-11-29 15:42:37 +01003097 *
3098 * INPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01003099 * 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.
Stefan Roese45993ea2006-11-29 15:42:37 +01003102 *
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.
Wolfgang Denkdd314e02006-11-30 01:54:07 +01003110 * ETH_OK otherwise.
Stefan Roese45993ea2006-11-29 15:42:37 +01003111 *
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)) {
Wolfgang Denkdd314e02006-11-30 01:54:07 +01003142/* DP(printf("Rx: command_status: %08x\n", command_status)); */
Stefan Roese45993ea2006-11-29 15:42:37 +01003143 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;
Wolfgang Denkdd314e02006-11-30 01:54:07 +01003152 p_pkt_info->l4i_chk = p_rx_curr_desc->buf_size; /* IP fragment indicator */
Stefan Roese45993ea2006-11-29 15:42:37 +01003153
3154 /* Clean the return info field to indicate that the packet has been */
Wolfgang Denkdd314e02006-11-30 01:54:07 +01003155 /* moved to the upper layers */
Stefan Roese45993ea2006-11-29 15:42:37 +01003156 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
Wolfgang Denkdd314e02006-11-30 01:54:07 +01003176 * 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.
Stefan Roese45993ea2006-11-29 15:42:37 +01003179 *
3180 * INPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01003181 * 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.
Stefan Roese45993ea2006-11-29 15:42:37 +01003184 *
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.
Wolfgang Denkdd314e02006-11-30 01:54:07 +01003190 * ETH_OK otherwise.
Stefan Roese45993ea2006-11-29 15:42:37 +01003191 *
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:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01003245 * 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
Stefan Roese45993ea2006-11-29 15:42:37 +01003248 *
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:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01003286 * 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
Stefan Roese45993ea2006-11-29 15:42:37 +01003289 *
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:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01003316 * 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.
Stefan Roese45993ea2006-11-29 15:42:37 +01003319 *
3320 * INPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01003321 * 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.
Stefan Roese45993ea2006-11-29 15:42:37 +01003324 *
3325 * OUTPUT:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01003326 * See description.
Stefan Roese45993ea2006-11-29 15:42:37 +01003327 *
3328 * RETURN:
Wolfgang Denkdd314e02006-11-30 01:54:07 +01003329 * None.
Stefan Roese45993ea2006-11-29 15:42:37 +01003330 *
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}