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