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