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