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_sr;
00297 uint16_t phy_to;
00298 uint16_t mode;
00299
00300
00301
00302
00303
00304
00305 NicPhyWrite(LAN91_PHYCR, LAN91_PHYCR_RST);
00306 for (phy_to = 0;; phy_to++) {
00307 NutSleep(63);
00308 if ((NicPhyRead(LAN91_PHYCR) & LAN91_PHYCR_RST) == 0)
00309 break;
00310 if (phy_to > 3)
00311 return -1;
00312 }
00313
00314
00315 NicPhyWrite(LAN91_PHYMSK, LAN91_PHYMSK_MLOSSSYN | LAN91_PHYMSK_MCWRD | LAN91_PHYMSK_MSSD |
00316 LAN91_PHYMSK_MESD | LAN91_PHYMSK_MRPOL | LAN91_PHYMSK_MJAB | LAN91_PHYMSK_MSPDDT | LAN91_PHYMSK_MDPLDT);
00317
00318
00319 mode = LAN91_RPCR_ANEG | LAN91_RPCR_LEDA_PAT | LAN91_RPCR_LEDB_PAT;
00320 nic_bs(0);
00321 nic_outw(LAN91_RPCR, mode);
00322
00323 #ifdef LAN91_FIXED
00324
00325 phy_sr = NicPhyRead(LAN91_PHYCFR1);
00326 NicPhyWrite(LAN91_PHYCFR1, phy_sr | 0x8000);
00327 NutSleep(63);
00328
00329
00330 NicPhyWrite(LAN91_PHYCR, LAN91_FIXED);
00331 nic_bs(0);
00332 nic_outw(LAN91_RPCR, mode);
00333
00334
00335 phy_sr = NicPhyRead(LAN91_PHYCFR1);
00336 NicPhyWrite(LAN91_PHYCFR1, phy_sr & ~0x8000);
00337 phy_sr = NicPhyRead(LAN91_PHYCFR1);
00338
00339 #else
00340
00341
00342
00343
00344 NicPhyWrite(LAN91_PHYANAD, LAN91_PHYANAD_TX_FDX | LAN91_PHYANAD_TX_HDX | LAN91_PHYANAD_10FDX | LAN91_PHYANAD_10_HDX | LAN91_PHYANAD_CSMA);
00345 NutSleep(63);
00346 for (phy_to = 0, phy_sr = 0;; phy_to++) {
00347
00348 if (phy_to >= 1024)
00349 return -1;
00350
00351 if ((phy_to & 127) == 0 ) {
00352 NicPhyWrite(LAN91_PHYCR, LAN91_PHYCR_ANEG_EN | LAN91_PHYCR_ANEG_RST);
00353 NutSleep(63);
00354 }
00355
00356 phy_sr = NicPhyRead(LAN91_PHYSR);
00357 if (phy_sr & LAN91_PHYSR_ANEG_ACK)
00358 break;
00359 NutSleep(63);
00360 }
00361 #endif
00362
00363 return 0;
00364 }
00365
00376 static INLINE int NicMmuWait(uint_fast16_t tmo)
00377 {
00378 while (tmo--) {
00379 if ((nic_inlb(LAN91_MMUCR) & LAN91_MMUCR_BUSY) == 0)
00380 break;
00381 NutDelay(1);
00382 }
00383 return tmo ? 0 : -1;
00384 }
00385
00391 static int NicReset(void)
00392 {
00393 #ifdef LAN91_RESET_BIT
00394 GpioPinConfigSet(LAN91_RESET_GPIO_BANK, LAN91_RESET_GPIO_BIT, GPIO_CFG_OUTPUT);
00395 GpioPinSet(LAN91_RESET_GPIO_BANK, LAN91_RESET_GPIO_BIT, 1);
00396 NutDelay(10);
00397 GpioPinSet(LAN91_RESET_GPIO_BANK, LAN91_RESET_GPIO_BIT, 0);
00398 NutDelay(100);
00399 #endif
00400
00401
00402 nic_outlb(LAN91_MSK, 0);
00403
00404
00405 nic_bs(0);
00406 nic_outw(LAN91_RCR, LAN91_RCR_SOFT_RST);
00407
00408
00409 nic_bs(1);
00410 nic_outw(LAN91_CR, LAN91_CR_EPH_EN);
00411
00412 NutDelay(10);
00413
00414
00415 nic_bs(0);
00416 nic_outw(LAN91_RCR, 0);
00417 nic_outw(LAN91_TCR, 0);
00418
00419
00420 nic_bs(1);
00421 nic_outw(LAN91_CTR, LAN91_CTR_AUTO_RELEASE);
00422
00423
00424 nic_bs(2);
00425 nic_outlb(LAN91_MMUCR, LAN91_MMU_RST);
00426 if (NicMmuWait(1000))
00427 return -1;
00428
00429 return 0;
00430 }
00431
00432
00433
00434
00435
00436
00437
00438
00439 static int NicStart(CONST uint8_t * mac)
00440 {
00441 uint_fast8_t i;
00442
00443 if (NicReset())
00444 return -1;
00445
00446
00447 nic_bs(3);
00448 nic_outlb(LAN91_ERCV, 7);
00449 nic_bs(0);
00450 nic_outw(LAN91_RCR, LAN91_RCR_RXEN);
00451
00452
00453 nic_outw(LAN91_TCR, LAN91_TCR_PAD_EN | LAN91_TCR_TXENA);
00454
00455
00456 if (NicPhyConfig())
00457 return -1;
00458
00459
00460 nic_bs(1);
00461 for (i = 0; i < 6; i++)
00462 nic_outlb(LAN91_IAR + i, mac[i]);
00463
00464
00465 nic_bs(2);
00466 nic_outlb(LAN91_MSK, LAN91_INT_ERCV | LAN91_INT_RCV | LAN91_INT_RX_OVRN);
00467
00468 return 0;
00469 }
00470
00471 #if defined(LAN91_SIGNAL)
00472
00473
00474
00475 static void NicInterrupt(void *arg)
00476 {
00477 uint8_t isr;
00478 uint8_t imr;
00479 NICINFO *ni = (NICINFO *) ((NUTDEVICE *) arg)->dev_dcb;
00480
00481 #ifdef NUT_PERFMON
00482 ni->ni_interrupts++;
00483 #endif
00484
00485 nic_bs(2);
00486 imr = nic_inlb(LAN91_MSK);
00487 nic_outlb(LAN91_MSK, 0);
00488
00489
00490 isr = nic_inlb(LAN91_IST);
00491 isr &= imr;
00492
00493
00494
00495
00496
00497
00498 if (isr & LAN91_INT_TX_EMPTY) {
00499 nic_outlb(LAN91_ACK, LAN91_INT_TX_EMPTY);
00500 imr &= ~LAN91_INT_TX_EMPTY;
00501 }
00502
00503 else if (isr & LAN91_INT_TX) {
00504
00505 nic_bs(0);
00506 nic_outw(LAN91_TCR, nic_inlb(LAN91_TCR) | LAN91_TCR_TXENA);
00507 nic_bs(2);
00508 nic_outlb(LAN91_ACK, LAN91_INT_TX);
00509
00510 nic_outlb(LAN91_MMUCR, LAN91_MMU_PKT);
00511 }
00512
00513
00514
00515
00516
00517
00518 if (isr & LAN91_INT_RX_OVRN) {
00519 nic_outlb(LAN91_ACK, LAN91_INT_RX_OVRN);
00520 NutEventPostFromIrq(&ni->ni_rx_rdy);
00521 }
00522 if (isr & LAN91_INT_ERCV) {
00523 nic_outlb(LAN91_ACK, LAN91_INT_ERCV);
00524 NutEventPostFromIrq(&ni->ni_rx_rdy);
00525 }
00526 if (isr & LAN91_INT_RCV) {
00527 nic_outlb(LAN91_ACK, LAN91_INT_RCV);
00528 imr &= ~LAN91_INT_RCV;
00529 NutEventPostFromIrq(&ni->ni_rx_rdy);
00530 }
00531
00532 if (isr & LAN91_INT_ALLOC) {
00533 imr &= ~LAN91_INT_ALLOC;
00534 NutEventPostFromIrq(&maq);
00535 }
00536 nic_outlb(LAN91_MSK, imr);
00537 }
00538 #endif
00539
00540
00541
00542
00543 static void NicWrite(uint8_t * buf, uint16_t len)
00544 {
00545 register uint16_t l = len - 1;
00546 register uint8_t ih = (uint16_t) l >> 8;
00547 register uint8_t il = (uint8_t) l;
00548
00549 if (!len)
00550 return;
00551
00552 do {
00553 do {
00554 nic_outlb(LAN91_DATA, *buf++);
00555 } while (il-- != 0);
00556 } while (ih-- != 0);
00557 }
00558
00559
00560
00561
00562 static void NicRead(uint8_t * buf, uint16_t len)
00563 {
00564 register uint16_t l = len - 1;
00565 register uint8_t ih = (uint16_t) l >> 8;
00566 register uint8_t il = (uint8_t) l;
00567
00568 if (!len)
00569 return;
00570
00571 do {
00572 do {
00573 *buf++ = nic_inlb(LAN91_DATA);
00574 } while (il-- != 0);
00575 } while (ih-- != 0);
00576 }
00577
00588 static NETBUF *NicGetPacket(void)
00589 {
00590 NETBUF *nb = 0;
00591 uint16_t fsw;
00592 uint16_t fbc;
00593
00594
00595
00596 nic_bs(2);
00597 if (nic_inw(LAN91_FIFO) & 0x8000) {
00598 return 0;
00599 }
00600
00601
00602 nic_outw(LAN91_PTR, LAN91_PTR_READ | LAN91_PTR_RCV | LAN91_PTR_AUTO_INCR);
00603 _NOP();
00604 _NOP();
00605 _NOP();
00606 _NOP();
00607
00608
00609 fsw = nic_inw(LAN91_DATA);
00610 fbc = nic_inw(LAN91_DATA);
00611
00612
00613 if (fsw & 0xAC00) {
00614 nb = (NETBUF *) 0xFFFF;
00615 }
00616
00617 else if (fbc < 66 || fbc > 1524) {
00618 nb = (NETBUF *) 0xFFFF;
00619 }
00620
00621 else {
00622
00623
00624
00625
00626 fbc -= 3;
00627 nb = NutNetBufAlloc(0, NBAF_DATALINK, fbc);
00628
00629
00630 if (nb)
00631 NicRead(nb->nb_dl.vp, fbc);
00632 }
00633
00634
00635 nic_outlb(LAN91_MMUCR, LAN91_MMU_TOP);
00636
00637 return nb;
00638 }
00639
00654 static int NicPutPacket(NETBUF * nb)
00655 {
00656 uint16_t sz;
00657 uint_fast8_t odd = 0;
00658 uint8_t imsk;
00659
00660
00661
00662
00663
00664
00665
00666 if ((sz = nb->nb_nw.sz + nb->nb_tp.sz + nb->nb_ap.sz) > ETHERMTU)
00667 return -1;
00668
00669
00670 imsk = nic_inlb(LAN91_MSK);
00671 nic_outlb(LAN91_MSK, 0);
00672
00673
00674 nic_bs(2);
00675 nic_outlb(LAN91_MMUCR, LAN91_MMU_ALO);
00676 if (NicMmuWait(100))
00677 return -1;
00678
00679
00680 nic_outlb(LAN91_MSK, imsk | LAN91_INT_ALLOC);
00681
00682
00683 sz += nb->nb_dl.sz;
00684 sz += 6;
00685 if (sz & 1) {
00686 sz++;
00687 odd++;
00688 }
00689
00690
00691 while ((nic_inlb(LAN91_IST) & LAN91_INT_ALLOC) == 0) {
00692 if (NutEventWait(&maq, 125)) {
00693 nic_outlb(LAN91_MMUCR, LAN91_MMU_RST);
00694 NicMmuWait(1000);
00695 nic_outlb(LAN91_MMUCR, LAN91_MMU_ALO);
00696 if (NicMmuWait(100) || (nic_inlb(LAN91_IST) & LAN91_INT_ALLOC) == 0) {
00697 if (NutEventWait(&maq, 125)) {
00698 return -1;
00699 }
00700 }
00701 }
00702 }
00703
00704
00705 imsk = nic_inlb(LAN91_MSK);
00706 nic_outlb(LAN91_MSK, 0);
00707
00708
00709 nic_outlb(LAN91_PNR, nic_inhb(LAN91_PNR));
00710
00711 nic_outw(LAN91_PTR, 0x4000);
00712
00713
00714 nic_outlb(LAN91_DATA, 0);
00715 nic_outlb(LAN91_DATA, 0);
00716
00717
00718 nic_outw(LAN91_DATA, sz);
00719
00720
00721 NicWrite(nb->nb_dl.vp, nb->nb_dl.sz);
00722 NicWrite(nb->nb_nw.vp, nb->nb_nw.sz);
00723 NicWrite(nb->nb_tp.vp, nb->nb_tp.sz);
00724 NicWrite(nb->nb_ap.vp, nb->nb_ap.sz);
00725
00726 if (odd)
00727 nic_outlb(LAN91_DATA, 0);
00728
00729
00730 nic_outw(LAN91_DATA, 0);
00731
00732
00733 if (NicMmuWait(100))
00734 return -1;
00735 nic_outlb(LAN91_MMUCR, LAN91_MMU_ENQ);
00736
00737
00738 imsk |= LAN91_INT_TX | LAN91_INT_TX_EMPTY;
00739 nic_outlb(LAN91_MSK, imsk);
00740
00741 return 0;
00742 }
00743
00744
00749 THREAD(NicRxLanc, arg)
00750 {
00751 NUTDEVICE *dev;
00752 IFNET *ifn;
00753 NICINFO *ni;
00754 NETBUF *nb;
00755 uint8_t imsk;
00756
00757 dev = arg;
00758 ifn = (IFNET *) dev->dev_icb;
00759 ni = (NICINFO *) dev->dev_dcb;
00760
00761
00762
00763
00764
00765
00766 while (!ETHER_IS_UNICAST(ifn->if_mac)) {
00767 NutSleep(10);
00768 }
00769
00770
00771
00772
00773
00774
00775
00776 while(NicStart(ifn->if_mac)) {
00777 NutSleep(1000);
00778 }
00779
00780 #ifdef LAN91_SIGNAL
00781 NutIrqSetMode(&LAN91_SIGNAL, NUT_IRQMODE_RISINGEDGE);
00782 NutIrqEnable(&LAN91_SIGNAL);
00783 #endif
00784
00785 NutEventPost(&mutex);
00786
00787
00788 NutThreadSetPriority(9);
00789
00790 for (;;) {
00791
00792
00793
00794
00795 NutEventWait(&ni->ni_rx_rdy, LAN91_RX_POLLTIME);
00796
00797
00798
00799
00800
00801 imsk = nic_inlb(LAN91_MSK);
00802 nic_outlb(LAN91_MSK, 0);
00803 while ((nb = NicGetPacket()) != 0) {
00804 if (nb != (NETBUF *) 0xFFFF) {
00805 #ifdef NUT_PERFMON
00806 ni->ni_rx_packets++;
00807 #endif
00808 (*ifn->if_recv) (dev, nb);
00809 }
00810 }
00811 nic_outlb(LAN91_MSK, imsk | LAN91_INT_RCV | LAN91_INT_ERCV);
00812 }
00813 }
00814
00825 static int Lan91Output(NUTDEVICE * dev, NETBUF * nb)
00826 {
00827 static uint_fast16_t mx_wait = LAN91_TX_POLLTIME;
00828 int rc = -1;
00829
00830
00831
00832
00833
00834 if (NutEventWait(&mutex, mx_wait) == 0) {
00835
00836 if (NicPutPacket(nb) == 0) {
00837 #ifdef NUT_PERFMON
00838 NICINFO *ni = (NICINFO *) dev->dev_dcb;
00839 ni->ni_tx_packets++;
00840 #endif
00841 rc = 0;
00842
00843
00844 mx_wait = LAN91_TX_POLLTIME;
00845 }
00846 NutEventPost(&mutex);
00847 }
00848 #if defined(LAN91_SIGNAL)
00849
00850
00851
00852
00853 else {
00854 mx_wait = 500;
00855 }
00856 #endif
00857 return rc;
00858 }
00859
00877 static int Lan91Init(NUTDEVICE * dev)
00878 {
00879
00880 #ifdef LAN91_SIGNAL
00881 NutIrqDisable(&LAN91_SIGNAL);
00882 #endif
00883 memset(dev->dev_dcb, 0, sizeof(NICINFO));
00884
00885 #ifdef LAN91_SIGNAL
00886
00887 if (NutRegisterIrqHandler(&LAN91_SIGNAL, NicInterrupt, dev))
00888 return -1;
00889 #endif
00890
00891
00892
00893
00894 NutThreadCreate("lan91rx", NicRxLanc, dev, 640);
00895
00896 return 0;
00897 }
00898
00899 static int Lan91IOCtl(NUTDEVICE * dev, int req, void *conf)
00900 {
00901 int rc = 0;
00902 uint32_t *lvp = (uint32_t *) conf;
00903 IFNET *nif = (IFNET *) dev->dev_icb;
00904
00905 switch (req) {
00906 case SIOCSIFFLAGS:
00907
00908 if (*lvp & IFF_UP) {
00909 if ((nif->if_flags & IFF_UP) == 0) {
00910
00911 }
00912 } else if (nif->if_flags & IFF_UP) {
00913
00914 }
00915 break;
00916 case SIOCGIFFLAGS:
00917
00918 *lvp = nif->if_flags;
00919 break;
00920 case SIOCSIFADDR:
00921
00922 memcpy(nif->if_mac, conf, sizeof(nif->if_mac));
00923 break;
00924 case SIOCGIFADDR:
00925
00926 memcpy(conf, nif->if_mac, sizeof(nif->if_mac));
00927 break;
00928 default:
00929 rc = -1;
00930 break;
00931 }
00932 return rc;
00933 }
00934
00935 static NICINFO dcb_eth0;
00936
00942 static IFNET ifn_eth0 = {
00943 IFT_ETHER,
00944 0,
00945 {0, 0, 0, 0, 0, 0},
00946 0,
00947 0,
00948 0,
00949 ETHERMTU,
00950 0,
00951 0,
00952 0,
00953 NutEtherInput,
00954 Lan91Output,
00955 NutEtherOutput,
00956 NULL
00957 };
00958
00968 NUTDEVICE devLan91 = {
00969 0,
00970 {'e', 't', 'h', '0', 0, 0, 0, 0, 0},
00971 IFTYP_NET,
00972 0,
00973 0,
00974 &ifn_eth0,
00975 &dcb_eth0,
00976 Lan91Init,
00977 Lan91IOCtl,
00978 0,
00979 0,
00980 #ifdef __HARVARD_ARCH__
00981 0,
00982 #endif
00983 0,
00984 0,
00985 0
00986 };
00987