FEC rx  corrupt data

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

FEC rx  corrupt data

1,039 Views
DiekG
Contributor I

I have the following problem
I'm using the interniche TCP/IP stack on the coldfire MCF5329.
I placed the FEC in internal loopback. When i display the receive descriptor and the transmit descriptor.
I note that the data in my receive descriptor is not the same as the data in de transmit descriptor. Here is a copy of my data:

DUMP TX BD
BD-address: 0x404029B8
 BD-cstatus: 0x00
 BD-length: 0x0E

0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x00 0xCF 0x52 0x53 0x54 0xCC 0x08 0x06
BD-address: 0x4040263C
 BD-cstatus: 0x00
 BD-length: 0x2E

0x00 0x01 0x08 0x00 0x06 0x04 0x00 0x01 0x00 0xCF 0x52 0x53 0x54 0xCC 0xC0 0xA8
0x00 0x62 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xC0 0xA8 0x00 0x04 0xC0 0xA8 0x00 0x04
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF


DUMP RX BD
BD-address 0x40400048
 BD-cstatus 0x80
 BD-length 0x40

0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x00 0xCF 0x52 0x53 0x54 0xCC 0xC0 0xA8 0x00 0x62
0x08 0x00 0x06 0x04 0x00 0x01 0x00 0xCF 0x00 0x04 0xC0 0xA8 0x00 0x04 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xC0 0xA8 0xC0 0xA8 0xFF 0xFF 0xFF 0xFF 0xD2 0xAE 0x02 0x7B
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF

As you can see is some of the data the same.

I have check and recheck all of the configurations of the fec, and can't see anything roung.My descriptor are aligned on 128 bit.

here are my configurations of my fec.
******************************************************************************

*******************************CODE******************************************

*********************************************************************

/* Configure interrupt registers */
 CF5329_FEC_EIMR = CF5329_FEC_EIMR_ALL_MASKS;  /* mask on all of 'em */
 /* clear any pending events */
 CF5329_FEC_EIR = CF5329_FEC_EIR_ALL_EVENTS;
#ifdef DEBUG_FEC
 /* If these values are not sticking return an error */
 if (CF5329_FEC_EIMR != CF5329_FEC_EIMR_ALL_MASKS)
    {
     /*dtrap();*/
     #if (STRING_INCL_ALL >= 0)
     string_strcpy(&l_buf1[0],"Error: FEC registers not responding\n");
     comm_send_msg(ID_COMM_PC,&l_buf1[0],COMM_TYPE_RS232);
     #endif
     return (-1);
   }
#endif
CF5329_FEC_TFWR = 0;
/*---------------------------------------------------------------------------*/
/*--- Initialize the hash table registers                                 ---*/
/*---------------------------------------------------------------------------*/
 CF5329_FEC_IALR = 0;
 CF5329_FEC_IAUR = 0;
/*----------------------------------------------------------------------------*/
/*---This driver doesn't support multicast frames yet, so we clear the hash---*/
/*--- table registers (t_g_hash_table_high and t_g_hash_table_low).        ---*/
/*--- To allow all multicasts in, we set all the bits in the group         ---*/
/*--- hash table registers.                                                ---*/
/*----------------------------------------------------------------------------*/
 CF5329_FEC_GALR = 0;//0x00000000; //0xffffffff;
 CF5329_FEC_GAUR = 0;//0x00000000;//0xffffffff;

/*--------------------------------------------------------------------------*/
/*--- Reset values are satisfactory for t_r_fstart and t_x_fstart,       ---*/
/*---  so this step is skipped.In some applications, the user may want   ---*/
/*--- to tune these values to provide more fifo space to rx or tx.       ---*/
/*--- Program this station's Ethernet physical address                   ---*/
/*--- Set the source address for the controller                          ---*/
/*--------------------------------------------------------------------------*/
 CF5329_FEC_PALR = (unsigned long)((0
 | (mac_addr_fec[0] <<24)
 | (mac_addr_fec[1] <<16)
 | (mac_addr_fec[2] <<8)
 | (mac_addr_fec[3] <<0)));
 CF5329_FEC_PAUR = (unsigned long)((0
 | (mac_addr_fec[4] <<24)
 | (mac_addr_fec[5] <<16)
 | CF5329_FEC_PAUR_TYPE(0x00008808)));
 
 CF5329_FEC_OPD =0x00018000;
 /*--- Program receive buffer size                                        ---*/
#if 1
 if (DUPLEX_phy_r17_dpm)
    {
     /* Configure FEC receiver mode:  */
     CF5329_FEC_RCR = (CF5329_FEC_RCR_MAX_FL(MAX_ETH_PKT) |
     CF5329_FEC_RCR_MII_MODE|
     CF5329_FEC_RCR_FCE|
     CF5329_FEC_RCR_PROM|
     CF5329_FEC_RCR_LOOP);         /*---full duplex                           ---*/
     /* Configure FEC transmitter mode:  */
     CF5329_FEC_TCR = ( 0 | CF5329_FEC_TCR_FDEN);/*--- full duplex         ---*/
    }
 else
    {
     /* Configure FEC receiver mode: */
     CF5329_FEC_RCR = (CF5329_FEC_RCR_MAX_FL(MAX_ETH_PKT)
                      |CF5329_FEC_RCR_MII_MODE
                      |CF5329_FEC_RCR_LOOP);
                      //|CF5329_FEC_RCR_DRT);
     /* Configure FEC transmitter mode:  */
     CF5329_FEC_TCR = ( 0 );    /* half duplex */
    }
#endif
/*-----------------------------------------------------------------------------*/
/*---FSL inlined the MII clock configuration code and made                  ---*/
/*--- it dependent on the SYS_CLK_MHz located in evb specific file          ---*/
/*--- Configure MII interface speed. Must be <= 2.5MHz                      ---*/
/*---                                                                       ---*/
/*---Desired MII clock is 2.5MHz                                            ---*/
/*---MII Speed Setting = System_Clock_Bus_Speed / (2.5MHz)                  ---*/
/*---To not divide using 2.5,                                               ---*/
/*--- just divide with 2 which gives extra margin anyway                    ---*/
/*-----------------------------------------------------------------------------*/
 CF5329_FEC_MSCR = CF5329_FEC_MSCR_MII_SPEED((unsigned long)(CF5329_SYS_CLK_KHZ*1)/(CF5329_FEC_SPEED_KHZ*2));
 CF5329_FEC_MIBC &= ~CF5329_FEC_MIBC_MIB_DISABLE;
 CF5329_FEC_FRSR = CF5329_FEC_FRSR_R_FSTART(0x33);
 CF5329_FEC_EMRBR = MAX_ETH_PKT;
/*-----------------------------------------------------------------------------*/
/*--- set up ring buffers - the FEC "BDs". Alloc extra space and round      ---*/
/*--- it down to a 128-bit aligned address as required by the FEC           ---*/
/*-----------------------------------------------------------------------------*/
 x_RxBDs = (BD *)memalign(16, NUM_RXBDS * sizeof(BD));
 if (x_RxBDs == NULL)
    {
     return (ENP_NOMEM);
    }
 #if (STRING_INCL_ALL >= 0)
 
 string_strcpy(&l_buf1[0],"x_RxBDS adr: ");
 string_cat_lhtostr_cat(&l_buf1[0],(unsigned long)x_RxBDs,1,"\r\n");
 comm_send_msg(ID_COMM_PC,&l_buf1[0],COMM_TYPE_RS232);
 #endif     
 
 x_TxBDs = (BD *)memalign(16, NUM_TXBDS * sizeof(BD));
 if (x_TxBDs == NULL)
    {
     return (ENP_NOMEM);
    }
 #if (STRING_INCL_ALL >= 0)
 string_strcpy(&l_buf1[0],"x_TxBDs adr: ");
 string_cat_lhtostr_cat(&l_buf1[0],(unsigned long)x_TxBDs,1,"\r\n");
 comm_send_msg(ID_COMM_PC,&l_buf1[0],COMM_TYPE_RS232);
 #endif

 /*--- loop through the buffer pools setting up the BD entries                ---*/
 l_rbd = x_RxBDs;
 for (i = 0; i < NUM_RXBDS; i++)
     {
       PACKET l_pkt;
       l_pkt = pk_alloc(MAX_ETH_PKT);            //FSL get pkt space from HEAP
       if (!l_pkt)
          {
           //dprintf("FECInit: fatal; rbd# %d out of Packet Buffers\n", i);
           return (-1);
          }
       x_rxpend[i] = l_pkt;    /* place pkt HEAP address in the rxpend[] array */
       l_rbd->bd_addr = (unsigned char *)l_pkt->nb_buff; /* map buffer to the ring */
       l_rbd->bd_length = MAX_ETH_PKT;            //FSL indicate max buffer size
       l_rbd->bd_cstatus = CF5329_FEC_RXBD_E;        //FSL mark buffer as empty
       l_rbd++;
      }
   /*--- mark last buffer with a "WRAP" bit                                       ---*/
   --l_rbd;
   l_rbd->bd_cstatus |= CF5329_FEC_RXBD_W;
   l_tbd = x_TxBDs;
   for (i = 0; i < NUM_TXBDS; i++)
       {
        /*--------------------------------------------------------------------------------*/
        /*--- alloc_uncached() cannot be used because of NPDEBUG,                      ---*/
        /*--- hence duplicate the alignment scheme here.                               ---*/
        /*--------------------------------------------------------------------------------*/
        x_TxLilPkts[i] = (unsigned char *)memalign(4, ETHHDR_SIZE);

        if (x_TxLilPkts[i] == NULL)
           {
            #if (STRING_INCL_ALL >= 0)
            string_strcpy(&l_buf1[0],"FECInit: fatal; tbd# %d out of eth hdr frame Buffers\n");
            string_cat_ltostr_cat(&l_buf1[0], i,"\n");
            comm_send_msg(ID_COMM_PC,&l_buf1[0],COMM_TYPE_RS232);
            #endif
            return (-1);
           }
        l_tbd->bd_cstatus = 0;
        l_tbd->bd_length = 0;
        l_tbd->bd_addr = 0;
        l_tbd++;
      }
 --l_tbd;
 l_tbd->bd_cstatus |= CF5329_FEC_TXBD_W;
 /* Configure start of Rx BD ring */
 CF5329_FEC_ERDSR =  (unsigned long)(&x_RxBDs[0]);
 /* Configure start of Tx BD ring */
 //FSL If processor header file had different naming for CF5329_FEC_ETDSR one was added for compatibility
 CF5329_FEC_ETDSR =  (unsigned long)(&x_TxBDs[0]);

************************************************************************

thus someone know how to solve this problem or know what's causing this problem
with friendly regards



Labels (1)
0 Kudos
1 Reply

297 Views
ddeluca
Contributor I

OK, as one who is not a big fan of developers who include their entire source code, I think I know wherein the problem lies. InterNiche appears to have a bug in their memalign method. It properly allocates enough space to align the RxBD and TxBD in your case, but in the process of alignment, it moves the pointer back instead of forward to the next available block. If you are using the NPDEBUG when you compile, as you step through, you will notice that the "memp" string that is placed in the correct spot, but because the pointer is moved to align it with the 16 byte boundary, it potentially allows your RxBD[ 0 ] or TxBD[ 0 ] to corrupt the entire memory block structure that is created. The problem is on line 514 of the iutil.c file. Rather than reading

 

      ptr = (char *)((unsigned)ptr & ~(align - 1));

it should be changed to:

 

      ptr = (char *)((unsigned)(ptr + align - 1) & ~(align - 1));

 

in order to ensure that the pointer gets aligned properly.

0 Kudos