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