00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 #include <cfg/os.h>
00068 #include <arch/arm.h>
00069
00070 #include <string.h>
00071
00072 #include <sys/atom.h>
00073 #include <sys/heap.h>
00074 #include <sys/thread.h>
00075 #include <sys/event.h>
00076 #include <sys/timer.h>
00077 #include <sys/confnet.h>
00078
00079 #include <netinet/if_ether.h>
00080 #include <net/ether.h>
00081 #include <net/if_var.h>
00082
00083 #include <dev/irqreg.h>
00084 #include <dev/dm9000e.h>
00085
00086 #ifdef NUTDEBUG
00087 #include <stdio.h>
00088 #endif
00089
00090 #ifndef NUT_THREAD_NICRXSTACK
00091 #define NUT_THREAD_NICRXSTACK 768
00092 #endif
00093
00094
00095
00096
00097 #ifndef NIC_BASE_ADDR
00098 #define NIC_BASE_ADDR 0x20000000
00099 #endif
00100
00101 #ifndef NIC_DATA_ADDR
00102 #define NIC_DATA_ADDR (NIC_BASE_ADDR + 4)
00103 #endif
00104
00105 #define INT0 0
00106 #define INT1 1
00107 #define INT2 2
00108 #define INT3 3
00109 #define INT4 4
00110 #define INT5 5
00111 #define INT6 6
00112 #define INT7 7
00113
00114 #ifndef NIC_SIGNAL_IRQ
00115 #define NIC_SIGNAL_IRQ INT1
00116 #endif
00117
00118 #ifdef NIC_RESET_BIT
00119
00120 #if (NIC_RESET_AVRPORT == AVRPORTB)
00121 #define NIC_RESET_PORT PORTB
00122 #define NIC_RESET_DDR DDRB
00123
00124 #elif (NIC_RESET_AVRPORT == AVRPORTD)
00125 #define NIC_RESET_PORT PORTD
00126 #define NIC_RESET_DDR DDRD
00127
00128 #elif (NIC_RESET_AVRPORT == AVRPORTE)
00129 #define NIC_RESET_PORT PORTE
00130 #define NIC_RESET_DDR DDRE
00131
00132 #elif (NIC_RESET_AVRPORT == AVRPORTF)
00133 #define NIC_RESET_PORT PORTF
00134 #define NIC_RESET_DDR DDRF
00135
00136 #endif
00137
00138 #endif
00139
00140
00141
00142
00143
00144 #if (NIC_SIGNAL_IRQ == INT0)
00145 #define NIC_SIGNAL sig_INTERRUPT0
00146
00147 #elif (NIC_SIGNAL_IRQ == INT2)
00148 #define NIC_SIGNAL sig_INTERRUPT2
00149
00150 #elif (NIC_SIGNAL_IRQ == INT3)
00151 #define NIC_SIGNAL sig_INTERRUPT3
00152
00153 #elif (NIC_SIGNAL_IRQ == INT4)
00154 #define NIC_SIGNAL sig_INTERRUPT4
00155
00156 #elif (NIC_SIGNAL_IRQ == INT5)
00157 #define NIC_SIGNAL sig_INTERRUPT5
00158
00159 #elif (NIC_SIGNAL_IRQ == INT6)
00160 #define NIC_SIGNAL sig_INTERRUPT6
00161
00162 #elif (NIC_SIGNAL_IRQ == INT7)
00163 #define NIC_SIGNAL sig_INTERRUPT7
00164
00165 #else
00166 #define NIC_SIGNAL sig_INTERRUPT1
00167
00168 #endif
00169
00174
00175 #define NIC_NCR 0x00
00176 #define NIC_NCR_LBM 0x06
00177 #define NIC_NCR_LBNORM 0x00
00178 #define NIC_NCR_LBMAC 0x02
00179 #define NIC_NCR_LBPHY 0x04
00180 #define NIC_NCR_RST 0x01
00181
00182 #define NIC_NSR 0x01
00183 #define NIC_NSR_SPEED 0x80
00184 #define NIC_NSR_LINKST 0x40
00185 #define NIC_NSR_WAKEST 0x20
00186 #define NIC_NSR_TX2END 0x08
00187 #define NIC_NSR_TX1END 0x04
00188 #define NIC_NSR_RXOV 0x02
00189
00190 #define NIC_TCR 0x02
00191 #define NIC_TCR_TXREQ 0x01
00192
00193 #define NIC_TSR1 0x03
00194
00195 #define NIC_TSR2 0x04
00196
00197 #define NIC_RCR 0x05
00198 #define NIC_RCR_DIS_LONG 0x20
00199 #define NIC_RCR_DIS_CRC 0x10
00200 #define NIC_RCR_ALL 0x08
00201 #define NIC_RCR_PRMSC 0x02
00202 #define NIC_RCR_RXEN 0x01
00203
00204 #define NIC_RSR 0x06
00205 #define NIC_RSR_ERRORS 0xBF
00206 #define NIC_RSR_RF 0x80
00207 #define NIC_RSR_MF 0x40
00208 #define NIC_RSR_LCS 0x20
00209 #define NIC_RSR_RWTO 0x10
00210 #define NIC_RSR_PLE 0x08
00211 #define NIC_RSR_AE 0x04
00212 #define NIC_RSR_CE 0x02
00213 #define NIC_RSR_FOE 0x01
00214
00215 #define NIC_ROCR 0x07
00216
00217 #define NIC_BPTR 0x08
00218
00219 #define NIC_FCTR 0x09
00220
00221 #define NIC_FCR 0x0A
00222
00223 #define NIC_EPCR 0x0B
00224
00225 #define NIC_EPAR 0x0C
00226
00227 #define NIC_EPDRL 0x0D
00228
00229 #define NIC_EPDRH 0x0E
00230
00231 #define NIC_WCR 0x0F
00232
00233 #define NIC_PAR 0x10
00234
00235 #define NIC_MAR 0x16
00236
00237 #define NIC_GPCR 0x1E
00238
00239 #define NIC_GPR 0x1F
00240
00241 #define NIC_TRPA 0x22
00242
00243 #define NIC_RWPA 0x24
00244
00245 #define NIC_VID 0x28
00246
00247 #define NIC_PID 0x2A
00248
00249 #define NIC_CHIPR 0x2C
00250
00251 #define NIC_SMCR 0x2F
00252
00253 #define NIC_MRCMDX 0xF0
00254
00255 #define NIC_MRCMD 0xF2
00256
00257 #define NIC_MRR 0xF4
00258
00259 #define NIC_MWCMDX 0xF6
00260
00261 #define NIC_MWCMD 0xF8
00262
00263 #define NIC_MWR 0xFA
00264
00265 #define NIC_TXPL 0xFC
00266
00267 #define NIC_ISR 0xFE
00268 #define NIC_ISR_IOM 0xC0
00269 #define NIC_ISR_M16 0x00
00270 #define NIC_ISR_M32 0x40
00271 #define NIC_ISR_M8 0x80
00272 #define NIC_ISR_ROOS 0x08
00273 #define NIC_ISR_ROS 0x04
00274 #define NIC_ISR_PTS 0x02
00275 #define NIC_ISR_PRS 0x01
00276
00277 #define NIC_IMR 0xFF
00278 #define NIC_IMR_PAR 0x80
00279 #define NIC_IMR_ROOM 0x08
00280 #define NIC_IMR_ROM 0x04
00281 #define NIC_IMR_PTM 0x02
00282 #define NIC_IMR_PRM 0x01
00283
00284 #define NIC_PHY_BMCR 0x00
00285
00286 #define NIC_PHY_BMSR 0x01
00287 #define NIC_PHY_BMSR_ANCOMPL 0x0020
00288 #define NIC_PHY_BMSR_LINKSTAT 0x0004
00289
00290 #define NIC_PHY_ID1 0x02
00291
00292 #define NIC_PHY_ID2 0x03
00293
00294 #define NIC_PHY_ANAR 0x04
00295
00296 #define NIC_PHY_ANLPAR 0x05
00297
00298 #define NIC_PHY_ANER 0x06
00299
00300 #define NIC_PHY_DSCR 0x10
00301
00302 #define NIC_PHY_DSCSR 0x11
00303
00304 #define NIC_PHY_10BTCSR 0x12
00305
00309 struct _NICINFO {
00310 #ifdef NUT_PERFMON
00311 u_long ni_rx_packets;
00312 u_long ni_tx_packets;
00313 u_long ni_overruns;
00314 u_long ni_rx_frame_errors;
00315 u_long ni_rx_crc_errors;
00316 u_long ni_rx_missed_errors;
00317 #endif
00318 HANDLE volatile ni_rx_rdy;
00319 HANDLE volatile ni_tx_rdy;
00320 HANDLE ni_mutex;
00321 volatile int ni_tx_queued;
00322 volatile int ni_tx_quelen;
00323 volatile int ni_insane;
00324 int ni_iomode;
00325 };
00326
00330 typedef struct _NICINFO NICINFO;
00331
00338
00339
00340 static INLINE void nic_outb(u_char reg, u_char val)
00341 {
00342 outb(NIC_BASE_ADDR, reg);
00343 outb(NIC_DATA_ADDR, val);
00344 }
00345
00346 static INLINE u_char nic_inb(u_short reg)
00347 {
00348 outb(NIC_BASE_ADDR, reg);
00349 return inb(NIC_DATA_ADDR);
00350 }
00351
00359 static u_short phy_inw(u_char reg)
00360 {
00361
00362 nic_outb(NIC_EPAR, 0x40 | reg);
00363
00364
00365 nic_outb(NIC_EPCR, 0x0C);
00366 NutDelay(1);
00367 nic_outb(NIC_EPCR, 0x00);
00368
00369
00370 return ((u_short) nic_inb(NIC_EPDRH) << 8) | (u_short) nic_inb(NIC_EPDRL);
00371 }
00372
00381 static void phy_outw(u_char reg, u_short val)
00382 {
00383
00384 nic_outb(NIC_EPAR, 0x40 | reg);
00385
00386
00387 nic_outb(NIC_EPDRL, (u_char) val);
00388 nic_outb(NIC_EPDRH, (u_char) (val >> 8));
00389
00390
00391 nic_outb(NIC_EPCR, 0x0A);
00392 NutDelay(1);
00393 nic_outb(NIC_EPCR, 0x00);
00394 }
00395
00396 static int NicPhyInit(void)
00397 {
00398
00399 phy_outw(NIC_PHY_ANAR, 0x01E1);
00400 phy_outw(NIC_PHY_BMCR, 0x1200);
00401
00402 nic_outb(NIC_GPCR, 1);
00403 nic_outb(NIC_GPR, 0);
00404
00405 return 0;
00406 }
00407
00413 static int NicReset(void)
00414 {
00415
00416 #ifdef undef_NIC_RESET_BIT
00417 sbi(NIC_RESET_DDR, NIC_RESET_BIT);
00418 sbi(NIC_RESET_PORT, NIC_RESET_BIT);
00419 NutDelay(WAIT100);
00420 cbi(NIC_RESET_PORT, NIC_RESET_BIT);
00421 NutDelay(WAIT250);
00422 NutDelay(WAIT250);
00423 #else
00424
00425 nic_outb(NIC_NCR, NIC_NCR_RST | NIC_NCR_LBMAC);
00426 NutDelay(1);
00427
00428 #endif
00429
00430 return NicPhyInit();
00431 }
00432
00433
00434
00435
00436 static void NicInterrupt(void *arg)
00437 {
00438 u_char isr;
00439 NICINFO *ni = (NICINFO *) ((NUTDEVICE *) arg)->dev_dcb;
00440
00441
00442 isr = nic_inb(NIC_ISR);
00443
00444
00445 if (isr & NIC_ISR_PRS) {
00446 nic_outb(NIC_ISR, NIC_ISR_PRS);
00447 NutEventPostFromIrq(&ni->ni_rx_rdy);
00448 }
00449
00450
00451 if (isr & NIC_ISR_PTS) {
00452 if (ni->ni_tx_queued) {
00453 if (ni->ni_tx_quelen) {
00454
00455 nic_outb(NIC_TXPL, (u_char) ni->ni_tx_quelen);
00456 nic_outb(NIC_TXPL + 1, (u_char) (ni->ni_tx_quelen >> 8));
00457 ni->ni_tx_quelen = 0;
00458 nic_outb(NIC_TCR, NIC_TCR_TXREQ);
00459 }
00460 ni->ni_tx_queued--;
00461 }
00462 nic_outb(NIC_ISR, NIC_ISR_PTS);
00463 NutEventPostFromIrq(&ni->ni_tx_rdy);
00464 }
00465
00466
00467 if (isr & NIC_ISR_ROS) {
00468 nic_outb(NIC_ISR, NIC_ISR_ROS);
00469 ni->ni_insane = 1;
00470 NutEventPostFromIrq(&ni->ni_rx_rdy);
00471 }
00472
00473
00474 if (isr & NIC_ISR_ROOS) {
00475 nic_outb(NIC_ISR, NIC_ISR_ROOS);
00476 NutEventPostFromIrq(&ni->ni_rx_rdy);
00477 }
00478 }
00479
00485 static void NicWrite8(u_char * buf, u_short len)
00486 {
00487 while (len--) {
00488 outb(NIC_DATA_ADDR, *buf);
00489 buf++;
00490 }
00491 }
00492
00498 static void NicWrite16(u_char * buf, u_short len)
00499 {
00500 u_short *wp = (u_short *) buf;
00501
00502 len = (len + 1) / 2;
00503 while (len--) {
00504 outw(NIC_DATA_ADDR, *wp);
00505 wp++;
00506 }
00507 }
00508
00514 static void NicRead8(u_char * buf, u_short len)
00515 {
00516 while (len--) {
00517 *buf++ = inb(NIC_DATA_ADDR);
00518 }
00519 }
00520
00526 static void NicRead16(u_char * buf, u_short len)
00527 {
00528 u_short *wp = (u_short *) buf;
00529
00530 len = (len + 1) / 2;
00531 while (len--) {
00532 *wp++ = inw(NIC_DATA_ADDR);
00533 }
00534 }
00535
00544 static int NicGetPacket(NICINFO * ni, NETBUF ** nbp)
00545 {
00546 int rc = -1;
00547 u_short fsw;
00548 u_short fbc;
00549
00550 *nbp = NULL;
00551
00552
00553 NutIrqDisable(&NIC_SIGNAL);
00554
00555
00556
00557
00558
00559
00560 nic_inb(NIC_MRCMDX);
00561
00562 _NOP(); _NOP(); _NOP(); _NOP();
00563 fsw = inb(NIC_DATA_ADDR);
00564 if (fsw > 1) {
00565 ni->ni_insane = 1;
00566 } else if (fsw) {
00567
00568 outb(NIC_BASE_ADDR, NIC_MRCMD);
00569 if (ni->ni_iomode == NIC_ISR_M16) {
00570 fsw = inw(NIC_DATA_ADDR);
00571 _NOP(); _NOP(); _NOP(); _NOP();
00572 fbc = inw(NIC_DATA_ADDR);
00573 } else {
00574 fsw = inb(NIC_DATA_ADDR) + ((u_short) inb(NIC_DATA_ADDR) << 8);
00575 _NOP(); _NOP(); _NOP(); _NOP();
00576 fbc = inb(NIC_DATA_ADDR) + ((u_short) inb(NIC_DATA_ADDR) << 8);
00577 }
00578
00579
00580
00581
00582
00583
00584 if (fbc > 1536) {
00585 ni->ni_insane = 1;
00586 } else {
00587
00588
00589
00590
00591 fsw >>= 8;
00592 fsw &= NIC_RSR_ERRORS;
00593 #ifdef NUT_PERMON
00594
00595 if (fsw) {
00596 if (RxStatus & NIC_RSR_CE) {
00597 ni->ni_crc_errors++;
00598 } else if (RxStatus & NIC_RSR_FOE) {
00599 ni->ni_overruns++;
00600 } else {
00601 ni->ni_rx_missed_errors++;
00602 }
00603 } else {
00604 ni->ni_rx_packets++;
00605 }
00606 #endif
00607
00608
00609
00610
00611 if (fsw || (*nbp = NutNetBufAlloc(0, NBAF_DATALINK, fbc - 4)) == NULL) {
00612 if (ni->ni_iomode == NIC_ISR_M16) {
00613 fbc = (fbc + 1) / 2;
00614 while (fbc--) {
00615 fsw = inw(NIC_DATA_ADDR);
00616 }
00617 } else {
00618 while (fbc--) {
00619 fsw = inb(NIC_DATA_ADDR);
00620 }
00621 }
00622 } else {
00623 if (ni->ni_iomode == NIC_ISR_M16) {
00624
00625 NicRead16((*nbp)->nb_dl.vp, (*nbp)->nb_dl.sz);
00626
00627 fsw = inw(NIC_DATA_ADDR);
00628 fsw = inw(NIC_DATA_ADDR);
00629 } else {
00630
00631 NicRead8((*nbp)->nb_dl.vp, (*nbp)->nb_dl.sz);
00632
00633 fsw = inb(NIC_DATA_ADDR);
00634 fsw = inb(NIC_DATA_ADDR);
00635 fsw = inb(NIC_DATA_ADDR);
00636 fsw = inb(NIC_DATA_ADDR);
00637 }
00638
00639 rc = 0;
00640 }
00641 }
00642 }
00643
00644
00645 if (ni->ni_insane == 0) {
00646 NutIrqEnable(&NIC_SIGNAL);
00647 }
00648 return rc;
00649 }
00650
00663 static int NicPutPacket(NICINFO * ni, NETBUF * nb)
00664 {
00665 int rc = -1;
00666 u_short sz;
00667
00668
00669
00670
00671
00672
00673
00674 if ((sz = nb->nb_nw.sz + nb->nb_tp.sz + nb->nb_ap.sz) > ETHERMTU) {
00675 return -1;
00676 }
00677 sz += nb->nb_dl.sz;
00678 if (sz & 1) {
00679 sz++;
00680 }
00681
00682
00683 NutIrqDisable(&NIC_SIGNAL);
00684
00685
00686 if (ni->ni_insane == 0) {
00687
00688 outb(NIC_BASE_ADDR, NIC_MWCMD);
00689
00690
00691 if (ni->ni_iomode == NIC_ISR_M16) {
00692 NicWrite16(nb->nb_dl.vp, nb->nb_dl.sz);
00693 NicWrite16(nb->nb_nw.vp, nb->nb_nw.sz);
00694 NicWrite16(nb->nb_tp.vp, nb->nb_tp.sz);
00695 NicWrite16(nb->nb_ap.vp, nb->nb_ap.sz);
00696 } else {
00697 NicWrite8(nb->nb_dl.vp, nb->nb_dl.sz);
00698 NicWrite8(nb->nb_nw.vp, nb->nb_nw.sz);
00699 NicWrite8(nb->nb_tp.vp, nb->nb_tp.sz);
00700 NicWrite8(nb->nb_ap.vp, nb->nb_ap.sz);
00701 }
00702
00703
00704 if (ni->ni_tx_queued == 0) {
00705 nic_outb(NIC_TXPL, (u_char) sz);
00706 nic_outb(NIC_TXPL + 1, (u_char) (sz >> 8));
00707 nic_outb(NIC_TCR, NIC_TCR_TXREQ);
00708 }
00709
00710 else {
00711 ni->ni_tx_quelen = sz;
00712 }
00713 ni->ni_tx_queued++;
00714 rc = 0;
00715 #ifdef NUT_PERFMON
00716 ni->ni_tx_packets++;
00717 #endif
00718 }
00719
00720
00721 NutIrqEnable(&NIC_SIGNAL);
00722
00723
00724
00725 if (rc == 0 && ni->ni_tx_queued > 1) {
00726 NutEventWait(&ni->ni_tx_rdy, 500);
00727 }
00728 return rc;
00729 }
00730
00738 static int NicStart(CONST u_char * mac)
00739 {
00740 int i;
00741 int link_wait = 20;
00742
00743
00744 nic_outb(NIC_GPR, 0);
00745 NutDelay(5);
00746
00747
00748 nic_outb(NIC_NCR, NIC_NCR_RST | NIC_NCR_LBMAC);
00749 NutDelay(5);
00750 nic_outb(NIC_NCR, NIC_NCR_RST | NIC_NCR_LBMAC);
00751 NutDelay(5);
00752
00753
00754
00755
00756
00757 nic_outb(NIC_GPR, 1);
00758 nic_outb(NIC_GPR, 0);
00759
00760
00761 for (i = 0; i < 6; i++) {
00762 nic_outb(NIC_PAR + i, mac[i]);
00763 }
00764
00765
00766 for (i = 0; i < 7; i++) {
00767 nic_outb(NIC_MAR + i, 0);
00768 }
00769 nic_outb(NIC_MAR + 7, 0x80);
00770
00771
00772 nic_outb(NIC_ISR, NIC_ISR_ROOS | NIC_ISR_ROS | NIC_ISR_PTS | NIC_ISR_PRS);
00773
00774
00775 nic_outb(NIC_RCR, NIC_RCR_DIS_LONG | NIC_RCR_DIS_CRC | NIC_RCR_RXEN | NIC_RCR_ALL);
00776
00777
00778 for (link_wait = 20;; link_wait--) {
00779 if (phy_inw(NIC_PHY_BMSR) & NIC_PHY_BMSR_ANCOMPL) {
00780 break;
00781 }
00782 if (link_wait == 0) {
00783 return -1;
00784 }
00785 NutSleep(200);
00786 }
00787
00788
00789 nic_outb(NIC_IMR, NIC_IMR_PAR | NIC_IMR_PTM | NIC_IMR_PRM);
00790
00791 return 0;
00792 }
00793
00798 THREAD(NicRxLanc, arg)
00799 {
00800 NUTDEVICE *dev;
00801 IFNET *ifn;
00802 NICINFO *ni;
00803 NETBUF *nb;
00804
00805 dev = arg;
00806 ifn = (IFNET *) dev->dev_icb;
00807 ni = (NICINFO *) dev->dev_dcb;
00808
00809
00810
00811
00812
00813
00814 for (;;) {
00815 int i;
00816
00817 for (i = 0; i < sizeof(ifn->if_mac); i++) {
00818 if (ifn->if_mac[i] && ifn->if_mac[i] != 0xFF) {
00819 break;
00820 }
00821 }
00822 if (i < sizeof(ifn->if_mac)) {
00823 break;
00824 }
00825 NutSleep(63);
00826 }
00827
00828
00829
00830
00831
00832
00833
00834 while (NicStart(ifn->if_mac)) {
00835 NutSleep(1000);
00836 }
00837
00838
00839 NutEventPost(&ni->ni_mutex);
00840
00841
00842 NutThreadSetPriority(9);
00843
00844
00845 outr(PIO_PDR, _BV(10));
00846 NutIrqEnable(&NIC_SIGNAL);
00847
00848 for (;;) {
00849
00850
00851
00852
00853 NutEventWait(&ni->ni_rx_rdy, 2000);
00854
00855
00856
00857
00858
00859 while (NicGetPacket(ni, &nb) == 0) {
00860
00861
00862 if (nb->nb_dl.sz < 60) {
00863 NutNetBufFree(nb);
00864 } else {
00865 (*ifn->if_recv) (dev, nb);
00866 }
00867 }
00868
00869
00870 while (ni->ni_insane) {
00871 if (NicStart(ifn->if_mac) == 0) {
00872 ni->ni_insane = 0;
00873 ni->ni_tx_queued = 0;
00874 ni->ni_tx_quelen = 0;
00875 NutIrqEnable(&NIC_SIGNAL);
00876 } else {
00877 NutSleep(1000);
00878 }
00879 }
00880 }
00881 }
00882
00893 int DmOutput(NUTDEVICE * dev, NETBUF * nb)
00894 {
00895 static u_long mx_wait = 5000;
00896 int rc = -1;
00897 NICINFO *ni = (NICINFO *) dev->dev_dcb;
00898
00899
00900
00901
00902
00903 while (rc) {
00904 if (ni->ni_insane) {
00905 break;
00906 }
00907 if (NutEventWait(&ni->ni_mutex, mx_wait)) {
00908 break;
00909 }
00910
00911
00912 if (ni->ni_tx_queued > 1) {
00913 if (NutEventWait(&ni->ni_tx_rdy, 500)) {
00914
00915 NutEventPost(&ni->ni_mutex);
00916 break;
00917 }
00918 } else if (NicPutPacket(ni, nb) == 0) {
00919
00920
00921 rc = 0;
00922 mx_wait = 5000;
00923 }
00924 NutEventPost(&ni->ni_mutex);
00925 }
00926
00927
00928
00929
00930 if (rc) {
00931 mx_wait = 500;
00932 }
00933 return rc;
00934 }
00935
00953 int DmInit(NUTDEVICE * dev)
00954 {
00955 u_long id;
00956 NICINFO *ni = (NICINFO *) dev->dev_dcb;
00957
00958
00959 id = (u_long) nic_inb(NIC_VID);
00960 id |= (u_long) nic_inb(NIC_VID + 1) << 8;
00961 id |= (u_long) nic_inb(NIC_PID) << 16;
00962 id |= (u_long) nic_inb(NIC_PID + 1) << 24;
00963 if (id != 0x90000A46) {
00964 return -1;
00965 }
00966
00967
00968 if (NicReset()) {
00969 return -1;
00970 }
00971
00972
00973 memset(ni, 0, sizeof(NICINFO));
00974
00975
00976 ni->ni_iomode = nic_inb(NIC_ISR) & NIC_ISR_IOM;
00977 if (ni->ni_iomode == NIC_ISR_M32) {
00978 return -1;
00979 }
00980
00981
00982 if (NutRegisterIrqHandler(&NIC_SIGNAL, NicInterrupt, dev)) {
00983 return -1;
00984 }
00985
00986
00987 if (NutThreadCreate("rxi1", NicRxLanc, dev, NUT_THREAD_NICRXSTACK) == NULL) {
00988 return -1;
00989 }
00990 return 0;
00991 }
00992
00993 static NICINFO dcb_eth0;
00994
01000 static IFNET ifn_eth0 = {
01001 IFT_ETHER,
01002 {0, 0, 0, 0, 0, 0},
01003 0,
01004 0,
01005 0,
01006 ETHERMTU,
01007 0,
01008 0,
01009 0,
01010 NutEtherInput,
01011 DmOutput,
01012 NutEtherOutput
01013 };
01014
01024 NUTDEVICE devDM9000E = {
01025 0,
01026 {'e', 't', 'h', '0', 0, 0, 0, 0, 0},
01027 IFTYP_NET,
01028 0,
01029 0,
01030 &ifn_eth0,
01031 &dcb_eth0,
01032 DmInit,
01033 0,
01034 0,
01035 0,
01036 #ifdef __HARVARD_ARCH__
01037 0,
01038 #endif
01039 0,
01040 0,
01041 0
01042 };
01043