Nut/OS  4.10.3
API Reference
macb.c
Go to the documentation of this file.
00001 
00036 /*
00037 * $Log: macb.c,v $
00038 *
00039 */
00040 
00041 #include <cfg/os.h>
00042 #include <cfg/dev.h>
00043 #include <cfg/arch/gpio.h>
00044 
00045 #include <arch/avr32.h>
00046 #include <arch/avr32/gpio.h>
00047 
00048 #include <string.h>
00049 
00050 #include <sys/atom.h>
00051 #include <sys/heap.h>
00052 #include <sys/thread.h>
00053 #include <sys/event.h>
00054 #include <sys/timer.h>
00055 #include <sys/confnet.h>
00056 
00057 #include <netinet/if_ether.h>
00058 #include <net/ether.h>
00059 #include <net/if_var.h>
00060 
00061 #include <dev/irqreg.h>
00062 #include <dev/gpio.h>
00063 
00064 #include <avr32/io.h>
00065 
00066 #ifdef NUTDEBUG
00067 #include <stdio.h>
00068 #endif
00069 
00070 #ifndef NUT_THREAD_NICRXSTACK
00071 #define NUT_THREAD_NICRXSTACK   768
00072 #endif
00073 
00074 #ifndef EMAC_RX_BUFFERS
00075 #define EMAC_RX_BUFFERS         32
00076 #endif
00077 #define EMAC_RX_BUFSIZ          128
00078 
00079 #define EMAC_TX_BUFFERS         2
00080 #ifndef EMAC_TX_BUFSIZ
00081 #define EMAC_TX_BUFSIZ          1536
00082 #endif
00083 
00084 #ifndef EMAC_LINK_LOOPS
00085 #define EMAC_LINK_LOOPS         1000000
00086 #endif
00087 
00092 #define NIC_PHY_BMCR            0x00    
00093 #define NIC_PHY_BMCR_COLTEST    0x0080  
00094 #define NIC_PHY_BMCR_FDUPLEX    0x0100  
00095 #define NIC_PHY_BMCR_ANEGSTART  0x0200  
00096 #define NIC_PHY_BMCR_ISOLATE    0x0400  
00097 #define NIC_PHY_BMCR_PWRDN      0x0800  
00098 #define NIC_PHY_BMCR_ANEGENA    0x1000  
00099 #define NIC_PHY_BMCR_100MBPS    0x2000  
00100 #define NIC_PHY_BMCR_LOOPBACK   0x4000  
00101 #define NIC_PHY_BMCR_RESET      0x8000  
00103 #define NIC_PHY_BMSR            0x01    
00104 #define NIC_PHY_BMSR_ANCOMPL    0x0020  
00105 #define NIC_PHY_BMSR_LINKSTAT   0x0004  
00107 #define NIC_PHY_ID1             0x02    
00108 #define NIC_PHY_ID2             0x03    
00109 #define NIC_PHY_ANAR            0x04    
00110 #define NIC_PHY_ANLPAR          0x05    
00111 #define NIC_PHY_ANEG_NP         0x8000  
00112 #define NIC_PHY_ANEG_ACK        0x4000  
00113 #define NIC_PHY_ANEG_RF         0x2000  
00114 #define NIC_PHY_ANEG_FCS        0x0400  
00115 #define NIC_PHY_ANEG_T4         0x0200  
00116 #define NIC_PHY_ANEG_TX_FDX     0x0100  
00117 #define NIC_PHY_ANEG_TX_HDX     0x0080  
00118 #define NIC_PHY_ANEG_10_FDX     0x0040  
00119 #define NIC_PHY_ANEG_10_HDX     0x0020  
00120 #define NIC_PHY_ANEG_BINSEL     0x001F  
00122 #define NIC_PHY_ANER            0x06    
00127 #define NIC_PHY_ADVERTISE_SLCT          0x001f  //!< Selector bits
00128 #define NIC_PHY_ADVERTISE_CSMA          0x0001  //!< Only selector supported
00129 #define NIC_PHY_ADVERTISE_10HALF        0x0020  //!< Try for 10mbps half-duplex
00130 #define NIC_PHY_ADVERTISE_1000XFULL     0x0020  //!< Try for 1000BASE-X full-duplex
00131 #define NIC_PHY_ADVERTISE_10FULL        0x0040  //!< Try for 10mbps full-duplex
00132 #define NIC_PHY_ADVERTISE_1000XHALF     0x0040  //!< Try for 1000BASE-X half-duplex
00133 #define NIC_PHY_ADVERTISE_100HALF       0x0080  //!< Try for 100mbps half-duplex
00134 #define NIC_PHY_ADVERTISE_1000XPAUSE    0x0080  //!< Try for 1000BASE-X pause
00135 #define NIC_PHY_ADVERTISE_100FULL       0x0100  //!< Try for 100mbps full-duplex
00136 #define NIC_PHY_ADVERTISE_1000XPSE_ASYM 0x0100  //!< Try for 1000BASE-X asym pause
00137 #define NIC_PHY_ADVERTISE_100BASE4      0x0200  //!< Try for 100mbps 4k packets
00138 #define NIC_PHY_ADVERTISE_PAUSE_CAP     0x0400  //!< Try for pause
00139 #define NIC_PHY_ADVERTISE_PAUSE_ASYM    0x0800  //!< Try for asymetric pause
00140 #define NIC_PHY_ADVERTISE_RESV          0x1000  //!< Unused...
00141 #define NIC_PHY_ADVERTISE_RFAULT        0x2000  //!< Say we can detect faults
00142 #define NIC_PHY_ADVERTISE_LPACK         0x4000  //!< Ack link partners response
00143 #define NIC_PHY_ADVERTISE_NPAGE         0x8000  //!< Next page bit
00144 
00145 #define NIC_PHY_ADVERTISE_FULL (NIC_PHY_ADVERTISE_100FULL | NIC_PHY_ADVERTISE_10FULL | NIC_PHY_ADVERTISE_CSMA)
00146 #define NIC_PHY_ADVERTISE_ALL (NIC_PHY_ADVERTISE_10HALF | NIC_PHY_ADVERTISE_10FULL | \
00147         NIC_PHY_ADVERTISE_100HALF | NIC_PHY_ADVERTISE_100FULL)
00148 
00157 #ifndef NIC_PHY_ADDR
00158 #define NIC_PHY_ADDR            0
00159 #endif
00160 
00161 #ifndef NIC_PHY_UID
00162 #define NIC_PHY_UID 0xffffffff
00163 #endif
00164 
00170 #define PHY_MODE_RMII
00171 
00172 
00176 struct _EMACINFO {
00177 #ifdef NUT_PERFMON
00178     uint32_t ni_rx_packets;     
00179     uint32_t ni_tx_packets;     
00180     uint32_t ni_overruns;       
00181     uint32_t ni_rx_frame_errors;        
00182     uint32_t ni_rx_crc_errors;  
00183     uint32_t ni_rx_missed_errors;       
00184 #endif
00185     HANDLE volatile ni_rx_rdy;  
00186     HANDLE volatile ni_tx_rdy;  
00187     HANDLE ni_mutex;            
00188     volatile int ni_tx_queued;  
00189     volatile int ni_tx_quelen;  
00190     volatile int ni_insane;     
00191     int ni_iomode;              
00192 };
00193 
00197 typedef struct _EMACINFO EMACINFO;
00198 
00199 /*
00200 * TODO: Buffers and their descriptors should be part of the EMACINFO
00201 * structure. Actually there will be no dual Ethernet chip (sure?),
00202 * but just to keep the code clean.
00203 */
00206 typedef struct _RxTdDescriptor {
00207     uint32_t addr;
00208     uint32_t status;
00209 } RxTdDescriptor;
00211 
00214 
00215 typedef struct _TxTdDescriptor {
00216     uint32_t addr;
00217     uint32_t status;
00218 } TxTdDescriptor;
00220 
00221 static volatile TxTdDescriptor txBufTab[EMAC_TX_BUFFERS];
00222 static volatile uint8_t txBuf[EMAC_TX_BUFFERS * EMAC_TX_BUFSIZ] __attribute__ ((aligned(4)));
00223 static unsigned int txBufIdx;
00224 
00225 static volatile RxTdDescriptor rxBufTab[EMAC_RX_BUFFERS];
00226 static volatile uint8_t rxBuf[EMAC_RX_BUFFERS * EMAC_RX_BUFSIZ] __attribute__ ((aligned(4)));
00227 static unsigned int rxBufIdx;
00228 
00229 #define RXBUF_OWNERSHIP     0x00000001
00230 #define RXBUF_WRAP          0x00000002
00231 #define RXBUF_ADDRMASK      0xFFFFFFFC
00232 
00233 #define RXS_BROADCAST_ADDR  0x80000000  
00234 #define RXS_MULTICAST_HASH  0x40000000  
00235 #define RXS_UNICAST_HASH    0x20000000  
00236 #define RXS_EXTERNAL_ADDR   0x10000000  
00237 #define RXS_SA1_ADDR        0x04000000  
00238 #define RXS_SA2_ADDR        0x02000000  
00239 #define RXS_SA3_ADDR        0x01000000  
00240 #define RXS_SA4_ADDR        0x00800000  
00241 #define RXS_TYPE_ID         0x00400000  
00242 #define RXS_VLAN_TAG        0x00200000  
00243 #define RXS_PRIORITY_TAG    0x00100000  
00244 #define RXS_VLAN_PRIORITY   0x000E0000  
00245 #define RXS_CFI_IND         0x00010000  
00246 #define RXS_EOF             0x00008000  
00247 #define RXS_SOF             0x00004000  
00248 #define RXS_RBF_OFFSET      0x00003000  
00249 #define RXS_LENGTH_FRAME    0x000007FF  
00251 #define TXS_USED            0x80000000  
00252 #define TXS_WRAP            0x40000000  
00253 #define TXS_ERROR           0x20000000  
00254 #define TXS_UNDERRUN        0x10000000  
00255 #define TXS_NO_BUFFER       0x08000000  
00256 #define TXS_NO_CRC          0x00010000  
00257 #define TXS_LAST_BUFF       0x00008000  
00264 
00265 
00272 static uint16_t phy_inw(volatile avr32_macb_t * macb, uint8_t reg)
00273 {
00274     uint16_t value;
00275 
00276     // initiate transaction: enable management port
00277     macb->ncr |= AVR32_MACB_NCR_MPE_MASK;
00278 
00279     // Write the PHY configuration frame to the MAN register
00280     macb->man = (AVR32_MACB_SOF_MASK & (0x01 << AVR32_MACB_SOF_OFFSET)) // SOF
00281         | (2 << AVR32_MACB_CODE_OFFSET) // Code
00282         | (2 << AVR32_MACB_RW_OFFSET)   // Read operation
00283         | ((NIC_PHY_ADDR & 0x1f) << AVR32_MACB_PHYA_OFFSET)     // Phy Add
00284         | (reg << AVR32_MACB_REGA_OFFSET);      // Reg Add
00285 
00286     // wait for PHY to be ready
00287     while (!(macb->nsr & AVR32_MACB_NSR_IDLE_MASK));
00288 
00289     // read the register value in maintenance register
00290     value = macb->man & 0x0000ffff;
00291 
00292     // disable management port
00293     macb->ncr &= ~AVR32_MACB_NCR_MPE_MASK;
00294 
00295     return value;
00296 }
00297 
00304 static void phy_outw(volatile avr32_macb_t * macb, uint8_t reg, uint16_t val)
00305 {
00306     // initiate transaction : enable management port
00307     macb->ncr |= AVR32_MACB_NCR_MPE_MASK;
00308 
00309     // Write the PHY configuration frame to the MAN register
00310     macb->man = ((AVR32_MACB_SOF_MASK & (0x01 << AVR32_MACB_SOF_OFFSET))        // SOF
00311                  | (2 << AVR32_MACB_CODE_OFFSET)        // Code
00312                  | (1 << AVR32_MACB_RW_OFFSET)  // Write operation
00313                  | ((NIC_PHY_ADDR & 0x1f) << AVR32_MACB_PHYA_OFFSET)    // Phy Add
00314                  | (reg << AVR32_MACB_REGA_OFFSET))     // Reg Add
00315         | (val & 0xffff);       // Data
00316 
00317     // wait for PHY to be ready
00318     while (!(macb->nsr & AVR32_MACB_NSR_IDLE_MASK));
00319 
00320     // disable management port
00321     macb->ncr &= ~AVR32_MACB_NCR_MPE_MASK;
00322 }
00323 
00329 static int probePhy(volatile avr32_macb_t * macb)
00330 {
00331     uint32_t physID;
00332     uint16_t phyval;
00333     // Read Phy ID. Ignore revision number.
00334     physID = (phy_inw(macb, NIC_PHY_ID2) & 0xFFF0) | ((phy_inw(macb, NIC_PHY_ID1) << 16) & 0xFFFF0000);
00335 #if NIC_PHY_UID != 0xffffffff
00336     if (physID != (NIC_PHY_UID & 0xFFFFFFF0)) {
00337         return -1;
00338     }
00339 #endif
00340 
00341     phyval = NIC_PHY_ADVERTISE_CSMA | NIC_PHY_ADVERTISE_ALL;
00342     phy_outw(macb, NIC_PHY_ANAR, phyval);
00343 
00344     phyval = phy_inw(macb, NIC_PHY_BMCR);
00345     phyval |= (NIC_PHY_BMCR_ANEGSTART | NIC_PHY_BMCR_ANEGENA);
00346     phy_outw(macb, NIC_PHY_BMCR, phyval);
00347 
00348     /* Handle auto negotiation if configured. */
00349     phyval = phy_inw(macb, NIC_PHY_BMCR);
00350     if (phyval & NIC_PHY_BMCR_ANEGENA) {
00351         int loops = EMAC_LINK_LOOPS;
00352         /* Wait for auto negotiation completed. */
00353         phy_inw(macb, NIC_PHY_BMSR);    /* Discard previously latched status. */
00354         while (--loops) {
00355             if (phy_inw(macb, NIC_PHY_BMSR) & NIC_PHY_BMSR_ANCOMPL) {
00356                 break;
00357             }
00358         }
00359         /* Return error on link timeout. */
00360         if (loops == 0) {
00361             macb->ncr &= ~AVR32_MACB_NCR_MPE_MASK;
00362             return -1;
00363         }
00364 
00365         /*
00366          * Read link partner abilities and configure EMAC.
00367          */
00368         phyval = phy_inw(macb, NIC_PHY_ANLPAR);
00369         if (phyval & NIC_PHY_ANEG_TX_FDX) {
00370             /* 100Mb full duplex. */
00371             macb->ncfgr |= AVR32_MACB_SPD_MASK | AVR32_MACB_FD_MASK;
00372         } else if (phyval & NIC_PHY_ANEG_TX_HDX) {
00373             /* 100Mb half duplex. */
00374             macb->ncfgr = (macb->ncfgr & ~AVR32_MACB_FD_MASK) | AVR32_MACB_SPD_MASK;
00375         } else if (phyval & NIC_PHY_ANEG_10_FDX) {
00376             /* 10Mb full duplex. */
00377             macb->ncfgr = (macb->ncfgr & ~AVR32_MACB_SPD_MASK) | AVR32_MACB_FD_MASK;
00378         } else {
00379             /* 10Mb half duplex. */
00380             macb->ncfgr &= ~(AVR32_MACB_SPD_MASK | AVR32_MACB_FD_MASK);
00381         }
00382     }
00383     return 0;
00384 }
00385 
00391 static int EmacReset(NUTDEVICE * dev)
00392 {
00393     volatile avr32_macb_t *macb = (avr32_macb_t *) dev->dev_base;
00394     const uint32_t hclk_hz = NutArchClockGet(NUT_HWCLK_PERIPHERAL_B);
00395 
00396     /* Disable TX and RX */
00397     macb->ncr = 0;
00398 
00399     /* Clear status registers */
00400     macb->NCR.clrstat = 1;
00401 
00402     /* Clear all status flags */
00403     macb->tsr = ~0UL;
00404     macb->rsr = ~0UL;
00405 
00406     /* Disable all interrupts */
00407     NutEnterCritical();
00408     macb->idr = ~0UL;
00409     macb->isr;
00410     NutExitCritical();
00411 
00412 #if defined(PHY_MODE_RMII)
00413     macb->usrio &= ~AVR32_MACB_RMII_MASK;
00414 #else
00415     macb->usrio |= AVR32_MACB_RMII_MASK;
00416 #endif
00417 
00418     /* Set MII management clock divider */
00419     if (hclk_hz <= 20000000)
00420         macb->ncfgr |= (AVR32_MACB_NCFGR_CLK_DIV8 << AVR32_MACB_NCFGR_CLK_OFFSET);
00421     else if (hclk_hz <= 40000000)
00422         macb->ncfgr |= (AVR32_MACB_NCFGR_CLK_DIV16 << AVR32_MACB_NCFGR_CLK_OFFSET);
00423     else if (hclk_hz <= 80000000)
00424         macb->ncfgr |= (AVR32_MACB_NCFGR_CLK_DIV32 << AVR32_MACB_NCFGR_CLK_OFFSET);
00425     else
00426         macb->ncfgr |= (AVR32_MACB_NCFGR_CLK_DIV64 << AVR32_MACB_NCFGR_CLK_OFFSET);
00427 
00428     /* Wait for PHY ready. */
00429     NutDelay(255);
00430 
00431     return probePhy(macb);
00432 }
00433 
00434 /*
00435 * NIC interrupt entry.
00436 */
00437 static void EmacInterrupt(void *arg)
00438 {
00439     unsigned int isr;
00440     unsigned int event;
00441     NUTDEVICE *dev = (NUTDEVICE *) arg;
00442     volatile avr32_macb_t *macb = (avr32_macb_t *) dev->dev_base;
00443     EMACINFO *ni = dev->dev_dcb;
00444 
00445     /* Read interrupt status and disable interrupts. */
00446     isr = macb->isr;
00447     event = macb->rsr;
00448 
00449     /* Receiver interrupt. */
00450     if ((isr & AVR32_MACB_IMR_RCOMP_MASK) || (event & AVR32_MACB_REC_MASK)) {
00451         macb->rsr = AVR32_MACB_REC_MASK;        // Clear
00452         macb->rsr;              // Read to force the previous write
00453         macb->idr = AVR32_MACB_IDR_RCOMP_MASK | AVR32_MACB_IDR_ROVR_MASK | AVR32_MACB_IDR_RXUBR_MASK;
00454         NutEventPostFromIrq(&ni->ni_rx_rdy);
00455     }
00456 
00457     /* Transmitter interrupt. */
00458     if (isr & AVR32_MACB_IMR_TCOMP_MASK) {
00459         macb->tsr = AVR32_MACB_TSR_COMP_MASK;   // Clear
00460         macb->tsr;              // Read to force the previous write
00461 
00462         NutEventPostFromIrq(&ni->ni_tx_rdy);
00463     }
00464 }
00465 
00471 static int EmacGetPacket(EMACINFO * ni, NETBUF ** nbp)
00472 {
00473     int rc = -1;
00474     unsigned int fbc = 0;
00475     unsigned int i;
00476     *nbp = NULL;
00477 
00478     /*
00479      * Search the next frame start. Release any fragment.
00480      */
00481     while ((rxBufTab[rxBufIdx].addr & RXBUF_OWNERSHIP) != 0 && (rxBufTab[rxBufIdx].status & RXS_SOF) == 0) {
00482         rxBufTab[rxBufIdx].addr &= ~(RXBUF_OWNERSHIP);
00483         rxBufIdx++;
00484         if (rxBufIdx >= EMAC_RX_BUFFERS) {
00485             rxBufIdx = 0;
00486         }
00487     }
00488 
00489     /*
00490      * Determine the size of the next frame.
00491      */
00492     i = rxBufIdx;
00493     while (rxBufTab[i].addr & RXBUF_OWNERSHIP) {
00494         if (i != rxBufIdx && (rxBufTab[i].status & RXS_SOF) != 0) {
00495             do {
00496                 rxBufTab[rxBufIdx].addr &= ~(RXBUF_OWNERSHIP);
00497                 rxBufIdx++;
00498                 if (rxBufIdx >= EMAC_RX_BUFFERS) {
00499                     rxBufIdx = 0;
00500                 }
00501             } while ((rxBufTab[rxBufIdx].addr & RXBUF_OWNERSHIP) != 0 && (rxBufTab[rxBufIdx].status & RXS_SOF) == 0);
00502             break;
00503         }
00504         if ((fbc = rxBufTab[i].status & RXS_LENGTH_FRAME) != 0) {
00505             break;
00506         }
00507         i++;
00508         if (i >= EMAC_RX_BUFFERS) {
00509             i = 0;
00510         }
00511     }
00512 
00513     if (fbc) {
00514         /*
00515          * Receiving long packets is unexpected. Let's declare the
00516          * chip insane. Short packets will be handled by the caller.
00517          */
00518 //              if (fbc > 1536) {
00519 //                      ni->ni_insane = 1;
00520 //              } else 
00521         {
00522             *nbp = NutNetBufAlloc(0, NBAF_DATALINK, (uint16_t) fbc);
00523             if (*nbp != NULL) {
00524                 uint8_t *bp = (uint8_t *) (*nbp)->nb_dl.vp;
00525                 unsigned int len;
00526 
00527                 while (fbc) {
00528                     if (fbc > EMAC_RX_BUFSIZ) {
00529                         len = EMAC_RX_BUFSIZ;
00530                     } else {
00531                         len = fbc;
00532                     }
00533                     memcpy(bp, (void *) (rxBufTab[rxBufIdx].addr & RXBUF_ADDRMASK), len);
00534                     rxBufTab[rxBufIdx].addr &= ~RXBUF_OWNERSHIP;
00535                     rxBufIdx++;
00536                     if (rxBufIdx >= EMAC_RX_BUFFERS) {
00537                         rxBufIdx = 0;
00538                     }
00539                     fbc -= len;
00540                     bp += len;
00541                 }
00542                 rc = 0;
00543             }
00544         }
00545     }
00546     return rc;
00547 }
00548 
00563 static int EmacPutPacket(int bufnum, NUTDEVICE * dev, NETBUF * nb)
00564 {
00565     volatile avr32_macb_t *macb = (avr32_macb_t *) dev->dev_base;
00566     int rc = -1;
00567     unsigned int sz;
00568     uint8_t *buf;
00569     EMACINFO *ni = dev->dev_dcb;
00570 
00571 
00572     /*
00573      * Calculate the number of bytes to be send. Do not send packets
00574      * larger than the Ethernet maximum transfer unit. The MTU
00575      * consist of 1500 data bytes plus the 14 byte Ethernet header
00576      * plus 4 bytes CRC. We check the data bytes only.
00577      */
00578     if ((sz = nb->nb_nw.sz + nb->nb_tp.sz + nb->nb_ap.sz) > ETHERMTU) {
00579         return -1;
00580     }
00581     sz += nb->nb_dl.sz;
00582     if (sz & 1) {
00583         sz++;
00584     }
00585 
00586     /* Disable EMAC interrupts. */
00587     NutIrqDisable(&sig_MACB);
00588 
00589     /* TODO: Check for link. */
00590     if (ni->ni_insane == 0) {
00591         buf = (uint8_t *) txBufTab[bufnum].addr;
00592         memcpy(buf, nb->nb_dl.vp, nb->nb_dl.sz);
00593         buf += nb->nb_dl.sz;
00594         memcpy(buf, nb->nb_nw.vp, nb->nb_nw.sz);
00595         buf += nb->nb_nw.sz;
00596         memcpy(buf, nb->nb_tp.vp, nb->nb_tp.sz);
00597         buf += nb->nb_tp.sz;
00598         memcpy(buf, nb->nb_ap.vp, nb->nb_ap.sz);
00599         sz |= TXS_LAST_BUFF;
00600         if (bufnum) {
00601             sz |= TXS_WRAP;
00602         }
00603         txBufTab[bufnum].status = sz;
00604         macb->ncr |= AVR32_MACB_TSTART_MASK;
00605         rc = 0;
00606 #ifdef NUT_PERFMON
00607         ni->ni_tx_packets++;
00608 #endif
00609     }
00610 
00611     /* Enable EMAC interrupts. */
00612     NutIrqEnable(&sig_MACB);
00613 
00614     return rc;
00615 }
00616 
00617 
00625 static int EmacStart(volatile avr32_macb_t * macb, CONST uint8_t * mac)
00626 {
00627     unsigned int i;
00628 
00629     /* Set local MAC address. */
00630     // Must be written SA1L then SA1H.
00631     macb->sa1b = (mac[3] << 24) | (mac[2] << 16) | (mac[1] << 8) | mac[0];
00632     macb->sa1t = (mac[5] << 8) | mac[4];
00633 
00634     /* Initialize receive buffer descriptors. */
00635     for (i = 0; i < EMAC_RX_BUFFERS - 1; i++) {
00636         rxBufTab[i].addr = (unsigned int) (&rxBuf[i * EMAC_RX_BUFSIZ]) & RXBUF_ADDRMASK;
00637     }
00638     rxBufTab[i].addr = ((unsigned int) (&rxBuf[i * EMAC_RX_BUFSIZ]) & RXBUF_ADDRMASK) | RXBUF_WRAP;
00639     macb->rbqp = (unsigned long) rxBufTab;
00640 
00641     /* Initialize transmit buffer descriptors. */
00642     for (i = 0; i < EMAC_TX_BUFFERS - 1; i++) {
00643         txBufTab[i].addr = (unsigned int) (&txBuf[i * EMAC_RX_BUFSIZ]);
00644         txBufTab[i].status = TXS_USED;
00645     }
00646     txBufTab[i].addr = (unsigned int) (&txBuf[i * EMAC_RX_BUFSIZ]);
00647     txBufTab[i].status = TXS_USED | TXS_WRAP;
00648     macb->tbqp = (unsigned long) txBufTab;
00649 
00650     /* Clear receiver status. */
00651     macb->rsr = AVR32_MACB_RSR_BNA_MASK | AVR32_MACB_RSR_OVR_MASK | AVR32_MACB_RSR_REC_MASK;
00652     macb->rsr;
00653 
00654     /* Discard FCS. */
00655     macb->ncfgr |= AVR32_MACB_NCFGR_DRFCS_MASK;
00656 
00657     /* Enable receiver, transmitter and statistics. */
00658     macb->ncr |= AVR32_MACB_NCR_RE_MASK | AVR32_MACB_NCR_TE_MASK;
00659 
00660     return 0;
00661 }
00662 
00667 THREAD(EmacRxThread, arg)
00668 {
00669     NUTDEVICE *dev = (NUTDEVICE *) arg;
00670     IFNET *ifn;
00671     EMACINFO *ni;
00672     NETBUF *nb;
00673     volatile avr32_macb_t *macb = (avr32_macb_t *) dev->dev_base;
00674 
00675     ifn = (IFNET *) dev->dev_icb;
00676     ni = (EMACINFO *) dev->dev_dcb;
00677 
00678     /*
00679      * This is a temporary hack. Due to a change in initialization,
00680      * we may not have got a MAC address yet. Wait until a valid one
00681      * has been set.
00682      */
00683     while (!ETHER_IS_UNICAST(ifn->if_mac)) {
00684         NutSleep(10);
00685     }
00686 
00687     /*
00688      * Do not continue unless we managed to start the NIC. We are
00689      * trapped here if the Ethernet link cannot be established.
00690      * This happens, for example, if no Ethernet cable is plugged
00691      * in.
00692      */
00693     while (EmacStart(macb, ifn->if_mac)) {
00694         EmacReset(dev);
00695         NutSleep(1000);
00696     }
00697 
00698     /* Initialize the access mutex. */
00699     NutEventPost(&ni->ni_mutex);
00700 
00701     /* Run at high priority. */
00702     NutThreadSetPriority(9);
00703 
00704     /* Enable receive and transmit interrupts. */
00705     macb->ier = AVR32_MACB_IER_ROVR_MASK | AVR32_MACB_IER_TCOMP_MASK | AVR32_MACB_IER_TUND_MASK |
00706         AVR32_MACB_IER_RXUBR_MASK | AVR32_MACB_IER_RCOMP_MASK;
00707     NutIrqEnable(&sig_MACB);
00708 
00709     for (;;) {
00710         /*
00711          * Wait for the arrival of new packets or poll the receiver every
00712          * 200 milliseconds. This short timeout helps a bit to deal with
00713          * the SAM9260 Ethernet problem.
00714          */
00715         NutEventWait(&ni->ni_rx_rdy, 200);
00716 
00717         /*
00718          * Fetch all packets from the NIC's internal buffer and pass
00719          * them to the registered handler.
00720          */
00721         while (EmacGetPacket(ni, &nb) == 0) {
00722             /* Discard short packets. */
00723             if (nb->nb_dl.sz < 60) {
00724                 NutNetBufFree(nb);
00725             } else {
00726                 (*ifn->if_recv) (dev, nb);
00727             }
00728         }
00729         macb->ier = AVR32_MACB_IER_ROVR_MASK | AVR32_MACB_IER_RXUBR_MASK | AVR32_MACB_IER_RCOMP_MASK;
00730 
00731         /* We got a weird chip, try to restart it. */
00732         while (ni->ni_insane) {
00733             EmacReset(dev);
00734             if (EmacStart(macb, ifn->if_mac) == 0) {
00735                 ni->ni_insane = 0;
00736                 ni->ni_tx_queued = 0;
00737                 ni->ni_tx_quelen = 0;
00738                 NutIrqEnable(&sig_MACB);
00739             } else {
00740                 NutSleep(1000);
00741             }
00742         }
00743     }
00744 }
00745 
00756 int EmacOutput(NUTDEVICE * dev, NETBUF * nb)
00757 {
00758     volatile avr32_macb_t *macb = (avr32_macb_t *) dev->dev_base;
00759     static uint32_t mx_wait = 5000;
00760     int rc = -1;
00761     EMACINFO *ni = (EMACINFO *) dev->dev_dcb;
00762 
00763     /*
00764      * After initialization we are waiting for a long time to give
00765      * the PHY a chance to establish an Ethernet link.
00766      */
00767     while (rc) {
00768         if (ni->ni_insane) {
00769             break;
00770         }
00771         if (NutEventWait(&ni->ni_mutex, mx_wait)) {
00772             break;
00773         }
00774 
00775         /* Check for packet queue space. */
00776         if ((txBufTab[txBufIdx].status & TXS_USED) == 0) {
00777             if (NutEventWait(&ni->ni_tx_rdy, 500) && (txBufTab[txBufIdx].status & TXS_USED) == 0) {
00778                 /* No queue space. Release the lock and give up. */
00779                 txBufTab[txBufIdx].status |= TXS_USED;
00780                 txBufIdx++;
00781                 txBufIdx &= 1;
00782                 NutEventPost(&ni->ni_mutex);
00783                 break;
00784             }
00785         } else {
00786             if (macb->tsr & AVR32_MACB_TSR_UND_MASK) {
00787                 txBufIdx = 0;
00788                 macb->tsr = AVR32_MACB_TSR_UND_MASK;
00789             }
00790             if (macb->tsr & AVR32_MACB_TSR_COMP_MASK) {
00791                 macb->tsr = AVR32_MACB_TSR_COMP_MASK;
00792             }
00793 
00794             if ((rc = EmacPutPacket(txBufIdx, dev, nb)) == 0) {
00795                 txBufIdx++;
00796                 txBufIdx &= 1;
00797             }
00798         }
00799         NutEventPost(&ni->ni_mutex);
00800     }
00801 
00802     /*
00803      * Probably no Ethernet link. Significantly reduce the waiting
00804      * time, so following transmission will soon return an error.
00805      */
00806     if (rc) {
00807         mx_wait = 500;
00808     } else {
00809         /* Ethernet works. Set a long waiting time in case we
00810            temporarily lose the link next time. */
00811         mx_wait = 5000;
00812     }
00813     return rc;
00814 }
00815 
00825 int EmacInit(NUTDEVICE * dev)
00826 {
00827     EMACINFO *ni = (EMACINFO *) dev->dev_dcb;
00828 
00829     /* Reserve Pins with the GPIO Controller */
00830 #if !defined(PHY_MODE_RMII)
00831     gpio_enable_module_pin(AVR32_MACB_CRS_0_PIN, AVR32_MACB_CRS_0_FUNCTION);
00832     gpio_enable_module_pin(AVR32_MACB_COL_0_PIN, AVR32_MACB_COL_0_FUNCTION);
00833     gpio_enable_module_pin(AVR32_MACB_RX_CLK_0_PIN, AVR32_MACB_RX_CLK_0_FUNCTION);
00834     gpio_enable_module_pin(AVR32_MACB_TX_ER_0_PIN, AVR32_MACB_TX_ER_0_FUNCTION);
00835 #endif
00836     gpio_enable_module_pin(AVR32_MACB_MDC_0_PIN, AVR32_MACB_MDC_0_FUNCTION);
00837     gpio_enable_module_pin(AVR32_MACB_MDIO_0_PIN, AVR32_MACB_MDIO_0_FUNCTION);
00838     gpio_enable_module_pin(AVR32_MACB_RXD_0_PIN, AVR32_MACB_RXD_0_FUNCTION);
00839     gpio_enable_module_pin(AVR32_MACB_TXD_0_PIN, AVR32_MACB_TXD_0_FUNCTION);
00840     gpio_enable_module_pin(AVR32_MACB_RXD_1_PIN, AVR32_MACB_RXD_1_FUNCTION);
00841     gpio_enable_module_pin(AVR32_MACB_TXD_1_PIN, AVR32_MACB_TXD_1_FUNCTION);
00842     gpio_enable_module_pin(AVR32_MACB_TX_EN_0_PIN, AVR32_MACB_TX_EN_0_FUNCTION);
00843     gpio_enable_module_pin(AVR32_MACB_RX_ER_0_PIN, AVR32_MACB_RX_ER_0_FUNCTION);
00844     gpio_enable_module_pin(AVR32_MACB_RX_DV_0_PIN, AVR32_MACB_RX_DV_0_FUNCTION);
00845     gpio_enable_module_pin(AVR32_MACB_TX_CLK_0_PIN, AVR32_MACB_TX_CLK_0_FUNCTION);
00846 
00847     /* Reset the controller. */
00848     if (EmacReset(dev)) {
00849         return -1;
00850     }
00851 
00852     /* Clear EMACINFO structure. */
00853     memset(ni, 0, sizeof(EMACINFO));
00854 
00855     /* Register interrupt handler. */
00856     if (NutRegisterIrqHandler(&sig_MACB, EmacInterrupt, dev)) {
00857         return -1;
00858     }
00859 
00860     /* Start the receiver thread. */
00861     if (NutThreadCreate("emacrx", EmacRxThread, dev, NUT_THREAD_NICRXSTACK) == NULL) {
00862         return -1;
00863     }
00864     return 0;
00865 }
00866 
00867 static EMACINFO dcb_eth0;
00868 
00874 static IFNET ifn_eth0 = {
00875     IFT_ETHER,                  
00876     0,                          
00877     {0, 0, 0, 0, 0, 0},         
00878     0,                          
00879     0,                          
00880     0,                          
00881     ETHERMTU,                   
00882     0,                          
00883     0,                          
00884     0,                          
00885     NutEtherInput,              
00886     EmacOutput,                 
00887     NutEtherOutput              
00888 };
00889 
00899 NUTDEVICE devAvr32macb = {
00900     0,                          
00901     {'e', 't', 'h', '0', 0, 0, 0, 0, 0},        
00902     IFTYP_NET,                  
00903     AVR32_MACB_ADDRESS,         
00904     0,                          
00905     &ifn_eth0,                  
00906     &dcb_eth0,                  
00907     EmacInit,                   
00908     0,                          
00909     0,                          
00910     0,                          
00911 #ifdef __HARVARD_ARCH__
00912     0,                          
00913 #endif
00914     0,                          
00915     0,                          
00916     0                           
00917 };
00918