index 1347ee6cf92cd28099a399ca86803dd660a4caf7..2b778c4a7dd407150d2dc5146a54bc8eb21daa96 100755 (executable)
-/**********************************************************\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
-NetapiNwalTransInfo_t * netapip_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
-//internal: build route\r
-void netcp_cfgp_build_route(NETCP_CFG_ROUTE_T * p_route, int16_t * p_flow, Qmss_QueueHnd * p_q)\r
-{\r
- if (!p_route) return;\r
- if (p_route->p_flow) *p_flow= p_route->p_flow->flowid;\r
- else *p_flow = CPPI_PARAM_NOT_SPECIFIED;\r
- if (p_route->p_dest_q) *p_q = pktio_get_q(p_route->p_dest_q);\r
- else *p_q=QMSS_PARAM_NOT_SPECIFIED;\r
-}\r
-/*-----------------------------------------------------------*/\r
-/*----------------database management stuff-------------------*/\r
-/*-----------------------------------------------------------*/\r
-\r
-/*=====================Policies=============================*/\r
-//internal: find a free slot for an SA \r
-int netcp_cfgp_find_policy_slot( NETAPI_NWAL_GLOBAL_CONTEXT_T *p, int tunnel)\r
-{\r
- int i;\r
- if ((tunnel <0 ) || (tunnel >=TUNE_NETAPI_MAX_SA)) return -1;\r
-\r
- //find a free entry\r
- for(i=0;i<TUNE_NETAPI_MAX_POLICY;i++)\r
- {\r
- if (!p->policy[i].in_use)\r
- {\r
- p->policy[i].in_use = 2; //pending\r
- p->policy[i].tunnel= tunnel; //save tunnel this is linked to \r
- return i;\r
- }\r
- }\r
- return -1;\r
-}\r
-\r
-//internal: delete a policy from list \r
-void netcp_cfgp_delete_policy(\r
- NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
- int policy_slot )\r
-{\r
- if ((policy_slot <0 ) || (policy_slot >= TUNE_NETAPI_MAX_POLICY))\r
- {\r
- return ;\r
- }\r
- p->policy[policy_slot].in_use=0;\r
- return;\r
-}\r
-\r
-//internal: insert an policy into the list \r
-void netcp_cfgp_insert_policy(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
- int policy_slot, //we 'reserved it already'\r
- void * handle)\r
-{\r
- p->policy[policy_slot].in_use=1;\r
- p->policy[policy_slot].nwal_handle = handle;\r
- return;\r
-}\r
-\r
-//internal: return nwal_handle for policy \r
-void *netcp_cfgp_get_policy( NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
- int policy_slot)\r
-{\r
- if ((policy_slot <0 ) || (policy_slot >= TUNE_NETAPI_MAX_POLICY)) return NULL;\r
- if (!p->policy[policy_slot].in_use) return NULL;\r
- return p->policy[policy_slot].nwal_handle;\r
-}\r
-\r
-\r
-\r
-/*======================SAs==================================*/\r
-//internal: find a free slot for an SA \r
-int netcp_cfgp_find_sa_slot( NETAPI_NWAL_GLOBAL_CONTEXT_T *p, int iface)\r
-{ \r
- int i;\r
- if ((iface <0 ) || (iface >=TUNE_NETAPI_MAX_INTERFACES)) return -1;\r
-\r
- //find a free entry\r
- for(i=0;i<TUNE_NETAPI_MAX_SA;i++)\r
- { \r
- if (!p->tunnel[i].in_use)\r
- {\r
- p->tunnel[i].in_use = 2; //pending\r
- p->tunnel[i].iface= iface; //save iface\r
- return i;\r
- }\r
- }\r
- return -1;\r
-}\r
- //internal: delete an SAr from list \r
-void netcp_cfgp_delete_sa(\r
- NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
- int sa_slot )\r
-{\r
- if ((sa_slot <0 ) || (sa_slot >= TUNE_NETAPI_MAX_SA))\r
- {\r
- return ;\r
- }\r
- p->tunnel[sa_slot].in_use=0;\r
- return;\r
-}\r
-\r
-//internal: insert an SA into the list \r
-void netcp_cfgp_insert_sa(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
- int sa_slot, //we 'reserved it already'\r
- int dir,\r
- int mode,\r
- void * temp1,\r
- void * temp2,\r
- void * handle_inflow,\r
- void * handle_sideband)\r
-{\r
- p->tunnel[sa_slot].in_use=1;\r
- p->tunnel[sa_slot].inbound = dir;\r
- p->tunnel[sa_slot].sa_mode = mode;\r
- p->tunnel[sa_slot].sa_handle_inflow = handle_inflow;\r
- p->tunnel[sa_slot].sa_handle_sideband = handle_sideband;\r
- return;\r
-}\r
-\r
-//internal: return nwal_handles for SA \r
-void *netcp_cfgp_get_sa_handles( NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
- int sa_slot, void ** p_sideband)\r
-{\r
- if ((sa_slot <0 ) || (sa_slot >= TUNE_NETAPI_MAX_SA)) return NULL;\r
- if (!p->tunnel[sa_slot].in_use) return NULL;\r
- *p_sideband = p->tunnel[sa_slot].sa_handle_sideband;\r
- return p->tunnel[sa_slot].sa_handle_inflow;\r
-}\r
-\r
-\r
-/*==============================fLOWS=============================*/\r
-//internal: find a free slot for a flow \r
-static int netcp_cfgp_find_flow_slot( NETAPI_NWAL_GLOBAL_CONTEXT_T *p)\r
-{\r
- int i;\r
- //find a free entry\r
- for(i=0;i<TUNE_NETAPI_MAX_FLOWS;i++)\r
- {\r
- if (!p->flows[i].in_use)\r
- {\r
- p->flows[i].in_use = 2; //pending\r
- return i;\r
- }\r
- }\r
- return -1;\r
-}\r
-\r
-//internal: clear flow slot \r
-static void netcp_cfgp_delete_flow(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,int slot)\r
-{\r
- if ((slot >=0 ) && (slot < TUNE_NETAPI_MAX_FLOWS))\r
- {\r
- p->flows[slot].in_use = 0;\r
- }\r
-}\r
-\r
-//internal: insert a flow into flow slot\r
-static NETCP_CFG_FLOW_HANDLE_T netcp_cfgp_insert_flow(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
- int slot, //we 'reserved it already'\r
- void * handle) //cppi flow handle. Save this for delete\r
-{\r
- p->flows[slot].in_use=1;\r
- p->flows[slot].handle = handle;\r
- p->flows[slot].flow.flowid = Cppi_getFlowId(handle);\r
- return (NETCP_CFG_FLOW_HANDLE_T) &p->flows[slot].flow;\r
-}\r
-\r
-//find entry matching the flowid. return slot# and the cppi handle\r
-static int netcp_cfgp_find_flow(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
- int flowid, \r
- void ** handle) \r
-{\r
-int i;\r
- *handle=NULL;\r
- for(i=0;i<TUNE_NETAPI_MAX_FLOWS;i++)\r
- {\r
- if ((p->flows[i].in_use)&&(p->flows[i].flow.flowid == flowid))\r
- {\r
- *handle = p->flows[i].handle;\r
- return i;\r
- }\r
- }\r
- return -1;\r
-}\r
-\r
-\r
-/*============================IP ADDRESSES==========================*/\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
-\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: 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
-/*==========================MAC INTERFACES======================*/\r
-//internal: insert 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
-\r
-//internal: get handle associated with interface\r
-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
-//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
-\r
-\r
-/*========================CLASSIFIERS==========================*/\r
-//internal: find a free slot for classifier rule\r
-static int netcp_cfgp_find_class_slot( NETAPI_NWAL_GLOBAL_CONTEXT_T *p)\r
-{\r
- int i;\r
- //find a free entry\r
- for(i=0;i<TUNE_NETAPI_MAX_CLASSIFIERS;i++)\r
- {\r
- if (!p->classi[i].in_use)\r
- {\r
- p->classi[i].in_use = 2; //pending\r
- return i;\r
- }\r
- }\r
- return -1;\r
-}\r
-\r
- //internal: delete a classifer from list \r
-static void netcp_cfgp_delete_class(\r
- NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
- int class_slot )\r
-{\r
- if ((class_slot <0 ) || (class_slot >= TUNE_NETAPI_MAX_CLASSIFIERS))\r
- {\r
- return ;\r
- }\r
- p->classi[class_slot].in_use=0;\r
- return;\r
-}\r
-\r
-//internal: insert a classifier into list \r
-static void netcp_cfgp_insert_class(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
- int class_slot, //we 'reserved it already'\r
- int class_type,\r
- void * L2_handle,\r
- void * L3_handle,\r
- void * L4_handle)\r
-{\r
- p->classi[class_slot].in_use=1;\r
- p->classi[class_slot].nwal_L2_handle = L2_handle;\r
- p->classi[class_slot].nwal_L3_handle = L3_handle;\r
- p->classi[class_slot].nwal_L4_handle = L4_handle;\r
- p->classi[class_slot].class_type = class_type;\r
- return;\r
-}\r
-\r
-//internal: return L4 nwal_handle for class\r
-static void *netcp_cfgp_get_l4_handle( NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
- int class_slot)\r
-{\r
- if ((class_slot <0 ) || (class_slot >= TUNE_NETAPI_MAX_CLASSIFIERS)) return NULL;\r
- if (!p->classi[class_slot].in_use) return NULL;\r
- return p->classi[class_slot].nwal_L4_handle;\r
-}\r
-\r
-//internal: return L3 nwal_handle for class\r
-static void *netcp_cfgp_get_l3_handle( NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
- int class_slot)\r
-{\r
- if ((class_slot <0 ) || (class_slot >= TUNE_NETAPI_MAX_CLASSIFIERS)) return NULL;\r
- if (!p->classi[class_slot].in_use) return NULL;\r
- return p->classi[class_slot].nwal_L3_handle;\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
-\r
-pTransInfo = netapip_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 = netapip_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 (route != NULL)\r
- {\r
- netcp_cfgp_build_route(route,&MacInfo.appRxPktFlowId, &MacInfo.appRxPktQueue);\r
- }\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 = netapip_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 (internal)****************/\r
-/*****************************************************************/\r
-static NETCP_CFG_IP_T netcp_cfgAddIpInternal(\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
- int flag) //TRUE: add IP to iface. False: add IP as part of classifier\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
-NETCP_CFG_IP_T temp;\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
-\r
- if (flag) //if adding IP to MAC then reserve a slot to save info\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
- return -1;\r
- }\r
- }\r
-\r
- //get a transaction object for config action\r
- pTransInfo = netapip_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
- netcp_cfgp_build_route(route,&nwalIpParam.appRxPktFlowId, &nwalIpParam.appRxPktQueue);\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
- if (flag)\r
- ip_rule_id = NETAPI_NETCP_MATCH_GENERIC_IP | iface_no | ((ip_slot&&0xff)<<8);\r
- else\r
- ip_rule_id = (NETAPI_NETCP_MATCH_CLASS_L3 | iface_no);\r
-\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
- if (flag)\r
- {\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
- if (flag)\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
- }\r
- pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;\r
- temp = (NETCP_CFG_IP_T) pTransInfo->handle;\r
- pTransInfo->inUse = nwal_FALSE;\r
- return (flag ? ip_rule_id: temp);\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
- return netcp_cfgAddIpInternal(\r
- h, iface_no, ipType, ip_addr, ip_qualifiers, route, err, \r
- 1);\r
-}\r
-\r
-/*****************************************************************/\r
-/***************Delete an attached IP*****************************/\r
-/*****************************************************************/\r
-static void netcp_cfgDelIpInternal(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
- void * handle, /* if flag==0, handle must be valid */\r
- int flag) /* flag==0 => delete IP rule that was part of classifier, not interface */\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
- if (flag)\r
- {\r
- ifHandle = netcp_cfgp_get_ip_handle(\r
- &netapi_get_global()->nwal_context, iface_no,\r
- ip_slot );\r
- }\r
- else \r
- {\r
- ifHandle = handle;\r
- }\r
- if(!ifHandle)\r
- {*err = NETAPI_ERR_BAD_INPUT; return ;}\r
- *err =0;\r
-\r
- //get a transaction id\r
- pTransInfo = netapip_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
- if (flag)\r
- printf (">netcp cfg: attached IP deleted\n");\r
- else\r
- printf (">netcp cfg: Classifier IP rule deleted\n");\r
- pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;\r
- pTransInfo->inUse = nwal_FALSE;\r
-\r
- //zap the entry\r
- if (flag)\r
- netcp_cfgp_delete_ip(&netapi_get_global()->nwal_context, \r
- iface_no,\r
- ip_slot);\r
- return ;\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
- netcp_cfgDelIpInternal( h, iface_no, ipType,\r
- ip_addr, ip_qualifiers, ip_rule_id,\r
- err, NULL, 1);\r
- return;\r
-}\r
-\r
-\r
-/**\r
- * @def netcp_cfgAddClass\r
- * @brief add a classifier rule into NETCP\r
- **/\r
-NETCP_CFG_CLASS_T netcp_cfgAddClass(NETAPI_T h,\r
- NETCP_CFG_CLASSIFIER_T *p_class,\r
- NETCP_CFG_ROUTE_HANDLE_T route,\r
- int action, int * err)\r
-{\r
-NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
-void * l3_handle=NULL; //ip handle\r
-nwal_RetValue retValue;\r
-NetapiNwalTransInfo_t *pTransInfo;\r
-nwal_TransID_t trans_id;\r
-int class_slot=-1;\r
-int iface_no;\r
-int ip_slot=-1;\r
-NETCP_CFG_CLASS_T classHandle; //returned by us\r
-nwal_appProtoType_t proto;\r
-nwalLocConnCfg_t tempCfg={\r
-0, //nwal_handle: to be filled in\r
-{0}, // l4 ports: to be filled in\r
-0, //core id (NA)\r
-0, //action\r
-CPPI_PARAM_NOT_SPECIFIED, //flow id\r
-QMSS_PARAM_NOT_SPECIFIED, //dest queue\r
-};\r
-\r
-if(!p_class) { *err=NETAPI_ERR_BAD_INPUT; return -1;}\r
-switch(p_class->classType)\r
-{\r
-default:\r
- printf(">netcp_cfg : classifier type %d not supported\n",p_class->classType);\r
- break;\r
-case(NETCP_CFG_CLASS_TYPE_L3_L4):\r
-case(NETCP_CFG_CLASS_TYPE_L4):\r
- //assume just type l4 only (L2, L3 defined by iface, l3 id )\r
- iface_no = p_class->u.c_l4.iface;\r
- if (p_class->classType== NETCP_CFG_CLASS_TYPE_L4)\r
- { \r
- ip_slot = (p_class->u.c_l4.ip>>8)&0xff;\r
- }\r
-\r
- //verify that iface has been configured \r
- if(!netapi_get_global()->nwal_context.interfaces[iface_no].in_use)\r
- {\r
- *err = NETAPI_ERR_BAD_INPUT;\r
- return -1;\r
- }\r
-\r
- if (p_class->classType== NETCP_CFG_CLASS_TYPE_L4)\r
- {\r
- //verify that ip has been configured and get its handle\r
- l3_handle = netcp_cfgp_get_ip_handle(\r
- &netapi_get_global()->nwal_context, iface_no,\r
- ip_slot );\r
- }\r
- else\r
- {\r
- nwalIpParam_t tempParam={\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
- //build nwalIpParam\r
- memcpy(&tempParam.locIpAddr,p_class->u.c_l3_l4.ip_addr, sizeof(nwalIpAddr_t));\r
- tempParam.ipType=p_class->u.c_l3_l4.ipType;\r
- //use nwal defauls for route\r
- if (p_class->u.c_l3_l4.ip_qualifiers)\r
- memcpy(&tempParam.ipOpt,p_class->u.c_l3_l4.ip_qualifiers, sizeof(nwalIpOpt_t));\r
- else\r
- memset(&tempParam.ipOpt,0, sizeof(nwalIpOpt_t));\r
-\r
-\r
- //find if we have a matching L3 handle for IP classifier; if not create it\r
- retValue = nwal_getIPAddr (((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
- &tempParam,\r
- netcp_cfgp_get_mac_handle(&netapi_get_global()->nwal_context, iface_no ),\r
- &l3_handle); \r
- if (retValue != nwal_TRUE) \r
- {\r
- int ret;\r
- //**NEW IP RULE \r
- //need to attach this IP RULE to the MAC\r
- l3_handle= (void *) netcp_cfgAddIpInternal(\r
- h, iface_no, \r
- p_class->u.c_l3_l4.ipType,\r
- p_class->u.c_l3_l4.ip_addr,\r
- p_class->u.c_l3_l4.ip_qualifiers,\r
- p_class->u.c_l3_l4.p_fail_route,\r
- &ret,\r
- FALSE);\r
- if(!ret)\r
- {\r
- l3_handle=NULL;\r
- }\r
- }\r
- } \r
- if(!l3_handle)\r
- {*err = NETAPI_ERR_BAD_INPUT; return -1 ;}\r
-\r
-\r
- //find free slot for CLASS & reserve\r
- class_slot= netcp_cfgp_find_class_slot(&netapi_get_global()->nwal_context);\r
- if(class_slot<0) {*err = NETAPI_ERR_NOMEM; return -1;}\r
- classHandle = NETAPI_NETCP_MATCH_CLASS | (class_slot<<8) | (iface_no&0xff);\r
- //build request from template\r
- tempCfg.inHandle=l3_handle;\r
- if (p_class->classType== NETCP_CFG_CLASS_TYPE_L4)\r
- { \r
- memcpy(&tempCfg.appProto,&p_class->u.c_l4.appProto,sizeof(nwalAppProto_t));\r
- proto = p_class->u.c_l4.proto;\r
- }\r
- else\r
- {\r
- memcpy(&tempCfg.appProto,&p_class->u.c_l3_l4.appProto,sizeof(nwalAppProto_t));\r
- proto = p_class->u.c_l3_l4.proto;\r
- }\r
- \r
- tempCfg.matchAction = (action==NETCP_CFG_ACTION_TO_SW) ? NWAL_MATCH_ACTION_HOST : NWAL_MATCH_ACTION_DISCARD;\r
- if (route)\r
- {\r
- netcp_cfgp_build_route(route,&tempCfg.appRxPktFlowId, &tempCfg.appRxPktQueue);\r
- }\r
-\r
- //get a transaction id\r
- pTransInfo = netapip_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; /* todo: fix this to TRANS_L4*/\r
- pTransInfo->netapi_handle = h;\r
- //issue request\r
- retValue = nwal_addConn(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
- trans_id,\r
- (nwal_AppId) classHandle,\r
- proto,\r
- &tempCfg,\r
- NULL,\r
- &pTransInfo->handle);\r
- if(retValue != nwal_OK)\r
- {\r
- *err = NETAPI_ERR_NWAL_ERR0;\r
- printf (">netcp cfg - ERROR: nwal_addConn returned Error Code %d\n",\r
- retValue);\r
- pTransInfo->inUse = nwal_FALSE;\r
- netcp_cfgp_delete_class(&netapi_get_global()->nwal_context, class_slot);\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: L4 Classifer added to interface %d ip %d (slot%d)\n", iface_no, ip_slot, class_slot);\r
- netcp_cfgp_insert_class(&netapi_get_global()->nwal_context, \r
- class_slot,\r
- p_class->classType, \r
- NULL, //L2 we have\r
- (p_class->classType== NETCP_CFG_CLASS_TYPE_L3_L4? l3_handle : NULL),\r
- pTransInfo->handle);\r
- pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;\r
- return classHandle;\r
-} //end switch\r
-return -1;\r
-}\r
-\r
-//delete classifier\r
-void netcp_cfgDelClass(NETAPI_T h,\r
- NETCP_CFG_CLASS_T classId,\r
- int *err)\r
-{\r
-NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
-void * L4_handle; //class handle -> L4\r
-void * L3_handle; //class handle -> L3\r
-nwal_RetValue retValue;\r
-NetapiNwalTransInfo_t *pTransInfo;\r
-nwal_TransID_t trans_id;\r
-int class_slot=-1;\r
-//int iface;\r
-//int ip_slot;\r
-\r
- class_slot = (classId>>8)&0xffff;\r
- L4_handle=netcp_cfgp_get_l4_handle(\r
- &netapi_get_global()->nwal_context,\r
- class_slot );\r
- if(!L4_handle) {*err = NETAPI_ERR_BAD_INPUT; return ;}\r
- L3_handle = netcp_cfgp_get_l3_handle(\r
- &netapi_get_global()->nwal_context,\r
- class_slot );\r
- /* l3 handle might be NULL,, depending on type of classifier */\r
-\r
- netcp_cfgp_delete_class(\r
- &netapi_get_global()->nwal_context,\r
- class_slot );\r
- //get a transaction id\r
- pTransInfo = netapip_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 for L4\r
- retValue = nwal_delConn(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
- trans_id,\r
- L4_handle);\r
- if(retValue != nwal_OK)\r
- {\r
- *err = NETAPI_ERR_NWAL_ERR0;\r
- printf (">netcp cfg - ERROR: nwal_delConn returned Error Code %d\n",\r
- retValue);\r
- pTransInfo->inUse = nwal_FALSE;\r
- return ; /* todo: what about the L3? */\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: Classifer deleted\n");\r
- pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;\r
- pTransInfo->inUse = nwal_FALSE;\r
-\r
- /* delete L3 if we have to */\r
- if (L3_handle)\r
- {\r
- netcp_cfgDelIpInternal( h, 0, 0,\r
- NULL, NULL, 0,\r
- err, L3_handle, 0);\r
- }\r
- return ;\r
-}\r
-\r
-\r
-/*--------------flow management--------*/\r
-// ADD A Flow\r
-NETCP_CFG_FLOW_HANDLE_T netcp_cfgAddFlow(NETAPI_T h,\r
- int n,\r
- Pktlib_HeapHandle handles[],\r
- int sizes[],\r
- int * err )\r
-{\r
- Cppi_RxFlowCfg rxFlowCfg;\r
- Uint8 isAlloc;\r
- Qmss_QueueHnd rxBufQ[TUNE_NETAPI_MAX_BUF_POOLS_IN_FLOW];\r
- Uint32 rxBufSize[TUNE_NETAPI_MAX_BUF_POOLS_IN_FLOW];\r
- int i;\r
- Cppi_FlowHnd FlowHnd;\r
- int slot;\r
- NETCP_CFG_FLOW_HANDLE_T retVal;\r
-\r
- *err= 0; /* ok */\r
- //get a slot to save new flow\r
- slot = netcp_cfgp_find_flow_slot(&netapi_get_global()->nwal_context);\r
- if (slot<0) { *err= NETAPI_ERR_NOMEM; return NULL; }\r
-\r
- //configure flow\r
- memset(&rxFlowCfg,0,sizeof(Cppi_RxFlowCfg));\r
- for (i = 0; i < TUNE_NETAPI_MAX_BUF_POOLS_IN_FLOW; i++)\r
- {\r
- if (i >= n)\r
- {\r
- rxBufQ[i] = 0;\r
- rxBufSize[i] = 0;\r
- } else\r
- {\r
- rxBufQ[i] = Pktlib_getInternalHeapQueue(handles[i]);\r
- //todo: verity sizes< heapsize\r
- //todo: verify order\r
- rxBufSize[i]= sizes[i];\r
- }\r
- if (i && (rxBufQ[i] <= 0))\r
- {\r
- rxBufQ[i] = rxBufQ[i-1];\r
- rxBufSize[i] = 0;\r
- }\r
- }\r
- /* Configure Rx flow */\r
- rxFlowCfg.flowIdNum = CPPI_PARAM_NOT_SPECIFIED;\r
- rxFlowCfg.rx_dest_qnum = 100; //DANGEROUS> TODO PUT VALID Q HERE\r
- rxFlowCfg.rx_dest_qmgr = 0;\r
- rxFlowCfg.rx_sop_offset = 0;\r
- rxFlowCfg.rx_ps_location = Cppi_PSLoc_PS_IN_DESC;\r
- rxFlowCfg.rx_desc_type = Cppi_DescType_HOST;\r
- rxFlowCfg.rx_error_handling = 0;\r
-\r
- rxFlowCfg.rx_psinfo_present = 1;\r
- rxFlowCfg.rx_einfo_present = 1;\r
-\r
- rxFlowCfg.rx_dest_tag_lo = 0;\r
- rxFlowCfg.rx_dest_tag_hi = 0;\r
- rxFlowCfg.rx_src_tag_lo = 0;\r
- rxFlowCfg.rx_src_tag_hi = 0;\r
-\r
- rxFlowCfg.rx_size_thresh0_en = rxBufSize[1] ? 1 : 0;\r
- rxFlowCfg.rx_size_thresh1_en = rxBufSize[2] ? 1 : 0;\r
- rxFlowCfg.rx_size_thresh2_en = rxBufSize[3] ? 1 : 0;\r
-\r
- rxFlowCfg.rx_dest_tag_lo_sel = 0;\r
- rxFlowCfg.rx_dest_tag_hi_sel = 0;\r
- rxFlowCfg.rx_src_tag_lo_sel = 0;\r
- rxFlowCfg.rx_src_tag_hi_sel = 0;\r
-\r
- rxFlowCfg.rx_fdq1_qnum = rxBufQ[1];\r
- rxFlowCfg.rx_fdq1_qmgr = 0;\r
- rxFlowCfg.rx_fdq2_qnum = rxBufQ[2];\r
-\r
- rxFlowCfg.rx_fdq2_qmgr = 0;\r
- rxFlowCfg.rx_fdq3_qnum = rxBufQ[3];\r
-\r
- rxFlowCfg.rx_fdq3_qmgr = 0;\r
-\r
- rxFlowCfg.rx_size_thresh0 = rxBufSize[1] ? rxBufSize[0] : 0;\r
- rxFlowCfg.rx_size_thresh1 = rxBufSize[2] ? rxBufSize[1] : 0;\r
- rxFlowCfg.rx_size_thresh2 = rxBufSize[3] ? rxBufSize[2] : 0;\r
-\r
- rxFlowCfg.rx_fdq0_sz0_qnum = rxBufQ[0];\r
- rxFlowCfg.rx_fdq0_sz0_qmgr = 0;\r
- rxFlowCfg.rx_fdq0_sz1_qnum = rxBufQ[1];\r
- rxFlowCfg.rx_fdq0_sz1_qmgr = 0;\r
- rxFlowCfg.rx_fdq0_sz2_qnum = rxBufQ[2];\r
- rxFlowCfg.rx_fdq0_sz2_qmgr = 0;\r
- rxFlowCfg.rx_fdq0_sz3_qnum = rxBufQ[3];\r
- rxFlowCfg.rx_fdq0_sz3_qmgr = 0;\r
-\r
- {\r
- //todo: replace this with a nwal call to get global cntx info\r
- Cppi_CpDmaInitCfg cpdmaCfg;\r
- memset(&cpdmaCfg,0,sizeof(Cppi_CpDmaInitCfg));\r
- cpdmaCfg.dmaNum = Cppi_CpDma_PASS_CPDMA;\r
- FlowHnd =\r
- Cppi_configureRxFlow (Cppi_open (&cpdmaCfg), &rxFlowCfg, &isAlloc);\r
-}\r
- if (FlowHnd == NULL)\r
- {\r
- *err= NETAPI_ERR_NORES;\r
- netcp_cfgp_delete_flow(&netapi_get_global()->nwal_context, slot);\r
- return (NULL);\r
- }\r
-\r
- //update slot\r
- retVal = netcp_cfgp_insert_flow(&netapi_get_global()->nwal_context, slot, (void*) FlowHnd);\r
- printf(">netcp cfg: flow %d created\n", ((NETCP_CFG_FLOW_T *) retVal)->flowid);\r
- return ( retVal);\r
-\r
-\r
-\r
-}\r
-\r
-//Delete a flow\r
-void netcp_cfgDelFlow(NETAPI_T h , NETCP_CFG_FLOW_HANDLE_T f , int * err)\r
-{\r
- int slot;\r
- void * handle;\r
- *err=0;\r
- /* find entry */\r
- slot = netcp_cfgp_find_flow(&netapi_get_global()->nwal_context, ((NETCP_CFG_FLOW_T *) f) ->flowid, &handle);\r
- if (slot<0) {*err = NETAPI_ERR_BAD_INPUT; return;}\r
-\r
- Cppi_closeRxFlow( (Cppi_FlowHnd) handle);\r
- netcp_cfgp_delete_flow(&netapi_get_global()->nwal_context, slot);\r
- printf(">netcp cfg: flow %d deleted\n", ((NETCP_CFG_FLOW_T *) f)->flowid);\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
- case NETAPI_NWAL_HANDLE_TRANS_PORT:\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_SA:\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_SA_POLICY:\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
- 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
+/**********************************************************
+ * 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:
+ *
+ * Copyright (c) Texas Instruments Incorporated 2013
+ *
+ * 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 "netapi.h"
+
+extern NETAPI_SHM_T* pnetapiShm;
+
+/******************************************************************
+ ********************Netapi internal*************************************
+*******************************************************************/
+
+
+/********************************************************************
+ * FUNCTION PURPOSE: Netapi internal function to get a free transaction id
+ ********************************************************************
+ * DESCRIPTION: Netapi internal function to get a free transaction id.
+ ********************************************************************/
+NetapiNwalTransInfo_t * netapip_getFreeTransInfo(NETAPI_HANDLE_T *p_handle,
+ NETAPI_PROC_GLOBAL_T *p_proc_global,
+ nwal_TransID_t *pTransId)
+{
+ uint16_t count=0;
+
+ count=0;
+ p_handle->spinLock.lock(&pnetapiShm->netapi_netcp_cfg_lock);
+ while(count < TUNE_NETAPI_MAX_NUM_TRANS)
+ {
+ if((p_proc_global->nwal_context.transInfos[count].inUse) != nwal_TRUE)
+ {
+ p_proc_global->nwal_context.transInfos[count].inUse = nwal_TRUE;
+ *pTransId = count;
+ p_handle->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_lock);
+ return(&p_proc_global->nwal_context.transInfos[count]);
+ }
+ count++;
+ }
+ p_handle->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_lock);
+ /* trouble. need to wait for one to free up*/
+ /* to do: handle this by forcing a poll of cntrl queue*/
+ netapi_Log(">netcp_cfg: trying to get free transaction slot but all full!!\n");
+ return NULL;
+
+}
+
+/********************************************************************
+ * FUNCTION PURPOSE: Netapi internal function to free a transaction id
+ ********************************************************************
+ * DESCRIPTION: Netapi internal function to free a transaction id
+ ********************************************************************/
+void netapip_freeTransInfo(NetapiNwalTransInfo_t *pTransInfo)
+{
+ pTransInfo->inUse = nwal_FALSE;
+ pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;
+ pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_NONE;
+}
+/********************************************************************
+ * FUNCTION PURPOSE: Netapi internal function to build a route
+ ********************************************************************
+ * DESCRIPTION: Netapi internal function to build a route
+ ********************************************************************/
+void netapip_netcpCfgBuildRoute(NETCP_CFG_ROUTE_T * p_route,
+ int16_t *p_flow,
+ Qmss_QueueHnd *p_q,
+ nwalRouteType_t *p_type)
+{
+ if (!p_route) return;
+ if (p_route->p_flow) *p_flow= p_route->p_flow->flowid;
+ else *p_flow = CPPI_PARAM_NOT_SPECIFIED;
+
+ if (p_route->p_dest_q) *p_q = netapi_pktioGetQ(p_route->p_dest_q);
+ else *p_q=QMSS_PARAM_NOT_SPECIFIED;
+
+ *p_type = p_route->routeType;
+}
+
+
+/******************************************************/
+/*----------------database management stuff */
+/******************************************************/
+
+/*=====================POLICIES=============================*/
+
+/********************************************************************
+ * FUNCTION PURPOSE: Netapi internal function to find a free slot for an SA
+ ********************************************************************
+ * DESCRIPTION: Netapi internal function to find a free slot for an SA
+ ********************************************************************/
+int netapip_netcpCfgFindPolicySlot(NETAPI_HANDLE_T *p_handle,
+ NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
+ int tunnel)
+{
+ int i;
+ if ((tunnel <0 ) || (tunnel >=TUNE_NETAPI_MAX_SA))
+ return -1;
+
+ p_handle->spinLock.lock(&pnetapiShm->netapi_netcp_cfg_lock);
+ //find a free entry
+ for(i=0;i<TUNE_NETAPI_MAX_POLICY;i++)
+ {
+ if (!p->policy[i].in_use)
+ {
+ p->policy[i].in_use = 2; //pending
+ p->policy[i].tunnel= tunnel; //save tunnel this is linked to
+ p_handle->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_lock);
+ return i;
+ }
+ }
+ p_handle->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_lock);
+ return -1;
+}
+
+/********************************************************************
+ * FUNCTION PURPOSE: Netapi internal function to delete a policy from policy list
+ ********************************************************************
+ * DESCRIPTION: Netapi internal function to delete a policy from policy list
+ ********************************************************************/
+void netapip_netcpCfgDeletePolicy(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
+ int policy_slot)
+{
+ if ((policy_slot <0 ) || (policy_slot >= TUNE_NETAPI_MAX_POLICY))
+ {
+ return ;
+ }
+ p->policy[policy_slot].in_use=0;
+ return;
+}
+
+/********************************************************************
+ * FUNCTION PURPOSE: Netapi internal function to insert a policy to the policy list
+ ********************************************************************
+ * DESCRIPTION: Netapi internal function to insert a policy to the policy list
+ ********************************************************************/
+void netapip_netcpCfgInsertPolicy(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
+ int policy_slot,
+ void * handle,
+ void * user_data)
+{
+ p->policy[policy_slot].in_use=1;
+ p->policy[policy_slot].nwal_handle = handle;
+ p->policy[policy_slot].user_data = user_data;
+ return;
+}
+
+/************************************************************************
+ * FUNCTION PURPOSE: Netapi internal function which returns NWAL handle for a policy
+ ************************************************************************
+ * DESCRIPTION: Netapi internal function which returns NWAL handle for a policy
+ ************************************************************************/
+void *netapip_netcpCfgGetPolicy(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
+ int policy_slot)
+{
+ if ((policy_slot <0 ) || (policy_slot >= TUNE_NETAPI_MAX_POLICY))
+ return NULL;
+ if (!p->policy[policy_slot].in_use)
+ return NULL;
+ return p->policy[policy_slot].nwal_handle;
+}
+
+/********************************************************************
+ * FUNCTION PURPOSE: Netapi internal function to find a free slot in SA list for a SA
+ ********************************************************************
+ * DESCRIPTION: Netapi internal function to find a free slot in SA list for an SA
+ ********************************************************************/
+int netapip_netcpCfgFindSaSlot(NETAPI_HANDLE_T *p_handle,
+ NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
+ int iface)
+{
+ int i;
+ if (iface != NETCP_CFG_NO_INTERFACE)
+ {
+ if ((iface <0 ) || (iface >=TUNE_NETAPI_MAX_NUM_MAC)) return -1;
+ }
+ p_handle->spinLock.lock(&pnetapiShm->netapi_netcp_cfg_lock);
+ //find a free entry
+ for(i=0;i<TUNE_NETAPI_MAX_SA;i++)
+ {
+ if (!p->tunnel[i].in_use)
+ {
+ p->tunnel[i].in_use = 2; //pending
+ p->tunnel[i].iface= iface; //save iface
+ p_handle->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_lock);
+ return i;
+ }
+ }
+ p_handle->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_lock);
+ return -1;
+}
+
+/********************************************************************
+ * FUNCTION PURPOSE: Netapi internal function to delete an SA from SA list
+ ********************************************************************
+ * DESCRIPTION: Netapi internal function to delete an SA from SA list
+ ********************************************************************/
+void netapip_netcpCfgDeleteSa(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
+ int sa_slot)
+{
+ if ((sa_slot <0 ) || (sa_slot >= TUNE_NETAPI_MAX_SA))
+ {
+ return ;
+ }
+ p->tunnel[sa_slot].in_use=0;
+ return;
+}
+
+
+/****************************************************************************
+ * FUNCTION PURPOSE: Internal function to retrieve SB command info template
+ **************************************************************************
+ * DESCRIPTION: Internal function to retrieve SB command info template
+ ***************************************************************************/
+nwalTxDmPSCmdInfo_t* netapip_netcpCfgGetSaSBInfo(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
+ NETCP_CFG_SA_T sa_app_id)
+{
+ int sa_slot = netapi_cfgGetMatchId(sa_app_id);
+ if ((sa_slot <0 ) || (sa_slot >= TUNE_NETAPI_MAX_SA))
+ {
+ return NULL;
+ }
+ return (&p->tunnel[sa_slot].dmPSCmdInfo);
+}
+
+/****************************************************************************
+ * FUNCTION PURPOSE: Internal function to retrieve Inflow mode
+ * software information required to transmit packet
+ **************************************************************************
+ * DESCRIPTION: Internal function to retrieve Inflow mode
+ * software information required to transmit packet
+ ***************************************************************************/
+int netapip_netcpCfgGetSaInflowInfo(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
+ NETCP_CFG_SA_T sa_app_id,
+ uint32_t *swInfo0,
+ uint32_t *swInfo1)
+{
+ int sa_slot = netapi_cfgGetMatchId(sa_app_id);
+ if ((sa_slot <0 ) || (sa_slot >= TUNE_NETAPI_MAX_SA))
+ {
+ return 0;
+ }
+ *swInfo0 = p->tunnel[sa_slot].swInfo0;
+ *swInfo1 = p->tunnel[sa_slot].swInfo1;
+ return 1;
+}
+
+/********************************************************************
+ * FUNCTION PURPOSE: Netapi internal function to insert an SA to the SA list
+ ********************************************************************
+ * DESCRIPTION: Netapi internal function to insert an SA to the SA list
+ ********************************************************************/
+void netapip_netcpCfgInsertSa(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
+ int sa_slot,
+ int dir,
+ int mode,
+ void * temp1,
+ void * temp2,
+ void * handle_inflow,
+ void * handle_sideband,
+ nwalTxDmPSCmdInfo_t *dmPSCmdInfo,
+ uint32_t swInfo0,
+ uint32_t swInfo1,
+ void* user_data)
+{
+ p->tunnel[sa_slot].in_use=1;
+ p->tunnel[sa_slot].inbound = dir;
+ p->tunnel[sa_slot].sa_mode = mode;
+ p->tunnel[sa_slot].sa_handle_inflow = handle_inflow;
+ p->tunnel[sa_slot].sa_handle_sideband = handle_sideband;
+ p->tunnel[sa_slot].swInfo0 = swInfo0;
+ p->tunnel[sa_slot].swInfo1 = swInfo1;
+ p->tunnel[sa_slot].user_data = user_data;
+ //netapi_Log("netapip_netcpCfgInsertSa: swInfo0 0x%x, swInfo1: 0x%x, user data: %d\n",
+// p->tunnel[sa_slot].swInfo0, p->tunnel[sa_slot].swInfo1, (uint32_t)p->tunnel[sa_slot].user_data);
+
+ if (dmPSCmdInfo)
+ {
+ memcpy(&p->tunnel[sa_slot].dmPSCmdInfo, dmPSCmdInfo, sizeof(nwalTxDmPSCmdInfo_t));
+ }
+ return;
+}
+
+/********************************************************************
+ * FUNCTION PURPOSE: Netapi internal function to return NWAL handles for an SA
+ ********************************************************************
+ * DESCRIPTION: Netapi internal function to return NWAL handles for an SA
+ ********************************************************************/
+ void *netapip_netcpCfgGetSaHandles(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
+ int sa_slot,
+ void ** p_sideband)
+{
+ if ((sa_slot <0 ) || (sa_slot >= TUNE_NETAPI_MAX_SA))
+ return NULL;
+ if (!p->tunnel[sa_slot].in_use)
+ return NULL;
+ *p_sideband = p->tunnel[sa_slot].sa_handle_sideband;
+ return p->tunnel[sa_slot].sa_handle_inflow;
+}
+
+
+/*==============================FLOWS=============================*/
+
+/********************************************************************
+ * FUNCTION PURPOSE: Netapi internal function to find a free slot for a flow
+ ********************************************************************
+ * DESCRIPTION: Netapi internal function to find a free slot for a flow
+ ********************************************************************/
+static int netapip_netcpCfgFindFlowSlot(NETAPI_HANDLE_T *p_handle,
+ NETAPI_NWAL_GLOBAL_CONTEXT_T *p)
+{
+ int i;
+ //find a free entry
+ p_handle->spinLock.lock(&pnetapiShm->netapi_netcp_cfg_lock);
+ for(i=0;i<TUNE_NETAPI_MAX_FLOWS;i++)
+ {
+ if (!p->flows[i].in_use)
+ {
+ p->flows[i].in_use = 2; /* pending */
+ p_handle->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_lock);
+ return i;
+ }
+ }
+ p_handle->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_lock);
+ return -1;
+}
+
+/********************************************************************
+ * FUNCTION PURPOSE: Netapi internal function to find delete a flow from flow list
+ ********************************************************************
+ * DESCRIPTION: Netapi internal function to find delete a flow from flow list
+ ********************************************************************/
+static void netapip_netcpCfgDeleteFlow(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
+ int slot)
+{
+ if ((slot >=0 ) && (slot < TUNE_NETAPI_MAX_FLOWS))
+ {
+ p->flows[slot].in_use = 0;
+ }
+}
+
+/********************************************************************
+ * FUNCTION PURPOSE: Netapi internal function to insert a flow to the flow list
+ ********************************************************************
+ * DESCRIPTION: Netapi internal function to delete a flow from flow list
+ ********************************************************************/
+static NETCP_CFG_FLOW_HANDLE_T netapip_netcpCfgInsertFlow(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
+ int slot,
+ int dma_engine,
+ void * handle)
+{
+ p->flows[slot].in_use=1;
+ p->flows[slot].handle = handle;
+ p->flows[slot].flow.flowid = Cppi_getFlowId(handle);
+ p->flows[slot].flow.dma_engine = dma_engine;
+ return (NETCP_CFG_FLOW_HANDLE_T) &p->flows[slot].flow;
+}
+
+/********************************************************************
+ * FUNCTION PURPOSE: Netapi internal function to find entry matching the flowid
+ ********************************************************************
+ * DESCRIPTION: Netapi internal function to find entry matching the flowid. Returns
+ * the slot number and the cPPI handle.
+ ********************************************************************/
+static int netapip_netcpCfgFindFlow(NETAPI_HANDLE_T *p_handle,
+ NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
+ int flowid,
+ int dma_engine,
+ void ** handle)
+{
+ int i;
+ *handle=NULL;
+ p_handle->spinLock.lock(&pnetapiShm->netapi_netcp_cfg_lock);
+ for(i=0;i<TUNE_NETAPI_MAX_FLOWS;i++)
+ {
+ if ((p->flows[i].in_use)&&
+ (p->flows[i].flow.flowid == flowid)&&
+ (p->flows[i].flow.dma_engine == dma_engine))
+ {
+ *handle = p->flows[i].handle;
+ p_handle->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_lock);
+ return i;
+ }
+ }
+ p_handle->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_lock);
+ return -1;
+}
+
+
+
+/*============================IP ADDRESSES==========================*/
+
+/***************************************************************************
+ * FUNCTION PURPOSE: Netapi internal function to find a free slot for IP rule in IP slot list
+ ***************************************************************************
+ * DESCRIPTION: NNetapi internal function to find a free slot for IP rule in IP slot list
+ ***************************************************************************/
+static int netapip_netcpCfgFindIpSlot(NETAPI_HANDLE_T *p_handle,
+ NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
+ int iface_no)
+{
+ int i;
+
+ //find a free entry
+ p_handle->spinLock.lock(&pnetapiShm->netapi_netcp_cfg_lock);
+ for(i=0;i<TUNE_NETAPI_MAX_NUM_IP;i++)
+ {
+ if (!p->ips[i].in_use)
+ {
+ p->ips[i].in_use = 2; //pending
+ p_handle->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_lock);
+ return i;
+ }
+ }
+ p_handle->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_lock);
+ return -1;
+}
+
+/***************************************************************************
+ * FUNCTION PURPOSE: Netapi internal function to insert an IP address into interface
+ ***************************************************************************
+ * DESCRIPTION: Netapi internal function to insert an IP address into interface
+ ***************************************************************************/
+static void netapip_netcpCfgInsertIp(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
+ nwal_IpType ipType,
+ nwalIpAddr_t *ip_addr,
+ nwalIpOpt_t *ip_qualifiers,
+ int iface_no,
+ int ip_slot,
+ void * handle,
+ void * user_data)
+{
+ p->ips[ip_slot].in_use=1;
+ memcpy(&p->ips[ip_slot].ip_addr, ip_addr, sizeof(nwalIpAddr_t));
+ if(ip_qualifiers)
+ {
+ memcpy(&p->ips[ip_slot].ip_qualifiers, ip_qualifiers, sizeof(nwalIpOpt_t));
+ }
+ else
+ {
+ memset(&p->ips[ip_slot].ip_qualifiers, 0, sizeof(nwalIpOpt_t));
+ }
+ p->ips[ip_slot].ip_type = ipType;
+ p->ips[ip_slot].nwal_handle = handle;
+ p->ips[ip_slot].user_data = user_data;
+ p->ips[ip_slot].ref_count++;
+
+}
+
+/***************************************************************************
+ * FUNCTION PURPOSE: Netapi internal function to free IP slot associated with IP address
+ ***************************************************************************
+ * DESCRIPTION: Netapi internal function to free IP slot associated with IP address
+ ***************************************************************************/
+static void netapip_netcpCfgDeleteIp(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
+ int iface_no,
+ int ip_slot)
+{
+ if ((ip_slot >=0) &&(ip_slot <=TUNE_NETAPI_MAX_NUM_IP))
+ {
+ p->ips[ip_slot].in_use=0;
+ p->ips[ip_slot].ref_count = 0;
+ }
+}
+
+/***************************************************************************
+ * FUNCTION PURPOSE: Netapi internal function to get IP handle associated with IP address
+ ***************************************************************************
+ * DESCRIPTION: Netapi internal function to get IP handle associated with IP address
+ ***************************************************************************/
+static void *netapip_netcpCfgGetIpHandle(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
+ int iface_no,
+ int ip_slot)
+{
+ if ((ip_slot <0)||(ip_slot>=TUNE_NETAPI_MAX_NUM_IP))
+ return NULL;
+ if (!p->ips[ip_slot].in_use)
+ return NULL;
+ return (void *) p->ips[ip_slot].nwal_handle;
+}
+
+/*==========================MAC INTERFACES======================*/
+
+
+
+/*******************************************************************************
+ * FUNCTION PURPOSE: Netapi internal function to insert an interface to the interface list
+ *******************************************************************************
+ * DESCRIPTION: Netapi internal function to insert an interface to the interface list
+ *******************************************************************************/
+static void netapip_netcpCfgInsertMac(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_NUM_MAC))
+ {
+ 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
+ netapi_Log("netapip_netcpCfgInsertMac, global context 0x%x\n", p);
+ }
+ else
+ netapi_Log(">netapip_netcpCfgInsertMac insert interface # out of range %d\n",iface_no);
+
+}
+
+/*******************************************************************************
+ * FUNCTION PURPOSE: Netapi internal function to get handle associated with interface
+ *******************************************************************************
+ * DESCRIPTION: Netapi internal function to get handle associated with interface
+ *******************************************************************************/
+void* netapip_netcpCfgGetMacHandle(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
+ int iface_no)
+{
+ if (iface_no == NETCP_CFG_NO_INTERFACE)
+ {
+ return NULL;
+ }
+ if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_NUM_MAC))
+ {
+ return NULL;
+ }
+ else if ( p->interfaces[iface_no].in_use)
+ {
+ return (void *) p->interfaces[iface_no].nwal_handle;
+ }
+ //no valid entry in slot
+ return NULL;
+}
+/*******************************************************************************
+ * FUNCTION PURPOSE: Netapi internal function to delete interface from interface list
+ *******************************************************************************
+ * DESCRIPTION: Netapi internal function to delete interface from interface list
+ *******************************************************************************/
+static void netapip_netcpCfgDeleteMac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
+ int iface_no)
+{
+ if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_NUM_MAC))
+ {
+ p->interfaces[iface_no].in_use = 0;
+ }
+}
+
+/*========================CLASSIFIERS==========================*/
+
+/*******************************************************************************
+ * FUNCTION PURPOSE: Netapi internal function to find a free slot for classifier rule
+ *******************************************************************************
+ * DESCRIPTION: Netapi internal function to find a free slot for classifier rule
+ *******************************************************************************/
+static int netapip_netcpCfgFindClassSlot(NETAPI_HANDLE_T *p_handle,
+ NETAPI_NWAL_GLOBAL_CONTEXT_T *p)
+{
+ int i;
+ p_handle->spinLock.lock(&pnetapiShm->netapi_netcp_cfg_lock);
+ for(i=0;i<TUNE_NETAPI_MAX_CLASSIFIERS;i++)
+ {
+ if (!p->classi[i].in_use)
+ {
+ p->classi[i].in_use = 2; //pending
+ p_handle->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_lock);
+ return i;
+ }
+ }
+ p_handle->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_lock);
+ return -1;
+}
+/*******************************************************************************
+ * FUNCTION PURPOSE: Netapi internal function to find a delete a classifer from classifer list
+ *******************************************************************************
+ * DESCRIPTION: Netapi internal function to find a delete a classifer from classifer list
+ *******************************************************************************/
+static void netapip_netcpCfgDeleteClass(
+ NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
+ int class_slot )
+{
+ if ((class_slot <0 ) || (class_slot >= TUNE_NETAPI_MAX_CLASSIFIERS))
+ {
+ return;
+ }
+ p->classi[class_slot].in_use=0;
+}
+
+/*******************************************************************************
+ * FUNCTION PURPOSE: Netapi internal function to find a insert a classifer to classifer list
+ *******************************************************************************
+ * DESCRIPTION: Netapi internal function to find a insert a classifer to classifer list
+ *******************************************************************************/
+static void netapip_netcpCfgInsertClass(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
+ int class_slot,
+ int class_type,
+ void * L2_handle,
+ void * L3_handle,
+ void * L4_handle,
+ void * user_data)
+{
+ if ((class_slot >=0 ) && (class_slot < TUNE_NETAPI_MAX_CLASSIFIERS))
+ {
+ p->classi[class_slot].in_use=1;
+ p->classi[class_slot].nwal_L2_handle = L2_handle;
+ p->classi[class_slot].nwal_L3_handle = L3_handle;
+ p->classi[class_slot].nwal_L4_handle = L4_handle;
+ p->classi[class_slot].class_type = class_type;
+ p->classi[class_slot].user_data = user_data;
+ }
+}
+
+/*******************************************************************************
+ * FUNCTION PURPOSE: Netapi internal function to get L4 nwal handle for classifier
+ *******************************************************************************
+ * DESCRIPTION: Netapi internal function to get L4 nwal handle for classifier
+ *******************************************************************************/
+static void *netapip_netcpCfgGetL4Handle(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
+ int class_slot)
+{
+ if ((class_slot <0 ) || (class_slot >= TUNE_NETAPI_MAX_CLASSIFIERS))
+ {
+ return NULL;
+ }
+ if (!p->classi[class_slot].in_use)
+ {
+ return NULL;
+ }
+ return p->classi[class_slot].nwal_L4_handle;
+}
+
+/*******************************************************************************
+ * FUNCTION PURPOSE: Netapi internal function to get L3 nwal handle for classifier
+ *******************************************************************************
+ * DESCRIPTION: Netapi internal function to get L3 nwal handle for classifier
+ *******************************************************************************/
+static void *netapip_netcpCfgGetL3Handle(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
+ int class_slot)
+{
+ if ((class_slot <0 ) || (class_slot >= TUNE_NETAPI_MAX_CLASSIFIERS))
+ {
+ return NULL;
+ }
+ if (!p->classi[class_slot].in_use)
+ {
+ return NULL;
+ }
+ return p->classi[class_slot].nwal_L3_handle;
+}
+
+
+/***********************************************************************************/
+/****************************************API****************************************/
+/***********************************************************************************/
+
+
+/********************************************************************
+ * FUNCTION PURPOSE: API to request statistics from NETCP
+ ********************************************************************
+ * DESCRIPTION: API to request statistics from NETCP
+ ********************************************************************/
+void netapi_netcpCfgReqStats(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 = netapip_getFreeTransInfo(n,
+ (NETAPI_PROC_GLOBAL_T *) n->proc_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??
+ netapi_Log("> netapi_netcpCfg reqStats failed, err=%d\n",ret);
+ }
+ netapip_freeTransInfo(pTransInfo);
+}
+/********************************************************************
+ * FUNCTION PURPOSE: API to create a MAC interface
+ ********************************************************************
+ * DESCRIPTION: API to create a MAC interface
+ ********************************************************************/
+NETCP_CFG_MACIF_T netapi_netcpCfgCreateMacInterface(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 */
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* Remote 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 */
+ 0
+ };
+
+ 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 = netapip_getFreeTransInfo(n,
+ (NETAPI_PROC_GLOBAL_T *) n->proc_global,
+ &trans_id);
+ if (!pTransInfo)
+ {
+ *err = NETAPI_ERR_BUSY;
+ return -1;
+ }
+ pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC;
+ pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
+ pTransInfo->inUse = nwal_TRUE;
+ pTransInfo->netapi_handle = h;
+
+ /* set up MacInfo */
+ memcpy(&macInfo.macAddr,p_mac,6);
+ /* todo: vlan */
+ if (switch_port)
+ {
+ macInfo.validParams |= NWAL_SET_MAC_VALID_PARAM_IFNUM ;
+ macInfo.ifNum = switch_port; /* */
+ }
+
+ if (route != NULL)
+ {
+ if((route->valid_params & NETCP_CFG_VALID_PARAM_ROUTE_TYPE) ==
+ NETCP_CFG_VALID_PARAM_ROUTE_TYPE)
+ {
+ macInfo.validParams |=
+ NWAL_SET_MAC_VALID_PARAM_ROUTE_TYPE;
+ }
+ netapip_netcpCfgBuildRoute(route,
+ &macInfo.appRxPktFlowId,
+ &macInfo.appRxPktQueue,
+ &macInfo.routeType);
+ }
+ 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;
+ netapi_Log ("netapi_netcpCfg - ERROR: nwal_setMacIface returned Error Code %d\n",
+ retValue);
+ netapip_freeTransInfo(pTransInfo);
+ 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 ((pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
+ (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_OPEN))
+ {
+ // 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);
+ }
+ if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
+ {
+ netapip_freeTransInfo(pTransInfo);
+ *err = NETAPI_ERR_PA_FW;
+ netapi_Log (">netapi_netcpCfgCreateMacInterface - ERROR returned by NETCP PA firmware %d\n",
+ *err);
+ return -1;
+ }
+
+ }
+ netapi_Log ("netapi_netcpCfg: MAC i/f %d added\n", iface_no);
+ netapip_netcpCfgInsertMac(&netapi_get_global()->nwal_context,
+ p_mac, iface_no, state,vlan,
+ (void *) pTransInfo->handle);
+ netapip_freeTransInfo(pTransInfo);
+ return (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no);
+}
+
+/********************************************************************
+ * FUNCTION PURPOSE: API to delete MAC interface
+ ********************************************************************
+ * DESCRIPTION: API to delete MAC interface
+ ********************************************************************/
+void netapi_netcpCfgDelMac(NETAPI_T h,
+ int iface_no,
+ int *err)
+{
+ nwal_RetValue ret;
+ NetapiNwalTransInfo_t *pTransInfo;
+ nwal_TransID_t trans_id;
+ NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
+ void * ifHandle;
+
+ //get the nwal handle assoicated with this iface
+ ifHandle = netapip_netcpCfgGetMacHandle(&netapi_get_global()->nwal_context, iface_no );
+ if(!ifHandle)
+ {
+ *err = NETAPI_ERR_BAD_INPUT; return ;
+ }
+ *err =0;
+
+ //get a transaction id
+ pTransInfo = netapip_getFreeTransInfo(n,
+ (NETAPI_PROC_GLOBAL_T *) n->proc_global,
+ &trans_id);
+ if (!pTransInfo)
+ {
+ *err = NETAPI_ERR_BUSY;
+ return ;
+ }
+ pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC;
+ pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING;
+ pTransInfo->inUse = nwal_TRUE;
+ pTransInfo->netapi_handle = h;
+
+ //issue request
+ ret = nwal_delMacIface(
+ ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
+ trans_id,
+ ifHandle);
+ if(ret != nwal_OK)
+ {
+ *err = NETAPI_ERR_NWAL_ERR0;
+ netapi_Log ("netapi_netcpCfg - ERROR: nwal_delMacIface returned Error Code %d\n",
+ ret);
+ netapip_freeTransInfo(pTransInfo);
+ return;
+ }
+ //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 ((pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
+ (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_IDLE))
+ {
+ // 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);
+ }
+ if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
+ {
+ netapip_freeTransInfo(pTransInfo);
+ *err = NETAPI_ERR_PA_FW;
+ netapi_Log (">netapi_netcpCfgCreateMacInterface - ERROR returned by NETCP PA firmware %d\n",
+ *err);
+ netapip_netcpCfgDeleteMac(&netapi_get_global()->nwal_context, iface_no);
+ return;
+ }
+ }
+ netapi_Log ("netapi_netcpCfg: MAC i/f %d deleted\n",iface_no);
+ netapip_freeTransInfo(pTransInfo);
+ //zap the entry
+ netapip_netcpCfgDeleteMac(&netapi_get_global()->nwal_context, iface_no);
+ return ;
+}
+
+
+/********************************************************************
+ * FUNCTION PURPOSE: NETAPi internal function to Add IP to MAC interface
+ ********************************************************************
+ * DESCRIPTION: NETAPi internal function to Add IP to MAC interface
+ ********************************************************************/
+static NETCP_CFG_IP_T netapip_netcpCfgAddIpInternal(NETAPI_T h,
+ int iface_no,
+ nwal_IpType ipType,
+ nwalIpAddr_t * ip_addr,
+ nwalIpAddr_t *ip_rem_addr,
+ nwalIpOpt_t * ip_qualifiers,
+ NETCP_CFG_ROUTE_HANDLE_T route,/*NULL for default*/
+ void * user_data,
+ int * err,
+ int flag) /*TRUE: add IP to iface,
+ FALSE: add IP as part of classifier */
+{
+ static unsigned char zeroIP4[]={0,0,0,0};
+ static unsigned char zeroIP6[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+ NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
+ void * n_handle=NULL;
+ nwalIpParam_t nwalIpParam= {
+ 0,
+ pa_IPV4, /* IP Type */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Dest IP */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Source 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 */
+ 0
+};
+ nwal_RetValue retValue;
+ NetapiNwalTransInfo_t *pTransInfo;
+ nwal_TransID_t trans_id;
+ int ip_slot=-1;
+ NETCP_CFG_IP_T ip_rule_id;
+ NETCP_CFG_IP_T temp;
+
+ //verify that iface has been configured
+ if (iface_no != NETCP_CFG_NO_INTERFACE)
+ {
+ if ((iface_no<0) || (iface_no>= TUNE_NETAPI_MAX_NUM_MAC)) {*err = NETAPI_ERR_BAD_INPUT; return -1;}
+ }
+
+ if (iface_no != NETCP_CFG_NO_INTERFACE)
+ {
+ netapi_Log("netapip_netcpCfgAddIpInternal, in_use %d\n", netapi_get_global()->nwal_context.interfaces[iface_no].in_use);
+ netapi_Log("netapip_netcpCfgAddIpInternal, p 0x%x\n", &netapi_get_global()->nwal_context);
+ 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;
+ }
+ }
+ if (flag) //if adding IP to MAC then reserve a slot to save info
+ {
+ //find free slot for IP & reserve
+ ip_slot= netapip_netcpCfgFindIpSlot(n,
+ &netapi_get_global()->nwal_context,
+ iface_no);
+ if (ip_slot <0)
+ {
+ *err= NETAPI_ERR_NOMEM; //no room
+ return -1;
+ }
+ }
+
+ //get a transaction object for config action
+ pTransInfo = netapip_getFreeTransInfo(n,
+ (NETAPI_PROC_GLOBAL_T *) n->proc_global,
+ &trans_id);
+ if (!pTransInfo)
+ {
+ *err = NETAPI_ERR_BUSY;
+ if (flag)
+ {
+ netapip_netcpCfgDeleteIp(&netapi_get_global()->nwal_context,
+ iface_no,
+ ip_slot);
+ }
+ return -1;
+ }
+ pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;
+ pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
+ pTransInfo->inUse = nwal_TRUE;
+ pTransInfo->netapi_handle = h;
+
+ //build nwalIpParam
+ memcpy(&nwalIpParam.locIpAddr,ip_addr, sizeof(nwalIpAddr_t));
+ if (ip_rem_addr)
+ {
+ if (ipType == nwal_IPV4)
+ {
+ if(memcmp(ip_rem_addr, zeroIP4, sizeof(nwalIpv4Addr_t)))
+ {
+ nwalIpParam.validParams |= NWAL_SET_IP_VALID_PARAM_REMOTE_IP;
+ memcpy(&nwalIpParam.remIpAddr,ip_rem_addr, sizeof(nwalIpAddr_t));
+ }
+ }
+ else
+ {
+ if(memcmp(ip_rem_addr, zeroIP6, sizeof(nwalIpv6Addr_t)))
+ {
+ nwalIpParam.validParams |= NWAL_SET_IP_VALID_PARAM_REMOTE_IP;
+ memcpy(&nwalIpParam.remIpAddr,ip_rem_addr, sizeof(nwalIpAddr_t));
+ }
+ }
+ }
+ nwalIpParam.ipType=ipType;
+ if(route)
+ {
+ if((route->valid_params & NETCP_CFG_VALID_PARAM_ROUTE_TYPE) ==
+ NETCP_CFG_VALID_PARAM_ROUTE_TYPE)
+ {
+ nwalIpParam.validParams |=
+ NWAL_SET_IP_VALID_PARAM_ROUTE_TYPE;
+ }
+ netapip_netcpCfgBuildRoute(route,
+ &nwalIpParam.appRxPktFlowId,
+ &nwalIpParam.appRxPktQueue,
+ &nwalIpParam.routeType);
+ }
+ else{} //use nwal defaults
+
+ if (ip_qualifiers)
+ memcpy(&nwalIpParam.ipOpt,ip_qualifiers, sizeof(nwalIpOpt_t));
+ else
+ memset(&nwalIpParam.ipOpt,0, sizeof(nwalIpOpt_t));
+
+ //build the rule id that will be returned when a packet matches
+ if (flag)
+ ip_rule_id = NETAPI_NETCP_MATCH_GENERIC_IP | iface_no | ((ip_slot&& NETAPI_NETCP_MATCH_ID_MASK) << NETAPI_NETCP_MATCH_ID_SHIFT);
+ else
+ ip_rule_id = (NETAPI_NETCP_MATCH_CLASS_L3 | iface_no);
+
+ retValue = nwal_setIPAddr( netapi_get_global()->nwal_context.nwalInstHandle,
+ trans_id,
+ (nwal_AppId) (ip_rule_id),
+ n_handle,
+ &nwalIpParam,
+ &pTransInfo->handle);
+
+ if(retValue != nwal_OK)
+ {
+ *err = NETAPI_ERR_NWAL_ERR0;
+ netapi_Log ("netcp_cfg: nwal_setIP returned Error Code %d\n",
+ retValue);
+ netapip_freeTransInfo(pTransInfo);
+ //zap the entry
+ if (flag)
+ {
+ netapip_netcpCfgDeleteIp(&netapi_get_global()->nwal_context,
+ iface_no,
+ ip_slot);
+ }
+ 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 ((pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
+ (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_OPEN))
+ {
+ // 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);
+ }
+ if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
+ {
+ netapip_freeTransInfo(pTransInfo);
+ *err = NETAPI_ERR_PA_FW;
+ netapi_Log ("netapip_netcpCfgAddIpInternal - ERROR returned by NETCP PA firmware %d\n", *err);
+ return -1;
+ }
+ }
+ if (flag)
+ {
+ netapi_Log ("netcp_cfg: IP added to interface %d (slot%d)\n", iface_no, ip_slot);
+ netapip_netcpCfgInsertIp(&netapi_get_global()->nwal_context,
+ ipType,
+ ip_addr,
+ ip_qualifiers,
+ iface_no,
+ ip_slot,
+ pTransInfo->handle,
+ user_data);
+ }
+
+ temp = (NETCP_CFG_IP_T) pTransInfo->handle;
+ netapip_freeTransInfo(pTransInfo);
+ return (flag ? ip_rule_id: temp);
+}
+
+/********************************************************************
+ * FUNCTION PURPOSE: API to Add IP to MAC interface
+ ********************************************************************
+ * DESCRIPTION: API to Add IP to MAC interface
+ ********************************************************************/
+NETCP_CFG_IP_T netapi_netcpCfgAddIp(NETAPI_T h,
+ int iface_no,
+ nwal_IpType ipType,
+ nwalIpAddr_t* ip_addr,
+ nwalIpAddr_t* ip_rem_addr,
+ nwalIpOpt_t* ip_qualifiers,
+ NETCP_CFG_ROUTE_HANDLE_T route, //NULL for default
+ void* user_data,
+ int* err)
+{
+ return netapip_netcpCfgAddIpInternal(h,
+ iface_no,
+ ipType,
+ ip_addr,
+ ip_rem_addr,
+ ip_qualifiers,
+ route,
+ user_data,
+ err,
+ 1);
+}
+/***************************************************************************
+* DESCRIPTION:Netapi internal function to check reference count of IP
+***************************************************************************/
+static Bool netapip_netcpCfgCheckIpRefCount(NETAPI_HANDLE_T *p_handle,
+ NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
+ int ip_slot)
+{
+
+ if ((ip_slot >=0) &&(ip_slot <=TUNE_NETAPI_MAX_NUM_IP))
+ {
+ p_handle->spinLock.lock(&pnetapiShm->netapi_netcp_cfg_lock);
+ /* IS IP is associated with alteast 2 rules, if yes, then dont delete IP */
+ if(p->ips[ip_slot].ref_count)
+ p->ips[ip_slot].ref_count--;
+ if (p->ips[ip_slot].ref_count)
+ {
+ p_handle->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_lock);
+ return FALSE;
+ }
+ else
+ {
+ p_handle->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_lock);
+ return TRUE;
+ }
+ }
+ else
+ return FALSE;
+}
+
+/********************************************************************
+ * FUNCTION PURPOSE: NETAPI internal function to detach IP from MAC interface
+ ********************************************************************
+ * DESCRIPTION: NETAPI internal function to detach IP from MAC interface
+ ********************************************************************/
+static void netapip_netcpCfgDelIpInternal(NETAPI_T h,
+ int iface_no,
+ nwal_IpType ipType,
+ nwalIpAddr_t * ip_addr,
+ nwalIpOpt_t * ip_qualifiers,
+ NETCP_CFG_IP_T ip_rule_id,
+ int *err,
+ void * handle, /* if flag==0, handle must be valid */
+ int flag) /* flag==0 => delete IP rule that was part of classifier, not interface */
+{
+ nwal_RetValue ret;
+ NetapiNwalTransInfo_t *pTransInfo;
+ nwal_TransID_t trans_id;
+ NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
+ void * ifHandle;
+ int ip_slot = netapi_cfgGetMatchId(ip_rule_id);
+ //get the nwal handle assoicated with this ip
+ if (flag)
+ {
+ ifHandle = netapip_netcpCfgGetIpHandle(
+ &netapi_get_global()->nwal_context, iface_no,
+ ip_slot );
+ }
+ else
+ {
+ ifHandle = handle;
+ }
+ if(!ifHandle)
+ {
+ *err = NETAPI_ERR_BAD_INPUT;
+ return ;
+ }
+ *err =0;
+
+ /* need to check to see if this IP is attached to a classifier(s)
+ and only delete if this is last classifier */
+ if (!netapip_netcpCfgCheckIpRefCount(n,
+ &netapi_get_global()->nwal_context,
+ ip_slot))
+ {
+ return;
+ }
+
+ //get a transaction id
+ pTransInfo = netapip_getFreeTransInfo(n,
+ (NETAPI_PROC_GLOBAL_T *) n->proc_global,
+ &trans_id);
+ if (!pTransInfo)
+ {
+ *err = NETAPI_ERR_BUSY;
+ return;
+ }
+ pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;
+ pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING;
+ pTransInfo->inUse = nwal_TRUE;
+ pTransInfo->netapi_handle = h;
+ //issue request
+ ret = nwal_delIPAddr(
+ ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
+ trans_id,
+ ifHandle);
+ if(ret != nwal_OK)
+ {
+ *err = NETAPI_ERR_NWAL_ERR0;
+ netapi_Log ("netcp_cfg - ERROR: nwal_delMacIface returned Error Code %d\n",
+ ret);
+ netapip_freeTransInfo(pTransInfo);
+ return ;
+ }
+ //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 ((pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
+ (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_IDLE))
+ {
+ // 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);
+ }
+ if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
+ {
+ netapip_freeTransInfo(pTransInfo);
+ *err = NETAPI_ERR_PA_FW;
+ netapi_Log (">netapip_netcpCfgDelIpInternal - ERROR returned by NETCP PA firmware %d\n", *err);
+ return;
+ }
+ }
+
+ netapip_freeTransInfo(pTransInfo);
+
+ //zap the entry
+ if (flag)
+ netapip_netcpCfgDeleteIp(&netapi_get_global()->nwal_context,
+ iface_no,
+ ip_slot);
+ return ;
+}
+
+/********************************************************************
+ * FUNCTION PURPOSE: API to detach IP from MAC interface
+ ********************************************************************
+ * DESCRIPTION: API to detach IP from MAC interface
+ ********************************************************************/
+void netapi_netcpCfgDelIp(NETAPI_T h,
+ int iface_no,
+ nwal_IpType ipType,
+ nwalIpAddr_t* ip_addr,
+ nwalIpOpt_t* ip_qualifiers,
+ NETCP_CFG_IP_T ip_rule_id,
+ int* err)
+{
+ netapip_netcpCfgDelIpInternal( h, iface_no, ipType,
+ ip_addr, ip_qualifiers, ip_rule_id,
+ err, NULL, 1);
+ return;
+}
+
+
+/********************************************************************
+ * FUNCTION PURPOSE: API to attach a classifier rule to NETCP
+ ********************************************************************
+ * DESCRIPTION: API to attach a classifier rule to NETCP
+ ********************************************************************/
+NETCP_CFG_CLASS_T netapi_netcpCfgAddClass(NETAPI_T h,
+ NETCP_CFG_CLASSIFIER_T* p_class,
+ NETCP_CFG_ROUTE_HANDLE_T route,
+ int action,
+ void* user_data,
+ int* err)
+{
+ NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
+ void * l3_handle=NULL; //ip handle
+ nwal_RetValue retValue;
+ NetapiNwalTransInfo_t *pTransInfo;
+ nwal_TransID_t trans_id;
+ int class_slot=-1;
+ int iface_no;
+ int ip_slot=-1;
+ NETCP_CFG_CLASS_T classHandle; //returned by us
+ nwal_appProtoType_t proto;
+ nwalRxConnCfg_t tempCfg=
+ {
+ 0, //nwal_handle: to be filled in
+ 0, // l4 ports: to be filled in
+ 0, //core id (NA)
+ 0, //action
+ CPPI_PARAM_NOT_SPECIFIED, //flow id
+ QMSS_PARAM_NOT_SPECIFIED, //dest queue
+ 0,
+ 0, // l4 ports: to be filled in
+ };
+
+ *err = NETAPI_ERR_OK;
+
+ if(!p_class)
+ {
+ *err=NETAPI_ERR_BAD_INPUT;
+ return -1;
+ }
+ switch(p_class->classType)
+ {
+ default:
+ netapi_Log(">netapi_netcpCfg : classifier type %d not supported\n",p_class->classType);
+ break;
+ case(NETCP_CFG_CLASS_TYPE_L3_L4):
+ case(NETCP_CFG_CLASS_TYPE_L4):
+ //assume just type l4 only (L2, L3 defined by iface, l3 id )
+ iface_no = p_class->u.c_l4.iface;
+ if (p_class->classType== NETCP_CFG_CLASS_TYPE_L4)
+ {
+ ip_slot = netapi_cfgGetMatchId(p_class->u.c_l4.ip);
+ }
+
+ //verify that iface has been configured
+ if (iface_no != NETCP_CFG_NO_INTERFACE)
+ {
+ if(!netapi_get_global()->nwal_context.interfaces[iface_no].in_use)
+ {
+ *err = NETAPI_ERR_BAD_INPUT;
+ return -1;
+ }
+ }
+
+ if (p_class->classType== NETCP_CFG_CLASS_TYPE_L4)
+ {
+ //verify that ip has been configured and get its handle
+ l3_handle = netapip_netcpCfgGetIpHandle(
+ &netapi_get_global()->nwal_context, iface_no,
+ ip_slot );
+ }
+ else
+ {
+ nwalIpParam_t tempParam=
+ {
+ 0,
+ pa_IPV4, /* IP Type */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Dest IP */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Source 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 */
+ 0
+ };
+ //build nwalIpParam
+ memcpy(&tempParam.locIpAddr,p_class->u.c_l3_l4.ip_addr, sizeof(nwalIpAddr_t));
+ tempParam.ipType=p_class->u.c_l3_l4.ipType;
+ //use nwal defauls for route
+ if (p_class->u.c_l3_l4.ip_qualifiers)
+ memcpy(&tempParam.ipOpt,p_class->u.c_l3_l4.ip_qualifiers, sizeof(nwalIpOpt_t));
+ else
+ memset(&tempParam.ipOpt,0, sizeof(nwalIpOpt_t));
+
+ //find if we have a matching L3 handle for IP classifier; if not create it
+ retValue = nwal_getIPAddr (((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
+ &tempParam,
+ netapip_netcpCfgGetMacHandle(&netapi_get_global()->nwal_context, iface_no ),
+ &l3_handle);
+ if (retValue != nwal_TRUE)
+ {
+ int ret;
+ //**NEW IP RULE
+ //need to attach this IP RULE to the MAC
+ l3_handle= (void *) netapip_netcpCfgAddIpInternal(
+ h, iface_no,
+ p_class->u.c_l3_l4.ipType,
+ p_class->u.c_l3_l4.ip_addr,
+ NULL,
+ p_class->u.c_l3_l4.ip_qualifiers,
+ p_class->u.c_l3_l4.p_fail_route,
+ user_data,
+ &ret,
+ FALSE);
+ if(!ret)
+ {
+ l3_handle=NULL;
+ }
+ }
+ }
+ if(!l3_handle)
+ {
+ *err = NETAPI_ERR_BAD_INPUT;
+ return -1 ;
+ }
+
+
+ //find free slot for CLASS & reserve
+ class_slot= netapip_netcpCfgFindClassSlot(n,
+ &netapi_get_global()->nwal_context);
+ if(class_slot<0) {*err = NETAPI_ERR_NOMEM; return -1;}
+ classHandle = NETAPI_NETCP_MATCH_CLASS |
+ (class_slot << NETAPI_NETCP_MATCH_ID_SHIFT) |
+ (iface_no & NETAPI_NETCP_MATCH_LOGICAL_MAC_IFACE_MASK);
+ //build request from template
+ tempCfg.inHandle=l3_handle;
+ if (p_class->classType== NETCP_CFG_CLASS_TYPE_L4)
+ {
+ memcpy(&tempCfg.appProto,&p_class->u.c_l4.appProto,sizeof(nwalAppProto_t));
+ proto = p_class->u.c_l4.proto;
+ }
+ else
+ {
+ memcpy(&tempCfg.appProto,&p_class->u.c_l3_l4.appProto,sizeof(nwalAppProto_t));
+ proto = p_class->u.c_l3_l4.proto;
+ }
+
+ tempCfg.matchAction = (action==NETCP_CFG_ACTION_TO_SW) ? NWAL_MATCH_ACTION_HOST : NWAL_MATCH_ACTION_DISCARD;
+ if (route)
+ {
+ if((route->valid_params & NETCP_CFG_VALID_PARAM_ROUTE_TYPE) ==
+ NETCP_CFG_VALID_PARAM_ROUTE_TYPE)
+ {
+ tempCfg.validParams |=
+ NWAL_SET_CONN_VALID_PARAM_ROUTE_TYPE;
+ }
+ netapip_netcpCfgBuildRoute(route,
+ &tempCfg.appRxPktFlowId,
+ &tempCfg.appRxPktQueue,
+ &tempCfg.routeType);
+ }
+
+
+ //get a transaction id
+ pTransInfo = netapip_getFreeTransInfo(n,
+ (NETAPI_PROC_GLOBAL_T *) n->proc_global,
+ &trans_id);
+ if (!pTransInfo)
+ {
+ *err = NETAPI_ERR_BUSY;
+ return -1;
+ }
+ pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_PORT;
+ pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
+ pTransInfo->inUse = nwal_TRUE;
+ pTransInfo->netapi_handle = h;
+ //issue request
+ retValue = nwal_addConn(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
+ trans_id,
+ (nwal_AppId) classHandle,
+ proto,
+ &tempCfg,
+ NULL,
+ &pTransInfo->handle);
+ if(retValue != nwal_OK)
+ {
+ *err = NETAPI_ERR_NWAL_ERR0;
+ netapi_Log ("netcp_cfg - ERROR: nwal_delMacIface returned Error Code %d\n",
+ retValue);
+ netapip_freeTransInfo(pTransInfo);
+ netapip_netcpCfgDeleteClass(&netapi_get_global()->nwal_context, class_slot);
+ 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 ((pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
+ (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_OPEN))
+ {
+ // 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);
+ }
+ if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
+ {
+ netapip_freeTransInfo(pTransInfo);
+ *err = NETAPI_ERR_PA_FW;
+ netapip_netcpCfgDeleteClass(&netapi_get_global()->nwal_context, class_slot);
+ netapi_Log (">netcp_cfgAddClass - ERROR returned by NETCP PA firmware %d\n", *err);
+ return -1;
+ }
+ }
+ netapi_Log ("netcp_cfg: L4 Classifer added to interface %d ip %d (slot%d)\n", iface_no, ip_slot, class_slot);
+ netapip_netcpCfgInsertClass(&netapi_get_global()->nwal_context,
+ class_slot,
+ p_class->classType,
+ NULL, //L2 we have
+ (p_class->classType== NETCP_CFG_CLASS_TYPE_L3_L4? l3_handle : NULL),
+ pTransInfo->handle,
+ user_data);
+
+ netapip_freeTransInfo(pTransInfo);
+ return classHandle;
+ } //end switch
+
+return -1;
+}
+
+/********************************************************************
+ * FUNCTION PURPOSE: API to delete a preconfigured classifier
+ ********************************************************************
+ * DESCRIPTION: API to delete a preconfigured classifier
+ ********************************************************************/
+void netapi_netcpCfgDelClass(NETAPI_T h,
+ NETCP_CFG_CLASS_T classId,
+ int* err)
+{
+ NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
+ void * L4_handle; //class handle -> L4
+ void * L3_handle; //class handle -> L3
+ nwal_RetValue retValue;
+ NetapiNwalTransInfo_t *pTransInfo;
+ nwal_TransID_t trans_id;
+ int class_slot=-1;
+
+ class_slot = netapi_cfgGetMatchId(classId);
+ L4_handle=netapip_netcpCfgGetL4Handle(&netapi_get_global()->nwal_context, class_slot);
+ if(!L4_handle)
+ {
+ *err = NETAPI_ERR_BAD_INPUT;
+ goto ERR_netapi_netcpCfgDelClass;
+ }
+ L3_handle = netapip_netcpCfgGetL3Handle( &netapi_get_global()->nwal_context, class_slot );
+ /* l3 handle might be NULL,, depending on type of classifier */
+
+ netapip_netcpCfgDeleteClass(
+ &netapi_get_global()->nwal_context,
+ class_slot );
+ //get a transaction id
+ pTransInfo = netapip_getFreeTransInfo(n,
+ (NETAPI_PROC_GLOBAL_T *) n->proc_global,
+ &trans_id);
+ if (!pTransInfo)
+ {
+ *err = NETAPI_ERR_BUSY;
+ goto ERR_netapi_netcpCfgDelClass;
+ }
+ pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_PORT;
+ pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING;
+ pTransInfo->inUse = nwal_TRUE;
+ pTransInfo->netapi_handle = h;
+ //issue request for L4
+ retValue = nwal_delConn(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
+ trans_id,
+ L4_handle);
+ if(retValue != nwal_OK)
+ {
+ *err = NETAPI_ERR_NWAL_ERR0;
+ netapi_Log ("netcp_cfg - ERROR: nwal_delMacIface returned Error Code %d\n", retValue);
+ netapip_freeTransInfo(pTransInfo);
+ goto ERR_netapi_netcpCfgDelClass; /* todo: what about the L3? */
+ }
+ //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 ((pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
+ (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_IDLE))
+ {
+ // 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);
+ }
+ }
+ if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
+ {
+ netapip_freeTransInfo(pTransInfo);
+ *err = NETAPI_ERR_PA_FW;
+ netapi_Log (">netapi_netcpCfgDelClass - ERROR returned by NETCP PA firmware %d\n", *err);
+ goto ERR_netapi_netcpCfgDelClass;
+ }
+ netapi_Log ("netcp_cfg: Classifer deleted\n");
+ pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;
+ pTransInfo->inUse = nwal_FALSE;
+
+ /* delete L3 if we have to */
+ if (L3_handle)
+ {
+ netapip_netcpCfgDelIpInternal( h, 0, 0,
+ NULL, NULL, 0,
+ err, L3_handle, 0);
+ }
+ netapip_freeTransInfo(pTransInfo);
+
+ERR_netapi_netcpCfgDelClass:
+ return;
+}
+
+/********************************************************************
+ * FUNCTION PURPOSE: API to add a flow
+ ********************************************************************
+ * DESCRIPTION: API to add a flow
+ ********************************************************************/
+/*--------------flow management--------*/
+// ADD A Flow
+NETCP_CFG_FLOW_HANDLE_T netapi_netcpCfgAddFlow(NETAPI_T h,
+ int n,
+ Pktlib_HeapHandle handles[],
+ int sizes[],
+ NETCP_CFG_FLOW_CONFIG_T* p_cfg,
+ int* err )
+{
+ Cppi_RxFlowCfg rxFlowCfg;
+ Uint8 isAlloc;
+ Qmss_QueueHnd rxBufQ[TUNE_NETAPI_MAX_BUF_POOLS_IN_FLOW];
+ Uint32 rxBufSize[TUNE_NETAPI_MAX_BUF_POOLS_IN_FLOW];
+ int i;
+ Cppi_FlowHnd FlowHnd;
+ int slot;
+ NETCP_CFG_FLOW_HANDLE_T retVal;
+ NETAPI_HANDLE_T * pHandle = (NETAPI_HANDLE_T *) h;
+ *err= 0; /* ok */
+ if (!p_cfg)
+ {
+ *err= NETAPI_ERR_BAD_INPUT;
+ return NULL;
+ }
+ //get a slot to save new flow
+ slot = netapip_netcpCfgFindFlowSlot(pHandle,
+ &netapi_get_global()->nwal_context);
+
+ if (slot<0) { *err= NETAPI_ERR_NOMEM; return NULL; }
+
+ //configure flow
+ memset(&rxFlowCfg,0,sizeof(Cppi_RxFlowCfg));
+ for (i = 0; i < TUNE_NETAPI_MAX_BUF_POOLS_IN_FLOW; i++)
+ {
+ if (i >= n)
+ {
+ rxBufQ[i] = 0;
+ rxBufSize[i] = 0;
+ }
+ else
+ {
+ rxBufQ[i] = Pktlib_getInternalHeapQueue(handles[i]);
+ //todo: verity sizes< heapsize
+ //todo: verify order
+ rxBufSize[i]= sizes[i];
+ }
+ if (i && (rxBufQ[i] <= 0))
+ {
+ rxBufQ[i] = rxBufQ[i-1];
+ rxBufSize[i] = 0;
+ }
+ }
+
+ /* Configure Rx flow */
+ rxFlowCfg.flowIdNum = p_cfg->flow_index;/*CPPI_PARAM_NOT_SPECIFIED*/;
+ rxFlowCfg.rx_dest_qnum = netapi_pktioGetQ(p_cfg->p_dest_q);
+ rxFlowCfg.rx_dest_qmgr = Qmss_getQueueNumber(rxFlowCfg.rx_dest_qnum).qMgr;
+ rxFlowCfg.rx_sop_offset = p_cfg->recv_offset;
+ rxFlowCfg.rx_ps_location = Cppi_PSLoc_PS_IN_DESC;
+ rxFlowCfg.rx_desc_type = Cppi_DescType_HOST;
+ rxFlowCfg.rx_error_handling = p_cfg->block;
+
+ rxFlowCfg.rx_psinfo_present = 1;
+ rxFlowCfg.rx_einfo_present = 1;
+
+ rxFlowCfg.rx_dest_tag_lo = 0;
+ rxFlowCfg.rx_dest_tag_hi = 0;
+ rxFlowCfg.rx_src_tag_lo = 0;
+ rxFlowCfg.rx_src_tag_hi = 0;
+
+ rxFlowCfg.rx_size_thresh0_en = rxBufSize[1] ? 1 : 0;
+ rxFlowCfg.rx_size_thresh1_en = rxBufSize[2] ? 1 : 0;
+ rxFlowCfg.rx_size_thresh2_en = rxBufSize[3] ? 1 : 0;
+
+ if (p_cfg->dma_index==NETAPI_DMA_NETCP )
+ rxFlowCfg.rx_dest_tag_lo_sel =0;
+ else
+ rxFlowCfg.rx_dest_tag_lo_sel = 0x4;
+ rxFlowCfg.rx_dest_tag_hi_sel = 0;
+ rxFlowCfg.rx_src_tag_lo_sel = 0;
+ rxFlowCfg.rx_src_tag_hi_sel = 0;
+
+ rxFlowCfg.rx_fdq1_qnum = rxBufQ[1];
+ rxFlowCfg.rx_fdq1_qmgr = (rxBufQ[1] ? Qmss_getQueueNumber(rxBufQ[1]).qMgr: 0);
+ rxFlowCfg.rx_fdq2_qnum = rxBufQ[2];
+ rxFlowCfg.rx_fdq2_qmgr = (rxBufQ[2] ? Qmss_getQueueNumber(rxBufQ[2]).qMgr: 0);
+ rxFlowCfg.rx_fdq3_qnum = rxBufQ[3];
+ rxFlowCfg.rx_fdq3_qmgr = (rxBufQ[3] ? Qmss_getQueueNumber(rxBufQ[3]).qMgr: 0);
+
+ rxFlowCfg.rx_size_thresh0 = rxBufSize[1] ? rxBufSize[0] : 0;
+ rxFlowCfg.rx_size_thresh1 = rxBufSize[2] ? rxBufSize[1] : 0;
+ rxFlowCfg.rx_size_thresh2 = rxBufSize[3] ? rxBufSize[2] : 0;
+
+ rxFlowCfg.rx_fdq0_sz0_qnum = rxBufQ[0];
+ rxFlowCfg.rx_fdq0_sz0_qmgr = (rxBufQ[0] ? Qmss_getQueueNumber(rxBufQ[0]).qMgr: 0);
+ rxFlowCfg.rx_fdq0_sz1_qnum = rxBufQ[1];
+ rxFlowCfg.rx_fdq0_sz1_qmgr = (rxBufQ[1] ? Qmss_getQueueNumber(rxBufQ[1]).qMgr:0);
+ rxFlowCfg.rx_fdq0_sz2_qnum = rxBufQ[2];
+ rxFlowCfg.rx_fdq0_sz2_qmgr = (rxBufQ[2] ? Qmss_getQueueNumber(rxBufQ[2]).qMgr:0);
+ rxFlowCfg.rx_fdq0_sz3_qnum = rxBufQ[3];
+ rxFlowCfg.rx_fdq0_sz3_qmgr = (rxBufQ[3] ? Qmss_getQueueNumber(rxBufQ[3]).qMgr:0);
+ {
+ //todo: replace this with a nwal call to get global cntx info
+ Cppi_CpDmaInitCfg cpdmaCfg;
+ Cppi_Handle cppiHnd;
+ memset(&cpdmaCfg,0,sizeof(Cppi_CpDmaInitCfg));
+ cpdmaCfg.dmaNum = (p_cfg->dma_index==NETAPI_DMA_NETCP ) ?Cppi_CpDma_PASS_CPDMA: Cppi_CpDma_QMSS_CPDMA;
+ cppiHnd= Cppi_open (&cpdmaCfg);
+ if (cppiHnd == NULL)
+ {
+ netapip_netcpCfgDeleteFlow(&netapi_get_global()->nwal_context, slot);
+ *err= NETAPI_ERR_NORES;
+ return NULL;
+ }
+ FlowHnd = Cppi_configureRxFlow (cppiHnd, &rxFlowCfg, &isAlloc);
+ }
+ if (FlowHnd == NULL)
+ {
+ *err= NETAPI_ERR_NORES;
+ netapip_netcpCfgDeleteFlow(&netapi_get_global()->nwal_context, slot);
+ return (NULL);
+ }
+
+ //update slot
+ retVal = netapip_netcpCfgInsertFlow(&netapi_get_global()->nwal_context,
+ slot,
+ p_cfg->dma_index,
+ (void*) FlowHnd);
+ netapi_Log(">netcp cfg: flow %d created in dma index %d\n",
+ ((NETCP_CFG_FLOW_T *) retVal)->flowid, p_cfg->dma_index);
+ return (retVal);
+}
+
+/********************************************************************
+ * FUNCTION PURPOSE: API to delete a flow
+ ********************************************************************
+ * DESCRIPTION: API to delete a flow
+ ********************************************************************/
+void netapi_netcpCfgDelFlow(NETAPI_T h,
+ NETCP_CFG_FLOW_HANDLE_T f,
+ int* err)
+{
+ int slot;
+ void * handle;
+ *err=0;
+ NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
+ /* find entry */
+ slot = netapip_netcpCfgFindFlow(n,
+ &netapi_get_global()->nwal_context,
+ ((NETCP_CFG_FLOW_T *) f) ->flowid,
+ ((NETCP_CFG_FLOW_T *) f) ->dma_engine,
+ &handle);
+ if (slot<0)
+ {
+ *err = NETAPI_ERR_BAD_INPUT;
+ return;
+ }
+
+ Cppi_closeRxFlow( (Cppi_FlowHnd) handle);
+ netapip_netcpCfgDeleteFlow(&netapi_get_global()->nwal_context,
+ slot);
+ netapi_Log(">netcp cfg: flow %d (dma index %d) deleted\n",
+ ((NETCP_CFG_FLOW_T *) f)->flowid,
+ ((NETCP_CFG_FLOW_T *) f)->dma_engine);
+ return;
+}
+
+/******************************************************************************
+ * FUNCTION PURPOSE: API to configure NETCP with global rules for exception packet handling
+ ******************************************************************************
+ * DESCRIPTION: API to configure NETCP with global rules for exception packet handling
+ *****************************************************************************/
+NETCP_CFG_EXCEPTION_PKT_T netapi_netcpCfgExceptions(NETAPI_T h,
+ int exception_id,
+ nwal_matchAction_t action,
+ NETCP_CFG_ROUTE_HANDLE_T p_route)
+{
+ nwalCtlInfo_t ctrl;
+ NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
+ nwal_RetValue retVal = 0;
+ memset(&ctrl, 0, sizeof(nwalCtlInfo_t));
+
+
+ if (p_route != NULL)
+ {
+ if((p_route->valid_params & NETCP_CFG_VALID_PARAM_ROUTE_TYPE) ==
+ NETCP_CFG_VALID_PARAM_ROUTE_TYPE)
+ {
+ ctrl.validParams |=
+ NWAL_CONTROL_VALID_PARAM_ROUTE_TYPE;
+ ctrl.routeType = p_route->routeType;
+ }
+ netapip_netcpCfgBuildRoute(p_route,
+ &ctrl.appRxPktFlowId,
+ &ctrl.appRxPktQueue,
+ &ctrl.routeType);
+ }
+ else
+ {
+ ctrl.appRxPktFlowId = NWAL_FLOW_NOT_SPECIFIED;
+ ctrl.appRxPktQueue = NWAL_QUEUE_NOT_SPECIFIED;
+ }
+
+ ctrl.appId = (void*)(NETAPI_NETCP_CFG_MATCH_EXCEPTION | exception_id);
+
+ ctrl.matchAction = action;
+
+ if (exception_id == NETCP_CFG_ALL_EXCEPTIONS)
+ {
+ ctrl.pktCtl = NWAL_CTRL_CFG_ALL_EXCEPTIONS;
+ }
+ else
+ {
+ ctrl.pa_EROUTE_Id = exception_id;
+ ctrl.pktCtl = NWAL_CTRL_CFG_SINGLE_EXCEPTION;
+ }
+
+ retVal = nwal_control(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle, &ctrl);
+
+ return (NETCP_CFG_EXCEPTION_PKT_T) ctrl.appId;
+
+}
+
+/*************************************************************************/
+/*********************************INTERNAL*******************************/
+/************************************************************************/
+
+/********************************************************************
+ * FUNCTION PURPOSE: NETAPI internal function, NETCP command reply callback
+ ********************************************************************
+ * DESCRIPTION: NETAPI internal function, NETCP command reply callback
+ ********************************************************************/
+void netapip_netcpCfgNWALCmdCallBack(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_proc_global()->nwal_context.numBogusTransIds++;
+ return;
+ }
+
+ p_trans= &netapi_get_proc_global()->nwal_context.transInfos[trans_id];
+ p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;
+
+ if(ret != nwal_OK)
+ {
+ netapi_Log ("netcp_cfg : netapip_netcpCfgNWALCmdCallBack returned Error Code %d for trans_id %d\n",
+ ret, trans_id);
+ // update error code that is fialed in p_trans */
+ //todo: atomic inc
+ p_trans->state = NETAPI_NWAL_HANDLE_STATE_ERR;
+ netapi_get_proc_global()->nwal_context.numCmdFail++;
+ }
+ else
+ {
+ //todo: atomic inc
+ netapi_get_proc_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;
+ }
+ case NETAPI_NWAL_HANDLE_TRANS_PORT:
+ {
+ 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_SA:
+ {
+ 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_SA_POLICY:
+ {
+ 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;
+ }
+ default:
+ {
+ netapi_Log ("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;
+ }
+}
+
+
+/********************************************************************
+ * FUNCTION PURPOSE: NETAPI internal function, PA stats reply callback
+ ********************************************************************
+ * DESCRIPTION: NETAPI internal function, PA stats reply callback
+ ********************************************************************/
+void netapip_netcpCfgNWALCmdPaStatsReply(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_proc_global()->nwal_context.numBogusTransIds++;
+ return;
+ }
+
+ p_trans= &netapi_get_proc_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;
+
+ //callout result to application !!
+ if (p_local->stats_cb)
+ {
+ (*p_local->stats_cb)(p_trans->netapi_handle,stats);
+ }
+}
+