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.

Howto read the ethernet link speed on C6655

Hi

I need some help in reading the link speed on the ethernet connection on my custom C6655 board.

I have connected my custom board to my PC, and the PC detects that the connection is 1Gb/s, and I can send data to and from my DSP - so I know the connection is there. My problem is that I need to know the link status on the DSP, because in the final application there will be no PC.

I have tried using the emac_poll() function like this

static void UpdateLink(int *link_status)
{
  EMAC_LINK_INFO_T link_info;

  if (emac_poll(0, &link_info) == EMAC_DRV_RESULT_OK)
  {
    *link_status = link_info.link_status;
  }
}

But it allways returns 0 in link_info.link_status - even though I can see on the PC that the link is 1Gb/s

My application is using 

ndk_2_24_00_11

bios_6_41_00_26

pdk_C6657_1_1_2_6

When the network is opened I get the following output in the emulator

[C66xx_0] emac_init: core 0, port 0, total number of channels/MAC addresses: 1/1
MAC addresses configured for channel 0:
C4-ED-BA-9E-F6-BE
SGMII reset successful........
SGMII config successful........
emac_open core 0 port 0 successfully
Registration of the EMAC Successful, waiting for link up ..
Network Added: If-1:192.168.0.189
Service Status: Telnet : Enabled : : 000
Service Status: HTTP : Enabled : : 000

It should be noted that our custom board does not use the same PHY as the EVM, instead it uses the MARVELL Alaska 88E1512, but I do not know if that makes any difference.

Thanks

Jens

  • Hi Jens,
    Please refer to the following C6655's EMAC user guide.
    www.ti.com/.../spruhh1.pdf

    Refer to the chapter 7.6, MR_ADV_ABILITY register to know about the duplexity.
  • Thanks TS

    I can see that this could work, but I was hoping that there was a function in the PDK or NDK that could provide me with the information.

    I have chosen to use the information from the PHY which I can extract using MDIO like this

    void get_phy_status (Uint16* status)
    {
      SET_PHYPAGE(0);
      *status = readPhyReg(APP_PORT0_PHY_ADDR, 17);
    }
    
    typedef struct
    {
      Uint16 Jabber:1;    
      Uint16 Polarity:1;    
      Uint16 DTEPowerStatus:1;
      Uint16 GlobalLinkStatus:1;
      Uint16 CopperEnergyDetectStatus:1;
      Uint16 DownshiftStatus:1;
      Uint16 MDICrossoverStatus:1;
      Uint16 Reserved:1;
      Uint16 ReceivePauseEnabled:1;
      Uint16 TransmitPauseEnabled:1;
      Uint16 CopperLink:1;
      Uint16 SpeedAndDuplexResolved:1;
      Uint16 PageReceived:1;
      Uint16 Duplex:1;
      Uint16 Speed:2;
    } S_COPPER_SPECIFIC_STATUS_REGISTER1;
    
    typedef enum
    {
      E_No_Link,
      E_10Mbs_Half_Duplex,
      E_10Mbs_Full_Duplex,
      E_100Mbs_Half_Duplex,
      E_100Mbs_Full_Duplex,
      E_1000Mbs_Full_Duplex
    } LinkState;
    
    static void UpdateLink(void)
    {
        S_COPPER_SPECIFIC_STATUS_REGISTER1 status;
        EMAC_LINK_INFO_T        link_info;
    
    /* does not work 
        if (emac_poll(0, &link_info) == EMAC_DRV_RESULT_OK)
        {
          *_stEthernetTest.link_status = link_info.link_status;
        }
    */
        get_phy_status ((Uint16*)&status);
        if(status.SpeedAndDuplexResolved == 1)
        {
          switch(status.Speed)
          {
            case 2: /*1000Mbps*/
              *_stEthernetTest.link_status = E_1000Mbs_Full_Duplex; 
              break;
            case 1: /*100Mbps*/
              *_stEthernetTest.link_status = E_100Mbs_Half_Duplex + status.Duplex; 
              break;
            case 0: /*10Mbps*/
              *_stEthernetTest.link_status = E_10Mbs_Half_Duplex + status.Duplex;
              break;
            default:  
              *_stEthernetTest.link_status = E_No_Link;
          }
        }
        else
        {
          *_stEthernetTest.link_status = E_No_Link;
        }
    
    }  
    

    I am not sure this is the most optimal way, but it will have to do for now

    best

    Jens

    void get_phy_status (Uint16* status){  SET_PHYPAGE(0);  *status = readPhyReg(APP_PORT0_PHY_ADDR, 17);}

  • Thanks for your update.