added classifier to netcp_cfg.c
[keystone-rtos/netapi.git] / ti / runtime / netapi / src / netcp_cfg.c
1 /**********************************************************\r
2  * file: netcp_cfg.c\r
3  * purpose: netcp configurations routines\r
4  **************************************************************\r
5  * FILE: netcp_cfg.c\r
6  * \r
7  * DESCRIPTION:  netcp configuration main source file for user space transport\r
8  *               library\r
9  * \r
10  * REVISION HISTORY:  rev 0.0.1 \r
11  *\r
12  *  Copyright (c) Texas Instruments Incorporated 2010-2011\r
13  * \r
14  *  Redistribution and use in source and binary forms, with or without \r
15  *  modification, are permitted provided that the following conditions \r
16  *  are met:\r
17  *\r
18  *    Redistributions of source code must retain the above copyright \r
19  *    notice, this list of conditions and the following disclaimer.\r
20  *\r
21  *    Redistributions in binary form must reproduce the above copyright\r
22  *    notice, this list of conditions and the following disclaimer in the \r
23  *    documentation and/or other materials provided with the   \r
24  *    distribution.\r
25  *\r
26  *    Neither the name of Texas Instruments Incorporated nor the names of\r
27  *    its contributors may be used to endorse or promote products derived\r
28  *    from this software without specific prior written permission.\r
29  *\r
30  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \r
31  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \r
32  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
33  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \r
34  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \r
35  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \r
36  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
37  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
38  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
39  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
40  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
41 \r
42  ******************************************************/\r
43 #include <stdio.h>\r
44 #include <stdlib.h>\r
45 #include <unistd.h>\r
46 #include <string.h>\r
47 #include "netapi.h"\r
48 #include "netcp_cfg.h"\r
49 #include "netapi_loc.h"\r
50 \r
51 /******************************************************************\r
52  ********************Utility*************************************\r
53 *******************************************************************/\r
54 \r
55 \r
56 //get a free transaction id\r
57 static NetapiNwalTransInfo_t *  netapi_GetFreeTransInfo(NETAPI_GLOBAL_T *p_global, nwal_TransID_t *pTransId)\r
58 {\r
59          uint16_t    count=0;\r
60 \r
61         count=0;\r
62         while(count < TUNE_NETAPI_MAX_NUM_TRANS)\r
63         {\r
64             if((p_global->nwal_context.transInfos[count].inUse) != nwal_TRUE)\r
65             {\r
66                 p_global->nwal_context.transInfos[count].inUse = nwal_TRUE;\r
67                 *pTransId = count;\r
68                 return(&p_global->nwal_context.transInfos[count]);\r
69             }\r
70             count++;\r
71         }\r
72          \r
73         /* trouble.  need to wait for one to free up*/\r
74         /* to do: handle this by forcing a poll of cntrl queue*/\r
75         printf(">netcp_cfg: trying to get free transaction slot but all full!!\n");\r
76         return NULL;\r
77 \r
78 }\r
79 \r
80 //internal: find a free slot for IP rule in interface\r
81 static int netcp_cfgp_find_ip_slot(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
82                           int iface_no)\r
83 {\r
84    int i;\r
85    if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_INTERFACES))\r
86    {\r
87         return -1;\r
88    }\r
89    if (!p->interfaces[iface_no].in_use) return -1;\r
90 \r
91    //find a free entry\r
92    for(i=0;i<TUNE_NETAPI_MAX_IP_PER_INTERFACE;i++)\r
93    {\r
94        if (!p->interfaces[iface_no].ips[i].in_use)\r
95        {\r
96            p->interfaces[iface_no].ips[i].in_use = 2; //pending\r
97            return i;\r
98        }\r
99    }\r
100    return -1;\r
101 }\r
102 \r
103 //internal: find a free slot for classifier rule\r
104 static int netcp_cfgp_find_class_slot( NETAPI_NWAL_GLOBAL_CONTEXT_T *p)\r
105 {\r
106    int i;\r
107          //find a free entry\r
108    for(i=0;i<TUNE_NETAPI_MAX_CLASSIFIERS;i++)\r
109    {\r
110        if (!p->classi[i].in_use)\r
111        {\r
112            p->classi[i].in_use = 2; //pending\r
113            return i;\r
114        }\r
115    }\r
116    return -1;   \r
117 }\r
118 \r
119 //internal:  insert an IP address into iface\r
120 static void netcp_cfgp_insert_ip(NETAPI_NWAL_GLOBAL_CONTEXT_T *p, \r
121                           nwal_IpType ipType,\r
122                           nwalIpAddr_t *ip_addr, \r
123                           nwalIpOpt_t *ip_qualifiers, \r
124                           int iface_no,\r
125                           int ip_slot,  //we 'reserved it already'\r
126                           void * handle)\r
127 {\r
128         p->interfaces[iface_no].ips[ip_slot].in_use=1;\r
129         memcpy(&p->interfaces[iface_no].ips[ip_slot].ip_addr, ip_addr, sizeof(nwalIpAddr_t));\r
130         if(ip_qualifiers)\r
131         memcpy(&p->interfaces[iface_no].ips[ip_slot].ip_qualifiers, ip_qualifiers, sizeof(nwalIpOpt_t));\r
132         else\r
133         memset(&p->interfaces[iface_no].ips[ip_slot].ip_qualifiers, 0, sizeof(nwalIpOpt_t));\r
134         p->interfaces[iface_no].ips[ip_slot].ip_type = ipType;\r
135         p->interfaces[iface_no].ips[ip_slot].nwal_handle = handle;\r
136         return;\r
137 }\r
138 \r
139 \r
140 //internal: insert interface info into global context\r
141 static void netcp_cfgp_insert_mac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p, unsigned char * p_mac, \r
142                            int iface_no, int state, NETCP_CFG_VLAN_T vlan, void * handle)\r
143 {\r
144    if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_INTERFACES))\r
145    {\r
146         memset(&p->interfaces[iface_no],0,sizeof(NETCP_INTERFACE_T));\r
147         p->interfaces[iface_no].in_use = 1;\r
148         memcpy(&p->interfaces[iface_no].mac[0], p_mac,6);\r
149         p->interfaces[iface_no].state = state;\r
150         //todo p->interfaces[iface_no].vlan = vlan;\r
151         p->interfaces[iface_no].nwal_handle = handle; //save handle assoicated with this rule\r
152    }\r
153    else printf(">netcp_cfg insert interface # out of range %d\n",iface_no);\r
154 \r
155 }\r
156 //internal: clear inteface entry\r
157 static void netcp_cfgp_delete_mac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,int iface_no)  \r
158 {\r
159    if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_INTERFACES))\r
160    {\r
161         p->interfaces[iface_no].in_use = 0;\r
162    }\r
163 }\r
164 //internal: free IP slot associated with ip address \r
165 static void netcp_cfgp_delete_ip(\r
166          NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
167          int iface_no,\r
168          int ip_slot )\r
169 {\r
170    if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_INTERFACES))\r
171    {\r
172         return ;\r
173    }\r
174    if (!p->interfaces[iface_no].in_use) return ;\r
175    if ((ip_slot <0)||(ip_slot>TUNE_NETAPI_MAX_IP_PER_INTERFACE)) return ;\r
176    p->interfaces[iface_no].ips[ip_slot].in_use=0;\r
177    return;\r
178 }\r
179 \r
180 \r
181 //internal: get IP handle associated with ip address \r
182 static void *netcp_cfgp_get_ip_handle(\r
183          NETAPI_NWAL_GLOBAL_CONTEXT_T *p, \r
184          int iface_no,\r
185          int ip_slot )\r
186 {\r
187    if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_INTERFACES))\r
188    {\r
189         return NULL;\r
190    }\r
191    if (!p->interfaces[iface_no].in_use) return NULL;\r
192    if ((ip_slot <0)||(ip_slot>=TUNE_NETAPI_MAX_IP_PER_INTERFACE)) return NULL;\r
193    if (!p->interfaces[iface_no].ips[ip_slot].in_use) return NULL;\r
194    return (void *) p->interfaces[iface_no].ips[ip_slot].nwal_handle;\r
195 }\r
196 \r
197 //internal: get handle associated with interface\r
198 static void* netcp_cfgp_get_mac_handle(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,int iface_no)\r
199 {\r
200    if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_INTERFACES))\r
201    {\r
202         return NULL;\r
203    }\r
204    else if ( p->interfaces[iface_no].in_use)\r
205    {\r
206      return (void *) p->interfaces[iface_no].nwal_handle;\r
207    }\r
208    //no valid entry in slot\r
209    return NULL;\r
210 }\r
211 \r
212  //internal: delete a classifer from list \r
213 static void netcp_cfgp_delete_class(\r
214          NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
215          int class_slot )\r
216 {\r
217    if ((class_slot <0 ) || (class_slot >= TUNE_NETAPI_MAX_CLASSIFIERS))\r
218    {\r
219         return ;\r
220    }\r
221    p->classi[class_slot].in_use=0;\r
222    return;\r
223 }\r
224 \r
225 //internal:  insert a classifier into list \r
226 static void netcp_cfgp_insert_class(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
227                           int class_slot,  //we 'reserved it already'\r
228                           int class_type,\r
229                           void * L2_handle,\r
230                           void * L3_handle,\r
231                           void * L4_handle)\r
232 {\r
233         p->classi[class_slot].in_use=1;\r
234         p->classi[class_slot].nwal_L2_handle = L2_handle;\r
235         p->classi[class_slot].nwal_L3_handle = L3_handle;\r
236         p->classi[class_slot].nwal_L4_handle = L4_handle;\r
237         p->classi[class_slot].class_type = class_type;\r
238         return;\r
239 }\r
240 \r
241 //internal: return nwal_handle for class\r
242 static void *netcp_cfgp_get_class_handle( NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
243                           int class_slot)\r
244 {\r
245    if ((class_slot <0 ) || (class_slot >= TUNE_NETAPI_MAX_CLASSIFIERS)) return NULL;\r
246    if (!p->classi[class_slot].in_use) return NULL;\r
247    return p->classi[class_slot].nwal_L4_handle;\r
248 }\r
249 \r
250 /***********************************************************************************/\r
251 /****************************************API****************************************/\r
252 /***********************************************************************************/\r
253 \r
254 \r
255 /*****************************************************************\r
256  *  Queury Stats\r
257  ****************************************************************/\r
258 void netcp_cfgReqStats(NETAPI_T  h, NETCP_CFG_STATS_CB cb, int doClear, int *err) \r
259 {\r
260 nwal_RetValue ret;\r
261 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
262 NetapiNwalTransInfo_t *pTransInfo;\r
263 nwal_TransID_t     transId;\r
264 if ((!n) || (!cb)) {*err = NETAPI_ERR_BAD_INPUT; return ;}\r
265 *err =0;\r
266 \r
267 pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &transId);\r
268 if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return ;}\r
269 pTransInfo->transType = NETAPI_NWAL_HANDLE_STAT_REQUEST;\r
270 pTransInfo->netapi_handle = h;\r
271 n->nwal_local.stats_cb = cb;\r
272 ret = nwal_getPAStats( ((NETAPI_GLOBAL_T *) n->global)->nwal_context.nwalInstHandle,\r
273                           transId,\r
274                           NULL,\r
275                           doClear);\r
276 if(ret !=  nwal_OK)\r
277 {\r
278    pTransInfo->inUse = nwal_FALSE;\r
279    *err = NETAPI_ERR_BUSY;  //no resources??\r
280    printf("> netcp_cfg reqStats failed, err=%d\n",ret);\r
281 }\r
282 \r
283 }\r
284 /*****************************************************************\r
285  *  CREATE A MAC INTERFACE\r
286  ****************************************************************/\r
287 NETCP_CFG_MACIF_T  netcp_cfgCreateMacInterface(\r
288                   NETAPI_T  h,\r
289                   uint8_t *p_mac,\r
290                   int  iface_no, \r
291                   int switch_port, \r
292                   NETCP_CFG_ROUTE_HANDLE_T  route,\r
293                   NETCP_CFG_VLAN_T  vlan,  //future\r
294                   int state,  //0=down, 1=up  //ignored\r
295                   int * err\r
296                   )\r
297 {\r
298 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
299 nwalMacParam_t   MacInfo= {\r
300     0,      /* validParams */\r
301     0,      /* ifNum */\r
302     0,      /* vlanId      */\r
303     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },      /* Local mac */\r
304     NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */\r
305     NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */\r
306     CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */\r
307     QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */\r
308 };\r
309 \r
310 nwal_RetValue       retValue;\r
311 NetapiNwalTransInfo_t *pTransInfo;\r
312 nwal_TransID_t     trans_id;\r
313 \r
314     if ((!n) || (!p_mac)) {*err = NETAPI_ERR_BAD_INPUT; return -1;}\r
315     *err =0;\r
316 \r
317     pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
318     if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return -1;}\r
319     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC;\r
320     pTransInfo->netapi_handle = h; \r
321 \r
322     /* set up MacInfo */\r
323     memcpy(&MacInfo.macAddr,p_mac,6); \r
324     /* todo: vlan */\r
325     MacInfo.ifNum = switch_port;  /* todo: check for 0/1 relative*/\r
326 \r
327 #if 0  //todo\r
328     if (route != NULL)\r
329     {\r
330         MacInfo.appRxPktFlowId = ((NETCP_CFG_FLOW_T *)(route.flow))->flowid;\r
331         MacInfo.appRxPktQueue = PKTIO_GET_Q(route->p_dest_q);\r
332         //handle action ??\r
333     }\r
334 #endif\r
335     pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;\r
336     retValue = nwal_setMacIface( ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
337                                   trans_id,\r
338                                   (nwal_AppId) (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no),\r
339                                   &MacInfo,\r
340                                   &pTransInfo->handle);\r
341     if(retValue !=  nwal_OK)\r
342     {\r
343         *err = NETAPI_ERR_NWAL_ERR0;\r
344         printf (">netcp cfg - ERROR: nwal_setMacIface returned Error Code %d\n",\r
345                     retValue);\r
346         pTransInfo->inUse = nwal_FALSE;\r
347         return -1;\r
348     }\r
349     //pTransInfo->inUse = nwal_FALSE;\r
350 \r
351     //wait here until its done since scheduler isn't running yet most likely..\r
352     // todo:  make this handled by scheduler poll later ??\r
353     if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
354     {\r
355         n->nwal_local.numPendingCfg++;\r
356         while ((volatile) n->nwal_local.numPendingCfg)\r
357         {\r
358             // if response is there, then this poll squirts out in the CTl poll callback, \r
359             // which handles the rest (including decrmenting #pending!!\r
360             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
361         }\r
362     }\r
363     printf (">netcp cfg: MAC i/f %d added\n", iface_no);\r
364     netcp_cfgp_insert_mac(&netapi_get_global()->nwal_context, \r
365                           p_mac, iface_no, state,vlan,\r
366                           (void *) pTransInfo->handle);\r
367     pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;\r
368     pTransInfo->inUse = nwal_FALSE;\r
369     return  (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no);\r
370 }\r
371 \r
372 \r
373 /*****************************************************************/\r
374 /***************Delete a mac interface****************************/\r
375 /*****************************************************************/\r
376 void netcp_cfgDelMac(NETAPI_T h,int iface_no,  int *err)\r
377 {\r
378     nwal_RetValue ret;\r
379     NetapiNwalTransInfo_t *pTransInfo;\r
380     nwal_TransID_t     trans_id;\r
381     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
382     void * ifHandle;\r
383 \r
384     //get the nwal handle assoicated with this iface\r
385     ifHandle = netcp_cfgp_get_mac_handle(&netapi_get_global()->nwal_context, iface_no );\r
386     if(!ifHandle) \r
387             {*err = NETAPI_ERR_BAD_INPUT; return ;}\r
388     *err =0;\r
389     \r
390     //get a transaction id\r
391     pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
392     if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return ;}\r
393     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC;\r
394     pTransInfo->netapi_handle = h;\r
395     //issue request\r
396     ret = nwal_delMacIface(\r
397                 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
398                 trans_id,\r
399                 ifHandle);\r
400     if(ret !=  nwal_OK)\r
401     {\r
402         *err = NETAPI_ERR_NWAL_ERR0;\r
403         printf (">netcp cfg - ERROR: nwal_delMacIface returned Error Code %d\n",\r
404                     ret);\r
405         pTransInfo->inUse = nwal_FALSE;\r
406         return ;\r
407     }\r
408     //wait here until its done since scheduler isn't running yet most likely..\r
409     // todo:  make this handled by scheduler poll later ??\r
410     if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
411     {\r
412         n->nwal_local.numPendingCfg++;\r
413         while ((volatile) n->nwal_local.numPendingCfg)\r
414         {\r
415             // if response is there, then this poll squirts out in the CTl poll callback, \r
416             // which handles the rest (including decrmenting #pending!!\r
417             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
418         }\r
419     }\r
420     printf (">netcp cfg: MAC i/f %d deleted\n",iface_no);\r
421     pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;\r
422     pTransInfo->inUse = nwal_FALSE;\r
423     //zap the entry\r
424     netcp_cfgp_delete_mac(&netapi_get_global()->nwal_context,  iface_no);\r
425     return ;\r
426 }\r
427 \r
428 \r
429 /*****************************************************************/\r
430 /***************Add IP to MAC interface (internal)****************/\r
431 /*****************************************************************/\r
432 static NETCP_CFG_IP_T  netcp_cfgAddIpInternal(\r
433                   NETAPI_T  h,\r
434                   int  iface_no,\r
435                   nwal_IpType ipType,\r
436                   nwalIpAddr_t  * ip_addr,\r
437                   nwalIpOpt_t * ip_qualifiers,\r
438                   NETCP_CFG_ROUTE_HANDLE_T  route,  //NULL for default\r
439                   int * err,\r
440                   int  flag) //TRUE: add IP to iface.  False: add IP as part of classifier\r
441 {\r
442 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
443 void * n_handle;\r
444 nwalIpParam_t    nwalIpParam= {\r
445     pa_IPV4,      /* IP Type */\r
446     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Dest IP */\r
447     { 0x0,0,0,0},/* IP Options */\r
448     NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */\r
449     NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */\r
450     CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */\r
451     QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */\r
452 };\r
453 nwal_RetValue       retValue;\r
454 NetapiNwalTransInfo_t *pTransInfo;\r
455 nwal_TransID_t     trans_id;\r
456 int ip_slot=-1;\r
457 NETCP_CFG_IP_T ip_rule_id;\r
458 NETCP_CFG_IP_T temp;\r
459 \r
460      //verify that iface has been configurred \r
461      if ((iface_no<0) || (iface_no>= TUNE_NETAPI_MAX_INTERFACES)) {*err = NETAPI_ERR_BAD_INPUT; return -1;}\r
462 \r
463      if(netapi_get_global()->nwal_context.interfaces[iface_no].in_use)\r
464      {\r
465         n_handle =  netapi_get_global()->nwal_context.interfaces[iface_no].nwal_handle;\r
466      }\r
467      else\r
468      {\r
469         *err = NETAPI_ERR_BAD_INPUT;\r
470         return -1;\r
471      }\r
472 \r
473      if (flag) //if adding IP to MAC then reserve a slot to save info\r
474      {\r
475          //find free slot for IP & reserve\r
476           ip_slot= netcp_cfgp_find_ip_slot(&netapi_get_global()->nwal_context, \r
477                                    iface_no);\r
478           if (ip_slot <0) \r
479           {\r
480                 *err= NETAPI_ERR_NOMEM;  //no room \r
481                 return -1;\r
482           }\r
483      }\r
484 \r
485      //get a transaction object for config action\r
486     pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
487     if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return -1;}\r
488     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;\r
489     pTransInfo->netapi_handle = h;\r
490 \r
491      //build nwalIpParam\r
492      memcpy(&nwalIpParam.locIpAddr,ip_addr, sizeof(nwalIpAddr_t));\r
493      nwalIpParam.ipType=ipType;\r
494      if(route)\r
495      {\r
496           //todo: support app defined routes\r
497      } \r
498      else{} //use nwal defaults\r
499      if (ip_qualifiers)\r
500         memcpy(&nwalIpParam.ipOpt,ip_qualifiers, sizeof(nwalIpOpt_t)); \r
501      else\r
502         memset(&nwalIpParam.ipOpt,0, sizeof(nwalIpOpt_t));\r
503 \r
504      //build the rule id that will be returned when a packet matches \r
505      if (flag)\r
506         ip_rule_id = NETAPI_NETCP_MATCH_GENERIC_IP | iface_no | ((ip_slot&&0xff)<<8);\r
507      else\r
508         ip_rule_id = (NETAPI_NETCP_MATCH_CLASS_L3 | iface_no);\r
509 \r
510      //perform config action\r
511      pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;\r
512      retValue = nwal_setIPAddr(   netapi_get_global()->nwal_context.nwalInstHandle,\r
513                                   trans_id,\r
514                                   (nwal_AppId) (ip_rule_id),\r
515                                   n_handle,\r
516                                   &nwalIpParam,\r
517                                   &pTransInfo->handle);\r
518 \r
519     if(retValue !=  nwal_OK)\r
520     {\r
521         *err = NETAPI_ERR_NWAL_ERR0;\r
522         printf (">netcp cfg: nwal_setIP returned Error Code %d\n",\r
523                     retValue);\r
524         pTransInfo->inUse = nwal_FALSE;\r
525         //zap the entry\r
526         if (flag)\r
527         {\r
528                 netcp_cfgp_delete_ip(&netapi_get_global()->nwal_context,\r
529                          iface_no,\r
530                          ip_slot);\r
531         }\r
532         return -1;\r
533     }\r
534     //wait here until its done since scheduler isn't running yet most likely..\r
535     // todo:  make this handled by scheduler poll later ??\r
536     if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
537     {\r
538         n->nwal_local.numPendingCfg++;\r
539         while ((volatile) n->nwal_local.numPendingCfg)\r
540         {\r
541             // if response is there, then this poll squirts out in the CTl poll callback, \r
542             // which handles the rest (including decrmenting #pending!!\r
543             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
544         }\r
545     }\r
546     if (flag)\r
547     {\r
548         printf (">netcp cfg: IP added to interface %d (slot%d)\n", iface_no, ip_slot);\r
549         netcp_cfgp_insert_ip(&netapi_get_global()->nwal_context, ipType, \r
550                           ip_addr, ip_qualifiers, iface_no, ip_slot,\r
551                           pTransInfo->handle);\r
552     }\r
553     pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;\r
554     temp = (NETCP_CFG_IP_T) pTransInfo->handle;\r
555     pTransInfo->inUse = nwal_FALSE;\r
556     return  (flag ? ip_rule_id:  temp);\r
557 }\r
558 /*****************************************************************/\r
559 /***************Add IP to MAC interface **************************/\r
560 /*****************************************************************/\r
561 NETCP_CFG_IP_T  netcp_cfgAddIp(\r
562                   NETAPI_T  h,\r
563                   int  iface_no,\r
564                   nwal_IpType ipType,\r
565                   nwalIpAddr_t  * ip_addr,\r
566                   nwalIpOpt_t * ip_qualifiers,\r
567                   NETCP_CFG_ROUTE_HANDLE_T  route,  //NULL for default\r
568                   int * err\r
569                   )\r
570 {\r
571         return netcp_cfgAddIpInternal(\r
572                 h, iface_no, ipType, ip_addr, ip_qualifiers, route, err, \r
573                 1);\r
574 }\r
575 \r
576 /*****************************************************************/\r
577 /***************Delete an attached IP*****************************/\r
578 /*****************************************************************/\r
579 void netcp_cfgDelIp(NETAPI_T h, int iface_no,  nwal_IpType ipType,\r
580                   nwalIpAddr_t  * ip_addr,\r
581                   nwalIpOpt_t * ip_qualifiers, \r
582                   NETCP_CFG_IP_T  ip_rule_id,\r
583                   int *err)\r
584 {\r
585     nwal_RetValue ret;\r
586     NetapiNwalTransInfo_t *pTransInfo;\r
587     nwal_TransID_t     trans_id;\r
588     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
589     void * ifHandle;\r
590     int ip_slot = (ip_rule_id>>8)&0xff;\r
591 \r
592     //get the nwal handle assoicated with this ip   \r
593     ifHandle = netcp_cfgp_get_ip_handle(\r
594          &netapi_get_global()->nwal_context, iface_no,\r
595          ip_slot );\r
596     if(!ifHandle)\r
597             {*err = NETAPI_ERR_BAD_INPUT; return ;}\r
598     *err =0;\r
599 \r
600     //get a transaction id\r
601     pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
602   if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return ;}\r
603     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;\r
604     pTransInfo->netapi_handle = h;\r
605     //issue request\r
606     ret = nwal_delIPAddr(\r
607                 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
608                 trans_id,\r
609                 ifHandle);\r
610     if(ret !=  nwal_OK)\r
611     {\r
612         *err = NETAPI_ERR_NWAL_ERR0;\r
613         printf (">netcp cfg - ERROR: nwal_delMacIface returned Error Code %d\n",\r
614                     ret);\r
615         pTransInfo->inUse = nwal_FALSE;\r
616         return ;\r
617     }\r
618     //wait here until its done since scheduler isn't running yet most likely..\r
619     // todo:  make this handled by scheduler poll later ??\r
620     if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
621     {\r
622        n->nwal_local.numPendingCfg++;\r
623         while ((volatile) n->nwal_local.numPendingCfg)\r
624         {\r
625             // if response is there, then this poll squirts out in the CTl poll callback, \r
626             // which handles the rest (including decrmenting #pending!!\r
627             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
628         }\r
629     }\r
630     printf (">netcp cfg: IP i/f deleted\n");\r
631     pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;\r
632     pTransInfo->inUse = nwal_FALSE;\r
633     //zap the entry\r
634     netcp_cfgp_delete_ip(&netapi_get_global()->nwal_context,  \r
635                          iface_no,\r
636                          ip_slot);\r
637     return ;\r
638 }\r
639 \r
640 /**\r
641  * @def netcp_cfgAddClass\r
642  * @brief  add a classifier rule into NETCP\r
643  **/\r
644 NETCP_CFG_CLASS_T netcp_cfgAddClass(NETAPI_T h,\r
645                                       NETCP_CFG_CLASSIFIER_T *p_class,\r
646                                       NETCP_CFG_ROUTE_HANDLE_T p_route,\r
647                                       int action, int * err)\r
648 {\r
649 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
650 void * l3_handle=NULL;  //ip handle\r
651 nwal_RetValue       retValue;\r
652 NetapiNwalTransInfo_t *pTransInfo;\r
653 nwal_TransID_t     trans_id;\r
654 int class_slot=-1;\r
655 int iface_no;\r
656 int ip_slot=-1;\r
657 NETCP_CFG_CLASS_T  classHandle;  //returned by us\r
658 nwal_appProtoType_t proto;\r
659 nwalLocConnCfg_t tempCfg={\r
660 0,  //nwal_handle: to be filled in\r
661 {0}, // l4 ports: to be filled in\r
662 0,  //core id (NA)\r
663 0, //action\r
664 CPPI_PARAM_NOT_SPECIFIED, //flow id\r
665 QMSS_PARAM_NOT_SPECIFIED, //dest queue\r
666 };\r
667 \r
668 if(!p_class) { *err=NETAPI_ERR_BAD_INPUT; return -1;}\r
669 switch(p_class->classType)\r
670 {\r
671 default:\r
672         printf(">netcp_cfg : classifier type %d not supported\n",p_class->classType);\r
673         break;\r
674 case(NETCP_CFG_CLASS_TYPE_L3_L4):\r
675 case(NETCP_CFG_CLASS_TYPE_L4):\r
676         //assume just type l4 only (L2, L3 defined by iface, l3 id )\r
677         iface_no = p_class->u.c_l4.iface;\r
678         if (p_class->classType== NETCP_CFG_CLASS_TYPE_L4)\r
679         { \r
680                 ip_slot = (p_class->u.c_l4.ip>>8)&0xff;\r
681         }\r
682 \r
683          //verify that iface has been configured \r
684         if(!netapi_get_global()->nwal_context.interfaces[iface_no].in_use)\r
685         {\r
686                 *err = NETAPI_ERR_BAD_INPUT;\r
687                 return -1;\r
688         }\r
689 \r
690         if (p_class->classType== NETCP_CFG_CLASS_TYPE_L4)\r
691         {\r
692              //verify that ip has been configured and get its handle\r
693              l3_handle = netcp_cfgp_get_ip_handle(\r
694                           &netapi_get_global()->nwal_context, iface_no,\r
695                           ip_slot );\r
696         }\r
697         else\r
698         {\r
699              nwalIpParam_t tempParam={\r
700     pa_IPV4,      /* IP Type */\r
701     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Dest IP */\r
702     { 0x0,0,0,0},/* IP Options */\r
703     NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */\r
704     NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */\r
705     CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */\r
706     QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */\r
707         };\r
708                 //build nwalIpParam\r
709                 memcpy(&tempParam.locIpAddr,p_class->u.c_l3_l4.ip_addr, sizeof(nwalIpAddr_t));\r
710                 tempParam.ipType=p_class->u.c_l3_l4.ipType;\r
711             //use nwal defauls for route\r
712             if (p_class->u.c_l3_l4.ip_qualifiers)\r
713                         memcpy(&tempParam.ipOpt,p_class->u.c_l3_l4.ip_qualifiers, sizeof(nwalIpOpt_t));\r
714              else\r
715                         memset(&tempParam.ipOpt,0, sizeof(nwalIpOpt_t));\r
716 \r
717 \r
718              //find if we have a matching L3 handle for IP classifier; if not create it\r
719              retValue =  nwal_getIPAddr (((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
720                                 &tempParam,\r
721                                 netcp_cfgp_get_mac_handle(&netapi_get_global()->nwal_context, iface_no ),\r
722                                 &l3_handle); \r
723              if (retValue != nwal_TRUE) \r
724              {\r
725                 int ret;\r
726                 //**NEW IP RULE  \r
727                 //need to attach this IP RULE to the MAC\r
728                 l3_handle= (void *) netcp_cfgAddIpInternal(\r
729                   h, iface_no, \r
730                   p_class->u.c_l3_l4.ipType,\r
731                   p_class->u.c_l3_l4.ip_addr,\r
732                   p_class->u.c_l3_l4.ip_qualifiers,\r
733                   p_class->u.c_l3_l4.p_fail_route,\r
734                   &ret,\r
735                   FALSE);\r
736                  if(!ret)\r
737                  {\r
738                         l3_handle=NULL;\r
739                  }\r
740              }\r
741         }         \r
742         if(!l3_handle)\r
743             {*err = NETAPI_ERR_BAD_INPUT; return -1 ;}\r
744 \r
745 \r
746         //find free slot for CLASS & reserve\r
747         class_slot= netcp_cfgp_find_class_slot(&netapi_get_global()->nwal_context);\r
748         if(class_slot<0) {*err = NETAPI_ERR_NOMEM; return -1;}\r
749         classHandle = NETAPI_NETCP_MATCH_CLASS | (class_slot<<8) | (iface_no&0xff);\r
750         //build request from template\r
751         tempCfg.inHandle=l3_handle;\r
752         if (p_class->classType== NETCP_CFG_CLASS_TYPE_L4)\r
753         { \r
754                 memcpy(&tempCfg.appProto,&p_class->u.c_l4.appProto,sizeof(nwalAppProto_t));\r
755                 proto = p_class->u.c_l4.proto;\r
756         }\r
757         else\r
758         {\r
759                 memcpy(&tempCfg.appProto,&p_class->u.c_l3_l4.appProto,sizeof(nwalAppProto_t));\r
760                 proto = p_class->u.c_l3_l4.proto;\r
761         }\r
762         \r
763         tempCfg.matchAction = (action==NETCP_CFG_ACTION_TO_SW)  ? NWAL_MATCH_ACTION_HOST : NWAL_MATCH_ACTION_DISCARD;\r
764         //todo: flowid and route \r
765         //get a transaction id\r
766         pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
767         if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return -1 ;}\r
768         pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP; /* todo: fix this to TRANS_L4*/\r
769         pTransInfo->netapi_handle = h;\r
770         //issue request\r
771         retValue = nwal_addConn(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
772                             trans_id,\r
773                             (nwal_AppId) classHandle,\r
774                             proto,\r
775                             &tempCfg,\r
776                             NULL,\r
777                             &pTransInfo->handle);\r
778         if(retValue !=  nwal_OK)\r
779         {\r
780             *err = NETAPI_ERR_NWAL_ERR0;\r
781             printf (">netcp cfg - ERROR: nwal_addConn returned Error Code %d\n",\r
782                     retValue);\r
783             pTransInfo->inUse = nwal_FALSE;\r
784             netcp_cfgp_delete_class(&netapi_get_global()->nwal_context, class_slot);\r
785             return -1;\r
786         }\r
787         //wait here until its done since scheduler isn't running yet most likely..\r
788         // todo:  make this handled by scheduler poll later ??\r
789         if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
790         {\r
791              n->nwal_local.numPendingCfg++;\r
792              while ((volatile) n->nwal_local.numPendingCfg)\r
793              {\r
794                 // if response is there, then this poll squirts out in the CTl poll callback, \r
795                 // which handles the rest (including decrmenting #pending!!\r
796                 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
797              }\r
798          }\r
799          printf (">netcp cfg: L4 Classifer added to interface %d ip %d (slot%d)\n", iface_no, ip_slot, class_slot);\r
800          netcp_cfgp_insert_class(&netapi_get_global()->nwal_context, \r
801                                    class_slot,\r
802                                  p_class->classType, \r
803                                   NULL,  //L2 we have\r
804                                   (p_class->classType== NETCP_CFG_CLASS_TYPE_L3_L4? l3_handle : NULL),\r
805                                   pTransInfo->handle);\r
806          pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;\r
807          return classHandle;\r
808 } //end switch\r
809 return -1;\r
810 }\r
811 \r
812 //delete classifier\r
813 void netcp_cfgDelClass(NETAPI_T h,\r
814                          NETCP_CFG_CLASS_T classId,\r
815                          int *err)\r
816 {\r
817 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
818 void * class_handle;  //class handle\r
819 nwal_RetValue       retValue;\r
820 NetapiNwalTransInfo_t *pTransInfo;\r
821 nwal_TransID_t     trans_id;\r
822 int class_slot=-1;\r
823 //int iface;\r
824 //int ip_slot;\r
825 \r
826         class_slot = (classId>>8)&0xffff;\r
827         class_handle=netcp_cfgp_get_class_handle(\r
828                         &netapi_get_global()->nwal_context,\r
829                         class_slot );\r
830         if(!class_handle)  {*err = NETAPI_ERR_BAD_INPUT; return -1;}\r
831         netcp_cfgp_delete_class(\r
832                         &netapi_get_global()->nwal_context,\r
833                         class_slot );\r
834         //get a transaction id\r
835         pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
836         if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return -1 ;}\r
837         pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;\r
838         pTransInfo->netapi_handle = h;\r
839         //issue request\r
840         retValue = nwal_delConn(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
841                             trans_id,\r
842                             class_handle);\r
843         if(retValue !=  nwal_OK)\r
844         {\r
845             *err = NETAPI_ERR_NWAL_ERR0;\r
846             printf (">netcp cfg - ERROR: nwal_delConn returned Error Code %d\n",\r
847                     retValue);\r
848             pTransInfo->inUse = nwal_FALSE;\r
849             return -1;\r
850         }\r
851         //wait here until its done since scheduler isn't running yet most likely..\r
852         // todo:  make this handled by scheduler poll later ??\r
853         if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
854         {\r
855              n->nwal_local.numPendingCfg++;\r
856              while ((volatile) n->nwal_local.numPendingCfg)\r
857              {\r
858                 // if response is there, then this poll squirts out in the CTl poll callback, \r
859                 // which handles the rest (including decrmenting #pending!!\r
860                 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
861              }\r
862          }\r
863          printf (">netcp cfg: Classifer deleted\n");\r
864          pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;\r
865          pTransInfo->inUse = nwal_FALSE;\r
866          return ;\r
867 }\r
868 \r
869 \r
870 /*************************************************************************/\r
871 /*********************************INTERNAL*******************************/\r
872 /************************************************************************/\r
873 \r
874 /***************************************************************\r
875  ********************METCP CMD Reply Callback******************\r
876  ***************************************************************/\r
877 void netapi_NWALCmdCallBack (nwal_AppId        appHandle,\r
878                           uint16_t            trans_id,\r
879                           nwal_RetValue     ret)\r
880 {\r
881     NetapiNwalTransInfo_t * p_trans;\r
882     NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL;\r
883 \r
884     if(trans_id == NWAL_TRANSID_SPIN_WAIT)\r
885     {\r
886         netapi_get_global()->nwal_context.numBogusTransIds++;\r
887         return;\r
888     }\r
889 \r
890     p_trans= &netapi_get_global()->nwal_context.transInfos[trans_id];\r
891     p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;\r
892 \r
893     if(ret != nwal_OK)\r
894     {\r
895         printf (">netcp cfg : NWALCmdCallBack returned Error Code %d\n",\r
896                     ret);\r
897         //todo: atomic inc\r
898         netapi_get_global()->nwal_context.numCmdFail++;\r
899     }\r
900     else\r
901     {\r
902         //todo: atomic inc\r
903         netapi_get_global()->nwal_context.numCmdPass++;\r
904         switch(p_trans->transType)\r
905         {\r
906             case NETAPI_NWAL_HANDLE_TRANS_MAC:\r
907             {\r
908                 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)\r
909                 {\r
910                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;\r
911                 }\r
912                 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
913                 {\r
914                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;\r
915                 }\r
916                 break;\r
917             }\r
918             case NETAPI_NWAL_HANDLE_TRANS_IP:\r
919             {\r
920                  if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)\r
921                 {\r
922                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;\r
923                 }\r
924                 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
925                 {\r
926                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;\r
927                 }\r
928                 break;\r
929             }\r
930             case NETAPI_NWAL_HANDLE_TRANS_PORT:\r
931             {\r
932                 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)\r
933                 {\r
934                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;\r
935                 }\r
936                 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
937                 {\r
938                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;\r
939                 }\r
940                 break;\r
941             }\r
942 #if 0\r
943             case TEST_NWAL_HANDLE_TRANS_SEC_ASSOC:\r
944             {\r
945                 if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING)\r
946                 {\r
947                     testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN;\r
948                 }\r
949                 else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
950                 {\r
951                     System_printf ("Set Security Assoc  Close ACK received for trans_id: %d\n",\r
952                                 testNwLocContext.transInfos[trans_id].transType,trans_id);\r
953                     nwal_SystemFlush();\r
954                     testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE;\r
955                 }\r
956                 break;\r
957             }\r
958 case TEST_NWAL_HANDLE_TRANS_SEC_POLICY:\r
959             {\r
960                 if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING)\r
961                 {\r
962                     testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN;\r
963                 }\r
964                 else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
965                 {\r
966                     System_printf ("Set Security Policy  Close ACK received for trans_id: %d\n",\r
967                                 testNwLocContext.transInfos[trans_id].transType,trans_id);\r
968                     nwal_SystemFlush();\r
969                     testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE;\r
970                 }\r
971                 break;\r
972             }\r
973 #endif\r
974             default:\r
975             {\r
976                 printf ("netcp cfg> Invalid transaction type %d for trans_id: %d\n",\r
977                     p_trans->transType,trans_id);\r
978                 break;\r
979             }\r
980         }\r
981     }\r
982 \r
983     p_local->numPendingCfg--;\r
984 \r
985     if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_IDLE)\r
986     {\r
987         p_trans->inUse = nwal_FALSE;\r
988     }\r
989 \r
990 }\r
991 \r
992 \r
993 /*******************************************************/\r
994 /**************stats reply callback**********************/\r
995 /*******************************************************/\r
996 void netapi_NWALCmdPaStatsReply (nwal_AppId        appHandle,\r
997                               nwal_TransID_t    trans_id,\r
998                               paSysStats_t      *stats)\r
999 {\r
1000     NetapiNwalTransInfo_t * p_trans;\r
1001     NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL;\r
1002   \r
1003     if(trans_id == NWAL_TRANSID_SPIN_WAIT)\r
1004     {\r
1005         netapi_get_global()->nwal_context.numBogusTransIds++;\r
1006         return;\r
1007     }\r
1008 \r
1009     p_trans= &netapi_get_global()->nwal_context.transInfos[trans_id];\r
1010     p_trans->inUse = nwal_FALSE;\r
1011     p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;\r
1012 \r
1013     //save a local copy  of some stuff*/\r
1014     p_local->numL2PktsRecvd=stats->classify1.nPackets;\r
1015     p_local->numL3PktsRecvd=stats->classify1.nIpv4Packets;\r
1016 #if 0\r
1017     p_local->numL4PktsRecvd=stats->;\r
1018     p_local->numL4PktsSent=stats->;\r
1019     p_local->TxErrDrop=stats->;\r
1020 #endif\r
1021     //callout result to application !!\r
1022     if (p_local->stats_cb) (*p_local->stats_cb)(p_trans->netapi_handle,stats);\r
1023     \r
1024\r
1025 \r