HI ,TI expert:
I am using C6678 to develop one product. I find the NDK cannot be restarted normally without hw reset.NDK cannot receive longer packet (larger than 100Bytes).It seems that the
receive free queue is exhausted.I almost read all the artiles about the issue in the forum and try all the
method I can think of.But unfortunately, the problem still exists.can you give some advice ? thank you in advance.
My current software flow is like the following:
(1)stage A software
C6678 power on and hardware reset, then my first stage A is running and the NDK starts up
Then ,software will download another software image (stage B software)from the remote host using TCP.
Stage A software parses the software image and load it and then shutdowns the ethernet and jump to the entry point to run (stage B software)
(2) stage B software:
the NDK stack and EMAC is restarted again. But I find that the NDK works abnormal and only little packet can be recevied.
for example: if I input the command on PC "ping 192.168.2.100 -t -l 100", 192.168.2.100 is the C6678 ipaddress . it works ok
if I input "ping 192.168.2.100 -t -l 1000" there is no response from C6678.
Then I do the same test based on C6678 EVM and find the same problem. I read almost all the artiles about NDK restart and still cannot resolve it.
what's more ,I add some debug info in the nimu driver and find some suspect.
In stage B startup , when the emac starts ,I find the gRxFreeQHnd queue is almost exhausted.
The following is my debug info
(a)after "if (Setup_Rx (ptr_net_device) != 0)" I call the Verify_Init function to check the gRxFreeQHnd, it is 110
(b)after "Set up the MAC Address LUT" ,I check the gRxFreeQHnd(Verify_Init), it is almost exhausted
Verify_Init: Expected 110 entry count for gRxFreeQHnd queue 738, found 1 entries
(c) after "Set up the MAC Address LUT for Broadcast" ,I check gRxFreeQHnd(Verify_Init), it is almost exhausted.
Verify_Init: Expected 110 entry count for gRxFreeQHnd queue 738, found 2 entries
the following is my checking code :
//hover qu check the descriptor
//hover qu check the descriptor
platform_printf ("rfdsp:start veryfy the descritor \n");
if (Verify_Init () != 0)
{
platform_printf ("rfdsp:Warning:Queue handler Verification failed \n");
}
memcpy (ðInfo.dst[0], ptr_pvt_data->pdi.bMacAddr, sizeof(paMacAddr_t));
/* Set up the MAC Address LUT*/
if (Add_MACAddress (ðInfo, &routeInfo) != 0)
{
platform_printf ("Add_MACAddress failed \n");
return -1;
}
platform_printf ("rfdsp:start veryfy the descritor after single mac address \n");
if (Verify_Init () != 0)
{
platform_printf ("rfdsp:Warning:Queue handler Verification failed \n");
}
memcpy (ðInfo.dst[0], broadcast_mac_addr, sizeof(paMacAddr_t));
/* Set up the MAC Address LUT for Broadcast */
if (Add_MACAddress (ðInfo, &routeInfo) != 0)
{
platform_printf ("Add_MACAddress failed \n");
return -1;
}
/* Verify the Tx and Rx Initializations */
if (Verify_Init () != 0)
{
platform_printf ("Warning:Queue handler Verification failed \n");
}
So I guess it may be the QMSS,PA ,CPPI or EMAC not be shutdown graceful. So I try to pop all the queue handle
and disable the gmac.The following is my shut down code
(1)EmacStop ,I add some code to pop the queue and reset GMAC
#if 1
//hover
platform_printf("disable GE switch port0\n");
CSL_CPSW_3GF_disablePort0();
platform_printf("disable acc pdsp\n");
Qmss_disableAccumulator (Qmss_PdspId_PDSP1, PA_ACC_CHANNEL_NUM);
platform_printf("disable gmac1&gmac2\n");
CSL_CPGMAC_SL_resetMac(0);
CSL_CPGMAC_SL_resetMac(1);
#endif
#if 1
//hover add pop all qmss queue
platform_printf("begin pop gTxFreeQHnd queue\n");
while ( Qmss_queuePop(gTxFreeQHnd) != NULL)
{
platform_printf("pop gTxFreeQHnd\n");
}
platform_printf("begin pop gTxReturnQHnd queue\n");
while ( Qmss_queuePop(gTxReturnQHnd) != NULL)
{
platform_printf("pop gTxReturnQHnd\n");
}
platform_printf("begin pop gRxFreeQHnd queue\n");
while ( Qmss_queuePop(gRxFreeQHnd) != NULL)
{
platform_printf("pop gRxFreeQHnd\n");
}
platform_printf("begin pop gRxQHnd queue\n");
while ( Qmss_queuePop(gRxQHnd) != NULL)
{
platform_printf("pop gRxQHnd\n");
}
platform_printf("begin pop gPaCfgCmdRespQHnd queue\n");
while ( Qmss_queuePop(gPaCfgCmdRespQHnd) != NULL)
{
platform_printf("pop gPaCfgCmdRespQHnd\n");
}
#endif
platform_printf("begin pop gPaTxQHnd queue\n");
for (i = 0; i < NUM_PA_TX_QUEUES; i++)
{
while ( Qmss_queuePop(gPaTxQHnd[i]) != NULL)
{
platform_printf("pop gPaTxQHnd[i] i=%d\n",i);
}
}
(2)add graceful down code :
void netservicestop()
{
NC_NetStop(0);
TaskSleep(3000);
c66x_set_PA_state_to_reset();
c66x_QmTeardown();
}
static void c66x_set_PA_state_to_reset()
{
int i,j;
/* Put each of the PDSPs into reset */
for (i = 0; i < 6; i++)
{
DEVICE_REG32_W( CSL_PA_SS_CFG_REGS + PDSP_CONTROL_OFFSET(i), 0);
for (j = 0; j < PA_NUM_MAILBOX_SLOTS; j++)
DEVICE_REG32_W (CSL_PA_SS_CFG_REGS + PA_REG_MAILBOX_SLOT(i, j), 0);
}
/* Reset packet ID */
DEVICE_REG32_W(CSL_PA_SS_CFG_REGS + PDSP_PKT_ID_SOFT_RESET_OFFSET, 1);
/* Reset LUT2 */
DEVICE_REG32_W(CSL_PA_SS_CFG_REGS + PDSP_LUT2_SOFT_RESET_OFFSET, 1);
/* Reset statistics */
DEVICE_REG32_W(CSL_PA_SS_CFG_REGS + PDSP_STATS_SOFT_RESET_OFFSET, 1);
/* Reset timers */
for (i = 0; i < 6; i++)
DEVICE_REG32_W( CSL_PA_SS_CFG_REGS + PDSP_TIMER_CNTRL_REG_OFFSET(i), 0);
platform_c66x_delay(100);
}
void c66x_QmTeardown (void)
{
int32_t i;
/* Linking RAM info */
for (i = 0; i < DEVICE_QM_NUM_LINKRAMS; i++) {
DEVICE_REG32_W (DEVICE_QM_MANAGER_BASE + QM_REG_LINKRAM_BASE(i), 0);
DEVICE_REG32_W (DEVICE_QM_MANAGER_BASE + QM_REG_LINKRAM_SIZE(i), 0);
}
/* Memory region info */
for (i = 0; i < DEVICE_QM_NUM_MEMREGIONS; i++) {
DEVICE_REG32_W (DEVICE_QM_DESC_SETUP_BASE + QM_REG_MEMR_BASE_ADDR(i)
, 0);
DEVICE_REG32_W (DEVICE_QM_DESC_SETUP_BASE + QM_REG_MEMR_START_IDX(i)
, 0);
DEVICE_REG32_W (DEVICE_QM_DESC_SETUP_BASE + QM_REG_MEMR_DESC_SETUP(i)
, 0);
}
} /* hwQmTeardown */