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