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
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 #include <cfg/os.h>
00098 #include <cfg/dev.h>
00099 #include <arch/arm.h>
00100 #include <cfg/arch/gpio.h>
00101
00102 #include <string.h>
00103
00104 #include <sys/atom.h>
00105 #include <sys/heap.h>
00106 #include <sys/thread.h>
00107 #include <sys/event.h>
00108 #include <sys/timer.h>
00109 #include <sys/confnet.h>
00110
00111 #include <netinet/if_ether.h>
00112 #include <net/ether.h>
00113 #include <net/if_var.h>
00114
00115 #include <dev/irqreg.h>
00116 #include <dev/at91_emac.h>
00117
00118 #ifdef NUTDEBUG
00119 #include <stdio.h>
00120 #endif
00121
00122 #ifndef NUT_THREAD_NICRXSTACK
00123
00124 #define NUT_THREAD_NICRXSTACK 320
00125 #endif
00126
00127 #ifndef EMAC_RX_BUFFERS
00128 #define EMAC_RX_BUFFERS 32
00129 #endif
00130 #define EMAC_RX_BUFSIZ 128
00131
00132 #define EMAC_TX_BUFFERS 2
00133 #ifndef EMAC_TX_BUFSIZ
00134 #define EMAC_TX_BUFSIZ 1536
00135 #endif
00136
00137 #ifndef EMAC_LINK_LOOPS
00138 #define EMAC_LINK_LOOPS 1000000
00139 #endif
00140
00145 #define NIC_PHY_BMCR 0x00
00146 #define NIC_PHY_BMCR_COLTEST 0x0080
00147 #define NIC_PHY_BMCR_FDUPLEX 0x0100
00148 #define NIC_PHY_BMCR_ANEGSTART 0x0200
00149 #define NIC_PHY_BMCR_ISOLATE 0x0400
00150 #define NIC_PHY_BMCR_PWRDN 0x0800
00151 #define NIC_PHY_BMCR_ANEGENA 0x1000
00152 #define NIC_PHY_BMCR_100MBPS 0x2000
00153 #define NIC_PHY_BMCR_LOOPBACK 0x4000
00154 #define NIC_PHY_BMCR_RESET 0x8000
00156 #define NIC_PHY_BMSR 0x01
00157 #define NIC_PHY_BMSR_ANCOMPL 0x0020
00158 #define NIC_PHY_BMSR_LINKSTAT 0x0004
00160 #define NIC_PHY_ID1 0x02
00161 #define NIC_PHY_ID2 0x03
00162 #define NIC_PHY_ANAR 0x04
00163 #define NIC_PHY_ANLPAR 0x05
00164 #define NIC_PHY_ANEG_NP 0x8000
00165 #define NIC_PHY_ANEG_ACK 0x4000
00166 #define NIC_PHY_ANEG_RF 0x2000
00167 #define NIC_PHY_ANEG_FCS 0x0400
00168 #define NIC_PHY_ANEG_T4 0x0200
00169 #define NIC_PHY_ANEG_TX_FDX 0x0100
00170 #define NIC_PHY_ANEG_TX_HDX 0x0080
00171 #define NIC_PHY_ANEG_10_FDX 0x0040
00172 #define NIC_PHY_ANEG_10_HDX 0x0020
00173 #define NIC_PHY_ANEG_BINSEL 0x001F
00175 #define NIC_PHY_ANER 0x06
00178
00179
00185 #ifndef NIC_PHY_ADDR
00186 #define NIC_PHY_ADDR 0
00187 #endif
00188
00189
00190 #if defined (MCU_AT91SAM9260) || defined(MCU_AT91SAM9XE512)
00191
00197 #define PHY_MODE_RMII
00198
00199
00200
00201
00202 #define EMAC_PIO_PUER PIOA_PUER
00203 #define EMAC_PIO_PUDR PIOA_PUDR
00204 #define EMAC_PIO_ASR PIOA_ASR
00205 #define EMAC_PIO_BSR PIOA_BSR
00206 #define EMAC_PIO_PDR PIOA_PDR
00207
00208 #define PHY_TXD0_BIT PA12_ETX0_A
00209 #define PHY_TXD1_BIT PA13_ETX1_A
00210 #define PHY_RXD0_AD0_BIT PA14_ERX0_A
00211 #define PHY_RXD1_AD1_BIT PA15_ERX1_A
00212 #define PHY_TXEN_BIT PA16_ETXEN_A
00213 #define PHY_RXDV_TESTMODE_BIT PA17_ERXDV_A
00214 #define PHY_RXER_RXD4_RPTR_BIT PA18_ERXER_A
00215 #define PHY_TXCLK_ISOLATE_BIT PA19_ETXCK_A
00216 #define PHY_MDC_BIT PA20_EMDC_A
00217 #define PHY_MDIO_BIT PA21_EMDIO_A
00219 #ifndef PHY_MODE_RMII
00220 #define PHY_TXD2_BIT PA10_ETX2_B
00221 #define PHY_TXD3_BIT PA11_ETX3_B
00222 #define PHY_TXER_TXD4_BIT PA22_ETXER_B
00223 #define PHY_RXCLK_10BTSER_BIT PA27_ERXCK_B
00224 #define PHY_COL_RMII_BIT PA29_ECOL_B
00225 #endif
00226
00227 #define PHY_RXD2_AD2_BIT PA25_ERX2_B
00228 #define PHY_RXD3_AD3_BIT PA26_ERX3_B
00229 #define PHY_CRS_AD4_BIT PA28_ECRS_B
00231 #define PHY_MII_PINS_A 0 \
00232 | _BV(PHY_TXD0_BIT) \
00233 | _BV(PHY_TXD1_BIT) \
00234 | _BV(PHY_RXD0_AD0_BIT) \
00235 | _BV(PHY_RXD1_AD1_BIT) \
00236 | _BV(PHY_TXEN_BIT) \
00237 | _BV(PHY_RXDV_TESTMODE_BIT) \
00238 | _BV(PHY_RXER_RXD4_RPTR_BIT) \
00239 | _BV(PHY_TXCLK_ISOLATE_BIT) \
00240 | _BV(PHY_MDC_BIT) \
00241 | _BV(PHY_MDIO_BIT)
00242
00243 #ifdef PHY_MODE_RMII
00244 #define PHY_MII_PINS_B 0
00245 #else
00246 #define PHY_MII_PINS_B 0 \
00247 | _BV(PHY_TXD2_BIT) \
00248 | _BV(PHY_TXD3_BIT) \
00249 | _BV(PHY_TXER_TXD4_BIT) \
00250 | _BV(PHY_RXD2_AD2_BIT) \
00251 | _BV(PHY_RXD3_AD3_BIT) \
00252 | _BV(PHY_RXCLK_10BTSER_BIT) \
00253 | _BV(PHY_CRS_AD4_BIT) \
00254 | _BV(PHY_COL_RMII_BIT)
00255 #endif
00256
00257 #elif defined (MCU_AT91SAM7X256)
00258
00259 #define EMAC_PIO_PER PIOB_PER
00260 #define EMAC_PIO_OER PIOB_OER
00261 #define EMAC_PIO_CODR PIOB_CODR
00262 #define EMAC_PIO_SODR PIOB_SODR
00263 #define EMAC_PIO_PUER PIOB_PUER
00264 #define EMAC_PIO_PUDR PIOB_PUDR
00265 #define EMAC_PIO_ASR PIOB_ASR
00266 #define EMAC_PIO_BSR PIOB_BSR
00267 #define EMAC_PIO_PDR PIOB_PDR
00268
00269 #define PHY_TXCLK_ISOLATE_BIT 0
00270 #define PHY_REFCLK_XT2_BIT 0
00271 #define PHY_TXEN_BIT 1
00272 #define PHY_TXD0_BIT 2
00273 #define PHY_TXD1_BIT 3
00274 #define PHY_CRS_AD4_BIT 4
00275 #define PHY_RXD0_AD0_BIT 5
00276 #define PHY_RXD1_AD1_BIT 6
00277 #define PHY_RXER_RXD4_RPTR_BIT 7
00278 #define PHY_MDC_BIT 8
00279 #define PHY_MDIO_BIT 9
00280 #define PHY_TXD2_BIT 10
00281 #define PHY_TXD3_BIT 11
00282 #define PHY_TXER_TXD4_BIT 12
00283 #define PHY_RXD2_AD2_BIT 13
00284 #define PHY_RXD3_AD3_BIT 14
00285 #define PHY_RXDV_TESTMODE_BIT 15
00286 #define PHY_COL_RMII_BIT 16
00287 #define PHY_RXCLK_10BTSER_BIT 17
00288 #ifndef PHY_PWRDN_BIT
00289 #define PHY_PWRDN_BIT 18
00290 #endif
00291 #define PHY_MDINTR_BIT 26
00292
00293 #define PHY_MII_PINS_A 0 \
00294 | _BV(PHY_REFCLK_XT2_BIT) \
00295 | _BV(PHY_TXEN_BIT) \
00296 | _BV(PHY_TXD0_BIT) \
00297 | _BV(PHY_TXD1_BIT) \
00298 | _BV(PHY_CRS_AD4_BIT) \
00299 | _BV(PHY_RXD0_AD0_BIT) \
00300 | _BV(PHY_RXD1_AD1_BIT) \
00301 | _BV(PHY_RXER_RXD4_RPTR_BIT) \
00302 | _BV(PHY_MDC_BIT) \
00303 | _BV(PHY_MDIO_BIT) \
00304 | _BV(PHY_TXD2_BIT) \
00305 | _BV(PHY_TXD3_BIT) \
00306 | _BV(PHY_TXER_TXD4_BIT) \
00307 | _BV(PHY_RXD2_AD2_BIT) \
00308 | _BV(PHY_RXD3_AD3_BIT) \
00309 | _BV(PHY_RXDV_TESTMODE_BIT) \
00310 | _BV(PHY_COL_RMII_BIT) \
00311 | _BV(PHY_RXCLK_10BTSER_BIT)
00312
00313 #define PHY_MII_PINS_B 0
00314
00315 #endif
00316
00320 struct _EMACINFO {
00321 #ifdef NUT_PERFMON
00322 uint32_t ni_rx_packets;
00323 uint32_t ni_tx_packets;
00324 uint32_t ni_overruns;
00325 uint32_t ni_rx_frame_errors;
00326 uint32_t ni_rx_crc_errors;
00327 uint32_t ni_rx_missed_errors;
00328 #endif
00329 HANDLE volatile ni_rx_rdy;
00330 HANDLE volatile ni_tx_rdy;
00331 HANDLE ni_mutex;
00332 volatile int ni_tx_queued;
00333 volatile int ni_tx_quelen;
00334 volatile int ni_insane;
00335 int ni_iomode;
00336 };
00337
00341 typedef struct _EMACINFO EMACINFO;
00342
00343
00344
00345
00346
00347
00348 typedef struct _BufDescriptor {
00349 unsigned int addr;
00350 unsigned int stat;
00351 } BufDescriptor;
00352
00353 static volatile BufDescriptor txBufTab[EMAC_TX_BUFFERS];
00354 static volatile uint8_t txBuf[EMAC_TX_BUFFERS * EMAC_TX_BUFSIZ] __attribute__ ((aligned(8)));
00355 static unsigned int txBufIdx;
00356
00357 static volatile BufDescriptor rxBufTab[EMAC_RX_BUFFERS];
00358 static volatile uint8_t rxBuf[EMAC_RX_BUFFERS * EMAC_RX_BUFSIZ] __attribute__ ((aligned(8)));
00359 static unsigned int rxBufIdx;
00360
00361 #define RXBUF_OWNERSHIP 0x00000001
00362 #define RXBUF_WRAP 0x00000002
00363 #define RXBUF_ADDRMASK 0xFFFFFFFC
00364
00365 #define RXS_BROADCAST_ADDR 0x80000000
00366 #define RXS_MULTICAST_HASH 0x40000000
00367 #define RXS_UNICAST_HASH 0x20000000
00368 #define RXS_EXTERNAL_ADDR 0x10000000
00369 #define RXS_SA1_ADDR 0x04000000
00370 #define RXS_SA2_ADDR 0x02000000
00371 #define RXS_SA3_ADDR 0x01000000
00372 #define RXS_SA4_ADDR 0x00800000
00373 #define RXS_TYPE_ID 0x00400000
00374 #define RXS_VLAN_TAG 0x00200000
00375 #define RXS_PRIORITY_TAG 0x00100000
00376 #define RXS_VLAN_PRIORITY 0x000E0000
00377 #define RXS_CFI_IND 0x00010000
00378 #define RXS_EOF 0x00008000
00379 #define RXS_SOF 0x00004000
00380 #define RXS_RBF_OFFSET 0x00003000
00381 #define RXS_LENGTH_FRAME 0x000007FF
00383 #define TXS_USED 0x80000000
00384 #define TXS_WRAP 0x40000000
00385 #define TXS_ERROR 0x20000000
00386 #define TXS_UNDERRUN 0x10000000
00387 #define TXS_NO_BUFFER 0x08000000
00388 #define TXS_NO_CRC 0x00010000
00389 #define TXS_LAST_BUFF 0x00008000
00396
00397
00404 static uint16_t phy_inw(uint8_t reg)
00405 {
00406
00407 outr(EMAC_MAN, EMAC_SOF | EMAC_RW_READ | EMAC_CODE |
00408 (NIC_PHY_ADDR << EMAC_PHYA_LSB) | (reg << EMAC_REGA_LSB));
00409
00410
00411 while ((inr(EMAC_NSR) & EMAC_IDLE) == 0);
00412
00413
00414 return (uint16_t) (inr(EMAC_MAN) >> EMAC_DATA_LSB);
00415 }
00416
00417 #ifndef PHY_MODE_RMII
00418
00424 static void phy_outw(uint8_t reg, uint16_t val)
00425 {
00426
00427 outr(EMAC_MAN, EMAC_SOF | EMAC_RW_WRITE | EMAC_CODE |
00428 (NIC_PHY_ADDR << EMAC_PHYA_LSB) | (reg << EMAC_REGA_LSB) | val);
00429
00430
00431 while ((inr(EMAC_NSR) & EMAC_IDLE) == 0);
00432 }
00433 #endif
00434
00440 static int EmacReset(uint32_t tmo)
00441 {
00442 uint16_t phyval;
00443
00444 outr(PMC_PCER, _BV(PIOA_ID));
00445 outr(PMC_PCER, _BV(PIOB_ID));
00446 outr(PMC_PCER, _BV(EMAC_ID));
00447
00448 #if defined (MCU_AT91SAM9260) || defined(MCU_AT91SAM7X256)
00449
00450 outr(EMAC_PIO_PUDR,
00451 #if !defined(PHY_MODE_RMII)
00452
00453 _BV(PHY_COL_RMII_BIT) |
00454 #endif
00455 _BV(PHY_RXDV_TESTMODE_BIT) |
00456 _BV(PHY_RXD0_AD0_BIT) | _BV(PHY_RXD1_AD1_BIT) |
00457 _BV(PHY_RXD2_AD2_BIT) | _BV(PHY_RXD3_AD3_BIT) | _BV(PHY_CRS_AD4_BIT));
00458
00459 #ifdef PHY_PWRDN_BIT
00460
00461 outr(EMAC_PIO_PER, _BV(PHY_PWRDN_BIT));
00462 outr(EMAC_PIO_OER, _BV(PHY_PWRDN_BIT));
00463 #ifdef PHY_PWRDN_NEGPOL
00464 outr(EMAC_PIO_SODR, _BV(PHY_PWRDN_BIT));
00465 #else
00466 outr(EMAC_PIO_CODR, _BV(PHY_PWRDN_BIT));
00467 #endif
00468 #endif
00469
00470
00471 outr(RSTC_MR, RSTC_KEY | (2 << RSTC_ERSTL_LSB) | RSTC_URSTEN);
00472 outr(RSTC_CR, RSTC_KEY | RSTC_EXTRST);
00473 while ((inr(RSTC_SR) & RSTC_NRSTL) == 0);
00474
00475
00476 outr(EMAC_PIO_PUER, _BV(PHY_RXDV_TESTMODE_BIT) |
00477 _BV(PHY_RXD0_AD0_BIT) | _BV(PHY_RXD1_AD1_BIT) |
00478 _BV(PHY_RXD2_AD2_BIT) | _BV(PHY_RXD3_AD3_BIT) | _BV(PHY_CRS_AD4_BIT));
00479 #endif
00480
00481
00482 outr(EMAC_PIO_ASR, PHY_MII_PINS_A);
00483 outr(EMAC_PIO_BSR, PHY_MII_PINS_B);
00484 outr(EMAC_PIO_PDR, PHY_MII_PINS_A | PHY_MII_PINS_B);
00485
00486
00487 #ifdef PHY_MODE_RMII
00488 outr(EMAC_USRIO, EMAC_RMII | EMAC_CLKEN);
00489 #else
00490 outr(EMAC_USRIO, EMAC_CLKEN);
00491 #endif
00492
00493
00494 outr(EMAC_NCR, inr(EMAC_NCR) | EMAC_MPE);
00495 outr(EMAC_NCFGR, inr(EMAC_NCFGR) | EMAC_CLK_HCLK_64);
00496
00497
00498 NutDelay(255);
00499
00500 #ifndef PHY_MODE_RMII
00501
00502 phy_inw(NIC_PHY_BMCR);
00503 phy_outw(NIC_PHY_BMCR, phy_inw(NIC_PHY_BMCR) & ~NIC_PHY_BMCR_ISOLATE);
00504 #endif
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514 #define MII_DM9161_ID_H 0x0181
00515 #define MII_DM9161_ID_L 0xb8a0
00516
00517 #define MII_AM79C875_ID_H 0x0022
00518 #define MII_AM79C875_ID_L 0x5540
00519
00520 #define MII_MICREL_ID_H 0x0022
00521 #define MII_MICREL_ID_L 0x1610
00522
00523 #define MII_LAN8700_ID_H 0x0007
00524 #define MII_LAN8700_ID_L 0xc0c0
00525
00526
00527
00528
00529
00530 if (phy_inw(NIC_PHY_ID1) != MII_DM9161_ID_H ||
00531 (phy_inw(NIC_PHY_ID2) & 0xFFF0) != MII_DM9161_ID_L) {
00532
00533 if (phy_inw(NIC_PHY_ID1) != MII_MICREL_ID_H ||
00534 (phy_inw(NIC_PHY_ID2) & 0xFFF0) != MII_MICREL_ID_L) {
00535 if (phy_inw(NIC_PHY_ID1) != MII_LAN8700_ID_H ||
00536 (phy_inw(NIC_PHY_ID2) & 0xFFF0) != MII_LAN8700_ID_L) {
00537 outr(EMAC_NCR, inr(EMAC_NCR) & ~EMAC_MPE);
00538 return -1;
00539 }
00540 }
00541 }
00542
00543
00544
00545
00546
00547 phyval = phy_inw(NIC_PHY_BMCR);
00548 if (phyval & NIC_PHY_BMCR_ANEGENA) {
00549
00550 phy_inw(NIC_PHY_BMSR);
00551 while (--tmo) {
00552 if (phy_inw(NIC_PHY_BMSR) & NIC_PHY_BMSR_ANCOMPL) {
00553 break;
00554 }
00555 }
00556
00557 if (tmo == 0) {
00558 outr(EMAC_NCR, inr(EMAC_NCR) & ~EMAC_MPE);
00559 return -1;
00560 }
00561
00562
00563
00564
00565 phyval = phy_inw(NIC_PHY_ANLPAR);
00566 if (phyval & NIC_PHY_ANEG_TX_FDX) {
00567
00568 outr(EMAC_NCFGR, inr(EMAC_NCFGR) | EMAC_SPD | EMAC_FD);
00569 }
00570 else if (phyval & NIC_PHY_ANEG_TX_HDX) {
00571
00572 outr(EMAC_NCFGR, (inr(EMAC_NCFGR) & ~EMAC_FD) | EMAC_SPD);
00573 }
00574 else if (phyval & NIC_PHY_ANEG_10_FDX) {
00575
00576 outr(EMAC_NCFGR, (inr(EMAC_NCFGR) & ~EMAC_SPD) | EMAC_FD);
00577 }
00578 else {
00579
00580 outr(EMAC_NCFGR, inr(EMAC_NCFGR) & ~(EMAC_SPD | EMAC_FD));
00581 }
00582 }
00583
00584
00585 outr(EMAC_NCR, inr(EMAC_NCR) & ~EMAC_MPE);
00586
00587 return 0;
00588 }
00589
00590
00591
00592
00593 static void EmacInterrupt(void *arg)
00594 {
00595 unsigned int isr;
00596 EMACINFO *ni = (EMACINFO *) ((NUTDEVICE *) arg)->dev_dcb;
00597
00598
00599 isr = inr(EMAC_ISR);
00600
00601
00602
00603 if ((isr & (EMAC_RCOMP | EMAC_ROVR | EMAC_RXUBR)) != 0) {
00604
00605 outr(EMAC_IDR, EMAC_RCOMP | EMAC_ROVR | EMAC_RXUBR);
00606 NutEventPostFromIrq(&ni->ni_rx_rdy);
00607 }
00608
00609
00610 if ((isr & EMAC_TCOMP) != 0 || (inr(EMAC_TSR) & EMAC_COMP) != 0) {
00611
00612 NutEventPostFromIrq(&ni->ni_tx_rdy);
00613 }
00614 }
00615
00621 static int EmacGetPacket(EMACINFO * ni, NETBUF ** nbp)
00622 {
00623 int rc = -1;
00624 unsigned int fbc = 0;
00625 unsigned int i;
00626 *nbp = NULL;
00627
00628
00629
00630
00631 while ((rxBufTab[rxBufIdx].addr & RXBUF_OWNERSHIP) != 0 && (rxBufTab[rxBufIdx].stat & RXS_SOF) == 0) {
00632 rxBufTab[rxBufIdx].addr &= ~(RXBUF_OWNERSHIP);
00633 rxBufIdx++;
00634 if (rxBufIdx >= EMAC_RX_BUFFERS) {
00635 rxBufIdx = 0;
00636 }
00637 }
00638
00639
00640
00641
00642 i = rxBufIdx;
00643 while (rxBufTab[i].addr & RXBUF_OWNERSHIP) {
00644 if (i != rxBufIdx && (rxBufTab[i].stat & RXS_SOF) != 0) {
00645 do {
00646 rxBufTab[rxBufIdx].addr &= ~(RXBUF_OWNERSHIP);
00647 rxBufIdx++;
00648 if (rxBufIdx >= EMAC_RX_BUFFERS) {
00649 rxBufIdx = 0;
00650 }
00651 } while ((rxBufTab[rxBufIdx].addr & RXBUF_OWNERSHIP) != 0 && (rxBufTab[rxBufIdx].stat & RXS_SOF) == 0);
00652 break;
00653 }
00654 if ((fbc = rxBufTab[i].stat & RXS_LENGTH_FRAME) != 0) {
00655 break;
00656 }
00657 i++;
00658 if (i >= EMAC_RX_BUFFERS) {
00659 i = 0;
00660 }
00661 }
00662
00663 if (fbc) {
00664
00665
00666
00667
00668 if (fbc > 1536) {
00669 ni->ni_insane = 1;
00670 } else {
00671 *nbp = NutNetBufAlloc(0, NBAF_DATALINK, (uint16_t)fbc);
00672 if (*nbp != NULL) {
00673 uint8_t *bp = (uint8_t *) (* nbp)->nb_dl.vp;
00674 unsigned int len;
00675
00676 while (fbc) {
00677 if (fbc > EMAC_RX_BUFSIZ) {
00678 len = EMAC_RX_BUFSIZ;
00679 } else {
00680 len = fbc;
00681 }
00682 memcpy(bp, (void *) (rxBufTab[rxBufIdx].addr & RXBUF_ADDRMASK), len);
00683 rxBufTab[rxBufIdx].addr &= ~RXBUF_OWNERSHIP;
00684 rxBufIdx++;
00685 if (rxBufIdx >= EMAC_RX_BUFFERS) {
00686 rxBufIdx = 0;
00687 }
00688 fbc -= len;
00689 bp += len;
00690 }
00691 rc = 0;
00692 }
00693 }
00694 }
00695 return rc;
00696 }
00697
00712 static int EmacPutPacket(int bufnum, EMACINFO * ni, NETBUF * nb)
00713 {
00714 int rc = -1;
00715 unsigned int sz;
00716 uint8_t *buf;
00717
00718
00719
00720
00721
00722
00723
00724 if ((sz = nb->nb_nw.sz + nb->nb_tp.sz + nb->nb_ap.sz) > ETHERMTU) {
00725 return -1;
00726 }
00727 sz += nb->nb_dl.sz;
00728 if (sz & 1) {
00729 sz++;
00730 }
00731
00732
00733 NutIrqDisable(&sig_EMAC);
00734
00735
00736 if (ni->ni_insane == 0) {
00737 buf = (uint8_t *) txBufTab[bufnum].addr;
00738 memcpy(buf, nb->nb_dl.vp, nb->nb_dl.sz);
00739 buf += nb->nb_dl.sz;
00740 memcpy(buf, nb->nb_nw.vp, nb->nb_nw.sz);
00741 buf += nb->nb_nw.sz;
00742 memcpy(buf, nb->nb_tp.vp, nb->nb_tp.sz);
00743 buf += nb->nb_tp.sz;
00744 memcpy(buf, nb->nb_ap.vp, nb->nb_ap.sz);
00745 sz |= TXS_LAST_BUFF;
00746 if (bufnum) {
00747 sz |= TXS_WRAP;
00748 }
00749 txBufTab[bufnum].stat = sz;
00750 outr(EMAC_NCR, inr(EMAC_NCR) | EMAC_TSTART);
00751 rc = 0;
00752 #ifdef NUT_PERFMON
00753 ni->ni_tx_packets++;
00754 #endif
00755 }
00756
00757
00758 NutIrqEnable(&sig_EMAC);
00759
00760 return rc;
00761 }
00762
00763
00771 static int EmacStart(CONST uint8_t * mac)
00772 {
00773 unsigned int i;
00774
00775
00776 outr(EMAC_SA1L, (mac[3] << 24) | (mac[2] << 16) | (mac[1] << 8) | mac[0]);
00777 outr(EMAC_SA1H, (mac[5] << 8) | mac[4]);
00778
00779
00780 for (i = 0; i < EMAC_RX_BUFFERS - 1; i++) {
00781 rxBufTab[i].addr = (unsigned int) (&rxBuf[i * EMAC_RX_BUFSIZ]) & RXBUF_ADDRMASK;
00782 }
00783 rxBufTab[i].addr = ((unsigned int) (&rxBuf[i * EMAC_RX_BUFSIZ]) & RXBUF_ADDRMASK) | RXBUF_WRAP;
00784 outr(EMAC_RBQP, (unsigned int) rxBufTab);
00785
00786
00787 txBufTab[0].addr = (unsigned int) (&txBuf[0]);
00788 txBufTab[0].stat = TXS_USED;
00789 txBufTab[1].addr = (unsigned int) (&txBuf[EMAC_TX_BUFSIZ]);
00790 txBufTab[1].stat = TXS_USED | TXS_WRAP;
00791 outr(EMAC_TBQP, (unsigned int) txBufTab);
00792
00793
00794 outr(EMAC_RSR, EMAC_OVR | EMAC_REC | EMAC_BNA);
00795
00796
00797 outr(EMAC_NCFGR, inr(EMAC_NCFGR) | EMAC_CAF | EMAC_DRFCS);
00798
00799
00800 outr(EMAC_NCR, inr(EMAC_NCR) | EMAC_TE | EMAC_RE | EMAC_WESTAT);
00801
00802 return 0;
00803 }
00804
00809 THREAD(EmacRxThread, arg)
00810 {
00811 NUTDEVICE *dev;
00812 IFNET *ifn;
00813 EMACINFO *ni;
00814 NETBUF *nb;
00815
00816 dev = arg;
00817 ifn = (IFNET *) dev->dev_icb;
00818 ni = (EMACINFO *) dev->dev_dcb;
00819
00820
00821
00822
00823
00824
00825 for (;;) {
00826 int i;
00827
00828 for (i = 0; i < sizeof(ifn->if_mac); i++) {
00829 if (ifn->if_mac[i] && ifn->if_mac[i] != 0xFF) {
00830 break;
00831 }
00832 }
00833 if (i < sizeof(ifn->if_mac)) {
00834 break;
00835 }
00836 NutSleep(63);
00837 }
00838
00839
00840
00841
00842
00843
00844
00845 while (EmacStart(ifn->if_mac)) {
00846 EmacReset(EMAC_LINK_LOOPS);
00847 NutSleep(1000);
00848 }
00849
00850
00851 NutEventPost(&ni->ni_mutex);
00852
00853
00854 NutThreadSetPriority(9);
00855
00856
00857 outr(EMAC_IER, EMAC_ROVR | EMAC_TCOMP | EMAC_TUND | EMAC_RXUBR | EMAC_RCOMP);
00858 NutIrqEnable(&sig_EMAC);
00859
00860 for (;;) {
00861
00862
00863
00864
00865
00866 NutEventWait(&ni->ni_rx_rdy, 200);
00867
00868
00869
00870
00871
00872 while (EmacGetPacket(ni, &nb) == 0) {
00873
00874 if (nb->nb_dl.sz < 60) {
00875 NutNetBufFree(nb);
00876 } else {
00877 (*ifn->if_recv) (dev, nb);
00878 }
00879 }
00880 outr(EMAC_IER, EMAC_ROVR | EMAC_RXUBR | EMAC_RCOMP);
00881
00882
00883 while (ni->ni_insane) {
00884 EmacReset(EMAC_LINK_LOOPS);
00885 if (EmacStart(ifn->if_mac) == 0) {
00886 ni->ni_insane = 0;
00887 ni->ni_tx_queued = 0;
00888 ni->ni_tx_quelen = 0;
00889 NutIrqEnable(&sig_EMAC);
00890 } else {
00891 NutSleep(1000);
00892 }
00893 }
00894 }
00895 }
00896
00907 int EmacOutput(NUTDEVICE * dev, NETBUF * nb)
00908 {
00909 static uint32_t mx_wait = 5000;
00910 int rc = -1;
00911 EMACINFO *ni = (EMACINFO *) dev->dev_dcb;
00912
00913
00914
00915
00916
00917 while (rc) {
00918 if (ni->ni_insane) {
00919 break;
00920 }
00921 if (NutEventWait(&ni->ni_mutex, mx_wait)) {
00922 break;
00923 }
00924
00925
00926 if ((txBufTab[txBufIdx].stat & TXS_USED) == 0) {
00927 if (NutEventWait(&ni->ni_tx_rdy, 500) && (txBufTab[txBufIdx].stat & TXS_USED) == 0) {
00928
00929 txBufTab[txBufIdx].stat |= TXS_USED;
00930 txBufIdx++;
00931 txBufIdx &= 1;
00932 NutEventPost(&ni->ni_mutex);
00933 break;
00934 }
00935 } else {
00936 if (inr(EMAC_TSR) & EMAC_UND) {
00937 txBufIdx = 0;
00938 outr(EMAC_TSR, EMAC_UND);
00939 }
00940 if (inr(EMAC_TSR) & EMAC_COMP) {
00941 outr(EMAC_TSR, EMAC_COMP);
00942 }
00943
00944 if ((rc = EmacPutPacket(txBufIdx, ni, nb)) == 0) {
00945 txBufIdx++;
00946 txBufIdx &= 1;
00947 }
00948 }
00949 NutEventPost(&ni->ni_mutex);
00950 }
00951
00952
00953
00954
00955
00956 if (rc) {
00957 mx_wait = 500;
00958 } else {
00959
00960
00961 mx_wait = 5000;
00962 }
00963 return rc;
00964 }
00965
00975 int EmacInit(NUTDEVICE * dev)
00976 {
00977 EMACINFO *ni = (EMACINFO *) dev->dev_dcb;
00978
00979
00980 if (EmacReset(EMAC_LINK_LOOPS)) {
00981 if (EmacReset(EMAC_LINK_LOOPS)) {
00982 return -1;
00983 }
00984 }
00985
00986
00987 memset(ni, 0, sizeof(EMACINFO));
00988
00989
00990 if (NutRegisterIrqHandler(&sig_EMAC, EmacInterrupt, dev)) {
00991 return -1;
00992 }
00993
00994
00995 if (NutThreadCreate("emacrx", EmacRxThread, dev,
00996 (NUT_THREAD_NICRXSTACK * NUT_THREAD_STACK_MULT) + NUT_THREAD_STACK_ADD) == NULL) {
00997 return -1;
00998 }
00999 return 0;
01000 }
01001
01002 static EMACINFO dcb_eth0;
01003
01009 static IFNET ifn_eth0 = {
01010 IFT_ETHER,
01011 0,
01012 {0, 0, 0, 0, 0, 0},
01013 0,
01014 0,
01015 0,
01016 ETHERMTU,
01017 0,
01018 0,
01019 0,
01020 NutEtherInput,
01021 EmacOutput,
01022 NutEtherOutput
01023 };
01024
01034 NUTDEVICE devAt91Emac = {
01035 0,
01036 {'e', 't', 'h', '0', 0, 0, 0, 0, 0},
01037 IFTYP_NET,
01038 0,
01039 0,
01040 &ifn_eth0,
01041 &dcb_eth0,
01042 EmacInit,
01043 0,
01044 0,
01045 0,
01046 #ifdef __HARVARD_ARCH__
01047 0,
01048 #endif
01049 0,
01050 0,
01051 0
01052 };
01053