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