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.

qmss termination/reinitialization



Hello.

I use QMSS on c6678 in the same source code (which initialize QMSS like in examples/ndk/client/resourcemgr.c:res_mgr_init_qmss and use than via paired pop/push) in two executables and first program starts the second. So this code starts twice without power reset. At the and of first program I close all opened queues.

But now Qmss_queuePop () function in second program returns Cppi_HostDesc->buffLen=0 or =204815136 without errors. Or Qmss_getQueueEntryCount() always return 0.

I guess it's because of incorrect QMSS termination in the first program.

So, is to close all opened queues enough for correct QMSS termination and reusing without power reset?

  • Hi Alex,
    What is the DSP part number used? I did not understand your query, please elaborate in detail. What you mean by "same code"?

  • Raja , I corrected the post.
  • Hi Alex,

    Thanks for your post.

    I think, after freeing the queue through Qmss_queueClose() API, the CPPI subsystem needs to be stopped through res_mgr_stop_cppi() API and the API will de-initialize the CPPI LLD which will check for the cfg_type and will appropriately close or free the CPPI transmit or receive channel as below:

    int32_t res_mgr_stop_cppi ( CPPI_CFG_TYPE  cfg_type)

    {

       uint32_t i;

       if (cfg_type == CPPI_CFG_PASS)

       {

           for (i = 0; i < gCppiCfg[cfg_type].num_rx_channels; i++)

               Cppi_channelClose (gPassCpdmaRxChanHnd[i]);

           for (i = 0; i < gCppiCfg[cfg_type].num_tx_queues; i++)

               Cppi_channelClose (gPassCpdmaTxChanHnd[i]);

       }

       return 0;

    }

    I guess, the above should be used for proper CPPI/QMSS termination.

    Also, there is no automatic deletion of payload buffers by a pktDMA, because there's no way for the hardware to know how the buffer was obtained.  And to my knowledge, the CPPI LLD does not do this either.  For Rx descriptor handling, it is generally up to the host software to recycle the descriptor to the appropriate queue and to free the payload buffer if necessary.

    Thanks & regards,

    Sivaraj K

    -------------------------------------------------------------------------------------------------------

    Please click the Verify Answer button on this post if it answers your question.

    -------------------------------------------------------------------------------------------------------

  • After disabling and closing all opened channels and Cppi_close without errors, Cppi_exit return CPPI_CPDMA_NOT_CLOSED.
    How can I fix it?

  • Hi,

    Have you ensured that the software recycles host packet/buffer descriptors recycled appropriately and frees the payload?

    How did you stop the CPPI subsystem and is your CPPI transmit or receive channel freed or closed appropriately? Could you please ensure this for proper CPPI termination which is more significant?

    Thanks & regards,

    Sivaraj K

    -------------------------------------------------------------------------------------------------------

    Please click the Verify Answer button on this post if it answers your question.

    -------------------------------------------------------------------------------------------------------

  • Sivaraj Kuppuraj said:
    Also, there is no automatic deletion of payload buffers by a pktDMA, because there's no way for the hardware to know how the buffer was obtained.  And to my knowledge, the CPPI LLD does not do this either.  For Rx descriptor handling, it is generally up to the host software to recycle the descriptor to the appropriate queue and to free the payload buffer if necessary.

    Sivaraj Kuppuraj said:
    Have you ensured that the software recycles host packet/buffer descriptors recycled appropriately and frees the payload?

    I think this circulation is necessary only during work time.
    But yes, I reset the buffer length and put the descriptor back to the free queue for each Qmss_queuePop from Rx queue.
    If something was wrong with recycling and queuing, than first program would have revealed that during work.
    And why do I have to take care of the descriptors, if I close the queue, thereby destroying it and any info about it, and the Qmss_queueClose function doesn't return any error?
    Sivaraj Kuppuraj said:
    How did you stop the CPPI subsystem and is your CPPI transmit or receive channel freed or closed appropriately? Could you please ensure this for proper CPPI termination which is more significant?
    Int32 DeInit_Cppi (Void)
    {
        if (Cppi_closeRxFlow(gRxFlowHnd) < 0)
            {
                System_printf ("Error Cppi_closeRxFlow \n");
                return -1;
            }
    
        int i, res;
        for (i = 0; i < NUM_PA_TX_QUEUES; i ++)
        {
            res = Cppi_channelDisable (gCpdmaTxChanHnd[i]);
            if (res<0)
            {
                printf ("Error Cppi_channelDisable: %d \n", res);
                return -1;
            }
            res = Cppi_channelClose   (gCpdmaTxChanHnd[i]);
            if (res<0)
            {
                printf ("Error Cppi_channelClose: %d \n", res);
                return -1;
            }
        }
    
        for (i = 0; i < NUM_PA_RX_CHANNELS; i++)
        {
            res = Cppi_channelDisable (gCpdmaRxChanHnd[i]);
            if (res<0)
            {
                printf ("Error Cppi_channelDisable: %d \n", res);
                return -1;
            }
            res = Cppi_channelClose   (gCpdmaRxChanHnd[i]);
            if (res<0)
            {
                printf ("Error Cppi_channelDisable: %d \n", res);
                return -1;
            }
        }
    
        if ((res = Cppi_close (gCpdmaHnd)) < 0)
        {
            printf ("Error Cppi_close %d \n", res);
            return -1;
        }
    
        if ((res = Cppi_exit ()) < 0) // return CPPI_CPDMA_NOT_CLOSED
        {
            printf ("Error Cppi_exit %d \n", res);
            return -1;
        }
    
        return 0;
    }

  • Hi,

    To my opinion, Cppi_close() and Cppi_exit () are mapped to unique functionalities which does the desired task and either of the routines doesn't relate to each other.  By this, we could say there is no relevancy between Cppi_close without errors and Cppi_exit return CPPI_CPDMA_NOT_CLOSED

    Also, if Qmss_queueClose function doesn't return any error which infers, it closes & destroys the queue successfully and thereby, it doesn't return any error. This is what it does and it mean to be.

    Thanks & regards,

    Sivaraj K

    -------------------------------------------------------------------------------------------------------

    Please click the Verify Answer button on this post if it answers your question.

    -------------------------------------------------------------------------------------------------------

  • The first problem in your crappy code:
    srio_drv doesn't contain pair function for Srio_init. Internals unaccessible. Without package code modification user can't deinit srio. And is not obvious that deinitialization are necessary.



    The second in your crappy code too:
    srio_drv.c:1180

    /* Enable all the SRIO Receive Channels */    
    {
        uint16_t            index;
        Cppi_RxChInitCfg    rxCfg;
        Cppi_ChHnd          chHnd;
        uint8_t             isAllocated;
    
        for (index = 0; index < 16; index++)
        {
            /* Open the SRIO Receive Channel */
            rxCfg.channelNum = CPPI_PARAM_NOT_SPECIFIED;
            rxCfg.rxEnable   = Cppi_ChState_CHANNEL_DISABLE;
            chHnd = Cppi_rxChannelOpen (gSRIODriverMCB.cppiHnd, &rxCfg, &isAllocated);
            if (chHnd == NULL)
            {
                Srio_osalLog ("Error: Opening SRIO Rx channel %d failed\n", rxCfg.channelNum);
                return -1;
            }
    
            /* Enable the channel */
            if (Cppi_channelEnable (chHnd) < 0)
            {
                Srio_osalLog ("Error: Enabling SRIO Rx Channel %d failed\n", index);
                return -1;
            }
        }
    }
    

    Index is not used. All channels pointers get lost.
    I fixed CPPI_CPDMA_NOT_CLOSED when fixed that.


    The third is question:
    Thought I have closed all qmss queues, PA, cppi flows and cppi itself,
    "Qmss_queuePop () function in second program returns Cppi_HostDesc->buffLen=0" still yet.

    Sivaraj Kuppuraj said:
    Have you ensured that the software recycles host packet/buffer descriptors recycled appropriately and frees the payload?

    I think this circulation is necessary only during work time (when I reset the buffer length and put the descriptor back to the free queue for each Qmss_queuePop from Rx queue).
    If something was wrong with recycling and queuing, than first program would have revealed that during work.
    And why do I have to take care of the descriptors, if I close the queue, thereby destroying it and any info about it, and the Qmss_queueClose function doesn't return any error?
    Payload buffers allocated statically and used by host descriptors.

  • In both programs I have
    pCppiDesc = Qmss_queuePop (gGlobalFreeQHnd)
    and then, after descriptors initialization,
    they have addresses like
     c1c4700
     c1c4750
     c1c47a0
     c1c47f0
    ...
    end push via Qmss_queuePushDescSize (gTxFreeQHnd, pCppiDesc, SIZE_HOST_DESC);

    First call pHostDesc = Qmss_queuePop (gTxFreeQHnd)
    in the first program return c1c4700 descriptor pointer.
    After all I close all qmss queues, cppi flows and cppi itself.
    But in the second program first call pHostDesc = Qmss_queuePop (gTxFreeQHnd) return c1c4750 or even greater address (c1c47f0 e.g). So it isn't first descriptor address c1c4700.

    How could this be if I've closed all before new initialization?

  • Bump!
    Is support going to support?!

  • Hi Alex,
    I am working with appropriate expert and will get back to you soon. Thank you.