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