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