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 
00194 #ifndef NIC_PHY_UID
00195 #define NIC_PHY_UID 0xffffffff
00196 #endif
00197 
00205 #define CHECK_ALL_KNOWN_PHY_IDS
00206 
00207 #if defined (MCU_AT91SAM9260) || defined(MCU_AT91SAM9XE512)
00208 
00214 #define PHY_MODE_RMII
00215 
00216 
00217 
00218 
00219 #define EMAC_PIO_ASR            PIOA_ASR
00220 #define EMAC_PIO_BSR            PIOA_BSR
00221 #define EMAC_PIO_PDR            PIOA_PDR
00222 
00223 #define PHY_TXD0_BIT            PA12_ETX0_A     
00224 #define PHY_TXD1_BIT            PA13_ETX1_A     
00225 #define PHY_RXD0_AD0_BIT        PA14_ERX0_A     
00226 #define PHY_RXD1_AD1_BIT        PA15_ERX1_A     
00227 #define PHY_TXEN_BIT            PA16_ETXEN_A    
00228 #define PHY_RXDV_TESTMODE_BIT   PA17_ERXDV_A    
00229 #define PHY_RXER_RXD4_RPTR_BIT  PA18_ERXER_A    
00230 #define PHY_TXCLK_ISOLATE_BIT   PA19_ETXCK_A    
00231 #define PHY_MDC_BIT             PA20_EMDC_A     
00232 #define PHY_MDIO_BIT            PA21_EMDIO_A    
00234 #ifndef PHY_MODE_RMII
00235 #define PHY_TXD2_BIT            PA10_ETX2_B     
00236 #define PHY_TXD3_BIT            PA11_ETX3_B     
00237 #define PHY_TXER_TXD4_BIT       PA22_ETXER_B    
00238 #define PHY_RXCLK_10BTSER_BIT   PA27_ERXCK_B    
00239 #define PHY_COL_RMII_BIT        PA29_ECOL_B     
00240 #endif
00241 
00242 #define PHY_RXD2_AD2_BIT        PA25_ERX2_B     
00243 #define PHY_RXD3_AD3_BIT        PA26_ERX3_B     
00244 #define PHY_CRS_AD4_BIT         PA28_ECRS_B     
00246 #define PHY_MII_PINS_A 0 \
00247     | _BV(PHY_TXD0_BIT) \
00248     | _BV(PHY_TXD1_BIT) \
00249     | _BV(PHY_RXD0_AD0_BIT) \
00250     | _BV(PHY_RXD1_AD1_BIT) \
00251     | _BV(PHY_TXEN_BIT) \
00252     | _BV(PHY_RXDV_TESTMODE_BIT) \
00253     | _BV(PHY_RXER_RXD4_RPTR_BIT) \
00254     | _BV(PHY_TXCLK_ISOLATE_BIT) \
00255     | _BV(PHY_MDC_BIT) \
00256     | _BV(PHY_MDIO_BIT)
00257 
00258 #ifdef PHY_MODE_RMII
00259 #define PHY_MII_PINS_B 0
00260 #else
00261 #define PHY_MII_PINS_B 0 \
00262     | _BV(PHY_TXD2_BIT) \
00263     | _BV(PHY_TXD3_BIT) \
00264     | _BV(PHY_TXER_TXD4_BIT) \
00265     | _BV(PHY_RXD2_AD2_BIT) \
00266     | _BV(PHY_RXD3_AD3_BIT) \
00267     | _BV(PHY_RXCLK_10BTSER_BIT) \
00268     | _BV(PHY_CRS_AD4_BIT) \
00269     | _BV(PHY_COL_RMII_BIT)
00270 #endif
00271 
00272 #elif defined (MCU_AT91SAM7X)
00273 
00274 #define EMAC_PIO_PER            PIOB_PER
00275 #define EMAC_PIO_OER            PIOB_OER
00276 #define EMAC_PIO_CODR           PIOB_CODR
00277 #define EMAC_PIO_SODR           PIOB_SODR
00278 #define EMAC_PIO_PUER           PIOB_PUER
00279 #define EMAC_PIO_PUDR           PIOB_PUDR
00280 #define EMAC_PIO_ASR            PIOB_ASR
00281 #define EMAC_PIO_BSR            PIOB_BSR
00282 #define EMAC_PIO_PDR            PIOB_PDR
00283 
00284 #define PHY_TXCLK_ISOLATE_BIT   0
00285 #define PHY_REFCLK_XT2_BIT      0
00286 #define PHY_TXEN_BIT            1
00287 #define PHY_TXD0_BIT            2
00288 #define PHY_TXD1_BIT            3
00289 #define PHY_CRS_AD4_BIT         4
00290 #define PHY_RXD0_AD0_BIT        5
00291 #define PHY_RXD1_AD1_BIT        6
00292 #define PHY_RXER_RXD4_RPTR_BIT  7
00293 #define PHY_MDC_BIT             8
00294 #define PHY_MDIO_BIT            9
00295 #define PHY_TXD2_BIT            10
00296 #define PHY_TXD3_BIT            11
00297 #define PHY_TXER_TXD4_BIT       12
00298 #define PHY_RXD2_AD2_BIT        13
00299 #define PHY_RXD3_AD3_BIT        14
00300 #define PHY_RXDV_TESTMODE_BIT   15
00301 #define PHY_COL_RMII_BIT        16
00302 #define PHY_RXCLK_10BTSER_BIT   17
00303 #define PHY_MDINTR_BIT          26
00304 
00305 #define PHY_MII_PINS_A 0 \
00306     | _BV(PHY_REFCLK_XT2_BIT) \
00307     | _BV(PHY_TXEN_BIT) \
00308     | _BV(PHY_TXD0_BIT) \
00309     | _BV(PHY_TXD1_BIT) \
00310     | _BV(PHY_CRS_AD4_BIT) \
00311     | _BV(PHY_RXD0_AD0_BIT) \
00312     | _BV(PHY_RXD1_AD1_BIT) \
00313     | _BV(PHY_RXER_RXD4_RPTR_BIT) \
00314     | _BV(PHY_MDC_BIT) \
00315     | _BV(PHY_MDIO_BIT) \
00316     | _BV(PHY_TXD2_BIT) \
00317     | _BV(PHY_TXD3_BIT) \
00318     | _BV(PHY_TXER_TXD4_BIT) \
00319     | _BV(PHY_RXD2_AD2_BIT) \
00320     | _BV(PHY_RXD3_AD3_BIT) \
00321     | _BV(PHY_RXDV_TESTMODE_BIT) \
00322     | _BV(PHY_COL_RMII_BIT) \
00323     | _BV(PHY_RXCLK_10BTSER_BIT)
00324 
00325 #define PHY_MII_PINS_B 0
00326 
00327 #endif
00328 
00332 struct _EMACINFO {
00333 #ifdef NUT_PERFMON
00334     uint32_t ni_rx_packets;       
00335     uint32_t ni_tx_packets;       
00336     uint32_t ni_overruns;         
00337     uint32_t ni_rx_frame_errors;  
00338     uint32_t ni_rx_crc_errors;    
00339     uint32_t ni_rx_missed_errors; 
00340 #endif
00341     HANDLE volatile ni_rx_rdy;  
00342     HANDLE volatile ni_tx_rdy;  
00343     HANDLE ni_mutex;            
00344     volatile int ni_tx_queued;  
00345     volatile int ni_tx_quelen;  
00346     volatile int ni_insane;     
00347     int ni_iomode;              
00348 };
00349 
00353 typedef struct _EMACINFO EMACINFO;
00354 
00355 
00356 
00357 
00358 
00359 
00360 typedef struct _BufDescriptor {
00361     unsigned int addr;
00362     unsigned int stat;
00363 } BufDescriptor;
00364 
00365 static volatile BufDescriptor txBufTab[EMAC_TX_BUFFERS];
00366 static volatile uint8_t txBuf[EMAC_TX_BUFFERS * EMAC_TX_BUFSIZ] __attribute__ ((aligned(8)));
00367 static unsigned int txBufIdx;
00368 
00369 static volatile BufDescriptor rxBufTab[EMAC_RX_BUFFERS];
00370 static volatile uint8_t rxBuf[EMAC_RX_BUFFERS * EMAC_RX_BUFSIZ] __attribute__ ((aligned(8)));
00371 static unsigned int rxBufIdx;
00372 
00373 #define RXBUF_OWNERSHIP     0x00000001
00374 #define RXBUF_WRAP          0x00000002
00375 #define RXBUF_ADDRMASK      0xFFFFFFFC
00376 
00377 #define RXS_BROADCAST_ADDR  0x80000000  
00378 #define RXS_MULTICAST_HASH  0x40000000  
00379 #define RXS_UNICAST_HASH    0x20000000  
00380 #define RXS_EXTERNAL_ADDR   0x10000000  
00381 #define RXS_SA1_ADDR        0x04000000  
00382 #define RXS_SA2_ADDR        0x02000000  
00383 #define RXS_SA3_ADDR        0x01000000  
00384 #define RXS_SA4_ADDR        0x00800000  
00385 #define RXS_TYPE_ID         0x00400000  
00386 #define RXS_VLAN_TAG        0x00200000  
00387 #define RXS_PRIORITY_TAG    0x00100000  
00388 #define RXS_VLAN_PRIORITY   0x000E0000  
00389 #define RXS_CFI_IND         0x00010000  
00390 #define RXS_EOF             0x00008000  
00391 #define RXS_SOF             0x00004000  
00392 #define RXS_RBF_OFFSET      0x00003000  
00393 #define RXS_LENGTH_FRAME    0x000007FF  
00395 #define TXS_USED            0x80000000  
00396 #define TXS_WRAP            0x40000000  
00397 #define TXS_ERROR           0x20000000  
00398 #define TXS_UNDERRUN        0x10000000  
00399 #define TXS_NO_BUFFER       0x08000000  
00400 #define TXS_NO_CRC          0x00010000  
00401 #define TXS_LAST_BUFF       0x00008000  
00403 #define MII_DM9161_ID     0x0181b8a0
00404 #define MII_AM79C875_ID   0x00225540
00405 #define MII_MICREL_ID     0x00221610
00406 #define MII_LAN8700_ID    0x0007c0c0
00407 #define MII_LAN8710_ID    0x0007C0F0
00408 
00409 
00414 
00422 static uint16_t phy_inw(uint8_t reg)
00423 {
00424     
00425     outr(EMAC_MAN, EMAC_SOF | EMAC_RW_READ | EMAC_CODE | 
00426         (NIC_PHY_ADDR << EMAC_PHYA_LSB) | (reg << EMAC_REGA_LSB));
00427 
00428     
00429     while ((inr(EMAC_NSR) & EMAC_IDLE) == 0);
00430 
00431     
00432     return (uint16_t) (inr(EMAC_MAN) >> EMAC_DATA_LSB);
00433 }
00434 
00435 #if !defined(PHY_MODE_RMII) || (NIC_PHY_UID == MII_LAN8710_ID)
00436 
00442 static void phy_outw(uint8_t reg, uint16_t val)
00443 {
00444     
00445     outr(EMAC_MAN, EMAC_SOF | EMAC_RW_WRITE | EMAC_CODE | 
00446         (NIC_PHY_ADDR << EMAC_PHYA_LSB) | (reg << EMAC_REGA_LSB) | val);
00447 
00448     
00449     while ((inr(EMAC_NSR) & EMAC_IDLE) == 0);
00450 }
00451 #endif
00452 
00458 static int probePhy(uint32_t tmo)
00459 {
00460     uint32_t physID;
00461     uint16_t phyval;
00462 
00463     
00464     physID = (phy_inw(NIC_PHY_ID2) & 0xFFF0) | ((phy_inw(NIC_PHY_ID1) << 16) & 0xFFFF0000);   
00465 #if NIC_PHY_UID != 0xffffffff
00466     if ( physID != (NIC_PHY_UID & 0xFFFFFFF0) ) {
00467         outr(EMAC_NCR, inr(EMAC_NCR) & ~EMAC_MPE);
00468         return -1;
00469     }
00470 #elif defined(CHECK_ALL_KNOWN_PHY_IDS)
00471     if ( physID != MII_DM9161_ID && physID != MII_AM79C875_ID && physID != MII_MICREL_ID && physID != MII_LAN8700_ID && physID != MII_LAN8710_ID) {
00472         outr(EMAC_NCR, inr(EMAC_NCR) & ~EMAC_MPE);
00473         return -1;
00474     }
00475 #endif
00476 
00477     
00478     phyval = phy_inw(NIC_PHY_BMCR);
00479     if (phyval & NIC_PHY_BMCR_ANEGENA) {
00480         
00481         phy_inw(NIC_PHY_BMSR);  
00482         while (--tmo) {
00483             if (phy_inw(NIC_PHY_BMSR) & NIC_PHY_BMSR_ANCOMPL) {
00484                 break;
00485             }
00486         }
00487         
00488         if (tmo == 0) {
00489             outr(EMAC_NCR, inr(EMAC_NCR) & ~EMAC_MPE);
00490             return -1;
00491         }
00492 
00493         
00494 
00495 
00496         phyval = phy_inw(NIC_PHY_ANLPAR);
00497         if (phyval & NIC_PHY_ANEG_TX_FDX) {
00498             
00499             outr(EMAC_NCFGR, inr(EMAC_NCFGR) | EMAC_SPD | EMAC_FD);
00500         }
00501         else if (phyval & NIC_PHY_ANEG_TX_HDX) {
00502             
00503             outr(EMAC_NCFGR, (inr(EMAC_NCFGR) & ~EMAC_FD) | EMAC_SPD);
00504         }
00505         else if (phyval & NIC_PHY_ANEG_10_FDX) {
00506             
00507             outr(EMAC_NCFGR, (inr(EMAC_NCFGR) & ~EMAC_SPD) | EMAC_FD);
00508         }
00509         else {
00510             
00511             outr(EMAC_NCFGR, inr(EMAC_NCFGR) & ~(EMAC_SPD | EMAC_FD));
00512         }
00513     }
00514 
00515     
00516     outr(EMAC_NCR, inr(EMAC_NCR) & ~EMAC_MPE);
00517 
00518     return 0;
00519 }
00520 
00526 static int EmacReset(uint32_t tmo)
00527 {
00528     
00529     outr(PMC_PCER, _BV(PIOA_ID));
00530     outr(PMC_PCER, _BV(PIOB_ID));
00531     outr(PMC_PCER, _BV(EMAC_ID));
00532 
00533     
00534     outr(EMAC_PIO_ASR, PHY_MII_PINS_A);
00535     outr(EMAC_PIO_BSR, PHY_MII_PINS_B);
00536     outr(EMAC_PIO_PDR, PHY_MII_PINS_A | PHY_MII_PINS_B);
00537 
00538     
00539 #ifdef PHY_MODE_RMII
00540     outr(EMAC_USRIO, EMAC_RMII | EMAC_CLKEN);
00541 #else
00542     outr(EMAC_USRIO, EMAC_CLKEN);
00543 #endif
00544 
00545     
00546     outr(EMAC_NCR, inr(EMAC_NCR) | EMAC_MPE);
00547     outr(EMAC_NCFGR, inr(EMAC_NCFGR) | EMAC_CLK_HCLK_64);
00548 
00549     
00550     NutDelay(255);
00551 
00552 #if NIC_PHY_UID == MII_LAN8710_ID
00553     
00554     phy_outw(18, phy_inw(18) | 0x00E0);
00555     phy_outw(NIC_PHY_BMCR, NIC_PHY_BMCR_RESET);
00556     NutSleep(100);
00557 #endif
00558 
00559 #ifndef PHY_MODE_RMII
00560     
00561     phy_inw(NIC_PHY_BMCR);
00562     phy_outw(NIC_PHY_BMCR, phy_inw(NIC_PHY_BMCR) & ~NIC_PHY_BMCR_ISOLATE);
00563 #endif
00564 
00565     return probePhy(tmo);
00566 }
00567 
00568 
00569 
00570 
00571 static void EmacInterrupt(void *arg)
00572 {
00573     unsigned int isr;
00574     EMACINFO *ni = (EMACINFO *) ((NUTDEVICE *) arg)->dev_dcb;
00575 
00576     
00577     isr = inr(EMAC_ISR);
00578 
00579     
00580     
00581     if ((isr & (EMAC_RCOMP | EMAC_ROVR | EMAC_RXUBR)) != 0) {
00582         
00583         outr(EMAC_IDR, EMAC_RCOMP | EMAC_ROVR | EMAC_RXUBR);
00584         NutEventPostFromIrq(&ni->ni_rx_rdy);
00585     }
00586 
00587     
00588     if ((isr & EMAC_TCOMP) != 0 || (inr(EMAC_TSR) & EMAC_COMP) != 0) {
00589         
00590         NutEventPostFromIrq(&ni->ni_tx_rdy);
00591     }
00592 }
00593 
00599 static int EmacGetPacket(EMACINFO * ni, NETBUF ** nbp)
00600 {
00601     int rc = -1;
00602     unsigned int fbc = 0;
00603     unsigned int i;
00604     *nbp = NULL;
00605 
00606     
00607 
00608 
00609     while ((rxBufTab[rxBufIdx].addr & RXBUF_OWNERSHIP) != 0 && (rxBufTab[rxBufIdx].stat & RXS_SOF) == 0) {
00610         rxBufTab[rxBufIdx].addr &= ~(RXBUF_OWNERSHIP);
00611         rxBufIdx++;
00612         if (rxBufIdx >= EMAC_RX_BUFFERS) {
00613             rxBufIdx = 0;
00614         }
00615     }
00616 
00617     
00618 
00619 
00620     i = rxBufIdx;
00621     while (rxBufTab[i].addr & RXBUF_OWNERSHIP) {
00622         if (i != rxBufIdx && (rxBufTab[i].stat & RXS_SOF) != 0) {
00623             do {
00624                 rxBufTab[rxBufIdx].addr &= ~(RXBUF_OWNERSHIP);
00625                 rxBufIdx++;
00626                 if (rxBufIdx >= EMAC_RX_BUFFERS) {
00627                     rxBufIdx = 0;
00628                 }
00629             } while ((rxBufTab[rxBufIdx].addr & RXBUF_OWNERSHIP) != 0 && (rxBufTab[rxBufIdx].stat & RXS_SOF) == 0);
00630             break;
00631         }
00632         if ((fbc = rxBufTab[i].stat & RXS_LENGTH_FRAME) != 0) {
00633             break;
00634         }
00635         i++;
00636         if (i >= EMAC_RX_BUFFERS) {
00637             i = 0;
00638         }
00639     }
00640 
00641     if (fbc) {
00642         
00643 
00644 
00645 
00646         if (fbc > 1536) {
00647             ni->ni_insane = 1;
00648         } else {
00649             *nbp = NutNetBufAlloc(0, NBAF_DATALINK, (uint16_t)fbc);
00650             if (*nbp != NULL) {
00651                 uint8_t *bp = (uint8_t *) (* nbp)->nb_dl.vp;
00652                 unsigned int len;
00653 
00654                 while (fbc) {
00655                     if (fbc > EMAC_RX_BUFSIZ) {
00656                         len = EMAC_RX_BUFSIZ;
00657                     } else {
00658                         len = fbc;
00659                     }
00660                     memcpy(bp, (void *) (rxBufTab[rxBufIdx].addr & RXBUF_ADDRMASK), len);
00661                     rxBufTab[rxBufIdx].addr &= ~RXBUF_OWNERSHIP;
00662                     rxBufIdx++;
00663                     if (rxBufIdx >= EMAC_RX_BUFFERS) {
00664                         rxBufIdx = 0;
00665                     }
00666                     fbc -= len;
00667                     bp += len;
00668                 }
00669                 rc = 0;
00670             }
00671         }
00672     }
00673     return rc;
00674 }
00675 
00690 static int EmacPutPacket(int bufnum, EMACINFO * ni, NETBUF * nb)
00691 {
00692     int rc = -1;
00693     unsigned int sz;
00694     uint8_t *buf;
00695 
00696     
00697 
00698 
00699 
00700 
00701 
00702     if ((sz = nb->nb_nw.sz + nb->nb_tp.sz + nb->nb_ap.sz) > ETHERMTU) {
00703         return -1;
00704     }
00705     sz += nb->nb_dl.sz;
00706     if (sz & 1) {
00707         sz++;
00708     }
00709 
00710     
00711     NutIrqDisable(&sig_EMAC);
00712 
00713     
00714     if (ni->ni_insane == 0) {
00715         buf = (uint8_t *) txBufTab[bufnum].addr;
00716         memcpy(buf, nb->nb_dl.vp, nb->nb_dl.sz);
00717         buf += nb->nb_dl.sz;
00718         memcpy(buf, nb->nb_nw.vp, nb->nb_nw.sz);
00719         buf += nb->nb_nw.sz;
00720         memcpy(buf, nb->nb_tp.vp, nb->nb_tp.sz);
00721         buf += nb->nb_tp.sz;
00722         memcpy(buf, nb->nb_ap.vp, nb->nb_ap.sz);
00723         sz |= TXS_LAST_BUFF;
00724         if (bufnum) {
00725             sz |= TXS_WRAP;
00726         }
00727         txBufTab[bufnum].stat = sz;
00728         outr(EMAC_NCR, inr(EMAC_NCR) | EMAC_TSTART);
00729         rc = 0;
00730 #ifdef NUT_PERFMON
00731         ni->ni_tx_packets++;
00732 #endif
00733     }
00734 
00735     
00736     NutIrqEnable(&sig_EMAC);
00737 
00738     return rc;
00739 }
00740 
00741 
00749 static int EmacStart(CONST uint8_t * mac)
00750 {
00751     unsigned int i;
00752 
00753     
00754     outr(EMAC_SA1L, (mac[3] << 24) | (mac[2] << 16) | (mac[1] << 8) | mac[0]);
00755     outr(EMAC_SA1H, (mac[5] << 8) | mac[4]);
00756 
00757     
00758     for (i = 0; i < EMAC_RX_BUFFERS - 1; i++) {
00759         rxBufTab[i].addr = (unsigned int) (&rxBuf[i * EMAC_RX_BUFSIZ]) & RXBUF_ADDRMASK;
00760     }
00761     rxBufTab[i].addr = ((unsigned int) (&rxBuf[i * EMAC_RX_BUFSIZ]) & RXBUF_ADDRMASK) | RXBUF_WRAP;
00762     outr(EMAC_RBQP, (unsigned int) rxBufTab);
00763 
00764     
00765     txBufTab[0].addr = (unsigned int) (&txBuf[0]);
00766     txBufTab[0].stat = TXS_USED;
00767     txBufTab[1].addr = (unsigned int) (&txBuf[EMAC_TX_BUFSIZ]);
00768     txBufTab[1].stat = TXS_USED | TXS_WRAP;
00769     outr(EMAC_TBQP, (unsigned int) txBufTab);
00770 
00771     
00772     outr(EMAC_RSR, EMAC_OVR | EMAC_REC | EMAC_BNA);
00773 
00774     
00775     outr(EMAC_NCFGR, inr(EMAC_NCFGR) | EMAC_DRFCS);
00776 
00777     
00778     outr(EMAC_NCR, inr(EMAC_NCR) | EMAC_TE | EMAC_RE | EMAC_WESTAT);
00779 
00780     return 0;
00781 }
00782 
00787 THREAD(EmacRxThread, arg)
00788 {
00789     NUTDEVICE *dev;
00790     IFNET *ifn;
00791     EMACINFO *ni;
00792     NETBUF *nb;
00793 
00794     dev = arg;
00795     ifn = (IFNET *) dev->dev_icb;
00796     ni = (EMACINFO *) dev->dev_dcb;
00797 
00798     
00799 
00800 
00801 
00802 
00803     while (!ETHER_IS_UNICAST(ifn->if_mac)) {
00804         NutSleep(10);
00805     }
00806 
00807     
00808 
00809 
00810 
00811 
00812 
00813     while (EmacStart(ifn->if_mac)) {
00814         EmacReset(EMAC_LINK_LOOPS);
00815         NutSleep(1000);
00816     }
00817 
00818     
00819     NutEventPost(&ni->ni_mutex);
00820 
00821     
00822     NutThreadSetPriority(9);
00823 
00824     
00825     outr(EMAC_IER, EMAC_ROVR | EMAC_TCOMP | EMAC_TUND | EMAC_RXUBR | EMAC_RCOMP);
00826     NutIrqEnable(&sig_EMAC);
00827 
00828     for (;;) {
00829         
00830 
00831 
00832 
00833 
00834         NutEventWait(&ni->ni_rx_rdy, 200);
00835 
00836         
00837 
00838 
00839 
00840         while (EmacGetPacket(ni, &nb) == 0) {
00841             
00842             if (nb->nb_dl.sz < 60) {
00843                 NutNetBufFree(nb);
00844             } else {
00845                 (*ifn->if_recv) (dev, nb);
00846             }
00847         }
00848         outr(EMAC_IER, EMAC_ROVR | EMAC_RXUBR | EMAC_RCOMP);
00849 
00850         
00851         while (ni->ni_insane) {
00852             EmacReset(EMAC_LINK_LOOPS);
00853             if (EmacStart(ifn->if_mac) == 0) {
00854                 ni->ni_insane = 0;
00855                 ni->ni_tx_queued = 0;
00856                 ni->ni_tx_quelen = 0;
00857                 NutIrqEnable(&sig_EMAC);
00858             } else {
00859                 NutSleep(1000);
00860             }
00861         }
00862     }
00863 }
00864 
00875 int EmacOutput(NUTDEVICE * dev, NETBUF * nb)
00876 {
00877     static uint32_t mx_wait = 5000;
00878     int rc = -1;
00879     EMACINFO *ni = (EMACINFO *) dev->dev_dcb;
00880 
00881     
00882 
00883 
00884 
00885     while (rc) {
00886         if (ni->ni_insane) {
00887             break;
00888         }
00889         if (NutEventWait(&ni->ni_mutex, mx_wait)) {
00890             break;
00891         }
00892 
00893         
00894         if ((txBufTab[txBufIdx].stat & TXS_USED) == 0) {
00895             if (NutEventWait(&ni->ni_tx_rdy, 500) && (txBufTab[txBufIdx].stat & TXS_USED) == 0) {
00896                 
00897                 txBufTab[txBufIdx].stat |= TXS_USED;
00898                 txBufIdx++;
00899                 txBufIdx &= 1;
00900                 NutEventPost(&ni->ni_mutex);
00901                 break;
00902             }
00903         } else {
00904             if (inr(EMAC_TSR) & EMAC_UND) {
00905                 txBufIdx = 0;
00906                     outr(EMAC_TSR, EMAC_UND);
00907                 }
00908             if (inr(EMAC_TSR) & EMAC_COMP) {
00909                     outr(EMAC_TSR, EMAC_COMP);
00910                 }
00911 
00912             if ((rc = EmacPutPacket(txBufIdx, ni, nb)) == 0) {
00913                 txBufIdx++;
00914                 txBufIdx &= 1;
00915             }
00916         }
00917         NutEventPost(&ni->ni_mutex);
00918     }
00919 
00920     
00921 
00922 
00923 
00924     if (rc) {
00925         mx_wait = 500;
00926     } else {
00927         
00928 
00929         mx_wait = 5000;
00930     }
00931     return rc;
00932 }
00933 
00943 int EmacInit(NUTDEVICE * dev)
00944 {
00945     EMACINFO *ni = (EMACINFO *) dev->dev_dcb;
00946 
00947     
00948     if (EmacReset(EMAC_LINK_LOOPS)) {
00949         if (EmacReset(EMAC_LINK_LOOPS)) {
00950             return -1;
00951         }
00952     }
00953 
00954     
00955     memset(ni, 0, sizeof(EMACINFO));
00956 
00957     
00958     if (NutRegisterIrqHandler(&sig_EMAC, EmacInterrupt, dev)) {
00959         return -1;
00960     }
00961 
00962     
00963     if (NutThreadCreate("emacrx", EmacRxThread, dev, 
00964         (NUT_THREAD_NICRXSTACK * NUT_THREAD_STACK_MULT) + NUT_THREAD_STACK_ADD) == NULL) {
00965         return -1;
00966     }
00967     return 0;
00968 }
00969 
00970 static EMACINFO dcb_eth0;
00971 
00977 static IFNET ifn_eth0 = {
00978     IFT_ETHER,                  
00979     0,                          
00980     {0, 0, 0, 0, 0, 0},         
00981     0,                          
00982     0,                          
00983     0,                          
00984     ETHERMTU,                   
00985     0,                          
00986     0,                          
00987     0,                          
00988     NutEtherInput,              
00989     EmacOutput,                 
00990     NutEtherOutput              
00991 };
00992 
01002 NUTDEVICE devAt91Emac = {
01003     0,                          
01004     {'e', 't', 'h', '0', 0, 0, 0, 0, 0},        
01005     IFTYP_NET,                  
01006     0,                          
01007     0,                          
01008     &ifn_eth0,                  
01009     &dcb_eth0,                  
01010     EmacInit,                   
01011     0,                          
01012     0,                          
01013     0,                          
01014 #ifdef __HARVARD_ARCH__
01015     0,                          
01016 #endif
01017     0,                          
01018     0,                          
01019     0                           
01020 };
01021