1347ee6cf92cd28099a399ca86803dd660a4caf7
[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 NetapiNwalTransInfo_t *  netapip_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 //internal: build route\r
80 void netcp_cfgp_build_route(NETCP_CFG_ROUTE_T * p_route, int16_t * p_flow,  Qmss_QueueHnd * p_q)\r
81 {\r
82     if (!p_route) return;\r
83     if (p_route->p_flow)  *p_flow= p_route->p_flow->flowid;\r
84     else *p_flow = CPPI_PARAM_NOT_SPECIFIED;\r
85     if (p_route->p_dest_q) *p_q = pktio_get_q(p_route->p_dest_q);\r
86     else *p_q=QMSS_PARAM_NOT_SPECIFIED;\r
87 }\r
88 /*-----------------------------------------------------------*/\r
89 /*----------------database management stuff-------------------*/\r
90 /*-----------------------------------------------------------*/\r
91 \r
92 /*=====================Policies=============================*/\r
93 //internal: find a free slot for an SA \r
94 int netcp_cfgp_find_policy_slot( NETAPI_NWAL_GLOBAL_CONTEXT_T *p, int tunnel)\r
95 {\r
96    int i;\r
97    if ((tunnel <0 ) || (tunnel >=TUNE_NETAPI_MAX_SA)) return -1;\r
98 \r
99          //find a free entry\r
100    for(i=0;i<TUNE_NETAPI_MAX_POLICY;i++)\r
101    {\r
102        if (!p->policy[i].in_use)\r
103        {\r
104            p->policy[i].in_use = 2; //pending\r
105            p->policy[i].tunnel= tunnel; //save tunnel this is linked to \r
106            return i;\r
107        }\r
108    }\r
109    return -1;\r
110 }\r
111 \r
112 //internal: delete a policy from list \r
113 void netcp_cfgp_delete_policy(\r
114          NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
115          int policy_slot )\r
116 {\r
117    if ((policy_slot <0 ) || (policy_slot >= TUNE_NETAPI_MAX_POLICY))\r
118    {\r
119         return ;\r
120    }\r
121    p->policy[policy_slot].in_use=0;\r
122    return;\r
123 }\r
124 \r
125 //internal:  insert an policy into the list  \r
126 void netcp_cfgp_insert_policy(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
127                           int policy_slot,  //we 'reserved it already'\r
128                           void * handle)\r
129 {\r
130         p->policy[policy_slot].in_use=1;\r
131         p->policy[policy_slot].nwal_handle = handle;\r
132         return;\r
133 }\r
134 \r
135 //internal: return nwal_handle for policy \r
136 void *netcp_cfgp_get_policy( NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
137                           int policy_slot)\r
138 {\r
139    if ((policy_slot <0 ) || (policy_slot >= TUNE_NETAPI_MAX_POLICY)) return NULL;\r
140    if (!p->policy[policy_slot].in_use) return NULL;\r
141    return p->policy[policy_slot].nwal_handle;\r
142 }\r
143 \r
144 \r
145 \r
146 /*======================SAs==================================*/\r
147 //internal: find a free slot for an SA \r
148 int netcp_cfgp_find_sa_slot( NETAPI_NWAL_GLOBAL_CONTEXT_T *p, int iface)\r
149 {                                    \r
150    int i;\r
151    if ((iface <0 ) || (iface >=TUNE_NETAPI_MAX_INTERFACES)) return -1;\r
152 \r
153          //find a free entry\r
154    for(i=0;i<TUNE_NETAPI_MAX_SA;i++)\r
155    {                       \r
156        if (!p->tunnel[i].in_use)\r
157        {\r
158            p->tunnel[i].in_use = 2; //pending\r
159            p->tunnel[i].iface= iface; //save iface\r
160            return i;\r
161        }\r
162    }\r
163    return -1;\r
164 }\r
165  //internal: delete an SAr from list \r
166 void netcp_cfgp_delete_sa(\r
167          NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
168          int sa_slot )\r
169 {\r
170    if ((sa_slot <0 ) || (sa_slot >= TUNE_NETAPI_MAX_SA))\r
171    {\r
172         return ;\r
173    }\r
174    p->tunnel[sa_slot].in_use=0;\r
175    return;\r
176 }\r
177 \r
178 //internal:  insert an SA into the list  \r
179 void netcp_cfgp_insert_sa(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
180                           int sa_slot,  //we 'reserved it already'\r
181                           int dir,\r
182                           int mode,\r
183                           void * temp1,\r
184                           void * temp2,\r
185                           void * handle_inflow,\r
186                           void * handle_sideband)\r
187 {\r
188         p->tunnel[sa_slot].in_use=1;\r
189         p->tunnel[sa_slot].inbound = dir;\r
190         p->tunnel[sa_slot].sa_mode = mode;\r
191         p->tunnel[sa_slot].sa_handle_inflow = handle_inflow;\r
192         p->tunnel[sa_slot].sa_handle_sideband = handle_sideband;\r
193         return;\r
194 }\r
195 \r
196 //internal: return nwal_handles for SA   \r
197 void *netcp_cfgp_get_sa_handles( NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
198                           int sa_slot, void ** p_sideband)\r
199 {\r
200    if ((sa_slot <0 ) || (sa_slot >= TUNE_NETAPI_MAX_SA)) return NULL;\r
201    if (!p->tunnel[sa_slot].in_use) return NULL;\r
202    *p_sideband = p->tunnel[sa_slot].sa_handle_sideband;\r
203    return p->tunnel[sa_slot].sa_handle_inflow;\r
204 }\r
205 \r
206 \r
207 /*==============================fLOWS=============================*/\r
208 //internal: find a free slot for a flow \r
209 static int netcp_cfgp_find_flow_slot( NETAPI_NWAL_GLOBAL_CONTEXT_T *p)\r
210 {\r
211    int i;\r
212          //find a free entry\r
213    for(i=0;i<TUNE_NETAPI_MAX_FLOWS;i++)\r
214    {\r
215        if (!p->flows[i].in_use)\r
216        {\r
217            p->flows[i].in_use = 2; //pending\r
218            return i;\r
219        }\r
220    }\r
221    return -1;\r
222 }\r
223 \r
224 //internal: clear flow slot \r
225 static void netcp_cfgp_delete_flow(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,int slot)\r
226 {\r
227    if ((slot >=0 ) && (slot < TUNE_NETAPI_MAX_FLOWS))\r
228    {\r
229         p->flows[slot].in_use = 0;\r
230    }\r
231 }\r
232 \r
233 //internal:  insert a flow into flow slot\r
234 static NETCP_CFG_FLOW_HANDLE_T netcp_cfgp_insert_flow(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
235                           int slot,  //we 'reserved it already'\r
236                           void * handle)  //cppi flow handle. Save this for delete\r
237 {\r
238         p->flows[slot].in_use=1;\r
239         p->flows[slot].handle = handle;\r
240         p->flows[slot].flow.flowid  = Cppi_getFlowId(handle);\r
241         return (NETCP_CFG_FLOW_HANDLE_T) &p->flows[slot].flow;\r
242 }\r
243 \r
244 //find entry matching the flowid.  return slot# and the cppi handle\r
245 static int netcp_cfgp_find_flow(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
246                           int flowid,  \r
247                           void ** handle) \r
248 {\r
249 int i;\r
250    *handle=NULL;\r
251    for(i=0;i<TUNE_NETAPI_MAX_FLOWS;i++)\r
252    {\r
253        if ((p->flows[i].in_use)&&(p->flows[i].flow.flowid == flowid))\r
254        {\r
255            *handle = p->flows[i].handle;\r
256            return i;\r
257        }\r
258    }\r
259    return -1;\r
260 }\r
261 \r
262 \r
263 /*============================IP ADDRESSES==========================*/\r
264 \r
265 //internal: find a free slot for IP rule in interface\r
266 static int netcp_cfgp_find_ip_slot(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
267                           int iface_no)\r
268 {\r
269    int i;\r
270    if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_INTERFACES))\r
271    {\r
272         return -1;\r
273    }\r
274    if (!p->interfaces[iface_no].in_use) return -1;\r
275 \r
276    //find a free entry\r
277    for(i=0;i<TUNE_NETAPI_MAX_IP_PER_INTERFACE;i++)\r
278    {\r
279        if (!p->interfaces[iface_no].ips[i].in_use)\r
280        {\r
281            p->interfaces[iface_no].ips[i].in_use = 2; //pending\r
282            return i;\r
283        }\r
284    }\r
285    return -1;\r
286 }\r
287 \r
288 \r
289 //internal:  insert an IP address into iface\r
290 static void netcp_cfgp_insert_ip(NETAPI_NWAL_GLOBAL_CONTEXT_T *p, \r
291                           nwal_IpType ipType,\r
292                           nwalIpAddr_t *ip_addr, \r
293                           nwalIpOpt_t *ip_qualifiers, \r
294                           int iface_no,\r
295                           int ip_slot,  //we 'reserved it already'\r
296                           void * handle)\r
297 {\r
298         p->interfaces[iface_no].ips[ip_slot].in_use=1;\r
299         memcpy(&p->interfaces[iface_no].ips[ip_slot].ip_addr, ip_addr, sizeof(nwalIpAddr_t));\r
300         if(ip_qualifiers)\r
301         memcpy(&p->interfaces[iface_no].ips[ip_slot].ip_qualifiers, ip_qualifiers, sizeof(nwalIpOpt_t));\r
302         else\r
303         memset(&p->interfaces[iface_no].ips[ip_slot].ip_qualifiers, 0, sizeof(nwalIpOpt_t));\r
304         p->interfaces[iface_no].ips[ip_slot].ip_type = ipType;\r
305         p->interfaces[iface_no].ips[ip_slot].nwal_handle = handle;\r
306         return;\r
307 }\r
308 \r
309 \r
310 //internal: free IP slot associated with ip address \r
311 static void netcp_cfgp_delete_ip(\r
312          NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
313          int iface_no,\r
314          int ip_slot )\r
315 {\r
316    if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_INTERFACES))\r
317    {\r
318         return ;\r
319    }\r
320    if (!p->interfaces[iface_no].in_use) return ;\r
321    if ((ip_slot <0)||(ip_slot>TUNE_NETAPI_MAX_IP_PER_INTERFACE)) return ;\r
322    p->interfaces[iface_no].ips[ip_slot].in_use=0;\r
323    return;\r
324 }\r
325 \r
326 \r
327 //internal: get IP handle associated with ip address \r
328 static void *netcp_cfgp_get_ip_handle(\r
329          NETAPI_NWAL_GLOBAL_CONTEXT_T *p, \r
330          int iface_no,\r
331          int ip_slot )\r
332 {\r
333    if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_INTERFACES))\r
334    {\r
335         return NULL;\r
336    }\r
337    if (!p->interfaces[iface_no].in_use) return NULL;\r
338    if ((ip_slot <0)||(ip_slot>=TUNE_NETAPI_MAX_IP_PER_INTERFACE)) return NULL;\r
339    if (!p->interfaces[iface_no].ips[ip_slot].in_use) return NULL;\r
340    return (void *) p->interfaces[iface_no].ips[ip_slot].nwal_handle;\r
341 }\r
342 \r
343 /*==========================MAC INTERFACES======================*/\r
344 //internal: insert interface info into global context\r
345 static void netcp_cfgp_insert_mac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p, unsigned char * p_mac,\r
346                            int iface_no, int state, NETCP_CFG_VLAN_T vlan, void * handle)\r
347 {\r
348    if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_INTERFACES))\r
349    {\r
350         memset(&p->interfaces[iface_no],0,sizeof(NETCP_INTERFACE_T));\r
351         p->interfaces[iface_no].in_use = 1;\r
352         memcpy(&p->interfaces[iface_no].mac[0], p_mac,6);\r
353         p->interfaces[iface_no].state = state;\r
354         //todo p->interfaces[iface_no].vlan = vlan;\r
355         p->interfaces[iface_no].nwal_handle = handle; //save handle assoicated with this rule\r
356    }\r
357    else printf(">netcp_cfg insert interface # out of range %d\n",iface_no);\r
358 \r
359 }\r
360 \r
361 //internal: get handle associated with interface\r
362 void* netcp_cfgp_get_mac_handle(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,int iface_no)\r
363 {\r
364    if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_INTERFACES))\r
365    {\r
366         return NULL;\r
367    }\r
368    else if ( p->interfaces[iface_no].in_use)\r
369    {\r
370      return (void *) p->interfaces[iface_no].nwal_handle;\r
371    }\r
372    //no valid entry in slot\r
373    return NULL;\r
374 }\r
375 //internal: clear inteface entry\r
376 static void netcp_cfgp_delete_mac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,int iface_no)\r
377 {\r
378    if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_INTERFACES))\r
379    {\r
380         p->interfaces[iface_no].in_use = 0;\r
381    }\r
382 }\r
383 \r
384 \r
385 /*========================CLASSIFIERS==========================*/\r
386 //internal: find a free slot for classifier rule\r
387 static int netcp_cfgp_find_class_slot( NETAPI_NWAL_GLOBAL_CONTEXT_T *p)\r
388 {\r
389    int i;\r
390          //find a free entry\r
391    for(i=0;i<TUNE_NETAPI_MAX_CLASSIFIERS;i++)\r
392    {\r
393        if (!p->classi[i].in_use)\r
394        {\r
395            p->classi[i].in_use = 2; //pending\r
396            return i;\r
397        }\r
398    }\r
399    return -1;\r
400 }\r
401 \r
402  //internal: delete a classifer from list \r
403 static void netcp_cfgp_delete_class(\r
404          NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
405          int class_slot )\r
406 {\r
407    if ((class_slot <0 ) || (class_slot >= TUNE_NETAPI_MAX_CLASSIFIERS))\r
408    {\r
409         return ;\r
410    }\r
411    p->classi[class_slot].in_use=0;\r
412    return;\r
413 }\r
414 \r
415 //internal:  insert a classifier into list \r
416 static void netcp_cfgp_insert_class(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
417                           int class_slot,  //we 'reserved it already'\r
418                           int class_type,\r
419                           void * L2_handle,\r
420                           void * L3_handle,\r
421                           void * L4_handle)\r
422 {\r
423         p->classi[class_slot].in_use=1;\r
424         p->classi[class_slot].nwal_L2_handle = L2_handle;\r
425         p->classi[class_slot].nwal_L3_handle = L3_handle;\r
426         p->classi[class_slot].nwal_L4_handle = L4_handle;\r
427         p->classi[class_slot].class_type = class_type;\r
428         return;\r
429 }\r
430 \r
431 //internal: return L4 nwal_handle for class\r
432 static void *netcp_cfgp_get_l4_handle( NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
433                           int class_slot)\r
434 {\r
435    if ((class_slot <0 ) || (class_slot >= TUNE_NETAPI_MAX_CLASSIFIERS)) return NULL;\r
436    if (!p->classi[class_slot].in_use) return NULL;\r
437    return p->classi[class_slot].nwal_L4_handle;\r
438 }\r
439 \r
440 //internal: return L3 nwal_handle for class\r
441 static void *netcp_cfgp_get_l3_handle( NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
442                           int class_slot)\r
443 {\r
444    if ((class_slot <0 ) || (class_slot >= TUNE_NETAPI_MAX_CLASSIFIERS)) return NULL;\r
445    if (!p->classi[class_slot].in_use) return NULL;\r
446    return p->classi[class_slot].nwal_L3_handle;\r
447 }\r
448 \r
449 \r
450 /***********************************************************************************/\r
451 /****************************************API****************************************/\r
452 /***********************************************************************************/\r
453 \r
454 \r
455 /*****************************************************************\r
456  *  Queury Stats\r
457  ****************************************************************/\r
458 void netcp_cfgReqStats(NETAPI_T  h, NETCP_CFG_STATS_CB cb, int doClear, int *err) \r
459 {\r
460 nwal_RetValue ret;\r
461 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
462 NetapiNwalTransInfo_t *pTransInfo;\r
463 nwal_TransID_t     transId;\r
464 if ((!n) || (!cb)) {*err = NETAPI_ERR_BAD_INPUT; return ;}\r
465 *err =0;\r
466 \r
467 \r
468 pTransInfo = netapip_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &transId);\r
469 if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return ;}\r
470 pTransInfo->transType = NETAPI_NWAL_HANDLE_STAT_REQUEST;\r
471 pTransInfo->netapi_handle = h;\r
472 n->nwal_local.stats_cb = cb;\r
473 ret = nwal_getPAStats( ((NETAPI_GLOBAL_T *) n->global)->nwal_context.nwalInstHandle,\r
474                           transId,\r
475                           NULL,\r
476                           doClear);\r
477 if(ret !=  nwal_OK)\r
478 {\r
479    pTransInfo->inUse = nwal_FALSE;\r
480    *err = NETAPI_ERR_BUSY;  //no resources??\r
481    printf("> netcp_cfg reqStats failed, err=%d\n",ret);\r
482 }\r
483 \r
484 }\r
485 /*****************************************************************\r
486  *  CREATE A MAC INTERFACE\r
487  ****************************************************************/\r
488 NETCP_CFG_MACIF_T  netcp_cfgCreateMacInterface(\r
489                   NETAPI_T  h,\r
490                   uint8_t *p_mac,\r
491                   int  iface_no, \r
492                   int switch_port, \r
493                   NETCP_CFG_ROUTE_HANDLE_T  route,\r
494                   NETCP_CFG_VLAN_T  vlan,  //future\r
495                   int state,  //0=down, 1=up  //ignored\r
496                   int * err\r
497                   )\r
498 {\r
499 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
500 nwalMacParam_t   MacInfo= {\r
501     0,      /* validParams */\r
502     0,      /* ifNum */\r
503     0,      /* vlanId      */\r
504     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },      /* Local mac */\r
505     NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */\r
506     NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */\r
507     CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */\r
508     QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */\r
509 };\r
510 \r
511 nwal_RetValue       retValue;\r
512 NetapiNwalTransInfo_t *pTransInfo;\r
513 nwal_TransID_t     trans_id;\r
514 \r
515     if ((!n) || (!p_mac)) {*err = NETAPI_ERR_BAD_INPUT; return -1;}\r
516     *err =0;\r
517 \r
518     pTransInfo = netapip_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
519     if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return -1;}\r
520     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC;\r
521     pTransInfo->netapi_handle = h; \r
522 \r
523     /* set up MacInfo */\r
524     memcpy(&MacInfo.macAddr,p_mac,6); \r
525     /* todo: vlan */\r
526     MacInfo.ifNum = switch_port;  /* todo: check for 0/1 relative*/\r
527 \r
528     if (route != NULL)\r
529     {\r
530         netcp_cfgp_build_route(route,&MacInfo.appRxPktFlowId, &MacInfo.appRxPktQueue);\r
531     }\r
532     pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;\r
533     retValue = nwal_setMacIface( ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
534                                   trans_id,\r
535                                   (nwal_AppId) (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no),\r
536                                   &MacInfo,\r
537                                   &pTransInfo->handle);\r
538     if(retValue !=  nwal_OK)\r
539     {\r
540         *err = NETAPI_ERR_NWAL_ERR0;\r
541         printf (">netcp cfg - ERROR: nwal_setMacIface returned Error Code %d\n",\r
542                     retValue);\r
543         pTransInfo->inUse = nwal_FALSE;\r
544         return -1;\r
545     }\r
546     //pTransInfo->inUse = nwal_FALSE;\r
547 \r
548     //wait here until its done since scheduler isn't running yet most likely..\r
549     // todo:  make this handled by scheduler poll later ??\r
550     if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
551     {\r
552         n->nwal_local.numPendingCfg++;\r
553         while ((volatile) n->nwal_local.numPendingCfg)\r
554         {\r
555             // if response is there, then this poll squirts out in the CTl poll callback, \r
556             // which handles the rest (including decrmenting #pending!!\r
557             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
558         }\r
559     }\r
560     printf (">netcp cfg: MAC i/f %d added\n", iface_no);\r
561     netcp_cfgp_insert_mac(&netapi_get_global()->nwal_context, \r
562                           p_mac, iface_no, state,vlan,\r
563                           (void *) pTransInfo->handle);\r
564     pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;\r
565     pTransInfo->inUse = nwal_FALSE;\r
566     return  (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no);\r
567 }\r
568 \r
569 \r
570 /*****************************************************************/\r
571 /***************Delete a mac interface****************************/\r
572 /*****************************************************************/\r
573 void netcp_cfgDelMac(NETAPI_T h,int iface_no,  int *err)\r
574 {\r
575     nwal_RetValue ret;\r
576     NetapiNwalTransInfo_t *pTransInfo;\r
577     nwal_TransID_t     trans_id;\r
578     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
579     void * ifHandle;\r
580 \r
581     //get the nwal handle assoicated with this iface\r
582     ifHandle = netcp_cfgp_get_mac_handle(&netapi_get_global()->nwal_context, iface_no );\r
583     if(!ifHandle) \r
584             {*err = NETAPI_ERR_BAD_INPUT; return ;}\r
585     *err =0;\r
586     \r
587     //get a transaction id\r
588     pTransInfo = netapip_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
589     if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return ;}\r
590     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC;\r
591     pTransInfo->netapi_handle = h;\r
592     //issue request\r
593     ret = nwal_delMacIface(\r
594                 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
595                 trans_id,\r
596                 ifHandle);\r
597     if(ret !=  nwal_OK)\r
598     {\r
599         *err = NETAPI_ERR_NWAL_ERR0;\r
600         printf (">netcp cfg - ERROR: nwal_delMacIface returned Error Code %d\n",\r
601                     ret);\r
602         pTransInfo->inUse = nwal_FALSE;\r
603         return ;\r
604     }\r
605     //wait here until its done since scheduler isn't running yet most likely..\r
606     // todo:  make this handled by scheduler poll later ??\r
607     if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
608     {\r
609         n->nwal_local.numPendingCfg++;\r
610         while ((volatile) n->nwal_local.numPendingCfg)\r
611         {\r
612             // if response is there, then this poll squirts out in the CTl poll callback, \r
613             // which handles the rest (including decrmenting #pending!!\r
614             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
615         }\r
616     }\r
617     printf (">netcp cfg: MAC i/f %d deleted\n",iface_no);\r
618     pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;\r
619     pTransInfo->inUse = nwal_FALSE;\r
620     //zap the entry\r
621     netcp_cfgp_delete_mac(&netapi_get_global()->nwal_context,  iface_no);\r
622     return ;\r
623 }\r
624 \r
625 \r
626 /*****************************************************************/\r
627 /***************Add IP to MAC interface (internal)****************/\r
628 /*****************************************************************/\r
629 static NETCP_CFG_IP_T  netcp_cfgAddIpInternal(\r
630                   NETAPI_T  h,\r
631                   int  iface_no,\r
632                   nwal_IpType ipType,\r
633                   nwalIpAddr_t  * ip_addr,\r
634                   nwalIpOpt_t * ip_qualifiers,\r
635                   NETCP_CFG_ROUTE_HANDLE_T  route,  //NULL for default\r
636                   int * err,\r
637                   int  flag) //TRUE: add IP to iface.  False: add IP as part of classifier\r
638 {\r
639 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
640 void * n_handle;\r
641 nwalIpParam_t    nwalIpParam= {\r
642     pa_IPV4,      /* IP Type */\r
643     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Dest IP */\r
644     { 0x0,0,0,0},/* IP Options */\r
645     NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */\r
646     NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */\r
647     CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */\r
648     QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */\r
649 };\r
650 nwal_RetValue       retValue;\r
651 NetapiNwalTransInfo_t *pTransInfo;\r
652 nwal_TransID_t     trans_id;\r
653 int ip_slot=-1;\r
654 NETCP_CFG_IP_T ip_rule_id;\r
655 NETCP_CFG_IP_T temp;\r
656 \r
657      //verify that iface has been configurred \r
658      if ((iface_no<0) || (iface_no>= TUNE_NETAPI_MAX_INTERFACES)) {*err = NETAPI_ERR_BAD_INPUT; return -1;}\r
659 \r
660      if(netapi_get_global()->nwal_context.interfaces[iface_no].in_use)\r
661      {\r
662         n_handle =  netapi_get_global()->nwal_context.interfaces[iface_no].nwal_handle;\r
663      }\r
664      else\r
665      {\r
666         *err = NETAPI_ERR_BAD_INPUT;\r
667         return -1;\r
668      }\r
669 \r
670      if (flag) //if adding IP to MAC then reserve a slot to save info\r
671      {\r
672          //find free slot for IP & reserve\r
673           ip_slot= netcp_cfgp_find_ip_slot(&netapi_get_global()->nwal_context, \r
674                                    iface_no);\r
675           if (ip_slot <0) \r
676           {\r
677                 *err= NETAPI_ERR_NOMEM;  //no room \r
678                 return -1;\r
679           }\r
680      }\r
681 \r
682      //get a transaction object for config action\r
683     pTransInfo = netapip_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
684     if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return -1;}\r
685     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;\r
686     pTransInfo->netapi_handle = h;\r
687 \r
688      //build nwalIpParam\r
689      memcpy(&nwalIpParam.locIpAddr,ip_addr, sizeof(nwalIpAddr_t));\r
690      nwalIpParam.ipType=ipType;\r
691      if(route)\r
692      {\r
693         netcp_cfgp_build_route(route,&nwalIpParam.appRxPktFlowId, &nwalIpParam.appRxPktQueue);\r
694      } \r
695      else{} //use nwal defaults\r
696      if (ip_qualifiers)\r
697         memcpy(&nwalIpParam.ipOpt,ip_qualifiers, sizeof(nwalIpOpt_t)); \r
698      else\r
699         memset(&nwalIpParam.ipOpt,0, sizeof(nwalIpOpt_t));\r
700 \r
701      //build the rule id that will be returned when a packet matches \r
702      if (flag)\r
703         ip_rule_id = NETAPI_NETCP_MATCH_GENERIC_IP | iface_no | ((ip_slot&&0xff)<<8);\r
704      else\r
705         ip_rule_id = (NETAPI_NETCP_MATCH_CLASS_L3 | iface_no);\r
706 \r
707      //perform config action\r
708      pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;\r
709      retValue = nwal_setIPAddr(   netapi_get_global()->nwal_context.nwalInstHandle,\r
710                                   trans_id,\r
711                                   (nwal_AppId) (ip_rule_id),\r
712                                   n_handle,\r
713                                   &nwalIpParam,\r
714                                   &pTransInfo->handle);\r
715 \r
716     if(retValue !=  nwal_OK)\r
717     {\r
718         *err = NETAPI_ERR_NWAL_ERR0;\r
719         printf (">netcp cfg: nwal_setIP returned Error Code %d\n",\r
720                     retValue);\r
721         pTransInfo->inUse = nwal_FALSE;\r
722         //zap the entry\r
723         if (flag)\r
724         {\r
725                 netcp_cfgp_delete_ip(&netapi_get_global()->nwal_context,\r
726                          iface_no,\r
727                          ip_slot);\r
728         }\r
729         return -1;\r
730     }\r
731     //wait here until its done since scheduler isn't running yet most likely..\r
732     // todo:  make this handled by scheduler poll later ??\r
733     if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
734     {\r
735         n->nwal_local.numPendingCfg++;\r
736         while ((volatile) n->nwal_local.numPendingCfg)\r
737         {\r
738             // if response is there, then this poll squirts out in the CTl poll callback, \r
739             // which handles the rest (including decrmenting #pending!!\r
740             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
741         }\r
742     }\r
743     if (flag)\r
744     {\r
745         printf (">netcp cfg: IP added to interface %d (slot%d)\n", iface_no, ip_slot);\r
746         netcp_cfgp_insert_ip(&netapi_get_global()->nwal_context, ipType, \r
747                           ip_addr, ip_qualifiers, iface_no, ip_slot,\r
748                           pTransInfo->handle);\r
749     }\r
750     pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;\r
751     temp = (NETCP_CFG_IP_T) pTransInfo->handle;\r
752     pTransInfo->inUse = nwal_FALSE;\r
753     return  (flag ? ip_rule_id:  temp);\r
754 }\r
755 /*****************************************************************/\r
756 /***************Add IP to MAC interface **************************/\r
757 /*****************************************************************/\r
758 NETCP_CFG_IP_T  netcp_cfgAddIp(\r
759                   NETAPI_T  h,\r
760                   int  iface_no,\r
761                   nwal_IpType ipType,\r
762                   nwalIpAddr_t  * ip_addr,\r
763                   nwalIpOpt_t * ip_qualifiers,\r
764                   NETCP_CFG_ROUTE_HANDLE_T  route,  //NULL for default\r
765                   int * err\r
766                   )\r
767 {\r
768         return netcp_cfgAddIpInternal(\r
769                 h, iface_no, ipType, ip_addr, ip_qualifiers, route, err, \r
770                 1);\r
771 }\r
772 \r
773 /*****************************************************************/\r
774 /***************Delete an attached IP*****************************/\r
775 /*****************************************************************/\r
776 static void netcp_cfgDelIpInternal(NETAPI_T h, int iface_no,  nwal_IpType ipType,\r
777                   nwalIpAddr_t  * ip_addr,\r
778                   nwalIpOpt_t * ip_qualifiers, \r
779                   NETCP_CFG_IP_T  ip_rule_id,\r
780                   int *err, \r
781                   void * handle,   /* if flag==0, handle must be valid */\r
782                   int flag)        /* flag==0 => delete IP rule that was part of classifier, not interface */\r
783 {\r
784     nwal_RetValue ret;\r
785     NetapiNwalTransInfo_t *pTransInfo;\r
786     nwal_TransID_t     trans_id;\r
787     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
788     void * ifHandle;\r
789     int ip_slot = (ip_rule_id>>8)&0xff;\r
790 \r
791     //get the nwal handle assoicated with this ip   \r
792     if (flag)\r
793     {\r
794         ifHandle = netcp_cfgp_get_ip_handle(\r
795           &netapi_get_global()->nwal_context, iface_no,\r
796           ip_slot );\r
797     }\r
798     else \r
799     {\r
800         ifHandle = handle;\r
801     }\r
802     if(!ifHandle)\r
803             {*err = NETAPI_ERR_BAD_INPUT; return ;}\r
804     *err =0;\r
805 \r
806     //get a transaction id\r
807     pTransInfo = netapip_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
808     if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return ;}\r
809     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;\r
810     pTransInfo->netapi_handle = h;\r
811     //issue request\r
812     ret = nwal_delIPAddr(\r
813                 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
814                 trans_id,\r
815                 ifHandle);\r
816     if(ret !=  nwal_OK)\r
817     {\r
818         *err = NETAPI_ERR_NWAL_ERR0;\r
819         printf (">netcp cfg - ERROR: nwal_delMacIface returned Error Code %d\n",\r
820                     ret);\r
821         pTransInfo->inUse = nwal_FALSE;\r
822         return ;\r
823     }\r
824     //wait here until its done since scheduler isn't running yet most likely..\r
825     // todo:  make this handled by scheduler poll later ??\r
826     if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
827     {\r
828        n->nwal_local.numPendingCfg++;\r
829         while ((volatile) n->nwal_local.numPendingCfg)\r
830         {\r
831             // if response is there, then this poll squirts out in the CTl poll callback, \r
832             // which handles the rest (including decrmenting #pending!!\r
833             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
834         }\r
835     }\r
836     if (flag)\r
837         printf (">netcp cfg: attached IP deleted\n");\r
838     else\r
839         printf (">netcp cfg: Classifier IP rule deleted\n");\r
840     pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;\r
841     pTransInfo->inUse = nwal_FALSE;\r
842 \r
843     //zap the entry\r
844     if (flag)\r
845         netcp_cfgp_delete_ip(&netapi_get_global()->nwal_context,  \r
846                          iface_no,\r
847                          ip_slot);\r
848     return ;\r
849 }\r
850 \r
851 /*****************************************************************/\r
852 /***************Delete an attached IP*****************************/\r
853 /*****************************************************************/\r
854 void netcp_cfgDelIp(NETAPI_T h, int iface_no,  nwal_IpType ipType,\r
855                   nwalIpAddr_t  * ip_addr,\r
856                   nwalIpOpt_t * ip_qualifiers,\r
857                   NETCP_CFG_IP_T  ip_rule_id,\r
858                   int *err)\r
859 {\r
860         netcp_cfgDelIpInternal( h, iface_no, ipType,\r
861                   ip_addr, ip_qualifiers, ip_rule_id,\r
862                   err, NULL, 1);\r
863         return;\r
864 }\r
865 \r
866 \r
867 /**\r
868  * @def netcp_cfgAddClass\r
869  * @brief  add a classifier rule into NETCP\r
870  **/\r
871 NETCP_CFG_CLASS_T netcp_cfgAddClass(NETAPI_T h,\r
872                                       NETCP_CFG_CLASSIFIER_T *p_class,\r
873                                       NETCP_CFG_ROUTE_HANDLE_T route,\r
874                                       int action, int * err)\r
875 {\r
876 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
877 void * l3_handle=NULL;  //ip handle\r
878 nwal_RetValue       retValue;\r
879 NetapiNwalTransInfo_t *pTransInfo;\r
880 nwal_TransID_t     trans_id;\r
881 int class_slot=-1;\r
882 int iface_no;\r
883 int ip_slot=-1;\r
884 NETCP_CFG_CLASS_T  classHandle;  //returned by us\r
885 nwal_appProtoType_t proto;\r
886 nwalLocConnCfg_t tempCfg={\r
887 0,  //nwal_handle: to be filled in\r
888 {0}, // l4 ports: to be filled in\r
889 0,  //core id (NA)\r
890 0, //action\r
891 CPPI_PARAM_NOT_SPECIFIED, //flow id\r
892 QMSS_PARAM_NOT_SPECIFIED, //dest queue\r
893 };\r
894 \r
895 if(!p_class) { *err=NETAPI_ERR_BAD_INPUT; return -1;}\r
896 switch(p_class->classType)\r
897 {\r
898 default:\r
899         printf(">netcp_cfg : classifier type %d not supported\n",p_class->classType);\r
900         break;\r
901 case(NETCP_CFG_CLASS_TYPE_L3_L4):\r
902 case(NETCP_CFG_CLASS_TYPE_L4):\r
903         //assume just type l4 only (L2, L3 defined by iface, l3 id )\r
904         iface_no = p_class->u.c_l4.iface;\r
905         if (p_class->classType== NETCP_CFG_CLASS_TYPE_L4)\r
906         { \r
907                 ip_slot = (p_class->u.c_l4.ip>>8)&0xff;\r
908         }\r
909 \r
910          //verify that iface has been configured \r
911         if(!netapi_get_global()->nwal_context.interfaces[iface_no].in_use)\r
912         {\r
913                 *err = NETAPI_ERR_BAD_INPUT;\r
914                 return -1;\r
915         }\r
916 \r
917         if (p_class->classType== NETCP_CFG_CLASS_TYPE_L4)\r
918         {\r
919              //verify that ip has been configured and get its handle\r
920              l3_handle = netcp_cfgp_get_ip_handle(\r
921                           &netapi_get_global()->nwal_context, iface_no,\r
922                           ip_slot );\r
923         }\r
924         else\r
925         {\r
926              nwalIpParam_t tempParam={\r
927     pa_IPV4,      /* IP Type */\r
928     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Dest IP */\r
929     { 0x0,0,0,0},/* IP Options */\r
930     NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */\r
931     NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */\r
932     CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */\r
933     QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */\r
934         };\r
935                 //build nwalIpParam\r
936                 memcpy(&tempParam.locIpAddr,p_class->u.c_l3_l4.ip_addr, sizeof(nwalIpAddr_t));\r
937                 tempParam.ipType=p_class->u.c_l3_l4.ipType;\r
938             //use nwal defauls for route\r
939             if (p_class->u.c_l3_l4.ip_qualifiers)\r
940                         memcpy(&tempParam.ipOpt,p_class->u.c_l3_l4.ip_qualifiers, sizeof(nwalIpOpt_t));\r
941              else\r
942                         memset(&tempParam.ipOpt,0, sizeof(nwalIpOpt_t));\r
943 \r
944 \r
945              //find if we have a matching L3 handle for IP classifier; if not create it\r
946              retValue =  nwal_getIPAddr (((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
947                                 &tempParam,\r
948                                 netcp_cfgp_get_mac_handle(&netapi_get_global()->nwal_context, iface_no ),\r
949                                 &l3_handle); \r
950              if (retValue != nwal_TRUE) \r
951              {\r
952                 int ret;\r
953                 //**NEW IP RULE  \r
954                 //need to attach this IP RULE to the MAC\r
955                 l3_handle= (void *) netcp_cfgAddIpInternal(\r
956                   h, iface_no, \r
957                   p_class->u.c_l3_l4.ipType,\r
958                   p_class->u.c_l3_l4.ip_addr,\r
959                   p_class->u.c_l3_l4.ip_qualifiers,\r
960                   p_class->u.c_l3_l4.p_fail_route,\r
961                   &ret,\r
962                   FALSE);\r
963                  if(!ret)\r
964                  {\r
965                         l3_handle=NULL;\r
966                  }\r
967              }\r
968         }         \r
969         if(!l3_handle)\r
970             {*err = NETAPI_ERR_BAD_INPUT; return -1 ;}\r
971 \r
972 \r
973         //find free slot for CLASS & reserve\r
974         class_slot= netcp_cfgp_find_class_slot(&netapi_get_global()->nwal_context);\r
975         if(class_slot<0) {*err = NETAPI_ERR_NOMEM; return -1;}\r
976         classHandle = NETAPI_NETCP_MATCH_CLASS | (class_slot<<8) | (iface_no&0xff);\r
977         //build request from template\r
978         tempCfg.inHandle=l3_handle;\r
979         if (p_class->classType== NETCP_CFG_CLASS_TYPE_L4)\r
980         { \r
981                 memcpy(&tempCfg.appProto,&p_class->u.c_l4.appProto,sizeof(nwalAppProto_t));\r
982                 proto = p_class->u.c_l4.proto;\r
983         }\r
984         else\r
985         {\r
986                 memcpy(&tempCfg.appProto,&p_class->u.c_l3_l4.appProto,sizeof(nwalAppProto_t));\r
987                 proto = p_class->u.c_l3_l4.proto;\r
988         }\r
989         \r
990         tempCfg.matchAction = (action==NETCP_CFG_ACTION_TO_SW)  ? NWAL_MATCH_ACTION_HOST : NWAL_MATCH_ACTION_DISCARD;\r
991         if (route)\r
992         {\r
993                 netcp_cfgp_build_route(route,&tempCfg.appRxPktFlowId, &tempCfg.appRxPktQueue);\r
994         }\r
995 \r
996         //get a transaction id\r
997         pTransInfo = netapip_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
998         if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return -1 ;}\r
999         pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP; /* todo: fix this to TRANS_L4*/\r
1000         pTransInfo->netapi_handle = h;\r
1001         //issue request\r
1002         retValue = nwal_addConn(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
1003                             trans_id,\r
1004                             (nwal_AppId) classHandle,\r
1005                             proto,\r
1006                             &tempCfg,\r
1007                             NULL,\r
1008                             &pTransInfo->handle);\r
1009         if(retValue !=  nwal_OK)\r
1010         {\r
1011             *err = NETAPI_ERR_NWAL_ERR0;\r
1012             printf (">netcp cfg - ERROR: nwal_addConn returned Error Code %d\n",\r
1013                     retValue);\r
1014             pTransInfo->inUse = nwal_FALSE;\r
1015             netcp_cfgp_delete_class(&netapi_get_global()->nwal_context, class_slot);\r
1016             return -1;\r
1017         }\r
1018         //wait here until its done since scheduler isn't running yet most likely..\r
1019         // todo:  make this handled by scheduler poll later ??\r
1020         if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
1021         {\r
1022              n->nwal_local.numPendingCfg++;\r
1023              while ((volatile) n->nwal_local.numPendingCfg)\r
1024              {\r
1025                 // if response is there, then this poll squirts out in the CTl poll callback, \r
1026                 // which handles the rest (including decrmenting #pending!!\r
1027                 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
1028              }\r
1029          }\r
1030          printf (">netcp cfg: L4 Classifer added to interface %d ip %d (slot%d)\n", iface_no, ip_slot, class_slot);\r
1031          netcp_cfgp_insert_class(&netapi_get_global()->nwal_context, \r
1032                                    class_slot,\r
1033                                  p_class->classType, \r
1034                                   NULL,  //L2 we have\r
1035                                   (p_class->classType== NETCP_CFG_CLASS_TYPE_L3_L4? l3_handle : NULL),\r
1036                                   pTransInfo->handle);\r
1037          pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;\r
1038          return classHandle;\r
1039 } //end switch\r
1040 return -1;\r
1041 }\r
1042 \r
1043 //delete classifier\r
1044 void netcp_cfgDelClass(NETAPI_T h,\r
1045                          NETCP_CFG_CLASS_T classId,\r
1046                          int *err)\r
1047 {\r
1048 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
1049 void * L4_handle;  //class handle -> L4\r
1050 void * L3_handle;  //class handle -> L3\r
1051 nwal_RetValue       retValue;\r
1052 NetapiNwalTransInfo_t *pTransInfo;\r
1053 nwal_TransID_t     trans_id;\r
1054 int class_slot=-1;\r
1055 //int iface;\r
1056 //int ip_slot;\r
1057 \r
1058         class_slot = (classId>>8)&0xffff;\r
1059         L4_handle=netcp_cfgp_get_l4_handle(\r
1060                         &netapi_get_global()->nwal_context,\r
1061                         class_slot );\r
1062         if(!L4_handle)  {*err = NETAPI_ERR_BAD_INPUT; return ;}\r
1063         L3_handle = netcp_cfgp_get_l3_handle(\r
1064                         &netapi_get_global()->nwal_context,\r
1065                         class_slot );\r
1066         /* l3 handle might be NULL,, depending on type of classifier */\r
1067 \r
1068         netcp_cfgp_delete_class(\r
1069                         &netapi_get_global()->nwal_context,\r
1070                         class_slot );\r
1071         //get a transaction id\r
1072         pTransInfo = netapip_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
1073         if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return  ;}\r
1074         pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;\r
1075         pTransInfo->netapi_handle = h;\r
1076         //issue request for L4\r
1077         retValue = nwal_delConn(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
1078                             trans_id,\r
1079                             L4_handle);\r
1080         if(retValue !=  nwal_OK)\r
1081         {\r
1082             *err = NETAPI_ERR_NWAL_ERR0;\r
1083             printf (">netcp cfg - ERROR: nwal_delConn returned Error Code %d\n",\r
1084                     retValue);\r
1085             pTransInfo->inUse = nwal_FALSE;\r
1086             return ;  /* todo: what about the L3? */\r
1087         }\r
1088         //wait here until its done since scheduler isn't running yet most likely..\r
1089         // todo:  make this handled by scheduler poll later ??\r
1090         if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
1091         {\r
1092              n->nwal_local.numPendingCfg++;\r
1093              while ((volatile) n->nwal_local.numPendingCfg)\r
1094              {\r
1095                 // if response is there, then this poll squirts out in the CTl poll callback, \r
1096                 // which handles the rest (including decrmenting #pending!!\r
1097                 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
1098              }\r
1099          }\r
1100          printf (">netcp cfg: Classifer deleted\n");\r
1101          pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;\r
1102          pTransInfo->inUse = nwal_FALSE;\r
1103 \r
1104          /* delete L3 if we have to */\r
1105          if (L3_handle)\r
1106          {\r
1107              netcp_cfgDelIpInternal( h, 0, 0,\r
1108                   NULL, NULL, 0,\r
1109                   err, L3_handle,  0);\r
1110          }\r
1111          return ;\r
1112 }\r
1113 \r
1114 \r
1115 /*--------------flow management--------*/\r
1116 // ADD A Flow\r
1117 NETCP_CFG_FLOW_HANDLE_T netcp_cfgAddFlow(NETAPI_T h,\r
1118                                             int n,\r
1119                                             Pktlib_HeapHandle handles[],\r
1120                                             int sizes[],\r
1121                                             int * err )\r
1122 {\r
1123   Cppi_RxFlowCfg  rxFlowCfg;\r
1124   Uint8           isAlloc;\r
1125   Qmss_QueueHnd   rxBufQ[TUNE_NETAPI_MAX_BUF_POOLS_IN_FLOW];\r
1126   Uint32          rxBufSize[TUNE_NETAPI_MAX_BUF_POOLS_IN_FLOW];\r
1127   int             i;\r
1128   Cppi_FlowHnd FlowHnd;\r
1129   int  slot;\r
1130   NETCP_CFG_FLOW_HANDLE_T retVal;\r
1131 \r
1132   *err= 0;  /* ok */\r
1133   //get a slot to save new flow\r
1134   slot = netcp_cfgp_find_flow_slot(&netapi_get_global()->nwal_context);\r
1135   if (slot<0) { *err= NETAPI_ERR_NOMEM;  return NULL; }\r
1136 \r
1137   //configure flow\r
1138   memset(&rxFlowCfg,0,sizeof(Cppi_RxFlowCfg));\r
1139   for (i = 0; i < TUNE_NETAPI_MAX_BUF_POOLS_IN_FLOW; i++)\r
1140   {\r
1141       if (i >= n)\r
1142       {\r
1143           rxBufQ[i] = 0;\r
1144           rxBufSize[i] = 0;\r
1145       } else\r
1146       {\r
1147           rxBufQ[i] =   Pktlib_getInternalHeapQueue(handles[i]);\r
1148           //todo: verity sizes< heapsize\r
1149           //todo: verify order\r
1150           rxBufSize[i]= sizes[i];\r
1151       }\r
1152       if (i && (rxBufQ[i] <= 0))\r
1153       {\r
1154           rxBufQ[i] = rxBufQ[i-1];\r
1155           rxBufSize[i] = 0;\r
1156       }\r
1157   }\r
1158   /* Configure Rx flow */\r
1159   rxFlowCfg.flowIdNum      = CPPI_PARAM_NOT_SPECIFIED;\r
1160   rxFlowCfg.rx_dest_qnum   = 100;   //DANGEROUS>  TODO PUT VALID Q HERE\r
1161   rxFlowCfg.rx_dest_qmgr   = 0;\r
1162   rxFlowCfg.rx_sop_offset  = 0;\r
1163   rxFlowCfg.rx_ps_location = Cppi_PSLoc_PS_IN_DESC;\r
1164   rxFlowCfg.rx_desc_type   = Cppi_DescType_HOST;\r
1165   rxFlowCfg.rx_error_handling = 0;\r
1166 \r
1167   rxFlowCfg.rx_psinfo_present = 1;\r
1168   rxFlowCfg.rx_einfo_present  = 1;\r
1169 \r
1170   rxFlowCfg.rx_dest_tag_lo = 0;\r
1171   rxFlowCfg.rx_dest_tag_hi = 0;\r
1172   rxFlowCfg.rx_src_tag_lo  = 0;\r
1173   rxFlowCfg.rx_src_tag_hi  = 0;\r
1174 \r
1175   rxFlowCfg.rx_size_thresh0_en = rxBufSize[1] ? 1 : 0;\r
1176   rxFlowCfg.rx_size_thresh1_en = rxBufSize[2] ? 1 : 0;\r
1177   rxFlowCfg.rx_size_thresh2_en = rxBufSize[3] ? 1 : 0;\r
1178 \r
1179   rxFlowCfg.rx_dest_tag_lo_sel = 0;\r
1180   rxFlowCfg.rx_dest_tag_hi_sel = 0;\r
1181   rxFlowCfg.rx_src_tag_lo_sel  = 0;\r
1182   rxFlowCfg.rx_src_tag_hi_sel  = 0;\r
1183 \r
1184   rxFlowCfg.rx_fdq1_qnum = rxBufQ[1];\r
1185   rxFlowCfg.rx_fdq1_qmgr = 0;\r
1186   rxFlowCfg.rx_fdq2_qnum = rxBufQ[2];\r
1187 \r
1188   rxFlowCfg.rx_fdq2_qmgr = 0;\r
1189   rxFlowCfg.rx_fdq3_qnum = rxBufQ[3];\r
1190 \r
1191   rxFlowCfg.rx_fdq3_qmgr = 0;\r
1192 \r
1193   rxFlowCfg.rx_size_thresh0 = rxBufSize[1] ? rxBufSize[0] : 0;\r
1194   rxFlowCfg.rx_size_thresh1 = rxBufSize[2] ? rxBufSize[1] : 0;\r
1195   rxFlowCfg.rx_size_thresh2 = rxBufSize[3] ? rxBufSize[2] : 0;\r
1196 \r
1197   rxFlowCfg.rx_fdq0_sz0_qnum = rxBufQ[0];\r
1198   rxFlowCfg.rx_fdq0_sz0_qmgr = 0;\r
1199   rxFlowCfg.rx_fdq0_sz1_qnum = rxBufQ[1];\r
1200   rxFlowCfg.rx_fdq0_sz1_qmgr = 0;\r
1201   rxFlowCfg.rx_fdq0_sz2_qnum = rxBufQ[2];\r
1202   rxFlowCfg.rx_fdq0_sz2_qmgr = 0;\r
1203   rxFlowCfg.rx_fdq0_sz3_qnum = rxBufQ[3];\r
1204   rxFlowCfg.rx_fdq0_sz3_qmgr = 0;\r
1205 \r
1206  {\r
1207   //todo: replace this with a nwal call to get global cntx info\r
1208   Cppi_CpDmaInitCfg cpdmaCfg;\r
1209   memset(&cpdmaCfg,0,sizeof(Cppi_CpDmaInitCfg));\r
1210   cpdmaCfg.dmaNum   = Cppi_CpDma_PASS_CPDMA;\r
1211   FlowHnd =\r
1212       Cppi_configureRxFlow (Cppi_open (&cpdmaCfg), &rxFlowCfg, &isAlloc);\r
1213 }\r
1214   if (FlowHnd == NULL)\r
1215   {\r
1216       *err= NETAPI_ERR_NORES;\r
1217       netcp_cfgp_delete_flow(&netapi_get_global()->nwal_context, slot);\r
1218       return (NULL);\r
1219   }\r
1220 \r
1221   //update slot\r
1222   retVal = netcp_cfgp_insert_flow(&netapi_get_global()->nwal_context, slot, (void*) FlowHnd);\r
1223   printf(">netcp cfg:  flow %d created\n",  ((NETCP_CFG_FLOW_T *) retVal)->flowid);\r
1224   return ( retVal);\r
1225 \r
1226 \r
1227 \r
1228 }\r
1229 \r
1230 //Delete a flow\r
1231 void netcp_cfgDelFlow(NETAPI_T h , NETCP_CFG_FLOW_HANDLE_T f , int * err)\r
1232 {\r
1233         int slot;\r
1234         void * handle;\r
1235         *err=0;\r
1236         /* find entry */\r
1237         slot = netcp_cfgp_find_flow(&netapi_get_global()->nwal_context, ((NETCP_CFG_FLOW_T *) f) ->flowid, &handle);\r
1238         if (slot<0) {*err = NETAPI_ERR_BAD_INPUT; return;}\r
1239 \r
1240         Cppi_closeRxFlow( (Cppi_FlowHnd) handle);\r
1241         netcp_cfgp_delete_flow(&netapi_get_global()->nwal_context, slot);\r
1242         printf(">netcp cfg:  flow %d deleted\n",  ((NETCP_CFG_FLOW_T *) f)->flowid);\r
1243         return;\r
1244 }\r
1245 \r
1246 \r
1247 /*************************************************************************/\r
1248 /*********************************INTERNAL*******************************/\r
1249 /************************************************************************/\r
1250 \r
1251 /***************************************************************\r
1252  ********************METCP CMD Reply Callback******************\r
1253  ***************************************************************/\r
1254 void netapi_NWALCmdCallBack (nwal_AppId        appHandle,\r
1255                           uint16_t            trans_id,\r
1256                           nwal_RetValue     ret)\r
1257 {\r
1258     NetapiNwalTransInfo_t * p_trans;\r
1259     NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL;\r
1260 \r
1261     if(trans_id == NWAL_TRANSID_SPIN_WAIT)\r
1262     {\r
1263         netapi_get_global()->nwal_context.numBogusTransIds++;\r
1264         return;\r
1265     }\r
1266 \r
1267     p_trans= &netapi_get_global()->nwal_context.transInfos[trans_id];\r
1268     p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;\r
1269 \r
1270     if(ret != nwal_OK)\r
1271     {\r
1272         printf (">netcp cfg : NWALCmdCallBack returned Error Code %d\n",\r
1273                     ret);\r
1274         //todo: atomic inc\r
1275         netapi_get_global()->nwal_context.numCmdFail++;\r
1276     }\r
1277     else\r
1278     {\r
1279         //todo: atomic inc\r
1280         netapi_get_global()->nwal_context.numCmdPass++;\r
1281         switch(p_trans->transType)\r
1282         {\r
1283             case NETAPI_NWAL_HANDLE_TRANS_MAC:\r
1284             {\r
1285                 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)\r
1286                 {\r
1287                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;\r
1288                 }\r
1289                 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
1290                 {\r
1291                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;\r
1292                 }\r
1293                 break;\r
1294             }\r
1295             case NETAPI_NWAL_HANDLE_TRANS_IP:\r
1296             {\r
1297                  if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)\r
1298                 {\r
1299                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;\r
1300                 }\r
1301                 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
1302                 {\r
1303                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;\r
1304                 }\r
1305                 break;\r
1306             }\r
1307             case NETAPI_NWAL_HANDLE_TRANS_PORT:\r
1308             {\r
1309                 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)\r
1310                 {\r
1311                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;\r
1312                 }\r
1313                 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
1314                 {\r
1315                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;\r
1316                 }\r
1317                 break;\r
1318             }\r
1319             case NETAPI_NWAL_HANDLE_TRANS_SA:\r
1320             {\r
1321                 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)\r
1322                 {\r
1323                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;\r
1324                 }\r
1325                 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
1326                 {\r
1327                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;\r
1328                 }\r
1329                 break;\r
1330             }\r
1331             case NETAPI_NWAL_HANDLE_TRANS_SA_POLICY:\r
1332             {\r
1333                 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)\r
1334                 {\r
1335                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;\r
1336                 }\r
1337                 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
1338                 {\r
1339                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;\r
1340                 }\r
1341                 break;\r
1342             }\r
1343             default:\r
1344             {\r
1345                 printf ("netcp cfg> Invalid transaction type %d for trans_id: %d\n",\r
1346                     p_trans->transType,trans_id);\r
1347                 break;\r
1348             }\r
1349         }\r
1350     }\r
1351 \r
1352     p_local->numPendingCfg--;\r
1353 \r
1354     if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_IDLE)\r
1355     {\r
1356         p_trans->inUse = nwal_FALSE;\r
1357     }\r
1358 \r
1359 }\r
1360 \r
1361 \r
1362 /*******************************************************/\r
1363 /**************stats reply callback**********************/\r
1364 /*******************************************************/\r
1365 void netapi_NWALCmdPaStatsReply (nwal_AppId        appHandle,\r
1366                               nwal_TransID_t    trans_id,\r
1367                               paSysStats_t      *stats)\r
1368 {\r
1369     NetapiNwalTransInfo_t * p_trans;\r
1370     NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL;\r
1371   \r
1372     if(trans_id == NWAL_TRANSID_SPIN_WAIT)\r
1373     {\r
1374         netapi_get_global()->nwal_context.numBogusTransIds++;\r
1375         return;\r
1376     }\r
1377 \r
1378     p_trans= &netapi_get_global()->nwal_context.transInfos[trans_id];\r
1379     p_trans->inUse = nwal_FALSE;\r
1380     p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;\r
1381 \r
1382     //save a local copy  of some stuff*/\r
1383     p_local->numL2PktsRecvd=stats->classify1.nPackets;\r
1384     p_local->numL3PktsRecvd=stats->classify1.nIpv4Packets;\r
1385 #if 0\r
1386     p_local->numL4PktsRecvd=stats->;\r
1387     p_local->numL4PktsSent=stats->;\r
1388     p_local->TxErrDrop=stats->;\r
1389 #endif\r
1390     //callout result to application !!\r
1391     if (p_local->stats_cb) (*p_local->stats_cb)(p_trans->netapi_handle,stats);\r
1392     \r
1393\r
1394 \r