davinci_emac.c 21.1 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/*
 * Ethernet driver for TI TMS320DM644x (DaVinci) chips.
 *
 * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
 *
 * Parts shamelessly stolen from TI's dm644x_emac.c. Original copyright
 * follows:
 *
 * ----------------------------------------------------------------------------
 *
 * dm644x_emac.c
 *
 * TI DaVinci (DM644X) EMAC peripheral driver source for DV-EVM
 *
 * Copyright (C) 2005 Texas Instruments.
 *
 * ----------------------------------------------------------------------------
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 * ----------------------------------------------------------------------------

 * Modifications:
 * ver. 1.0: Sep 2005, Anant Gole - Created EMAC version for uBoot.
 * ver  1.1: Nov 2005, Anant Gole - Extended the RX logic for multiple descriptors
 *
 */
#include <common.h>
#include <command.h>
#include <net.h>
#include <miiphy.h>
43
#include <malloc.h>
44
#include <asm/arch/emac_defs.h>
45
#include <asm/io.h>
46
47
48
49

unsigned int	emac_dbg = 0;
#define debug_emac(fmt,args...)	if (emac_dbg) printf(fmt,##args)

50
#ifdef DAVINCI_EMAC_GIG_ENABLE
51
#define emac_gigabit_enable(phy_addr)	davinci_eth_gigabit_enable(phy_addr)
52
#else
53
#define emac_gigabit_enable(phy_addr)	/* no gigabit to enable */
54
55
#endif

56
static void davinci_eth_mdio_enable(void);
57
58
59
60
61
62
63
64

static int gen_init_phy(int phy_addr);
static int gen_is_phy_connected(int phy_addr);
static int gen_get_link_speed(int phy_addr);
static int gen_auto_negotiate(int phy_addr);

void eth_mdio_enable(void)
{
65
	davinci_eth_mdio_enable();
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
}

/* EMAC Addresses */
static volatile emac_regs	*adap_emac = (emac_regs *)EMAC_BASE_ADDR;
static volatile ewrap_regs	*adap_ewrap = (ewrap_regs *)EMAC_WRAPPER_BASE_ADDR;
static volatile mdio_regs	*adap_mdio = (mdio_regs *)EMAC_MDIO_BASE_ADDR;

/* EMAC descriptors */
static volatile emac_desc	*emac_rx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_RX_DESC_BASE);
static volatile emac_desc	*emac_tx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_TX_DESC_BASE);
static volatile emac_desc	*emac_rx_active_head = 0;
static volatile emac_desc	*emac_rx_active_tail = 0;
static int			emac_rx_queue_active = 0;

/* Receive packet buffers */
static unsigned char		emac_rx_buffers[EMAC_MAX_RX_BUFFERS * (EMAC_MAX_ETHERNET_PKT_SIZE + EMAC_PKT_ALIGN)];

83
84
#define MAX_PHY		3

85
/* PHY address for a discovered PHY (0xff - not found) */
86
87
88
89
static u_int8_t	active_phy_addr[MAX_PHY] = { 0xff, 0xff, 0xff };

/* number of PHY found active */
static u_int8_t	num_phy;
90

91
phy_t				phy[MAX_PHY];
92

93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
static int davinci_eth_set_mac_addr(struct eth_device *dev)
{
	unsigned long		mac_hi;
	unsigned long		mac_lo;

	/*
	 * Set MAC Addresses & Init multicast Hash to 0 (disable any multicast
	 * receive)
	 *  Using channel 0 only - other channels are disabled
	 *  */
	writel(0, &adap_emac->MACINDEX);
	mac_hi = (dev->enetaddr[3] << 24) |
		 (dev->enetaddr[2] << 16) |
		 (dev->enetaddr[1] << 8)  |
		 (dev->enetaddr[0]);
	mac_lo = (dev->enetaddr[5] << 8) |
		 (dev->enetaddr[4]);

	writel(mac_hi, &adap_emac->MACADDRHI);
#if defined(DAVINCI_EMAC_VERSION2)
	writel(mac_lo | EMAC_MAC_ADDR_IS_VALID | EMAC_MAC_ADDR_MATCH,
	       &adap_emac->MACADDRLO);
#else
	writel(mac_lo, &adap_emac->MACADDRLO);
#endif

	writel(0, &adap_emac->MACHASH1);
	writel(0, &adap_emac->MACHASH2);

	/* Set source MAC address - REQUIRED */
	writel(mac_hi, &adap_emac->MACSRCADDRHI);
	writel(mac_lo, &adap_emac->MACSRCADDRLO);


	return 0;
}

130
static void davinci_eth_mdio_enable(void)
131
132
133
134
135
{
	u_int32_t	clkdiv;

	clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;

136
137
138
139
140
	writel((clkdiv & 0xff) |
	       MDIO_CONTROL_ENABLE |
	       MDIO_CONTROL_FAULT |
	       MDIO_CONTROL_FAULT_ENABLE,
	       &adap_mdio->CONTROL);
141

142
143
	while (readl(&adap_mdio->CONTROL) & MDIO_CONTROL_IDLE)
		;
144
145
146
147
148
149
150
}

/*
 * Tries to find an active connected PHY. Returns 1 if address if found.
 * If no active PHY (or more than one PHY) found returns 0.
 * Sets active_phy_addr variable.
 */
151
static int davinci_eth_phy_detect(void)
152
153
154
{
	u_int32_t	phy_act_state;
	int		i;
155
156
157
158
159
160
	int		j;
	unsigned int	count = 0;

	active_phy_addr[0] = 0xff;
	active_phy_addr[1] = 0xff;
	active_phy_addr[2] = 0xff;
161

162
163
	udelay(1000);
	phy_act_state = readl(&adap_mdio->ALIVE);
164

165
	if (phy_act_state == 0)
166
		return 0;		/* No active PHYs */
167

168
	debug_emac("davinci_eth_phy_detect(), ALIVE = 0x%08x\n", phy_act_state);
169

170
	for (i = 0, j = 0; i < 32; i++)
171
		if (phy_act_state & (1 << i)) {
172
173
			count++;
			active_phy_addr[j++] = i;
174
175
		}

176
177
178
	num_phy = count;

	return count;
179
180
181
182
}


/* Read a PHY register via MDIO inteface. Returns 1 on success, 0 otherwise */
183
int davinci_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data)
184
185
186
{
	int	tmp;

187
188
	while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO)
		;
189

190
191
192
193
194
	writel(MDIO_USERACCESS0_GO |
	       MDIO_USERACCESS0_WRITE_READ |
	       ((reg_num & 0x1f) << 21) |
	       ((phy_addr & 0x1f) << 16),
	       &adap_mdio->USERACCESS0);
195
196

	/* Wait for command to complete */
197
198
	while ((tmp = readl(&adap_mdio->USERACCESS0)) & MDIO_USERACCESS0_GO)
		;
199
200
201
202
203
204
205
206
207
208
209

	if (tmp & MDIO_USERACCESS0_ACK) {
		*data = tmp & 0xffff;
		return(1);
	}

	*data = -1;
	return(0);
}

/* Write to a PHY register via MDIO inteface. Blocks until operation is complete. */
210
int davinci_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data)
211
212
{

213
214
	while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO)
		;
215

216
217
218
219
220
221
	writel(MDIO_USERACCESS0_GO |
	       MDIO_USERACCESS0_WRITE_WRITE |
	       ((reg_num & 0x1f) << 21) |
	       ((phy_addr & 0x1f) << 16) |
	       (data & 0xffff),
	       &adap_mdio->USERACCESS0);
222
223

	/* Wait for command to complete */
224
225
	while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO)
		;
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246

	return(1);
}

/* PHY functions for a generic PHY */
static int gen_init_phy(int phy_addr)
{
	int	ret = 1;

	if (gen_get_link_speed(phy_addr)) {
		/* Try another time */
		ret = gen_get_link_speed(phy_addr);
	}

	return(ret);
}

static int gen_is_phy_connected(int phy_addr)
{
	u_int16_t	dummy;

247
248
249
250
251
252
253
254
255
256
257
258
	return davinci_eth_phy_read(phy_addr, MII_PHYSID1, &dummy);
}

static int get_active_phy(void)
{
	int i;

	for (i = 0; i < num_phy; i++)
		if (phy[i].get_link_speed(active_phy_addr[i]))
			return i;

	return -1;	/* Return error if no link */
259
260
261
262
263
264
}

static int gen_get_link_speed(int phy_addr)
{
	u_int16_t	tmp;

265
266
267
268
	if (davinci_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp) &&
			(tmp & 0x04)) {
#if defined(CONFIG_DRIVER_TI_EMAC_USE_RMII) && \
		defined(CONFIG_MACH_DAVINCI_DA850_EVM)
269
		davinci_eth_phy_read(phy_addr, MII_LPA, &tmp);
270
271

		/* Speed doesn't matter, there is no setting for it in EMAC. */
272
		if (tmp & (LPA_100FULL | LPA_10FULL)) {
273
274
275
276
277
278
279
280
281
282
			/* set EMAC for Full Duplex  */
			writel(EMAC_MACCONTROL_MIIEN_ENABLE |
					EMAC_MACCONTROL_FULLDUPLEX_ENABLE,
					&adap_emac->MACCONTROL);
		} else {
			/*set EMAC for Half Duplex  */
			writel(EMAC_MACCONTROL_MIIEN_ENABLE,
					&adap_emac->MACCONTROL);
		}

283
		if (tmp & (LPA_100FULL | LPA_100HALF))
284
285
286
287
288
289
290
291
			writel(readl(&adap_emac->MACCONTROL) |
					EMAC_MACCONTROL_RMIISPEED_100,
					 &adap_emac->MACCONTROL);
		else
			writel(readl(&adap_emac->MACCONTROL) &
					~EMAC_MACCONTROL_RMIISPEED_100,
					 &adap_emac->MACCONTROL);
#endif
292
		return(1);
293
	}
294
295
296
297
298
299
300

	return(0);
}

static int gen_auto_negotiate(int phy_addr)
{
	u_int16_t	tmp;
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
	u_int16_t	val;
	unsigned long	cntr = 0;

	if (!davinci_eth_phy_read(phy_addr, MII_BMCR, &tmp))
		return 0;

	val = tmp | BMCR_FULLDPLX | BMCR_ANENABLE |
						BMCR_SPEED100;
	davinci_eth_phy_write(phy_addr, MII_BMCR, val);

	if (!davinci_eth_phy_read(phy_addr, MII_ADVERTISE, &val))
		return 0;

	val |= (ADVERTISE_100FULL | ADVERTISE_100HALF | ADVERTISE_10FULL |
							ADVERTISE_10HALF);
	davinci_eth_phy_write(phy_addr, MII_ADVERTISE, val);
317

318
	if (!davinci_eth_phy_read(phy_addr, MII_BMCR, &tmp))
319
320
321
		return(0);

	/* Restart Auto_negotiation  */
322
	tmp |= BMCR_ANRESTART;
323
	davinci_eth_phy_write(phy_addr, MII_BMCR, tmp);
324
325

	/*check AutoNegotiate complete */
326
327
328
329
330
331
332
333
334
335
336
	do {
		udelay(40000);
		if (!davinci_eth_phy_read(phy_addr, MII_BMSR, &tmp))
			return 0;

		if (tmp & BMSR_ANEGCOMPLETE)
			break;

		cntr++;
	} while (cntr < 200);

337
	if (!davinci_eth_phy_read(phy_addr, MII_BMSR, &tmp))
338
339
		return(0);

340
	if (!(tmp & BMSR_ANEGCOMPLETE))
341
342
343
344
345
346
347
		return(0);

	return(gen_get_link_speed(phy_addr));
}
/* End of generic PHY functions */


348
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
Mike Frysinger's avatar
Mike Frysinger committed
349
static int davinci_mii_phy_read(const char *devname, unsigned char addr, unsigned char reg, unsigned short *value)
350
{
351
	return(davinci_eth_phy_read(addr, reg, value) ? 0 : 1);
352
353
}

Mike Frysinger's avatar
Mike Frysinger committed
354
static int davinci_mii_phy_write(const char *devname, unsigned char addr, unsigned char reg, unsigned short value)
355
{
356
	return(davinci_eth_phy_write(addr, reg, value) ? 0 : 1);
357
358
359
}
#endif

360
static void  __attribute__((unused)) davinci_eth_gigabit_enable(int phy_addr)
361
362
363
{
	u_int16_t data;

364
	if (davinci_eth_phy_read(phy_addr, 0, &data)) {
365
366
367
368
369
		if (data & (1 << 6)) { /* speed selection MSB */
			/*
			 * Check if link detected is giga-bit
			 * If Gigabit mode detected, enable gigbit in MAC
			 */
370
371
372
373
			writel(readl(&adap_emac->MACCONTROL) |
				EMAC_MACCONTROL_GIGFORCE |
				EMAC_MACCONTROL_GIGABIT_ENABLE,
				&adap_emac->MACCONTROL);
374
375
376
		}
	}
}
377
378

/* Eth device open */
379
static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
380
381
382
383
{
	dv_reg_p		addr;
	u_int32_t		clkdiv, cnt;
	volatile emac_desc	*rx_desc;
384
	int			index;
385
386
387
388

	debug_emac("+ emac_open\n");

	/* Reset EMAC module and disable interrupts in wrapper */
389
390
391
392
393
394
395
396
397
	writel(1, &adap_emac->SOFTRESET);
	while (readl(&adap_emac->SOFTRESET) != 0)
		;
#if defined(DAVINCI_EMAC_VERSION2)
	writel(1, &adap_ewrap->softrst);
	while (readl(&adap_ewrap->softrst) != 0)
		;
#else
	writel(0, &adap_ewrap->EWCTL);
398
	for (cnt = 0; cnt < 5; cnt++) {
399
		clkdiv = readl(&adap_ewrap->EWCTL);
400
	}
401
#endif
402

403
404
405
406
407
408
#if defined(CONFIG_DRIVER_TI_EMAC_USE_RMII) && \
	defined(CONFIG_MACH_DAVINCI_DA850_EVM)
	adap_ewrap->c0rxen = adap_ewrap->c1rxen = adap_ewrap->c2rxen = 0;
	adap_ewrap->c0txen = adap_ewrap->c1txen = adap_ewrap->c2txen = 0;
	adap_ewrap->c0miscen = adap_ewrap->c1miscen = adap_ewrap->c2miscen = 0;
#endif
409
410
	rx_desc = emac_rx_desc;

411
412
	writel(1, &adap_emac->TXCONTROL);
	writel(1, &adap_emac->RXCONTROL);
413

414
	davinci_eth_set_mac_addr(dev);
415
416
417
418

	/* Set DMA 8 TX / 8 RX Head pointers to 0 */
	addr = &adap_emac->TX0HDP;
	for(cnt = 0; cnt < 16; cnt++)
419
		writel(0, addr++);
420
421
422

	addr = &adap_emac->RX0HDP;
	for(cnt = 0; cnt < 16; cnt++)
423
		writel(0, addr++);
424
425
426
427

	/* Clear Statistics (do this before setting MacControl register) */
	addr = &adap_emac->RXGOODFRAMES;
	for(cnt = 0; cnt < EMAC_NUM_STATS; cnt++)
428
		writel(0, addr++);
429
430

	/* No multicast addressing */
431
432
	writel(0, &adap_emac->MACHASH1);
	writel(0, &adap_emac->MACHASH2);
433
434
435
436
437
438
439
440
441
442
443

	/* Create RX queue and set receive process in place */
	emac_rx_active_head = emac_rx_desc;
	for (cnt = 0; cnt < EMAC_MAX_RX_BUFFERS; cnt++) {
		rx_desc->next = (u_int32_t)(rx_desc + 1);
		rx_desc->buffer = &emac_rx_buffers[cnt * (EMAC_MAX_ETHERNET_PKT_SIZE + EMAC_PKT_ALIGN)];
		rx_desc->buff_off_len = EMAC_MAX_ETHERNET_PKT_SIZE;
		rx_desc->pkt_flag_len = EMAC_CPPI_OWNERSHIP_BIT;
		rx_desc++;
	}

444
	/* Finalize the rx desc list */
445
446
447
448
449
450
	rx_desc--;
	rx_desc->next = 0;
	emac_rx_active_tail = rx_desc;
	emac_rx_queue_active = 1;

	/* Enable TX/RX */
451
452
	writel(EMAC_MAX_ETHERNET_PKT_SIZE, &adap_emac->RXMAXLEN);
	writel(0, &adap_emac->RXBUFFEROFFSET);
453

454
455
456
457
458
	/*
	 * No fancy configs - Use this for promiscous debug
	 *   - EMAC_RXMBPENABLE_RXCAFEN_ENABLE
	 */
	writel(EMAC_RXMBPENABLE_RXBROADEN, &adap_emac->RXMBPENABLE);
459
460

	/* Enable ch 0 only */
461
	writel(1, &adap_emac->RXUNICASTSET);
462
463

	/* Enable MII interface and Full duplex mode */
464
465
466
467
468
469
470
471
472
473
#ifdef CONFIG_SOC_DA8XX
	writel((EMAC_MACCONTROL_MIIEN_ENABLE |
		EMAC_MACCONTROL_FULLDUPLEX_ENABLE |
		EMAC_MACCONTROL_RMIISPEED_100),
	       &adap_emac->MACCONTROL);
#else
	writel((EMAC_MACCONTROL_MIIEN_ENABLE |
		EMAC_MACCONTROL_FULLDUPLEX_ENABLE),
	       &adap_emac->MACCONTROL);
#endif
474
475
476

	/* Init MDIO & get link state */
	clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
477
478
479
480
481
	writel((clkdiv & 0xff) | MDIO_CONTROL_ENABLE | MDIO_CONTROL_FAULT,
	       &adap_mdio->CONTROL);

	/* We need to wait for MDIO to start */
	udelay(1000);
482

483
484
	index = get_active_phy();
	if (index == -1)
485
486
		return(0);

487
	emac_gigabit_enable(active_phy_addr[index]);
488

489
	/* Start receive process */
490
	writel((u_int32_t)emac_rx_desc, &adap_emac->RX0HDP);
491
492
493
494
495
496
497

	debug_emac("- emac_open\n");

	return(1);
}

/* EMAC Channel Teardown */
498
static void davinci_eth_ch_teardown(int ch)
499
500
501
502
503
504
505
506
{
	dv_reg		dly = 0xff;
	dv_reg		cnt;

	debug_emac("+ emac_ch_teardown\n");

	if (ch == EMAC_CH_TX) {
		/* Init TX channel teardown */
507
		writel(0, &adap_emac->TXTEARDOWN);
508
509
510
511
512
513
514
515
516
517
518
		do {
			/*
			 * Wait here for Tx teardown completion interrupt to
			 * occur. Note: A task delay can be called here to pend
			 * rather than occupying CPU cycles - anyway it has
			 * been found that teardown takes very few cpu cycles
			 * and does not affect functionality
			 */
			dly--;
			udelay(1);
			if (dly == 0)
Wolfgang Denk's avatar
Wolfgang Denk committed
519
				break;
520
521
522
523
			cnt = readl(&adap_emac->TX0CP);
		} while (cnt != 0xfffffffc);
		writel(cnt, &adap_emac->TX0CP);
		writel(0, &adap_emac->TX0HDP);
524
525
	} else {
		/* Init RX channel teardown */
526
		writel(0, &adap_emac->RXTEARDOWN);
527
528
529
530
531
532
533
534
535
536
537
		do {
			/*
			 * Wait here for Rx teardown completion interrupt to
			 * occur. Note: A task delay can be called here to pend
			 * rather than occupying CPU cycles - anyway it has
			 * been found that teardown takes very few cpu cycles
			 * and does not affect functionality
			 */
			dly--;
			udelay(1);
			if (dly == 0)
Wolfgang Denk's avatar
Wolfgang Denk committed
538
				break;
539
540
541
542
			cnt = readl(&adap_emac->RX0CP);
		} while (cnt != 0xfffffffc);
		writel(cnt, &adap_emac->RX0CP);
		writel(0, &adap_emac->RX0HDP);
543
544
545
546
547
548
	}

	debug_emac("- emac_ch_teardown\n");
}

/* Eth device close */
549
static void davinci_eth_close(struct eth_device *dev)
550
551
552
{
	debug_emac("+ emac_close\n");

553
554
	davinci_eth_ch_teardown(EMAC_CH_TX);	/* TX Channel teardown */
	davinci_eth_ch_teardown(EMAC_CH_RX);	/* RX Channel teardown */
555
556

	/* Reset EMAC module and disable interrupts in wrapper */
557
558
559
560
561
562
	writel(1, &adap_emac->SOFTRESET);
#if defined(DAVINCI_EMAC_VERSION2)
	writel(1, &adap_ewrap->softrst);
#else
	writel(0, &adap_ewrap->EWCTL);
#endif
563

564
565
566
567
568
569
#if defined(CONFIG_DRIVER_TI_EMAC_USE_RMII) && \
	defined(CONFIG_MACH_DAVINCI_DA850_EVM)
	adap_ewrap->c0rxen = adap_ewrap->c1rxen = adap_ewrap->c2rxen = 0;
	adap_ewrap->c0txen = adap_ewrap->c1txen = adap_ewrap->c2txen = 0;
	adap_ewrap->c0miscen = adap_ewrap->c1miscen = adap_ewrap->c2miscen = 0;
#endif
570
571
572
573
574
575
576
577
578
	debug_emac("- emac_close\n");
}

static int tx_send_loop = 0;

/*
 * This function sends a single packet on the network and returns
 * positive number (number of bytes transmitted) or negative for error
 */
579
580
static int davinci_eth_send_packet (struct eth_device *dev,
					volatile void *packet, int length)
581
582
{
	int ret_status = -1;
583
	int index;
584
585
	tx_send_loop = 0;

586
587
588
	index = get_active_phy();
	if (index == -1) {
		printf(" WARN: emac_send_packet: No link\n");
589
590
591
		return (ret_status);
	}

592
	emac_gigabit_enable(active_phy_addr[index]);
593

594
	/* Check packet size and if < EMAC_MIN_ETHERNET_PKT_SIZE, pad it up */
Wolfgang Denk's avatar
Wolfgang Denk committed
595
	if (length < EMAC_MIN_ETHERNET_PKT_SIZE) {
596
597
598
599
		length = EMAC_MIN_ETHERNET_PKT_SIZE;
	}

	/* Populate the TX descriptor */
Wolfgang Denk's avatar
Wolfgang Denk committed
600
601
	emac_tx_desc->next = 0;
	emac_tx_desc->buffer = (u_int8_t *) packet;
602
603
	emac_tx_desc->buff_off_len = (length & 0xffff);
	emac_tx_desc->pkt_flag_len = ((length & 0xffff) |
Wolfgang Denk's avatar
Wolfgang Denk committed
604
605
606
				      EMAC_CPPI_SOP_BIT |
				      EMAC_CPPI_OWNERSHIP_BIT |
				      EMAC_CPPI_EOP_BIT);
607
	/* Send the packet */
608
	writel((unsigned long)emac_tx_desc, &adap_emac->TX0HDP);
609
610
611

	/* Wait for packet to complete or link down */
	while (1) {
612
		if (!phy[index].get_link_speed(active_phy_addr[index])) {
613
			davinci_eth_ch_teardown (EMAC_CH_TX);
Wolfgang Denk's avatar
Wolfgang Denk committed
614
615
			return (ret_status);
		}
616

617
		emac_gigabit_enable(active_phy_addr[index]);
618
619

		if (readl(&adap_emac->TXINTSTATRAW) & 0x01) {
Wolfgang Denk's avatar
Wolfgang Denk committed
620
621
			ret_status = length;
			break;
622
		}
Wolfgang Denk's avatar
Wolfgang Denk committed
623
		tx_send_loop++;
624
625
	}

Wolfgang Denk's avatar
Wolfgang Denk committed
626
	return (ret_status);
627
628
629
630
631
}

/*
 * This function handles receipt of a packet from the network
 */
632
static int davinci_eth_rcv_packet (struct eth_device *dev)
633
{
Wolfgang Denk's avatar
Wolfgang Denk committed
634
635
636
637
	volatile emac_desc *rx_curr_desc;
	volatile emac_desc *curr_desc;
	volatile emac_desc *tail_desc;
	int status, ret = -1;
638
639
640
641

	rx_curr_desc = emac_rx_active_head;
	status = rx_curr_desc->pkt_flag_len;
	if ((rx_curr_desc) && ((status & EMAC_CPPI_OWNERSHIP_BIT) == 0)) {
Wolfgang Denk's avatar
Wolfgang Denk committed
642
643
644
		if (status & EMAC_CPPI_RX_ERROR_FRAME) {
			/* Error in packet - discard it and requeue desc */
			printf ("WARN: emac_rcv_pkt: Error in packet\n");
645
		} else {
Wolfgang Denk's avatar
Wolfgang Denk committed
646
647
			NetReceive (rx_curr_desc->buffer,
				    (rx_curr_desc->buff_off_len & 0xffff));
648
			ret = rx_curr_desc->buff_off_len & 0xffff;
Wolfgang Denk's avatar
Wolfgang Denk committed
649
		}
650

Wolfgang Denk's avatar
Wolfgang Denk committed
651
		/* Ack received packet descriptor */
652
		writel((unsigned long)rx_curr_desc, &adap_emac->RX0CP);
Wolfgang Denk's avatar
Wolfgang Denk committed
653
654
655
		curr_desc = rx_curr_desc;
		emac_rx_active_head =
			(volatile emac_desc *) rx_curr_desc->next;
656

Wolfgang Denk's avatar
Wolfgang Denk committed
657
658
		if (status & EMAC_CPPI_EOQ_BIT) {
			if (emac_rx_active_head) {
659
660
				writel((unsigned long)emac_rx_active_head,
				       &adap_emac->RX0HDP);
661
662
			} else {
				emac_rx_queue_active = 0;
Wolfgang Denk's avatar
Wolfgang Denk committed
663
				printf ("INFO:emac_rcv_packet: RX Queue not active\n");
664
665
666
667
668
669
670
671
672
			}
		}

		/* Recycle RX descriptor */
		rx_curr_desc->buff_off_len = EMAC_MAX_ETHERNET_PKT_SIZE;
		rx_curr_desc->pkt_flag_len = EMAC_CPPI_OWNERSHIP_BIT;
		rx_curr_desc->next = 0;

		if (emac_rx_active_head == 0) {
Wolfgang Denk's avatar
Wolfgang Denk committed
673
			printf ("INFO: emac_rcv_pkt: active queue head = 0\n");
674
675
676
			emac_rx_active_head = curr_desc;
			emac_rx_active_tail = curr_desc;
			if (emac_rx_queue_active != 0) {
677
678
				writel((unsigned long)emac_rx_active_head,
				       &adap_emac->RX0HDP);
Wolfgang Denk's avatar
Wolfgang Denk committed
679
				printf ("INFO: emac_rcv_pkt: active queue head = 0, HDP fired\n");
680
681
682
683
684
				emac_rx_queue_active = 1;
			}
		} else {
			tail_desc = emac_rx_active_tail;
			emac_rx_active_tail = curr_desc;
Wolfgang Denk's avatar
Wolfgang Denk committed
685
			tail_desc->next = (unsigned int) curr_desc;
686
687
			status = tail_desc->pkt_flag_len;
			if (status & EMAC_CPPI_EOQ_BIT) {
688
689
				writel((unsigned long)curr_desc,
				       &adap_emac->RX0HDP);
690
691
692
693
				status &= ~EMAC_CPPI_EOQ_BIT;
				tail_desc->pkt_flag_len = status;
			}
		}
Wolfgang Denk's avatar
Wolfgang Denk committed
694
		return (ret);
695
	}
Wolfgang Denk's avatar
Wolfgang Denk committed
696
	return (0);
697
698
}

699
700
701
702
703
/*
 * This function initializes the emac hardware. It does NOT initialize
 * EMAC modules power or pin multiplexors, that is done by board_init()
 * much earlier in bootup process. Returns 1 on success, 0 otherwise.
 */
704
int davinci_emac_initialize(void)
705
706
707
708
{
	u_int32_t	phy_id;
	u_int16_t	tmp;
	int		i;
709
	int		ret;
710
711
712
713
714
715
716
717
	struct eth_device *dev;

	dev = malloc(sizeof *dev);

	if (dev == NULL)
		return -1;

	memset(dev, 0, sizeof *dev);
718
	sprintf(dev->name, "DaVinci-EMAC");
719
720
721
722
723
724

	dev->iobase = 0;
	dev->init = davinci_eth_open;
	dev->halt = davinci_eth_close;
	dev->send = davinci_eth_send_packet;
	dev->recv = davinci_eth_rcv_packet;
725
	dev->write_hwaddr = davinci_eth_set_mac_addr;
726
727

	eth_register(dev);
728
729
730

	davinci_eth_mdio_enable();

731
732
733
	/* let the EMAC detect the PHYs */
	udelay(5000);

734
	for (i = 0; i < 256; i++) {
735
		if (readl(&adap_mdio->ALIVE))
736
			break;
737
		udelay(1000);
738
739
740
741
742
743
744
	}

	if (i >= 256) {
		printf("No ETH PHY detected!!!\n");
		return(0);
	}

745
746
747
	/* Find if PHY(s) is/are connected */
	ret = davinci_eth_phy_detect();
	if (!ret)
748
		return(0);
749
750
	else
		printf(" %d ETH PHY detected\n", ret);
751
752

	/* Get PHY ID and initialize phy_ops for a detected PHY */
753
754
755
756
757
758
	for (i = 0; i < num_phy; i++) {
		if (!davinci_eth_phy_read(active_phy_addr[i], MII_PHYSID1,
							&tmp)) {
			active_phy_addr[i] = 0xff;
			continue;
		}
759

760
		phy_id = (tmp << 16) & 0xffff0000;
761

762
763
764
765
766
		if (!davinci_eth_phy_read(active_phy_addr[i], MII_PHYSID2,
							&tmp)) {
			active_phy_addr[i] = 0xff;
			continue;
		}
767

768
		phy_id |= tmp & 0x0000ffff;
769

770
771
772
773
774
775
776
777
778
		switch (phy_id) {
		case PHY_KSZ8873:
			sprintf(phy[i].name, "KSZ8873 @ 0x%02x",
						active_phy_addr[i]);
			phy[i].init = ksz8873_init_phy;
			phy[i].is_phy_connected = ksz8873_is_phy_connected;
			phy[i].get_link_speed = ksz8873_get_link_speed;
			phy[i].auto_negotiate = ksz8873_auto_negotiate;
			break;
779
		case PHY_LXT972:
780
781
782
783
784
785
			sprintf(phy[i].name, "LXT972 @ 0x%02x",
						active_phy_addr[i]);
			phy[i].init = lxt972_init_phy;
			phy[i].is_phy_connected = lxt972_is_phy_connected;
			phy[i].get_link_speed = lxt972_get_link_speed;
			phy[i].auto_negotiate = lxt972_auto_negotiate;
786
787
			break;
		case PHY_DP83848:
788
789
790
791
792
793
			sprintf(phy[i].name, "DP83848 @ 0x%02x",
						active_phy_addr[i]);
			phy[i].init = dp83848_init_phy;
			phy[i].is_phy_connected = dp83848_is_phy_connected;
			phy[i].get_link_speed = dp83848_get_link_speed;
			phy[i].auto_negotiate = dp83848_auto_negotiate;
794
			break;
795
		case PHY_ET1011C:
796
797
798
799
800
801
			sprintf(phy[i].name, "ET1011C @ 0x%02x",
						active_phy_addr[i]);
			phy[i].init = gen_init_phy;
			phy[i].is_phy_connected = gen_is_phy_connected;
			phy[i].get_link_speed = et1011c_get_link_speed;
			phy[i].auto_negotiate = gen_auto_negotiate;
802
			break;
803
		default:
804
805
806
807
808
809
810
			sprintf(phy[i].name, "GENERIC @ 0x%02x",
						active_phy_addr[i]);
			phy[i].init = gen_init_phy;
			phy[i].is_phy_connected = gen_is_phy_connected;
			phy[i].get_link_speed = gen_get_link_speed;
			phy[i].auto_negotiate = gen_auto_negotiate;
		}
811

812
		debug("Ethernet PHY: %s\n", phy.name);
813

814
815
816
		miiphy_register(phy[i].name, davinci_mii_phy_read,
						davinci_mii_phy_write);
	}
817
818
	return(1);
}