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