1 #include <rtthread.h>
2 #include <netif/ethernetif.h>
3 
4 #include "dm9000.h"
5 #include <s3c24x0.h>
6 
7 /*
8  * Davicom DM9000EP driver
9  *
10  * IRQ_LAN connects to EINT7(GPF7)
11  * nLAN_CS connects to nGCS4
12  */
13 
14 /* #define DM9000_DEBUG		1 */
15 #if DM9000_DEBUG
16 #define DM9000_TRACE	rt_kprintf
17 #else
18 #define DM9000_TRACE(...)
19 #endif
20 
21 /*
22  * DM9000 interrupt line is connected to PF7
23  */
24 //--------------------------------------------------------
25 
26 #define DM9000_PHY		  0x40	/* PHY address 0x01 */
27 
28 #define MAX_ADDR_LEN 6
29 enum DM9000_PHY_mode
30 {
31 	DM9000_10MHD = 0, DM9000_100MHD = 1,
32 	DM9000_10MFD = 4, DM9000_100MFD = 5,
33 	DM9000_AUTO  = 8, DM9000_1M_HPNA = 0x10
34 };
35 
36 enum DM9000_TYPE
37 {
38 	TYPE_DM9000E,
39 	TYPE_DM9000A,
40 	TYPE_DM9000B
41 };
42 
43 struct rt_dm9000_eth
44 {
45 	/* inherit from ethernet device */
46 	struct eth_device parent;
47 
48 	enum DM9000_TYPE type;
49 	enum DM9000_PHY_mode mode;
50 
51 	rt_uint8_t packet_cnt;				  /* packet I or II */
52 	rt_uint16_t queue_packet_len;		   /* queued packet (packet II) */
53 
54 	/* interface address info. */
55 	rt_uint8_t  dev_addr[MAX_ADDR_LEN];		/* hw address	*/
56 };
57 static struct rt_dm9000_eth dm9000_device;
58 static struct rt_semaphore sem_ack, sem_lock;
59 
60 void rt_dm9000_isr(int irqno);
61 
delay_ms(rt_uint32_t ms)62 static void delay_ms(rt_uint32_t ms)
63 {
64 	rt_uint32_t len;
65 	for (;ms > 0; ms --)
66 		for (len = 0; len < 100; len++ );
67 }
68 
69 /* Read a byte from I/O port */
dm9000_io_read(rt_uint16_t reg)70 rt_inline rt_uint8_t dm9000_io_read(rt_uint16_t reg)
71 {
72 	DM9000_IO = reg;
73 	return (rt_uint8_t) DM9000_DATA;
74 }
75 
76 /* Write a byte to I/O port */
dm9000_io_write(rt_uint16_t reg,rt_uint16_t value)77 rt_inline void dm9000_io_write(rt_uint16_t reg, rt_uint16_t value)
78 {
79 	DM9000_IO = reg;
80 	DM9000_DATA = value;
81 }
82 
83 /* Read a word from phyxcer */
phy_read(rt_uint16_t reg)84 rt_inline rt_uint16_t phy_read(rt_uint16_t reg)
85 {
86 	rt_uint16_t val;
87 
88 	/* Fill the phyxcer register into REG_0C */
89 	dm9000_io_write(DM9000_EPAR, DM9000_PHY | reg);
90 	dm9000_io_write(DM9000_EPCR, 0xc);	/* Issue phyxcer read command */
91 
92 	delay_ms(100);		/* Wait read complete */
93 
94 	dm9000_io_write(DM9000_EPCR, 0x0);	/* Clear phyxcer read command */
95 	val = (dm9000_io_read(DM9000_EPDRH) << 8) | dm9000_io_read(DM9000_EPDRL);
96 
97 	return val;
98 }
99 
100 /* Write a word to phyxcer */
phy_write(rt_uint16_t reg,rt_uint16_t value)101 rt_inline void phy_write(rt_uint16_t reg, rt_uint16_t value)
102 {
103 	/* Fill the phyxcer register into REG_0C */
104 	dm9000_io_write(DM9000_EPAR, DM9000_PHY | reg);
105 
106 	/* Fill the written data into REG_0D & REG_0E */
107 	dm9000_io_write(DM9000_EPDRL, (value & 0xff));
108 	dm9000_io_write(DM9000_EPDRH, ((value >> 8) & 0xff));
109 	dm9000_io_write(DM9000_EPCR, 0xa);	/* Issue phyxcer write command */
110 
111 	delay_ms(500);		/* Wait write complete */
112 
113 	dm9000_io_write(DM9000_EPCR, 0x0);	/* Clear phyxcer write command */
114 }
115 
116 /* Set PHY operationg mode */
phy_mode_set(rt_uint32_t media_mode)117 rt_inline void phy_mode_set(rt_uint32_t media_mode)
118 {
119 	rt_uint16_t phy_reg4 = 0x01e1, phy_reg0 = 0x1000;
120 	if (!(media_mode & DM9000_AUTO))
121 	{
122 		switch (media_mode)
123 		{
124 		case DM9000_10MHD:
125 			phy_reg4 = 0x21;
126 			phy_reg0 = 0x0000;
127 			break;
128 		case DM9000_10MFD:
129 			phy_reg4 = 0x41;
130 			phy_reg0 = 0x1100;
131 			break;
132 		case DM9000_100MHD:
133 			phy_reg4 = 0x81;
134 			phy_reg0 = 0x2000;
135 			break;
136 		case DM9000_100MFD:
137 			phy_reg4 = 0x101;
138 			phy_reg0 = 0x3100;
139 			break;
140 		}
141 		phy_write(4, phy_reg4);	/* Set PHY media mode */
142 		phy_write(0, phy_reg0);	/*  Tmp */
143 	}
144 
145 	dm9000_io_write(DM9000_GPCR, 0x01);	/* Let GPIO0 output */
146 	dm9000_io_write(DM9000_GPR, 0x00);	/* Enable PHY */
147 }
148 
149 /* interrupt service routine */
rt_dm9000_isr(int irqno)150 void rt_dm9000_isr(int irqno)
151 {
152 	rt_uint16_t int_status;
153 	rt_uint16_t last_io;
154 	rt_uint32_t eint_pend;
155 
156 	last_io = DM9000_IO;
157 
158 	/* Disable all interrupts */
159 	dm9000_io_write(DM9000_IMR, IMR_PAR);
160 
161 	/* Got DM9000 interrupt status */
162 	int_status = dm9000_io_read(DM9000_ISR);	/* Got ISR */
163 	dm9000_io_write(DM9000_ISR, int_status);	/* Clear ISR status */
164 
165 	DM9000_TRACE("dm9000 isr: int status %04x\n", int_status);
166 
167 	/* receive overflow */
168 	if (int_status & ISR_ROS)
169 	{
170 		rt_kprintf("overflow\n");
171 	}
172 
173 	if (int_status & ISR_ROOS)
174 	{
175 		rt_kprintf("overflow counter overflow\n");
176 	}
177 
178 	/* Received the coming packet */
179 	if (int_status & ISR_PRS)
180 	{
181 		/* a frame has been received */
182 		eth_device_ready(&(dm9000_device.parent));
183 	}
184 
185 	/* Transmit Interrupt check */
186 	if (int_status & ISR_PTS)
187 	{
188 		/* transmit done */
189 		int tx_status = dm9000_io_read(DM9000_NSR);	/* Got TX status */
190 
191 		if (tx_status & (NSR_TX2END | NSR_TX1END))
192 		{
193 			dm9000_device.packet_cnt --;
194 			if (dm9000_device.packet_cnt > 0)
195 			{
196 				DM9000_TRACE("dm9000 isr: tx second packet\n");
197 
198 				/* transmit packet II */
199 				/* Set TX length to DM9000 */
200 				dm9000_io_write(DM9000_TXPLL, dm9000_device.queue_packet_len & 0xff);
201 				dm9000_io_write(DM9000_TXPLH, (dm9000_device.queue_packet_len >> 8) & 0xff);
202 
203 				/* Issue TX polling command */
204 				dm9000_io_write(DM9000_TCR, TCR_TXREQ);	/* Cleared after TX complete */
205 			}
206 
207 			/* One packet sent complete */
208 			rt_sem_release(&sem_ack);
209 		}
210 	}
211 
212 	/* Re-enable interrupt mask */
213 	dm9000_io_write(DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM);
214 
215 	DM9000_IO = last_io;
216 }
217 
218 /* RT-Thread Device Interface */
219 /* initialize the interface */
rt_dm9000_init(rt_device_t dev)220 static rt_err_t rt_dm9000_init(rt_device_t dev)
221 {
222 	int i, oft, lnk;
223 	rt_uint32_t value;
224 
225 	/* RESET device */
226 	dm9000_io_write(DM9000_NCR, NCR_RST);
227 	delay_ms(1000);		/* delay 1ms */
228 
229 	/* identfy DM9000 */
230 	value  = dm9000_io_read(DM9000_VIDL);
231 	value |= dm9000_io_read(DM9000_VIDH) << 8;
232 	value |= dm9000_io_read(DM9000_PIDL) << 16;
233 	value |= dm9000_io_read(DM9000_PIDH) << 24;
234 	if (value == DM9000_ID)
235 	{
236 		rt_kprintf("dm9000 id: 0x%x\n", value);
237 	}
238 	else
239 	{
240 		rt_kprintf("dm9000 id: 0x%x\n", value);
241 		return -RT_ERROR;
242 	}
243 
244 	/* GPIO0 on pre-activate PHY */
245 	dm9000_io_write(DM9000_GPR, 0x00);				/* REG_1F bit0 activate phyxcer */
246 	dm9000_io_write(DM9000_GPCR, GPCR_GEP_CNTL);	/* Let GPIO0 output */
247 	dm9000_io_write(DM9000_GPR, 0x00);				 /* Enable PHY */
248 
249 	/* Set PHY */
250 	phy_mode_set(dm9000_device.mode);
251 
252 	/* Program operating register */
253 	dm9000_io_write(DM9000_NCR, 0x0);	/* only intern phy supported by now */
254 	dm9000_io_write(DM9000_TCR, 0);		/* TX Polling clear */
255 	dm9000_io_write(DM9000_BPTR, 0x3f);	/* Less 3Kb, 200us */
256 	dm9000_io_write(DM9000_FCTR, FCTR_HWOT(3) | FCTR_LWOT(8));	/* Flow Control : High/Low Water */
257 	dm9000_io_write(DM9000_FCR, 0x0);	/* SH FIXME: This looks strange! Flow Control */
258 	dm9000_io_write(DM9000_SMCR, 0);	/* Special Mode */
259 	dm9000_io_write(DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END);	/* clear TX status */
260 	dm9000_io_write(DM9000_ISR, 0x0f);	/* Clear interrupt status */
261 	dm9000_io_write(DM9000_TCR2, 0x80);	/* Switch LED to mode 1 */
262 
263 	/* set mac address */
264 	for (i = 0, oft = 0x10; i < 6; i++, oft++)
265 		dm9000_io_write(oft, dm9000_device.dev_addr[i]);
266 	/* set multicast address */
267 	for (i = 0, oft = 0x16; i < 8; i++, oft++)
268 		dm9000_io_write(oft, 0xff);
269 
270 	/* Activate DM9000 */
271 	dm9000_io_write(DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);	/* RX enable */
272 	dm9000_io_write(DM9000_IMR, IMR_PAR);
273 
274 	if (dm9000_device.mode == DM9000_AUTO)
275 	{
276 	    i = 0;
277 		while (!(phy_read(1) & 0x20))
278 		{
279 			/* autonegation complete bit */
280 			rt_thread_delay( RT_TICK_PER_SECOND/10 );
281 			i++;
282 			if (i > 30 ) /* wait 3s */
283 			{
284 				rt_kprintf("could not establish link\n");
285 				return 0;
286 			}
287 		}
288 	}
289 
290 	/* send a notify */
291 	eth_device_linkchange(&dm9000_device.parent, RT_TRUE);
292 
293 	/* see what we've got */
294 	lnk = phy_read(17) >> 12;
295 	rt_kprintf("operating at ");
296 	switch (lnk)
297 	{
298 	case 1:
299 		rt_kprintf("10M half duplex ");
300 		break;
301 	case 2:
302 		rt_kprintf("10M full duplex ");
303 		break;
304 	case 4:
305 		rt_kprintf("100M half duplex ");
306 		break;
307 	case 8:
308 		rt_kprintf("100M full duplex ");
309 		break;
310 	default:
311 		rt_kprintf("unknown: %d ", lnk);
312 		break;
313 	}
314 	rt_kprintf("mode\n");
315 
316 	/* Enable TX/RX interrupt mask */
317 	dm9000_io_write(DM9000_IMR,IMR_PAR | IMR_PTM | IMR_PRM);
318 
319 	return RT_EOK;
320 }
321 
rt_dm9000_open(rt_device_t dev,rt_uint16_t oflag)322 static rt_err_t rt_dm9000_open(rt_device_t dev, rt_uint16_t oflag)
323 {
324 	return RT_EOK;
325 }
326 
rt_dm9000_close(rt_device_t dev)327 static rt_err_t rt_dm9000_close(rt_device_t dev)
328 {
329 	/* RESET devie */
330 	phy_write(0, 0x8000);	/* PHY RESET */
331 	dm9000_io_write(DM9000_GPR, 0x01);	/* Power-Down PHY */
332 	dm9000_io_write(DM9000_IMR, 0x80);	/* Disable all interrupt */
333 	dm9000_io_write(DM9000_RCR, 0x00);	/* Disable RX */
334 
335 	return RT_EOK;
336 }
337 
rt_dm9000_read(rt_device_t dev,rt_off_t pos,void * buffer,rt_size_t size)338 static rt_ssize_t rt_dm9000_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
339 {
340 	rt_set_errno(-RT_ENOSYS);
341 	return 0;
342 }
343 
rt_dm9000_write(rt_device_t dev,rt_off_t pos,const void * buffer,rt_size_t size)344 static rt_ssize_t rt_dm9000_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
345 {
346 	rt_set_errno(-RT_ENOSYS);
347 	return 0;
348 }
349 
rt_dm9000_control(rt_device_t dev,int cmd,void * args)350 static rt_err_t rt_dm9000_control(rt_device_t dev, int cmd, void *args)
351 {
352 	switch (cmd)
353 	{
354 	case NIOCTL_GADDR:
355 		/* get mac address */
356 		if (args) rt_memcpy(args, dm9000_device.dev_addr, 6);
357 		else return -RT_ERROR;
358 		break;
359 
360 	default :
361 		break;
362 	}
363 
364 	return RT_EOK;
365 }
366 
367 /* ethernet device interface */
368 /* transmit packet. */
rt_dm9000_tx(rt_device_t dev,struct pbuf * p)369 rt_err_t rt_dm9000_tx( rt_device_t dev, struct pbuf* p)
370 {
371 	DM9000_TRACE("dm9000 tx: %d\n", p->tot_len);
372 
373 	/* lock DM9000 device */
374 	rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
375 
376 	/* disable dm9000a interrupt */
377 	dm9000_io_write(DM9000_IMR, IMR_PAR);
378 
379 	/* Move data to DM9000 TX RAM */
380 	DM9000_outb(DM9000_IO_BASE, DM9000_MWCMD);
381 
382 	{
383 		/* q traverses through linked list of pbuf's
384 		 * This list MUST consist of a single packet ONLY */
385 		struct pbuf *q;
386 		rt_uint16_t pbuf_index = 0;
387 		rt_uint8_t word[2], word_index = 0;
388 
389 		q = p;
390 		/* Write data into dm9000a, two bytes at a time
391 		 * Handling pbuf's with odd number of bytes correctly
392 		 * No attempt to optimize for speed has been made */
393 		while (q)
394 		{
395 			if (pbuf_index < q->len)
396 			{
397 				word[word_index++] = ((u8_t*)q->payload)[pbuf_index++];
398 				if (word_index == 2)
399 				{
400 					DM9000_outw(DM9000_DATA_BASE, (word[1] << 8) | word[0]);
401 					word_index = 0;
402 				}
403 			}
404 			else
405 			{
406 				q = q->next;
407 				pbuf_index = 0;
408 			}
409 		}
410 		/* One byte could still be unsent */
411 		if (word_index == 1)
412 		{
413 			DM9000_outw(DM9000_DATA_BASE, word[0]);
414 		}
415 	}
416 
417 	if (dm9000_device.packet_cnt == 0)
418 	{
419 		DM9000_TRACE("dm9000 tx: first packet\n");
420 
421 		dm9000_device.packet_cnt ++;
422 		/* Set TX length to DM9000 */
423 		dm9000_io_write(DM9000_TXPLL, p->tot_len & 0xff);
424 		dm9000_io_write(DM9000_TXPLH, (p->tot_len >> 8) & 0xff);
425 
426 		/* Issue TX polling command */
427 		dm9000_io_write(DM9000_TCR, TCR_TXREQ);	/* Cleared after TX complete */
428 	}
429 	else
430 	{
431 		DM9000_TRACE("dm9000 tx: second packet\n");
432 
433 		dm9000_device.packet_cnt ++;
434 		dm9000_device.queue_packet_len = p->tot_len;
435 	}
436 
437 	/* enable dm9000a interrupt */
438 	dm9000_io_write(DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM);
439 
440 	/* unlock DM9000 device */
441 	rt_sem_release(&sem_lock);
442 
443 	/* wait ack */
444 	rt_sem_take(&sem_ack, RT_WAITING_FOREVER);
445 
446 	DM9000_TRACE("dm9000 tx done\n");
447 
448 	return RT_EOK;
449 }
450 
451 /* reception packet. */
rt_dm9000_rx(rt_device_t dev)452 struct pbuf *rt_dm9000_rx(rt_device_t dev)
453 {
454 	struct pbuf* p;
455 	rt_uint32_t rxbyte;
456 	rt_uint16_t rx_status, rx_len;
457 	rt_uint16_t* data;
458 
459 	/* init p pointer */
460 	p = RT_NULL;
461 
462 	/* lock DM9000 device */
463 	rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
464 
465 __error_retry:
466 	/* Check packet ready or not */
467 	dm9000_io_read(DM9000_MRCMDX);				/* Dummy read */
468 	rxbyte = DM9000_inb(DM9000_DATA_BASE);		/* Got most updated data */
469 	if (rxbyte)
470 	{
471 		if (rxbyte > 1)
472 		{
473 			DM9000_TRACE("dm9000 rx: rx error, stop device\n");
474 
475 			dm9000_io_write(DM9000_RCR, 0x00);	/* Stop Device */
476 			dm9000_io_write(DM9000_ISR, 0x80);	/* Stop INT request */
477 		}
478 
479 		/* A packet ready now  & Get status/length */
480 		DM9000_outb(DM9000_IO_BASE, DM9000_MRCMD);
481 
482 		rx_status = DM9000_inw(DM9000_DATA_BASE);
483 		rx_len = DM9000_inw(DM9000_DATA_BASE);
484 
485 		DM9000_TRACE("dm9000 rx: status %04x len %d\n", rx_status, rx_len);
486 
487 		/* allocate buffer */
488 		p = pbuf_alloc(PBUF_LINK, rx_len, PBUF_RAM);
489 		if (p != RT_NULL)
490 		{
491 			struct pbuf* q;
492 			rt_int32_t len;
493 
494 			for (q = p; q != RT_NULL; q= q->next)
495 			{
496 				data = (rt_uint16_t*)q->payload;
497 				len = q->len;
498 
499 				while (len > 0)
500 				{
501 					*data = DM9000_inw(DM9000_DATA_BASE);
502 					data ++;
503 					len -= 2;
504 				}
505 			}
506 		}
507 		else
508 		{
509 			rt_uint16_t dummy;
510 
511 			rt_kprintf("dm9000 rx: no pbuf\n");
512 
513 			/* no pbuf, discard data from DM9000 */
514 			data = &dummy;
515 			while (rx_len)
516 			{
517 				*data = DM9000_inw(DM9000_DATA_BASE);
518 				rx_len -= 2;
519 			}
520 		}
521 
522 		if ((rx_status & 0xbf00) || (rx_len < 0x40)
523 				|| (rx_len > DM9000_PKT_MAX))
524 		{
525 			rt_kprintf("rx error: status %04x, rx_len: %d\n", rx_status, rx_len);
526 
527 			if (rx_status & 0x100)
528 			{
529 				rt_kprintf("rx fifo error\n");
530 			}
531 			if (rx_status & 0x200)
532 			{
533 				rt_kprintf("rx crc error\n");
534 			}
535 			if (rx_status & 0x8000)
536 			{
537 				rt_kprintf("rx length error\n");
538 			}
539 			if (rx_len > DM9000_PKT_MAX)
540 			{
541 				rt_kprintf("rx length too big\n");
542 
543 				/* RESET device */
544 				dm9000_io_write(DM9000_NCR, NCR_RST);
545 				rt_thread_delay(1); /* delay 5ms */
546 			}
547 
548 			/* it issues an error, release pbuf */
549 			if (p != RT_NULL) pbuf_free(p);
550 			p = RT_NULL;
551 
552 			goto __error_retry;
553 		}
554 	}
555 	else
556 	{
557 		/* clear packet received latch status */
558 		dm9000_io_write(DM9000_ISR, ISR_PTS);
559 
560 		/* restore receive interrupt */
561 		dm9000_io_write(DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM);
562 	}
563 
564 	/* unlock DM9000 device */
565 	rt_sem_release(&sem_lock);
566 
567 	return p;
568 }
569 
570 #define B4_Tacs				 0x0
571 #define B4_Tcos				 0x0
572 #define B4_Tacc				 0x7
573 #define B4_Tcoh				 0x0
574 #define B4_Tah				  0x0
575 #define B4_Tacp				 0x0
576 #define B4_PMC				  0x0
577 
INTEINT4_7_handler(int irqno,void * param)578 void INTEINT4_7_handler(int irqno, void *param)
579 {
580     rt_uint32_t eint_pend;
581 
582     eint_pend = EINTPEND;
583 
584     /* EINT7 : DM9000AEP */
585     if( eint_pend & (1<<7) )
586     {
587         rt_dm9000_isr(0);
588     }
589 
590 	/* clear EINT pending bit */
591 	EINTPEND = eint_pend;
592 }
593 
rt_hw_dm9000_init()594 int rt_hw_dm9000_init()
595 {
596 	/* Set GPF7 as EINT7 */
597 	GPFCON = GPFCON & (~(3 << 14)) | (2 << 14);
598 	GPFUP = GPFUP | (1 << 7);
599 	/* EINT7 High level interrupt */
600 	EXTINT0 = (EXTINT0 & (~(0x7 << 28))) | (0x1 << 28);
601 	/* Enable EINT7 */
602 	EINTMASK = EINTMASK & (~(1<<7));
603 	/* Set GPA15 as nGCS4 */
604 	GPACON |= 1 << 15;
605 	/* DM9000 width 16, wait enable */
606 	BWSCON = BWSCON & (~(0x7<<16)) | (0x5<<16);
607 	BANKCON4 = (1<<13) | (1<<11) | (0x6<<8) | (1<<6) | (1<<4) | (0<<2) | (0);
608 
609 	rt_sem_init(&sem_ack, "tx_ack", 1, RT_IPC_FLAG_FIFO);
610 	rt_sem_init(&sem_lock, "eth_lock", 1, RT_IPC_FLAG_FIFO);
611 
612 	dm9000_device.type  = TYPE_DM9000A;
613 	dm9000_device.mode	= DM9000_AUTO;
614 	dm9000_device.packet_cnt = 0;
615 	dm9000_device.queue_packet_len = 0;
616 
617 	/*
618 	 * SRAM Tx/Rx pointer automatically return to start address,
619 	 * Packet Transmitted, Packet Received
620 	 */
621 
622 	dm9000_device.dev_addr[0] = 0x00;
623 	dm9000_device.dev_addr[1] = 0x60;
624 	dm9000_device.dev_addr[2] = 0x6E;
625 	dm9000_device.dev_addr[3] = 0x11;
626 	dm9000_device.dev_addr[4] = 0x02;
627 	dm9000_device.dev_addr[5] = 0x0F;
628 
629 	dm9000_device.parent.parent.init	   = rt_dm9000_init;
630 	dm9000_device.parent.parent.open	   = rt_dm9000_open;
631 	dm9000_device.parent.parent.close	   = rt_dm9000_close;
632 	dm9000_device.parent.parent.read	   = rt_dm9000_read;
633 	dm9000_device.parent.parent.write	   = rt_dm9000_write;
634 	dm9000_device.parent.parent.control	= rt_dm9000_control;
635 	dm9000_device.parent.parent.user_data  = RT_NULL;
636 
637 	dm9000_device.parent.eth_rx	 = rt_dm9000_rx;
638 	dm9000_device.parent.eth_tx	 = rt_dm9000_tx;
639 
640 	eth_device_init(&(dm9000_device.parent), "e0");
641 
642 	/* instal interrupt */
643 	rt_hw_interrupt_install(INTEINT4_7, INTEINT4_7_handler, RT_NULL, "EINT4_7");
644 	rt_hw_interrupt_umask(INTEINT4_7);
645 
646 	return RT_EOK;
647 }
648 
649 INIT_DEVICE_EXPORT(rt_hw_dm9000_init);
650 
dm9000a(void)651 void dm9000a(void)
652 {
653 	rt_kprintf("\n");
654 	rt_kprintf("NCR   (%02X): %02x\n", DM9000_NCR,   dm9000_io_read(DM9000_NCR));
655 	rt_kprintf("NSR   (%02X): %02x\n", DM9000_NSR,   dm9000_io_read(DM9000_NSR));
656 	rt_kprintf("TCR   (%02X): %02x\n", DM9000_TCR,   dm9000_io_read(DM9000_TCR));
657 	rt_kprintf("TSRI  (%02X): %02x\n", DM9000_TSR1,  dm9000_io_read(DM9000_TSR1));
658 	rt_kprintf("TSRII (%02X): %02x\n", DM9000_TSR2,  dm9000_io_read(DM9000_TSR2));
659 	rt_kprintf("RCR   (%02X): %02x\n", DM9000_RCR,   dm9000_io_read(DM9000_RCR));
660 	rt_kprintf("RSR   (%02X): %02x\n", DM9000_RSR,   dm9000_io_read(DM9000_RSR));
661 	rt_kprintf("ORCR  (%02X): %02x\n", DM9000_ROCR,  dm9000_io_read(DM9000_ROCR));
662 	rt_kprintf("CRR   (%02X): %02x\n", DM9000_CHIPR, dm9000_io_read(DM9000_CHIPR));
663 	rt_kprintf("CSCR  (%02X): %02x\n", DM9000_CSCR,  dm9000_io_read(DM9000_CSCR));
664 	rt_kprintf("RCSSR (%02X): %02x\n", DM9000_RCSSR, dm9000_io_read(DM9000_RCSSR));
665 	rt_kprintf("ISR   (%02X): %02x\n", DM9000_ISR,   dm9000_io_read(DM9000_ISR));
666 	rt_kprintf("IMR   (%02X): %02x\n", DM9000_IMR,   dm9000_io_read(DM9000_IMR));
667 	rt_kprintf("\n");
668 }
669 
670 #ifdef RT_USING_FINSH
671 #include <finsh.h>
672 FINSH_FUNCTION_EXPORT(dm9000a, dm9000a register dump);
673 #endif
674