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 #include <string.h>
00042
00043 #include <cfg/os.h>
00044 #include <sys/atom.h>
00045 #include <sys/heap.h>
00046 #include <sys/thread.h>
00047 #include <sys/event.h>
00048 #include <sys/timer.h>
00049 #include <sys/confnet.h>
00050
00051 #include <netinet/if_ether.h>
00052 #include <net/ether.h>
00053 #include <net/if.h>
00054 #include <net/if_var.h>
00055
00056 #include <cfg/arch/gpio.h>
00057 #include <dev/irqreg.h>
00058 #include <dev/lan91.h>
00059
00060 #ifdef NUTDEBUG
00061 #include <stdio.h>
00062 #endif
00063
00064
00065
00066
00067 #if (LAN91_SIGNAL_IRQ == INT0)
00068 #define LAN91_SIGNAL sig_INTERRUPT0
00069 #elif (LAN91_SIGNAL_IRQ == INT1)
00070 #define LAN91_SIGNAL sig_INTERRUPT1
00071 #elif (LAN91_SIGNAL_IRQ == INT2)
00072 #define LAN91_SIGNAL sig_INTERRUPT2
00073 #elif (LAN91_SIGNAL_IRQ == INT3)
00074 #define LAN91_SIGNAL sig_INTERRUPT3
00075 #elif (LAN91_SIGNAL_IRQ == INT4)
00076 #define LAN91_SIGNAL sig_INTERRUPT4
00077 #elif (LAN91_SIGNAL_IRQ == INT5)
00078 #define LAN91_SIGNAL sig_INTERRUPT5
00079 #elif (LAN91_SIGNAL_IRQ == INT6)
00080 #define LAN91_SIGNAL sig_INTERRUPT6
00081 #elif (LAN91_SIGNAL_IRQ == INT7)
00082 #define LAN91_SIGNAL sig_INTERRUPT7
00083 #endif
00084
00085
00086
00087
00088 #if !defined(LAN91_RX_POLLTIME)
00089 #if defined(LAN91_SIGNAL)
00090 #define LAN91_RX_POLLTIME 2000
00091 #else
00092 #define LAN91_RX_POLLTIME 200
00093 #endif
00094 #endif
00095
00096 #if !defined(LAN91_TX_POLLTIME)
00097 #if defined(LAN91_SIGNAL)
00098 #define LAN91_TX_POLLTIME 5000
00099 #else
00100 #define LAN91_TX_POLLTIME 200
00101 #endif
00102 #endif
00103
00104
00109
00110 #define nic_outlb(addr, val) (*(volatile uint8_t *)(addr) = (val))
00111 #define nic_outhb(addr, val) (*(volatile uint8_t *)((addr) + 1) = (val))
00112 #define nic_outwx(addr, val) (*(volatile uint16_t *)(addr) = (val))
00113 #define nic_outw(addr, val) { \
00114 *(volatile uint8_t *)(addr) = (uint8_t)(val); \
00115 *((volatile uint8_t *)(addr) + 1) = (uint8_t)((val) >> 8); \
00116 }
00117
00118 #define nic_inlb(addr) (*(volatile uint8_t *)(addr))
00119 #define nic_inhb(addr) (*(volatile uint8_t *)((addr) + 1))
00120 #define nic_inw(addr) (*(volatile uint16_t *)(addr))
00121
00122 #define nic_bs(bank) nic_outlb(LAN91_BSR, bank)
00123
00128 struct _NICINFO {
00129 HANDLE volatile ni_rx_rdy;
00130 uint16_t ni_tx_cnt;
00131 #ifdef NUT_PERFMON
00132 uint32_t ni_rx_packets;
00133 uint32_t ni_tx_packets;
00134 uint32_t ni_interrupts;
00135 uint32_t ni_overruns;
00136 uint32_t ni_rx_frame_errors;
00137 uint32_t ni_rx_crc_errors;
00138 uint32_t ni_rx_missed_errors;
00139 #endif
00140 };
00141
00145 typedef struct _NICINFO NICINFO;
00146
00147 static HANDLE mutex;
00148 static HANDLE maq;
00149
00160 static uint8_t NicPhyRegSelect(uint8_t reg, uint8_t we)
00161 {
00162 uint8_t rs;
00163 uint8_t msk;
00164 uint_fast8_t i;
00165
00166 nic_bs(3);
00167 rs = (nic_inlb(LAN91_MGMT) & ~(LAN91_MGMT_MCLK | LAN91_MGMT_MDO)) | LAN91_MGMT_MDOE;
00168
00169
00170 for (i = 0; i < 33; i++) {
00171 nic_outlb(LAN91_MGMT, rs | LAN91_MGMT_MDO);
00172 nic_outlb(LAN91_MGMT, rs | LAN91_MGMT_MDO | LAN91_MGMT_MCLK);
00173 }
00174
00175
00176 nic_outlb(LAN91_MGMT, rs);
00177 nic_outlb(LAN91_MGMT, rs | LAN91_MGMT_MCLK);
00178 nic_outlb(LAN91_MGMT, rs | LAN91_MGMT_MDO);
00179 nic_outlb(LAN91_MGMT, rs | LAN91_MGMT_MDO | LAN91_MGMT_MCLK);
00180
00181
00182 if (we) {
00183 nic_outlb(LAN91_MGMT, rs);
00184 nic_outlb(LAN91_MGMT, rs | LAN91_MGMT_MCLK);
00185 nic_outlb(LAN91_MGMT, rs | LAN91_MGMT_MDO);
00186 nic_outlb(LAN91_MGMT, rs | LAN91_MGMT_MDO | LAN91_MGMT_MCLK);
00187 } else {
00188 nic_outlb(LAN91_MGMT, rs | LAN91_MGMT_MDO);
00189 nic_outlb(LAN91_MGMT, rs | LAN91_MGMT_MDO | LAN91_MGMT_MCLK);
00190 nic_outlb(LAN91_MGMT, rs);
00191 nic_outlb(LAN91_MGMT, rs | LAN91_MGMT_MCLK);
00192 }
00193
00194
00195 for (i = 0; i < 5; i++) {
00196 nic_outlb(LAN91_MGMT, rs);
00197 nic_outlb(LAN91_MGMT, rs | LAN91_MGMT_MCLK);
00198 }
00199
00200
00201 for (msk = 0x10; msk; msk >>= 1) {
00202 if (reg & msk) {
00203 nic_outlb(LAN91_MGMT, rs | LAN91_MGMT_MDO);
00204 nic_outlb(LAN91_MGMT, rs | LAN91_MGMT_MDO | LAN91_MGMT_MCLK);
00205 } else {
00206 nic_outlb(LAN91_MGMT, rs);
00207 nic_outlb(LAN91_MGMT, rs | LAN91_MGMT_MCLK);
00208 }
00209 }
00210 nic_outlb(LAN91_MGMT, rs);
00211
00212 return rs;
00213 }
00214
00224 static uint16_t NicPhyRead(uint8_t reg)
00225 {
00226 uint16_t rc = 0;
00227 uint8_t rs;
00228 uint_fast8_t i;
00229
00230
00231 rs = NicPhyRegSelect(reg, 0);
00232
00233
00234 rs &= ~LAN91_MGMT_MDOE;
00235 nic_outlb(LAN91_MGMT, rs);
00236 nic_outlb(LAN91_MGMT, rs | LAN91_MGMT_MCLK);
00237
00238
00239 for (i = 0; i < 16; i++) {
00240 nic_outlb(LAN91_MGMT, rs);
00241 nic_outlb(LAN91_MGMT, rs | LAN91_MGMT_MCLK);
00242 rc <<= 1;
00243 rc |= (nic_inlb(LAN91_MGMT) & LAN91_MGMT_MDI) != 0;
00244 }
00245
00246
00247 nic_outlb(LAN91_MGMT, rs);
00248
00249 return rc;
00250 }
00251
00260 static void NicPhyWrite(uint8_t reg, uint16_t val)
00261 {
00262 uint16_t msk;
00263 uint8_t rs;
00264
00265
00266 rs = NicPhyRegSelect(reg, 1);
00267
00268
00269 nic_outlb(LAN91_MGMT, rs | LAN91_MGMT_MDO);
00270 nic_outlb(LAN91_MGMT, rs | LAN91_MGMT_MDO | LAN91_MGMT_MCLK);
00271 nic_outlb(LAN91_MGMT, rs);
00272 nic_outlb(LAN91_MGMT, rs | LAN91_MGMT_MCLK);
00273
00274
00275 for (msk = 0x8000; msk; msk >>= 1) {
00276 if (val & msk) {
00277 nic_outlb(LAN91_MGMT, rs | LAN91_MGMT_MDO);
00278 nic_outlb(LAN91_MGMT, rs | LAN91_MGMT_MDO | LAN91_MGMT_MCLK);
00279 } else {
00280 nic_outlb(LAN91_MGMT, rs);
00281 nic_outlb(LAN91_MGMT, rs | LAN91_MGMT_MCLK);
00282 }
00283 }
00284
00285
00286 nic_outlb(LAN91_MGMT, rs & ~LAN91_MGMT_MDOE);
00287 }
00288
00294 static int NicPhyConfig(void)
00295 {
00296 uint16_t phy_sor;
00297 uint16_t phy_sr;
00298 uint16_t phy_to;
00299 uint16_t mode;
00300
00301
00302
00303
00304
00305
00306 NicPhyWrite(LAN91_PHYCR, LAN91_PHYCR_RST);
00307 for (phy_to = 0;; phy_to++) {
00308 NutSleep(63);
00309 if ((NicPhyRead(LAN91_PHYCR) & LAN91_PHYCR_RST) == 0)
00310 break;
00311 if (phy_to > 3)
00312 return -1;
00313 }
00314
00315
00316 phy_sor = NicPhyRead(LAN91_PHYSOR);
00317
00318
00319 NicPhyWrite(LAN91_PHYMSK, LAN91_PHYMSK_MLOSSSYN | LAN91_PHYMSK_MCWRD | LAN91_PHYMSK_MSSD |
00320 LAN91_PHYMSK_MESD | LAN91_PHYMSK_MRPOL | LAN91_PHYMSK_MJAB | LAN91_PHYMSK_MSPDDT | LAN91_PHYMSK_MDPLDT);
00321
00322
00323 mode = LAN91_RPCR_ANEG | LAN91_RPCR_LEDA_PAT | LAN91_RPCR_LEDB_PAT;
00324 nic_bs(0);
00325 nic_outw(LAN91_RPCR, mode);
00326
00327 #ifdef LAN91_FIXED
00328
00329 phy_sr = NicPhyRead(LAN91_PHYCFR1);
00330 NicPhyWrite(LAN91_PHYCFR1, phy_sr | 0x8000);
00331 NutSleep(63);
00332
00333
00334 NicPhyWrite(LAN91_PHYCR, LAN91_FIXED);
00335 nic_bs(0);
00336 nic_outw(LAN91_RPCR, mode);
00337
00338
00339 phy_sr = NicPhyRead(LAN91_PHYCFR1);
00340 NicPhyWrite(LAN91_PHYCFR1, phy_sr & ~0x8000);
00341 phy_sr = NicPhyRead(LAN91_PHYCFR1);
00342
00343 #else
00344
00345
00346
00347
00348 NicPhyWrite(LAN91_PHYANAD, LAN91_PHYANAD_TX_FDX | LAN91_PHYANAD_TX_HDX | LAN91_PHYANAD_10FDX | LAN91_PHYANAD_10_HDX | LAN91_PHYANAD_CSMA);
00349 NutSleep(63);
00350 for (phy_to = 0, phy_sr = 0;; phy_to++) {
00351
00352 if (phy_to >= 1024)
00353 return -1;
00354
00355 if ((phy_to & 127) == 0 ) {
00356 NicPhyWrite(LAN91_PHYCR, LAN91_PHYCR_ANEG_EN | LAN91_PHYCR_ANEG_RST);
00357 NutSleep(63);
00358 }
00359
00360 phy_sr = NicPhyRead(LAN91_PHYSR);
00361 if (phy_sr & LAN91_PHYSR_ANEG_ACK)
00362 break;
00363 NutSleep(63);
00364 }
00365 #endif
00366
00367 return 0;
00368 }
00369
00380 static INLINE int NicMmuWait(uint_fast16_t tmo)
00381 {
00382 while (tmo--) {
00383 if ((nic_inlb(LAN91_MMUCR) & LAN91_MMUCR_BUSY) == 0)
00384 break;
00385 NutDelay(1);
00386 }
00387 return tmo ? 0 : -1;
00388 }
00389
00395 static int NicReset(void)
00396 {
00397 #ifdef LAN91_RESET_BIT
00398 GpioPinConfigSet(LAN91_RESET_GPIO_BANK, LAN91_RESET_GPIO_BIT, GPIO_CFG_OUTPUT);
00399 GpioPinSet(LAN91_RESET_GPIO_BANK, LAN91_RESET_GPIO_BIT, 1);
00400 NutDelay(10);
00401 GpioPinSet(LAN91_RESET_GPIO_BANK, LAN91_RESET_GPIO_BIT, 0);
00402 NutDelay(100);
00403 #endif
00404
00405
00406 nic_outlb(LAN91_MSK, 0);
00407
00408
00409 nic_bs(0);
00410 nic_outw(LAN91_RCR, LAN91_RCR_SOFT_RST);
00411
00412
00413 nic_bs(1);
00414 nic_outw(LAN91_CR, LAN91_CR_EPH_EN);
00415
00416 NutDelay(10);
00417
00418
00419 nic_bs(0);
00420 nic_outw(LAN91_RCR, 0);
00421 nic_outw(LAN91_TCR, 0);
00422
00423
00424 nic_bs(1);
00425 nic_outw(LAN91_CTR, LAN91_CTR_AUTO_RELEASE);
00426
00427
00428 nic_bs(2);
00429 nic_outlb(LAN91_MMUCR, LAN91_MMU_RST);
00430 if (NicMmuWait(1000))
00431 return -1;
00432
00433 return 0;
00434 }
00435
00436
00437
00438
00439
00440
00441
00442
00443 static int NicStart(CONST uint8_t * mac)
00444 {
00445 uint_fast8_t i;
00446
00447 if (NicReset())
00448 return -1;
00449
00450
00451 nic_bs(3);
00452 nic_outlb(LAN91_ERCV, 7);
00453 nic_bs(0);
00454 nic_outw(LAN91_RCR, LAN91_RCR_RXEN);
00455
00456
00457 nic_outw(LAN91_TCR, LAN91_TCR_PAD_EN | LAN91_TCR_TXENA);
00458
00459
00460 if (NicPhyConfig())
00461 return -1;
00462
00463
00464 nic_bs(1);
00465 for (i = 0; i < 6; i++)
00466 nic_outlb(LAN91_IAR + i, mac[i]);
00467
00468
00469 nic_bs(2);
00470 nic_outlb(LAN91_MSK, LAN91_INT_ERCV | LAN91_INT_RCV | LAN91_INT_RX_OVRN);
00471
00472 return 0;
00473 }
00474
00475 #if defined(LAN91_SIGNAL)
00476
00477
00478
00479 static void NicInterrupt(void *arg)
00480 {
00481 uint8_t isr;
00482 uint8_t imr;
00483 NICINFO *ni = (NICINFO *) ((NUTDEVICE *) arg)->dev_dcb;
00484
00485 #ifdef NUT_PERFMON
00486 ni->ni_interrupts++;
00487 #endif
00488
00489 nic_bs(2);
00490 imr = nic_inlb(LAN91_MSK);
00491 nic_outlb(LAN91_MSK, 0);
00492
00493
00494 isr = nic_inlb(LAN91_IST);
00495 isr &= imr;
00496
00497
00498
00499
00500
00501
00502 if (isr & LAN91_INT_TX_EMPTY) {
00503 nic_outlb(LAN91_ACK, LAN91_INT_TX_EMPTY);
00504 imr &= ~LAN91_INT_TX_EMPTY;
00505 }
00506
00507 else if (isr & LAN91_INT_TX) {
00508
00509 nic_bs(0);
00510 nic_outw(LAN91_TCR, nic_inlb(LAN91_TCR) | LAN91_TCR_TXENA);
00511 nic_bs(2);
00512 nic_outlb(LAN91_ACK, LAN91_INT_TX);
00513
00514 nic_outlb(LAN91_MMUCR, LAN91_MMU_PKT);
00515 }
00516
00517
00518
00519
00520
00521
00522 if (isr & LAN91_INT_RX_OVRN) {
00523 nic_outlb(LAN91_ACK, LAN91_INT_RX_OVRN);
00524 NutEventPostFromIrq(&ni->ni_rx_rdy);
00525 }
00526 if (isr & LAN91_INT_ERCV) {
00527 nic_outlb(LAN91_ACK, LAN91_INT_ERCV);
00528 NutEventPostFromIrq(&ni->ni_rx_rdy);
00529 }
00530 if (isr & LAN91_INT_RCV) {
00531 nic_outlb(LAN91_ACK, LAN91_INT_RCV);
00532 imr &= ~LAN91_INT_RCV;
00533 NutEventPostFromIrq(&ni->ni_rx_rdy);
00534 }
00535
00536 if (isr & LAN91_INT_ALLOC) {
00537 imr &= ~LAN91_INT_ALLOC;
00538 NutEventPostFromIrq(&maq);
00539 }
00540 nic_outlb(LAN91_MSK, imr);
00541 }
00542 #endif
00543
00544
00545
00546
00547 static void NicWrite(uint8_t * buf, uint16_t len)
00548 {
00549 register uint16_t l = len - 1;
00550 register uint8_t ih = (uint16_t) l >> 8;
00551 register uint8_t il = (uint8_t) l;
00552
00553 if (!len)
00554 return;
00555
00556 do {
00557 do {
00558 nic_outlb(LAN91_DATA, *buf++);
00559 } while (il-- != 0);
00560 } while (ih-- != 0);
00561 }
00562
00563
00564
00565
00566 static void NicRead(uint8_t * buf, uint16_t len)
00567 {
00568 register uint16_t l = len - 1;
00569 register uint8_t ih = (uint16_t) l >> 8;
00570 register uint8_t il = (uint8_t) l;
00571
00572 if (!len)
00573 return;
00574
00575 do {
00576 do {
00577 *buf++ = nic_inlb(LAN91_DATA);
00578 } while (il-- != 0);
00579 } while (ih-- != 0);
00580 }
00581
00592 static NETBUF *NicGetPacket(void)
00593 {
00594 NETBUF *nb = 0;
00595 uint16_t fsw;
00596 uint16_t fbc;
00597
00598
00599
00600 nic_bs(2);
00601 if (nic_inw(LAN91_FIFO) & 0x8000) {
00602 return 0;
00603 }
00604
00605
00606 nic_outw(LAN91_PTR, LAN91_PTR_READ | LAN91_PTR_RCV | LAN91_PTR_AUTO_INCR);
00607 _NOP();
00608 _NOP();
00609 _NOP();
00610 _NOP();
00611
00612
00613 fsw = nic_inw(LAN91_DATA);
00614 fbc = nic_inw(LAN91_DATA);
00615
00616
00617 if (fsw & 0xAC00) {
00618 nb = (NETBUF *) 0xFFFF;
00619 }
00620
00621 else if (fbc < 66 || fbc > 1524) {
00622 nb = (NETBUF *) 0xFFFF;
00623 }
00624
00625 else {
00626
00627
00628
00629
00630 fbc -= 3;
00631 nb = NutNetBufAlloc(0, NBAF_DATALINK, fbc);
00632
00633
00634 if (nb)
00635 NicRead(nb->nb_dl.vp, fbc);
00636 }
00637
00638
00639 nic_outlb(LAN91_MMUCR, LAN91_MMU_TOP);
00640
00641 return nb;
00642 }
00643
00658 static int NicPutPacket(NETBUF * nb)
00659 {
00660 uint16_t sz;
00661 uint_fast8_t odd = 0;
00662 uint8_t imsk;
00663
00664
00665
00666
00667
00668
00669
00670 if ((sz = nb->nb_nw.sz + nb->nb_tp.sz + nb->nb_ap.sz) > ETHERMTU)
00671 return -1;
00672
00673
00674 imsk = nic_inlb(LAN91_MSK);
00675 nic_outlb(LAN91_MSK, 0);
00676
00677
00678 nic_bs(2);
00679 nic_outlb(LAN91_MMUCR, LAN91_MMU_ALO);
00680 if (NicMmuWait(100))
00681 return -1;
00682
00683
00684 nic_outlb(LAN91_MSK, imsk | LAN91_INT_ALLOC);
00685
00686
00687 sz += nb->nb_dl.sz;
00688 sz += 6;
00689 if (sz & 1) {
00690 sz++;
00691 odd++;
00692 }
00693
00694
00695 while ((nic_inlb(LAN91_IST) & LAN91_INT_ALLOC) == 0) {
00696 if (NutEventWait(&maq, 125)) {
00697 nic_outlb(LAN91_MMUCR, LAN91_MMU_RST);
00698 NicMmuWait(1000);
00699 nic_outlb(LAN91_MMUCR, LAN91_MMU_ALO);
00700 if (NicMmuWait(100) || (nic_inlb(LAN91_IST) & LAN91_INT_ALLOC) == 0) {
00701 if (NutEventWait(&maq, 125)) {
00702 return -1;
00703 }
00704 }
00705 }
00706 }
00707
00708
00709 imsk = nic_inlb(LAN91_MSK);
00710 nic_outlb(LAN91_MSK, 0);
00711
00712
00713 nic_outlb(LAN91_PNR, nic_inhb(LAN91_PNR));
00714
00715 nic_outw(LAN91_PTR, 0x4000);
00716
00717
00718 nic_outlb(LAN91_DATA, 0);
00719 nic_outlb(LAN91_DATA, 0);
00720
00721
00722 nic_outw(LAN91_DATA, sz);
00723
00724
00725 NicWrite(nb->nb_dl.vp, nb->nb_dl.sz);
00726 NicWrite(nb->nb_nw.vp, nb->nb_nw.sz);
00727 NicWrite(nb->nb_tp.vp, nb->nb_tp.sz);
00728 NicWrite(nb->nb_ap.vp, nb->nb_ap.sz);
00729
00730 if (odd)
00731 nic_outlb(LAN91_DATA, 0);
00732
00733
00734 nic_outw(LAN91_DATA, 0);
00735
00736
00737 if (NicMmuWait(100))
00738 return -1;
00739 nic_outlb(LAN91_MMUCR, LAN91_MMU_ENQ);
00740
00741
00742 imsk |= LAN91_INT_TX | LAN91_INT_TX_EMPTY;
00743 nic_outlb(LAN91_MSK, imsk);
00744
00745 return 0;
00746 }
00747
00748
00753 THREAD(NicRxLanc, arg)
00754 {
00755 NUTDEVICE *dev;
00756 IFNET *ifn;
00757 NICINFO *ni;
00758 NETBUF *nb;
00759 uint8_t imsk;
00760
00761 dev = arg;
00762 ifn = (IFNET *) dev->dev_icb;
00763 ni = (NICINFO *) dev->dev_dcb;
00764
00765
00766
00767
00768
00769
00770 while (!ETHER_IS_UNICAST(ifn->if_mac)) {
00771 NutSleep(10);
00772 }
00773
00774
00775
00776
00777
00778
00779
00780 while(NicStart(ifn->if_mac)) {
00781 NutSleep(1000);
00782 }
00783
00784 #ifdef LAN91_SIGNAL
00785 NutIrqSetMode(&LAN91_SIGNAL, NUT_IRQMODE_RISINGEDGE);
00786 NutIrqEnable(&LAN91_SIGNAL);
00787 #endif
00788
00789 NutEventPost(&mutex);
00790
00791
00792 NutThreadSetPriority(9);
00793
00794 for (;;) {
00795
00796
00797
00798
00799 NutEventWait(&ni->ni_rx_rdy, LAN91_RX_POLLTIME);
00800
00801
00802
00803
00804
00805 imsk = nic_inlb(LAN91_MSK);
00806 nic_outlb(LAN91_MSK, 0);
00807 while ((nb = NicGetPacket()) != 0) {
00808 if (nb != (NETBUF *) 0xFFFF) {
00809 #ifdef NUT_PERFMON
00810 ni->ni_rx_packets++;
00811 #endif
00812 (*ifn->if_recv) (dev, nb);
00813 }
00814 }
00815 nic_outlb(LAN91_MSK, imsk | LAN91_INT_RCV | LAN91_INT_ERCV);
00816 }
00817 }
00818
00829 static int Lan91Output(NUTDEVICE * dev, NETBUF * nb)
00830 {
00831 static uint_fast16_t mx_wait = LAN91_TX_POLLTIME;
00832 int rc = -1;
00833 NICINFO *ni;
00834
00835
00836
00837
00838
00839 if (NutEventWait(&mutex, mx_wait) == 0) {
00840 ni = (NICINFO *) dev->dev_dcb;
00841
00842 if (NicPutPacket(nb) == 0) {
00843 #ifdef NUT_PERFMON
00844 ni->ni_tx_packets++;
00845 #endif
00846 rc = 0;
00847
00848
00849 mx_wait = LAN91_TX_POLLTIME;
00850 }
00851 NutEventPost(&mutex);
00852 }
00853 #if defined(LAN91_SIGNAL)
00854
00855
00856
00857
00858 else {
00859 mx_wait = 500;
00860 }
00861 #endif
00862 return rc;
00863 }
00864
00882 static int Lan91Init(NUTDEVICE * dev)
00883 {
00884
00885 #ifdef LAN91_SIGNAL
00886 NutIrqDisable(&LAN91_SIGNAL);
00887 #endif
00888 memset(dev->dev_dcb, 0, sizeof(NICINFO));
00889
00890 #ifdef LAN91_SIGNAL
00891
00892 if (NutRegisterIrqHandler(&LAN91_SIGNAL, NicInterrupt, dev))
00893 return -1;
00894 #endif
00895
00896
00897
00898
00899 NutThreadCreate("lan91rx", NicRxLanc, dev, 640);
00900
00901 return 0;
00902 }
00903
00904 static int Lan91IOCtl(NUTDEVICE * dev, int req, void *conf)
00905 {
00906 int rc = 0;
00907 uint32_t *lvp = (uint32_t *) conf;
00908 IFNET *nif = (IFNET *) dev->dev_icb;
00909
00910 switch (req) {
00911 case SIOCSIFFLAGS:
00912
00913 if (*lvp & IFF_UP) {
00914 if ((nif->if_flags & IFF_UP) == 0) {
00915
00916 }
00917 } else if (nif->if_flags & IFF_UP) {
00918
00919 }
00920 break;
00921 case SIOCGIFFLAGS:
00922
00923 *lvp = nif->if_flags;
00924 break;
00925 case SIOCSIFADDR:
00926
00927 memcpy(nif->if_mac, conf, sizeof(nif->if_mac));
00928 break;
00929 case SIOCGIFADDR:
00930
00931 memcpy(conf, nif->if_mac, sizeof(nif->if_mac));
00932 break;
00933 default:
00934 rc = -1;
00935 break;
00936 }
00937 return rc;
00938 }
00939
00940 static NICINFO dcb_eth0;
00941
00947 static IFNET ifn_eth0 = {
00948 IFT_ETHER,
00949 0,
00950 {0, 0, 0, 0, 0, 0},
00951 0,
00952 0,
00953 0,
00954 ETHERMTU,
00955 0,
00956 0,
00957 0,
00958 NutEtherInput,
00959 Lan91Output,
00960 NutEtherOutput,
00961 NULL
00962 };
00963
00973 NUTDEVICE devLan91 = {
00974 0,
00975 {'e', 't', 'h', '0', 0, 0, 0, 0, 0},
00976 IFTYP_NET,
00977 0,
00978 0,
00979 &ifn_eth0,
00980 &dcb_eth0,
00981 Lan91Init,
00982 Lan91IOCtl,
00983 0,
00984 0,
00985 #ifdef __HARVARD_ARCH__
00986 0,
00987 #endif
00988 0,
00989 0,
00990 0
00991 };
00992