]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/netapi.git/blob - ti/runtime/netapi/src/netcp_cfg.c
Implemented per core net_test stats, integration with latest version of HPLIB
[keystone-rtos/netapi.git] / ti / runtime / netapi / src / netcp_cfg.c
1 /**********************************************************
2  * file: netcp_cfg.c
3  * purpose: netcp configurations routines
4  **************************************************************
5  * FILE: netcp_cfg.c
6  * 
7  * DESCRIPTION:  netcp configuration main source file for user space transport
8  *               library
9  * 
10  * REVISION HISTORY:  rev 0.0.1 
11  *
12  *  Copyright (c) Texas Instruments Incorporated 2010-2011
13  * 
14  *  Redistribution and use in source and binary forms, with or without 
15  *  modification, are permitted provided that the following conditions 
16  *  are met:
17  *
18  *    Redistributions of source code must retain the above copyright 
19  *    notice, this list of conditions and the following disclaimer.
20  *
21  *    Redistributions in binary form must reproduce the above copyright
22  *    notice, this list of conditions and the following disclaimer in the 
23  *    documentation and/or other materials provided with the   
24  *    distribution.
25  *
26  *    Neither the name of Texas Instruments Incorporated nor the names of
27  *    its contributors may be used to endorse or promote products derived
28  *    from this software without specific prior written permission.
29  *
30  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
31  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
32  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
34  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
35  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
36  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
39  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
40  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42  ******************************************************/
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <unistd.h>
46 #include <string.h>
47 #include "netapi.h"
48 #include "netcp_cfg.h"
49 #include "netapi_loc.h"
51 /******************************************************************
52  ********************Utility*************************************
53 *******************************************************************/
56 //get a free transaction id
57 NetapiNwalTransInfo_t *  netapip_GetFreeTransInfo(NETAPI_GLOBAL_T *p_global, nwal_TransID_t *pTransId)
58 {
59          uint16_t    count=0;
61         count=0;
62         while(count < TUNE_NETAPI_MAX_NUM_TRANS)
63         {
64             if((p_global->nwal_context.transInfos[count].inUse) != nwal_TRUE)
65             {
66                 p_global->nwal_context.transInfos[count].inUse = nwal_TRUE;
67                 *pTransId = count;
68                 return(&p_global->nwal_context.transInfos[count]);
69             }
70             count++;
71         }
72          
73         /* trouble.  need to wait for one to free up*/
74         /* to do: handle this by forcing a poll of cntrl queue*/
75         printf(">netcp_cfg: trying to get free transaction slot but all full!!\n");
76         return NULL;
78 }
79 //internal: build route
80 void netcp_cfgp_build_route(NETCP_CFG_ROUTE_T * p_route, int16_t * p_flow,  Qmss_QueueHnd * p_q)
81 {
82     if (!p_route) return;
83     if (p_route->p_flow)  *p_flow= p_route->p_flow->flowid;
84     else *p_flow = CPPI_PARAM_NOT_SPECIFIED;
85     if (p_route->p_dest_q) *p_q = pktio_get_q(p_route->p_dest_q);
86     else *p_q=QMSS_PARAM_NOT_SPECIFIED;
87 }
88 /*-----------------------------------------------------------*/
89 /*----------------database management stuff-------------------*/
90 /*-----------------------------------------------------------*/
92 /*=====================Policies=============================*/
93 //internal: find a free slot for an SA 
94 int netcp_cfgp_find_policy_slot( NETAPI_NWAL_GLOBAL_CONTEXT_T *p, int tunnel)
95 {
96    int i;
97    if ((tunnel <0 ) || (tunnel >=TUNE_NETAPI_MAX_SA)) return -1;
99          //find a free entry
100    for(i=0;i<TUNE_NETAPI_MAX_POLICY;i++)
101    {
102        if (!p->policy[i].in_use)
103        {
104            p->policy[i].in_use = 2; //pending
105            p->policy[i].tunnel= tunnel; //save tunnel this is linked to 
106            return i;
107        }
108    }
109    return -1;
112 //internal: delete a policy from list 
113 void netcp_cfgp_delete_policy(
114          NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
115          int policy_slot )
117    if ((policy_slot <0 ) || (policy_slot >= TUNE_NETAPI_MAX_POLICY))
118    {
119         return ;
120    }
121    p->policy[policy_slot].in_use=0;
122    return;
125 //internal:  insert an policy into the list  
126 void netcp_cfgp_insert_policy(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
127                           int policy_slot,  //we 'reserved it already'
128                           void * handle)
130         p->policy[policy_slot].in_use=1;
131         p->policy[policy_slot].nwal_handle = handle;
132         return;
135 //internal: return nwal_handle for policy 
136 void *netcp_cfgp_get_policy( NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
137                           int policy_slot)
139    if ((policy_slot <0 ) || (policy_slot >= TUNE_NETAPI_MAX_POLICY)) return NULL;
140    if (!p->policy[policy_slot].in_use) return NULL;
141    return p->policy[policy_slot].nwal_handle;
146 /*======================SAs==================================*/
147 //internal: find a free slot for an SA 
148 int netcp_cfgp_find_sa_slot( NETAPI_NWAL_GLOBAL_CONTEXT_T *p, int iface)
149 {                                    
150    int i;
151    if (iface != NETCP_CFG_NO_INTERFACE)
152    {
153    if ((iface <0 ) || (iface >=TUNE_NETAPI_MAX_NUM_MAC)) return -1;
154    }
155          //find a free entry
156    for(i=0;i<TUNE_NETAPI_MAX_SA;i++)
157    {                       
158        if (!p->tunnel[i].in_use)
159        {
160            p->tunnel[i].in_use = 2; //pending
161            p->tunnel[i].iface= iface; //save iface
162            return i;
163        }
164    }
165    return -1;
167  //internal: delete an SAr from list 
168 void netcp_cfgp_delete_sa(
169          NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
170          int sa_slot )
172    if ((sa_slot <0 ) || (sa_slot >= TUNE_NETAPI_MAX_SA))
173    {
174         return ;
175    }
176    p->tunnel[sa_slot].in_use=0;
177    return;
180 //internal:  insert an SA into the list  
181 void netcp_cfgp_insert_sa(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
182                           int sa_slot,  //we 'reserved it already'
183                           int dir,
184                           int mode,
185                           void * temp1,
186                           void * temp2,
187                           void * handle_inflow,
188                           void * handle_sideband)
190         p->tunnel[sa_slot].in_use=1;
191         p->tunnel[sa_slot].inbound = dir;
192         p->tunnel[sa_slot].sa_mode = mode;
193         p->tunnel[sa_slot].sa_handle_inflow = handle_inflow;
194         p->tunnel[sa_slot].sa_handle_sideband = handle_sideband;
195         return;
198 //internal: return nwal_handles for SA   
199 void *netcp_cfgp_get_sa_handles( NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
200                           int sa_slot, void ** p_sideband)
202    if ((sa_slot <0 ) || (sa_slot >= TUNE_NETAPI_MAX_SA)) return NULL;
203    if (!p->tunnel[sa_slot].in_use) return NULL;
204    *p_sideband = p->tunnel[sa_slot].sa_handle_sideband;
205    return p->tunnel[sa_slot].sa_handle_inflow;
209 /*==============================fLOWS=============================*/
210 //internal: find a free slot for a flow 
211 static int netcp_cfgp_find_flow_slot( NETAPI_NWAL_GLOBAL_CONTEXT_T *p)
213    int i;
214          //find a free entry
215    for(i=0;i<TUNE_NETAPI_MAX_FLOWS;i++)
216    {
217        if (!p->flows[i].in_use)
218        {
219            p->flows[i].in_use = 2; //pending
220            return i;
221        }
222    }
223    return -1;
226 //internal: clear flow slot 
227 static void netcp_cfgp_delete_flow(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,int slot)
229    if ((slot >=0 ) && (slot < TUNE_NETAPI_MAX_FLOWS))
230    {
231         p->flows[slot].in_use = 0;
232    }
235 //internal:  insert a flow into flow slot
236 static NETCP_CFG_FLOW_HANDLE_T netcp_cfgp_insert_flow(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
237                           int slot,  //we 'reserved it already'
238                           void * handle)  //cppi flow handle. Save this for delete
240         p->flows[slot].in_use=1;
241         p->flows[slot].handle = handle;
242         p->flows[slot].flow.flowid  = Cppi_getFlowId(handle);
243         return (NETCP_CFG_FLOW_HANDLE_T) &p->flows[slot].flow;
246 //find entry matching the flowid.  return slot# and the cppi handle
247 static int netcp_cfgp_find_flow(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
248                           int flowid,  
249                           void ** handle) 
251 int i;
252    *handle=NULL;
253    for(i=0;i<TUNE_NETAPI_MAX_FLOWS;i++)
254    {
255        if ((p->flows[i].in_use)&&(p->flows[i].flow.flowid == flowid))
256        {
257            *handle = p->flows[i].handle;
258            return i;
259        }
260    }
261    return -1;
265 /*============================IP ADDRESSES==========================*/
267 //internal: find a free slot for IP rule 
268 static int netcp_cfgp_find_ip_slot(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
269                           int iface_no)
271    int i;
273    //find a free entry
274    for(i=0;i<TUNE_NETAPI_MAX_NUM_IP;i++)
275    {
276        if (!p->ips[i].in_use)
277        {
278            p->ips[i].in_use = 2; //pending
279            return i;
280        }
281    }
282    return -1;
286 //internal:  insert an IP address into iface
287 static void netcp_cfgp_insert_ip(NETAPI_NWAL_GLOBAL_CONTEXT_T *p, 
288                           nwal_IpType ipType,
289                           nwalIpAddr_t *ip_addr, 
290                           nwalIpOpt_t *ip_qualifiers, 
291                           int iface_no,
292                           int ip_slot,  //we 'reserved it already'
293                           void * handle)
295         p->ips[ip_slot].in_use=1;
296         memcpy(&p->ips[ip_slot].ip_addr, ip_addr, sizeof(nwalIpAddr_t));
297         if(ip_qualifiers)
298         memcpy(&p->ips[ip_slot].ip_qualifiers, ip_qualifiers, sizeof(nwalIpOpt_t));
299         else
300         memset(&p->ips[ip_slot].ip_qualifiers, 0, sizeof(nwalIpOpt_t));
301         p->ips[ip_slot].ip_type = ipType;
302         p->ips[ip_slot].nwal_handle = handle;
303         return;
307 //internal: free IP slot associated with ip address 
308 static void netcp_cfgp_delete_ip(
309          NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
310          int iface_no,
311          int ip_slot )
313    if ((ip_slot <0)||(ip_slot>TUNE_NETAPI_MAX_NUM_IP)) return ;
314    p->ips[ip_slot].in_use=0;
315    return;
319 //internal: get IP handle associated with ip address 
320 static void *netcp_cfgp_get_ip_handle(
321          NETAPI_NWAL_GLOBAL_CONTEXT_T *p, 
322          int iface_no,
323          int ip_slot )
325    if ((ip_slot <0)||(ip_slot>=TUNE_NETAPI_MAX_NUM_IP)) return NULL;
326    if (!p->ips[ip_slot].in_use) return NULL;
327    return (void *) p->ips[ip_slot].nwal_handle;
330 /*==========================MAC INTERFACES======================*/
331 //internal: insert interface info into global context
332 static void netcp_cfgp_insert_mac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p, unsigned char * p_mac,
333                            int iface_no, int state, NETCP_CFG_VLAN_T vlan, void * handle)
335    if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_NUM_MAC))
336    {
337         memset(&p->interfaces[iface_no],0,sizeof(NETCP_INTERFACE_T));
338         p->interfaces[iface_no].in_use = 1;
339         memcpy(&p->interfaces[iface_no].mac[0], p_mac,6);
340         p->interfaces[iface_no].state = state;
341         //todo p->interfaces[iface_no].vlan = vlan;
342         p->interfaces[iface_no].nwal_handle = handle; //save handle assoicated with this rule
343    }
344    else printf(">netcp_cfg insert interface # out of range %d\n",iface_no);
348 //internal: get handle associated with interface
349 void* netcp_cfgp_get_mac_handle(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,int iface_no)
351    if (iface_no == NETCP_CFG_NO_INTERFACE) return NULL;
352    if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_NUM_MAC))
353    {
354         return NULL;
355    }
356    else if ( p->interfaces[iface_no].in_use)
357    {
358      return (void *) p->interfaces[iface_no].nwal_handle;
359    }
360    //no valid entry in slot
361    return NULL;
363 //internal: clear inteface entry
364 static void netcp_cfgp_delete_mac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,int iface_no)
366    if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_NUM_MAC))
367    {
368         p->interfaces[iface_no].in_use = 0;
369    }
373 /*========================CLASSIFIERS==========================*/
374 //internal: find a free slot for classifier rule
375 static int netcp_cfgp_find_class_slot( NETAPI_NWAL_GLOBAL_CONTEXT_T *p)
377    int i;
378          //find a free entry
379    for(i=0;i<TUNE_NETAPI_MAX_CLASSIFIERS;i++)
380    {
381        if (!p->classi[i].in_use)
382        {
383            p->classi[i].in_use = 2; //pending
384            return i;
385        }
386    }
387    return -1;
390  //internal: delete a classifer from list 
391 static void netcp_cfgp_delete_class(
392          NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
393          int class_slot )
395    if ((class_slot <0 ) || (class_slot >= TUNE_NETAPI_MAX_CLASSIFIERS))
396    {
397         return ;
398    }
399    p->classi[class_slot].in_use=0;
400    return;
403 //internal:  insert a classifier into list 
404 static void netcp_cfgp_insert_class(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
405                           int class_slot,  //we 'reserved it already'
406                           int class_type,
407                           void * L2_handle,
408                           void * L3_handle,
409                           void * L4_handle)
411         p->classi[class_slot].in_use=1;
412         p->classi[class_slot].nwal_L2_handle = L2_handle;
413         p->classi[class_slot].nwal_L3_handle = L3_handle;
414         p->classi[class_slot].nwal_L4_handle = L4_handle;
415         p->classi[class_slot].class_type = class_type;
416         return;
419 //internal: return L4 nwal_handle for class
420 static void *netcp_cfgp_get_l4_handle( NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
421                           int class_slot)
423    if ((class_slot <0 ) || (class_slot >= TUNE_NETAPI_MAX_CLASSIFIERS)) return NULL;
424    if (!p->classi[class_slot].in_use) return NULL;
425    return p->classi[class_slot].nwal_L4_handle;
428 //internal: return L3 nwal_handle for class
429 static void *netcp_cfgp_get_l3_handle( NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
430                           int class_slot)
432    if ((class_slot <0 ) || (class_slot >= TUNE_NETAPI_MAX_CLASSIFIERS)) return NULL;
433    if (!p->classi[class_slot].in_use) return NULL;
434    return p->classi[class_slot].nwal_L3_handle;
438 /***********************************************************************************/
439 /****************************************API****************************************/
440 /***********************************************************************************/
443 /*****************************************************************
444  *  Queury Stats
445  ****************************************************************/
446 void netcp_cfgReqStats(NETAPI_T  h, NETCP_CFG_STATS_CB cb, int doClear, int *err) 
448 nwal_RetValue ret;
449 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
450 NetapiNwalTransInfo_t *pTransInfo;
451 nwal_TransID_t     transId;
452 if ((!n) || (!cb)) {*err = NETAPI_ERR_BAD_INPUT; return ;}
453 *err =0;
456 pTransInfo = netapip_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &transId);
457 if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return ;}
458 pTransInfo->transType = NETAPI_NWAL_HANDLE_STAT_REQUEST;
459 pTransInfo->netapi_handle = h;
460 n->nwal_local.stats_cb = cb;
461 ret = nwal_getPAStats( ((NETAPI_GLOBAL_T *) n->global)->nwal_context.nwalInstHandle,
462                           transId,
463                           NULL,
464                           doClear);
465 if(ret !=  nwal_OK)
467    pTransInfo->inUse = nwal_FALSE;
468    *err = NETAPI_ERR_BUSY;  //no resources??
469    printf("> netcp_cfg reqStats failed, err=%d\n",ret);
473 /*****************************************************************
474  *  CREATE A MAC INTERFACE
475  ****************************************************************/
476 NETCP_CFG_MACIF_T  netcp_cfgCreateMacInterface(
477                   NETAPI_T  h,
478                   uint8_t *p_mac,
479                   int  iface_no, 
480                   int switch_port, 
481                   NETCP_CFG_ROUTE_HANDLE_T  route,
482                   NETCP_CFG_VLAN_T  vlan,  //future
483                   int state,  //0=down, 1=up  //ignored
484                   int * err
485                   )
487 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
488 nwalMacParam_t   MacInfo= {
489     0,      /* validParams */
490     0,      /* ifNum */
491     0,      /* vlanId      */
492     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },      /* Local mac */
493     NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */
494     NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */
495     CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */
496     QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */
497 };
499 nwal_RetValue       retValue;
500 NetapiNwalTransInfo_t *pTransInfo;
501 nwal_TransID_t     trans_id;
503     if ((!n) || (!p_mac)) {*err = NETAPI_ERR_BAD_INPUT; return -1;}
504     *err =0;
506     pTransInfo = netapip_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
507     if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return -1;}
508     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC;
509     pTransInfo->netapi_handle = h; 
511     /* set up MacInfo */
512     memcpy(&MacInfo.macAddr,p_mac,6); 
513     /* todo: vlan */
514     MacInfo.ifNum = switch_port;  /* todo: check for 0/1 relative*/
516     if (route != NULL)
517     {
518         netcp_cfgp_build_route(route,&MacInfo.appRxPktFlowId, &MacInfo.appRxPktQueue);
519     }
520     pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
521     retValue = nwal_setMacIface( ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
522                                   trans_id,
523                                   (nwal_AppId) (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no),
524                                   &MacInfo,
525                                   &pTransInfo->handle);
526     if(retValue !=  nwal_OK)
527     {
528         *err = NETAPI_ERR_NWAL_ERR0;
529         printf (">netcp cfg - ERROR: nwal_setMacIface returned Error Code %d\n",
530                     retValue);
531         pTransInfo->inUse = nwal_FALSE;
532         return -1;
533     }
534     //pTransInfo->inUse = nwal_FALSE;
536     //wait here until its done since scheduler isn't running yet most likely..
537     // todo:  make this handled by scheduler poll later ??
538     if(trans_id != NWAL_TRANSID_SPIN_WAIT)
539     {
540         n->nwal_local.numPendingCfg++;
541         while ((volatile) n->nwal_local.numPendingCfg)
542         {
543             // if response is there, then this poll squirts out in the CTl poll callback, 
544             // which handles the rest (including decrmenting #pending!!
545             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
546         }
547     }
548     printf (">netcp cfg: MAC i/f %d added\n", iface_no);
549     netcp_cfgp_insert_mac(&netapi_get_global()->nwal_context, 
550                           p_mac, iface_no, state,vlan,
551                           (void *) pTransInfo->handle);
552     pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;
553     pTransInfo->inUse = nwal_FALSE;
554     return  (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no);
558 /*****************************************************************/
559 /***************Delete a mac interface****************************/
560 /*****************************************************************/
561 void netcp_cfgDelMac(NETAPI_T h,int iface_no,  int *err)
563     nwal_RetValue ret;
564     NetapiNwalTransInfo_t *pTransInfo;
565     nwal_TransID_t     trans_id;
566     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
567     void * ifHandle;
569     //get the nwal handle assoicated with this iface
570     ifHandle = netcp_cfgp_get_mac_handle(&netapi_get_global()->nwal_context, iface_no );
571     if(!ifHandle) 
572             {*err = NETAPI_ERR_BAD_INPUT; return ;}
573     *err =0;
574     
575     //get a transaction id
576     pTransInfo = netapip_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
577     if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return ;}
578     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC;
579     pTransInfo->netapi_handle = h;
580     //issue request
581     ret = nwal_delMacIface(
582                 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
583                 trans_id,
584                 ifHandle);
585     if(ret !=  nwal_OK)
586     {
587         *err = NETAPI_ERR_NWAL_ERR0;
588         printf (">netcp cfg - ERROR: nwal_delMacIface returned Error Code %d\n",
589                     ret);
590         pTransInfo->inUse = nwal_FALSE;
591         return ;
592     }
593     //wait here until its done since scheduler isn't running yet most likely..
594     // todo:  make this handled by scheduler poll later ??
595     if(trans_id != NWAL_TRANSID_SPIN_WAIT)
596     {
597         n->nwal_local.numPendingCfg++;
598         while ((volatile) n->nwal_local.numPendingCfg)
599         {
600             // if response is there, then this poll squirts out in the CTl poll callback, 
601             // which handles the rest (including decrmenting #pending!!
602             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
603         }
604     }
605     printf (">netcp cfg: MAC i/f %d deleted\n",iface_no);
606     pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;
607     pTransInfo->inUse = nwal_FALSE;
608     //zap the entry
609     netcp_cfgp_delete_mac(&netapi_get_global()->nwal_context,  iface_no);
610     return ;
614 /*****************************************************************/
615 /***************Add IP to MAC interface (internal)****************/
616 /*****************************************************************/
617 static NETCP_CFG_IP_T  netcp_cfgAddIpInternal(
618                   NETAPI_T  h,
619                   int  iface_no,
620                   nwal_IpType ipType,
621                   nwalIpAddr_t  * ip_addr,
622                   nwalIpOpt_t * ip_qualifiers,
623                   NETCP_CFG_ROUTE_HANDLE_T  route,  //NULL for default
624                   int * err,
625                   int  flag) //TRUE: add IP to iface.  False: add IP as part of classifier
627 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
628 void * n_handle=NULL;
629 nwalIpParam_t    nwalIpParam= {
630     pa_IPV4,      /* IP Type */
631     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Dest IP */
632     { 0x0,0,0,0},/* IP Options */
633     NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */
634     NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */
635     CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */
636     QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */
637 };
638 nwal_RetValue       retValue;
639 NetapiNwalTransInfo_t *pTransInfo;
640 nwal_TransID_t     trans_id;
641 int ip_slot=-1;
642 NETCP_CFG_IP_T ip_rule_id;
643 NETCP_CFG_IP_T temp;
645      //verify that iface has been configured 
646      if (iface_no != NETCP_CFG_NO_INTERFACE)
647      {
648      if ((iface_no<0) || (iface_no>= TUNE_NETAPI_MAX_NUM_MAC)) {*err = NETAPI_ERR_BAD_INPUT; return -1;}
649      }
651      if (iface_no != NETCP_CFG_NO_INTERFACE)
652      {
653      if(netapi_get_global()->nwal_context.interfaces[iface_no].in_use)
654      {
655         n_handle =  netapi_get_global()->nwal_context.interfaces[iface_no].nwal_handle;
656      }
657      else
658      {
659         *err = NETAPI_ERR_BAD_INPUT;
660         return -1;
661      }
662      }
663      if (flag) //if adding IP to MAC then reserve a slot to save info
664      {
665          //find free slot for IP & reserve
666           ip_slot= netcp_cfgp_find_ip_slot(&netapi_get_global()->nwal_context, 
667                                    iface_no);
668           if (ip_slot <0) 
669           {
670                 *err= NETAPI_ERR_NOMEM;  //no room 
671                 return -1;
672           }
673      }
675      //get a transaction object for config action
676     pTransInfo = netapip_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
677     if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return -1;}
678     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;
679     pTransInfo->netapi_handle = h;
681      //build nwalIpParam
682      memcpy(&nwalIpParam.locIpAddr,ip_addr, sizeof(nwalIpAddr_t));
683      nwalIpParam.ipType=ipType;
684      if(route)
685      {
686         netcp_cfgp_build_route(route,&nwalIpParam.appRxPktFlowId, &nwalIpParam.appRxPktQueue);
687      } 
688      else{} //use nwal defaults
689      if (ip_qualifiers)
690         memcpy(&nwalIpParam.ipOpt,ip_qualifiers, sizeof(nwalIpOpt_t)); 
691      else
692         memset(&nwalIpParam.ipOpt,0, sizeof(nwalIpOpt_t));
694      //build the rule id that will be returned when a packet matches 
695      if (flag)
696         ip_rule_id = NETAPI_NETCP_MATCH_GENERIC_IP | iface_no | ((ip_slot&&0xff)<<8);
697      else
698         ip_rule_id = (NETAPI_NETCP_MATCH_CLASS_L3 | iface_no);
700      //perform config action
701      pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
702      retValue = nwal_setIPAddr(   netapi_get_global()->nwal_context.nwalInstHandle,
703                                   trans_id,
704                                   (nwal_AppId) (ip_rule_id),
705                                   n_handle,
706                                   &nwalIpParam,
707                                   &pTransInfo->handle);
709     if(retValue !=  nwal_OK)
710     {
711         *err = NETAPI_ERR_NWAL_ERR0;
712         printf (">netcp cfg: nwal_setIP returned Error Code %d\n",
713                     retValue);
714         pTransInfo->inUse = nwal_FALSE;
715         //zap the entry
716         if (flag)
717         {
718                 netcp_cfgp_delete_ip(&netapi_get_global()->nwal_context,
719                          iface_no,
720                          ip_slot);
721         }
722         return -1;
723     }
724     //wait here until its done since scheduler isn't running yet most likely..
725     // todo:  make this handled by scheduler poll later ??
726     if(trans_id != NWAL_TRANSID_SPIN_WAIT)
727     {
728         n->nwal_local.numPendingCfg++;
729         while ((volatile) n->nwal_local.numPendingCfg)
730         {
731             // if response is there, then this poll squirts out in the CTl poll callback, 
732             // which handles the rest (including decrmenting #pending!!
733             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
734         }
735     }
736     if (flag)
737     {
738         printf (">netcp cfg: IP added to interface %d (slot%d)\n", iface_no, ip_slot);
739         netcp_cfgp_insert_ip(&netapi_get_global()->nwal_context, ipType, 
740                           ip_addr, ip_qualifiers, iface_no, ip_slot,
741                           pTransInfo->handle);
742     }
743     pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;
744     temp = (NETCP_CFG_IP_T) pTransInfo->handle;
745     pTransInfo->inUse = nwal_FALSE;
746     return  (flag ? ip_rule_id:  temp);
748 /*****************************************************************/
749 /***************Add IP to MAC interface **************************/
750 /*****************************************************************/
751 NETCP_CFG_IP_T  netcp_cfgAddIp(
752                   NETAPI_T  h,
753                   int  iface_no,
754                   nwal_IpType ipType,
755                   nwalIpAddr_t  * ip_addr,
756                   nwalIpOpt_t * ip_qualifiers,
757                   NETCP_CFG_ROUTE_HANDLE_T  route,  //NULL for default
758                   int * err
759                   )
761         return netcp_cfgAddIpInternal(
762                 h, iface_no, ipType, ip_addr, ip_qualifiers, route, err, 
763                 1);
766 /*****************************************************************/
767 /***************Delete an attached IP*****************************/
768 /*****************************************************************/
769 static void netcp_cfgDelIpInternal(NETAPI_T h, int iface_no,  nwal_IpType ipType,
770                   nwalIpAddr_t  * ip_addr,
771                   nwalIpOpt_t * ip_qualifiers, 
772                   NETCP_CFG_IP_T  ip_rule_id,
773                   int *err, 
774                   void * handle,   /* if flag==0, handle must be valid */
775                   int flag)        /* flag==0 => delete IP rule that was part of classifier, not interface */
777     nwal_RetValue ret;
778     NetapiNwalTransInfo_t *pTransInfo;
779     nwal_TransID_t     trans_id;
780     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
781     void * ifHandle;
782     int ip_slot = (ip_rule_id>>8)&0xff;
784     //get the nwal handle assoicated with this ip   
785     if (flag)
786     {
787         ifHandle = netcp_cfgp_get_ip_handle(
788           &netapi_get_global()->nwal_context, iface_no,
789           ip_slot );
790     }
791     else 
792     {
793         ifHandle = handle;
794     }
795     if(!ifHandle)
796             {*err = NETAPI_ERR_BAD_INPUT; return ;}
797     *err =0;
799     //get a transaction id
800     pTransInfo = netapip_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
801     if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return ;}
802     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;
803     pTransInfo->netapi_handle = h;
804     //issue request
805     ret = nwal_delIPAddr(
806                 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
807                 trans_id,
808                 ifHandle);
809     if(ret !=  nwal_OK)
810     {
811         *err = NETAPI_ERR_NWAL_ERR0;
812         printf (">netcp cfg - ERROR: nwal_delMacIface returned Error Code %d\n",
813                     ret);
814         pTransInfo->inUse = nwal_FALSE;
815         return ;
816     }
817     //wait here until its done since scheduler isn't running yet most likely..
818     // todo:  make this handled by scheduler poll later ??
819     if(trans_id != NWAL_TRANSID_SPIN_WAIT)
820     {
821        n->nwal_local.numPendingCfg++;
822         while ((volatile) n->nwal_local.numPendingCfg)
823         {
824             // if response is there, then this poll squirts out in the CTl poll callback, 
825             // which handles the rest (including decrmenting #pending!!
826             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
827         }
828     }
829     if (flag)
830         printf (">netcp cfg: attached IP deleted\n");
831     else
832         printf (">netcp cfg: Classifier IP rule deleted\n");
833     pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;
834     pTransInfo->inUse = nwal_FALSE;
836     //zap the entry
837     if (flag)
838         netcp_cfgp_delete_ip(&netapi_get_global()->nwal_context,  
839                          iface_no,
840                          ip_slot);
841     return ;
844 /*****************************************************************/
845 /***************Delete an attached IP*****************************/
846 /*****************************************************************/
847 void netcp_cfgDelIp(NETAPI_T h, int iface_no,  nwal_IpType ipType,
848                   nwalIpAddr_t  * ip_addr,
849                   nwalIpOpt_t * ip_qualifiers,
850                   NETCP_CFG_IP_T  ip_rule_id,
851                   int *err)
853         netcp_cfgDelIpInternal( h, iface_no, ipType,
854                   ip_addr, ip_qualifiers, ip_rule_id,
855                   err, NULL, 1);
856         return;
860 /**
861  * @def netcp_cfgAddClass
862  * @brief  add a classifier rule into NETCP
863  **/
864 NETCP_CFG_CLASS_T netcp_cfgAddClass(NETAPI_T h,
865                                       NETCP_CFG_CLASSIFIER_T *p_class,
866                                       NETCP_CFG_ROUTE_HANDLE_T route,
867                                       int action, int * err)
869 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
870 void * l3_handle=NULL;  //ip handle
871 nwal_RetValue       retValue;
872 NetapiNwalTransInfo_t *pTransInfo;
873 nwal_TransID_t     trans_id;
874 int class_slot=-1;
875 int iface_no;
876 int ip_slot=-1;
877 NETCP_CFG_CLASS_T  classHandle;  //returned by us
878 nwal_appProtoType_t proto;
879 nwalRxConnCfg_t tempCfg={
880 0,  //nwal_handle: to be filled in
881 {0}, // l4 ports: to be filled in
882 0,  //core id (NA)
883 0, //action
884 CPPI_PARAM_NOT_SPECIFIED, //flow id
885 QMSS_PARAM_NOT_SPECIFIED, //dest queue
886 };
888 if(!p_class) { *err=NETAPI_ERR_BAD_INPUT; return -1;}
889 switch(p_class->classType)
891 default:
892         printf(">netcp_cfg : classifier type %d not supported\n",p_class->classType);
893         break;
894 case(NETCP_CFG_CLASS_TYPE_L3_L4):
895 case(NETCP_CFG_CLASS_TYPE_L4):
896         //assume just type l4 only (L2, L3 defined by iface, l3 id )
897         iface_no = p_class->u.c_l4.iface;
898         if (p_class->classType== NETCP_CFG_CLASS_TYPE_L4)
899         { 
900                 ip_slot = (p_class->u.c_l4.ip>>8)&0xff;
901         }
903          //verify that iface has been configured 
904         if (iface_no != NETCP_CFG_NO_INTERFACE)
905         {
906         if(!netapi_get_global()->nwal_context.interfaces[iface_no].in_use)
907         {
908                 *err = NETAPI_ERR_BAD_INPUT;
909                 return -1;
910         }
911         }
913         if (p_class->classType== NETCP_CFG_CLASS_TYPE_L4)
914         {
915              //verify that ip has been configured and get its handle
916              l3_handle = netcp_cfgp_get_ip_handle(
917                           &netapi_get_global()->nwal_context, iface_no,
918                           ip_slot );
919         }
920         else
921         {
922              nwalIpParam_t tempParam={
923     pa_IPV4,      /* IP Type */
924     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Dest IP */
925     { 0x0,0,0,0},/* IP Options */
926     NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */
927     NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */
928     CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */
929     QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */
930         };
931                 //build nwalIpParam
932                 memcpy(&tempParam.locIpAddr,p_class->u.c_l3_l4.ip_addr, sizeof(nwalIpAddr_t));
933                 tempParam.ipType=p_class->u.c_l3_l4.ipType;
934             //use nwal defauls for route
935             if (p_class->u.c_l3_l4.ip_qualifiers)
936                         memcpy(&tempParam.ipOpt,p_class->u.c_l3_l4.ip_qualifiers, sizeof(nwalIpOpt_t));
937              else
938                         memset(&tempParam.ipOpt,0, sizeof(nwalIpOpt_t));
941              //find if we have a matching L3 handle for IP classifier; if not create it
942              retValue =  nwal_getIPAddr (((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
943                                 &tempParam,
944                                 netcp_cfgp_get_mac_handle(&netapi_get_global()->nwal_context, iface_no ),
945                                 &l3_handle); 
946              if (retValue != nwal_TRUE) 
947              {
948                 int ret;
949                 //**NEW IP RULE  
950                 //need to attach this IP RULE to the MAC
951                 l3_handle= (void *) netcp_cfgAddIpInternal(
952                   h, iface_no, 
953                   p_class->u.c_l3_l4.ipType,
954                   p_class->u.c_l3_l4.ip_addr,
955                   p_class->u.c_l3_l4.ip_qualifiers,
956                   p_class->u.c_l3_l4.p_fail_route,
957                   &ret,
958                   FALSE);
959                  if(!ret)
960                  {
961                         l3_handle=NULL;
962                  }
963              }
964         }         
965         if(!l3_handle)
966             {*err = NETAPI_ERR_BAD_INPUT; return -1 ;}
969         //find free slot for CLASS & reserve
970         class_slot= netcp_cfgp_find_class_slot(&netapi_get_global()->nwal_context);
971         if(class_slot<0) {*err = NETAPI_ERR_NOMEM; return -1;}
972         classHandle = NETAPI_NETCP_MATCH_CLASS | (class_slot<<8) | (iface_no&0xff);
973         //build request from template
974         tempCfg.inHandle=l3_handle;
975         if (p_class->classType== NETCP_CFG_CLASS_TYPE_L4)
976         { 
977                 memcpy(&tempCfg.appProto,&p_class->u.c_l4.appProto,sizeof(nwalAppProto_t));
978                 proto = p_class->u.c_l4.proto;
979         }
980         else
981         {
982                 memcpy(&tempCfg.appProto,&p_class->u.c_l3_l4.appProto,sizeof(nwalAppProto_t));
983                 proto = p_class->u.c_l3_l4.proto;
984         }
985         
986         tempCfg.matchAction = (action==NETCP_CFG_ACTION_TO_SW)  ? NWAL_MATCH_ACTION_HOST : NWAL_MATCH_ACTION_DISCARD;
987         if (route)
988         {
989                 netcp_cfgp_build_route(route,&tempCfg.appRxPktFlowId, &tempCfg.appRxPktQueue);
990         }
992         //get a transaction id
993         pTransInfo = netapip_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
994         if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return -1 ;}
995         pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP; /* todo: fix this to TRANS_L4*/
996         pTransInfo->netapi_handle = h;
997         //issue request
998         retValue = nwal_addConn(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
999                             trans_id,
1000                             (nwal_AppId) classHandle,
1001                             proto,
1002                             &tempCfg,
1003                             NULL,
1004                             &pTransInfo->handle);
1005         if(retValue !=  nwal_OK)
1006         {
1007             *err = NETAPI_ERR_NWAL_ERR0;
1008             printf (">netcp cfg - ERROR: nwal_addConn returned Error Code %d\n",
1009                     retValue);
1010             pTransInfo->inUse = nwal_FALSE;
1011             netcp_cfgp_delete_class(&netapi_get_global()->nwal_context, class_slot);
1012             return -1;
1013         }
1014         //wait here until its done since scheduler isn't running yet most likely..
1015         // todo:  make this handled by scheduler poll later ??
1016         if(trans_id != NWAL_TRANSID_SPIN_WAIT)
1017         {
1018              n->nwal_local.numPendingCfg++;
1019              while ((volatile) n->nwal_local.numPendingCfg)
1020              {
1021                 // if response is there, then this poll squirts out in the CTl poll callback, 
1022                 // which handles the rest (including decrmenting #pending!!
1023                 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
1024              }
1025          }
1026          printf (">netcp cfg: L4 Classifer added to interface %d ip %d (slot%d)\n", iface_no, ip_slot, class_slot);
1027          netcp_cfgp_insert_class(&netapi_get_global()->nwal_context, 
1028                                    class_slot,
1029                                  p_class->classType, 
1030                                   NULL,  //L2 we have
1031                                   (p_class->classType== NETCP_CFG_CLASS_TYPE_L3_L4? l3_handle : NULL),
1032                                   pTransInfo->handle);
1033          pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;
1034          return classHandle;
1035 } //end switch
1036 return -1;
1039 //delete classifier
1040 void netcp_cfgDelClass(NETAPI_T h,
1041                          NETCP_CFG_CLASS_T classId,
1042                          int *err)
1044 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
1045 void * L4_handle;  //class handle -> L4
1046 void * L3_handle;  //class handle -> L3
1047 nwal_RetValue       retValue;
1048 NetapiNwalTransInfo_t *pTransInfo;
1049 nwal_TransID_t     trans_id;
1050 int class_slot=-1;
1051 //int iface;
1052 //int ip_slot;
1054         class_slot = (classId>>8)&0xffff;
1055         L4_handle=netcp_cfgp_get_l4_handle(
1056                         &netapi_get_global()->nwal_context,
1057                         class_slot );
1058         if(!L4_handle)  {*err = NETAPI_ERR_BAD_INPUT; return ;}
1059         L3_handle = netcp_cfgp_get_l3_handle(
1060                         &netapi_get_global()->nwal_context,
1061                         class_slot );
1062         /* l3 handle might be NULL,, depending on type of classifier */
1064         netcp_cfgp_delete_class(
1065                         &netapi_get_global()->nwal_context,
1066                         class_slot );
1067         //get a transaction id
1068         pTransInfo = netapip_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
1069         if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return  ;}
1070         pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;
1071         pTransInfo->netapi_handle = h;
1072         //issue request for L4
1073         retValue = nwal_delConn(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
1074                             trans_id,
1075                             L4_handle);
1076         if(retValue !=  nwal_OK)
1077         {
1078             *err = NETAPI_ERR_NWAL_ERR0;
1079             printf (">netcp cfg - ERROR: nwal_delConn returned Error Code %d\n",
1080                     retValue);
1081             pTransInfo->inUse = nwal_FALSE;
1082             return ;  /* todo: what about the L3? */
1083         }
1084         //wait here until its done since scheduler isn't running yet most likely..
1085         // todo:  make this handled by scheduler poll later ??
1086         if(trans_id != NWAL_TRANSID_SPIN_WAIT)
1087         {
1088              n->nwal_local.numPendingCfg++;
1089              while ((volatile) n->nwal_local.numPendingCfg)
1090              {
1091                 // if response is there, then this poll squirts out in the CTl poll callback, 
1092                 // which handles the rest (including decrmenting #pending!!
1093                 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
1094              }
1095          }
1096          printf (">netcp cfg: Classifer deleted\n");
1097          pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;
1098          pTransInfo->inUse = nwal_FALSE;
1100          /* delete L3 if we have to */
1101          if (L3_handle)
1102          {
1103              netcp_cfgDelIpInternal( h, 0, 0,
1104                   NULL, NULL, 0,
1105                   err, L3_handle,  0);
1106          }
1107          return ;
1111 /*--------------flow management--------*/
1112 // ADD A Flow
1113 NETCP_CFG_FLOW_HANDLE_T netcp_cfgAddFlow(NETAPI_T h,
1114                                             int n,
1115                                             Pktlib_HeapHandle handles[],
1116                                             int sizes[],
1117                                             int byte_offset,
1118                                             int * err )
1120   Cppi_RxFlowCfg  rxFlowCfg;
1121   Uint8           isAlloc;
1122   Qmss_QueueHnd   rxBufQ[TUNE_NETAPI_MAX_BUF_POOLS_IN_FLOW];
1123   Uint32          rxBufSize[TUNE_NETAPI_MAX_BUF_POOLS_IN_FLOW];
1124   int             i;
1125   Cppi_FlowHnd FlowHnd;
1126   int  slot;
1127   NETCP_CFG_FLOW_HANDLE_T retVal;
1129   *err= 0;  /* ok */
1130   //get a slot to save new flow
1131   slot = netcp_cfgp_find_flow_slot(&netapi_get_global()->nwal_context);
1132   if (slot<0) { *err= NETAPI_ERR_NOMEM;  return NULL; }
1134   //configure flow
1135   memset(&rxFlowCfg,0,sizeof(Cppi_RxFlowCfg));
1136   for (i = 0; i < TUNE_NETAPI_MAX_BUF_POOLS_IN_FLOW; i++)
1137   {
1138       if (i >= n)
1139       {
1140           rxBufQ[i] = 0;
1141           rxBufSize[i] = 0;
1142       } else
1143       {
1144           rxBufQ[i] =   Pktlib_getInternalHeapQueue(handles[i]);
1145           //todo: verity sizes< heapsize
1146           //todo: verify order
1147           rxBufSize[i]= sizes[i];
1148       }
1149       if (i && (rxBufQ[i] <= 0))
1150       {
1151           rxBufQ[i] = rxBufQ[i-1];
1152           rxBufSize[i] = 0;
1153       }
1154   }
1155   /* Configure Rx flow */
1156   rxFlowCfg.flowIdNum      = CPPI_PARAM_NOT_SPECIFIED;
1157   rxFlowCfg.rx_dest_qnum   = 100;   //DANGEROUS>  TODO PUT VALID Q HERE
1158   rxFlowCfg.rx_dest_qmgr   = 0;
1159   rxFlowCfg.rx_sop_offset  = byte_offset;
1160   rxFlowCfg.rx_ps_location = Cppi_PSLoc_PS_IN_DESC;
1161   rxFlowCfg.rx_desc_type   = Cppi_DescType_HOST;
1162   rxFlowCfg.rx_error_handling = 0;
1164   rxFlowCfg.rx_psinfo_present = 1;
1165   rxFlowCfg.rx_einfo_present  = 1;
1167   rxFlowCfg.rx_dest_tag_lo = 0;
1168   rxFlowCfg.rx_dest_tag_hi = 0;
1169   rxFlowCfg.rx_src_tag_lo  = 0;
1170   rxFlowCfg.rx_src_tag_hi  = 0;
1172   rxFlowCfg.rx_size_thresh0_en = rxBufSize[1] ? 1 : 0;
1173   rxFlowCfg.rx_size_thresh1_en = rxBufSize[2] ? 1 : 0;
1174   rxFlowCfg.rx_size_thresh2_en = rxBufSize[3] ? 1 : 0;
1176   rxFlowCfg.rx_dest_tag_lo_sel = 0;
1177   rxFlowCfg.rx_dest_tag_hi_sel = 0;
1178   rxFlowCfg.rx_src_tag_lo_sel  = 0;
1179   rxFlowCfg.rx_src_tag_hi_sel  = 0;
1181   rxFlowCfg.rx_fdq1_qnum = rxBufQ[1];
1182   rxFlowCfg.rx_fdq1_qmgr = 0;
1183   rxFlowCfg.rx_fdq2_qnum = rxBufQ[2];
1185   rxFlowCfg.rx_fdq2_qmgr = 0;
1186   rxFlowCfg.rx_fdq3_qnum = rxBufQ[3];
1188   rxFlowCfg.rx_fdq3_qmgr = 0;
1190   rxFlowCfg.rx_size_thresh0 = rxBufSize[1] ? rxBufSize[0] : 0;
1191   rxFlowCfg.rx_size_thresh1 = rxBufSize[2] ? rxBufSize[1] : 0;
1192   rxFlowCfg.rx_size_thresh2 = rxBufSize[3] ? rxBufSize[2] : 0;
1194   rxFlowCfg.rx_fdq0_sz0_qnum = rxBufQ[0];
1195   rxFlowCfg.rx_fdq0_sz0_qmgr = 0;
1196   rxFlowCfg.rx_fdq0_sz1_qnum = rxBufQ[1];
1197   rxFlowCfg.rx_fdq0_sz1_qmgr = 0;
1198   rxFlowCfg.rx_fdq0_sz2_qnum = rxBufQ[2];
1199   rxFlowCfg.rx_fdq0_sz2_qmgr = 0;
1200   rxFlowCfg.rx_fdq0_sz3_qnum = rxBufQ[3];
1201   rxFlowCfg.rx_fdq0_sz3_qmgr = 0;
1203  {
1204   //todo: replace this with a nwal call to get global cntx info
1205   Cppi_CpDmaInitCfg cpdmaCfg;
1206   memset(&cpdmaCfg,0,sizeof(Cppi_CpDmaInitCfg));
1207   cpdmaCfg.dmaNum   = Cppi_CpDma_PASS_CPDMA;
1208   FlowHnd =
1209       Cppi_configureRxFlow (Cppi_open (&cpdmaCfg), &rxFlowCfg, &isAlloc);
1211   if (FlowHnd == NULL)
1212   {
1213       *err= NETAPI_ERR_NORES;
1214       netcp_cfgp_delete_flow(&netapi_get_global()->nwal_context, slot);
1215       return (NULL);
1216   }
1218   //update slot
1219   retVal = netcp_cfgp_insert_flow(&netapi_get_global()->nwal_context, slot, (void*) FlowHnd);
1220   printf(">netcp cfg:  flow %d created\n",  ((NETCP_CFG_FLOW_T *) retVal)->flowid);
1221   return ( retVal);
1227 //Delete a flow
1228 void netcp_cfgDelFlow(NETAPI_T h , NETCP_CFG_FLOW_HANDLE_T f , int * err)
1230         int slot;
1231         void * handle;
1232         *err=0;
1233         /* find entry */
1234         slot = netcp_cfgp_find_flow(&netapi_get_global()->nwal_context, ((NETCP_CFG_FLOW_T *) f) ->flowid, &handle);
1235         if (slot<0) {*err = NETAPI_ERR_BAD_INPUT; return;}
1237         Cppi_closeRxFlow( (Cppi_FlowHnd) handle);
1238         netcp_cfgp_delete_flow(&netapi_get_global()->nwal_context, slot);
1239         printf(">netcp cfg:  flow %d deleted\n",  ((NETCP_CFG_FLOW_T *) f)->flowid);
1240         return;
1244 /*************************************************************************/
1245 /*********************************INTERNAL*******************************/
1246 /************************************************************************/
1248 /***************************************************************
1249  ********************NETCP CMD Reply Callback******************
1250  ***************************************************************/
1251 void netapi_NWALCmdCallBack (nwal_AppId        appHandle,
1252                           uint16_t            trans_id,
1253                           nwal_RetValue     ret)
1255     NetapiNwalTransInfo_t * p_trans;
1256     NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL;
1258     if(trans_id == NWAL_TRANSID_SPIN_WAIT)
1259     {
1260         netapi_get_global()->nwal_context.numBogusTransIds++;
1261         return;
1262     }
1264     p_trans= &netapi_get_global()->nwal_context.transInfos[trans_id];
1265     p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;
1267     if(ret != nwal_OK)
1268     {
1269         printf (">netcp cfg : NWALCmdCallBack returned Error Code %d\n",
1270                     ret);
1271         // update error code that is fialed  in p_trans */
1272         //todo: atomic inc
1273         netapi_get_global()->nwal_context.numCmdFail++;
1274     }
1275     else
1276     {
1277         //todo: atomic inc
1278         netapi_get_global()->nwal_context.numCmdPass++;
1279         switch(p_trans->transType)
1280         {
1281             case NETAPI_NWAL_HANDLE_TRANS_MAC:
1282             {
1283                 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
1284                 {
1285                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;
1286                 }
1287                 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
1288                 {
1289                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
1290                 }
1291                 break;
1292             }
1293             case NETAPI_NWAL_HANDLE_TRANS_IP:
1294             {
1295                  if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
1296                 {
1297                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;
1298                 }
1299                 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
1300                 {
1301                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
1302                 }
1303                 break;
1304             }
1305             case NETAPI_NWAL_HANDLE_TRANS_PORT:
1306             {
1307                 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
1308                 {
1309                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;
1310                 }
1311                 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
1312                 {
1313                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
1314                 }
1315                 break;
1316             }
1317             case NETAPI_NWAL_HANDLE_TRANS_SA:
1318             {
1319                 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
1320                 {
1321                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;
1322                 }
1323                 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
1324                 {
1325                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
1326                 }
1327                 break;
1328             }
1329             case NETAPI_NWAL_HANDLE_TRANS_SA_POLICY:
1330             {
1331                 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
1332                 {
1333                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;
1334                 }
1335                 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
1336                 {
1337                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
1338                 }
1339                 break;
1340             }
1341             default:
1342             {
1343                 printf ("netcp cfg> Invalid transaction type %d for trans_id: %d\n",
1344                     p_trans->transType,trans_id);
1345                 break;
1346             }
1347         }
1348     }
1350     p_local->numPendingCfg--;
1352     if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_IDLE)
1353     {
1354         p_trans->inUse = nwal_FALSE;
1355     }
1360 /*******************************************************/
1361 /**************stats reply callback**********************/
1362 /*******************************************************/
1363 void netapi_NWALCmdPaStatsReply (nwal_AppId        appHandle,
1364                               nwal_TransID_t    trans_id,
1365                               paSysStats_t      *stats)
1367     NetapiNwalTransInfo_t * p_trans;
1368     NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL;
1369   
1370     if(trans_id == NWAL_TRANSID_SPIN_WAIT)
1371     {
1372         netapi_get_global()->nwal_context.numBogusTransIds++;
1373         return;
1374     }
1376     p_trans= &netapi_get_global()->nwal_context.transInfos[trans_id];
1377     p_trans->inUse = nwal_FALSE;
1378     p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;
1380     //save a local copy  of some stuff*/
1381     p_local->numL2PktsRecvd=stats->classify1.nPackets;
1382     p_local->numL3PktsRecvd=stats->classify1.nIpv4Packets;
1383 #if 0
1384     p_local->numL4PktsRecvd=stats->;
1385     p_local->numL4PktsSent=stats->;
1386     p_local->TxErrDrop=stats->;
1387 #endif
1388     //callout result to application !!
1389     if (p_local->stats_cb) (*p_local->stats_cb)(p_trans->netapi_handle,stats);
1390     
1391