/**
 * ============================================================================
 * = 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-2001 Intel Corporation. All rights reserved.
 *
 * = PRODUCT
 *      Intel(r) IXA SDK 3.0 for the IXP2000 Network Processor, Release 6
 *
 * = FILENAME
 *      ix_cc_stkdrv_vidd.h
 *
 * = DESCRIPTION
 *      Header file for the local VIDD component of the Stack Driver.
 *
 * = AUTHOR
 *      Aaron Luk
 *      aaron.luk@intel.com
 *
 * = CHANGE HISTORY
 *       6/19/2002 - initial revision
 *
 * ============================================================================
 * $Id: ix_cc_stkdrv_vidd.h,v 1.31 2003/01/25 22:25:52 asluk Exp $
 */

#if !defined(__IX_CC_STKDRV_VIDD_H__)
#define __IX_CC_STKDRV_VIDD_H__

#include "ix_cc_error.h"
#include <stdio.h>
#include "ix_ossl.h"
#include "ix_rm.h"
#include "ix_cc.h"
#include "ix_cc_properties.h"
#include "cc/ix_cc_stkdrv_common.h"

#include "vxWorks.h"
#include "assert.h"
#include "cacheLib.h"
#include "end.h"            /* Common END structures. */
#include "errno.h"
#include "etherLib.h"
#include "etherMultiLib.h"      /* multicast stuff. */
#include "m2Lib.h"
#include "memLib.h"
#include "muxLib.h"
#include "muxTkLib.h"
#include "net/if.h"
#include "net/if_subr.h"
#include "net/mbuf.h"
#include "net/protosw.h"
#include "net/route.h"
#include "netBufLib.h"
#include "netLib.h"
#include "netinet/if_ether.h"
#include "netinet/in.h"
#include "netinet/in_systm.h"
#include "netinet/in_var.h"
#include "netinet/ip.h"
#include "sys/ioctl.h"
#include "sys/socket.h"

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

/**
 * Pre-processor symbol and macro definitions.
 */

/* Number of buffers in VIDD buffer pool. */
#define IX_CC_STKDRV_VIDD_NUM_ELEMENTS 2048

/**
 * Type definitions.
 */

    
/**
 * TYPENAME: ix_cc_stkdrv_vidd_physical_if_node
 * 
 * DESCRIPTION: This list of data structures are created upon
 * initialization by the VIDD and represent the hardware network
 * interfaces.
 *
 */
typedef struct ix_s_cc_stkdrv_vidd_ctrl ix_cc_stkdrv_vidd_ctrl;
typedef struct ix_s_cc_stkdrv_vidd_physical_if_node ix_cc_stkdrv_vidd_physical_if_node;
struct ix_s_cc_stkdrv_vidd_physical_if_node
{
    /* corresponding END_OBJ struct */
    END_OBJ end;

    /* pointer to the cookie used for MUX communication */
    void* pMuxCookie;

    /* circular reference to VIDD control structure */
    ix_cc_stkdrv_vidd_ctrl* pViddCtrl;

    /* pointer to a context on the CC side, used when passing packets from the VIDD. */
    void* pCCPktContext;

    /* Pointer to port info shared between the CC Module and the VIDD. */
    ix_cc_stkdrv_physical_if_info* pPhysicalIfInfo;

    /* next interface structure in the list of the structures. */
    ix_cc_stkdrv_vidd_physical_if_node* pNextPhysicalIf;
};

/**
 * TYPENAME: ix_cc_stkdrv_vidd_fp_node
 * 
 * DESCRIPTION: This is the structure representing a Forwarding Plane Object.
 * It is constructed as a linked list for future expansion of FPs.
 * Created by VIDD during initialization.
 *
 */
typedef struct ix_s_cc_stkdrv_vidd_fp_node ix_cc_stkdrv_vidd_fp_node;
struct ix_s_cc_stkdrv_vidd_fp_node
{
    /* ID of this forwarding plane */
    ix_uint32 fpId;
    
    /* Head of linked list of physical interfaces for the forwarding plane */
    ix_cc_stkdrv_vidd_physical_if_node* pPhysicalIfs;
    
    /* number of ports on this FP. */
    ix_uint32 numPorts;

    /* Pointer to next FP in the list - in this release this will be NULL */
    ix_cc_stkdrv_vidd_fp_node* pNextFp;
};


/**
 * TYPENAME: ix_cc_stkdrv_vidd_ctrl
 * 
 * DESCRIPTION: This structure is defined by the driver and is created during
 * the initialization. It holds the control information about interfaces and
 * forwarding planes, and can be used as a context for all communication
 * between the CC Module and the VIDD.
 *
 */
struct ix_s_cc_stkdrv_vidd_ctrl
{
    /* list of forwarding planes */
    ix_cc_stkdrv_vidd_fp_node* pFps;

    /**
     * Memory cookie used by MUX buffering - this identifies
     * the buffer pool that is shared among all VIDD interfaces.
     */
    NET_POOL_ID pNetPool;

    /**
     * Pointer to Mblk memory area used to create the buffer pool.
     * We must store this pointer at initialization and free its
     * memory at shutdown.
     */
    void* pMclBlkCfg;

    /**
     * Pointer to cluster memory area used to create the buffer pool.
     * We must store this pointer at initialization and free its
     * memory at shutdown.
     */
    void* pClustMem;

    /* handle to ix buffer freelist used to get buffers for transmit */
    ix_buffer_free_list_handle hFreeList;
};



/**
 * Prototypes for interface functions.
 */


/**
 * NAME: ix_cc_stkdrv_vidd_fini
 *
 * DESCRIPTION: This function is called by the CC Module to shutdown the local
 * VIDD and free any memory allocated to it.
 * 
 * @Param:  - IN void* arg_pContext - pointer to context, in this case the VIDD
 *          control structure.
 *
 * @Return: IX_SUCCESS
 */
ix_error ix_cc_stkdrv_vidd_fini(
                                void* arg_pContext
                                );



/**
 * NAME: ix_cc_stkdrv_vidd_npt_load
 *
 * DESCRIPTION: This function registers a port with the VxWorks MUX layer.
 * The user does not call this function directly - the VxWorks MUX layer uses it
 * as an entry point when adding a new physical interface.  This function
 * is implemented as a two-pass algorithm - the MUX layer calls this
 * function twice - once with an empty initialization string, and then with
 * the real initialization string.
 * 
 * @Param:  - IN void* pBsp - optional BSP-specific information.  This will
 *          be used as a context, in this case a pointer to the VIDD control
 *          structure.
 * @Param:  - INOUT char* initString - on the first pass of this function,
 *          initString is passed in as an empty allocated string, and the
 *          base name of the interface (e.g. "eth") is copied into it.  On
 *          the second pass, initString is NULL.
 *
 * @Return: Pointer to the END_OBJ structure contained in the VIDD interface data structure.
 *          NULL
 */
END_OBJ* ix_cc_stkdrv_vidd_npt_load(
                                    char* initString,
                                    void* pBsp
                                   );

/**
 * NAME: ix_cc_stkdrv_vidd_npt_unload
 *
 * DESCRIPTION: This function is called by the MUX to "release" the device.
 * The function is called for each port that has been activated by call to
 * the ix_cc_stkdrv_vidd_npt_load().
 * 
 * @Param:  - IN END_OBJ* pEnd - Pointer to END_OBJ data structure
 *          allocated by the Load() function.
 *
 * @Return: OK
 */
STATUS ix_cc_stkdrv_vidd_npt_unload(
                                      END_OBJ* pEnd
                                      );

/**
 * NAME: ix_cc_stkdrv_vidd_npt_start
 *
 * DESCRIPTION: This function brings up IXP network interface
 * specified by END_OBJ structure and makes the interface active
 * and available to the OS.
 * 
 * @Param:  - IN END_OBJ* pEnd - Pointer to END_OBJ data structure
 *          allocated by the Load() function.
 * @Param:  - INOUT
 * @Param:  - OUT  
 *
 * @Return: OK
 */
STATUS ix_cc_stkdrv_vidd_npt_start(
                                     END_OBJ* pEnd
                                     );

/**
 * NAME: ix_cc_stkdrv_vidd_npt_stop
 *
 * DESCRIPTION: The Stop() function brings down IXP interface
 * specified by END_OBJ structure and deactivates the interface.
 * 
 * @Param:  - IN END_OBJ* pEnd - Pointer to END_OBJ data structure
 *          allocated by the Load() function.
 * @Param:  - INOUT
 * @Param:  - OUT  
 *
 * @Return: OK
 *          ERROR
 */
STATUS ix_cc_stkdrv_vidd_npt_stop(
                                    END_OBJ* pEnd
                                    );
/**
 * NAME: ix_cc_stkdrv_vidd_npt_ioctl
 *
 * DESCRIPTION: The VIDD needs to support ioctl commands to keep
 * the ioctl interface with existing network protocols. The table
 * below gives the list of commonly-used ioctl commands.
 * Command          Function                        Data Type       Supported
 * --------------------------------------------------------------------------
 * SIOCGIFMTU       Get MTU.                        char*           Yes
 * EIOCSFLAGS       Set device flags                int             Yes
 * EIOCGFLAGS       Get device flags                int             Yes
 * EIOCSADDR        Set device address              char*           No
 * EIOCGADDR        Get device address              char*           Yes
 * EIOCMULTIADD     Add multicast address           char*           No
 * EIOCMULTIDEL     Delete multicast address        char*           No
 * EIOCMULTIGET     Get multicast list              MULTI_TABLE*    No
 * EIOCPOLLSTART    Set device into polling mode    NULL            No
 * EIOCPOLLSTOP     Set device into interrupt mode  NULL            No
 * EIOCGFBUF        Get minimum first buffer
 *                  for chaining                    int             Yes
 * EIOCGHDRLEN      Get the size of the data
 *                  link header                     int             Yes
 * EIOCGNPT         Query a driver to determine
 *                  whether it is a NPT driver      int             Yes
 * EIOCGMIB2233     retrieves the RFC2233
 *                  MIB II table                    M2_ID*          Yes
 * EIOCGMIB2        Get the MIB-II counters
 *                  from the driver                 char*           Yes
 *
 * 
 * @Param:  - IN END_OBJ* pEnd - Pointer to END_OBJ data structure
 *          allocated by the Load() function.
 * @Param:  - IN int command - ioctl command.
 * @Param:  - INOUT caddr_t buffer - character buffer holding response from the command.
 *
 * @Return: OK
 *          EINVAL
 */
int ix_cc_stkdrv_vidd_npt_ioctl(
                                END_OBJ* pEnd,
                                int command,
                                caddr_t buffer
                                );

/**
 * NAME: ix_cc_stkdrv_vidd_npt_send
 *
 * DESCRIPTION: The MUX interface calls this function when the network
 * protocol is sending a network packet. Network buffers are represented 
 * by an mBlk chain in VxWorks. This function takes the packet stored in
 * the mBlk, performs all necessary checks on the packet, and stores the
 * packet data in an ix_buffer_handle before calling the stack driver
 * core component API ix_cc_stkdrv_send_packet() function.
 * 
 * @Param:  - IN END_OBJ* pEnd - pointer to the END_OBJ structure.
 *          It identifies the transmit interface.
 * @Param:  - IN M_BLK_ID pMblk - mBlk chain containing the network
 *          buffer. The data represents the full link layer frame. 
 * @Param:  - IN char* dstMacAddr - destination MAC address from the
 *          OS stack. Ignored by this function as the IPv4 CC will do a
 *          route lookup to obtain the destination MAC address.
 * @Param:  - IN long netType - network service type.  Ignored by VIDD.
 * @Param:  - IN void* pSpare - optional network service data.  Ignored by VIDD.
 *
 * @Return: OK
 *          ERROR
 */
STATUS ix_cc_stkdrv_vidd_npt_send(
                                  END_OBJ* pEnd, 
                                  M_BLK_ID pMblk, 
                                  char* dstMacAddr,
                                  long netType,
                                  void* pSpare
                                  );

/**
 * NAME: ix_cc_stkdrv_vidd_npt_mCastAddrAdd
 *
 * DESCRIPTION: This function adds a new link-layer multicast address
 * to the table of multicast addresses for the IXP interface - in the
 * initial release this call does not affect the underlying hardware.
 * 
 * @Param:  - IN END_OBJ* pEnd - pointer to the END_OBJ structure to
 *          help identify the IXP port.
 * @Param:  - IN char* pAddress - physical address to add to the
 *          Multicast table.
 *
 * @Return: OK
 *          ERROR
 */
STATUS ix_cc_stkdrv_vidd_npt_mCastAddrAdd(
                                          END_OBJ * pEnd,
                                          char* pAddress
                                          );

/**
 * NAME: ix_cc_stkdrv_vidd_npt_mCastAddrDel
 *
 * DESCRIPTION: The function removes previously added link-layer
 * multicast address - in the initial release this does not affect
 * the underlying hardware.
 * 
 * @Param:  - IN END_OBJ* pEnd - pointer to the END_OBJ structure to
 *          help identify the IXP port.
 * @Param:  - IN char* pAddress - physical address to delete from the
 *          Multicast table.
 *
 * @Return: OK
 *          ERROR
 */
STATUS ix_cc_stkdrv_vidd_npt_mCastAddrDel(
                                          END_OBJ * pEnd,
                                          char* pAddress
                                          );

/**
 * NAME: ix_cc_stkdrv_vidd_npt_mCastAddrGet
 *
 * DESCRIPTION: This function gets the list of all multicast
 * addresses that are active on the interface. 
 * 
 * @Param:  - IN END_OBJ* pEnd - pointer to the END_OBJ structure to
 *          help identify the IXP port.
 * @Param:  - IN MULTI_TABLE* pTable - pointer to the structure where
 *          the list will be put.
 *
 * @Return: OK
 *          ERROR
 */
STATUS ix_cc_stkdrv_vidd_npt_mCastAddrGet(
                                          END_OBJ * pEnd,
                                          MULTI_TABLE* pTable
                                          );

/**
 * NAME: ix_cc_stkdrv_vidd_npt_pollSend
 *
 * DESCRIPTION: Polling-mode equivalent to the send() routine.
 * This routine should transfer frames directly to the output core
 * component or exit immediately if the core component is busy -
 * this is not supported in the initial release and always returns ERROR.
 * 
 * @Param:  - IN END_OBJ* pEnd - pointer to the END_OBJ structure. It
 *          identifies the transmit interface.
 * @Param:  - IN M_BLK_ID pMblk - mBlk chain containing the network
 *          buffer. The data represents the full link layer frame.
 * @Param:  - IN char* dstMacAddr - destination MAC address from the
 *          OS stack. Ignored by this function as the VIDD will do its
 *          own route table lookup to obtain the destination MAC address.
 * @Param:  - IN long netType - network service type.
 * @Param:  - IN void* pSpare - optional network service data.
 *
 * @Return: ERROR
 */
STATUS ix_cc_stkdrv_vidd_npt_pollSend(END_OBJ* pEND,
                                      M_BLK_ID pPkt,
                                      char* dstAddr,
                                      long netType,
                                      void * pSpareData
                                      );

/**
 * NAME: ix_cc_stkdrv_vidd_npt_pollRcv
 *
 * DESCRIPTION: The current implementation of core component model
 * does not support PollReceive().  Therefore this function always
 * returns an error.
 * 
 * @Param:  - IN END_OBJ* pEnd - pointer to the END_OBJ structure. It
 *          identifies the transmit interface.
 * @Param:  - IN M_BLK_ID pMblk - mBlk chain containing the network
 *          buffer. The data represents the full link layer frame.
 * @Param:  - IN long* pNetSvc - network service type.
 * @Param:  - IN long* pNetOffset - offset to network frame.
 * @Param:  - IN void* pSpare - optional network service data.
 *
 * @Return: OK
 *          ERROR
 */
STATUS ix_cc_stkdrv_vidd_npt_pollRcv(END_OBJ* pEND,
                                     M_BLK_ID pMblk,
                                     long* pNetSvc,
                                     long* pNetOffset, 
                                     void* pSpareData
                                     );

/**
 * NAME: ix_cc_stkdrv_vidd_npt_pollRcv
 *
 * DESCRIPTION: For Ethernet interfaces, the stack will attempt to
 *              prepend a MAC address to outgoing packets.  Thus this
 *              function just returns OK, because the MAC address
 *              will be formed by the uBlocks.
 * 
 * @Param:  - IN M_BLK_ID arg_pData - mBlk chain containing outgoing data.
 * @Param:  - IN M_BLK_ID arg_pSrc - source address, in an mBlk.
 * @Param:  - IN M_BLK_ID arg_pDst - destination address, in an mBlk.
 * @Param:  - IN BOOL arg_bool.
 *
 * @Return: NULL.
 */
M_BLK_ID ix_cc_stkdrv_vidd_npt_formAddress(
                                         M_BLK_ID arg_pData,
                                         M_BLK_ID arg_pSrc,
                                         M_BLK_ID arg_pDst,
                                         BOOL arg_bool
                                         );

/**
 * NAME: ix_cc_stkdrv_vidd_receive_pkt
 *
 * DESCRIPTION: This is the VIDD entry point (packet processing
 * callback invoked by the CC Module) that receives packets from
 * the CC Module and passes them to the local network stack.
 * 
 * @Param:  - IN ix_buffer_handle arg_hBuffer - handle to the input packet.
 * @Param:  - IN void* arg_pCtx - pointer to the context, in this case
 *          the port structure.
 * @Param:  - IN ix_cc_stkdrv_packet_type packetType - packet type.
 *          Ignored in the VIDD case.
 *
 * @Return: IX_SUCCESS
 *          IX_CC_ERROR_OOM_SYSTEM
 *          IX_CC_ERROR_ENTRY_NOT_FOUND
 *          IX_CC_ERROR_NULL
 */
ix_error ix_cc_stkdrv_vidd_receive_pkt(
                                       ix_buffer_handle arg_pBuffer,
                                       void* arg_pCtx, 
                                       ix_cc_stkdrv_packet_type packetType
                                       );


/**
 * NAME: ix_cc_stkdrv_vidd_receive_msg_int
 *
 * DESCRIPTION: This is the VIDD entry point (integer message processing
 * callback invoked by the CC Module) that receives integer messages
 * from the CC Module and processes the interface property updates
 * contained within those messages.
 * 
 * @Param:  - IN ix_cc_stkdrv_vidd_msg_id arg_MsgId - identification of the message.
 * @Param:  - IN ix_uint32 arg_msg - integer message value.
 * @Param:  - IN void *arg_pContext - pointer to the context.  Here the context
 *          is the physical interface structure.
 * @Param:  - OUT void** arg_ppReplyMsg - location of pointer to reply message,
 *          if any.
 * @Param:  - OUT ix_uint32* arg_pReplyMsgSize - pointer to size of reply message,
 *          if any.
 *
 * @Return: IX_SUCCESS
 *          IX_CC_ERROR_NULL
 *          IX_CC_STKDRV_VIDD_ERROR_MUX
 *          IX_CC_ERROR_UNDEFINED_MSG
 */
ix_error ix_cc_stkdrv_vidd_receive_msg_int(
                                           ix_cc_stkdrv_vidd_msg_id arg_msgId,
                                           const ix_uint32 arg_msg,
                                           void *arg_pContext,
                                           void** arg_ppReplyMsg,
                                           ix_uint32* arg_pReplyMsgSize
                                           );

/**
 * Exported variables.
 */



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

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