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.

66AK2E05: Unable to receive incoming packets

Part Number: 66AK2E05

Hi Team, Hoping for your clarification.

Experiencing an intermittent mode that is unable to receive incoming packets on our Gigabit Ethernet interface but transmits packets successfully.  Once this happens we cannot recover w/o a power cycle.  Does errata_usagenote.28 apply to the SGMII interface used for Gigabit Ethernet?  The errata says it does not apply to the 10G interface but doesn't say anything about the SGMII for the 1Gb interface.

Thank you very much.

-Mark

  • 1G is so slow, it is very unusual that the link ever looses lock. Things that can cause issues

    A) only a single side of the differential is getting through, the receiver would be happy, but on loss of sync, the idle would not fire.

    B) etch is not properly laid out using differential rules

    The errata is more for interfaces at or above 4G where pre and post emphasis is required.

    The default pre and post emphasis in the config files or CSL should deal with 1G SGMII.

    There is a diagnostic dump that can be run to dump the SERDES receiver status. If the DLPF or CDR are NOT approximately 50% of their value plus or minus 30 steps or so, it could indicate the receiver has lost lock. Things to check would be refclk is at correct frequency for the Config/CSL used, A or B above.

    You could always try to toggle the sigdet register to reset the SERDES receiver to see if it recovers which would indicate the DLPF and or CDR were well out of range. There should be an API call that does just that.

    How long is the etch between the E05 and the remote device?

    Were they routed differentially?

  • Hi Denis, 

    The diagnostic tool we found only runs on the DSP. Is there a version for the ARM core?
     
    Thank you.
    -Mark
  • The core functionality is in C and the PDK package has build make files for C6x DSP. There are few helper functions like getting timestamps etc which are C6x specific.

     

    But if the code needs to be ported to ARM, it should be trivial to change these helper functions.

  • After some review, it looks like the code already has support for the ARM as well.

  • Hi Denis, seeking for further clarification.

    If 5.0 Gbps Baud Rate listed for SGMII means that it is affected by the errata (see post below). Also, can you provide more guidance on how to locate the ARM version of the diagnostic code.

    Thank you

    -Mark

  • SGMII runs at 1.25G baud or 1Gbps, so BER sweep is normally nor required.

    Some devices also support SGMII at 3.125G baud or 2.5Gbps rates.

    You can still do a BER sweep however for any speed.

    The code in in the PDK and already has the ARM defs so it can be run on an ARM processor as well.

  • Errata usage note 28 does not apply to 1.25G baud SGMII.

  • Which CPSW module is this issue for?

    Is it the 2 port 10G or the 8 port 1G CPSW?

  • HI Denis,

    Our issue is with the 8 port 1G CPSW and appears to be receive only, which is why the errata sparked our interest. Once the optimal values are determined by running the BER sweep is there a documented procedure on how to hard code them into the SerDes initialization process? Note that we are using PCIe on this module as well so would like to use this workaround for that interface as well.

    Thank you

  • There is some SERDES diagnostic function that allow you to dump the state of the SERDES.

    Things of interest is DLPF and CDR values.

    There is a SERDES lane register lane_004 with a field called SIGDET_OVR that allows the SERDES receiver to be reset. By setting that field to a 10b, and then back to 00b will cause the receiver to recal. If this resolves the receiver issue, we need to look at what may be causing the receiver to loose lock. The DLPF and CDR values can be used to see if the receiver is out of lock.

  • Here is code we ran on the DSP or ARM that allowed us to dump the DLPF and CDR values for the SERDES.

    #define BAND_VAL 62

    unsigned int fSerdesSbRead32(unsigned int addr)
    {
    return(*(volatile unsigned int *)(addr));
    }

    void fWrite32(unsigned int addr, unsigned int data)
    {
    *(volatile unsigned int *)(addr) = data;
    }

    unsigned int fRead32(unsigned int addr)
    {
    return(*(volatile unsigned int *)(addr));
    }

    void write_32_mask(unsigned int in_base,unsigned int iKeepMask,unsigned int iSetValue)
    {
    unsigned int iTmp;

    iTmp=fRead32(in_base);
    iTmp &= iKeepMask;
    iTmp |= ((~iKeepMask)&iSetValue);
    fWrite32(in_base,iTmp);
    }

    void fSerdesSbWriteTbusAddr(unsigned int iSerdesCfgBase,int iSelect,int iOffset)
    {
    int iPhyA = (iSerdesCfgBase != 0x0231e000);
    int iTwoLaner;

    iTwoLaner=(fSerdesSbRead32(iSerdesCfgBase + 0x1fc0)>>16)&0x0ffff;
    if ((iTwoLaner==0x4eb9)||(iTwoLaner==0x4ebd)) iTwoLaner=0; else iTwoLaner=1;
    if ((iSelect)&&(iTwoLaner)) iSelect++;

    if (iPhyA)
    {
    write_32_mask(iSerdesCfgBase+0x0008, 0x00FFFFFF, (((iSelect) << 5) + iOffset) << 24);
    }
    else
    {
    write_32_mask(iSerdesCfgBase+0x00fc, 0xf800ffff, (((iSelect) << 8) + iOffset) << 16);
    }
    }

    unsigned int fSerdesSbReadTbusVal(unsigned int iSerdesCfgBase)
    {
    int iPhyA = (iSerdesCfgBase != 0x0231e000);
    unsigned int iTmp;

    if(iPhyA)
    {
    iTmp = (fSerdesSbRead32(iSerdesCfgBase + 0x0ec) >> 24) & 0x0ff;
    iTmp |=((fSerdesSbRead32(iSerdesCfgBase + 0x0fc) >> 16) & 0x00f00);
    }
    else
    {
    iTmp = (fSerdesSbRead32(iSerdesCfgBase + 0x0f8) >> 16) & 0x0fff;
    }
    return(iTmp);
    }

    unsigned int fSerdesSbReadSelectedTbus(unsigned int iSerdesCfgBase,int iSelect,int iOffset)
    {
    fSerdesSbWriteTbusAddr(iSerdesCfgBase,iSelect,iOffset); //Set tbus address
    return(fSerdesSbReadTbusVal(iSerdesCfgBase)); //Get TBUS Value
    }

    void fDumpPortDlpfCdr(unsigned int iBase,int iLanes,int iMask)
    {//unsigned int fSerdesSbReadSelectedTbus(unsigned int iSerdesCfgBase,int iSelect,int iOffset)
    int iPhyA = (iBase != 0x0231e000);
    int i;
    unsigned int dlpf1,dlpf2,cdrcaldata;

    printf("DLPF: ");
    for(i=0;i<iLanes;i++) if (((1<<i)&iMask)!=0)
    {
    dlpf1=(fSerdesSbReadSelectedTbus(iBase,i+1,(iPhyA)?0x05:0x05) >> 2) & 0x3ff;
    dlpf2=(fSerdesSbReadSelectedTbus(iBase,i+1,(iPhyA)?0x05:0x05) >> 2) & 0x3ff;
    if (((dlpf1<(512-BAND_VAL))||(dlpf1>(512+BAND_VAL)))&&(dlpf2>(512-BAND_VAL))&&((dlpf2<(512+BAND_VAL))))
    dlpf1=dlpf2;
    if (i!=0) printf(", ");
    printf("%d",dlpf1);
    }
    printf(" CDR Cal: ");
    for(i=0;i<iLanes;i++) if (((1<<i)&iMask)!=0)
    {
    cdrcaldata=(fSerdesSbReadSelectedTbus(iBase,i+1,(iPhyA)?0x06:0x06) >> 3) & 0x0ff;
    if (i!=0) printf(", ");
    printf("%d",cdrcaldata);
    }
    printf("\n");
    }

    main()
    {
    unsigned int SerdesBaseAddress;

    SerdesBaseAddress=0x0231a000; //Example for Hyperlink SERDES base!
    fDumpPortDlpfCdr(SerdesBaseAddress,4,0xf);
    }

  • Once the BER sweep is done and the optimal values are gathered, they can be hardcoded instead of going through auto adaptation. 

    If you are using CSL, then forceattboost flag in the CSL_SERDES_LANE_ENABLE_PARAMS_T struct should be set. The att and boost values to be hardcoded should be set in the same struct rx_coeff.force_att_val[lane_num], rx_coeff.force_boost_val[lane_num] values. 

    Regards,
    Arun