/**
 * ============================================================================
 * = 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_eth_rx_internal.h
 *
 * = DESCRIPTION
 *      This file contains parameters used internally by Pos Rx core 
 *      component.
 *
 *
 * = CHANGE HISTORY
 *      7/15/2002 - Created.
 *
 * ============================================================================
 * $Id: ix_cc_eth_rx_internal.h,v 1.10 2003/01/31 20:48:23 rranjeet Exp $
 */

#if !defined(__IX_CC_ETH_RX_INTERNAL_H__)
#define __IX_CC_ETH_RX_INTERNAL_H__


/**
 * System defined include files required.
 */
#include "cc/ix_cc_eth_rx.h" 
#include "ix_ossl.h"
#include "ix_rm.h"
#include "ix_error.h"


#if defined(__cplusplus)
extern "C"
{
#endif /* end defined(__cplusplus) */



/**
 * Prototypes for internal functions.
 */




/* Size defines for callback context tables */
#define ETH_RX_NUM_ENTRIES_CB_CTX_TBL_COMMON          128 /* must be power of 2 */
#define ETH_RX_NUM_ENTRIES_CB_CTX_TBL_GET_STAT        ETH_RX_NUM_ENTRIES_CB_CTX_TBL_COMMON
#define ETH_RX_SIZE_CB_CTX_TBL_GET_STAT               (ETH_RX_NUM_ENTRIES_CB_CTX_TBL_GET_STAT * sizeof(ix_cc_eth_rx_cb_ctx_entry))
#define ETH_RX_NUM_ENTRIES_CB_CTX_TBL_GET_IF        ETH_RX_NUM_ENTRIES_CB_CTX_TBL_COMMON
#define ETH_RX_SIZE_CB_CTX_TBL_GET_IF               (ETH_RX_NUM_ENTRIES_CB_CTX_TBL_GET_IF * sizeof(ix_cc_eth_rx_cb_ctx_entry))

/* various size definitions for 32bit and 64-bit counter support */
/*Rx packets, Rx bytes, Dropped packets, Exception packets*/
#define ETH_RX_NUM_COUNTERS_PER_PORT                   4 
#define ETH_RX_TOTAL_NUM_COUNTERS       (IX_CC_ETH_RX_MAX_NUM_PORTS * ETH_RX_NUM_COUNTERS_PER_PORT)
#define ETH_RX_SIZE_32BIT_COUNTER_BUF   (ETH_RX_TOTAL_NUM_COUNTERS * sizeof(ix_uint32))
#define ETH_RX_SIZE_64BIT_COUNTER_HDL	(ETH_RX_TOTAL_NUM_COUNTERS * sizeof(ix_counter_64bit_handle))


/**
 * Callback context entry structure
 */
typedef struct s_cc_eth_rx_cb_ctx_entry
{
    ix_uint8 flags;
    void *pUserCtx;     /* user context */
    void *pUserCb;      /* user callback */
} ix_cc_eth_rx_cb_ctx_entry;



/* values for flags field of the callback context entry structure */
#define CC_ETH_RX_ENTRY_FLAGS_NOT_USED     0x00 /* free entry */
#define CC_ETH_RX_ENTRY_FLAGS_USED_STATIC  0x01 /* used static entry */
#define CC_ETH_RX_ENTRY_FLAGS_USED_DYNAMIC 0x02 /* used dynamic entry */

/**
 * Callback context entry table structure
 */
typedef struct s_cc_eth_rx_cb_ctx_tbl
{
    ix_uint32 index;                 /* index pointing to the next free item */
    ix_cc_eth_rx_cb_ctx_entry *pTable; /* free cb context entry array */ 
} ix_cc_eth_rx_cb_ctx_tbl;



/**
 * Control block structure
 */
typedef struct ix_s_cc_eth_rx_ctl_blk
{

	/**
     * Number of channels. This will be read in from the properties structure
     */
    ix_uint32 numChannels;

    ix_uint32 mev2Num;        /* Ethernet Rx MEv2 number */
    ix_uint32 l2DecapMev2Num; /* L2 Decap MEv2 number */
    ix_uint32 filterTableSize; /* Size of filter Table */    
    ix_uint32 portMode;        /* Port mode bit map */
	/**
     * Local blade id and port id of each channel.  
     * This will be derived from ix_cc_init_context structure.
     */
    ix_uint32 portId[IX_CC_ETH_RX_MAX_NUM_ETH_PORTS];
    ix_uint32 bladeId;

	/**
     * Port status.  This is maintained by the library API to 
     * enable and disable the channel interface.
     */
    ix_cc_eth_rx_if_state portState[IX_CC_ETH_RX_MAX_NUM_ETH_PORTS];
    ix_counter_64bit_handle *pCounterHandlers64Bit; /* 64-bit counter handler array */
    ix_uint32 *pCounterBase32Bit;                /* 32-bit counters memory */
    ix_cc_eth_rx_mac_filter_table_entry *pFilterTableBase; /* SRAM filter table base */
    ix_uint32 filterTableTotalNumEntries;        /* Total number of entries in the filter table */
    ix_uint32 filterTableNumEntriesBaseBucket;   /* Total number of entries in the base bucket */
    ix_uint32 filterTableNumEntriesOvBucket;     /* Total number of entries in the overflow bucket */
    ix_uint32 *pPortMapBase;                     /* Port Map base */
    ix_cc_eth_rx_cb_ctx_tbl *pCbCtxTblGetStatInfo; /* free cb context table for stats info */
	ix_cc_eth_rx_cb_ctx_tbl *pCbCtxTblGetIfState; /* free cb context table for interface state info */
	ix_ossl_mutex_t mid; /*Mutex id used by the component in critical sections.*/
} ix_cc_eth_rx_ctl_blk;



/**
 * MACRO NAME: IX_CC_ETH_RX_ALLOC_ENTRY
 *
 * DESCRIPTION: This macro allocates a user specified structure.
 *              The structure is either allocated from the free entry array
 *              passed in by the user or from OSSL if one is not 
 *              available from the array.
 *
 * @Param: arg_pTbl - IN: pointer to the free entry array.
 * @Param: arg_CurIndex - IN: current index to the array.
 * @Param: arg_TblSize - IN: size of the table (MUST be a power of 2)
 * @Param: arg_Type - IN: data type of the array element.
 *
 * @Param: arg_pEntry - OUT: pointer to the free entry.
 *
 * @Return:  - None
 */
#define IX_CC_ETH_RX_ALLOC_ENTRY(                                   \
    arg_pTbl,                                                        \
    arg_CurIndex,                                                    \
    arg_TblSize,                                                     \
    arg_Type,                                                        \
    arg_pEntry)                                                      \
{                                                                    \
                                                                     \
    arg_pEntry = arg_pTbl + arg_CurIndex;                            \
                                                                     \
    if (arg_pEntry->flags == CC_ETH_RX_ENTRY_FLAGS_NOT_USED)        \
    {                                                                \
        arg_pEntry->flags = CC_ETH_RX_ENTRY_FLAGS_USED_STATIC;      \
        arg_CurIndex = (arg_CurIndex + 1) & (arg_TblSize - 1);       \
    }                                                                \
    else                                                             \
    {                                                                \
        if ((arg_pEntry = (arg_Type *)ix_ossl_malloc(sizeof(arg_Type))) != NULL) \
        {                                                            \
            arg_pEntry->flags = CC_ETH_RX_ENTRY_FLAGS_USED_DYNAMIC; \
        }                                                            \
    }                                                                \
}



/**
 * MACRO NAME: IX_CC_ETH_RX_FREE_ENTRY
 *
 * DESCRIPTION: This macro frees a structure.
 *              The structure may be freed back to system memory if 
 *              was allocated from it.
 *
 * @Param: arg_pEntry - IN: pointer to the entry to be freed.
 *
 * @Return:  - None
 */
#define IX_CC_ETH_RX_FREE_ENTRY(                                      \
    arg_pEntry)                                                        \
{                                                                      \
                                                                       \
    if ((arg_pEntry)->flags == CC_ETH_RX_ENTRY_FLAGS_USED_STATIC)       \
    {                                                                  \
        (arg_pEntry)->flags = CC_ETH_RX_ENTRY_FLAGS_NOT_USED;           \
    }                                                                  \
    else if ((arg_pEntry)->flags == CC_ETH_RX_ENTRY_FLAGS_USED_DYNAMIC) \
    {                                                                  \
        ix_ossl_free(arg_pEntry);                                      \
    }                                                                  \
}



/*********************************
 * MAC filtering related defines *
 *********************************/

/**
 * MACRO NAME: _IX_CC_ETH_RX_MAC_FILTER_HASH
 * 
 * DESCRIPTION: Hash a 6-byte MAC address into a 10-bit value.  This uses
 *              the same algorithm used by the Ethernet Rx microblock:
 * 
 *    hash = A ^ B ^ C ^ D ^ E ^ F
 *    if (hash == 0)
 *        hash = 1;
 *    where A:B:C:D:E:F is the MAC address.
 *
 * @Param: arg_pKey - IN: 6-byte MAC address in network byte order.
 * @Param: arg_Hash - OUT: 10-bit hashing result
 *
 * @Return: 10-bit hashing result
 */
#define _IX_CC_ETH_RX_MAC_FILTER_HASH(                                              \
    arg_pKey,                                                                       \
    arg_Hash)                                                                       \
{                                                                                   \
    ix_uint16 hash;                                                                 \
    if ((hash = (ix_uint16)(arg_pKey[0] ^ arg_pKey[1] ^ arg_pKey[2] ^ arg_pKey[3] ^ arg_pKey[4] ^ arg_pKey[5])) == 0) \
    {                                                                               \
        hash = 1;                                                                   \
    }                                                                               \
    arg_Hash = hash;                                                                \
}



/**
 * MACRO NAME: _IX_CC_ETH_RX_COPY_MAC_ADDR
 *
 * DESCRIPTION: This macro copies a MAC address from a src array
 *              to a dest array.
 *
 * @Param: arg_pDestMacAddr - IN: pointer to the dest array.
 * @Param: arg_pSrcMacAddr - IN: pointer to the src array.
 *
 * @Return:  - None
 */
#define _IX_CC_ETH_RX_COPY_MAC_ADDR(                           \
    arg_pDestMacAddr,                                          \
    arg_pSrcMacAddr)                                           \
{                                                              \
    arg_pDestMacAddr[5] = arg_pSrcMacAddr[5];                  \
    arg_pDestMacAddr[4] = arg_pSrcMacAddr[4];                  \
    arg_pDestMacAddr[3] = arg_pSrcMacAddr[3];                  \
    arg_pDestMacAddr[2] = arg_pSrcMacAddr[2];                  \
    arg_pDestMacAddr[1] = arg_pSrcMacAddr[1];                  \
    arg_pDestMacAddr[0] = arg_pSrcMacAddr[0];                  \
}



#if defined(__cplusplus)
}
#endif /* end defined(__cplusplus) */

#endif /* end !defined(__IX_CC_ETH_RX_INTERNAL_H__) */
