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
00068
00069
00070
00071 #include <cfg/os.h>
00072 #include <arch/arm.h>
00073
00074 #include <string.h>
00075
00076 #include <sys/atom.h>
00077 #include <sys/heap.h>
00078 #include <sys/thread.h>
00079 #include <sys/event.h>
00080 #include <sys/timer.h>
00081 #include <sys/confnet.h>
00082
00083 #include <netinet/if_ether.h>
00084 #include <net/ether.h>
00085 #include <net/if_var.h>
00086
00087 #include <dev/irqreg.h>
00088 #include <dev/dm9000e.h>
00089
00090 #ifdef NUTDEBUG
00091 #include <stdio.h>
00092 #endif
00093
00094 #ifndef NUT_THREAD_NICRXSTACK
00095 #define NUT_THREAD_NICRXSTACK 768
00096 #endif
00097
00098
00099
00100
00101 #if defined(ETHERNUT3)
00102
00103 #ifndef NIC_BASE_ADDR
00104 #define NIC_BASE_ADDR 0x20000000
00105 #endif
00106
00107 #ifndef NIC_SIGNAL_IRQ
00108 #define NIC_SIGNAL_IRQ INT1
00109 #endif
00110
00111 #ifndef NIC_SIGNAL_PDR
00112 #define NIC_SIGNAL_PDR PIO_PDR
00113 #endif
00114
00115 #ifndef NIC_SIGNAL_BIT
00116 #define NIC_SIGNAL_BIT 10
00117 #endif
00118
00119 #elif defined(ELEKTOR_IR1)
00120
00121 #ifndef NIC_BASE_ADDR
00122 #define NIC_BASE_ADDR 0x30000000
00123 #endif
00124
00125 #ifndef NIC_SIGNAL_IRQ
00126 #define NIC_SIGNAL_IRQ INT0
00127 #endif
00128
00129 #ifndef NIC_SIGNAL_PDR
00130 #define NIC_SIGNAL_PDR PIOB_PDR
00131 #endif
00132
00133 #ifndef NIC_SIGNAL_XSR
00134 #define NIC_SIGNAL_XSR PIOB_ASR
00135 #endif
00136
00137 #ifndef NIC_SIGNAL_BIT
00138 #define NIC_SIGNAL_BIT PB20_IRQ0_A
00139 #endif
00140
00141 #endif
00142
00143 #ifndef NIC_DATA_ADDR
00144 #define NIC_DATA_ADDR (NIC_BASE_ADDR + 4)
00145 #endif
00146
00147 #define INT0 0
00148 #define INT1 1
00149 #define INT2 2
00150 #define INT3 3
00151 #define INT4 4
00152 #define INT5 5
00153 #define INT6 6
00154 #define INT7 7
00155
00156 #ifdef NIC_RESET_BIT
00157
00158 #if (NIC_RESET_AVRPORT == AVRPORTB)
00159 #define NIC_RESET_PORT PORTB
00160 #define NIC_RESET_DDR DDRB
00161
00162 #elif (NIC_RESET_AVRPORT == AVRPORTD)
00163 #define NIC_RESET_PORT PORTD
00164 #define NIC_RESET_DDR DDRD
00165
00166 #elif (NIC_RESET_AVRPORT == AVRPORTE)
00167 #define NIC_RESET_PORT PORTE
00168 #define NIC_RESET_DDR DDRE
00169
00170 #elif (NIC_RESET_AVRPORT == AVRPORTF)
00171 #define NIC_RESET_PORT PORTF
00172 #define NIC_RESET_DDR DDRF
00173
00174 #endif
00175
00176 #endif
00177
00178
00179
00180
00181
00182 #if (NIC_SIGNAL_IRQ == INT0)
00183 #define NIC_SIGNAL sig_INTERRUPT0
00184
00185 #elif (NIC_SIGNAL_IRQ == INT2)
00186 #define NIC_SIGNAL sig_INTERRUPT2
00187
00188 #elif (NIC_SIGNAL_IRQ == INT3)
00189 #define NIC_SIGNAL sig_INTERRUPT3
00190
00191 #elif (NIC_SIGNAL_IRQ == INT4)
00192 #define NIC_SIGNAL sig_INTERRUPT4
00193
00194 #elif (NIC_SIGNAL_IRQ == INT5)
00195 #define NIC_SIGNAL sig_INTERRUPT5
00196
00197 #elif (NIC_SIGNAL_IRQ == INT6)
00198 #define NIC_SIGNAL sig_INTERRUPT6
00199
00200 #elif (NIC_SIGNAL_IRQ == INT7)
00201 #define NIC_SIGNAL sig_INTERRUPT7
00202
00203 #else
00204 #define NIC_SIGNAL sig_INTERRUPT1
00205
00206 #endif
00207
00212
00213 #define NIC_NCR 0x00
00214 #define NIC_NCR_LBM 0x06
00215 #define NIC_NCR_LBNORM 0x00
00216 #define NIC_NCR_LBMAC 0x02
00217 #define NIC_NCR_LBPHY 0x04
00218 #define NIC_NCR_RST 0x01
00219
00220 #define NIC_NSR 0x01
00221 #define NIC_NSR_SPEED 0x80
00222 #define NIC_NSR_LINKST 0x40
00223 #define NIC_NSR_WAKEST 0x20
00224 #define NIC_NSR_TX2END 0x08
00225 #define NIC_NSR_TX1END 0x04
00226 #define NIC_NSR_RXOV 0x02
00227
00228 #define NIC_TCR 0x02
00229 #define NIC_TCR_TXREQ 0x01
00230
00231 #define NIC_TSR1 0x03
00232
00233 #define NIC_TSR2 0x04
00234
00235 #define NIC_RCR 0x05
00236 #define NIC_RCR_DIS_LONG 0x20
00237 #define NIC_RCR_DIS_CRC 0x10
00238 #define NIC_RCR_ALL 0x08
00239 #define NIC_RCR_PRMSC 0x02
00240 #define NIC_RCR_RXEN 0x01
00241
00242 #define NIC_RSR 0x06
00243 #define NIC_RSR_ERRORS 0xBF
00244 #define NIC_RSR_RF 0x80
00245 #define NIC_RSR_MF 0x40
00246 #define NIC_RSR_LCS 0x20
00247 #define NIC_RSR_RWTO 0x10
00248 #define NIC_RSR_PLE 0x08
00249 #define NIC_RSR_AE 0x04
00250 #define NIC_RSR_CE 0x02
00251 #define NIC_RSR_FOE 0x01
00252
00253 #define NIC_ROCR 0x07
00254
00255 #define NIC_BPTR 0x08
00256
00257 #define NIC_FCTR 0x09
00258
00259 #define NIC_FCR 0x0A
00260
00261 #define NIC_EPCR 0x0B
00262
00263 #define NIC_EPAR 0x0C
00264
00265 #define NIC_EPDRL 0x0D
00266
00267 #define NIC_EPDRH 0x0E
00268
00269 #define NIC_WCR 0x0F
00270
00271 #define NIC_PAR 0x10
00272
00273 #define NIC_MAR 0x16
00274
00275 #define NIC_GPCR 0x1E
00276
00277 #define NIC_GPR 0x1F
00278
00279 #define NIC_TRPA 0x22
00280
00281 #define NIC_RWPA 0x24
00282
00283 #define NIC_VID 0x28
00284
00285 #define NIC_PID 0x2A
00286
00287 #define NIC_CHIPR 0x2C
00288
00289 #define NIC_SMCR 0x2F
00290
00291 #define NIC_MRCMDX 0xF0
00292
00293 #define NIC_MRCMD 0xF2
00294
00295 #define NIC_MRR 0xF4
00296
00297 #define NIC_MWCMDX 0xF6
00298
00299 #define NIC_MWCMD 0xF8
00300
00301 #define NIC_MWR 0xFA
00302
00303 #define NIC_TXPL 0xFC
00304
00305 #define NIC_ISR 0xFE
00306 #define NIC_ISR_IOM 0xC0
00307 #define NIC_ISR_M16 0x00
00308 #define NIC_ISR_M32 0x40
00309 #define NIC_ISR_M8 0x80
00310 #define NIC_ISR_ROOS 0x08
00311 #define NIC_ISR_ROS 0x04
00312 #define NIC_ISR_PTS 0x02
00313 #define NIC_ISR_PRS 0x01
00314
00315 #define NIC_IMR 0xFF
00316 #define NIC_IMR_PAR 0x80
00317 #define NIC_IMR_ROOM 0x08
00318 #define NIC_IMR_ROM 0x04
00319 #define NIC_IMR_PTM 0x02
00320 #define NIC_IMR_PRM 0x01
00321
00322 #define NIC_PHY_BMCR 0x00
00323
00324 #define NIC_PHY_BMSR 0x01
00325 #define NIC_PHY_BMSR_ANCOMPL 0x0020
00326 #define NIC_PHY_BMSR_LINKSTAT 0x0004
00327
00328 #define NIC_PHY_ID1 0x02
00329
00330 #define NIC_PHY_ID2 0x03
00331
00332 #define NIC_PHY_ANAR 0x04
00333
00334 #define NIC_PHY_ANLPAR 0x05
00335
00336 #define NIC_PHY_ANER 0x06
00337
00338 #define NIC_PHY_DSCR 0x10
00339
00340 #define NIC_PHY_DSCSR 0x11
00341
00342 #define NIC_PHY_10BTCSR 0x12
00343
00347 struct _NICINFO {
00348 #ifdef NUT_PERFMON
00349 u_long ni_rx_packets;
00350 u_long ni_tx_packets;
00351 u_long ni_overruns;
00352 u_long ni_rx_frame_errors;
00353 u_long ni_rx_crc_errors;
00354 u_long ni_rx_missed_errors;
00355 #endif
00356 HANDLE volatile ni_rx_rdy;
00357 HANDLE volatile ni_tx_rdy;
00358 HANDLE ni_mutex;
00359 volatile int ni_tx_queued;
00360 volatile int ni_tx_quelen;
00361 volatile int ni_insane;
00362 int ni_iomode;
00363 };
00364
00368 typedef struct _NICINFO NICINFO;
00369
00376
00377
00378 static INLINE void nic_outb(u_char reg, u_char val)
00379 {
00380 outb(NIC_BASE_ADDR, reg);
00381 outb(NIC_DATA_ADDR, val);
00382 }
00383
00384 static INLINE u_char nic_inb(u_short reg)
00385 {
00386 outb(NIC_BASE_ADDR, reg);
00387 return inb(NIC_DATA_ADDR);
00388 }
00389
00397 static u_short phy_inw(u_char reg)
00398 {
00399
00400 nic_outb(NIC_EPAR, 0x40 | reg);
00401
00402
00403 nic_outb(NIC_EPCR, 0x0C);
00404 NutDelay(1);
00405 nic_outb(NIC_EPCR, 0x00);
00406
00407
00408 return ((u_short) nic_inb(NIC_EPDRH) << 8) | (u_short) nic_inb(NIC_EPDRL);
00409 }
00410
00419 static void phy_outw(u_char reg, u_short val)
00420 {
00421
00422 nic_outb(NIC_EPAR, 0x40 | reg);
00423
00424
00425 nic_outb(NIC_EPDRL, (u_char) val);
00426 nic_outb(NIC_EPDRH, (u_char) (val >> 8));
00427
00428
00429 nic_outb(NIC_EPCR, 0x0A);
00430 NutDelay(1);
00431 nic_outb(NIC_EPCR, 0x00);
00432 }
00433
00434 static int NicPhyInit(void)
00435 {
00436
00437 phy_outw(NIC_PHY_ANAR, 0x01E1);
00438 phy_outw(NIC_PHY_BMCR, 0x1200);
00439
00440 nic_outb(NIC_GPCR, 1);
00441 nic_outb(NIC_GPR, 0);
00442
00443 return 0;
00444 }
00445
00451 static int NicReset(void)
00452 {
00453
00454 #ifdef undef_NIC_RESET_BIT
00455 sbi(NIC_RESET_DDR, NIC_RESET_BIT);
00456 sbi(NIC_RESET_PORT, NIC_RESET_BIT);
00457 NutDelay(WAIT100);
00458 cbi(NIC_RESET_PORT, NIC_RESET_BIT);
00459 NutDelay(WAIT250);
00460 NutDelay(WAIT250);
00461 #else
00462
00463 nic_outb(NIC_NCR, NIC_NCR_RST | NIC_NCR_LBMAC);
00464 NutDelay(1);
00465
00466 #endif
00467
00468 return NicPhyInit();
00469 }
00470
00471
00472
00473
00474 static void NicInterrupt(void *arg)
00475 {
00476 u_char isr;
00477 NICINFO *ni = (NICINFO *) ((NUTDEVICE *) arg)->dev_dcb;
00478
00479
00480 isr = nic_inb(NIC_ISR);
00481
00482
00483 if (isr & NIC_ISR_PRS) {
00484 nic_outb(NIC_ISR, NIC_ISR_PRS);
00485 NutEventPostFromIrq(&ni->ni_rx_rdy);
00486 }
00487
00488
00489 if (isr & NIC_ISR_PTS) {
00490 if (ni->ni_tx_queued) {
00491 if (ni->ni_tx_quelen) {
00492
00493 nic_outb(NIC_TXPL, (u_char) ni->ni_tx_quelen);
00494 nic_outb(NIC_TXPL + 1, (u_char) (ni->ni_tx_quelen >> 8));
00495 ni->ni_tx_quelen = 0;
00496 nic_outb(NIC_TCR, NIC_TCR_TXREQ);
00497 }
00498 ni->ni_tx_queued--;
00499 }
00500 nic_outb(NIC_ISR, NIC_ISR_PTS);
00501 NutEventPostFromIrq(&ni->ni_tx_rdy);
00502 }
00503
00504
00505 if (isr & NIC_ISR_ROS) {
00506 nic_outb(NIC_ISR, NIC_ISR_ROS);
00507 ni->ni_insane = 1;
00508 NutEventPostFromIrq(&ni->ni_rx_rdy);
00509 }
00510
00511
00512 if (isr & NIC_ISR_ROOS) {
00513 nic_outb(NIC_ISR, NIC_ISR_ROOS);
00514 NutEventPostFromIrq(&ni->ni_rx_rdy);
00515 }
00516 }
00517
00523 static void NicWrite8(u_char * buf, u_short len)
00524 {
00525 while (len--) {
00526 outb(NIC_DATA_ADDR, *buf);
00527 buf++;
00528 }
00529 }
00530
00536 static void NicWrite16(u_char * buf, u_short len)
00537 {
00538 u_short *wp = (u_short *) buf;
00539
00540 len = (len + 1) / 2;
00541 while (len--) {
00542 outw(NIC_DATA_ADDR, *wp);
00543 wp++;
00544 }
00545 }
00546
00552 static void NicRead8(u_char * buf, u_short len)
00553 {
00554 while (len--) {
00555 *buf++ = inb(NIC_DATA_ADDR);
00556 }
00557 }
00558
00564 static void NicRead16(u_char * buf, u_short len)
00565 {
00566 u_short *wp = (u_short *) buf;
00567
00568 len = (len + 1) / 2;
00569 while (len--) {
00570 *wp++ = inw(NIC_DATA_ADDR);
00571 }
00572 }
00573
00582 static int NicGetPacket(NICINFO * ni, NETBUF ** nbp)
00583 {
00584 int rc = -1;
00585 u_short fsw;
00586 u_short fbc;
00587
00588 *nbp = NULL;
00589
00590
00591 NutIrqDisable(&NIC_SIGNAL);
00592
00593
00594
00595
00596
00597
00598 nic_inb(NIC_MRCMDX);
00599
00600 _NOP(); _NOP(); _NOP(); _NOP();
00601 fsw = inb(NIC_DATA_ADDR);
00602 if (fsw > 1) {
00603 ni->ni_insane = 1;
00604 } else if (fsw) {
00605
00606 outb(NIC_BASE_ADDR, NIC_MRCMD);
00607 if (ni->ni_iomode == NIC_ISR_M16) {
00608 fsw = inw(NIC_DATA_ADDR);
00609 _NOP(); _NOP(); _NOP(); _NOP();
00610 fbc = inw(NIC_DATA_ADDR);
00611 } else {
00612 fsw = inb(NIC_DATA_ADDR) + ((u_short) inb(NIC_DATA_ADDR) << 8);
00613 _NOP(); _NOP(); _NOP(); _NOP();
00614 fbc = inb(NIC_DATA_ADDR) + ((u_short) inb(NIC_DATA_ADDR) << 8);
00615 }
00616
00617
00618
00619
00620
00621
00622 if (fbc > 1536) {
00623 ni->ni_insane = 1;
00624 } else {
00625
00626
00627
00628
00629 fsw >>= 8;
00630 fsw &= NIC_RSR_ERRORS;
00631 #ifdef NUT_PERMON
00632
00633 if (fsw) {
00634 if (RxStatus & NIC_RSR_CE) {
00635 ni->ni_crc_errors++;
00636 } else if (RxStatus & NIC_RSR_FOE) {
00637 ni->ni_overruns++;
00638 } else {
00639 ni->ni_rx_missed_errors++;
00640 }
00641 } else {
00642 ni->ni_rx_packets++;
00643 }
00644 #endif
00645
00646
00647
00648
00649 if (fsw || (*nbp = NutNetBufAlloc(0, NBAF_DATALINK, fbc - 4)) == NULL) {
00650 if (ni->ni_iomode == NIC_ISR_M16) {
00651 fbc = (fbc + 1) / 2;
00652 while (fbc--) {
00653 fsw = inw(NIC_DATA_ADDR);
00654 }
00655 } else {
00656 while (fbc--) {
00657 fsw = inb(NIC_DATA_ADDR);
00658 }
00659 }
00660 } else {
00661 if (ni->ni_iomode == NIC_ISR_M16) {
00662
00663 NicRead16((*nbp)->nb_dl.vp, (*nbp)->nb_dl.sz);
00664
00665 fsw = inw(NIC_DATA_ADDR);
00666 fsw = inw(NIC_DATA_ADDR);
00667 } else {
00668
00669 NicRead8((*nbp)->nb_dl.vp, (*nbp)->nb_dl.sz);
00670
00671 fsw = inb(NIC_DATA_ADDR);
00672 fsw = inb(NIC_DATA_ADDR);
00673 fsw = inb(NIC_DATA_ADDR);
00674 fsw = inb(NIC_DATA_ADDR);
00675 }
00676
00677 rc = 0;
00678 }
00679 }
00680 }
00681
00682
00683 if (ni->ni_insane == 0) {
00684 NutIrqEnable(&NIC_SIGNAL);
00685 }
00686 return rc;
00687 }
00688
00701 static int NicPutPacket(NICINFO * ni, NETBUF * nb)
00702 {
00703 int rc = -1;
00704 u_short sz;
00705
00706
00707
00708
00709
00710
00711
00712 if ((sz = nb->nb_nw.sz + nb->nb_tp.sz + nb->nb_ap.sz) > ETHERMTU) {
00713 return -1;
00714 }
00715 sz += nb->nb_dl.sz;
00716 if (sz & 1) {
00717 sz++;
00718 }
00719
00720
00721 NutIrqDisable(&NIC_SIGNAL);
00722
00723
00724 if (ni->ni_insane == 0) {
00725
00726 outb(NIC_BASE_ADDR, NIC_MWCMD);
00727
00728
00729 if (ni->ni_iomode == NIC_ISR_M16) {
00730 NicWrite16(nb->nb_dl.vp, nb->nb_dl.sz);
00731 NicWrite16(nb->nb_nw.vp, nb->nb_nw.sz);
00732 NicWrite16(nb->nb_tp.vp, nb->nb_tp.sz);
00733 NicWrite16(nb->nb_ap.vp, nb->nb_ap.sz);
00734 } else {
00735 NicWrite8(nb->nb_dl.vp, nb->nb_dl.sz);
00736 NicWrite8(nb->nb_nw.vp, nb->nb_nw.sz);
00737 NicWrite8(nb->nb_tp.vp, nb->nb_tp.sz);
00738 NicWrite8(nb->nb_ap.vp, nb->nb_ap.sz);
00739 }
00740
00741
00742 if (ni->ni_tx_queued == 0) {
00743 nic_outb(NIC_TXPL, (u_char) sz);
00744 nic_outb(NIC_TXPL + 1, (u_char) (sz >> 8));
00745 nic_outb(NIC_TCR, NIC_TCR_TXREQ);
00746 }
00747
00748 else {
00749 ni->ni_tx_quelen = sz;
00750 }
00751 ni->ni_tx_queued++;
00752 rc = 0;
00753 #ifdef NUT_PERFMON
00754 ni->ni_tx_packets++;
00755 #endif
00756 }
00757
00758
00759 NutIrqEnable(&NIC_SIGNAL);
00760
00761
00762
00763 if (rc == 0 && ni->ni_tx_queued > 1) {
00764 NutEventWait(&ni->ni_tx_rdy, 500);
00765 }
00766 return rc;
00767 }
00768
00776 static int NicStart(CONST u_char * mac)
00777 {
00778 int i;
00779 int link_wait = 20;
00780
00781
00782 nic_outb(NIC_GPR, 0);
00783 NutDelay(5);
00784
00785
00786 nic_outb(NIC_NCR, NIC_NCR_RST | NIC_NCR_LBMAC);
00787 NutDelay(5);
00788 nic_outb(NIC_NCR, NIC_NCR_RST | NIC_NCR_LBMAC);
00789 NutDelay(5);
00790
00791
00792
00793
00794
00795 nic_outb(NIC_GPR, 1);
00796 nic_outb(NIC_GPR, 0);
00797
00798
00799 for (i = 0; i < 6; i++) {
00800 nic_outb(NIC_PAR + i, mac[i]);
00801 }
00802
00803
00804 for (i = 0; i < 7; i++) {
00805 nic_outb(NIC_MAR + i, 0);
00806 }
00807 nic_outb(NIC_MAR + 7, 0x80);
00808
00809
00810 nic_outb(NIC_ISR, NIC_ISR_ROOS | NIC_ISR_ROS | NIC_ISR_PTS | NIC_ISR_PRS);
00811
00812
00813 nic_outb(NIC_RCR, NIC_RCR_DIS_LONG | NIC_RCR_DIS_CRC | NIC_RCR_RXEN | NIC_RCR_ALL);
00814
00815
00816 for (link_wait = 20;; link_wait--) {
00817 if (phy_inw(NIC_PHY_BMSR) & NIC_PHY_BMSR_ANCOMPL) {
00818 break;
00819 }
00820 if (link_wait == 0) {
00821 return -1;
00822 }
00823 NutSleep(200);
00824 }
00825
00826
00827 nic_outb(NIC_IMR, NIC_IMR_PAR | NIC_IMR_PTM | NIC_IMR_PRM);
00828
00829 return 0;
00830 }
00831
00836 THREAD(NicRxLanc, arg)
00837 {
00838 NUTDEVICE *dev;
00839 IFNET *ifn;
00840 NICINFO *ni;
00841 NETBUF *nb;
00842
00843 dev = arg;
00844 ifn = (IFNET *) dev->dev_icb;
00845 ni = (NICINFO *) dev->dev_dcb;
00846
00847
00848
00849
00850
00851
00852 for (;;) {
00853 int i;
00854
00855 for (i = 0; i < sizeof(ifn->if_mac); i++) {
00856 if (ifn->if_mac[i] && ifn->if_mac[i] != 0xFF) {
00857 break;
00858 }
00859 }
00860 if (i < sizeof(ifn->if_mac)) {
00861 break;
00862 }
00863 NutSleep(63);
00864 }
00865
00866
00867
00868
00869
00870
00871
00872 while (NicStart(ifn->if_mac)) {
00873 NutSleep(1000);
00874 }
00875
00876
00877 NutEventPost(&ni->ni_mutex);
00878
00879
00880 NutThreadSetPriority(9);
00881
00882
00883 #ifdef NIC_SIGNAL_XSR
00884 outr(NIC_SIGNAL_XSR, _BV(NIC_SIGNAL_BIT));
00885 #if defined(ELEKTOR_IR1)
00886
00887 outr(PMC_PCER, _BV(IRQ0_ID));
00888 #endif
00889 #endif
00890 outr(NIC_SIGNAL_PDR, _BV(NIC_SIGNAL_BIT));
00891 NutIrqEnable(&NIC_SIGNAL);
00892 #if defined(ELEKTOR_IR1)
00893
00894 NutIrqSetMode(&NIC_SIGNAL, NUT_IRQMODE_HIGHLEVEL);
00895 #endif
00896
00897 for (;;) {
00898
00899
00900
00901
00902 NutEventWait(&ni->ni_rx_rdy, 2000);
00903
00904
00905
00906
00907
00908 while (NicGetPacket(ni, &nb) == 0) {
00909
00910
00911 if (nb->nb_dl.sz < 60) {
00912 NutNetBufFree(nb);
00913 } else {
00914 (*ifn->if_recv) (dev, nb);
00915 }
00916 }
00917
00918
00919 while (ni->ni_insane) {
00920 if (NicStart(ifn->if_mac) == 0) {
00921 ni->ni_insane = 0;
00922 ni->ni_tx_queued = 0;
00923 ni->ni_tx_quelen = 0;
00924 NutIrqEnable(&NIC_SIGNAL);
00925 } else {
00926 NutSleep(1000);
00927 }
00928 }
00929 }
00930 }
00931
00942 int DmOutput(NUTDEVICE * dev, NETBUF * nb)
00943 {
00944 static u_long mx_wait = 5000;
00945 int rc = -1;
00946 NICINFO *ni = (NICINFO *) dev->dev_dcb;
00947
00948
00949
00950
00951
00952 while (rc) {
00953 if (ni->ni_insane) {
00954 break;
00955 }
00956 if (NutEventWait(&ni->ni_mutex, mx_wait)) {
00957 break;
00958 }
00959
00960
00961 if (ni->ni_tx_queued > 1) {
00962 if (NutEventWait(&ni->ni_tx_rdy, 500)) {
00963
00964 NutEventPost(&ni->ni_mutex);
00965 break;
00966 }
00967 } else if (NicPutPacket(ni, nb) == 0) {
00968
00969
00970 rc = 0;
00971 mx_wait = 5000;
00972 }
00973 NutEventPost(&ni->ni_mutex);
00974 }
00975
00976
00977
00978
00979 if (rc) {
00980 mx_wait = 500;
00981 }
00982 return rc;
00983 }
00984
01002 int DmInit(NUTDEVICE * dev)
01003 {
01004 u_long id;
01005 NICINFO *ni = (NICINFO *) dev->dev_dcb;
01006
01007 #if defined(ELEKTOR_IR1)
01008 outr(PIOA_BSR, _BV(PA20_NCS2_B));
01009 outr(PIOA_PDR, _BV(PA20_NCS2_B));
01010 outr(PIOC_BSR, _BV(PC16_NWAIT_B) | _BV(PC21_NWR0_B) | _BV(PC22_NRD_B));
01011 outr(PIOC_PDR, _BV(PC16_NWAIT_B) | _BV(PC21_NWR0_B) | _BV(PC22_NRD_B));
01012
01013 outr(SMC_CSR(2)
01014 , (1 << SMC_NWS_LSB)
01015 | SMC_WSEN
01016 | (2 << SMC_TDF_LSB)
01017 | SMC_BAT
01018 | SMC_DBW_16
01019 | (1 << SMC_RWSETUP_LSB)
01020 | (1 << SMC_RWHOLD_LSB)
01021 );
01022 #endif
01023
01024
01025 id = (u_long) nic_inb(NIC_VID);
01026 id |= (u_long) nic_inb(NIC_VID + 1) << 8;
01027 id |= (u_long) nic_inb(NIC_PID) << 16;
01028 id |= (u_long) nic_inb(NIC_PID + 1) << 24;
01029 if (id != 0x90000A46) {
01030 return -1;
01031 }
01032
01033
01034 if (NicReset()) {
01035 return -1;
01036 }
01037
01038
01039 memset(ni, 0, sizeof(NICINFO));
01040
01041
01042 ni->ni_iomode = nic_inb(NIC_ISR) & NIC_ISR_IOM;
01043 if (ni->ni_iomode == NIC_ISR_M32) {
01044 return -1;
01045 }
01046
01047
01048 if (NutRegisterIrqHandler(&NIC_SIGNAL, NicInterrupt, dev)) {
01049 return -1;
01050 }
01051
01052
01053 if (NutThreadCreate("rxi1", NicRxLanc, dev, NUT_THREAD_NICRXSTACK) == NULL) {
01054 return -1;
01055 }
01056 return 0;
01057 }
01058
01059 static NICINFO dcb_eth0;
01060
01066 static IFNET ifn_eth0 = {
01067 IFT_ETHER,
01068 {0, 0, 0, 0, 0, 0},
01069 0,
01070 0,
01071 0,
01072 ETHERMTU,
01073 0,
01074 0,
01075 0,
01076 NutEtherInput,
01077 DmOutput,
01078 NutEtherOutput
01079 };
01080
01090 NUTDEVICE devDM9000E = {
01091 0,
01092 {'e', 't', 'h', '0', 0, 0, 0, 0, 0},
01093 IFTYP_NET,
01094 0,
01095 0,
01096 &ifn_eth0,
01097 &dcb_eth0,
01098 DmInit,
01099 0,
01100 0,
01101 0,
01102 #ifdef __HARVARD_ARCH__
01103 0,
01104 #endif
01105 0,
01106 0,
01107 0
01108 };
01109