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