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