/**
 * ============================================================================
 * = COPYRIGHT
 *              INTEL CORPORATION PROPRIETARY INFORMATION
 *   This software is supplied under the terms of a license agreement or
 *   nondisclosure agreement with Intel Corporation and may not be copied 
 *   or disclosed except in accordance with the terms in that agreement.
 *      Copyright (C) 2000-2002 Intel Corporation. All rights reserved.
 *
 * = PRODUCT
 *      Intel(r) IXA SDK for the IXP2X00 Network Processor
 *
 * = FILENAME
 *      ix_cc_sched.c
 *
 * = DESCRIPTION
 *         The file contains API functions exposed by Scheduler Core Component
 *
 * = AUTHOR
 *      Herman Zaks
 *      Herman.Zaks@intel.com
 *
**/

#define IX_ERROR_FILE_IDENT "$Id: ix_cc_sched.c,v 1.14 2002/10/31 00:25:02 lbmiller Exp $"

#include "ix_cc_error.h"
#include "ix_types.h"
#include "ix_error.h"
#include "ix_rm.h"

#if !defined(IX_EXCLUDE_CCI)
    #include "ix_cci.h"
#endif /* end !defined(IX_EXCLUDE_CCI) */

#include "ix_cc.h"
#include "cc/ix_cc_sched.h"
#include "cc/internal/ix_cc_sched_internal.h"

/**
 * NAME: ix_cc_sched_init()
 *
 * DESCRIPTION: Initialization function invoked by the Execution Engine of the CCI
 * 
 * @Param:  -   IN  ix_cc_handle arg_hCcHandle - handle of the Scheduler given by CCI 
 *              OUT void** arg_ppContext - 
 *                                  address to fill up with the pointer to the Scheduler Core Context
 * @Return: IX_SUCCESS or valid ix_error if code fails ;
 */

ix_error ix_cc_sched_init(ix_cc_handle arg_hCcHandle, void** arg_ppContext)
{
    ix_cc_sched_context* pContext = NULL;

/* Check the input arguments */
    ix_error err = IX_SUCCESS;
    if (IX_NULL_HANDLE == arg_hCcHandle) 
    {
        return IX_ERROR_WARNING(IX_CC_SCHED_INVALID_HANDLE,("Invalid CC handle"));
        
    }
    if (NULL == arg_ppContext)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_NULL,("Null Context argument in Scheduler"));
    }
    
    /* get memory for context structure */ 
    pContext = (ix_cc_sched_context*)ix_ossl_malloc(sizeof(ix_cc_sched_context));
    if (NULL == pContext)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_OOM_SYSTEM,("No system memory available"));
    }
    ix_ossl_memset(pContext,0,sizeof(ix_cc_sched_context));
    /* get memory for config structure */
    pContext->pUblockConfig = (ix_cc_sched_ublock_config*)ix_ossl_malloc(sizeof(ix_cc_sched_ublock_config));
    if (NULL == pContext->pUblockConfig)
    {
        ix_ossl_free(pContext);
        return IX_ERROR_WARNING(IX_CC_ERROR_OOM_SYSTEM, ("No system memory available"));
    }
    ix_ossl_memset(pContext->pUblockConfig,0,sizeof(ix_cc_sched_ublock_config));

    pContext->hSchedHandle = arg_hCcHandle;
    IX_ERROR_C(_ix_cc_sched_update_configuration(pContext),err);
    if (err != IX_SUCCESS)
    {
        ix_ossl_free(pContext->pUblockConfig);
        ix_ossl_free(pContext);
        return err;
    }

    IX_ERROR_C(_ix_cc_sched_patch_microblock(pContext),err); 
    if (err != IX_SUCCESS)
    {
        ix_rm_mem_free(pContext->pUblockConfig->virtual_base);
        ix_ossl_free(pContext->pUblockConfig);
        ix_ossl_free(pContext);
        return err;
    }
    /* set CC context */
    *arg_ppContext = pContext;
    return err;

}

/**
 * NAME: ix_cc_sched_fini()
 *
 * DESCRIPTION: Shut down function invoked by the Execution Engine of the CCI
 * 
 * @Param:  -   IN  ix_cc_handle arg_hCcHandle - handle of the Scheduler given by CCI 
 *              IN void *arg_ppContext - pointer to the Scheduler Core Context
 *
 * @Return: IX_SUCCESS or valid ix_error if code fails ;
 */

ix_error ix_cc_sched_fini(ix_cc_handle arg_hCcHandle, void* arg_pContext)
{
    ix_error err = IX_SUCCESS;
    ix_cc_sched_context* pContext = arg_pContext;
    if (NULL == arg_pContext) 
    {
        err = IX_ERROR_NEW(IX_CC_ERROR_NULL,IX_ERROR_LEVEL_WARNING);
    }
    else if (arg_hCcHandle != pContext->hSchedHandle)
    {
        err = IX_ERROR_NEW(IX_CC_SCHED_INVALID_HANDLE,IX_ERROR_LEVEL_WARNING);
    }
    
    if (IX_SUCCESS == err)
    {
        /* rm memory deallocation */
        IX_ERROR_CRT(ix_rm_mem_free(pContext->pUblockConfig->virtual_base),IX_CC_SCHED_ERROR_FREE_MEM, 
                                IX_ERROR_LEVEL_WARNING);
        /* ossl memory deallocation */
        ix_ossl_free(pContext->pUblockConfig);
        ix_ossl_free(pContext);
    }
    return err;
}
