added del_ip, del_mac functions
[keystone-rtos/netapi.git] / ti / runtime / netapi / src / netcp_cfg.c
index eb971fa1568db72310f2a7e6bf2bc4abbaeb07e1..abc5ebb27a86d8776676a471db87e1560c002dc3 100644 (file)
-/**********************************************************
- * file: netcp_cfg.c
- * purpose: netcp configurations routines
- **************************************************************
- * FILE: netcp_cfg.c
- * 
- * DESCRIPTION:  netcp configuration main source file for user space transport
- *               library
- * 
- * REVISION HISTORY:  rev 0.0.1 
- *
- *  Copyright (c) Texas Instruments Incorporated 2010-2011
- * 
- *  Redistribution and use in source and binary forms, with or without 
- *  modification, are permitted provided that the following conditions 
- *  are met:
- *
- *    Redistributions of source code must retain the above copyright 
- *    notice, this list of conditions and the following disclaimer.
- *
- *    Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the 
- *    documentation and/or other materials provided with the   
- *    distribution.
- *
- *    Neither the name of Texas Instruments Incorporated nor the names of
- *    its contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- ******************************************************/
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include "netapi.h"
-#include "netcp_cfg.h"
-#include "netapi_loc.h"
-
-/******************************************************************
- ********************Utility*************************************
-*******************************************************************/
-
-
-//get a free transaction id
-static NetapiNwalTransInfo_t *  netapi_GetFreeTransInfo(NETAPI_GLOBAL_T *p_global, nwal_TransID_t *pTransId)
-{
-         uint16_t    count=0;
-
-       count=0;
-        while(count < TUNE_NETAPI_MAX_NUM_TRANS)
-        {
-            if((p_global->nwal_context.transInfos[count].inUse) != nwal_TRUE)
-            {
-                p_global->nwal_context.transInfos[count].inUse = nwal_TRUE;
-                *pTransId = count;
-                return(&p_global->nwal_context.transInfos[count]);
-            }
-            count++;
-        }
-         
-        /* trouble.  need to wait for one to free up*/
-        /* to do: handle this by forcing a poll of cntrl queue*/
-        printf(">netcp_cfg: trying to get free transaction slot but all full!!\n");
-        return NULL;
-
-}
-//internal:  insert an IP address into iface
-void netcp_cfgp_insert_ip(NETAPI_NWAL_GLOBAL_CONTEXT_T *p, 
-                          nwal_IpType ipType,
-                          nwalIpAddr_t *ip_addr, 
-                          nwalIpOpt_t *ip_qualifiers, 
-                          int iface_no,
-                          void * handle)
-{
-int i;
-for(i=0;i<TUNE_NETAPI_MAX_IP_PER_INTERFACE;i++)
-{
-   if (!p->interfaces[iface_no].ips[i].in_use)
-   {
-        p->interfaces[iface_no].ips[i].in_use=1;
-        memcpy(&p->interfaces[iface_no].ips[i].ip_addr, ip_addr, sizeof(nwalIpAddr_t));
-        if(ip_qualifiers)
-        memcpy(&p->interfaces[iface_no].ips[i].ip_qualifiers, ip_qualifiers, sizeof(nwalIpOpt_t));
-        else
-        memset(&p->interfaces[iface_no].ips[i].ip_qualifiers, 0, sizeof(nwalIpOpt_t));
-        p->interfaces[iface_no].ips[i].ip_type = ipType;
-        p->interfaces[iface_no].ips[i].nwal_handle = handle;
-        return;
-   }
-}
-printf(">netcp_cfg - add ip:  no room in table\n");
-
-}
-
-
-//internal: instert interface info into global context
-void netcp_cfgp_insert_mac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p, unsigned char * p_mac, 
-                           int iface_no, int state, NETCP_CFG_VLAN_T vlan, void * handle)
-{
-   if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_INTERFACES))
-   {
-        memset(&p->interfaces[iface_no],0,sizeof(NETCP_INTERFACE_T));
-       p->interfaces[iface_no].in_use = 1;
-       memcpy(&p->interfaces[iface_no].mac[0], p_mac,6);
-        p->interfaces[iface_no].state = state;
-       //todo p->interfaces[iface_no].vlan = vlan;
-       p->interfaces[iface_no].nwal_handle = handle; //save handle assoicated with this rule
-   }
-   else printf(">netcp_cfg insert interface # out of range %d\n",iface_no);
-
-}
-//internal: clear inteface entry
-void netcp_cfgp_delete_mac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,int iface_no)  
-{
-   if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_INTERFACES))
-   {
-        p->interfaces[iface_no].in_use = 0;
-   }
-   else printf(">netcp_cfg delete interface # out of range %d\n",iface_no);
-
-}
-
-
-//internal:
-
-/***********************************************************************************/
-/****************************************API****************************************/
-/***********************************************************************************/
-
-
-/*****************************************************************
- *  Queury Stats
- ****************************************************************/
-void netcp_cfgReqStats(NETAPI_T  h, NETCP_CFG_STATS_CB cb, int doClear, int *err) 
-{
-nwal_RetValue ret;
-NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
-NetapiNwalTransInfo_t *pTransInfo;
-nwal_TransID_t     transId;
-if ((!n) || (!cb)) {*err = NETAPI_ERR_BAD_INPUT; return ;}
-*err =0;
-
-pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &transId);
-if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return ;}
-pTransInfo->transType = NETAPI_NWAL_HANDLE_STAT_REQUEST;
-pTransInfo->netapi_handle = h;
-n->nwal_local.stats_cb = cb;
-ret = nwal_getPAStats( ((NETAPI_GLOBAL_T *) n->global)->nwal_context.nwalInstHandle,
-                          transId,
-                          NULL,
-                          doClear);
-if(ret !=  nwal_OK)
-{
-   pTransInfo->inUse = nwal_FALSE;
-   *err = NETAPI_ERR_BUSY;  //no resources??
-   printf("> netcp_cfg reqStats failed, err=%d\n",ret);
-}
-
-}
-/*****************************************************************
- *  CREATE A MAC INTERFACE
- ****************************************************************/
-NETCP_CFG_MACIF_T  netcp_cfgCreateMacInterface(
-                  NETAPI_T  h,
-                  uint8_t *p_mac,
-                 int  iface_no, 
-                  int switch_port, 
-                  NETCP_CFG_ROUTE_HANDLE_T  route,
-                  NETCP_CFG_VLAN_T  vlan,  //future
-                  int state,  //0=down, 1=up  //ignored
-                  int * err
-                  )
-{
-NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
-nwalMacParam_t   MacInfo= {
-    0,      /* validParams */
-    0,      /* ifNum */
-    0,      /* vlanId      */
-    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },      /* Local mac */
-    NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */
-    NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */
-    CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */
-    QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */
-};
-
-nwal_RetValue       retValue;
-NetapiNwalTransInfo_t *pTransInfo;
-nwal_TransID_t     trans_id;
-
-    if ((!n) || (!p_mac)) {*err = NETAPI_ERR_BAD_INPUT; return -1;}
-    *err =0;
-
-    pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
-    if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return -1;}
-    pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC;
-    pTransInfo->netapi_handle = h; 
-
-    /* set up MacInfo */
-    memcpy(&MacInfo.macAddr,p_mac,6); 
-    /* todo: vlan */
-    MacInfo.ifNum = switch_port;  /* todo: check for 0/1 relative*/
-
-#if 0  //todo
-    if (route != NULL)
-    {
-        MacInfo.appRxPktFlowId = ((NETCP_CFG_FLOW_T *)(route.flow))->flowid;
-        MacInfo.appRxPktQueue = PKTIO_GET_Q(route->p_dest_q);
-        //handle action ??
-    }
-#endif
-    pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
-    retValue = nwal_setMacIface( ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
-                                  trans_id,
-                                  (nwal_AppId) (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no),
-                                  &MacInfo,
-                                  &pTransInfo->handle);
-    if(retValue !=  nwal_OK)
-    {
-       *err = NETAPI_ERR_NWAL_ERR0;
-        printf (">netcp cfg - ERROR: nwal_setMacIface returned Error Code %d\n",
-                    retValue);
-        pTransInfo->inUse = nwal_FALSE;
-        return -1;
-    }
-    //pTransInfo->inUse = nwal_FALSE;
-
-    //wait here until its done since scheduler isn't running yet most likely..
-    // todo:  make this handled by scheduler poll later ??
-    if(trans_id != NWAL_TRANSID_SPIN_WAIT)
-    {
-        n->nwal_local.numPendingCfg++;
-        while ((volatile) n->nwal_local.numPendingCfg)
-        {
-           // if response is there, then this poll squirts out in the CTl poll callback, 
-            // which handles the rest (including decrmenting #pending!!
-            nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
-        }
-    }
-    printf (">netcp cfg: MAC i/f added\n");
-    netcp_cfgp_insert_mac(&netapi_get_global()->nwal_context, 
-                          p_mac, iface_no, state,vlan,
-                          (void *) pTransInfo->handle);
-    pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;
-    pTransInfo->inUse = nwal_FALSE;
-    return  (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no);
-}
-
-
-/*****************************************************************/
-/***************Delete a mac interface****************************/
-/*****************************************************************/
-void netcp_cfgDelMac(NETAPI_T h,int iface_no,  int *err)
-{
-
-    *err =0;
-
-    netcp_cfgp_delete_mac(&netapi_get_global()->nwal_context,  iface_no);
-    printf(">netcp_cfg:  del mac not fully implemented \n");
-    return;
-}
-
-
-/*****************************************************************/
-/***************Add IP to MAC interface****************************/
-/*****************************************************************/
-NETCP_CFG_IP_T  netcp_addIp(
-                  NETAPI_T  h,
-                  int  iface_no,
-                  nwal_IpType ipType,
-                 nwalIpAddr_t  * ip_addr,
-                 nwalIpOpt_t * ip_qualifiers,
-                  NETCP_CFG_ROUTE_HANDLE_T  route,  //NULL for default
-                  int * err
-                  )
-{
-NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
-void * n_handle;
-nwalIpParam_t    nwalIpParam= {
-    pa_IPV4,      /* IP Type */
-    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Dest IP */
-    { 0x0,0,0,0},/* IP Options */
-    NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */
-    NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */
-    CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */
-    QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */
-};
-nwal_RetValue       retValue;
-NetapiNwalTransInfo_t *pTransInfo;
-nwal_TransID_t     trans_id;
-
-
-     //verify that iface has been configurred 
-     if ((iface_no<0) || (iface_no>= TUNE_NETAPI_MAX_INTERFACES)) {*err = NETAPI_ERR_BAD_INPUT; return -1;}
-
-     if(netapi_get_global()->nwal_context.interfaces[iface_no].in_use)
-     {
-       n_handle =  netapi_get_global()->nwal_context.interfaces[iface_no].nwal_handle;
-     }
-     else
-     {
-       *err = NETAPI_ERR_BAD_INPUT;
-       return -1;
-     }
-
-     //get a transaction object for config action
-    pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
-    if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return -1;}
-    pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;
-    pTransInfo->netapi_handle = h;
-
-     //build nwalIpParam
-     memcpy(&nwalIpParam.locIpAddr,ip_addr, sizeof(nwalIpAddr_t));
-     nwalIpParam.ipType=ipType;
-     if(route)
-     {
-          //todo: support app defined routes
-     } 
-     else{} //use nwal defaults
-     if (ip_qualifiers)
-       memcpy(&nwalIpParam.ipOpt,ip_qualifiers, sizeof(nwalIpOpt_t)); 
-     else
-        memset(&nwalIpParam.ipOpt,0, sizeof(nwalIpOpt_t));
-
-     //perform config action
-     pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
-     retValue = nwal_setIPAddr(   netapi_get_global()->nwal_context.nwalInstHandle,
-                                  trans_id,
-                                  (nwal_AppId) (NETAPI_NETCP_MATCH_GENERIC_IP | iface_no),
-                                  n_handle,
-                                  &nwalIpParam,
-                                  &pTransInfo->handle);
-
-    if(retValue !=  nwal_OK)
-    {
-        *err = NETAPI_ERR_NWAL_ERR0;
-        printf (">netcp cfg: nwal_setIP returned Error Code %d\n",
-                    retValue);
-        pTransInfo->inUse = nwal_FALSE;
-        return -1;
-    }
-    //wait here until its done since scheduler isn't running yet most likely..
-    // todo:  make this handled by scheduler poll later ??
-    if(trans_id != NWAL_TRANSID_SPIN_WAIT)
-    {
-        n->nwal_local.numPendingCfg++;
-        while ((volatile) n->nwal_local.numPendingCfg)
-        {
-            // if response is there, then this poll squirts out in the CTl poll callback, 
-            // which handles the rest (including decrmenting #pending!!
-            nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
-        }
-    }
-    printf (">netcp cfg: IP added\n");
-    netcp_cfgp_insert_ip(&netapi_get_global()->nwal_context, ipType, 
-                          ip_addr, ip_qualifiers, iface_no, 
-                          pTransInfo->handle);
-    pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;
-    pTransInfo->inUse = nwal_FALSE;
-    return  (NETAPI_NETCP_MATCH_GENERIC_IP | iface_no);
-}
-
-
-
-/*************************************************************************/
-/*********************************INTERNAL*******************************/
-/************************************************************************/
-
-/***************************************************************
- ********************METCP CMD Reply Callback******************
- ***************************************************************/
-void netapi_NWALCmdCallBack (nwal_AppId        appHandle,
-                          uint16_t            trans_id,
-                          nwal_RetValue     ret)
-{
-    NetapiNwalTransInfo_t * p_trans;
-    NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL;
-
-    if(trans_id == NWAL_TRANSID_SPIN_WAIT)
-    {
-        netapi_get_global()->nwal_context.numBogusTransIds++;
-        return;
-    }
-
-    p_trans= &netapi_get_global()->nwal_context.transInfos[trans_id];
-    p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;
-
-    if(ret != nwal_OK)
-    {
-        printf (">netcp cfg : NWALCmdCallBack returned Error Code %d\n",
-                    ret);
-       //todo: atomic inc
-        netapi_get_global()->nwal_context.numCmdFail++;
-    }
-    else
-    {
-       //todo: atomic inc
-        netapi_get_global()->nwal_context.numCmdPass++;
-        switch(p_trans->transType)
-        {
-            case NETAPI_NWAL_HANDLE_TRANS_MAC:
-            {
-                if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
-                {
-                    p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;
-                }
-                else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
-                {
-                    p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
-                }
-                break;
-            }
-            case NETAPI_NWAL_HANDLE_TRANS_IP:
-            {
-                 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
-                {
-                    p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;
-                }
-                else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
-                {
-                    p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
-                }
-                break;
-            }
-#if 0
-            case TEST_NWAL_HANDLE_TRANS_PORT:
-            {
-                if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING)
-                {
-                    testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN;
-                }
-                else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING)
-                {
-                    testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE;
-                }
-                break;
-            }
-            case TEST_NWAL_HANDLE_TRANS_SEC_ASSOC:
-            {
-                if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING)
-                {
-                    testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN;
-                }
-                else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING)
-                {
-                    System_printf ("Set Security Assoc  Close ACK received for trans_id: %d\n",
-                                testNwLocContext.transInfos[trans_id].transType,trans_id);
-                    nwal_SystemFlush();
-                    testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE;
-                }
-                break;
-            }
-case TEST_NWAL_HANDLE_TRANS_SEC_POLICY:
-            {
-                if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING)
-                {
-                    testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN;
-                }
-                else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING)
-                {
-                    System_printf ("Set Security Policy  Close ACK received for trans_id: %d\n",
-                                testNwLocContext.transInfos[trans_id].transType,trans_id);
-                    nwal_SystemFlush();
-                    testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE;
-                }
-                break;
-            }
-#endif
-            default:
-            {
-                printf ("netcp cfg> Invalid transaction type %d for trans_id: %d\n",
-                    p_trans->transType,trans_id);
-                break;
-            }
-        }
-    }
-
-    p_local->numPendingCfg--;
-
-    if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_IDLE)
-    {
-        p_trans->inUse = nwal_FALSE;
-    }
-
-}
-
-
-/*******************************************************/
-/**************stats reply callback**********************/
-/*******************************************************/
-void netapi_NWALCmdPaStatsReply (nwal_AppId        appHandle,
-                              nwal_TransID_t    trans_id,
-                              paSysStats_t      *stats)
-{
-    NetapiNwalTransInfo_t * p_trans;
-    NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL;
-  
-    if(trans_id == NWAL_TRANSID_SPIN_WAIT)
-    {
-        netapi_get_global()->nwal_context.numBogusTransIds++;
-        return;
-    }
-
-    p_trans= &netapi_get_global()->nwal_context.transInfos[trans_id];
-    p_trans->inUse = nwal_FALSE;
-    p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;
-
-    //save a local copy  of some stuff*/
-    p_local->numL2PktsRecvd=stats->classify1.nPackets;
-    p_local->numL3PktsRecvd=stats->classify1.nIpv4Packets;
-#if 0
-    p_local->numL4PktsRecvd=stats->;
-    p_local->numL4PktsSent=stats->;
-    p_local->TxErrDrop=stats->;
-#endif
-    //callout result to application !!
-    if (p_local->stats_cb) (*p_local->stats_cb)(p_trans->netapi_handle,stats);
-    
-} 
-
+/**********************************************************\r
+ * file: netcp_cfg.c\r
+ * purpose: netcp configurations routines\r
+ **************************************************************\r
+ * FILE: netcp_cfg.c\r
+ * \r
+ * DESCRIPTION:  netcp configuration main source file for user space transport\r
+ *               library\r
+ * \r
+ * REVISION HISTORY:  rev 0.0.1 \r
+ *\r
+ *  Copyright (c) Texas Instruments Incorporated 2010-2011\r
+ * \r
+ *  Redistribution and use in source and binary forms, with or without \r
+ *  modification, are permitted provided that the following conditions \r
+ *  are met:\r
+ *\r
+ *    Redistributions of source code must retain the above copyright \r
+ *    notice, this list of conditions and the following disclaimer.\r
+ *\r
+ *    Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the \r
+ *    documentation and/or other materials provided with the   \r
+ *    distribution.\r
+ *\r
+ *    Neither the name of Texas Instruments Incorporated nor the names of\r
+ *    its contributors may be used to endorse or promote products derived\r
+ *    from this software without specific prior written permission.\r
+ *\r
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \r
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \r
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \r
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \r
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \r
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+\r
+ ******************************************************/\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <unistd.h>\r
+#include <string.h>\r
+#include "netapi.h"\r
+#include "netcp_cfg.h"\r
+#include "netapi_loc.h"\r
+\r
+/******************************************************************\r
+ ********************Utility*************************************\r
+*******************************************************************/\r
+\r
+\r
+//get a free transaction id\r
+static NetapiNwalTransInfo_t *  netapi_GetFreeTransInfo(NETAPI_GLOBAL_T *p_global, nwal_TransID_t *pTransId)\r
+{\r
+         uint16_t    count=0;\r
+\r
+       count=0;\r
+        while(count < TUNE_NETAPI_MAX_NUM_TRANS)\r
+        {\r
+            if((p_global->nwal_context.transInfos[count].inUse) != nwal_TRUE)\r
+            {\r
+                p_global->nwal_context.transInfos[count].inUse = nwal_TRUE;\r
+                *pTransId = count;\r
+                return(&p_global->nwal_context.transInfos[count]);\r
+            }\r
+            count++;\r
+        }\r
+         \r
+        /* trouble.  need to wait for one to free up*/\r
+        /* to do: handle this by forcing a poll of cntrl queue*/\r
+        printf(">netcp_cfg: trying to get free transaction slot but all full!!\n");\r
+        return NULL;\r
+\r
+}\r
+\r
+//internal: find a free slot for IP rule in interface\r
+static int netcp_cfgp_find_ip_slot(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
+                          int iface_no)\r
+{\r
+   int i;\r
+   if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_INTERFACES))\r
+   {\r
+        return -1;\r
+   }\r
+   if (!p->interfaces[iface_no].in_use) return -1;\r
+\r
+   //find a free entry\r
+   for(i=0;i<TUNE_NETAPI_MAX_IP_PER_INTERFACE;i++)\r
+   {\r
+       if (!p->interfaces[iface_no].ips[i].in_use)\r
+       {\r
+           p->interfaces[iface_no].ips[i].in_use = 2; //pending\r
+           return i;\r
+       }\r
+   }\r
+   return -1;\r
+}\r
+\r
+//internal:  insert an IP address into iface\r
+static void netcp_cfgp_insert_ip(NETAPI_NWAL_GLOBAL_CONTEXT_T *p, \r
+                          nwal_IpType ipType,\r
+                          nwalIpAddr_t *ip_addr, \r
+                          nwalIpOpt_t *ip_qualifiers, \r
+                          int iface_no,\r
+                          int ip_slot,  //we 'reserved it already'\r
+                          void * handle)\r
+{\r
+        p->interfaces[iface_no].ips[ip_slot].in_use=1;\r
+        memcpy(&p->interfaces[iface_no].ips[ip_slot].ip_addr, ip_addr, sizeof(nwalIpAddr_t));\r
+        if(ip_qualifiers)\r
+        memcpy(&p->interfaces[iface_no].ips[ip_slot].ip_qualifiers, ip_qualifiers, sizeof(nwalIpOpt_t));\r
+        else\r
+        memset(&p->interfaces[iface_no].ips[ip_slot].ip_qualifiers, 0, sizeof(nwalIpOpt_t));\r
+        p->interfaces[iface_no].ips[ip_slot].ip_type = ipType;\r
+        p->interfaces[iface_no].ips[ip_slot].nwal_handle = handle;\r
+        return;\r
+}\r
+\r
+\r
+//internal: instert interface info into global context\r
+static void netcp_cfgp_insert_mac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p, unsigned char * p_mac, \r
+                           int iface_no, int state, NETCP_CFG_VLAN_T vlan, void * handle)\r
+{\r
+   if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_INTERFACES))\r
+   {\r
+        memset(&p->interfaces[iface_no],0,sizeof(NETCP_INTERFACE_T));\r
+       p->interfaces[iface_no].in_use = 1;\r
+       memcpy(&p->interfaces[iface_no].mac[0], p_mac,6);\r
+        p->interfaces[iface_no].state = state;\r
+       //todo p->interfaces[iface_no].vlan = vlan;\r
+       p->interfaces[iface_no].nwal_handle = handle; //save handle assoicated with this rule\r
+   }\r
+   else printf(">netcp_cfg insert interface # out of range %d\n",iface_no);\r
+\r
+}\r
+//internal: clear inteface entry\r
+static void netcp_cfgp_delete_mac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,int iface_no)  \r
+{\r
+   if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_INTERFACES))\r
+   {\r
+        p->interfaces[iface_no].in_use = 0;\r
+   }\r
+}\r
+//internal: free IP slot associated with ip address \r
+static void netcp_cfgp_delete_ip(\r
+         NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
+         int iface_no,\r
+         int ip_slot )\r
+{\r
+   if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_INTERFACES))\r
+   {\r
+        return ;\r
+   }\r
+   if (!p->interfaces[iface_no].in_use) return ;\r
+   if ((ip_slot <0)||(ip_slot>TUNE_NETAPI_MAX_IP_PER_INTERFACE)) return ;\r
+   p->interfaces[iface_no].ips[ip_slot].in_use=0;\r
+   return;\r
+}\r
+\r
+\r
+//internal: get IP handle associated with ip address \r
+static void *netcp_cfgp_get_ip_handle(\r
+         NETAPI_NWAL_GLOBAL_CONTEXT_T *p, \r
+         int iface_no,\r
+         int ip_slot )\r
+{\r
+   if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_INTERFACES))\r
+   {\r
+       return NULL;\r
+   }\r
+   if (!p->interfaces[iface_no].in_use) return NULL;\r
+   if ((ip_slot <0)||(ip_slot>=TUNE_NETAPI_MAX_IP_PER_INTERFACE)) return NULL;\r
+   if (!p->interfaces[iface_no].ips[ip_slot].in_use) return NULL;\r
+   return (void *) p->interfaces[iface_no].ips[ip_slot].nwal_handle;\r
+}\r
+\r
+//internal: get handle associated with interface\r
+static void* netcp_cfgp_get_mac_handle(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,int iface_no)\r
+{\r
+   if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_INTERFACES))\r
+   {\r
+       return NULL;\r
+   }\r
+   else if ( p->interfaces[iface_no].in_use)\r
+   {\r
+     return (void *) p->interfaces[iface_no].nwal_handle;\r
+   }\r
+   //no valid entry in slot\r
+   return NULL;\r
+}\r
+\r
+\r
+/***********************************************************************************/\r
+/****************************************API****************************************/\r
+/***********************************************************************************/\r
+\r
+\r
+/*****************************************************************\r
+ *  Queury Stats\r
+ ****************************************************************/\r
+void netcp_cfgReqStats(NETAPI_T  h, NETCP_CFG_STATS_CB cb, int doClear, int *err) \r
+{\r
+nwal_RetValue ret;\r
+NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
+NetapiNwalTransInfo_t *pTransInfo;\r
+nwal_TransID_t     transId;\r
+if ((!n) || (!cb)) {*err = NETAPI_ERR_BAD_INPUT; return ;}\r
+*err =0;\r
+\r
+pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &transId);\r
+if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return ;}\r
+pTransInfo->transType = NETAPI_NWAL_HANDLE_STAT_REQUEST;\r
+pTransInfo->netapi_handle = h;\r
+n->nwal_local.stats_cb = cb;\r
+ret = nwal_getPAStats( ((NETAPI_GLOBAL_T *) n->global)->nwal_context.nwalInstHandle,\r
+                          transId,\r
+                          NULL,\r
+                          doClear);\r
+if(ret !=  nwal_OK)\r
+{\r
+   pTransInfo->inUse = nwal_FALSE;\r
+   *err = NETAPI_ERR_BUSY;  //no resources??\r
+   printf("> netcp_cfg reqStats failed, err=%d\n",ret);\r
+}\r
+\r
+}\r
+/*****************************************************************\r
+ *  CREATE A MAC INTERFACE\r
+ ****************************************************************/\r
+NETCP_CFG_MACIF_T  netcp_cfgCreateMacInterface(\r
+                  NETAPI_T  h,\r
+                  uint8_t *p_mac,\r
+                 int  iface_no, \r
+                  int switch_port, \r
+                  NETCP_CFG_ROUTE_HANDLE_T  route,\r
+                  NETCP_CFG_VLAN_T  vlan,  //future\r
+                  int state,  //0=down, 1=up  //ignored\r
+                  int * err\r
+                  )\r
+{\r
+NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
+nwalMacParam_t   MacInfo= {\r
+    0,      /* validParams */\r
+    0,      /* ifNum */\r
+    0,      /* vlanId      */\r
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },      /* Local mac */\r
+    NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */\r
+    NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */\r
+    CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */\r
+    QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */\r
+};\r
+\r
+nwal_RetValue       retValue;\r
+NetapiNwalTransInfo_t *pTransInfo;\r
+nwal_TransID_t     trans_id;\r
+\r
+    if ((!n) || (!p_mac)) {*err = NETAPI_ERR_BAD_INPUT; return -1;}\r
+    *err =0;\r
+\r
+    pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
+    if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return -1;}\r
+    pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC;\r
+    pTransInfo->netapi_handle = h; \r
+\r
+    /* set up MacInfo */\r
+    memcpy(&MacInfo.macAddr,p_mac,6); \r
+    /* todo: vlan */\r
+    MacInfo.ifNum = switch_port;  /* todo: check for 0/1 relative*/\r
+\r
+#if 0  //todo\r
+    if (route != NULL)\r
+    {\r
+        MacInfo.appRxPktFlowId = ((NETCP_CFG_FLOW_T *)(route.flow))->flowid;\r
+        MacInfo.appRxPktQueue = PKTIO_GET_Q(route->p_dest_q);\r
+        //handle action ??\r
+    }\r
+#endif\r
+    pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;\r
+    retValue = nwal_setMacIface( ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
+                                  trans_id,\r
+                                  (nwal_AppId) (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no),\r
+                                  &MacInfo,\r
+                                  &pTransInfo->handle);\r
+    if(retValue !=  nwal_OK)\r
+    {\r
+       *err = NETAPI_ERR_NWAL_ERR0;\r
+        printf (">netcp cfg - ERROR: nwal_setMacIface returned Error Code %d\n",\r
+                    retValue);\r
+        pTransInfo->inUse = nwal_FALSE;\r
+        return -1;\r
+    }\r
+    //pTransInfo->inUse = nwal_FALSE;\r
+\r
+    //wait here until its done since scheduler isn't running yet most likely..\r
+    // todo:  make this handled by scheduler poll later ??\r
+    if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
+    {\r
+        n->nwal_local.numPendingCfg++;\r
+        while ((volatile) n->nwal_local.numPendingCfg)\r
+        {\r
+           // if response is there, then this poll squirts out in the CTl poll callback, \r
+            // which handles the rest (including decrmenting #pending!!\r
+            nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
+        }\r
+    }\r
+    printf (">netcp cfg: MAC i/f %d added\n", iface_no);\r
+    netcp_cfgp_insert_mac(&netapi_get_global()->nwal_context, \r
+                          p_mac, iface_no, state,vlan,\r
+                          (void *) pTransInfo->handle);\r
+    pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;\r
+    pTransInfo->inUse = nwal_FALSE;\r
+    return  (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no);\r
+}\r
+\r
+\r
+/*****************************************************************/\r
+/***************Delete a mac interface****************************/\r
+/*****************************************************************/\r
+void netcp_cfgDelMac(NETAPI_T h,int iface_no,  int *err)\r
+{\r
+    nwal_RetValue ret;\r
+    NetapiNwalTransInfo_t *pTransInfo;\r
+    nwal_TransID_t     trans_id;\r
+    NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
+    void * ifHandle;\r
+\r
+    //get the nwal handle assoicated with this iface\r
+    ifHandle = netcp_cfgp_get_mac_handle(&netapi_get_global()->nwal_context, iface_no );\r
+    if(!ifHandle) \r
+            {*err = NETAPI_ERR_BAD_INPUT; return ;}\r
+    *err =0;\r
+    \r
+    //get a transaction id\r
+    pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
+    if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return ;}\r
+    pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC;\r
+    pTransInfo->netapi_handle = h;\r
+    //issue request\r
+    ret = nwal_delMacIface(\r
+                ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
+                trans_id,\r
+                ifHandle);\r
+    if(ret !=  nwal_OK)\r
+    {\r
+        *err = NETAPI_ERR_NWAL_ERR0;\r
+        printf (">netcp cfg - ERROR: nwal_delMacIface returned Error Code %d\n",\r
+                    ret);\r
+        pTransInfo->inUse = nwal_FALSE;\r
+        return ;\r
+    }\r
+    //wait here until its done since scheduler isn't running yet most likely..\r
+    // todo:  make this handled by scheduler poll later ??\r
+    if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
+    {\r
+        n->nwal_local.numPendingCfg++;\r
+        while ((volatile) n->nwal_local.numPendingCfg)\r
+        {\r
+            // if response is there, then this poll squirts out in the CTl poll callback, \r
+            // which handles the rest (including decrmenting #pending!!\r
+            nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
+        }\r
+    }\r
+    printf (">netcp cfg: MAC i/f %d deleted\n",iface_no);\r
+    pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;\r
+    pTransInfo->inUse = nwal_FALSE;\r
+    //zap the entry\r
+    netcp_cfgp_delete_mac(&netapi_get_global()->nwal_context,  iface_no);\r
+    return ;\r
+}\r
+\r
+\r
+/*****************************************************************/\r
+/***************Add IP to MAC interface****************************/\r
+/*****************************************************************/\r
+NETCP_CFG_IP_T  netcp_cfgAddIp(\r
+                  NETAPI_T  h,\r
+                  int  iface_no,\r
+                  nwal_IpType ipType,\r
+                 nwalIpAddr_t  * ip_addr,\r
+                 nwalIpOpt_t * ip_qualifiers,\r
+                  NETCP_CFG_ROUTE_HANDLE_T  route,  //NULL for default\r
+                  int * err\r
+                  )\r
+{\r
+NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
+void * n_handle;\r
+nwalIpParam_t    nwalIpParam= {\r
+    pa_IPV4,      /* IP Type */\r
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Dest IP */\r
+    { 0x0,0,0,0},/* IP Options */\r
+    NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */\r
+    NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */\r
+    CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */\r
+    QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */\r
+};\r
+nwal_RetValue       retValue;\r
+NetapiNwalTransInfo_t *pTransInfo;\r
+nwal_TransID_t     trans_id;\r
+int ip_slot=-1;\r
+NETCP_CFG_IP_T ip_rule_id;\r
+\r
+     //verify that iface has been configurred \r
+     if ((iface_no<0) || (iface_no>= TUNE_NETAPI_MAX_INTERFACES)) {*err = NETAPI_ERR_BAD_INPUT; return -1;}\r
+\r
+     if(netapi_get_global()->nwal_context.interfaces[iface_no].in_use)\r
+     {\r
+       n_handle =  netapi_get_global()->nwal_context.interfaces[iface_no].nwal_handle;\r
+     }\r
+     else\r
+     {\r
+       *err = NETAPI_ERR_BAD_INPUT;\r
+       return -1;\r
+     }\r
+     //find free slot for IP & reserve\r
+     ip_slot= netcp_cfgp_find_ip_slot(&netapi_get_global()->nwal_context, \r
+                                   iface_no);\r
+     if (ip_slot <0) \r
+     {\r
+       *err= NETAPI_ERR_NOMEM;  //no room \r
+     }\r
+\r
+     //get a transaction object for config action\r
+    pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
+    if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return -1;}\r
+    pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;\r
+    pTransInfo->netapi_handle = h;\r
+\r
+     //build nwalIpParam\r
+     memcpy(&nwalIpParam.locIpAddr,ip_addr, sizeof(nwalIpAddr_t));\r
+     nwalIpParam.ipType=ipType;\r
+     if(route)\r
+     {\r
+          //todo: support app defined routes\r
+     } \r
+     else{} //use nwal defaults\r
+     if (ip_qualifiers)\r
+       memcpy(&nwalIpParam.ipOpt,ip_qualifiers, sizeof(nwalIpOpt_t)); \r
+     else\r
+        memset(&nwalIpParam.ipOpt,0, sizeof(nwalIpOpt_t));\r
+\r
+     //build the rule id that will be returned when a packet matches \r
+     ip_rule_id = NETAPI_NETCP_MATCH_GENERIC_IP | iface_no | ((ip_slot&&0xff)<<8);\r
+     //perform config action\r
+     pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;\r
+     retValue = nwal_setIPAddr(   netapi_get_global()->nwal_context.nwalInstHandle,\r
+                                  trans_id,\r
+                                  (nwal_AppId) (ip_rule_id),\r
+                                  n_handle,\r
+                                  &nwalIpParam,\r
+                                  &pTransInfo->handle);\r
+\r
+    if(retValue !=  nwal_OK)\r
+    {\r
+        *err = NETAPI_ERR_NWAL_ERR0;\r
+        printf (">netcp cfg: nwal_setIP returned Error Code %d\n",\r
+                    retValue);\r
+        pTransInfo->inUse = nwal_FALSE;\r
+        //zap the entry\r
+        netcp_cfgp_delete_ip(&netapi_get_global()->nwal_context,\r
+                         iface_no,\r
+                         ip_slot);\r
+\r
+        return -1;\r
+    }\r
+    //wait here until its done since scheduler isn't running yet most likely..\r
+    // todo:  make this handled by scheduler poll later ??\r
+    if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
+    {\r
+        n->nwal_local.numPendingCfg++;\r
+        while ((volatile) n->nwal_local.numPendingCfg)\r
+        {\r
+            // if response is there, then this poll squirts out in the CTl poll callback, \r
+            // which handles the rest (including decrmenting #pending!!\r
+            nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
+        }\r
+    }\r
+    printf (">netcp cfg: IP added to interface %d (slot%d)\n", iface_no, ip_slot);\r
+    netcp_cfgp_insert_ip(&netapi_get_global()->nwal_context, ipType, \r
+                          ip_addr, ip_qualifiers, iface_no, ip_slot,\r
+                          pTransInfo->handle);\r
+    pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;\r
+    pTransInfo->inUse = nwal_FALSE;\r
+    return  (ip_rule_id);\r
+}\r
+\r
+/*****************************************************************/\r
+/***************Delete an attached IP*****************************/\r
+/*****************************************************************/\r
+void netcp_cfgDelIp(NETAPI_T h, int iface_no,  nwal_IpType ipType,\r
+                  nwalIpAddr_t  * ip_addr,\r
+                  nwalIpOpt_t * ip_qualifiers, \r
+                  NETCP_CFG_IP_T  ip_rule_id,\r
+                  int *err)\r
+{\r
+    nwal_RetValue ret;\r
+    NetapiNwalTransInfo_t *pTransInfo;\r
+    nwal_TransID_t     trans_id;\r
+    NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
+    void * ifHandle;\r
+    int ip_slot = (ip_rule_id>>8)&0xff;\r
+\r
+    //get the nwal handle assoicated with this ip   \r
+    ifHandle = netcp_cfgp_get_ip_handle(\r
+         &netapi_get_global()->nwal_context, iface_no,\r
+         ip_slot );\r
+    if(!ifHandle)\r
+            {*err = NETAPI_ERR_BAD_INPUT; return ;}\r
+    *err =0;\r
+\r
+    //get a transaction id\r
+    pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
+  if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return ;}\r
+    pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;\r
+    pTransInfo->netapi_handle = h;\r
+    //issue request\r
+    ret = nwal_delIPAddr(\r
+                ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
+                trans_id,\r
+                ifHandle);\r
+    if(ret !=  nwal_OK)\r
+    {\r
+        *err = NETAPI_ERR_NWAL_ERR0;\r
+        printf (">netcp cfg - ERROR: nwal_delMacIface returned Error Code %d\n",\r
+                    ret);\r
+        pTransInfo->inUse = nwal_FALSE;\r
+        return ;\r
+    }\r
+    //wait here until its done since scheduler isn't running yet most likely..\r
+    // todo:  make this handled by scheduler poll later ??\r
+    if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
+    {\r
+       n->nwal_local.numPendingCfg++;\r
+        while ((volatile) n->nwal_local.numPendingCfg)\r
+        {\r
+            // if response is there, then this poll squirts out in the CTl poll callback, \r
+            // which handles the rest (including decrmenting #pending!!\r
+            nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
+        }\r
+    }\r
+    printf (">netcp cfg: IP i/f deleted\n");\r
+    pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;\r
+    pTransInfo->inUse = nwal_FALSE;\r
+    //zap the entry\r
+    netcp_cfgp_delete_ip(&netapi_get_global()->nwal_context,  \r
+                         iface_no,\r
+                         ip_slot);\r
+    return ;\r
+}\r
+\r
+\r
+/*************************************************************************/\r
+/*********************************INTERNAL*******************************/\r
+/************************************************************************/\r
+\r
+/***************************************************************\r
+ ********************METCP CMD Reply Callback******************\r
+ ***************************************************************/\r
+void netapi_NWALCmdCallBack (nwal_AppId        appHandle,\r
+                          uint16_t            trans_id,\r
+                          nwal_RetValue     ret)\r
+{\r
+    NetapiNwalTransInfo_t * p_trans;\r
+    NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL;\r
+\r
+    if(trans_id == NWAL_TRANSID_SPIN_WAIT)\r
+    {\r
+        netapi_get_global()->nwal_context.numBogusTransIds++;\r
+        return;\r
+    }\r
+\r
+    p_trans= &netapi_get_global()->nwal_context.transInfos[trans_id];\r
+    p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;\r
+\r
+    if(ret != nwal_OK)\r
+    {\r
+        printf (">netcp cfg : NWALCmdCallBack returned Error Code %d\n",\r
+                    ret);\r
+       //todo: atomic inc\r
+        netapi_get_global()->nwal_context.numCmdFail++;\r
+    }\r
+    else\r
+    {\r
+       //todo: atomic inc\r
+        netapi_get_global()->nwal_context.numCmdPass++;\r
+        switch(p_trans->transType)\r
+        {\r
+            case NETAPI_NWAL_HANDLE_TRANS_MAC:\r
+            {\r
+                if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)\r
+                {\r
+                    p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;\r
+                }\r
+                else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
+                {\r
+                    p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;\r
+                }\r
+                break;\r
+            }\r
+            case NETAPI_NWAL_HANDLE_TRANS_IP:\r
+            {\r
+                 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)\r
+                {\r
+                    p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;\r
+                }\r
+                else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
+                {\r
+                    p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;\r
+                }\r
+                break;\r
+            }\r
+#if 0\r
+            case TEST_NWAL_HANDLE_TRANS_PORT:\r
+            {\r
+                if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING)\r
+                {\r
+                    testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN;\r
+                }\r
+                else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
+                {\r
+                    testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE;\r
+                }\r
+                break;\r
+            }\r
+            case TEST_NWAL_HANDLE_TRANS_SEC_ASSOC:\r
+            {\r
+                if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING)\r
+                {\r
+                    testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN;\r
+                }\r
+                else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
+                {\r
+                    System_printf ("Set Security Assoc  Close ACK received for trans_id: %d\n",\r
+                                testNwLocContext.transInfos[trans_id].transType,trans_id);\r
+                    nwal_SystemFlush();\r
+                    testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE;\r
+                }\r
+                break;\r
+            }\r
+case TEST_NWAL_HANDLE_TRANS_SEC_POLICY:\r
+            {\r
+                if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING)\r
+                {\r
+                    testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN;\r
+                }\r
+                else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
+                {\r
+                    System_printf ("Set Security Policy  Close ACK received for trans_id: %d\n",\r
+                                testNwLocContext.transInfos[trans_id].transType,trans_id);\r
+                    nwal_SystemFlush();\r
+                    testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE;\r
+                }\r
+                break;\r
+            }\r
+#endif\r
+            default:\r
+            {\r
+                printf ("netcp cfg> Invalid transaction type %d for trans_id: %d\n",\r
+                    p_trans->transType,trans_id);\r
+                break;\r
+            }\r
+        }\r
+    }\r
+\r
+    p_local->numPendingCfg--;\r
+\r
+    if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_IDLE)\r
+    {\r
+        p_trans->inUse = nwal_FALSE;\r
+    }\r
+\r
+}\r
+\r
+\r
+/*******************************************************/\r
+/**************stats reply callback**********************/\r
+/*******************************************************/\r
+void netapi_NWALCmdPaStatsReply (nwal_AppId        appHandle,\r
+                              nwal_TransID_t    trans_id,\r
+                              paSysStats_t      *stats)\r
+{\r
+    NetapiNwalTransInfo_t * p_trans;\r
+    NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL;\r
+  \r
+    if(trans_id == NWAL_TRANSID_SPIN_WAIT)\r
+    {\r
+        netapi_get_global()->nwal_context.numBogusTransIds++;\r
+        return;\r
+    }\r
+\r
+    p_trans= &netapi_get_global()->nwal_context.transInfos[trans_id];\r
+    p_trans->inUse = nwal_FALSE;\r
+    p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;\r
+\r
+    //save a local copy  of some stuff*/\r
+    p_local->numL2PktsRecvd=stats->classify1.nPackets;\r
+    p_local->numL3PktsRecvd=stats->classify1.nIpv4Packets;\r
+#if 0\r
+    p_local->numL4PktsRecvd=stats->;\r
+    p_local->numL4PktsSent=stats->;\r
+    p_local->TxErrDrop=stats->;\r
+#endif\r
+    //callout result to application !!\r
+    if (p_local->stats_cb) (*p_local->stats_cb)(p_trans->netapi_handle,stats);\r
+    \r
+} \r
+\r