4dbb1ce9fc0963b7af08454ad5aa7d65fb5a851b
[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                           void * L2_handle,\r
229                           void * L3_handle,\r
230                           void * L4_handle)\r
231 {\r
232         p->classi[class_slot].in_use=1;\r
233         p->classi[class_slot].nwal_L2_handle = L2_handle;\r
234         p->classi[class_slot].nwal_L3_handle = L3_handle;\r
235         p->classi[class_slot].nwal_L4_handle = L4_handle;\r
236         return;\r
237 }\r
238 \r
239 //internal: return nwal_handle for class\r
240 static void *netcp_cfgp_get_class_handle( NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
241                           int class_slot)\r
242 {\r
243    if ((class_slot <0 ) || (class_slot >= TUNE_NETAPI_MAX_CLASSIFIERS)) return NULL;\r
244    if (!p->classi[class_slot].in_use) return NULL;\r
245    return p->classi[class_slot].nwal_L4_handle;\r
246 }\r
247 \r
248 /***********************************************************************************/\r
249 /****************************************API****************************************/\r
250 /***********************************************************************************/\r
251 \r
252 \r
253 /*****************************************************************\r
254  *  Queury Stats\r
255  ****************************************************************/\r
256 void netcp_cfgReqStats(NETAPI_T  h, NETCP_CFG_STATS_CB cb, int doClear, int *err) \r
257 {\r
258 nwal_RetValue ret;\r
259 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
260 NetapiNwalTransInfo_t *pTransInfo;\r
261 nwal_TransID_t     transId;\r
262 if ((!n) || (!cb)) {*err = NETAPI_ERR_BAD_INPUT; return ;}\r
263 *err =0;\r
264 \r
265 pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &transId);\r
266 if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return ;}\r
267 pTransInfo->transType = NETAPI_NWAL_HANDLE_STAT_REQUEST;\r
268 pTransInfo->netapi_handle = h;\r
269 n->nwal_local.stats_cb = cb;\r
270 ret = nwal_getPAStats( ((NETAPI_GLOBAL_T *) n->global)->nwal_context.nwalInstHandle,\r
271                           transId,\r
272                           NULL,\r
273                           doClear);\r
274 if(ret !=  nwal_OK)\r
275 {\r
276    pTransInfo->inUse = nwal_FALSE;\r
277    *err = NETAPI_ERR_BUSY;  //no resources??\r
278    printf("> netcp_cfg reqStats failed, err=%d\n",ret);\r
279 }\r
280 \r
281 }\r
282 /*****************************************************************\r
283  *  CREATE A MAC INTERFACE\r
284  ****************************************************************/\r
285 NETCP_CFG_MACIF_T  netcp_cfgCreateMacInterface(\r
286                   NETAPI_T  h,\r
287                   uint8_t *p_mac,\r
288                   int  iface_no, \r
289                   int switch_port, \r
290                   NETCP_CFG_ROUTE_HANDLE_T  route,\r
291                   NETCP_CFG_VLAN_T  vlan,  //future\r
292                   int state,  //0=down, 1=up  //ignored\r
293                   int * err\r
294                   )\r
295 {\r
296 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
297 nwalMacParam_t   MacInfo= {\r
298     0,      /* validParams */\r
299     0,      /* ifNum */\r
300     0,      /* vlanId      */\r
301     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },      /* Local mac */\r
302     NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */\r
303     NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */\r
304     CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */\r
305     QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */\r
306 };\r
307 \r
308 nwal_RetValue       retValue;\r
309 NetapiNwalTransInfo_t *pTransInfo;\r
310 nwal_TransID_t     trans_id;\r
311 \r
312     if ((!n) || (!p_mac)) {*err = NETAPI_ERR_BAD_INPUT; return -1;}\r
313     *err =0;\r
314 \r
315     pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
316     if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return -1;}\r
317     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC;\r
318     pTransInfo->netapi_handle = h; \r
319 \r
320     /* set up MacInfo */\r
321     memcpy(&MacInfo.macAddr,p_mac,6); \r
322     /* todo: vlan */\r
323     MacInfo.ifNum = switch_port;  /* todo: check for 0/1 relative*/\r
324 \r
325 #if 0  //todo\r
326     if (route != NULL)\r
327     {\r
328         MacInfo.appRxPktFlowId = ((NETCP_CFG_FLOW_T *)(route.flow))->flowid;\r
329         MacInfo.appRxPktQueue = PKTIO_GET_Q(route->p_dest_q);\r
330         //handle action ??\r
331     }\r
332 #endif\r
333     pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;\r
334     retValue = nwal_setMacIface( ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
335                                   trans_id,\r
336                                   (nwal_AppId) (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no),\r
337                                   &MacInfo,\r
338                                   &pTransInfo->handle);\r
339     if(retValue !=  nwal_OK)\r
340     {\r
341         *err = NETAPI_ERR_NWAL_ERR0;\r
342         printf (">netcp cfg - ERROR: nwal_setMacIface returned Error Code %d\n",\r
343                     retValue);\r
344         pTransInfo->inUse = nwal_FALSE;\r
345         return -1;\r
346     }\r
347     //pTransInfo->inUse = nwal_FALSE;\r
348 \r
349     //wait here until its done since scheduler isn't running yet most likely..\r
350     // todo:  make this handled by scheduler poll later ??\r
351     if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
352     {\r
353         n->nwal_local.numPendingCfg++;\r
354         while ((volatile) n->nwal_local.numPendingCfg)\r
355         {\r
356             // if response is there, then this poll squirts out in the CTl poll callback, \r
357             // which handles the rest (including decrmenting #pending!!\r
358             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
359         }\r
360     }\r
361     printf (">netcp cfg: MAC i/f %d added\n", iface_no);\r
362     netcp_cfgp_insert_mac(&netapi_get_global()->nwal_context, \r
363                           p_mac, iface_no, state,vlan,\r
364                           (void *) pTransInfo->handle);\r
365     pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;\r
366     pTransInfo->inUse = nwal_FALSE;\r
367     return  (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no);\r
368 }\r
369 \r
370 \r
371 /*****************************************************************/\r
372 /***************Delete a mac interface****************************/\r
373 /*****************************************************************/\r
374 void netcp_cfgDelMac(NETAPI_T h,int iface_no,  int *err)\r
375 {\r
376     nwal_RetValue ret;\r
377     NetapiNwalTransInfo_t *pTransInfo;\r
378     nwal_TransID_t     trans_id;\r
379     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
380     void * ifHandle;\r
381 \r
382     //get the nwal handle assoicated with this iface\r
383     ifHandle = netcp_cfgp_get_mac_handle(&netapi_get_global()->nwal_context, iface_no );\r
384     if(!ifHandle) \r
385             {*err = NETAPI_ERR_BAD_INPUT; return ;}\r
386     *err =0;\r
387     \r
388     //get a transaction id\r
389     pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
390     if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return ;}\r
391     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC;\r
392     pTransInfo->netapi_handle = h;\r
393     //issue request\r
394     ret = nwal_delMacIface(\r
395                 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
396                 trans_id,\r
397                 ifHandle);\r
398     if(ret !=  nwal_OK)\r
399     {\r
400         *err = NETAPI_ERR_NWAL_ERR0;\r
401         printf (">netcp cfg - ERROR: nwal_delMacIface returned Error Code %d\n",\r
402                     ret);\r
403         pTransInfo->inUse = nwal_FALSE;\r
404         return ;\r
405     }\r
406     //wait here until its done since scheduler isn't running yet most likely..\r
407     // todo:  make this handled by scheduler poll later ??\r
408     if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
409     {\r
410         n->nwal_local.numPendingCfg++;\r
411         while ((volatile) n->nwal_local.numPendingCfg)\r
412         {\r
413             // if response is there, then this poll squirts out in the CTl poll callback, \r
414             // which handles the rest (including decrmenting #pending!!\r
415             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
416         }\r
417     }\r
418     printf (">netcp cfg: MAC i/f %d deleted\n",iface_no);\r
419     pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;\r
420     pTransInfo->inUse = nwal_FALSE;\r
421     //zap the entry\r
422     netcp_cfgp_delete_mac(&netapi_get_global()->nwal_context,  iface_no);\r
423     return ;\r
424 }\r
425 \r
426 \r
427 /*****************************************************************/\r
428 /***************Add IP to MAC interface****************************/\r
429 /*****************************************************************/\r
430 NETCP_CFG_IP_T  netcp_cfgAddIp(\r
431                   NETAPI_T  h,\r
432                   int  iface_no,\r
433                   nwal_IpType ipType,\r
434                   nwalIpAddr_t  * ip_addr,\r
435                   nwalIpOpt_t * ip_qualifiers,\r
436                   NETCP_CFG_ROUTE_HANDLE_T  route,  //NULL for default\r
437                   int * err\r
438                   )\r
439 {\r
440 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
441 void * n_handle;\r
442 nwalIpParam_t    nwalIpParam= {\r
443     pa_IPV4,      /* IP Type */\r
444     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Dest IP */\r
445     { 0x0,0,0,0},/* IP Options */\r
446     NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */\r
447     NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */\r
448     CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */\r
449     QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */\r
450 };\r
451 nwal_RetValue       retValue;\r
452 NetapiNwalTransInfo_t *pTransInfo;\r
453 nwal_TransID_t     trans_id;\r
454 int ip_slot=-1;\r
455 NETCP_CFG_IP_T ip_rule_id;\r
456 \r
457      //verify that iface has been configurred \r
458      if ((iface_no<0) || (iface_no>= TUNE_NETAPI_MAX_INTERFACES)) {*err = NETAPI_ERR_BAD_INPUT; return -1;}\r
459 \r
460      if(netapi_get_global()->nwal_context.interfaces[iface_no].in_use)\r
461      {\r
462         n_handle =  netapi_get_global()->nwal_context.interfaces[iface_no].nwal_handle;\r
463      }\r
464      else\r
465      {\r
466         *err = NETAPI_ERR_BAD_INPUT;\r
467         return -1;\r
468      }\r
469      //find free slot for IP & reserve\r
470      ip_slot= netcp_cfgp_find_ip_slot(&netapi_get_global()->nwal_context, \r
471                                    iface_no);\r
472      if (ip_slot <0) \r
473      {\r
474         *err= NETAPI_ERR_NOMEM;  //no room \r
475      }\r
476 \r
477      //get a transaction object for config action\r
478     pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
479     if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return -1;}\r
480     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;\r
481     pTransInfo->netapi_handle = h;\r
482 \r
483      //build nwalIpParam\r
484      memcpy(&nwalIpParam.locIpAddr,ip_addr, sizeof(nwalIpAddr_t));\r
485      nwalIpParam.ipType=ipType;\r
486      if(route)\r
487      {\r
488           //todo: support app defined routes\r
489      } \r
490      else{} //use nwal defaults\r
491      if (ip_qualifiers)\r
492         memcpy(&nwalIpParam.ipOpt,ip_qualifiers, sizeof(nwalIpOpt_t)); \r
493      else\r
494         memset(&nwalIpParam.ipOpt,0, sizeof(nwalIpOpt_t));\r
495 \r
496      //build the rule id that will be returned when a packet matches \r
497      ip_rule_id = NETAPI_NETCP_MATCH_GENERIC_IP | iface_no | ((ip_slot&&0xff)<<8);\r
498      //perform config action\r
499      pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;\r
500      retValue = nwal_setIPAddr(   netapi_get_global()->nwal_context.nwalInstHandle,\r
501                                   trans_id,\r
502                                   (nwal_AppId) (ip_rule_id),\r
503                                   n_handle,\r
504                                   &nwalIpParam,\r
505                                   &pTransInfo->handle);\r
506 \r
507     if(retValue !=  nwal_OK)\r
508     {\r
509         *err = NETAPI_ERR_NWAL_ERR0;\r
510         printf (">netcp cfg: nwal_setIP returned Error Code %d\n",\r
511                     retValue);\r
512         pTransInfo->inUse = nwal_FALSE;\r
513         //zap the entry\r
514         netcp_cfgp_delete_ip(&netapi_get_global()->nwal_context,\r
515                          iface_no,\r
516                          ip_slot);\r
517 \r
518         return -1;\r
519     }\r
520     //wait here until its done since scheduler isn't running yet most likely..\r
521     // todo:  make this handled by scheduler poll later ??\r
522     if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
523     {\r
524         n->nwal_local.numPendingCfg++;\r
525         while ((volatile) n->nwal_local.numPendingCfg)\r
526         {\r
527             // if response is there, then this poll squirts out in the CTl poll callback, \r
528             // which handles the rest (including decrmenting #pending!!\r
529             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
530         }\r
531     }\r
532     printf (">netcp cfg: IP added to interface %d (slot%d)\n", iface_no, ip_slot);\r
533     netcp_cfgp_insert_ip(&netapi_get_global()->nwal_context, ipType, \r
534                           ip_addr, ip_qualifiers, iface_no, ip_slot,\r
535                           pTransInfo->handle);\r
536     pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;\r
537     pTransInfo->inUse = nwal_FALSE;\r
538     return  (ip_rule_id);\r
539 }\r
540 \r
541 /*****************************************************************/\r
542 /***************Delete an attached IP*****************************/\r
543 /*****************************************************************/\r
544 void netcp_cfgDelIp(NETAPI_T h, int iface_no,  nwal_IpType ipType,\r
545                   nwalIpAddr_t  * ip_addr,\r
546                   nwalIpOpt_t * ip_qualifiers, \r
547                   NETCP_CFG_IP_T  ip_rule_id,\r
548                   int *err)\r
549 {\r
550     nwal_RetValue ret;\r
551     NetapiNwalTransInfo_t *pTransInfo;\r
552     nwal_TransID_t     trans_id;\r
553     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
554     void * ifHandle;\r
555     int ip_slot = (ip_rule_id>>8)&0xff;\r
556 \r
557     //get the nwal handle assoicated with this ip   \r
558     ifHandle = netcp_cfgp_get_ip_handle(\r
559          &netapi_get_global()->nwal_context, iface_no,\r
560          ip_slot );\r
561     if(!ifHandle)\r
562             {*err = NETAPI_ERR_BAD_INPUT; return ;}\r
563     *err =0;\r
564 \r
565     //get a transaction id\r
566     pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
567   if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return ;}\r
568     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;\r
569     pTransInfo->netapi_handle = h;\r
570     //issue request\r
571     ret = nwal_delIPAddr(\r
572                 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
573                 trans_id,\r
574                 ifHandle);\r
575     if(ret !=  nwal_OK)\r
576     {\r
577         *err = NETAPI_ERR_NWAL_ERR0;\r
578         printf (">netcp cfg - ERROR: nwal_delMacIface returned Error Code %d\n",\r
579                     ret);\r
580         pTransInfo->inUse = nwal_FALSE;\r
581         return ;\r
582     }\r
583     //wait here until its done since scheduler isn't running yet most likely..\r
584     // todo:  make this handled by scheduler poll later ??\r
585     if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
586     {\r
587        n->nwal_local.numPendingCfg++;\r
588         while ((volatile) n->nwal_local.numPendingCfg)\r
589         {\r
590             // if response is there, then this poll squirts out in the CTl poll callback, \r
591             // which handles the rest (including decrmenting #pending!!\r
592             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
593         }\r
594     }\r
595     printf (">netcp cfg: IP i/f deleted\n");\r
596     pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;\r
597     pTransInfo->inUse = nwal_FALSE;\r
598     //zap the entry\r
599     netcp_cfgp_delete_ip(&netapi_get_global()->nwal_context,  \r
600                          iface_no,\r
601                          ip_slot);\r
602     return ;\r
603 }\r
604 \r
605 /**\r
606  * @def netcp_cfgAddClass\r
607  * @brief  add a classifier rule into NETCP\r
608  **/\r
609 NETCP_CFG_CLASS_T netcp_cfgAddClass(NETAPI_T h,\r
610                                       NETCP_CFG_CLASSIFIER_T *p_class,\r
611                                       NETCP_CFG_ROUTE_HANDLE_T p_route,\r
612                                       int action, int * err)\r
613 {\r
614 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
615 void * l3_handle;  //ip handle\r
616 nwal_RetValue       retValue;\r
617 NetapiNwalTransInfo_t *pTransInfo;\r
618 nwal_TransID_t     trans_id;\r
619 int class_slot=-1;\r
620 int iface;\r
621 int ip_slot;\r
622 NETCP_CFG_CLASS_T  classHandle;  //returned by us\r
623 nwal_appProtoType_t proto;\r
624 nwalLocConnCfg_t tempCfg={\r
625 0,  //nwal_handle: to be filled in\r
626 {0}, // l4 ports: to be filled in\r
627 0,  //core id (NA)\r
628 0, //action\r
629 CPPI_PARAM_NOT_SPECIFIED, //flow id\r
630 QMSS_PARAM_NOT_SPECIFIED, //dest queue\r
631 };\r
632 \r
633 if(!p_class) { *err=NETAPI_ERR_BAD_INPUT; return -1;}\r
634 switch(p_class->classType)\r
635 {\r
636 default:\r
637         printf(">netcp_cfg : classifier type %d not supported\n",p_class->classType);\r
638         break;\r
639 \r
640 case(NETCP_CFG_CLASS_TYPE_L4):\r
641         //assume just type l4 only (L2, L3 defined by iface, l3 id )\r
642         iface = p_class->u.c_l4.iface;\r
643         ip_slot = (p_class->u.c_l4.ip>>8)&0xff;\r
644 \r
645          //verify that iface has been configured \r
646         if(!netapi_get_global()->nwal_context.interfaces[iface].in_use)\r
647         {\r
648                 *err = NETAPI_ERR_BAD_INPUT;\r
649                 return -1;\r
650         }\r
651         //verify that ip has been configured and get its handle\r
652         l3_handle = netcp_cfgp_get_ip_handle(\r
653                           &netapi_get_global()->nwal_context, iface,\r
654                           ip_slot );\r
655         if(!l3_handle)\r
656             {*err = NETAPI_ERR_BAD_INPUT; return -1 ;}\r
657 \r
658 \r
659         //find free slot for CLASS & reserve\r
660         class_slot= netcp_cfgp_find_class_slot(&netapi_get_global()->nwal_context);\r
661         if(class_slot<0) {*err = NETAPI_ERR_NOMEM; return -1;}\r
662         classHandle = NETAPI_NETCP_MATCH_CLASS | (class_slot<<8) | (iface&0xff);\r
663         //build request from template\r
664         tempCfg.inHandle=l3_handle;\r
665         memcpy(&tempCfg.appProto,&p_class->u.c_l4.appProto,sizeof(nwalAppProto_t));\r
666         tempCfg.matchAction = (action==NETCP_CFG_ACTION_TO_SW)  ? NWAL_MATCH_ACTION_HOST : NWAL_MATCH_ACTION_DISCARD;\r
667         proto = p_class->u.c_l4.proto;\r
668         //todo: flowid and route \r
669         //get a transaction id\r
670         pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
671         if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return -1 ;}\r
672         pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;\r
673         pTransInfo->netapi_handle = h;\r
674         //issue request\r
675         retValue = nwal_addConn(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
676                             trans_id,\r
677                             (nwal_AppId) classHandle,\r
678                             proto,\r
679                             &tempCfg,\r
680                             NULL,\r
681                             &pTransInfo->handle);\r
682         if(retValue !=  nwal_OK)\r
683         {\r
684             *err = NETAPI_ERR_NWAL_ERR0;\r
685             printf (">netcp cfg - ERROR: nwal_addConn returned Error Code %d\n",\r
686                     retValue);\r
687             pTransInfo->inUse = nwal_FALSE;\r
688             netcp_cfgp_delete_class(&netapi_get_global()->nwal_context, class_slot);\r
689             return -1;\r
690         }\r
691         //wait here until its done since scheduler isn't running yet most likely..\r
692         // todo:  make this handled by scheduler poll later ??\r
693         if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
694         {\r
695              n->nwal_local.numPendingCfg++;\r
696              while ((volatile) n->nwal_local.numPendingCfg)\r
697              {\r
698                 // if response is there, then this poll squirts out in the CTl poll callback, \r
699                 // which handles the rest (including decrmenting #pending!!\r
700                 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
701              }\r
702          }\r
703          printf (">netcp cfg: L4 Classifer added to interface %d ip %d (slot%d)\n", iface, ip_slot, class_slot);\r
704          netcp_cfgp_insert_class(&netapi_get_global()->nwal_context, \r
705                                    class_slot,\r
706                                   NULL,  //L2 we have\r
707                                   NULL,  //L3 we have\r
708                                   pTransInfo->handle);\r
709          pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;\r
710 \r
711         \r
712         return classHandle;\r
713 } //end switch\r
714 return -1;\r
715 }\r
716 \r
717 //delete classifier\r
718 void netcp_cfgDelClass(NETAPI_T h,\r
719                          NETCP_CFG_CLASS_T classId,\r
720                          int *err)\r
721 {\r
722 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
723 void * class_handle;  //class handle\r
724 nwal_RetValue       retValue;\r
725 NetapiNwalTransInfo_t *pTransInfo;\r
726 nwal_TransID_t     trans_id;\r
727 int class_slot=-1;\r
728 //int iface;\r
729 //int ip_slot;\r
730 \r
731         class_slot = (classId>>8)&0xffff;\r
732         class_handle=netcp_cfgp_get_class_handle(\r
733                         &netapi_get_global()->nwal_context,\r
734                         class_slot );\r
735         if(!class_handle)  {*err = NETAPI_ERR_BAD_INPUT; return -1;}\r
736         netcp_cfgp_delete_class(\r
737                         &netapi_get_global()->nwal_context,\r
738                         class_slot );\r
739         //get a transaction id\r
740         pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
741         if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return -1 ;}\r
742         pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;\r
743         pTransInfo->netapi_handle = h;\r
744         //issue request\r
745         retValue = nwal_delConn(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
746                             trans_id,\r
747                             class_handle);\r
748         if(retValue !=  nwal_OK)\r
749         {\r
750             *err = NETAPI_ERR_NWAL_ERR0;\r
751             printf (">netcp cfg - ERROR: nwal_delConn returned Error Code %d\n",\r
752                     retValue);\r
753             pTransInfo->inUse = nwal_FALSE;\r
754             return -1;\r
755         }\r
756         //wait here until its done since scheduler isn't running yet most likely..\r
757         // todo:  make this handled by scheduler poll later ??\r
758         if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
759         {\r
760              n->nwal_local.numPendingCfg++;\r
761              while ((volatile) n->nwal_local.numPendingCfg)\r
762              {\r
763                 // if response is there, then this poll squirts out in the CTl poll callback, \r
764                 // which handles the rest (including decrmenting #pending!!\r
765                 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
766              }\r
767          }\r
768          printf (">netcp cfg: Classifer deleted\n");\r
769          pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;\r
770          pTransInfo->inUse = nwal_FALSE;\r
771          return ;\r
772 }\r
773 \r
774 \r
775 /*************************************************************************/\r
776 /*********************************INTERNAL*******************************/\r
777 /************************************************************************/\r
778 \r
779 /***************************************************************\r
780  ********************METCP CMD Reply Callback******************\r
781  ***************************************************************/\r
782 void netapi_NWALCmdCallBack (nwal_AppId        appHandle,\r
783                           uint16_t            trans_id,\r
784                           nwal_RetValue     ret)\r
785 {\r
786     NetapiNwalTransInfo_t * p_trans;\r
787     NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL;\r
788 \r
789     if(trans_id == NWAL_TRANSID_SPIN_WAIT)\r
790     {\r
791         netapi_get_global()->nwal_context.numBogusTransIds++;\r
792         return;\r
793     }\r
794 \r
795     p_trans= &netapi_get_global()->nwal_context.transInfos[trans_id];\r
796     p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;\r
797 \r
798     if(ret != nwal_OK)\r
799     {\r
800         printf (">netcp cfg : NWALCmdCallBack returned Error Code %d\n",\r
801                     ret);\r
802         //todo: atomic inc\r
803         netapi_get_global()->nwal_context.numCmdFail++;\r
804     }\r
805     else\r
806     {\r
807         //todo: atomic inc\r
808         netapi_get_global()->nwal_context.numCmdPass++;\r
809         switch(p_trans->transType)\r
810         {\r
811             case NETAPI_NWAL_HANDLE_TRANS_MAC:\r
812             {\r
813                 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)\r
814                 {\r
815                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;\r
816                 }\r
817                 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
818                 {\r
819                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;\r
820                 }\r
821                 break;\r
822             }\r
823             case NETAPI_NWAL_HANDLE_TRANS_IP:\r
824             {\r
825                  if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)\r
826                 {\r
827                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;\r
828                 }\r
829                 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
830                 {\r
831                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;\r
832                 }\r
833                 break;\r
834             }\r
835             case NETAPI_NWAL_HANDLE_TRANS_PORT:\r
836             {\r
837                 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)\r
838                 {\r
839                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;\r
840                 }\r
841                 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
842                 {\r
843                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;\r
844                 }\r
845                 break;\r
846             }\r
847 #if 0\r
848             case TEST_NWAL_HANDLE_TRANS_SEC_ASSOC:\r
849             {\r
850                 if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING)\r
851                 {\r
852                     testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN;\r
853                 }\r
854                 else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
855                 {\r
856                     System_printf ("Set Security Assoc  Close ACK received for trans_id: %d\n",\r
857                                 testNwLocContext.transInfos[trans_id].transType,trans_id);\r
858                     nwal_SystemFlush();\r
859                     testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE;\r
860                 }\r
861                 break;\r
862             }\r
863 case TEST_NWAL_HANDLE_TRANS_SEC_POLICY:\r
864             {\r
865                 if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING)\r
866                 {\r
867                     testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN;\r
868                 }\r
869                 else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
870                 {\r
871                     System_printf ("Set Security Policy  Close ACK received for trans_id: %d\n",\r
872                                 testNwLocContext.transInfos[trans_id].transType,trans_id);\r
873                     nwal_SystemFlush();\r
874                     testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE;\r
875                 }\r
876                 break;\r
877             }\r
878 #endif\r
879             default:\r
880             {\r
881                 printf ("netcp cfg> Invalid transaction type %d for trans_id: %d\n",\r
882                     p_trans->transType,trans_id);\r
883                 break;\r
884             }\r
885         }\r
886     }\r
887 \r
888     p_local->numPendingCfg--;\r
889 \r
890     if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_IDLE)\r
891     {\r
892         p_trans->inUse = nwal_FALSE;\r
893     }\r
894 \r
895 }\r
896 \r
897 \r
898 /*******************************************************/\r
899 /**************stats reply callback**********************/\r
900 /*******************************************************/\r
901 void netapi_NWALCmdPaStatsReply (nwal_AppId        appHandle,\r
902                               nwal_TransID_t    trans_id,\r
903                               paSysStats_t      *stats)\r
904 {\r
905     NetapiNwalTransInfo_t * p_trans;\r
906     NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL;\r
907   \r
908     if(trans_id == NWAL_TRANSID_SPIN_WAIT)\r
909     {\r
910         netapi_get_global()->nwal_context.numBogusTransIds++;\r
911         return;\r
912     }\r
913 \r
914     p_trans= &netapi_get_global()->nwal_context.transInfos[trans_id];\r
915     p_trans->inUse = nwal_FALSE;\r
916     p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;\r
917 \r
918     //save a local copy  of some stuff*/\r
919     p_local->numL2PktsRecvd=stats->classify1.nPackets;\r
920     p_local->numL3PktsRecvd=stats->classify1.nIpv4Packets;\r
921 #if 0\r
922     p_local->numL4PktsRecvd=stats->;\r
923     p_local->numL4PktsSent=stats->;\r
924     p_local->TxErrDrop=stats->;\r
925 #endif\r
926     //callout result to application !!\r
927     if (p_local->stats_cb) (*p_local->stats_cb)(p_trans->netapi_handle,stats);\r
928     \r
929\r
930 \r