at91_emac.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2006-2007 by egnite Software GmbH
00003  * Copyright (C) 2010 by egnite GmbH
00004  *
00005  * All rights reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions
00009  * are met:
00010  *
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  * 2. Redistributions in binary form must reproduce the above copyright
00014  *    notice, this list of conditions and the following disclaimer in the
00015  *    documentation and/or other materials provided with the distribution.
00016  * 3. Neither the name of the copyright holders nor the names of
00017  *    contributors may be used to endorse or promote products derived
00018  *    from this software without specific prior written permission.
00019  *
00020  * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS
00021  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00022  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00023  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE
00024  * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00025  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00026  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00027  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00028  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00029  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00030  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00031  * SUCH DAMAGE.
00032  *
00033  * For additional information see http://www.ethernut.de/
00034  *
00035  */
00036 
00037 /*
00038  * $Log$
00039  * Revision 1.16  2009/02/06 15:37:39  haraldkipp
00040  * Added stack space multiplier and addend. Adjusted stack space.
00041  *
00042  * Revision 1.15  2009/01/17 11:26:37  haraldkipp
00043  * Getting rid of two remaining BSD types in favor of stdint.
00044  * Replaced 'u_int' by 'unsinged int' and 'uptr_t' by 'uintptr_t'.
00045  *
00046  * Revision 1.14  2008/08/28 11:12:15  haraldkipp
00047  * Added interface flags, which will be required to implement Ethernet ioctl
00048  * functions.
00049  *
00050  * Revision 1.13  2008/08/11 06:59:04  haraldkipp
00051  * BSD types replaced by stdint types (feature request #1282721).
00052  *
00053  * Revision 1.12  2008/08/06 12:43:41  haraldkipp
00054  * First EMAC reset failed on power-up. Initialize EMAC clock and MII mode
00055  * earlier.
00056  * Added support for Ethernut 5 (AT91SAM9XE reference design).
00057  *
00058  * Revision 1.11  2007/09/06 20:07:24  olereinhardt
00059  * Changed phy detection and added support for micel phy (SAM7-EX256 Board)
00060  *
00061  * Revision 1.10  2007/08/29 07:43:52  haraldkipp
00062  * Documentation updated and corrected.
00063  *
00064  * Revision 1.9  2007/05/02 11:20:26  haraldkipp
00065  * Pull-up enable/disable simplified.
00066  * Added multicast table entry.
00067  *
00068  * Revision 1.8  2007/04/20 13:06:08  haraldkipp
00069  * Previous change failed on SAM7X-EK. We are now using PHY address 0 by
00070  * default and disable all pull-ups during PHY reset.
00071  *
00072  * Revision 1.7  2007/04/12 09:13:10  haraldkipp
00073  * Bugfix: PHY initialization may fail with pull-ups enabled.
00074  *
00075  * Revision 1.6  2007/02/15 16:00:45  haraldkipp
00076  * Configurable buffer usage and link timeout.
00077  *
00078  * Revision 1.5  2006/10/17 11:06:12  haraldkipp
00079  * Number of loops waiting for links increased to 10000 and NIC resets
00080  * reduced. This will help to link to auto MDIX via direct cable.
00081  *
00082  * Revision 1.4  2006/10/08 16:41:34  haraldkipp
00083  * PHY address and power down bit are now configurable.
00084  *
00085  * Revision 1.3  2006/10/05 17:10:37  haraldkipp
00086  * Link detection was unreliable. This also caused bug #1567785.
00087  * Now NutRegisterDevice will return an error, if there is no
00088  * link available. Applications may then call NutRegisterDevice again.
00089  *
00090  * Revision 1.2  2006/09/29 12:29:16  haraldkipp
00091  * Several fixes to make it running reliably on the AT91SAM9260.
00092  *
00093  * Revision 1.1  2006/08/31 18:58:47  haraldkipp
00094  * More general AT91 MAC driver replaces the SAM7X specific version.
00095  * This had been tested on the SAM9260, but loses Ethernet packets
00096  * for a yet unknown reason.
00097  *
00098  */
00099 
00100 #include <cfg/os.h>
00101 #include <cfg/dev.h>
00102 #include <arch/arm.h>
00103 #include <cfg/arch/gpio.h>
00104 
00105 #include <string.h>
00106 
00107 #include <sys/atom.h>
00108 #include <sys/heap.h>
00109 #include <sys/thread.h>
00110 #include <sys/event.h>
00111 #include <sys/timer.h>
00112 #include <sys/confnet.h>
00113 
00114 #include <netinet/if_ether.h>
00115 #include <net/ether.h>
00116 #include <net/if_var.h>
00117 
00118 #include <dev/irqreg.h>
00119 #include <dev/at91_emac.h>
00120 
00121 #ifdef NUTDEBUG
00122 #include <stdio.h>
00123 #endif
00124 
00125 #ifndef NUT_THREAD_NICRXSTACK
00126 /* arm-elf-gcc used 168 bytes with optimized, 412 bytes with debug code. */
00127 #define NUT_THREAD_NICRXSTACK   320
00128 #endif
00129 
00130 #ifndef EMAC_RX_BUFFERS
00131 #define EMAC_RX_BUFFERS         32
00132 #endif
00133 #define EMAC_RX_BUFSIZ          128
00134 
00135 #define EMAC_TX_BUFFERS         2
00136 #ifndef EMAC_TX_BUFSIZ
00137 #define EMAC_TX_BUFSIZ          1536
00138 #endif
00139 
00140 #ifndef EMAC_LINK_LOOPS
00141 #define EMAC_LINK_LOOPS         1000000
00142 #endif
00143 
00148 #define NIC_PHY_BMCR            0x00    
00149 #define NIC_PHY_BMCR_COLTEST    0x0080  
00150 #define NIC_PHY_BMCR_FDUPLEX    0x0100  
00151 #define NIC_PHY_BMCR_ANEGSTART  0x0200  
00152 #define NIC_PHY_BMCR_ISOLATE    0x0400  
00153 #define NIC_PHY_BMCR_PWRDN      0x0800  
00154 #define NIC_PHY_BMCR_ANEGENA    0x1000  
00155 #define NIC_PHY_BMCR_100MBPS    0x2000  
00156 #define NIC_PHY_BMCR_LOOPBACK   0x4000  
00157 #define NIC_PHY_BMCR_RESET      0x8000  
00159 #define NIC_PHY_BMSR            0x01    
00160 #define NIC_PHY_BMSR_ANCOMPL    0x0020  
00161 #define NIC_PHY_BMSR_LINKSTAT   0x0004  
00163 #define NIC_PHY_ID1             0x02    
00164 #define NIC_PHY_ID2             0x03    
00165 #define NIC_PHY_ANAR            0x04    
00166 #define NIC_PHY_ANLPAR          0x05    
00167 #define NIC_PHY_ANEG_NP         0x8000  
00168 #define NIC_PHY_ANEG_ACK        0x4000  
00169 #define NIC_PHY_ANEG_RF         0x2000  
00170 #define NIC_PHY_ANEG_FCS        0x0400  
00171 #define NIC_PHY_ANEG_T4         0x0200  
00172 #define NIC_PHY_ANEG_TX_FDX     0x0100  
00173 #define NIC_PHY_ANEG_TX_HDX     0x0080  
00174 #define NIC_PHY_ANEG_10_FDX     0x0040  
00175 #define NIC_PHY_ANEG_10_HDX     0x0020  
00176 #define NIC_PHY_ANEG_BINSEL     0x001F  
00178 #define NIC_PHY_ANER            0x06    
00181 
00182 /* 
00183  * Board specific defaults.
00184  */
00185 #if defined(AT91SAM9260_EK)
00186 
00192 #define PHY_MODE_RMII
00193 
00194 #define PHY_STRAP_PINS 0 \
00195     | _BV(PHY_RXDV_TESTMODE_BIT) \
00196     | _BV(PHY_RXD0_AD0_BIT) \
00197     | _BV(PHY_RXD1_AD1_BIT) \
00198     | _BV(PHY_RXD2_AD2_BIT) \
00199     | _BV(PHY_RXD3_AD3_BIT) \
00200     | _BV(PHY_CRS_AD4_BIT)
00201 
00202 #elif defined(AT91SAM7X_EK)
00203 
00204 #define PHY_STRAP_PINS 0 \
00205     | _BV(PHY_COL_RMII_BIT) \
00206     | _BV(PHY_RXDV_TESTMODE_BIT) \
00207     | _BV(PHY_RXD0_AD0_BIT) \
00208     | _BV(PHY_RXD1_AD1_BIT) \
00209     | _BV(PHY_RXD2_AD2_BIT) \
00210     | _BV(PHY_RXD3_AD3_BIT) \
00211     | _BV(PHY_CRS_AD4_BIT)
00212 
00213 #endif
00214 
00220 #ifndef NIC_PHY_ADDR
00221 #define NIC_PHY_ADDR            0
00222 #endif
00223 
00224 
00225 #if defined (MCU_AT91SAM9260) || defined(MCU_AT91SAM9XE)
00226 
00227 #define EMAC_PIO_PER            PIOA_PER
00228 #define EMAC_PIO_OER            PIOA_OER
00229 #define EMAC_PIO_ODR            PIOA_ODR
00230 #define EMAC_PIO_CODR           PIOA_CODR
00231 #define EMAC_PIO_PUER           PIOA_PUER
00232 #define EMAC_PIO_PUDR           PIOA_PUDR
00233 #define EMAC_PIO_ASR            PIOA_ASR
00234 #define EMAC_PIO_BSR            PIOA_BSR
00235 #define EMAC_PIO_PDR            PIOA_PDR
00236 
00237 #define PHY_TXD0_BIT            PA12_ETX0_A     
00238 #define PHY_TXD1_BIT            PA13_ETX1_A     
00239 #define PHY_RXD0_AD0_BIT        PA14_ERX0_A     
00240 #define PHY_RXD1_AD1_BIT        PA15_ERX1_A     
00241 #define PHY_TXEN_BIT            PA16_ETXEN_A    
00242 #define PHY_RXDV_TESTMODE_BIT   PA17_ERXDV_A    
00243 #define PHY_RXER_RXD4_RPTR_BIT  PA18_ERXER_A    
00244 #define PHY_TXCLK_ISOLATE_BIT   PA19_ETXCK_A    
00245 #define PHY_MDC_BIT             PA20_EMDC_A     
00246 #define PHY_MDIO_BIT            PA21_EMDIO_A    
00248 #ifndef PHY_MODE_RMII
00249 #define PHY_TXD2_BIT            PA10_ETX2_B     
00250 #define PHY_TXD3_BIT            PA11_ETX3_B     
00251 #define PHY_TXER_TXD4_BIT       PA22_ETXER_B    
00252 #define PHY_RXCLK_10BTSER_BIT   PA27_ERXCK_B    
00253 #define PHY_COL_RMII_BIT        PA29_ECOL_B     
00254 #endif
00255 
00256 #define PHY_RXD2_AD2_BIT        PA25_ERX2_B     
00257 #define PHY_RXD3_AD3_BIT        PA26_ERX3_B     
00258 #define PHY_CRS_AD4_BIT         PA28_ECRS_B     
00260 #define PHY_MII_PINS_A 0 \
00261     | _BV(PHY_TXD0_BIT) \
00262     | _BV(PHY_TXD1_BIT) \
00263     | _BV(PHY_RXD0_AD0_BIT) \
00264     | _BV(PHY_RXD1_AD1_BIT) \
00265     | _BV(PHY_TXEN_BIT) \
00266     | _BV(PHY_RXDV_TESTMODE_BIT) \
00267     | _BV(PHY_RXER_RXD4_RPTR_BIT) \
00268     | _BV(PHY_TXCLK_ISOLATE_BIT) \
00269     | _BV(PHY_MDC_BIT) \
00270     | _BV(PHY_MDIO_BIT)
00271 
00272 #ifdef PHY_MODE_RMII
00273 #define PHY_MII_PINS_B 0
00274 #else
00275 #define PHY_MII_PINS_B 0 \
00276     | _BV(PHY_TXD2_BIT) \
00277     | _BV(PHY_TXD3_BIT) \
00278     | _BV(PHY_TXER_TXD4_BIT) \
00279     | _BV(PHY_RXD2_AD2_BIT) \
00280     | _BV(PHY_RXD3_AD3_BIT) \
00281     | _BV(PHY_RXCLK_10BTSER_BIT) \
00282     | _BV(PHY_CRS_AD4_BIT) \
00283     | _BV(PHY_COL_RMII_BIT)
00284 #endif
00285 
00286 #elif defined (MCU_AT91SAM7X)
00287 
00288 #define EMAC_PIO_PER            PIOB_PER
00289 #define EMAC_PIO_OER            PIOB_OER
00290 #define EMAC_PIO_ODR            PIOB_ODR
00291 #define EMAC_PIO_CODR           PIOB_CODR
00292 #define EMAC_PIO_SODR           PIOB_SODR
00293 #define EMAC_PIO_PUER           PIOB_PUER
00294 #define EMAC_PIO_PUDR           PIOB_PUDR
00295 #define EMAC_PIO_ASR            PIOB_ASR
00296 #define EMAC_PIO_BSR            PIOB_BSR
00297 #define EMAC_PIO_PDR            PIOB_PDR
00298 
00299 #define PHY_TXCLK_ISOLATE_BIT   0
00300 #define PHY_REFCLK_XT2_BIT      0
00301 #define PHY_TXEN_BIT            1
00302 #define PHY_TXD0_BIT            2
00303 #define PHY_TXD1_BIT            3
00304 #define PHY_CRS_AD4_BIT         4
00305 #define PHY_RXD0_AD0_BIT        5
00306 #define PHY_RXD1_AD1_BIT        6
00307 #define PHY_RXER_RXD4_RPTR_BIT  7
00308 #define PHY_MDC_BIT             8
00309 #define PHY_MDIO_BIT            9
00310 #define PHY_TXD2_BIT            10
00311 #define PHY_TXD3_BIT            11
00312 #define PHY_TXER_TXD4_BIT       12
00313 #define PHY_RXD2_AD2_BIT        13
00314 #define PHY_RXD3_AD3_BIT        14
00315 #define PHY_RXDV_TESTMODE_BIT   15
00316 #define PHY_COL_RMII_BIT        16
00317 #define PHY_RXCLK_10BTSER_BIT   17
00318 #ifndef PHY_PWRDN_BIT
00319 #define PHY_PWRDN_BIT           18
00320 #endif
00321 #define PHY_MDINTR_BIT          26
00322 
00323 #define PHY_MII_PINS_A 0 \
00324     | _BV(PHY_REFCLK_XT2_BIT) \
00325     | _BV(PHY_TXEN_BIT) \
00326     | _BV(PHY_TXD0_BIT) \
00327     | _BV(PHY_TXD1_BIT) \
00328     | _BV(PHY_CRS_AD4_BIT) \
00329     | _BV(PHY_RXD0_AD0_BIT) \
00330     | _BV(PHY_RXD1_AD1_BIT) \
00331     | _BV(PHY_RXER_RXD4_RPTR_BIT) \
00332     | _BV(PHY_MDC_BIT) \
00333     | _BV(PHY_MDIO_BIT) \
00334     | _BV(PHY_TXD2_BIT) \
00335     | _BV(PHY_TXD3_BIT) \
00336     | _BV(PHY_TXER_TXD4_BIT) \
00337     | _BV(PHY_RXD2_AD2_BIT) \
00338     | _BV(PHY_RXD3_AD3_BIT) \
00339     | _BV(PHY_RXDV_TESTMODE_BIT) \
00340     | _BV(PHY_COL_RMII_BIT) \
00341     | _BV(PHY_RXCLK_10BTSER_BIT)
00342 
00343 #define PHY_MII_PINS_B 0
00344 
00345 #endif
00346 
00347 #if !defined(PHY_ADDR_STRAP_PINS)
00348 #define PHY_ADDR_STRAP_PINS 0 \
00349     | _BV(PHY_RXDV_TESTMODE_BIT) \
00350     | _BV(PHY_RXD0_AD0_BIT) \
00351     | _BV(PHY_RXD1_AD1_BIT) \
00352     | _BV(PHY_RXD2_AD2_BIT) \
00353     | _BV(PHY_RXD3_AD3_BIT) \
00354     | _BV(PHY_CRS_AD4_BIT)
00355 #endif
00356 
00357 #if !defined(PHY_STRAP_PINS)
00358 #if defined(PHY_MODE_RMII)
00359 #define PHY_STRAP_PINS      (PHY_ADDR_STRAP_PINS)
00360 #else
00361 #define PHY_STRAP_PINS      (PHY_ADDR_STRAP_PINS | _BV(PHY_COL_RMII_BIT))
00362 #endif
00363 #endif
00364 
00368 struct _EMACINFO {
00369 #ifdef NUT_PERFMON
00370     uint32_t ni_rx_packets;       
00371     uint32_t ni_tx_packets;       
00372     uint32_t ni_overruns;         
00373     uint32_t ni_rx_frame_errors;  
00374     uint32_t ni_rx_crc_errors;    
00375     uint32_t ni_rx_missed_errors; 
00376 #endif
00377     HANDLE volatile ni_rx_rdy;  
00378     HANDLE volatile ni_tx_rdy;  
00379     HANDLE ni_mutex;            
00380     volatile int ni_tx_queued;  
00381     volatile int ni_tx_quelen;  
00382     volatile int ni_insane;     
00383     int ni_iomode;              
00384 };
00385 
00389 typedef struct _EMACINFO EMACINFO;
00390 
00391 /*
00392  * TODO: Buffers and their descriptors should be part of the EMACINFO
00393  * structure. Actually there will be no dual Ethernet chip (sure?),
00394  * but just to keep the code clean.
00395  */
00396 typedef struct _BufDescriptor {
00397     unsigned int addr;
00398     unsigned int stat;
00399 } BufDescriptor;
00400 
00401 static volatile BufDescriptor txBufTab[EMAC_TX_BUFFERS];
00402 static volatile uint8_t txBuf[EMAC_TX_BUFFERS * EMAC_TX_BUFSIZ] __attribute__ ((aligned(8)));
00403 static unsigned int txBufIdx;
00404 
00405 static volatile BufDescriptor rxBufTab[EMAC_RX_BUFFERS];
00406 static volatile uint8_t rxBuf[EMAC_RX_BUFFERS * EMAC_RX_BUFSIZ] __attribute__ ((aligned(8)));
00407 static unsigned int rxBufIdx;
00408 
00409 #define RXBUF_OWNERSHIP     0x00000001
00410 #define RXBUF_WRAP          0x00000002
00411 #define RXBUF_ADDRMASK      0xFFFFFFFC
00412 
00413 #define RXS_BROADCAST_ADDR  0x80000000  
00414 #define RXS_MULTICAST_HASH  0x40000000  
00415 #define RXS_UNICAST_HASH    0x20000000  
00416 #define RXS_EXTERNAL_ADDR   0x10000000  
00417 #define RXS_SA1_ADDR        0x04000000  
00418 #define RXS_SA2_ADDR        0x02000000  
00419 #define RXS_SA3_ADDR        0x01000000  
00420 #define RXS_SA4_ADDR        0x00800000  
00421 #define RXS_TYPE_ID         0x00400000  
00422 #define RXS_VLAN_TAG        0x00200000  
00423 #define RXS_PRIORITY_TAG    0x00100000  
00424 #define RXS_VLAN_PRIORITY   0x000E0000  
00425 #define RXS_CFI_IND         0x00010000  
00426 #define RXS_EOF             0x00008000  
00427 #define RXS_SOF             0x00004000  
00428 #define RXS_RBF_OFFSET      0x00003000  
00429 #define RXS_LENGTH_FRAME    0x000007FF  
00431 #define TXS_USED            0x80000000  
00432 #define TXS_WRAP            0x40000000  
00433 #define TXS_ERROR           0x20000000  
00434 #define TXS_UNDERRUN        0x10000000  
00435 #define TXS_NO_BUFFER       0x08000000  
00436 #define TXS_NO_CRC          0x00010000  
00437 #define TXS_LAST_BUFF       0x00008000  
00444 
00445 
00452 static uint16_t phy_inw(uint8_t reg)
00453 {
00454     /* PHY read command. */
00455     outr(EMAC_MAN, EMAC_SOF | EMAC_RW_READ | EMAC_CODE | 
00456         (NIC_PHY_ADDR << EMAC_PHYA_LSB) | (reg << EMAC_REGA_LSB));
00457 
00458     /* Wait until PHY logic completed. */
00459     while ((inr(EMAC_NSR) & EMAC_IDLE) == 0);
00460 
00461     /* Get data from PHY maintenance register. */
00462     return (uint16_t) (inr(EMAC_MAN) >> EMAC_DATA_LSB);
00463 }
00464 
00465 #ifndef PHY_MODE_RMII
00466 
00472 static void phy_outw(uint8_t reg, uint16_t val)
00473 {
00474     /* PHY write command. */
00475     outr(EMAC_MAN, EMAC_SOF | EMAC_RW_WRITE | EMAC_CODE | 
00476         (NIC_PHY_ADDR << EMAC_PHYA_LSB) | (reg << EMAC_REGA_LSB) | val);
00477 
00478     /* Wait until PHY logic completed. */
00479     while ((inr(EMAC_NSR) & EMAC_IDLE) == 0);
00480 }
00481 #endif
00482 
00488 static int EmacReset(uint32_t tmo)
00489 {
00490     uint16_t phyval;
00491 
00492     outr(PMC_PCER, _BV(PIOA_ID));
00493     outr(PMC_PCER, _BV(PIOB_ID));
00494     outr(PMC_PCER, _BV(EMAC_ID));
00495 
00496 #ifdef PHY_PWRDN_BIT
00497     /* Disable PHY power down. */
00498     outr(EMAC_PIO_PER, _BV(PHY_PWRDN_BIT));
00499     outr(EMAC_PIO_OER, _BV(PHY_PWRDN_BIT));
00500 #ifdef PHY_PWRDN_NEGPOL
00501     outr(EMAC_PIO_SODR, _BV(PHY_PWRDN_BIT));
00502 #else
00503     outr(EMAC_PIO_CODR, _BV(PHY_PWRDN_BIT));
00504 #endif
00505 #endif
00506 
00507 #if PHY_STRAP_PINS
00508     {
00509         uint32_t rstcr_tmp;
00510 
00511         /* Enable PIO mode on all pins. */
00512         outr(EMAC_PIO_PER, PHY_MII_PINS_A | PHY_MII_PINS_B);
00513         /* Disable TESTMODE and set PHY address 0 and by disabling pull-ups. */
00514         outr(EMAC_PIO_CODR, PHY_STRAP_PINS);
00515         outr(EMAC_PIO_OER, PHY_STRAP_PINS);
00516 
00517         /* Toggle external hardware reset pin. */
00518         rstcr_tmp = inr(RSTC_MR) & 0x00FFFFFF;
00519         outr(RSTC_MR, RSTC_KEY | (2 << RSTC_ERSTL_LSB));
00520      
00521         outr(RSTC_CR, RSTC_KEY | RSTC_EXTRST);
00522         while ((inr(RSTC_SR) & RSTC_NRSTL) == 0);
00523         outr(RSTC_MR, RSTC_KEY | rstcr_tmp); 
00524 
00525         /* Disable outputs. */
00526         outr(EMAC_PIO_ODR, PHY_STRAP_PINS);
00527     }
00528 #endif /* PHY_STRAP_PINS */
00529 
00530     /* Enable (R)MII peripherals. */
00531     outr(EMAC_PIO_ASR, PHY_MII_PINS_A);
00532     outr(EMAC_PIO_BSR, PHY_MII_PINS_B);
00533     outr(EMAC_PIO_PDR, PHY_MII_PINS_A | PHY_MII_PINS_B);
00534 
00535     /* Enable receive and transmit clocks and set MII mode. */
00536 #ifdef PHY_MODE_RMII
00537     outr(EMAC_USRIO, EMAC_RMII | EMAC_CLKEN);
00538 #else
00539     outr(EMAC_USRIO, EMAC_CLKEN);
00540 #endif
00541 
00542     /* Enable management port. */
00543     outr(EMAC_NCR, inr(EMAC_NCR) | EMAC_MPE);
00544     outr(EMAC_NCFGR, inr(EMAC_NCFGR) | EMAC_CLK_HCLK_64);
00545 
00546     /* Wait for PHY ready. */
00547     NutDelay(255);
00548 
00549 #ifndef PHY_MODE_RMII
00550     /* Clear MII isolate. */
00551     phy_inw(NIC_PHY_BMCR);
00552     phy_outw(NIC_PHY_BMCR, phy_inw(NIC_PHY_BMCR) & ~NIC_PHY_BMCR_ISOLATE);
00553 #endif
00554 
00555 //    /* For some unknown reason it seems to be required to read the ID registers first. */
00556 //    if (phy_inw(NIC_PHY_ID1) != 0x0181 || (phy_inw(NIC_PHY_ID2) & 0xFFF0) != 0xB8A0) {
00557 //        outr(EMAC_NCR, inr(EMAC_NCR) & ~EMAC_MPE);
00558 //        return -1;
00559 //    }
00560 
00561 // TODO: Make phy id configurable
00562 /* PHY ID */
00563 #define MII_DM9161_ID_H     0x0181
00564 #define MII_DM9161_ID_L     0xb8a0
00565 
00566 #define MII_AM79C875_ID_H   0x0022
00567 #define MII_AM79C875_ID_L   0x5540      
00568 
00569 #define MII_MICREL_ID_H     0x0022
00570 #define MII_MICREL_ID_L     0x1610
00571 
00572 #define MII_LAN8700_ID_H    0x0007
00573 #define MII_LAN8700_ID_L    0xc0c0
00574 
00575      /* For some unknown reason it seems to be required to read the ID 
00576 registers first. */
00577 
00578      // Check for DM PHY (as used on the ATMEL EK)
00579     if (phy_inw(NIC_PHY_ID1) != MII_DM9161_ID_H ||
00580        (phy_inw(NIC_PHY_ID2) & 0xFFF0) != MII_DM9161_ID_L) {
00581      // Check for MICREL PHY (as used on the Olimex SAM7-EX256)         
00582         if (phy_inw(NIC_PHY_ID1) != MII_MICREL_ID_H ||
00583            (phy_inw(NIC_PHY_ID2) & 0xFFF0) != MII_MICREL_ID_L) {
00584             if (phy_inw(NIC_PHY_ID1) != MII_LAN8700_ID_H ||
00585                (phy_inw(NIC_PHY_ID2) & 0xFFF0) != MII_LAN8700_ID_L) {
00586                 outr(EMAC_NCR, inr(EMAC_NCR) & ~EMAC_MPE);
00587                 return -1;
00588             }
00589         }
00590     }
00591 
00592 
00593 // TODO: END
00594 
00595     /* Handle auto negotiation if configured. */
00596     phyval = phy_inw(NIC_PHY_BMCR);
00597     if (phyval & NIC_PHY_BMCR_ANEGENA) {
00598         /* Wait for auto negotiation completed. */
00599         phy_inw(NIC_PHY_BMSR);  /* Discard previously latched status. */
00600         while (--tmo) {
00601             if (phy_inw(NIC_PHY_BMSR) & NIC_PHY_BMSR_ANCOMPL) {
00602                 break;
00603             }
00604         }
00605         /* Return error on link timeout. */
00606         if (tmo == 0) {
00607             outr(EMAC_NCR, inr(EMAC_NCR) & ~EMAC_MPE);
00608             return -1;
00609         }
00610 
00611         /*
00612          * Read link partner abilities and configure EMAC.
00613          */
00614         phyval = phy_inw(NIC_PHY_ANLPAR);
00615         if (phyval & NIC_PHY_ANEG_TX_FDX) {
00616             /* 100Mb full duplex. */
00617             outr(EMAC_NCFGR, inr(EMAC_NCFGR) | EMAC_SPD | EMAC_FD);
00618         }
00619         else if (phyval & NIC_PHY_ANEG_TX_HDX) {
00620             /* 100Mb half duplex. */
00621             outr(EMAC_NCFGR, (inr(EMAC_NCFGR) & ~EMAC_FD) | EMAC_SPD);
00622         }
00623         else if (phyval & NIC_PHY_ANEG_10_FDX) {
00624             /* 10Mb full duplex. */
00625             outr(EMAC_NCFGR, (inr(EMAC_NCFGR) & ~EMAC_SPD) | EMAC_FD);
00626         }
00627         else {
00628             /* 10Mb half duplex. */
00629             outr(EMAC_NCFGR, inr(EMAC_NCFGR) & ~(EMAC_SPD | EMAC_FD));
00630         }
00631     }
00632 
00633     /* Disable management port. */
00634     outr(EMAC_NCR, inr(EMAC_NCR) & ~EMAC_MPE);
00635 
00636     return 0;
00637 }
00638 
00639 /*
00640  * NIC interrupt entry.
00641  */
00642 static void EmacInterrupt(void *arg)
00643 {
00644     unsigned int isr;
00645     EMACINFO *ni = (EMACINFO *) ((NUTDEVICE *) arg)->dev_dcb;
00646 
00647     /* Read interrupt status and disable interrupts. */
00648     isr = inr(EMAC_ISR);
00649 
00650     /* Receiver interrupt. */
00651     //if ((isr & EMAC_RCOMP) != 0 || (isr & EMAC_ROVR) != 0 || (inr(EMAC_RSR) & EMAC_REC) != 0) {
00652     if ((isr & (EMAC_RCOMP | EMAC_ROVR | EMAC_RXUBR)) != 0) {
00653         //outr(EMAC_RSR, EMAC_REC);
00654         outr(EMAC_IDR, EMAC_RCOMP | EMAC_ROVR | EMAC_RXUBR);
00655         NutEventPostFromIrq(&ni->ni_rx_rdy);
00656     }
00657 
00658     /* Transmitter interrupt. */
00659     if ((isr & EMAC_TCOMP) != 0 || (inr(EMAC_TSR) & EMAC_COMP) != 0) {
00660         //outr(EMAC_TSR, EMAC_COMP);
00661         NutEventPostFromIrq(&ni->ni_tx_rdy);
00662     }
00663 }
00664 
00670 static int EmacGetPacket(EMACINFO * ni, NETBUF ** nbp)
00671 {
00672     int rc = -1;
00673     unsigned int fbc = 0;
00674     unsigned int i;
00675     *nbp = NULL;
00676 
00677     /*
00678      * Search the next frame start. Release any fragment.
00679      */
00680     while ((rxBufTab[rxBufIdx].addr & RXBUF_OWNERSHIP) != 0 && (rxBufTab[rxBufIdx].stat & RXS_SOF) == 0) {
00681         rxBufTab[rxBufIdx].addr &= ~(RXBUF_OWNERSHIP);
00682         rxBufIdx++;
00683         if (rxBufIdx >= EMAC_RX_BUFFERS) {
00684             rxBufIdx = 0;
00685         }
00686     }
00687 
00688     /*
00689      * Determine the size of the next frame.
00690      */
00691     i = rxBufIdx;
00692     while (rxBufTab[i].addr & RXBUF_OWNERSHIP) {
00693         if (i != rxBufIdx && (rxBufTab[i].stat & RXS_SOF) != 0) {
00694             do {
00695                 rxBufTab[rxBufIdx].addr &= ~(RXBUF_OWNERSHIP);
00696                 rxBufIdx++;
00697                 if (rxBufIdx >= EMAC_RX_BUFFERS) {
00698                     rxBufIdx = 0;
00699                 }
00700             } while ((rxBufTab[rxBufIdx].addr & RXBUF_OWNERSHIP) != 0 && (rxBufTab[rxBufIdx].stat & RXS_SOF) == 0);
00701             break;
00702         }
00703         if ((fbc = rxBufTab[i].stat & RXS_LENGTH_FRAME) != 0) {
00704             break;
00705         }
00706         i++;
00707         if (i >= EMAC_RX_BUFFERS) {
00708             i = 0;
00709         }
00710     }
00711 
00712     if (fbc) {
00713         /*
00714          * Receiving long packets is unexpected. Let's declare the 
00715          * chip insane. Short packets will be handled by the caller.
00716          */
00717         if (fbc > 1536) {
00718             ni->ni_insane = 1;
00719         } else {
00720             *nbp = NutNetBufAlloc(0, NBAF_DATALINK, (uint16_t)fbc);
00721             if (*nbp != NULL) {
00722                 uint8_t *bp = (uint8_t *) (* nbp)->nb_dl.vp;
00723                 unsigned int len;
00724 
00725                 while (fbc) {
00726                     if (fbc > EMAC_RX_BUFSIZ) {
00727                         len = EMAC_RX_BUFSIZ;
00728                     } else {
00729                         len = fbc;
00730                     }
00731                     memcpy(bp, (void *) (rxBufTab[rxBufIdx].addr & RXBUF_ADDRMASK), len);
00732                     rxBufTab[rxBufIdx].addr &= ~RXBUF_OWNERSHIP;
00733                     rxBufIdx++;
00734                     if (rxBufIdx >= EMAC_RX_BUFFERS) {
00735                         rxBufIdx = 0;
00736                     }
00737                     fbc -= len;
00738                     bp += len;
00739                 }
00740                 rc = 0;
00741             }
00742         }
00743     }
00744     return rc;
00745 }
00746 
00761 static int EmacPutPacket(int bufnum, EMACINFO * ni, NETBUF * nb)
00762 {
00763     int rc = -1;
00764     unsigned int sz;
00765     uint8_t *buf;
00766 
00767     /*
00768      * Calculate the number of bytes to be send. Do not send packets 
00769      * larger than the Ethernet maximum transfer unit. The MTU
00770      * consist of 1500 data bytes plus the 14 byte Ethernet header
00771      * plus 4 bytes CRC. We check the data bytes only.
00772      */
00773     if ((sz = nb->nb_nw.sz + nb->nb_tp.sz + nb->nb_ap.sz) > ETHERMTU) {
00774         return -1;
00775     }
00776     sz += nb->nb_dl.sz;
00777     if (sz & 1) {
00778         sz++;
00779     }
00780 
00781     /* Disable EMAC interrupts. */
00782     NutIrqDisable(&sig_EMAC);
00783 
00784     /* TODO: Check for link. */
00785     if (ni->ni_insane == 0) {
00786         buf = (uint8_t *) txBufTab[bufnum].addr;
00787         memcpy(buf, nb->nb_dl.vp, nb->nb_dl.sz);
00788         buf += nb->nb_dl.sz;
00789         memcpy(buf, nb->nb_nw.vp, nb->nb_nw.sz);
00790         buf += nb->nb_nw.sz;
00791         memcpy(buf, nb->nb_tp.vp, nb->nb_tp.sz);
00792         buf += nb->nb_tp.sz;
00793         memcpy(buf, nb->nb_ap.vp, nb->nb_ap.sz);
00794         sz |= TXS_LAST_BUFF;
00795         if (bufnum) {
00796             sz |= TXS_WRAP;
00797         }
00798         txBufTab[bufnum].stat = sz;
00799         outr(EMAC_NCR, inr(EMAC_NCR) | EMAC_TSTART);
00800         rc = 0;
00801 #ifdef NUT_PERFMON
00802         ni->ni_tx_packets++;
00803 #endif
00804     }
00805 
00806     /* Enable EMAC interrupts. */
00807     NutIrqEnable(&sig_EMAC);
00808 
00809     return rc;
00810 }
00811 
00812 
00820 static int EmacStart(CONST uint8_t * mac)
00821 {
00822     unsigned int i;
00823 
00824     /* Set local MAC address. */
00825     outr(EMAC_SA1L, (mac[3] << 24) | (mac[2] << 16) | (mac[1] << 8) | mac[0]);
00826     outr(EMAC_SA1H, (mac[5] << 8) | mac[4]);
00827 
00828     /* Initialize receive buffer descriptors. */
00829     for (i = 0; i < EMAC_RX_BUFFERS - 1; i++) {
00830         rxBufTab[i].addr = (unsigned int) (&rxBuf[i * EMAC_RX_BUFSIZ]) & RXBUF_ADDRMASK;
00831     }
00832     rxBufTab[i].addr = ((unsigned int) (&rxBuf[i * EMAC_RX_BUFSIZ]) & RXBUF_ADDRMASK) | RXBUF_WRAP;
00833     outr(EMAC_RBQP, (unsigned int) rxBufTab);
00834 
00835     /* Initialize transmit buffer descriptors. */
00836     txBufTab[0].addr = (unsigned int) (&txBuf[0]);
00837     txBufTab[0].stat = TXS_USED;
00838     txBufTab[1].addr = (unsigned int) (&txBuf[EMAC_TX_BUFSIZ]);
00839     txBufTab[1].stat = TXS_USED | TXS_WRAP;
00840     outr(EMAC_TBQP, (unsigned int) txBufTab);
00841 
00842     /* Clear receiver status. */
00843     outr(EMAC_RSR, EMAC_OVR | EMAC_REC | EMAC_BNA);
00844 
00845     /* Copy all frames and discard FCS. */
00846     outr(EMAC_NCFGR, inr(EMAC_NCFGR) | EMAC_CAF | EMAC_DRFCS);
00847 
00848     /* Enable receiver, transmitter and statistics. */
00849     outr(EMAC_NCR, inr(EMAC_NCR) | EMAC_TE | EMAC_RE | EMAC_WESTAT);
00850 
00851     return 0;
00852 }
00853 
00858 THREAD(EmacRxThread, arg)
00859 {
00860     NUTDEVICE *dev;
00861     IFNET *ifn;
00862     EMACINFO *ni;
00863     NETBUF *nb;
00864 
00865     dev = arg;
00866     ifn = (IFNET *) dev->dev_icb;
00867     ni = (EMACINFO *) dev->dev_dcb;
00868 
00869     /*
00870      * This is a temporary hack. Due to a change in initialization,
00871      * we may not have got a MAC address yet. Wait until one has been
00872      * set.
00873      */
00874     for (;;) {
00875         int i;
00876 
00877         for (i = 0; i < sizeof(ifn->if_mac); i++) {
00878             if (ifn->if_mac[i] && ifn->if_mac[i] != 0xFF) {
00879                 break;
00880             }
00881         }
00882         if (i < sizeof(ifn->if_mac)) {
00883             break;
00884         }
00885         NutSleep(63);
00886     }
00887 
00888     /*
00889      * Do not continue unless we managed to start the NIC. We are
00890      * trapped here if the Ethernet link cannot be established.
00891      * This happens, for example, if no Ethernet cable is plugged
00892      * in.
00893      */
00894     while (EmacStart(ifn->if_mac)) {
00895         EmacReset(EMAC_LINK_LOOPS);
00896         NutSleep(1000);
00897     }
00898 
00899     /* Initialize the access mutex. */
00900     NutEventPost(&ni->ni_mutex);
00901 
00902     /* Run at high priority. */
00903     NutThreadSetPriority(9);
00904 
00905     /* Enable receive and transmit interrupts. */
00906     outr(EMAC_IER, EMAC_ROVR | EMAC_TCOMP | EMAC_TUND | EMAC_RXUBR | EMAC_RCOMP);
00907     NutIrqEnable(&sig_EMAC);
00908 
00909     for (;;) {
00910         /*
00911          * Wait for the arrival of new packets or poll the receiver every 
00912          * 200 milliseconds. This short timeout helps a bit to deal with
00913          * the SAM9260 Ethernet problem.
00914          */
00915         NutEventWait(&ni->ni_rx_rdy, 200);
00916 
00917         /*
00918          * Fetch all packets from the NIC's internal buffer and pass 
00919          * them to the registered handler.
00920          */
00921         while (EmacGetPacket(ni, &nb) == 0) {
00922             /* Discard short packets. */
00923             if (nb->nb_dl.sz < 60) {
00924                 NutNetBufFree(nb);
00925             } else {
00926                 (*ifn->if_recv) (dev, nb);
00927             }
00928         }
00929         outr(EMAC_IER, EMAC_ROVR | EMAC_RXUBR | EMAC_RCOMP);
00930 
00931         /* We got a weird chip, try to restart it. */
00932         while (ni->ni_insane) {
00933             EmacReset(EMAC_LINK_LOOPS);
00934             if (EmacStart(ifn->if_mac) == 0) {
00935                 ni->ni_insane = 0;
00936                 ni->ni_tx_queued = 0;
00937                 ni->ni_tx_quelen = 0;
00938                 NutIrqEnable(&sig_EMAC);
00939             } else {
00940                 NutSleep(1000);
00941             }
00942         }
00943     }
00944 }
00945 
00956 int EmacOutput(NUTDEVICE * dev, NETBUF * nb)
00957 {
00958     static uint32_t mx_wait = 5000;
00959     int rc = -1;
00960     EMACINFO *ni = (EMACINFO *) dev->dev_dcb;
00961 
00962     /*
00963      * After initialization we are waiting for a long time to give
00964      * the PHY a chance to establish an Ethernet link.
00965      */
00966     while (rc) {
00967         if (ni->ni_insane) {
00968             break;
00969         }
00970         if (NutEventWait(&ni->ni_mutex, mx_wait)) {
00971             break;
00972         }
00973 
00974         /* Check for packet queue space. */
00975         if ((txBufTab[txBufIdx].stat & TXS_USED) == 0) {
00976             if (NutEventWait(&ni->ni_tx_rdy, 500) && (txBufTab[txBufIdx].stat & TXS_USED) == 0) {
00977                 /* No queue space. Release the lock and give up. */
00978                 txBufTab[txBufIdx].stat |= TXS_USED;
00979                 txBufIdx++;
00980                 txBufIdx &= 1;
00981                 NutEventPost(&ni->ni_mutex);
00982                 break;
00983             }
00984         } else {
00985             if (inr(EMAC_TSR) & EMAC_UND) {
00986                 txBufIdx = 0;
00987                 outr(EMAC_TSR, EMAC_UND);
00988             }
00989             if (inr(EMAC_TSR) & EMAC_COMP) {
00990                 outr(EMAC_TSR, EMAC_COMP);
00991             }
00992 
00993             if ((rc = EmacPutPacket(txBufIdx, ni, nb)) == 0) {
00994                 txBufIdx++;
00995                 txBufIdx &= 1;
00996             }
00997         }
00998         NutEventPost(&ni->ni_mutex);
00999     }
01000 
01001     /*
01002      * Probably no Ethernet link. Significantly reduce the waiting
01003      * time, so following transmission will soon return an error.
01004      */
01005     if (rc) {
01006         mx_wait = 500;
01007     } else {
01008         /* Ethernet works. Set a long waiting time in case we
01009            temporarly lose the link next time. */
01010         mx_wait = 5000;
01011     }
01012     return rc;
01013 }
01014 
01024 int EmacInit(NUTDEVICE * dev)
01025 {
01026     EMACINFO *ni = (EMACINFO *) dev->dev_dcb;
01027 
01028     /* Reset the controller. */
01029     if (EmacReset(EMAC_LINK_LOOPS)) {
01030         if (EmacReset(EMAC_LINK_LOOPS)) {
01031             return -1;
01032         }
01033     }
01034 
01035     /* Clear EMACINFO structure. */
01036     memset(ni, 0, sizeof(EMACINFO));
01037 
01038     /* Register interrupt handler. */
01039     if (NutRegisterIrqHandler(&sig_EMAC, EmacInterrupt, dev)) {
01040         return -1;
01041     }
01042 
01043     /* Start the receiver thread. */
01044     if (NutThreadCreate("emacrx", EmacRxThread, dev, 
01045         (NUT_THREAD_NICRXSTACK * NUT_THREAD_STACK_MULT) + NUT_THREAD_STACK_ADD) == NULL) {
01046         return -1;
01047     }
01048     return 0;
01049 }
01050 
01051 static EMACINFO dcb_eth0;
01052 
01058 static IFNET ifn_eth0 = {
01059     IFT_ETHER,                  
01060     0,                          
01061     {0, 0, 0, 0, 0, 0},         
01062     0,                          
01063     0,                          
01064     0,                          
01065     ETHERMTU,                   
01066     0,                          
01067     0,                          
01068     0,                          
01069     NutEtherInput,              
01070     EmacOutput,                 
01071     NutEtherOutput              
01072 };
01073 
01083 NUTDEVICE devAt91Emac = {
01084     0,                          
01085     {'e', 't', 'h', '0', 0, 0, 0, 0, 0},        
01086     IFTYP_NET,                  
01087     0,                          
01088     0,                          
01089     &ifn_eth0,                  
01090     &dcb_eth0,                  
01091     EmacInit,                   
01092     0,                          
01093     0,                          
01094     0,                          
01095 #ifdef __HARVARD_ARCH__
01096     0,                          
01097 #endif
01098     0,                          
01099     0,                          
01100     0                           
01101 };
01102 

© 2000-2007 by egnite Software GmbH - visit http://www.ethernut.de/