This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

how to configure EMAC?

Other Parts Discussed in Thread: AM3874, AM3871, DP83620

Hi,

I'd like to know where & how EMAC should be configured.

I'm now using Am3874/DM8148 and want to use ethernet port 1 as 100M speed.

I guess it will include Ethernet PHY setting.

I hope there will be example source code for it.

 

Thanks.

BR,

Devin

  • Devin

    Are you looking driver for linux, some other os or standalone non os platform?

    Regards
    Mugunthan V N

  • Hi Muguthan,

    Any reference source will be good.

    Current issue is that RX has some issue. TX is no problem.

    When RX buffer is configured as just 1, first frame is received properly,. but  it isn't received any frame after that.

    When RX buffer is 10, data are written up to RX[9], but data aren't written on RX[0] anymore.

    What will be problem?

    Thanks and BR,

    Devin

    ------------ below are current source code--------------------

    //#include "lib.h"
    #include "Miiphy.h"
    //#include "Ethernet_comm.h"
    #include "Emac.h"
    #include "EtherCAT_master.h"
    #include "Net.h"
    #include "M32e_main.h"
    //#include "iodefine.h"

    //type_HW_CFG LAN_HW_CFG_buf;
    unsigned long ByteTest;
    unsigned long RX_temp;


    /* EMAC Addresses */
    static volatile emac_regs *adap_emac = (emac_regs *)EMAC_BASE_ADDR;
    static volatile ewrap_regs *adap_ewrap = (ewrap_regs *)EMAC_WRAPPER_BASE_ADDR;
    static volatile mdio_regs *adap_mdio = (mdio_regs *)EMAC_MDIO_BASE_ADDR;

    /* EMAC descriptors */
    volatile emac_desc   *emac_rx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_RX_DESC_BASE);
    static volatile emac_desc *emac_tx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_TX_DESC_BASE);
    volatile emac_desc   *emac_rx_active_head = 0;
    volatile emac_desc   *emac_rx_active_tail = 0;
    int       emac_rx_queue_active = 0;

    /* Receive packet buffers */
    //static unsigned char  emac_rx_buffers[EMAC_MAX_RX_BUFFERS * (EMAC_MAX_ETHERNET_PKT_SIZE + EMAC_PKT_ALIGN)];

    /* PHY address for a discovered PHY (0xff - not found) */
    static volatile unsigned char active_phy_addr = 0xff;    // Check Hardware Wiring!!!

    static unsigned char  ethernet_mac_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };

    VOID udelay(UINT);
    int ethernet_send_packet (volatile void *packet, int length);
    int ethernet_rcv_packet (void);
    int emac_initialize(void);
    static int get_link_speed(int phy_addr);

    //------------------------------------------------------------------------------------------------------
    //------------------------------------------------------------------------------------------------------
    //------------ AM3871 EMAC Coding
    //------------------------------------------------------------------------------------------------------
    //------------------------------------------------------------------------------------------------------
    /* Read a PHY register via MDIO inteface. Returns 1 on success, 0 otherwise */
    int ethernet_phy_read(unsigned char phy_addr, unsigned char reg_num, unsigned short *data)
    {
     int tmp;

     while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO)
      ;

     writel(MDIO_USERACCESS0_GO |
            MDIO_USERACCESS0_WRITE_READ |
            ((reg_num & 0x1f) << 21) |
            ((phy_addr & 0x1f) << 16),
            &adap_mdio->USERACCESS0);

     /* Wait for command to complete */
     while ((tmp = readl(&adap_mdio->USERACCESS0)) & MDIO_USERACCESS0_GO)
      ;

     if (tmp & MDIO_USERACCESS0_ACK) {
      *data = tmp & 0xffff;
      return(1);
     }

     *data = 0xffff;
     return(0);
    }

    /* Write to a PHY register via MDIO inteface. Blocks until operation is complete. */
    int ethernet_phy_write(unsigned char phy_addr, unsigned char reg_num, unsigned short data)
    {

     while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO)
      ;

     writel(MDIO_USERACCESS0_GO |
            MDIO_USERACCESS0_WRITE_WRITE |
            ((reg_num & 0x1f) << 21) |
            ((phy_addr & 0x1f) << 16) |
            (data & 0xffff),
            &adap_mdio->USERACCESS0);

     /* Wait for command to complete */
     while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO)
      ;

     return(1);
    }
    /* PHY functions for a generic PHY */
    static int init_phy(int phy_addr)
    {
     int ret = 1;
     unsigned short val;
     unsigned short tmp;

     if (!ethernet_phy_read(phy_addr, PHY_BMCR, &tmp))
      return(0);
      
     val = tmp | PHY_BMCR_RESET;      // Phy Reset
     ethernet_phy_write(phy_addr, PHY_BMCR, val);

     do
     {
      if (!ethernet_phy_read(phy_addr, PHY_BMCR, &tmp))
       return(0);
     }while(tmp & PHY_BMCR_RESET == 0);
     
     if (get_link_speed(phy_addr)) {
      /* Try another time */
      ret = get_link_speed(phy_addr);
     }

     return(ret);
    }

    static int phy_connected(int phy_addr)
    {
     unsigned short dummy;
     unsigned short dummy2;

     ethernet_phy_read(phy_addr, PHY_PHYIDR1, &dummy);
     ethernet_phy_read(phy_addr, PHY_PHYIDR2, &dummy2);
     
     return(1);
    }

    static int auto_negotiate(int phy_addr)
    {
     unsigned short tmp;
     unsigned short val;
     unsigned int cntr = 0;
     unsigned int cnt = 0;


     if (!ethernet_phy_read(phy_addr, PHY_BMCR, &tmp))
      return(0);

     val = tmp | PHY_BMCR_DPLX | PHY_BMCR_AUTON | PHY_BMCR_100_MBPS;  // Full-Duplex, Auto-Negotiation enable, 100MBps
     ethernet_phy_write(phy_addr, PHY_BMCR, val);
     ethernet_phy_read(phy_addr, PHY_BMCR, &val);

     /* advertise 100 Full Duplex */
     ethernet_phy_read(phy_addr,PHY_ANAR, &val);
     val |= (PHY_ANLPAR_10 | PHY_ANLPAR_10FD | PHY_ANLPAR_TX | PHY_ANLPAR_TXFD); // 10BASE-T, 10BASE-T Full Duplex, 100BASE-T, 100BASE-T Full Duplex Support
     ethernet_phy_write(phy_addr,PHY_ANAR, val);
     ethernet_phy_read(phy_addr,PHY_ANAR, &val);

     /* PHY LED configuration */
     ethernet_phy_read(phy_addr,PHY_PHYCTRL, &val);
     val = val & PHY_PHYCR_LED_00;
     ethernet_phy_write(phy_addr,PHY_PHYCTRL, val);

     ethernet_phy_read(phy_addr, PHY_BMCR, &tmp);

     if (!ethernet_phy_read(phy_addr, PHY_RBR, &tmp))
      return(0);

     /* Restart Auto_negotiation  */
    // tmp |= PHY_BMCR_RST_NEG;
    // ethernet_phy_write(phy_addr, PHY_BMCR, tmp);

     /*check AutoNegotiate complete - it can take upto 3 secs*/
     do
     {
    //  udelay(40000);   // 40ms Delay
      for(cnt=0;cnt < 40; cnt++)
       NU_Relinquish();
       
      cntr++;

      if (ethernet_phy_read(phy_addr, PHY_BMSR, &tmp))
      {
       if(tmp & PHY_BMSR_AUTN_COMP)
        break;
      }

     }while(cntr < 2500000);

     if (!ethernet_phy_read(phy_addr, PHY_BMSR, &tmp))
      return(0);

     g_adwDebug[1] = tmp;

     if (!(tmp & PHY_BMSR_AUTN_COMP))
      return(0);

     ethernet_phy_read(phy_addr,PHY_ANLPAR, &val);
     g_adwDebug[2] = val;
     ethernet_phy_read(phy_addr,PHY_ANER, &val);
     g_adwDebug[3]= val;
     ethernet_phy_read(phy_addr,PHY_PHYSTS, &val);
     g_adwDebug[4] = val;
     ethernet_phy_read(phy_addr,PHY_RBR, &val);
     g_adwDebug[5] = val;
     ethernet_phy_read(phy_addr,PHY_PHYCTRL, &val);
     g_adwDebug[6] = val;
     ethernet_phy_read(phy_addr,PHY_PHYCTRL2, &val);
     g_adwDebug[7] = val;

     return(get_link_speed(phy_addr));
    }


    static int get_link_speed(int phy_addr)
    {
     unsigned short tmp;

     if (ethernet_phy_read(phy_addr, PHY_BMSR, &tmp) && (tmp & 0x04))
      return(1);

     return(0);
    }


    static void ethernet_mdio_enable(void)
    {
     unsigned int clkdiv;

     clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;

     writel((clkdiv & 0xff) |
            MDIO_CONTROL_ENABLE |
            MDIO_CONTROL_FAULT |
            MDIO_CONTROL_FAULT_ENABLE,
            &adap_mdio->CONTROL);

     while (readl(&adap_mdio->CONTROL) & MDIO_CONTROL_IDLE)
      ;
    }

    /* Ethernet device open */
    //static int ethernet_open(struct eth_device *dev, bd_t *bis)
    static int ethernet_open()
    {
     dv_reg_p   addr;
     unsigned int  clkdiv, cnt;
     volatile emac_desc *rx_desc;
     unsigned long  mac_hi;
     unsigned long  mac_lo;
        unsigned int  mac_control = 0;
        unsigned int   val;


     /* Reset EMAC module and disable interrupts in wrapper */
     writel(1, &adap_emac->CPSWSWRESET);    // CPGMAC_SL1
     while (readl(&adap_emac->CPSWSWRESET) != 0)
     
     writel(1, &adap_emac->SL1SOFTRST);    // CPGMAC_SL1
     while (readl(&adap_emac->SL1SOFTRST) != 0)  
     
     writel(1, &adap_emac->SL2SOFTRST);    // CPGMAC_SL2
     while (readl(&adap_emac->SL2SOFTRST) != 0)  
      ;
     writel(1, &adap_emac->SOFTRESET);    // CPDMA
     while (readl(&adap_emac->SOFTRESET) != 0)
      ;
     writel(1, &adap_ewrap->softrst);    // Subsystem
     while (readl(&adap_ewrap->softrst) != 0)
      ;

     rx_desc = emac_rx_desc;

     writel(1, &adap_emac->TXCONTROL);   // TX Enable
     writel(1, &adap_emac->RXCONTROL);   // RX Enable

     /* Set ALE Control Enable/Bypass  */
     /* ALE Port control Forward */
     val = adap_emac->ALECTRL;
     val = val | EMAC_ALE_BYPASS | EMAC_ALE_ENABLE;
     writel(val, &adap_emac->ALECTRL);

     val = adap_emac->ALEPORTCTRL0;
     val = val | EMAC_ALE_PORT_FORWARD;
     writel(val, &adap_emac->ALEPORTCTRL0);

     val = adap_emac->ALEPORTCTRL1;
     val = val | EMAC_ALE_PORT_FORWARD;
     writel(val, &adap_emac->ALEPORTCTRL1);

     val = adap_emac->ALEPORTCTRL2;
     val = val | EMAC_ALE_PORT_FORWARD;
     writel(val, &adap_emac->ALEPORTCTRL2);

     /* Set MAC Addresses & Init multicast Hash to 0 (disable any multicast receive) */
     /* Using channel 0 only - other channels are disabled */
     mac_hi = (o_EC_SourceAddress2.b[3] << 24) |
       (o_EC_SourceAddress2.b[2] << 16) |
       (o_EC_SourceAddress2.b[1] << 8) |
       (o_EC_SourceAddress2.b[0]);
     mac_lo = (o_EC_SourceAddress2.b[5] << 8) |
       (o_EC_SourceAddress2.b[4]);

     writel(mac_hi, &adap_emac->SL2SAHI);
     writel(mac_lo, &adap_emac->SL2SALO);

     /* Set DMA 8 TX / 8 RX Head pointers to 0 */
     addr = &adap_emac->TX0HDP;
     for(cnt = 0; cnt < 16; cnt++)
      writel(0, addr++);

     addr = &adap_emac->RX0HDP;
     for(cnt = 0; cnt < 16; cnt++)
      writel(0, addr++);

     /* Statistics Port Enable */
     writel(7, &adap_emac->CPSWSTATPORTEN);   // Port0, Port1, Port2 Enable

     /* Clear Statistics (do this before setting MacControl register) */
     addr = &adap_emac->RXGOODFRAMES;
     for(cnt = 0; cnt < EMAC_NUM_STATS; cnt++)
      writel(0, addr++);

     /* Create RX queue and set receive process in place */
     emac_rx_active_head = emac_rx_desc;
     for (cnt = 0; cnt < EMAC_MAX_RX_BUFFERS; cnt++) {
      rx_desc->next = BD_TO_HW((unsigned int)(rx_desc + 1));
    //  rx_desc->next = 0;
      rx_desc->buffer = (UINT8 *)&acRX_Frame_Data[cnt][0];
      rx_desc->buff_off_len = EMAC_MAX_ETHERNET_PKT_SIZE;
      rx_desc->pkt_flag_len = EMAC_CPPI_OWNERSHIP_BIT;
      rx_desc++;
     }

     /* Finalize the rx desc list */
     rx_desc--;
     rx_desc->next = 0;
     emac_rx_active_tail = rx_desc;
     emac_rx_queue_active = 1;

     /* Enable TX/RX */
     writel(EMAC_MAX_ETHERNET_PKT_SIZE, &adap_emac->SL2RXMAXLEN);
     writel(0, &adap_emac->RXBUFFEROFFSET);

     /* Init MDIO & get link state */
     clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
     writel((clkdiv & 0xff) | MDIO_CONTROL_ENABLE | MDIO_CONTROL_FAULT,
            &adap_mdio->CONTROL);

     /* We need to wait for MDIO to start */
    // udelay(1000);    // 1ms Delay
     NU_Relinquish();

    // if (!phy.auto_negotiate(active_phy_addr))
    //  return(0);

     mac_control |= EMAC_MACCONTROL_MIIEN_ENABLE;
     mac_control |= EMAC_MACCONTROL_FULLDUPLEX_ENABLE;
     mac_control |= EMAC_MACCONTROL_RMIISPEED_100;
     mac_control |= EMAC_MACCONTROL_RMIISPEED_100_2;

     writel(mac_control, &adap_emac->SL2MACCTRL);

     /* Start receive process */
     writel((BD_TO_HW((unsigned int)emac_rx_desc)), &adap_emac->RX0HDP);

     return(1);
    }

    /* EMAC Channel Teardown */
    static void ethernet_ch_teardown(int ch)
    {
     dv_reg  dly = 0xff;
     dv_reg  cnt;

     if (ch == EMAC_CH_TX)
     {
      /* Init TX channel teardown */
      writel(1, &adap_emac->TXTEARDOWN);
      do
      {
       /*
        * Wait here for Tx teardown completion interrupt to
        * occur. Note: A task delay can be called here to pend
        * rather than occupying CPU cycles - anyway it has
        * been found that teardown takes very few cpu cycles
        * and does not affect functionality
        */
       dly--;
       udelay(1);  // 1us Delay
       if (dly == 0)
        break;
       cnt = readl(&adap_emac->TX0CP);
      } while (cnt != 0xfffffffc);
      writel(cnt, &adap_emac->TX0CP);
      writel(0, &adap_emac->TX0HDP);
     }
     else
     {
      /* Init RX channel teardown */
      writel(1, &adap_emac->RXTEARDOWN);
      do
      {
       /*
        * Wait here for Rx teardown completion interrupt to
        * occur. Note: A task delay can be called here to pend
        * rather than occupying CPU cycles - anyway it has
        * been found that teardown takes very few cpu cycles
        * and does not affect functionality
        */
       dly--;
       udelay(1);  // 1us Delay
       if (dly == 0)
        break;
       cnt = readl(&adap_emac->RX0CP);
      } while (cnt != 0xfffffffc);
      writel(cnt, &adap_emac->RX0CP);
      writel(0, &adap_emac->RX0HDP);
     }
    }

    /* Eth device close */
    //static void ethernet_close(struct eth_device *dev)
    static void ethernet_close()
    {
     ethernet_ch_teardown(EMAC_CH_TX); /* TX Channel teardown */
     ethernet_ch_teardown(EMAC_CH_RX); /* RX Channel teardown */

     /* Reset EMAC module and disable interrupts in wrapper */
     writel(1, &adap_emac->SOFTRESET);
     writel(1, &adap_ewrap->softrst);
    }

    /*
     * This function sends a single packet on the network and returns
     * positive number (number of bytes transmitted) or negative for error
     */
    //int ethernet_send_packet (volatile void *packet, int length)
    int ethernet_send_packet (volatile void *packet, int length)
    {
     int ret_status = -1;

     /* Return error if no link */
     if (!get_link_speed(active_phy_addr))
     {
      g_pS_MSTATUS->S_Com.S_Opr.bLinkupInfo = OFF;
      return (ret_status);
     }
     else
      g_pS_MSTATUS->S_Com.S_Opr.bLinkupInfo = ON;

     /* Check packet size and if < EMAC_MIN_ETHERNET_PKT_SIZE, pad it up */
     if (length < EMAC_MIN_ETHERNET_PKT_SIZE)
     {
      length = EMAC_MIN_ETHERNET_PKT_SIZE;
     }

     /* Populate the TX descriptor */
     emac_tx_desc->next = 0;
     emac_tx_desc->buffer = (unsigned char *) packet;
     emac_tx_desc->buff_off_len = (length & 0xffff);
     emac_tx_desc->pkt_flag_len = ((length & 0xffff) |
              EMAC_CPPI_SOP_BIT |
              EMAC_CPPI_OWNERSHIP_BIT |
              EMAC_CPPI_EOP_BIT | EMAC_CPPI_TP_EN | EMAC_CPPI_TP_PORT2);
     /* Send the packet */
     writel((BD_TO_HW((unsigned int) emac_tx_desc)), &adap_emac->TX0HDP);

     /* Wait for packet to complete or link down */
     while (1)
     {
      if (!get_link_speed(active_phy_addr))
      {
       ethernet_ch_teardown (EMAC_CH_TX);
       g_pS_MSTATUS->S_Com.S_Opr.bLinkupInfo = OFF;
       return (ret_status);
      }
      else
       g_pS_MSTATUS->S_Com.S_Opr.bLinkupInfo = ON;

      if (readl(&adap_emac->TXINTSTATRAW) & 0x01)
      {
       ret_status = length;
       break;
      }
     }
     return (ret_status);
    }

    /*
     * This function handles receipt of a packet from the network
     */
    int ethernet_rcv_packet ()
    {
     volatile emac_desc *rx_curr_desc;
     volatile emac_desc *curr_desc;
     volatile emac_desc *tail_desc;
     int status, length = -1;

     readl(&adap_emac->RXINTSTATRAW);
     rx_curr_desc = emac_rx_active_head;
     status = rx_curr_desc->pkt_flag_len;
     if ((rx_curr_desc) && ((status & EMAC_CPPI_OWNERSHIP_BIT) == 0)) {
      if (status & EMAC_CPPI_RX_ERROR_FRAME)
      {
      }
      else
      {
       length = rx_curr_desc->buff_off_len & 0xffff;
       MemCpy8((UINT8 *)&acRX_Frame_Data2, rx_curr_desc->buffer, length);
       MemSet8(rx_curr_desc->buffer, 0, length);
      }

      /* Ack received packet descriptor */
      writel(((unsigned int) rx_curr_desc), &adap_emac->RX0CP);
      curr_desc = rx_curr_desc;
      emac_rx_active_head = (volatile emac_desc *)(rx_curr_desc->next);

      if (status & EMAC_CPPI_EOQ_BIT)
      {
       if (emac_rx_active_head)
       {
        writel(((unsigned int) emac_rx_active_head), &adap_emac->RX0HDP);
       }
       else
       {
        emac_rx_queue_active = 0;
       }
      }

      /* Recycle RX descriptor */
      rx_curr_desc->buff_off_len = EMAC_MAX_ETHERNET_PKT_SIZE;
      rx_curr_desc->pkt_flag_len = EMAC_CPPI_OWNERSHIP_BIT;
      rx_curr_desc->next = 0;

      if (emac_rx_active_head == 0)
      {
       emac_rx_active_head = curr_desc;
       emac_rx_active_tail = curr_desc;
       if (emac_rx_queue_active != 0) {
        writel(((unsigned int) emac_rx_active_head), &adap_emac->RX0HDP);
        emac_rx_queue_active = 1;
       }
      } else {
       tail_desc = emac_rx_active_tail;
       emac_rx_active_tail = curr_desc;
       tail_desc->next = BD_TO_HW((unsigned int) curr_desc);
       status = tail_desc->pkt_flag_len;
       if (status & EMAC_CPPI_EOQ_BIT)
       {
        writel(((unsigned int) curr_desc), &adap_emac->RX0HDP);
        status &= ~EMAC_CPPI_EOQ_BIT;
        tail_desc->pkt_flag_len = status;
       }
      }
      return (length);
     }
     return (0);
    }

    /*
     * This function initializes the emac hardware. It does NOT initialize
     * EMAC modules power or pin multiplexors, that is done by board_init()
     * much earlier in bootup process. Returns 1 on success, 0 otherwise.
     */
    int emac_initialize(void)
    {
     unsigned int phy_id;
     int  i;
     unsigned int phy_act_state;
     
    // struct eth_device *dev;

    // dev = (struct eth_device *)malloc(sizeof *dev);

    // if (dev == 0)
    //  return -1;

    // MemSet8((UINT8 *)&dev, 0, sizeof *dev);

    // dev->iobase = 0;
    // dev->init = ethernet_open();
     ethernet_open();
    // ethernet_close();
    // dev->halt = ethernet_close();
    // dev->send = ethernet_send_packet;
    // dev->recv = ethernet_rcv_packet;

    // eth_register(dev);

     ethernet_mdio_enable();

     for (i = 0; i < 256; i++) {
      if (readl(&adap_mdio->ALIVE))
       break;
      udelay(10);    // 10us Delay
     }

     /* Find if a PHY is connected and get it's address */
     phy_act_state = readl(&adap_mdio->ALIVE) & EMAC_MDIO_PHY_MASK;
     if (phy_act_state == 0)
      return(0);

     for (i = 0; i < 32; i++) {
      if (phy_act_state & (1 << i)) {
       if (phy_act_state & ~(1 << i))
        return(0);  /* More than one PHY */
       else {
        active_phy_addr = i;
       }
      }
     }

     phy_id |= 0x00080017;    // DP83620

     init_phy(active_phy_addr);
     phy_connected(active_phy_addr);
     if(get_link_speed(active_phy_addr))
      g_pS_MSTATUS->S_Com.S_Opr.bLinkupInfo=ON;
     auto_negotiate(active_phy_addr);

     return(1);
    }

    VOID udelay(UINT time)   // time: us단위
    {
     UINT32 dwTemp, dwTemp1, dwTemp2, dwTemp3, dwTemp4;

     dwTemp4 = (UINT32)((double)ESAL_DP_TIMER_CLOCK_RATE/(double)ESAL_PR_TMR_OS_CLOCK_PRESCALE/(double)NU_PLUS_TICKS_PER_SEC);
     dwTemp = (time * dwTemp4) / 1000;
     dwTemp1 = ESAL_PR_TMR_OS_COUNT_READ();
     dwTemp3 = 0;
     do {
      dwTemp2 = ESAL_PR_TMR_OS_COUNT_READ();
      if(dwTemp2 >= dwTemp1)
      {
       dwTemp3 = dwTemp2 - dwTemp1;
      }
      else
      {
       dwTemp3 = dwTemp2 - dwTemp1 + dwTemp4;
      }
      if(dwTemp3 >= dwTemp)
       dwTemp = 0;
     } while (dwTemp!=0);
    }

  • Devin

    You can take a reference driver from u-boot cpsw driver from below git repo.
    http://arago-project.org/git/projects/?p=u-boot-omap3.git;a=shortlog;h=refs/heads/ti81xx-master
    Files:
    evm.c - http://arago-project.org/git/projects/?p=u-boot-omap3.git;a=blob;f=board/ti/ti8148/evm.c;h=3884e7cded6c3e31865762b67c551653cb35c475;hb=refs/heads/ti81xx-master
    CPSW driver - http://arago-project.org/git/projects/?p=u-boot-omap3.git;a=blob;f=drivers/net/cpsw.c;h=d43687d576c93ec062a9032164cbf289fed730f0;hb=refs/heads/ti81xx-master

    Can you check whether you are resubmitting the rx descriptor properly before DMA run out of rx descriptors.

    Regards
    Mugunthan V N