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