]> Git Repo - u-boot.git/blame - drivers/net/dm9000x.c
net: smc911x: Pass around driver private data
[u-boot.git] / drivers / net / dm9000x.c
CommitLineData
83d290c5 1// SPDX-License-Identifier: GPL-2.0+
281e00a3
WD
2/*
3 dm9000.c: Version 1.2 12/15/2003
4
5 A Davicom DM9000 ISA NIC fast Ethernet driver for Linux.
6 Copyright (C) 1997 Sten Wang
7
281e00a3
WD
8 (C)Copyright 1997-1998 DAVICOM Semiconductor,Inc. All Rights Reserved.
9
10V0.11 06/20/2001 REG_0A bit3=1, default enable BP with DA match
53677ef1
WD
11 06/22/2001 Support DM9801 progrmming
12 E3: R25 = ((R24 + NF) & 0x00ff) | 0xf000
13 E4: R25 = ((R24 + NF) & 0x00ff) | 0xc200
14 R17 = (R17 & 0xfff0) | NF + 3
15 E5: R25 = ((R24 + NF - 3) & 0x00ff) | 0xc200
16 R17 = (R17 & 0xfff0) | NF
17
18v1.00 modify by simon 2001.9.5
93e14596 19 change for kernel 2.4.x
281e00a3 20
53677ef1 21v1.1 11/09/2001 fix force mode bug
281e00a3
WD
22
23v1.2 03/18/2003 Weilun Huang <[email protected]>:
24 Fixed phy reset.
25 Added tx/rx 32 bit mode.
26 Cleaned up for kernel merge.
27
28--------------------------------------
29
a101361b
RB
30 12/15/2003 Initial port to u-boot by
31 Sascha Hauer <[email protected]>
32
33 06/03/2008 Remy Bohmer <[email protected]>
850ba755
RB
34 - Fixed the driver to work with DM9000A.
35 (check on ISR receive status bit before reading the
36 FIFO as described in DM9000 programming guide and
37 application notes)
a101361b 38 - Added autodetect of databus width.
134e2662 39 - Made debug code compile again.
acba3184
RB
40 - Adapt eth_send such that it matches the DM9000*
41 application notes. Needed to make it work properly
42 for DM9000A.
fbcb7ece
RB
43 - Adapted reset procedure to match DM9000 application
44 notes (i.e. double reset)
98291e2e 45 - some minor code cleanups
a101361b 46 These changes are tested with DM9000{A,EP,E} together
e5a3bc24 47 with a 200MHz Atmel AT91SAM9261 core
281e00a3 48
d26b739a 49TODO: external MII is not functional, only internal at the moment.
281e00a3
WD
50*/
51
52#include <common.h>
53#include <command.h>
54#include <net.h>
55#include <asm/io.h>
e5a3bc24 56#include <dm9000.h>
281e00a3 57
281e00a3
WD
58#include "dm9000x.h"
59
60/* Board/System/Debug information/definition ---------------- */
61
281e00a3
WD
62/* #define CONFIG_DM9000_DEBUG */
63
64#ifdef CONFIG_DM9000_DEBUG
134e2662
RB
65#define DM9000_DBG(fmt,args...) printf(fmt, ##args)
66#define DM9000_DMP_PACKET(func,packet,length) \
67 do { \
68 int i; \
076cd24c 69 printf("%s: length: %d\n", func, length); \
134e2662
RB
70 for (i = 0; i < length; i++) { \
71 if (i % 8 == 0) \
72 printf("\n%s: %02x: ", func, i); \
73 printf("%02x ", ((unsigned char *) packet)[i]); \
74 } printf("\n"); \
75 } while(0)
76#else
281e00a3 77#define DM9000_DBG(fmt,args...)
134e2662
RB
78#define DM9000_DMP_PACKET(func,packet,length)
79#endif
80
281e00a3
WD
81/* Structure/enum declaration ------------------------------- */
82typedef struct board_info {
83 u32 runt_length_counter; /* counter: RX length < 64byte */
84 u32 long_length_counter; /* counter: RX length > 1514byte */
85 u32 reset_counter; /* counter: RESET */
86 u32 reset_tx_timeout; /* RESET caused by TX Timeout */
87 u32 reset_rx_status; /* RESET caused by RX Statsus wrong */
88 u16 tx_pkt_cnt;
89 u16 queue_start_addr;
90 u16 dbug_cnt;
91 u8 phy_addr;
92 u8 device_wait_reset; /* device state */
281e00a3 93 unsigned char srom[128];
0e38c938 94 void (*outblk)(volatile void *data_ptr, int count);
a101361b
RB
95 void (*inblk)(void *data_ptr, int count);
96 void (*rx_status)(u16 *RxStatus, u16 *RxLen);
60f61e6d 97 struct eth_device netdev;
98291e2e 98} board_info_t;
a101361b 99static board_info_t dm9000_info;
281e00a3 100
60f61e6d 101
281e00a3 102/* function declaration ------------------------------------- */
281e00a3 103static int dm9000_probe(void);
09c04c20
AF
104static u16 dm9000_phy_read(int);
105static void dm9000_phy_write(int, u16);
281e00a3
WD
106static u8 DM9000_ior(int);
107static void DM9000_iow(int reg, u8 value);
108
109/* DM9000 network board routine ---------------------------- */
5c1d082b 110#ifndef CONFIG_DM9000_BYTE_SWAPPED
67bee2fb
MF
111#define DM9000_outb(d,r) writeb(d, (volatile u8 *)(r))
112#define DM9000_outw(d,r) writew(d, (volatile u16 *)(r))
113#define DM9000_outl(d,r) writel(d, (volatile u32 *)(r))
114#define DM9000_inb(r) readb((volatile u8 *)(r))
115#define DM9000_inw(r) readw((volatile u16 *)(r))
116#define DM9000_inl(r) readl((volatile u32 *)(r))
5c1d082b
JJ
117#else
118#define DM9000_outb(d, r) __raw_writeb(d, r)
119#define DM9000_outw(d, r) __raw_writew(d, r)
120#define DM9000_outl(d, r) __raw_writel(d, r)
121#define DM9000_inb(r) __raw_readb(r)
122#define DM9000_inw(r) __raw_readw(r)
123#define DM9000_inl(r) __raw_readl(r)
124#endif
281e00a3
WD
125
126#ifdef CONFIG_DM9000_DEBUG
127static void
128dump_regs(void)
129{
130 DM9000_DBG("\n");
131 DM9000_DBG("NCR (0x00): %02x\n", DM9000_ior(0));
132 DM9000_DBG("NSR (0x01): %02x\n", DM9000_ior(1));
133 DM9000_DBG("TCR (0x02): %02x\n", DM9000_ior(2));
134 DM9000_DBG("TSRI (0x03): %02x\n", DM9000_ior(3));
135 DM9000_DBG("TSRII (0x04): %02x\n", DM9000_ior(4));
136 DM9000_DBG("RCR (0x05): %02x\n", DM9000_ior(5));
137 DM9000_DBG("RSR (0x06): %02x\n", DM9000_ior(6));
134e2662 138 DM9000_DBG("ISR (0xFE): %02x\n", DM9000_ior(DM9000_ISR));
281e00a3
WD
139 DM9000_DBG("\n");
140}
a101361b
RB
141#endif
142
0e38c938 143static void dm9000_outblk_8bit(volatile void *data_ptr, int count)
a101361b
RB
144{
145 int i;
146 for (i = 0; i < count; i++)
147 DM9000_outb((((u8 *) data_ptr)[i] & 0xff), DM9000_DATA);
148}
149
0e38c938 150static void dm9000_outblk_16bit(volatile void *data_ptr, int count)
a101361b
RB
151{
152 int i;
153 u32 tmplen = (count + 1) / 2;
154
155 for (i = 0; i < tmplen; i++)
156 DM9000_outw(((u16 *) data_ptr)[i], DM9000_DATA);
157}
0e38c938 158static void dm9000_outblk_32bit(volatile void *data_ptr, int count)
a101361b
RB
159{
160 int i;
161 u32 tmplen = (count + 3) / 4;
162
163 for (i = 0; i < tmplen; i++)
164 DM9000_outl(((u32 *) data_ptr)[i], DM9000_DATA);
165}
166
167static void dm9000_inblk_8bit(void *data_ptr, int count)
168{
169 int i;
170 for (i = 0; i < count; i++)
171 ((u8 *) data_ptr)[i] = DM9000_inb(DM9000_DATA);
172}
173
174static void dm9000_inblk_16bit(void *data_ptr, int count)
175{
176 int i;
177 u32 tmplen = (count + 1) / 2;
178
179 for (i = 0; i < tmplen; i++)
180 ((u16 *) data_ptr)[i] = DM9000_inw(DM9000_DATA);
181}
182static void dm9000_inblk_32bit(void *data_ptr, int count)
183{
184 int i;
185 u32 tmplen = (count + 3) / 4;
186
187 for (i = 0; i < tmplen; i++)
188 ((u32 *) data_ptr)[i] = DM9000_inl(DM9000_DATA);
189}
190
191static void dm9000_rx_status_32bit(u16 *RxStatus, u16 *RxLen)
192{
d6ee5fa4 193 u32 tmpdata;
a101361b
RB
194
195 DM9000_outb(DM9000_MRCMD, DM9000_IO);
196
d6ee5fa4 197 tmpdata = DM9000_inl(DM9000_DATA);
943b825b
TL
198 *RxStatus = __le16_to_cpu(tmpdata);
199 *RxLen = __le16_to_cpu(tmpdata >> 16);
a101361b
RB
200}
201
202static void dm9000_rx_status_16bit(u16 *RxStatus, u16 *RxLen)
203{
204 DM9000_outb(DM9000_MRCMD, DM9000_IO);
205
943b825b
TL
206 *RxStatus = __le16_to_cpu(DM9000_inw(DM9000_DATA));
207 *RxLen = __le16_to_cpu(DM9000_inw(DM9000_DATA));
a101361b
RB
208}
209
210static void dm9000_rx_status_8bit(u16 *RxStatus, u16 *RxLen)
211{
212 DM9000_outb(DM9000_MRCMD, DM9000_IO);
213
943b825b
TL
214 *RxStatus =
215 __le16_to_cpu(DM9000_inb(DM9000_DATA) +
216 (DM9000_inb(DM9000_DATA) << 8));
217 *RxLen =
218 __le16_to_cpu(DM9000_inb(DM9000_DATA) +
219 (DM9000_inb(DM9000_DATA) << 8));
a101361b 220}
281e00a3
WD
221
222/*
223 Search DM9000 board, allocate space and register it
224*/
225int
226dm9000_probe(void)
227{
228 u32 id_val;
229 id_val = DM9000_ior(DM9000_VIDL);
230 id_val |= DM9000_ior(DM9000_VIDH) << 8;
231 id_val |= DM9000_ior(DM9000_PIDL) << 16;
232 id_val |= DM9000_ior(DM9000_PIDH) << 24;
233 if (id_val == DM9000_ID) {
234 printf("dm9000 i/o: 0x%x, id: 0x%x \n", CONFIG_DM9000_BASE,
235 id_val);
236 return 0;
237 } else {
238 printf("dm9000 not found at 0x%08x id: 0x%08x\n",
239 CONFIG_DM9000_BASE, id_val);
240 return -1;
241 }
242}
243
281e00a3
WD
244/* General Purpose dm9000 reset routine */
245static void
246dm9000_reset(void)
247{
fbcb7ece
RB
248 DM9000_DBG("resetting DM9000\n");
249
250 /* Reset DM9000,
251 see DM9000 Application Notes V1.22 Jun 11, 2004 page 29 */
252
d26b739a
AD
253 /* DEBUG: Make all GPIO0 outputs, all others inputs */
254 DM9000_iow(DM9000_GPCR, GPCR_GPIO0_OUT);
fbcb7ece
RB
255 /* Step 1: Power internal PHY by writing 0 to GPIO0 pin */
256 DM9000_iow(DM9000_GPR, 0);
257 /* Step 2: Software reset */
d26b739a 258 DM9000_iow(DM9000_NCR, (NCR_LBK_INT_MAC | NCR_RST));
fbcb7ece
RB
259
260 do {
261 DM9000_DBG("resetting the DM9000, 1st reset\n");
262 udelay(25); /* Wait at least 20 us */
263 } while (DM9000_ior(DM9000_NCR) & 1);
264
265 DM9000_iow(DM9000_NCR, 0);
d26b739a 266 DM9000_iow(DM9000_NCR, (NCR_LBK_INT_MAC | NCR_RST)); /* Issue a second reset */
fbcb7ece
RB
267
268 do {
269 DM9000_DBG("resetting the DM9000, 2nd reset\n");
270 udelay(25); /* Wait at least 20 us */
271 } while (DM9000_ior(DM9000_NCR) & 1);
272
273 /* Check whether the ethernet controller is present */
274 if ((DM9000_ior(DM9000_PIDL) != 0x0) ||
275 (DM9000_ior(DM9000_PIDH) != 0x90))
276 printf("ERROR: resetting DM9000 -> not responding\n");
281e00a3
WD
277}
278
60f61e6d 279/* Initialize dm9000 board
281e00a3 280*/
60f61e6d 281static int dm9000_init(struct eth_device *dev, bd_t *bd)
281e00a3
WD
282{
283 int i, oft, lnk;
a101361b
RB
284 u8 io_mode;
285 struct board_info *db = &dm9000_info;
286
60f61e6d 287 DM9000_DBG("%s\n", __func__);
281e00a3
WD
288
289 /* RESET device */
290 dm9000_reset();
d26b739a
AD
291
292 if (dm9000_probe() < 0)
293 return -1;
281e00a3 294
a101361b
RB
295 /* Auto-detect 8/16/32 bit mode, ISR Bit 6+7 indicate bus width */
296 io_mode = DM9000_ior(DM9000_ISR) >> 6;
297
298 switch (io_mode) {
299 case 0x0: /* 16-bit mode */
300 printf("DM9000: running in 16 bit mode\n");
301 db->outblk = dm9000_outblk_16bit;
302 db->inblk = dm9000_inblk_16bit;
303 db->rx_status = dm9000_rx_status_16bit;
304 break;
305 case 0x01: /* 32-bit mode */
306 printf("DM9000: running in 32 bit mode\n");
307 db->outblk = dm9000_outblk_32bit;
308 db->inblk = dm9000_inblk_32bit;
309 db->rx_status = dm9000_rx_status_32bit;
310 break;
311 case 0x02: /* 8 bit mode */
312 printf("DM9000: running in 8 bit mode\n");
313 db->outblk = dm9000_outblk_8bit;
314 db->inblk = dm9000_inblk_8bit;
315 db->rx_status = dm9000_rx_status_8bit;
316 break;
317 default:
318 /* Assume 8 bit mode, will probably not work anyway */
319 printf("DM9000: Undefined IO-mode:0x%x\n", io_mode);
320 db->outblk = dm9000_outblk_8bit;
321 db->inblk = dm9000_inblk_8bit;
322 db->rx_status = dm9000_rx_status_8bit;
323 break;
324 }
325
d26b739a 326 /* Program operating register, only internal phy supported */
98291e2e
RB
327 DM9000_iow(DM9000_NCR, 0x0);
328 /* TX Polling clear */
329 DM9000_iow(DM9000_TCR, 0);
330 /* Less 3Kb, 200us */
d26b739a 331 DM9000_iow(DM9000_BPTR, BPTR_BPHW(3) | BPTR_JPT_600US);
98291e2e
RB
332 /* Flow Control : High/Low Water */
333 DM9000_iow(DM9000_FCTR, FCTR_HWOT(3) | FCTR_LWOT(8));
334 /* SH FIXME: This looks strange! Flow Control */
335 DM9000_iow(DM9000_FCR, 0x0);
336 /* Special Mode */
337 DM9000_iow(DM9000_SMCR, 0);
338 /* clear TX status */
339 DM9000_iow(DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END);
340 /* Clear interrupt status */
d26b739a 341 DM9000_iow(DM9000_ISR, ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS);
281e00a3 342
07754372 343 printf("MAC: %pM\n", dev->enetaddr);
0adb5b76 344 if (!is_valid_ethaddr(dev->enetaddr)) {
c583ee16 345 printf("WARNING: Bad MAC address (uninitialized EEPROM?)\n");
c583ee16 346 }
d26b739a
AD
347
348 /* fill device MAC address registers */
349 for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++)
07754372 350 DM9000_iow(oft, dev->enetaddr[i]);
281e00a3
WD
351 for (i = 0, oft = 0x16; i < 8; i++, oft++)
352 DM9000_iow(oft, 0xff);
353
354 /* read back mac, just to be sure */
355 for (i = 0, oft = 0x10; i < 6; i++, oft++)
356 DM9000_DBG("%02x:", DM9000_ior(oft));
357 DM9000_DBG("\n");
358
359 /* Activate DM9000 */
98291e2e
RB
360 /* RX enable */
361 DM9000_iow(DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);
362 /* Enable TX/RX interrupt mask */
363 DM9000_iow(DM9000_IMR, IMR_PAR);
364
281e00a3 365 i = 0;
09c04c20 366 while (!(dm9000_phy_read(1) & 0x20)) { /* autonegation complete bit */
281e00a3
WD
367 udelay(1000);
368 i++;
369 if (i == 10000) {
370 printf("could not establish link\n");
371 return 0;
372 }
373 }
374
375 /* see what we've got */
09c04c20 376 lnk = dm9000_phy_read(17) >> 12;
281e00a3
WD
377 printf("operating at ");
378 switch (lnk) {
379 case 1:
380 printf("10M half duplex ");
381 break;
382 case 2:
383 printf("10M full duplex ");
384 break;
385 case 4:
386 printf("100M half duplex ");
387 break;
388 case 8:
389 printf("100M full duplex ");
390 break;
391 default:
392 printf("unknown: %d ", lnk);
393 break;
394 }
395 printf("mode\n");
396 return 0;
397}
398
399/*
400 Hardware start transmission.
401 Send a packet to media from the upper layer.
402*/
7f9a8a67 403static int dm9000_send(struct eth_device *netdev, void *packet, int length)
281e00a3 404{
281e00a3 405 int tmo;
a101361b
RB
406 struct board_info *db = &dm9000_info;
407
60f61e6d 408 DM9000_DMP_PACKET(__func__ , packet, length);
281e00a3 409
acba3184
RB
410 DM9000_iow(DM9000_ISR, IMR_PTM); /* Clear Tx bit in ISR */
411
281e00a3 412 /* Move data to DM9000 TX RAM */
acba3184 413 DM9000_outb(DM9000_MWCMD, DM9000_IO); /* Prepare for TX-data */
281e00a3 414
a101361b 415 /* push the data to the TX-fifo */
0e38c938 416 (db->outblk)(packet, length);
281e00a3
WD
417
418 /* Set TX length to DM9000 */
419 DM9000_iow(DM9000_TXPLL, length & 0xff);
420 DM9000_iow(DM9000_TXPLH, (length >> 8) & 0xff);
421
422 /* Issue TX polling command */
acba3184 423 DM9000_iow(DM9000_TCR, TCR_TXREQ); /* Cleared after TX complete */
281e00a3
WD
424
425 /* wait for end of transmission */
6d0f6bcf 426 tmo = get_timer(0) + 5 * CONFIG_SYS_HZ;
acba3184
RB
427 while ( !(DM9000_ior(DM9000_NSR) & (NSR_TX1END | NSR_TX2END)) ||
428 !(DM9000_ior(DM9000_ISR) & IMR_PTM) ) {
281e00a3
WD
429 if (get_timer(0) >= tmo) {
430 printf("transmission timeout\n");
431 break;
432 }
433 }
acba3184
RB
434 DM9000_iow(DM9000_ISR, IMR_PTM); /* Clear Tx bit in ISR */
435
281e00a3
WD
436 DM9000_DBG("transmit done\n\n");
437 return 0;
438}
439
440/*
441 Stop the interface.
442 The interface is stopped when it is brought.
443*/
60f61e6d 444static void dm9000_halt(struct eth_device *netdev)
281e00a3 445{
60f61e6d 446 DM9000_DBG("%s\n", __func__);
281e00a3
WD
447
448 /* RESET devie */
09c04c20 449 dm9000_phy_write(0, 0x8000); /* PHY RESET */
281e00a3
WD
450 DM9000_iow(DM9000_GPR, 0x01); /* Power-Down PHY */
451 DM9000_iow(DM9000_IMR, 0x80); /* Disable all interrupt */
452 DM9000_iow(DM9000_RCR, 0x00); /* Disable RX */
453}
454
455/*
456 Received a packet and pass to upper layer
457*/
60f61e6d 458static int dm9000_rx(struct eth_device *netdev)
281e00a3 459{
1fd92db8
JH
460 u8 rxbyte;
461 u8 *rdptr = (u8 *)net_rx_packets[0];
281e00a3 462 u16 RxStatus, RxLen = 0;
a101361b 463 struct board_info *db = &dm9000_info;
281e00a3 464
850ba755
RB
465 /* Check packet ready or not, we must check
466 the ISR status first for DM9000A */
467 if (!(DM9000_ior(DM9000_ISR) & 0x01)) /* Rx-ISR bit must be set. */
281e00a3
WD
468 return 0;
469
850ba755 470 DM9000_iow(DM9000_ISR, 0x01); /* clear PR status latched in bit 0 */
281e00a3 471
850ba755
RB
472 /* There is _at least_ 1 package in the fifo, read them all */
473 for (;;) {
474 DM9000_ior(DM9000_MRCMDX); /* Dummy read */
281e00a3 475
0e38c938
RB
476 /* Get most updated data,
477 only look at bits 0:1, See application notes DM9000 */
478 rxbyte = DM9000_inb(DM9000_DATA) & 0x03;
281e00a3 479
850ba755
RB
480 /* Status check: this byte must be 0 or 1 */
481 if (rxbyte > DM9000_PKT_RDY) {
482 DM9000_iow(DM9000_RCR, 0x00); /* Stop Device */
483 DM9000_iow(DM9000_ISR, 0x80); /* Stop INT request */
484 printf("DM9000 error: status check fail: 0x%x\n",
485 rxbyte);
486 return 0;
487 }
281e00a3 488
850ba755
RB
489 if (rxbyte != DM9000_PKT_RDY)
490 return 0; /* No packet received, ignore */
491
492 DM9000_DBG("receiving packet\n");
493
494 /* A packet ready now & Get status/length */
495 (db->rx_status)(&RxStatus, &RxLen);
496
497 DM9000_DBG("rx status: 0x%04x rx len: %d\n", RxStatus, RxLen);
498
499 /* Move data from DM9000 */
500 /* Read received packet from RX SRAM */
501 (db->inblk)(rdptr, RxLen);
502
503 if ((RxStatus & 0xbf00) || (RxLen < 0x40)
504 || (RxLen > DM9000_PKT_MAX)) {
505 if (RxStatus & 0x100) {
506 printf("rx fifo error\n");
507 }
508 if (RxStatus & 0x200) {
509 printf("rx crc error\n");
510 }
511 if (RxStatus & 0x8000) {
512 printf("rx length error\n");
513 }
514 if (RxLen > DM9000_PKT_MAX) {
515 printf("rx length too big\n");
516 dm9000_reset();
517 }
518 } else {
60f61e6d 519 DM9000_DMP_PACKET(__func__ , rdptr, RxLen);
281e00a3 520
850ba755 521 DM9000_DBG("passing packet to upper layer\n");
1fd92db8 522 net_process_received_packet(net_rx_packets[0], RxLen);
281e00a3 523 }
281e00a3
WD
524 }
525 return 0;
526}
527
528/*
529 Read a word data from SROM
530*/
e5a3bc24
RB
531#if !defined(CONFIG_DM9000_NO_SROM)
532void dm9000_read_srom_word(int offset, u8 *to)
281e00a3
WD
533{
534 DM9000_iow(DM9000_EPAR, offset);
535 DM9000_iow(DM9000_EPCR, 0x4);
5f470948 536 udelay(8000);
281e00a3 537 DM9000_iow(DM9000_EPCR, 0x0);
ad74cae9
DB
538 to[0] = DM9000_ior(DM9000_EPDRL);
539 to[1] = DM9000_ior(DM9000_EPDRH);
281e00a3
WD
540}
541
e5a3bc24 542void dm9000_write_srom_word(int offset, u16 val)
5e5803e1
SB
543{
544 DM9000_iow(DM9000_EPAR, offset);
545 DM9000_iow(DM9000_EPDRH, ((val >> 8) & 0xff));
546 DM9000_iow(DM9000_EPDRL, (val & 0xff));
547 DM9000_iow(DM9000_EPCR, 0x12);
548 udelay(8000);
549 DM9000_iow(DM9000_EPCR, 0);
550}
e5a3bc24 551#endif
5e5803e1 552
07754372
BW
553static void dm9000_get_enetaddr(struct eth_device *dev)
554{
555#if !defined(CONFIG_DM9000_NO_SROM)
556 int i;
557 for (i = 0; i < 3; i++)
558 dm9000_read_srom_word(i, dev->enetaddr + (2 * i));
559#endif
560}
561
281e00a3
WD
562/*
563 Read a byte from I/O port
564*/
565static u8
566DM9000_ior(int reg)
567{
568 DM9000_outb(reg, DM9000_IO);
569 return DM9000_inb(DM9000_DATA);
570}
571
572/*
573 Write a byte to I/O port
574*/
575static void
576DM9000_iow(int reg, u8 value)
577{
578 DM9000_outb(reg, DM9000_IO);
579 DM9000_outb(value, DM9000_DATA);
580}
581
582/*
583 Read a word from phyxcer
584*/
585static u16
09c04c20 586dm9000_phy_read(int reg)
281e00a3
WD
587{
588 u16 val;
589
590 /* Fill the phyxcer register into REG_0C */
591 DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);
592 DM9000_iow(DM9000_EPCR, 0xc); /* Issue phyxcer read command */
98291e2e 593 udelay(100); /* Wait read complete */
281e00a3
WD
594 DM9000_iow(DM9000_EPCR, 0x0); /* Clear phyxcer read command */
595 val = (DM9000_ior(DM9000_EPDRH) << 8) | DM9000_ior(DM9000_EPDRL);
596
597 /* The read data keeps on REG_0D & REG_0E */
09c04c20 598 DM9000_DBG("dm9000_phy_read(0x%x): 0x%x\n", reg, val);
281e00a3
WD
599 return val;
600}
601
602/*
603 Write a word to phyxcer
604*/
605static void
09c04c20 606dm9000_phy_write(int reg, u16 value)
281e00a3
WD
607{
608
609 /* Fill the phyxcer register into REG_0C */
610 DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);
611
612 /* Fill the written data into REG_0D & REG_0E */
613 DM9000_iow(DM9000_EPDRL, (value & 0xff));
614 DM9000_iow(DM9000_EPDRH, ((value >> 8) & 0xff));
615 DM9000_iow(DM9000_EPCR, 0xa); /* Issue phyxcer write command */
98291e2e 616 udelay(500); /* Wait write complete */
281e00a3 617 DM9000_iow(DM9000_EPCR, 0x0); /* Clear phyxcer write command */
09c04c20 618 DM9000_DBG("dm9000_phy_write(reg:0x%x, value:0x%x)\n", reg, value);
281e00a3 619}
60f61e6d
RB
620
621int dm9000_initialize(bd_t *bis)
622{
623 struct eth_device *dev = &(dm9000_info.netdev);
624
07754372
BW
625 /* Load MAC address from EEPROM */
626 dm9000_get_enetaddr(dev);
627
60f61e6d
RB
628 dev->init = dm9000_init;
629 dev->halt = dm9000_halt;
630 dev->send = dm9000_send;
631 dev->recv = dm9000_rx;
192bc694 632 strcpy(dev->name, "dm9000");
60f61e6d
RB
633
634 eth_register(dev);
635
636 return 0;
637}
This page took 0.411328 seconds and 4 git commands to generate.