added del_ip, del_mac functions
[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:  insert an IP address into iface\r
104 static void netcp_cfgp_insert_ip(NETAPI_NWAL_GLOBAL_CONTEXT_T *p, \r
105                           nwal_IpType ipType,\r
106                           nwalIpAddr_t *ip_addr, \r
107                           nwalIpOpt_t *ip_qualifiers, \r
108                           int iface_no,\r
109                           int ip_slot,  //we 'reserved it already'\r
110                           void * handle)\r
111 {\r
112         p->interfaces[iface_no].ips[ip_slot].in_use=1;\r
113         memcpy(&p->interfaces[iface_no].ips[ip_slot].ip_addr, ip_addr, sizeof(nwalIpAddr_t));\r
114         if(ip_qualifiers)\r
115         memcpy(&p->interfaces[iface_no].ips[ip_slot].ip_qualifiers, ip_qualifiers, sizeof(nwalIpOpt_t));\r
116         else\r
117         memset(&p->interfaces[iface_no].ips[ip_slot].ip_qualifiers, 0, sizeof(nwalIpOpt_t));\r
118         p->interfaces[iface_no].ips[ip_slot].ip_type = ipType;\r
119         p->interfaces[iface_no].ips[ip_slot].nwal_handle = handle;\r
120         return;\r
121 }\r
122 \r
123 \r
124 //internal: instert interface info into global context\r
125 static void netcp_cfgp_insert_mac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p, unsigned char * p_mac, \r
126                            int iface_no, int state, NETCP_CFG_VLAN_T vlan, void * handle)\r
127 {\r
128    if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_INTERFACES))\r
129    {\r
130         memset(&p->interfaces[iface_no],0,sizeof(NETCP_INTERFACE_T));\r
131         p->interfaces[iface_no].in_use = 1;\r
132         memcpy(&p->interfaces[iface_no].mac[0], p_mac,6);\r
133         p->interfaces[iface_no].state = state;\r
134         //todo p->interfaces[iface_no].vlan = vlan;\r
135         p->interfaces[iface_no].nwal_handle = handle; //save handle assoicated with this rule\r
136    }\r
137    else printf(">netcp_cfg insert interface # out of range %d\n",iface_no);\r
138 \r
139 }\r
140 //internal: clear inteface entry\r
141 static void netcp_cfgp_delete_mac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,int iface_no)  \r
142 {\r
143    if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_INTERFACES))\r
144    {\r
145         p->interfaces[iface_no].in_use = 0;\r
146    }\r
147 }\r
148 //internal: free IP slot associated with ip address \r
149 static void netcp_cfgp_delete_ip(\r
150          NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
151          int iface_no,\r
152          int ip_slot )\r
153 {\r
154    if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_INTERFACES))\r
155    {\r
156         return ;\r
157    }\r
158    if (!p->interfaces[iface_no].in_use) return ;\r
159    if ((ip_slot <0)||(ip_slot>TUNE_NETAPI_MAX_IP_PER_INTERFACE)) return ;\r
160    p->interfaces[iface_no].ips[ip_slot].in_use=0;\r
161    return;\r
162 }\r
163 \r
164 \r
165 //internal: get IP handle associated with ip address \r
166 static void *netcp_cfgp_get_ip_handle(\r
167          NETAPI_NWAL_GLOBAL_CONTEXT_T *p, \r
168          int iface_no,\r
169          int ip_slot )\r
170 {\r
171    if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_INTERFACES))\r
172    {\r
173         return NULL;\r
174    }\r
175    if (!p->interfaces[iface_no].in_use) return NULL;\r
176    if ((ip_slot <0)||(ip_slot>=TUNE_NETAPI_MAX_IP_PER_INTERFACE)) return NULL;\r
177    if (!p->interfaces[iface_no].ips[ip_slot].in_use) return NULL;\r
178    return (void *) p->interfaces[iface_no].ips[ip_slot].nwal_handle;\r
179 }\r
180 \r
181 //internal: get handle associated with interface\r
182 static void* netcp_cfgp_get_mac_handle(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,int iface_no)\r
183 {\r
184    if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_INTERFACES))\r
185    {\r
186         return NULL;\r
187    }\r
188    else if ( p->interfaces[iface_no].in_use)\r
189    {\r
190      return (void *) p->interfaces[iface_no].nwal_handle;\r
191    }\r
192    //no valid entry in slot\r
193    return NULL;\r
194 }\r
195 \r
196 \r
197 /***********************************************************************************/\r
198 /****************************************API****************************************/\r
199 /***********************************************************************************/\r
200 \r
201 \r
202 /*****************************************************************\r
203  *  Queury Stats\r
204  ****************************************************************/\r
205 void netcp_cfgReqStats(NETAPI_T  h, NETCP_CFG_STATS_CB cb, int doClear, int *err) \r
206 {\r
207 nwal_RetValue ret;\r
208 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
209 NetapiNwalTransInfo_t *pTransInfo;\r
210 nwal_TransID_t     transId;\r
211 if ((!n) || (!cb)) {*err = NETAPI_ERR_BAD_INPUT; return ;}\r
212 *err =0;\r
213 \r
214 pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &transId);\r
215 if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return ;}\r
216 pTransInfo->transType = NETAPI_NWAL_HANDLE_STAT_REQUEST;\r
217 pTransInfo->netapi_handle = h;\r
218 n->nwal_local.stats_cb = cb;\r
219 ret = nwal_getPAStats( ((NETAPI_GLOBAL_T *) n->global)->nwal_context.nwalInstHandle,\r
220                           transId,\r
221                           NULL,\r
222                           doClear);\r
223 if(ret !=  nwal_OK)\r
224 {\r
225    pTransInfo->inUse = nwal_FALSE;\r
226    *err = NETAPI_ERR_BUSY;  //no resources??\r
227    printf("> netcp_cfg reqStats failed, err=%d\n",ret);\r
228 }\r
229 \r
230 }\r
231 /*****************************************************************\r
232  *  CREATE A MAC INTERFACE\r
233  ****************************************************************/\r
234 NETCP_CFG_MACIF_T  netcp_cfgCreateMacInterface(\r
235                   NETAPI_T  h,\r
236                   uint8_t *p_mac,\r
237                   int  iface_no, \r
238                   int switch_port, \r
239                   NETCP_CFG_ROUTE_HANDLE_T  route,\r
240                   NETCP_CFG_VLAN_T  vlan,  //future\r
241                   int state,  //0=down, 1=up  //ignored\r
242                   int * err\r
243                   )\r
244 {\r
245 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
246 nwalMacParam_t   MacInfo= {\r
247     0,      /* validParams */\r
248     0,      /* ifNum */\r
249     0,      /* vlanId      */\r
250     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },      /* Local mac */\r
251     NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */\r
252     NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */\r
253     CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */\r
254     QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */\r
255 };\r
256 \r
257 nwal_RetValue       retValue;\r
258 NetapiNwalTransInfo_t *pTransInfo;\r
259 nwal_TransID_t     trans_id;\r
260 \r
261     if ((!n) || (!p_mac)) {*err = NETAPI_ERR_BAD_INPUT; return -1;}\r
262     *err =0;\r
263 \r
264     pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
265     if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return -1;}\r
266     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC;\r
267     pTransInfo->netapi_handle = h; \r
268 \r
269     /* set up MacInfo */\r
270     memcpy(&MacInfo.macAddr,p_mac,6); \r
271     /* todo: vlan */\r
272     MacInfo.ifNum = switch_port;  /* todo: check for 0/1 relative*/\r
273 \r
274 #if 0  //todo\r
275     if (route != NULL)\r
276     {\r
277         MacInfo.appRxPktFlowId = ((NETCP_CFG_FLOW_T *)(route.flow))->flowid;\r
278         MacInfo.appRxPktQueue = PKTIO_GET_Q(route->p_dest_q);\r
279         //handle action ??\r
280     }\r
281 #endif\r
282     pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;\r
283     retValue = nwal_setMacIface( ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
284                                   trans_id,\r
285                                   (nwal_AppId) (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no),\r
286                                   &MacInfo,\r
287                                   &pTransInfo->handle);\r
288     if(retValue !=  nwal_OK)\r
289     {\r
290         *err = NETAPI_ERR_NWAL_ERR0;\r
291         printf (">netcp cfg - ERROR: nwal_setMacIface returned Error Code %d\n",\r
292                     retValue);\r
293         pTransInfo->inUse = nwal_FALSE;\r
294         return -1;\r
295     }\r
296     //pTransInfo->inUse = nwal_FALSE;\r
297 \r
298     //wait here until its done since scheduler isn't running yet most likely..\r
299     // todo:  make this handled by scheduler poll later ??\r
300     if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
301     {\r
302         n->nwal_local.numPendingCfg++;\r
303         while ((volatile) n->nwal_local.numPendingCfg)\r
304         {\r
305             // if response is there, then this poll squirts out in the CTl poll callback, \r
306             // which handles the rest (including decrmenting #pending!!\r
307             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
308         }\r
309     }\r
310     printf (">netcp cfg: MAC i/f %d added\n", iface_no);\r
311     netcp_cfgp_insert_mac(&netapi_get_global()->nwal_context, \r
312                           p_mac, iface_no, state,vlan,\r
313                           (void *) pTransInfo->handle);\r
314     pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;\r
315     pTransInfo->inUse = nwal_FALSE;\r
316     return  (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no);\r
317 }\r
318 \r
319 \r
320 /*****************************************************************/\r
321 /***************Delete a mac interface****************************/\r
322 /*****************************************************************/\r
323 void netcp_cfgDelMac(NETAPI_T h,int iface_no,  int *err)\r
324 {\r
325     nwal_RetValue ret;\r
326     NetapiNwalTransInfo_t *pTransInfo;\r
327     nwal_TransID_t     trans_id;\r
328     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
329     void * ifHandle;\r
330 \r
331     //get the nwal handle assoicated with this iface\r
332     ifHandle = netcp_cfgp_get_mac_handle(&netapi_get_global()->nwal_context, iface_no );\r
333     if(!ifHandle) \r
334             {*err = NETAPI_ERR_BAD_INPUT; return ;}\r
335     *err =0;\r
336     \r
337     //get a transaction id\r
338     pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
339     if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return ;}\r
340     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC;\r
341     pTransInfo->netapi_handle = h;\r
342     //issue request\r
343     ret = nwal_delMacIface(\r
344                 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
345                 trans_id,\r
346                 ifHandle);\r
347     if(ret !=  nwal_OK)\r
348     {\r
349         *err = NETAPI_ERR_NWAL_ERR0;\r
350         printf (">netcp cfg - ERROR: nwal_delMacIface returned Error Code %d\n",\r
351                     ret);\r
352         pTransInfo->inUse = nwal_FALSE;\r
353         return ;\r
354     }\r
355     //wait here until its done since scheduler isn't running yet most likely..\r
356     // todo:  make this handled by scheduler poll later ??\r
357     if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
358     {\r
359         n->nwal_local.numPendingCfg++;\r
360         while ((volatile) n->nwal_local.numPendingCfg)\r
361         {\r
362             // if response is there, then this poll squirts out in the CTl poll callback, \r
363             // which handles the rest (including decrmenting #pending!!\r
364             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
365         }\r
366     }\r
367     printf (">netcp cfg: MAC i/f %d deleted\n",iface_no);\r
368     pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;\r
369     pTransInfo->inUse = nwal_FALSE;\r
370     //zap the entry\r
371     netcp_cfgp_delete_mac(&netapi_get_global()->nwal_context,  iface_no);\r
372     return ;\r
373 }\r
374 \r
375 \r
376 /*****************************************************************/\r
377 /***************Add IP to MAC interface****************************/\r
378 /*****************************************************************/\r
379 NETCP_CFG_IP_T  netcp_cfgAddIp(\r
380                   NETAPI_T  h,\r
381                   int  iface_no,\r
382                   nwal_IpType ipType,\r
383                   nwalIpAddr_t  * ip_addr,\r
384                   nwalIpOpt_t * ip_qualifiers,\r
385                   NETCP_CFG_ROUTE_HANDLE_T  route,  //NULL for default\r
386                   int * err\r
387                   )\r
388 {\r
389 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
390 void * n_handle;\r
391 nwalIpParam_t    nwalIpParam= {\r
392     pa_IPV4,      /* IP Type */\r
393     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Dest IP */\r
394     { 0x0,0,0,0},/* IP Options */\r
395     NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */\r
396     NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */\r
397     CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */\r
398     QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */\r
399 };\r
400 nwal_RetValue       retValue;\r
401 NetapiNwalTransInfo_t *pTransInfo;\r
402 nwal_TransID_t     trans_id;\r
403 int ip_slot=-1;\r
404 NETCP_CFG_IP_T ip_rule_id;\r
405 \r
406      //verify that iface has been configurred \r
407      if ((iface_no<0) || (iface_no>= TUNE_NETAPI_MAX_INTERFACES)) {*err = NETAPI_ERR_BAD_INPUT; return -1;}\r
408 \r
409      if(netapi_get_global()->nwal_context.interfaces[iface_no].in_use)\r
410      {\r
411         n_handle =  netapi_get_global()->nwal_context.interfaces[iface_no].nwal_handle;\r
412      }\r
413      else\r
414      {\r
415         *err = NETAPI_ERR_BAD_INPUT;\r
416         return -1;\r
417      }\r
418      //find free slot for IP & reserve\r
419      ip_slot= netcp_cfgp_find_ip_slot(&netapi_get_global()->nwal_context, \r
420                                    iface_no);\r
421      if (ip_slot <0) \r
422      {\r
423         *err= NETAPI_ERR_NOMEM;  //no room \r
424      }\r
425 \r
426      //get a transaction object for config action\r
427     pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
428     if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return -1;}\r
429     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;\r
430     pTransInfo->netapi_handle = h;\r
431 \r
432      //build nwalIpParam\r
433      memcpy(&nwalIpParam.locIpAddr,ip_addr, sizeof(nwalIpAddr_t));\r
434      nwalIpParam.ipType=ipType;\r
435      if(route)\r
436      {\r
437           //todo: support app defined routes\r
438      } \r
439      else{} //use nwal defaults\r
440      if (ip_qualifiers)\r
441         memcpy(&nwalIpParam.ipOpt,ip_qualifiers, sizeof(nwalIpOpt_t)); \r
442      else\r
443         memset(&nwalIpParam.ipOpt,0, sizeof(nwalIpOpt_t));\r
444 \r
445      //build the rule id that will be returned when a packet matches \r
446      ip_rule_id = NETAPI_NETCP_MATCH_GENERIC_IP | iface_no | ((ip_slot&&0xff)<<8);\r
447      //perform config action\r
448      pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;\r
449      retValue = nwal_setIPAddr(   netapi_get_global()->nwal_context.nwalInstHandle,\r
450                                   trans_id,\r
451                                   (nwal_AppId) (ip_rule_id),\r
452                                   n_handle,\r
453                                   &nwalIpParam,\r
454                                   &pTransInfo->handle);\r
455 \r
456     if(retValue !=  nwal_OK)\r
457     {\r
458         *err = NETAPI_ERR_NWAL_ERR0;\r
459         printf (">netcp cfg: nwal_setIP returned Error Code %d\n",\r
460                     retValue);\r
461         pTransInfo->inUse = nwal_FALSE;\r
462         //zap the entry\r
463         netcp_cfgp_delete_ip(&netapi_get_global()->nwal_context,\r
464                          iface_no,\r
465                          ip_slot);\r
466 \r
467         return -1;\r
468     }\r
469     //wait here until its done since scheduler isn't running yet most likely..\r
470     // todo:  make this handled by scheduler poll later ??\r
471     if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
472     {\r
473         n->nwal_local.numPendingCfg++;\r
474         while ((volatile) n->nwal_local.numPendingCfg)\r
475         {\r
476             // if response is there, then this poll squirts out in the CTl poll callback, \r
477             // which handles the rest (including decrmenting #pending!!\r
478             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
479         }\r
480     }\r
481     printf (">netcp cfg: IP added to interface %d (slot%d)\n", iface_no, ip_slot);\r
482     netcp_cfgp_insert_ip(&netapi_get_global()->nwal_context, ipType, \r
483                           ip_addr, ip_qualifiers, iface_no, ip_slot,\r
484                           pTransInfo->handle);\r
485     pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;\r
486     pTransInfo->inUse = nwal_FALSE;\r
487     return  (ip_rule_id);\r
488 }\r
489 \r
490 /*****************************************************************/\r
491 /***************Delete an attached IP*****************************/\r
492 /*****************************************************************/\r
493 void netcp_cfgDelIp(NETAPI_T h, int iface_no,  nwal_IpType ipType,\r
494                   nwalIpAddr_t  * ip_addr,\r
495                   nwalIpOpt_t * ip_qualifiers, \r
496                   NETCP_CFG_IP_T  ip_rule_id,\r
497                   int *err)\r
498 {\r
499     nwal_RetValue ret;\r
500     NetapiNwalTransInfo_t *pTransInfo;\r
501     nwal_TransID_t     trans_id;\r
502     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
503     void * ifHandle;\r
504     int ip_slot = (ip_rule_id>>8)&0xff;\r
505 \r
506     //get the nwal handle assoicated with this ip   \r
507     ifHandle = netcp_cfgp_get_ip_handle(\r
508          &netapi_get_global()->nwal_context, iface_no,\r
509          ip_slot );\r
510     if(!ifHandle)\r
511             {*err = NETAPI_ERR_BAD_INPUT; return ;}\r
512     *err =0;\r
513 \r
514     //get a transaction id\r
515     pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
516   if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return ;}\r
517     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;\r
518     pTransInfo->netapi_handle = h;\r
519     //issue request\r
520     ret = nwal_delIPAddr(\r
521                 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
522                 trans_id,\r
523                 ifHandle);\r
524     if(ret !=  nwal_OK)\r
525     {\r
526         *err = NETAPI_ERR_NWAL_ERR0;\r
527         printf (">netcp cfg - ERROR: nwal_delMacIface returned Error Code %d\n",\r
528                     ret);\r
529         pTransInfo->inUse = nwal_FALSE;\r
530         return ;\r
531     }\r
532     //wait here until its done since scheduler isn't running yet most likely..\r
533     // todo:  make this handled by scheduler poll later ??\r
534     if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
535     {\r
536        n->nwal_local.numPendingCfg++;\r
537         while ((volatile) n->nwal_local.numPendingCfg)\r
538         {\r
539             // if response is there, then this poll squirts out in the CTl poll callback, \r
540             // which handles the rest (including decrmenting #pending!!\r
541             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
542         }\r
543     }\r
544     printf (">netcp cfg: IP i/f deleted\n");\r
545     pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;\r
546     pTransInfo->inUse = nwal_FALSE;\r
547     //zap the entry\r
548     netcp_cfgp_delete_ip(&netapi_get_global()->nwal_context,  \r
549                          iface_no,\r
550                          ip_slot);\r
551     return ;\r
552 }\r
553 \r
554 \r
555 /*************************************************************************/\r
556 /*********************************INTERNAL*******************************/\r
557 /************************************************************************/\r
558 \r
559 /***************************************************************\r
560  ********************METCP CMD Reply Callback******************\r
561  ***************************************************************/\r
562 void netapi_NWALCmdCallBack (nwal_AppId        appHandle,\r
563                           uint16_t            trans_id,\r
564                           nwal_RetValue     ret)\r
565 {\r
566     NetapiNwalTransInfo_t * p_trans;\r
567     NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL;\r
568 \r
569     if(trans_id == NWAL_TRANSID_SPIN_WAIT)\r
570     {\r
571         netapi_get_global()->nwal_context.numBogusTransIds++;\r
572         return;\r
573     }\r
574 \r
575     p_trans= &netapi_get_global()->nwal_context.transInfos[trans_id];\r
576     p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;\r
577 \r
578     if(ret != nwal_OK)\r
579     {\r
580         printf (">netcp cfg : NWALCmdCallBack returned Error Code %d\n",\r
581                     ret);\r
582         //todo: atomic inc\r
583         netapi_get_global()->nwal_context.numCmdFail++;\r
584     }\r
585     else\r
586     {\r
587         //todo: atomic inc\r
588         netapi_get_global()->nwal_context.numCmdPass++;\r
589         switch(p_trans->transType)\r
590         {\r
591             case NETAPI_NWAL_HANDLE_TRANS_MAC:\r
592             {\r
593                 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)\r
594                 {\r
595                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;\r
596                 }\r
597                 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
598                 {\r
599                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;\r
600                 }\r
601                 break;\r
602             }\r
603             case NETAPI_NWAL_HANDLE_TRANS_IP:\r
604             {\r
605                  if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)\r
606                 {\r
607                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;\r
608                 }\r
609                 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
610                 {\r
611                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;\r
612                 }\r
613                 break;\r
614             }\r
615 #if 0\r
616             case TEST_NWAL_HANDLE_TRANS_PORT:\r
617             {\r
618                 if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING)\r
619                 {\r
620                     testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN;\r
621                 }\r
622                 else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
623                 {\r
624                     testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE;\r
625                 }\r
626                 break;\r
627             }\r
628             case TEST_NWAL_HANDLE_TRANS_SEC_ASSOC:\r
629             {\r
630                 if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING)\r
631                 {\r
632                     testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN;\r
633                 }\r
634                 else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
635                 {\r
636                     System_printf ("Set Security Assoc  Close ACK received for trans_id: %d\n",\r
637                                 testNwLocContext.transInfos[trans_id].transType,trans_id);\r
638                     nwal_SystemFlush();\r
639                     testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE;\r
640                 }\r
641                 break;\r
642             }\r
643 case TEST_NWAL_HANDLE_TRANS_SEC_POLICY:\r
644             {\r
645                 if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING)\r
646                 {\r
647                     testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN;\r
648                 }\r
649                 else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
650                 {\r
651                     System_printf ("Set Security Policy  Close ACK received for trans_id: %d\n",\r
652                                 testNwLocContext.transInfos[trans_id].transType,trans_id);\r
653                     nwal_SystemFlush();\r
654                     testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE;\r
655                 }\r
656                 break;\r
657             }\r
658 #endif\r
659             default:\r
660             {\r
661                 printf ("netcp cfg> Invalid transaction type %d for trans_id: %d\n",\r
662                     p_trans->transType,trans_id);\r
663                 break;\r
664             }\r
665         }\r
666     }\r
667 \r
668     p_local->numPendingCfg--;\r
669 \r
670     if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_IDLE)\r
671     {\r
672         p_trans->inUse = nwal_FALSE;\r
673     }\r
674 \r
675 }\r
676 \r
677 \r
678 /*******************************************************/\r
679 /**************stats reply callback**********************/\r
680 /*******************************************************/\r
681 void netapi_NWALCmdPaStatsReply (nwal_AppId        appHandle,\r
682                               nwal_TransID_t    trans_id,\r
683                               paSysStats_t      *stats)\r
684 {\r
685     NetapiNwalTransInfo_t * p_trans;\r
686     NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL;\r
687   \r
688     if(trans_id == NWAL_TRANSID_SPIN_WAIT)\r
689     {\r
690         netapi_get_global()->nwal_context.numBogusTransIds++;\r
691         return;\r
692     }\r
693 \r
694     p_trans= &netapi_get_global()->nwal_context.transInfos[trans_id];\r
695     p_trans->inUse = nwal_FALSE;\r
696     p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;\r
697 \r
698     //save a local copy  of some stuff*/\r
699     p_local->numL2PktsRecvd=stats->classify1.nPackets;\r
700     p_local->numL3PktsRecvd=stats->classify1.nIpv4Packets;\r
701 #if 0\r
702     p_local->numL4PktsRecvd=stats->;\r
703     p_local->numL4PktsSent=stats->;\r
704     p_local->TxErrDrop=stats->;\r
705 #endif\r
706     //callout result to application !!\r
707     if (p_local->stats_cb) (*p_local->stats_cb)(p_trans->netapi_handle,stats);\r
708     \r
709\r
710 \r