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_AT91SAM7X)
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 #if defined (MCU_AT91SAM9260) || defined(MCU_AT91SAM7X)
00444 uint32_t rstcr_tmp;
00445 #endif
00446
00447 outr(PMC_PCER, _BV(PIOA_ID));
00448 outr(PMC_PCER, _BV(PIOB_ID));
00449 outr(PMC_PCER, _BV(EMAC_ID));
00450
00451 #if defined (MCU_AT91SAM9260) || defined(MCU_AT91SAM7X)
00452
00453 outr(EMAC_PIO_PUDR,
00454 #if !defined(PHY_MODE_RMII)
00455
00456 _BV(PHY_COL_RMII_BIT) |
00457 #endif
00458 _BV(PHY_RXDV_TESTMODE_BIT) |
00459 _BV(PHY_RXD0_AD0_BIT) | _BV(PHY_RXD1_AD1_BIT) |
00460 _BV(PHY_RXD2_AD2_BIT) | _BV(PHY_RXD3_AD3_BIT) | _BV(PHY_CRS_AD4_BIT));
00461
00462 #ifdef PHY_PWRDN_BIT
00463
00464 outr(EMAC_PIO_PER, _BV(PHY_PWRDN_BIT));
00465 outr(EMAC_PIO_OER, _BV(PHY_PWRDN_BIT));
00466 #ifdef PHY_PWRDN_NEGPOL
00467 outr(EMAC_PIO_SODR, _BV(PHY_PWRDN_BIT));
00468 #else
00469 outr(EMAC_PIO_CODR, _BV(PHY_PWRDN_BIT));
00470 #endif
00471 #endif
00472
00473
00474 rstcr_tmp = inr(RSTC_MR) & 0x00FFFFFF;
00475 outr(RSTC_MR, RSTC_KEY | (2 << RSTC_ERSTL_LSB));
00476
00477 outr(RSTC_CR, RSTC_KEY | RSTC_EXTRST);
00478 while ((inr(RSTC_SR) & RSTC_NRSTL) == 0);
00479 outr(RSTC_MR, RSTC_KEY | rstcr_tmp);
00480
00481
00482 outr(EMAC_PIO_PUER, _BV(PHY_RXDV_TESTMODE_BIT) |
00483 _BV(PHY_RXD0_AD0_BIT) | _BV(PHY_RXD1_AD1_BIT) |
00484 _BV(PHY_RXD2_AD2_BIT) | _BV(PHY_RXD3_AD3_BIT) | _BV(PHY_CRS_AD4_BIT));
00485 #endif
00486
00487
00488 outr(EMAC_PIO_ASR, PHY_MII_PINS_A);
00489 outr(EMAC_PIO_BSR, PHY_MII_PINS_B);
00490 outr(EMAC_PIO_PDR, PHY_MII_PINS_A | PHY_MII_PINS_B);
00491
00492
00493 #ifdef PHY_MODE_RMII
00494 outr(EMAC_USRIO, EMAC_RMII | EMAC_CLKEN);
00495 #else
00496 outr(EMAC_USRIO, EMAC_CLKEN);
00497 #endif
00498
00499
00500 outr(EMAC_NCR, inr(EMAC_NCR) | EMAC_MPE);
00501 outr(EMAC_NCFGR, inr(EMAC_NCFGR) | EMAC_CLK_HCLK_64);
00502
00503
00504 NutDelay(255);
00505
00506 #ifndef PHY_MODE_RMII
00507
00508 phy_inw(NIC_PHY_BMCR);
00509 phy_outw(NIC_PHY_BMCR, phy_inw(NIC_PHY_BMCR) & ~NIC_PHY_BMCR_ISOLATE);
00510 #endif
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520 #define MII_DM9161_ID_H 0x0181
00521 #define MII_DM9161_ID_L 0xb8a0
00522
00523 #define MII_AM79C875_ID_H 0x0022
00524 #define MII_AM79C875_ID_L 0x5540
00525
00526 #define MII_MICREL_ID_H 0x0022
00527 #define MII_MICREL_ID_L 0x1610
00528
00529 #define MII_LAN8700_ID_H 0x0007
00530 #define MII_LAN8700_ID_L 0xc0c0
00531
00532
00533
00534
00535
00536 if (phy_inw(NIC_PHY_ID1) != MII_DM9161_ID_H ||
00537 (phy_inw(NIC_PHY_ID2) & 0xFFF0) != MII_DM9161_ID_L) {
00538
00539 if (phy_inw(NIC_PHY_ID1) != MII_MICREL_ID_H ||
00540 (phy_inw(NIC_PHY_ID2) & 0xFFF0) != MII_MICREL_ID_L) {
00541 if (phy_inw(NIC_PHY_ID1) != MII_LAN8700_ID_H ||
00542 (phy_inw(NIC_PHY_ID2) & 0xFFF0) != MII_LAN8700_ID_L) {
00543 outr(EMAC_NCR, inr(EMAC_NCR) & ~EMAC_MPE);
00544 return -1;
00545 }
00546 }
00547 }
00548
00549
00550
00551
00552
00553 phyval = phy_inw(NIC_PHY_BMCR);
00554 if (phyval & NIC_PHY_BMCR_ANEGENA) {
00555
00556 phy_inw(NIC_PHY_BMSR);
00557 while (--tmo) {
00558 if (phy_inw(NIC_PHY_BMSR) & NIC_PHY_BMSR_ANCOMPL) {
00559 break;
00560 }
00561 }
00562
00563 if (tmo == 0) {
00564 outr(EMAC_NCR, inr(EMAC_NCR) & ~EMAC_MPE);
00565 return -1;
00566 }
00567
00568
00569
00570
00571 phyval = phy_inw(NIC_PHY_ANLPAR);
00572 if (phyval & NIC_PHY_ANEG_TX_FDX) {
00573
00574 outr(EMAC_NCFGR, inr(EMAC_NCFGR) | EMAC_SPD | EMAC_FD);
00575 }
00576 else if (phyval & NIC_PHY_ANEG_TX_HDX) {
00577
00578 outr(EMAC_NCFGR, (inr(EMAC_NCFGR) & ~EMAC_FD) | EMAC_SPD);
00579 }
00580 else if (phyval & NIC_PHY_ANEG_10_FDX) {
00581
00582 outr(EMAC_NCFGR, (inr(EMAC_NCFGR) & ~EMAC_SPD) | EMAC_FD);
00583 }
00584 else {
00585
00586 outr(EMAC_NCFGR, inr(EMAC_NCFGR) & ~(EMAC_SPD | EMAC_FD));
00587 }
00588 }
00589
00590
00591 outr(EMAC_NCR, inr(EMAC_NCR) & ~EMAC_MPE);
00592
00593 return 0;
00594 }
00595
00596
00597
00598
00599 static void EmacInterrupt(void *arg)
00600 {
00601 unsigned int isr;
00602 EMACINFO *ni = (EMACINFO *) ((NUTDEVICE *) arg)->dev_dcb;
00603
00604
00605 isr = inr(EMAC_ISR);
00606
00607
00608
00609 if ((isr & (EMAC_RCOMP | EMAC_ROVR | EMAC_RXUBR)) != 0) {
00610
00611 outr(EMAC_IDR, EMAC_RCOMP | EMAC_ROVR | EMAC_RXUBR);
00612 NutEventPostFromIrq(&ni->ni_rx_rdy);
00613 }
00614
00615
00616 if ((isr & EMAC_TCOMP) != 0 || (inr(EMAC_TSR) & EMAC_COMP) != 0) {
00617
00618 NutEventPostFromIrq(&ni->ni_tx_rdy);
00619 }
00620 }
00621
00627 static int EmacGetPacket(EMACINFO * ni, NETBUF ** nbp)
00628 {
00629 int rc = -1;
00630 unsigned int fbc = 0;
00631 unsigned int i;
00632 *nbp = NULL;
00633
00634
00635
00636
00637 while ((rxBufTab[rxBufIdx].addr & RXBUF_OWNERSHIP) != 0 && (rxBufTab[rxBufIdx].stat & RXS_SOF) == 0) {
00638 rxBufTab[rxBufIdx].addr &= ~(RXBUF_OWNERSHIP);
00639 rxBufIdx++;
00640 if (rxBufIdx >= EMAC_RX_BUFFERS) {
00641 rxBufIdx = 0;
00642 }
00643 }
00644
00645
00646
00647
00648 i = rxBufIdx;
00649 while (rxBufTab[i].addr & RXBUF_OWNERSHIP) {
00650 if (i != rxBufIdx && (rxBufTab[i].stat & RXS_SOF) != 0) {
00651 do {
00652 rxBufTab[rxBufIdx].addr &= ~(RXBUF_OWNERSHIP);
00653 rxBufIdx++;
00654 if (rxBufIdx >= EMAC_RX_BUFFERS) {
00655 rxBufIdx = 0;
00656 }
00657 } while ((rxBufTab[rxBufIdx].addr & RXBUF_OWNERSHIP) != 0 && (rxBufTab[rxBufIdx].stat & RXS_SOF) == 0);
00658 break;
00659 }
00660 if ((fbc = rxBufTab[i].stat & RXS_LENGTH_FRAME) != 0) {
00661 break;
00662 }
00663 i++;
00664 if (i >= EMAC_RX_BUFFERS) {
00665 i = 0;
00666 }
00667 }
00668
00669 if (fbc) {
00670
00671
00672
00673
00674 if (fbc > 1536) {
00675 ni->ni_insane = 1;
00676 } else {
00677 *nbp = NutNetBufAlloc(0, NBAF_DATALINK, (uint16_t)fbc);
00678 if (*nbp != NULL) {
00679 uint8_t *bp = (uint8_t *) (* nbp)->nb_dl.vp;
00680 unsigned int len;
00681
00682 while (fbc) {
00683 if (fbc > EMAC_RX_BUFSIZ) {
00684 len = EMAC_RX_BUFSIZ;
00685 } else {
00686 len = fbc;
00687 }
00688 memcpy(bp, (void *) (rxBufTab[rxBufIdx].addr & RXBUF_ADDRMASK), len);
00689 rxBufTab[rxBufIdx].addr &= ~RXBUF_OWNERSHIP;
00690 rxBufIdx++;
00691 if (rxBufIdx >= EMAC_RX_BUFFERS) {
00692 rxBufIdx = 0;
00693 }
00694 fbc -= len;
00695 bp += len;
00696 }
00697 rc = 0;
00698 }
00699 }
00700 }
00701 return rc;
00702 }
00703
00718 static int EmacPutPacket(int bufnum, EMACINFO * ni, NETBUF * nb)
00719 {
00720 int rc = -1;
00721 unsigned int sz;
00722 uint8_t *buf;
00723
00724
00725
00726
00727
00728
00729
00730 if ((sz = nb->nb_nw.sz + nb->nb_tp.sz + nb->nb_ap.sz) > ETHERMTU) {
00731 return -1;
00732 }
00733 sz += nb->nb_dl.sz;
00734 if (sz & 1) {
00735 sz++;
00736 }
00737
00738
00739 NutIrqDisable(&sig_EMAC);
00740
00741
00742 if (ni->ni_insane == 0) {
00743 buf = (uint8_t *) txBufTab[bufnum].addr;
00744 memcpy(buf, nb->nb_dl.vp, nb->nb_dl.sz);
00745 buf += nb->nb_dl.sz;
00746 memcpy(buf, nb->nb_nw.vp, nb->nb_nw.sz);
00747 buf += nb->nb_nw.sz;
00748 memcpy(buf, nb->nb_tp.vp, nb->nb_tp.sz);
00749 buf += nb->nb_tp.sz;
00750 memcpy(buf, nb->nb_ap.vp, nb->nb_ap.sz);
00751 sz |= TXS_LAST_BUFF;
00752 if (bufnum) {
00753 sz |= TXS_WRAP;
00754 }
00755 txBufTab[bufnum].stat = sz;
00756 outr(EMAC_NCR, inr(EMAC_NCR) | EMAC_TSTART);
00757 rc = 0;
00758 #ifdef NUT_PERFMON
00759 ni->ni_tx_packets++;
00760 #endif
00761 }
00762
00763
00764 NutIrqEnable(&sig_EMAC);
00765
00766 return rc;
00767 }
00768
00769
00777 static int EmacStart(CONST uint8_t * mac)
00778 {
00779 unsigned int i;
00780
00781
00782 outr(EMAC_SA1L, (mac[3] << 24) | (mac[2] << 16) | (mac[1] << 8) | mac[0]);
00783 outr(EMAC_SA1H, (mac[5] << 8) | mac[4]);
00784
00785
00786 for (i = 0; i < EMAC_RX_BUFFERS - 1; i++) {
00787 rxBufTab[i].addr = (unsigned int) (&rxBuf[i * EMAC_RX_BUFSIZ]) & RXBUF_ADDRMASK;
00788 }
00789 rxBufTab[i].addr = ((unsigned int) (&rxBuf[i * EMAC_RX_BUFSIZ]) & RXBUF_ADDRMASK) | RXBUF_WRAP;
00790 outr(EMAC_RBQP, (unsigned int) rxBufTab);
00791
00792
00793 txBufTab[0].addr = (unsigned int) (&txBuf[0]);
00794 txBufTab[0].stat = TXS_USED;
00795 txBufTab[1].addr = (unsigned int) (&txBuf[EMAC_TX_BUFSIZ]);
00796 txBufTab[1].stat = TXS_USED | TXS_WRAP;
00797 outr(EMAC_TBQP, (unsigned int) txBufTab);
00798
00799
00800 outr(EMAC_RSR, EMAC_OVR | EMAC_REC | EMAC_BNA);
00801
00802
00803 outr(EMAC_NCFGR, inr(EMAC_NCFGR) | EMAC_CAF | EMAC_DRFCS);
00804
00805
00806 outr(EMAC_NCR, inr(EMAC_NCR) | EMAC_TE | EMAC_RE | EMAC_WESTAT);
00807
00808 return 0;
00809 }
00810
00815 THREAD(EmacRxThread, arg)
00816 {
00817 NUTDEVICE *dev;
00818 IFNET *ifn;
00819 EMACINFO *ni;
00820 NETBUF *nb;
00821
00822 dev = arg;
00823 ifn = (IFNET *) dev->dev_icb;
00824 ni = (EMACINFO *) dev->dev_dcb;
00825
00826
00827
00828
00829
00830
00831 while (!ETHER_IS_UNICAST(ifn->if_mac)) {
00832 NutSleep(10);
00833 }
00834
00835
00836
00837
00838
00839
00840
00841 while (EmacStart(ifn->if_mac)) {
00842 EmacReset(EMAC_LINK_LOOPS);
00843 NutSleep(1000);
00844 }
00845
00846
00847 NutEventPost(&ni->ni_mutex);
00848
00849
00850 NutThreadSetPriority(9);
00851
00852
00853 outr(EMAC_IER, EMAC_ROVR | EMAC_TCOMP | EMAC_TUND | EMAC_RXUBR | EMAC_RCOMP);
00854 NutIrqEnable(&sig_EMAC);
00855
00856 for (;;) {
00857
00858
00859
00860
00861
00862 NutEventWait(&ni->ni_rx_rdy, 200);
00863
00864
00865
00866
00867
00868 while (EmacGetPacket(ni, &nb) == 0) {
00869
00870 if (nb->nb_dl.sz < 60) {
00871 NutNetBufFree(nb);
00872 } else {
00873 (*ifn->if_recv) (dev, nb);
00874 }
00875 }
00876 outr(EMAC_IER, EMAC_ROVR | EMAC_RXUBR | EMAC_RCOMP);
00877
00878
00879 while (ni->ni_insane) {
00880 EmacReset(EMAC_LINK_LOOPS);
00881 if (EmacStart(ifn->if_mac) == 0) {
00882 ni->ni_insane = 0;
00883 ni->ni_tx_queued = 0;
00884 ni->ni_tx_quelen = 0;
00885 NutIrqEnable(&sig_EMAC);
00886 } else {
00887 NutSleep(1000);
00888 }
00889 }
00890 }
00891 }
00892
00903 int EmacOutput(NUTDEVICE * dev, NETBUF * nb)
00904 {
00905 static uint32_t mx_wait = 5000;
00906 int rc = -1;
00907 EMACINFO *ni = (EMACINFO *) dev->dev_dcb;
00908
00909
00910
00911
00912
00913 while (rc) {
00914 if (ni->ni_insane) {
00915 break;
00916 }
00917 if (NutEventWait(&ni->ni_mutex, mx_wait)) {
00918 break;
00919 }
00920
00921
00922 if ((txBufTab[txBufIdx].stat & TXS_USED) == 0) {
00923 if (NutEventWait(&ni->ni_tx_rdy, 500) && (txBufTab[txBufIdx].stat & TXS_USED) == 0) {
00924
00925 txBufTab[txBufIdx].stat |= TXS_USED;
00926 txBufIdx++;
00927 txBufIdx &= 1;
00928 NutEventPost(&ni->ni_mutex);
00929 break;
00930 }
00931 } else {
00932 if (inr(EMAC_TSR) & EMAC_UND) {
00933 txBufIdx = 0;
00934 outr(EMAC_TSR, EMAC_UND);
00935 }
00936 if (inr(EMAC_TSR) & EMAC_COMP) {
00937 outr(EMAC_TSR, EMAC_COMP);
00938 }
00939
00940 if ((rc = EmacPutPacket(txBufIdx, ni, nb)) == 0) {
00941 txBufIdx++;
00942 txBufIdx &= 1;
00943 }
00944 }
00945 NutEventPost(&ni->ni_mutex);
00946 }
00947
00948
00949
00950
00951
00952 if (rc) {
00953 mx_wait = 500;
00954 } else {
00955
00956
00957 mx_wait = 5000;
00958 }
00959 return rc;
00960 }
00961
00971 int EmacInit(NUTDEVICE * dev)
00972 {
00973 EMACINFO *ni = (EMACINFO *) dev->dev_dcb;
00974
00975
00976 if (EmacReset(EMAC_LINK_LOOPS)) {
00977 if (EmacReset(EMAC_LINK_LOOPS)) {
00978 return -1;
00979 }
00980 }
00981
00982
00983 memset(ni, 0, sizeof(EMACINFO));
00984
00985
00986 if (NutRegisterIrqHandler(&sig_EMAC, EmacInterrupt, dev)) {
00987 return -1;
00988 }
00989
00990
00991 if (NutThreadCreate("emacrx", EmacRxThread, dev,
00992 (NUT_THREAD_NICRXSTACK * NUT_THREAD_STACK_MULT) + NUT_THREAD_STACK_ADD) == NULL) {
00993 return -1;
00994 }
00995 return 0;
00996 }
00997
00998 static EMACINFO dcb_eth0;
00999
01005 static IFNET ifn_eth0 = {
01006 IFT_ETHER,
01007 0,
01008 {0, 0, 0, 0, 0, 0},
01009 0,
01010 0,
01011 0,
01012 ETHERMTU,
01013 0,
01014 0,
01015 0,
01016 NutEtherInput,
01017 EmacOutput,
01018 NutEtherOutput
01019 };
01020
01030 NUTDEVICE devAt91Emac = {
01031 0,
01032 {'e', 't', 'h', '0', 0, 0, 0, 0, 0},
01033 IFTYP_NET,
01034 0,
01035 0,
01036 &ifn_eth0,
01037 &dcb_eth0,
01038 EmacInit,
01039 0,
01040 0,
01041 0,
01042 #ifdef __HARVARD_ARCH__
01043 0,
01044 #endif
01045 0,
01046 0,
01047 0
01048 };
01049