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