Set qmQueMgmtProxyDataReg to NULL for k1, k2h
[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:
11  *
12  *  Copyright (c) Texas Instruments Incorporated 2013
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  ******************************************************/
44 #include "netapi.h"
47 /******************************************************************
48  ********************Netapi internal*************************************
49 *******************************************************************/
50 static hplib_spinLock_T netapi_netcp_cfg_lock = hplib_spinLock_UNLOCKED_INITIALIZER;
52 /********************************************************************
53  * FUNCTION PURPOSE:  Netapi internal function to get a free transaction id
54  ********************************************************************
55  * DESCRIPTION:  Netapi internal function to get a free transaction id.
56  ********************************************************************/
57 NetapiNwalTransInfo_t * netapip_getFreeTransInfo(NETAPI_GLOBAL_T *p_global,
58                                                  nwal_TransID_t *pTransId)
59 {
60     uint16_t    count=0;
62     count=0;
63     hplib_mSpinLockLock(&netapi_netcp_cfg_lock);
64     while(count < TUNE_NETAPI_MAX_NUM_TRANS)
65     {
66         if((p_global->nwal_context.transInfos[count].inUse) != nwal_TRUE)
67         {
68             p_global->nwal_context.transInfos[count].inUse = nwal_TRUE;
69             *pTransId = count;
70             hplib_mSpinLockUnlock(&netapi_netcp_cfg_lock);
71             return(&p_global->nwal_context.transInfos[count]);
72         }
73         count++;
74     }
75     hplib_mSpinLockUnlock(&netapi_netcp_cfg_lock);
76     /* trouble.  need to wait for one to free up*/
77     /* to do: handle this by forcing a poll of cntrl queue*/
78     netapi_Log(">netcp_cfg: trying to get free transaction slot but all full!!\n");
79     return NULL;
81 }
83 /********************************************************************
84  * FUNCTION PURPOSE:  Netapi internal function to free a transaction id
85  ********************************************************************
86  * DESCRIPTION:  Netapi internal function to free a transaction id
87  ********************************************************************/
88 void netapip_freeTransInfo(NetapiNwalTransInfo_t *pTransInfo)
89 {
90     pTransInfo->inUse = nwal_FALSE;
91     pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;
92     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_NONE;
93 }
94 /********************************************************************
95  * FUNCTION PURPOSE:  Netapi internal function to build a route
96  ********************************************************************
97  * DESCRIPTION:  Netapi internal function to build a route
98  ********************************************************************/
99 void netapip_netcpCfgBuildRoute(NETCP_CFG_ROUTE_T * p_route,
100                                 int16_t * p_flow,  
101                                 Qmss_QueueHnd * p_q)
103     if (!p_route) return;
104     if (p_route->p_flow)  *p_flow= p_route->p_flow->flowid;
105     else *p_flow = CPPI_PARAM_NOT_SPECIFIED;
106     if (p_route->p_dest_q) *p_q = netapi_pktioGetQ(p_route->p_dest_q);
107     else *p_q=QMSS_PARAM_NOT_SPECIFIED;
111 /******************************************************/
112 /*----------------database management stuff           */
113 /******************************************************/
115 /*=====================POLICIES=============================*/
117 /********************************************************************
118  * FUNCTION PURPOSE:  Netapi internal function to find a free slot for an SA
119  ********************************************************************
120  * DESCRIPTION:  Netapi internal function to find a free slot for an SA
121  ********************************************************************/
122 int netapip_netcpCfgFindPolicySlot(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
123                                    int tunnel)
125     int i;
126     if ((tunnel <0 ) || (tunnel >=TUNE_NETAPI_MAX_SA))
127         return -1;
129     hplib_mSpinLockLock(&netapi_netcp_cfg_lock);
130     //find a free entry
131     for(i=0;i<TUNE_NETAPI_MAX_POLICY;i++)
132     {
133         if (!p->policy[i].in_use)
134         {
135             p->policy[i].in_use = 2; //pending
136             p->policy[i].tunnel= tunnel; //save tunnel this is linked to 
137             hplib_mSpinLockUnlock(&netapi_netcp_cfg_lock);
138             return i;
139         }
140     }
141     hplib_mSpinLockUnlock(&netapi_netcp_cfg_lock);
142     return -1;
145 /********************************************************************
146  * FUNCTION PURPOSE:  Netapi internal function to delete a policy from policy list
147  ********************************************************************
148  * DESCRIPTION:  Netapi internal function to delete a policy from policy list
149  ********************************************************************/
150 void netapip_netcpCfgDeletePolicy(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
151                                   int policy_slot)
153     if ((policy_slot <0 ) || (policy_slot >= TUNE_NETAPI_MAX_POLICY))
154     {
155         return ;
156     }
157     p->policy[policy_slot].in_use=0;
158     return;
161 /********************************************************************
162  * FUNCTION PURPOSE:  Netapi internal function to insert a policy to the policy list
163  ********************************************************************
164  * DESCRIPTION:  Netapi internal function to insert a policy to the policy list
165  ********************************************************************/
166 void netapip_netcpCfgInsertPolicy(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
167                                   int policy_slot,
168                                   void * handle,
169                                   void * user_data)
171     p->policy[policy_slot].in_use=1;
172     p->policy[policy_slot].nwal_handle = handle;
173     p->policy[policy_slot].user_data = user_data;
174     return;
177 /************************************************************************
178  * FUNCTION PURPOSE:  Netapi internal function which returns NWAL handle for a policy
179  ************************************************************************
180  * DESCRIPTION:  Netapi internal function which returns NWAL handle for a policy
181  ************************************************************************/
182 void *netapip_netcpCfgGetPolicy(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
183                                 int policy_slot)
185     if ((policy_slot <0 ) || (policy_slot >= TUNE_NETAPI_MAX_POLICY))
186         return NULL;
187     if (!p->policy[policy_slot].in_use)
188         return NULL;
189     return p->policy[policy_slot].nwal_handle;
192 /********************************************************************
193  * FUNCTION PURPOSE:  Netapi internal function to find a free slot in SA list for a SA
194  ********************************************************************
195  * DESCRIPTION:  Netapi internal function to find a free slot in SA list for an SA
196  ********************************************************************/
197 int netapip_netcpCfgFindSaSlot(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
198                                int iface)
199 {                                    
200    int i;
201    if (iface != NETCP_CFG_NO_INTERFACE)
202    {
203    if ((iface <0 ) || (iface >=TUNE_NETAPI_MAX_NUM_MAC)) return -1;
204    }
205            hplib_mSpinLockLock(&netapi_netcp_cfg_lock);
206          //find a free entry
207    for(i=0;i<TUNE_NETAPI_MAX_SA;i++)
208    {                       
209        if (!p->tunnel[i].in_use)
210        {
211            p->tunnel[i].in_use = 2; //pending
212            p->tunnel[i].iface= iface; //save iface
213            hplib_mSpinLockUnlock(&netapi_netcp_cfg_lock);
214            return i;
215        }
216    }
217    hplib_mSpinLockUnlock(&netapi_netcp_cfg_lock);
218    return -1;
221 /********************************************************************
222  * FUNCTION PURPOSE:  Netapi internal function to delete an SA from SA list
223  ********************************************************************
224  * DESCRIPTION: Netapi internal function to delete an SA from SA list 
225  ********************************************************************/
226 void netapip_netcpCfgDeleteSa(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
227                               int sa_slot)
229     if ((sa_slot <0 ) || (sa_slot >= TUNE_NETAPI_MAX_SA))
230     {
231         return ;
232     }
233     p->tunnel[sa_slot].in_use=0;
234     return;
238 /****************************************************************************
239  * FUNCTION PURPOSE:  Internal function to retrieve SB command info template
240  **************************************************************************
241  * DESCRIPTION:  Internal function to retrieve SB command info template
242  ***************************************************************************/
243 nwalTxDmPSCmdInfo_t* netapip_netcpCfgGetSaSBInfo(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
244                                                  NETCP_CFG_SA_T    sa_app_id)
246      int sa_slot = netapi_cfgGetMatchId(sa_app_id);
247     if ((sa_slot <0 ) || (sa_slot >= TUNE_NETAPI_MAX_SA))
248     {
249         return NULL;
250     }
251     return (&p->tunnel[sa_slot].dmPSCmdInfo);
254 /****************************************************************************
255  * FUNCTION PURPOSE:  Internal function to retrieve Inflow mode 
256  *                    software information required to transmit packet
257  **************************************************************************
258  * DESCRIPTION:  Internal function to retrieve Inflow mode 
259  *                    software information required to transmit packet
260  ***************************************************************************/
261 int netapip_netcpCfgGetSaInflowInfo(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
262                                     NETCP_CFG_SA_T    sa_app_id,
263                                     uint32_t *swInfo0,
264                                     uint32_t *swInfo1)
266     int sa_slot = netapi_cfgGetMatchId(sa_app_id);
267     if ((sa_slot <0 ) || (sa_slot >= TUNE_NETAPI_MAX_SA))
268     {
269         return 0;
270     }
271     *swInfo0 = p->tunnel[sa_slot].swInfo0;
272     *swInfo1 = p->tunnel[sa_slot].swInfo1;
273     return 1;
276 /********************************************************************
277  * FUNCTION PURPOSE:  Netapi internal function to insert an SA to the SA list
278  ********************************************************************
279  * DESCRIPTION: Netapi internal function to insert an SA to the SA list 
280  ********************************************************************/
281 void netapip_netcpCfgInsertSa(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
282                               int sa_slot,
283                               int dir,
284                               int mode,
285                               void * temp1,
286                               void * temp2,
287                               void * handle_inflow,
288                               void * handle_sideband,
289                               nwalTxDmPSCmdInfo_t *dmPSCmdInfo,
290                               uint32_t swInfo0,
291                               uint32_t swInfo1,
292                               void* user_data)
294     p->tunnel[sa_slot].in_use=1;
295     p->tunnel[sa_slot].inbound = dir;
296     p->tunnel[sa_slot].sa_mode = mode;
297     p->tunnel[sa_slot].sa_handle_inflow = handle_inflow;
298     p->tunnel[sa_slot].sa_handle_sideband = handle_sideband;
299     p->tunnel[sa_slot].swInfo0 = swInfo0;
300     p->tunnel[sa_slot].swInfo1 = swInfo1;
301     p->tunnel[sa_slot].user_data = user_data;
302     //netapi_Log("netapip_netcpCfgInsertSa: swInfo0 0x%x, swInfo1: 0x%x, user data: %d\n",
303 //        p->tunnel[sa_slot].swInfo0, p->tunnel[sa_slot].swInfo1, (uint32_t)p->tunnel[sa_slot].user_data);
305     if (dmPSCmdInfo)
306     {
307         memcpy(&p->tunnel[sa_slot].dmPSCmdInfo, dmPSCmdInfo, sizeof(nwalTxDmPSCmdInfo_t));
308     }
309     return;
312 /********************************************************************
313  * FUNCTION PURPOSE:  Netapi internal function to return NWAL handles for an SA
314  ********************************************************************
315  * DESCRIPTION: Netapi internal function to return NWAL handles for an SA
316  ********************************************************************/
317  void *netapip_netcpCfgGetSaHandles(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
318                                     int sa_slot,
319                                     void ** p_sideband)
321     if ((sa_slot <0 ) || (sa_slot >= TUNE_NETAPI_MAX_SA))
322         return NULL;
323     if (!p->tunnel[sa_slot].in_use)
324         return NULL;
325     *p_sideband = p->tunnel[sa_slot].sa_handle_sideband;
326     return p->tunnel[sa_slot].sa_handle_inflow;
330 /*==============================FLOWS=============================*/
332 /********************************************************************
333  * FUNCTION PURPOSE:  Netapi internal function to find a free slot for a flow
334  ********************************************************************
335  * DESCRIPTION: Netapi internal function to find a free slot for a flow
336  ********************************************************************/
337 static int netapip_netcpCfgFindFlowSlot( NETAPI_NWAL_GLOBAL_CONTEXT_T *p)
339     int i;
340     //find a free entry
341     hplib_mSpinLockLock(&netapi_netcp_cfg_lock);
342     for(i=0;i<TUNE_NETAPI_MAX_FLOWS;i++)
343     {
344         if (!p->flows[i].in_use)
345         {
346             p->flows[i].in_use = 2; /* pending */
347             hplib_mSpinLockUnlock(&netapi_netcp_cfg_lock);
348             return i;
349         }
350     }
351     hplib_mSpinLockUnlock(&netapi_netcp_cfg_lock);
352     return -1;
355 /********************************************************************
356  * FUNCTION PURPOSE:  Netapi internal function to find delete a flow from flow list
357  ********************************************************************
358  * DESCRIPTION: Netapi internal function to find delete a flow from flow list
359  ********************************************************************/
360 static void netapip_netcpCfgDeleteFlow(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
361                                        int slot)
363     if ((slot >=0 ) && (slot < TUNE_NETAPI_MAX_FLOWS))
364     {
365         p->flows[slot].in_use = 0;
366     }
369 /********************************************************************
370  * FUNCTION PURPOSE:  Netapi internal function to  insert a flow to the  flow list
371  ********************************************************************
372  * DESCRIPTION: Netapi internal function to  delete a flow from flow list
373  ********************************************************************/
374 static NETCP_CFG_FLOW_HANDLE_T netapip_netcpCfgInsertFlow(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
375                                                           int slot,
376                                                           int dma_engine,
377                                                           void * handle)
379     p->flows[slot].in_use=1;
380     p->flows[slot].handle = handle;
381     p->flows[slot].flow.flowid  = Cppi_getFlowId(handle);
382     p->flows[slot].flow.dma_engine  = dma_engine;
383         return (NETCP_CFG_FLOW_HANDLE_T) &p->flows[slot].flow;
386 /********************************************************************
387  * FUNCTION PURPOSE:  Netapi internal function to find entry matching the flowid
388  ********************************************************************
389  * DESCRIPTION: Netapi internal function to find entry matching the flowid. Returns
390  * the slot number and the cPPI handle.
391  ********************************************************************/
392 static int netapip_netcpCfgFindFlow(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
393                                     int flowid,  
394                                     int dma_engine,
395                                     void ** handle) 
397     int i;
398     *handle=NULL;
399     hplib_mSpinLockLock(&netapi_netcp_cfg_lock);
400     for(i=0;i<TUNE_NETAPI_MAX_FLOWS;i++)
401     {
402        if ((p->flows[i].in_use)&&
403            (p->flows[i].flow.flowid == flowid)&&
404            (p->flows[i].flow.dma_engine == dma_engine))
405         {
406             *handle = p->flows[i].handle;
407             hplib_mSpinLockUnlock(&netapi_netcp_cfg_lock);
408             return i;
409         }
410     }
411     hplib_mSpinLockUnlock(&netapi_netcp_cfg_lock);
412    return -1;
417 /*============================IP ADDRESSES==========================*/
419 /***************************************************************************
420  * FUNCTION PURPOSE:  Netapi internal function to find a free slot for IP rule in IP slot list
421  ***************************************************************************
422  * DESCRIPTION: NNetapi internal function to find a free slot for IP rule in IP slot list
423  ***************************************************************************/
424 static int netapip_netcpCfgFindIpSlot(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
425                                       int iface_no)
427     int i;
429     //find a free entry
430     hplib_mSpinLockLock(&netapi_netcp_cfg_lock);
431     for(i=0;i<TUNE_NETAPI_MAX_NUM_IP;i++)
432     {
433         if (!p->ips[i].in_use)
434         {
435             p->ips[i].in_use = 2; //pending
436             hplib_mSpinLockUnlock(&netapi_netcp_cfg_lock);
437             return i;
438         }
439     }
440     hplib_mSpinLockUnlock(&netapi_netcp_cfg_lock);
441     return -1;
444 /***************************************************************************
445  * FUNCTION PURPOSE:  Netapi internal function to insert an IP address into interface
446  ***************************************************************************
447  * DESCRIPTION: Netapi internal function to insert an IP address into interface
448  ***************************************************************************/
449 static void netapip_netcpCfgInsertIp(NETAPI_NWAL_GLOBAL_CONTEXT_T *p, 
450                                      nwal_IpType ipType,
451                                      nwalIpAddr_t *ip_addr, 
452                                      nwalIpOpt_t *ip_qualifiers, 
453                                      int iface_no,
454                                      int ip_slot,
455                                      void * handle,
456                                      void * user_data)
458     p->ips[ip_slot].in_use=1;
459     memcpy(&p->ips[ip_slot].ip_addr, ip_addr, sizeof(nwalIpAddr_t));
460     if(ip_qualifiers)
461     {
462         memcpy(&p->ips[ip_slot].ip_qualifiers, ip_qualifiers, sizeof(nwalIpOpt_t));
463     }
464     else
465     {
466         memset(&p->ips[ip_slot].ip_qualifiers, 0, sizeof(nwalIpOpt_t));
467     }
468     p->ips[ip_slot].ip_type = ipType;
469     p->ips[ip_slot].nwal_handle = handle;
470     p->ips[ip_slot].user_data = user_data;
471     
474 /***************************************************************************
475  * FUNCTION PURPOSE:  Netapi internal function to free IP slot associated with IP address
476  ***************************************************************************
477  * DESCRIPTION: Netapi internal function to free IP slot associated with IP address
478  ***************************************************************************/
479 static void netapip_netcpCfgDeleteIp(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
480                                      int iface_no,
481                                      int ip_slot)
483     if ((ip_slot >=0) &&(ip_slot <=TUNE_NETAPI_MAX_NUM_IP))
484     {
485         p->ips[ip_slot].in_use=0;
486     }
489 /***************************************************************************
490  * FUNCTION PURPOSE:  Netapi internal function to get IP handle associated with IP address
491  ***************************************************************************
492  * DESCRIPTION: Netapi internal function to get IP handle associated with IP address
493  ***************************************************************************/
494 static void *netapip_netcpCfgGetIpHandle(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
495                                          int iface_no,
496                                          int ip_slot)
498     if ((ip_slot <0)||(ip_slot>=TUNE_NETAPI_MAX_NUM_IP))
499         return NULL;
500     if (!p->ips[ip_slot].in_use)
501         return NULL;
502     return (void *) p->ips[ip_slot].nwal_handle;
505 /*==========================MAC INTERFACES======================*/
509 /*******************************************************************************
510  * FUNCTION PURPOSE:  Netapi internal function to insert an interface to the interface list
511  *******************************************************************************
512  * DESCRIPTION:  Netapi internal function to insert an interface to the interface list
513  *******************************************************************************/
514 static void netapip_netcpCfgInsertMac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
515                                       unsigned char * p_mac,
516                                       int iface_no, 
517                                       int state, NETCP_CFG_VLAN_T vlan, 
518                                       void * handle)
520     if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_NUM_MAC))
521     {
522         memset(&p->interfaces[iface_no],0,sizeof(NETCP_INTERFACE_T));
523         p->interfaces[iface_no].in_use = 1;
524         memcpy(&p->interfaces[iface_no].mac[0], p_mac,6);
525         p->interfaces[iface_no].state = state;
526         //todo p->interfaces[iface_no].vlan = vlan;
527         p->interfaces[iface_no].nwal_handle = handle; //save handle assoicated with this rule
528         netapi_Log("netapip_netcpCfgInsertMac, global context 0x%x\n", p);
529     }
530     else 
531         netapi_Log(">netapip_netcpCfgInsertMac insert interface # out of range %d\n",iface_no);
535 /*******************************************************************************
536  * FUNCTION PURPOSE:  Netapi internal function to get handle associated with interface
537  *******************************************************************************
538  * DESCRIPTION:  Netapi internal function to get handle associated with interface
539  *******************************************************************************/
540 void* netapip_netcpCfgGetMacHandle(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
541                                    int iface_no)
543     if (iface_no == NETCP_CFG_NO_INTERFACE)
544     {
545         return NULL;
546     }
547     if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_NUM_MAC))
548     {
549         return NULL;
550     }
551     else if ( p->interfaces[iface_no].in_use)
552     {
553       return (void *) p->interfaces[iface_no].nwal_handle;
554     }
555     //no valid entry in slot
556     return NULL;
558 /*******************************************************************************
559  * FUNCTION PURPOSE:  Netapi internal function to delete interface from interface list
560  *******************************************************************************
561  * DESCRIPTION:  Netapi internal function to delete interface from interface list
562  *******************************************************************************/
563 static void netapip_netcpCfgDeleteMac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
564                                       int iface_no)
566     if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_NUM_MAC))
567     {
568         p->interfaces[iface_no].in_use = 0;
569     }
572 /*========================CLASSIFIERS==========================*/
574 /*******************************************************************************
575  * FUNCTION PURPOSE:  Netapi internal function to find a free slot for classifier rule
576  *******************************************************************************
577  * DESCRIPTION:  Netapi internal function to find a free slot for classifier rule
578  *******************************************************************************/
579 static int netapip_netcpCfgFindClassSlot( NETAPI_NWAL_GLOBAL_CONTEXT_T *p)
581     int i;
582     hplib_mSpinLockLock(&netapi_netcp_cfg_lock);
583     for(i=0;i<TUNE_NETAPI_MAX_CLASSIFIERS;i++)
584     {
585         if (!p->classi[i].in_use)
586         {
587             p->classi[i].in_use = 2; //pending
588             hplib_mSpinLockUnlock(&netapi_netcp_cfg_lock);
589             return i;
590         }
591     }
592     hplib_mSpinLockUnlock(&netapi_netcp_cfg_lock);
593     return -1;
595 /*******************************************************************************
596  * FUNCTION PURPOSE:  Netapi internal function to find a delete a classifer from classifer list
597  *******************************************************************************
598  * DESCRIPTION:  Netapi internal function to find a delete a classifer from classifer list
599  *******************************************************************************/
600 static void netapip_netcpCfgDeleteClass(
601          NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
602          int class_slot )
604     if ((class_slot <0 ) || (class_slot >= TUNE_NETAPI_MAX_CLASSIFIERS))
605     {
606         return;
607     }
608     p->classi[class_slot].in_use=0;
611 /*******************************************************************************
612  * FUNCTION PURPOSE:  Netapi internal function to find a insert a classifer to classifer list
613  *******************************************************************************
614  * DESCRIPTION:  Netapi internal function to find a insert a classifer to classifer list
615  *******************************************************************************/
616 static void netapip_netcpCfgInsertClass(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
617                                         int class_slot,
618                                         int class_type,
619                                         void * L2_handle,
620                                         void * L3_handle,
621                                         void * L4_handle,
622                                         void * user_data)
624     if ((class_slot >=0 ) && (class_slot < TUNE_NETAPI_MAX_CLASSIFIERS))
625     {
626         p->classi[class_slot].in_use=1;
627         p->classi[class_slot].nwal_L2_handle = L2_handle;
628         p->classi[class_slot].nwal_L3_handle = L3_handle;
629         p->classi[class_slot].nwal_L4_handle = L4_handle;
630         p->classi[class_slot].class_type = class_type;
631         p->classi[class_slot].user_data = user_data;
632     }
635 /*******************************************************************************
636  * FUNCTION PURPOSE:  Netapi internal function to get L4 nwal handle for classifier
637  *******************************************************************************
638  * DESCRIPTION:  Netapi internal function to get L4 nwal handle for classifier
639  *******************************************************************************/
640 static void *netapip_netcpCfgGetL4Handle(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
641                                          int class_slot)
643     if ((class_slot <0 ) || (class_slot >= TUNE_NETAPI_MAX_CLASSIFIERS))
644     {
645         return NULL;
646     }
647     if (!p->classi[class_slot].in_use)
648     {
649         return NULL;
650     }
651     return p->classi[class_slot].nwal_L4_handle;
654 /*******************************************************************************
655  * FUNCTION PURPOSE:  Netapi internal function to get L3 nwal handle for classifier
656  *******************************************************************************
657  * DESCRIPTION:  Netapi internal function to get L3 nwal handle for classifier
658  *******************************************************************************/
659 static void *netapip_netcpCfgGetL3Handle(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
660                                          int class_slot)
662     if ((class_slot <0 ) || (class_slot >= TUNE_NETAPI_MAX_CLASSIFIERS))
663     {
664         return NULL;
665     }
666     if (!p->classi[class_slot].in_use)
667     {
668         return NULL;
669     }
670     return p->classi[class_slot].nwal_L3_handle;
674 /***********************************************************************************/
675 /****************************************API****************************************/
676 /***********************************************************************************/
679 /********************************************************************
680  * FUNCTION PURPOSE:  API to request statistics from NETCP
681  ********************************************************************
682  * DESCRIPTION:  API to request statistics from NETCP
683  ********************************************************************/
684 void netapi_netcpCfgReqStats(NETAPI_T  h, 
685                              NETCP_CFG_STATS_CB cb,
686                              int doClear,
687                              int *err) 
689     nwal_RetValue ret;
690     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
691     NetapiNwalTransInfo_t *pTransInfo;
692     nwal_TransID_t     transId;
693     if ((!n) || (!cb))
694     {
695         *err = NETAPI_ERR_BAD_INPUT;
696         return ;
697     }
698     *err =0;
700     pTransInfo = netapip_getFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &transId);
701     if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return ;}
702     pTransInfo->transType = NETAPI_NWAL_HANDLE_STAT_REQUEST;
703     pTransInfo->netapi_handle = h;
704     n->nwal_local.stats_cb = cb;
705     ret = nwal_getPAStats( ((NETAPI_GLOBAL_T *) n->global)->nwal_context.nwalInstHandle,
706                               transId,
707                               NULL,
708                               doClear);
709     if(ret !=  nwal_OK)
710     {
711         //pTransInfo->inUse = nwal_FALSE;
712         *err = NETAPI_ERR_BUSY;  //no resources??
713         netapi_Log("> netapi_netcpCfg reqStats failed, err=%d\n",ret);
714     }
715     netapip_freeTransInfo(pTransInfo);
717 /********************************************************************
718  * FUNCTION PURPOSE:  API to create a MAC interface
719  ********************************************************************
720  * DESCRIPTION:  API to create a MAC interface
721  ********************************************************************/
722 NETCP_CFG_MACIF_T  netapi_netcpCfgCreateMacInterface(NETAPI_T  h,
723                                                      uint8_t *p_mac,
724                                                      int  iface_no, 
725                                                      int switch_port, 
726                                                      NETCP_CFG_ROUTE_HANDLE_T  route,
727                                                      NETCP_CFG_VLAN_T  vlan,  //future
728                                                      int state,  //0=down, 1=up  //ignored
729                                                      int * err)
731     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
732     nwalMacParam_t   MacInfo=
733     {
734         0,      /* validParams */
735         0,      /* ifNum */
736         0,      /* vlanId      */
737         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },      /* Local mac */
738         NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */
739         NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */
740         CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */
741         QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */
742     };
744     nwal_RetValue       retValue;
745     NetapiNwalTransInfo_t *pTransInfo;
746     nwal_TransID_t     trans_id;
748     if ((!n) || (!p_mac)) {*err = NETAPI_ERR_BAD_INPUT; return -1;}
749     *err =0;
751     pTransInfo = netapip_getFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
752     if (!pTransInfo)
753     {
754         *err =  NETAPI_ERR_BUSY;
755         return -1;
756     }
757     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC;
758     pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
759     pTransInfo->inUse = nwal_TRUE;
760     pTransInfo->netapi_handle = h;
762     /* set up MacInfo */
763     memcpy(&MacInfo.macAddr,p_mac,6); 
764     /* todo: vlan */
765     if (switch_port)
766     {
767         MacInfo.validParams =NWAL_SET_MAC_VALID_PARAM_IFNUM ;
768         MacInfo.ifNum = switch_port;  /* */
769     }
771     if (route != NULL)
772     {
773         netapip_netcpCfgBuildRoute(route,&MacInfo.appRxPktFlowId, &MacInfo.appRxPktQueue);
774     }
775     retValue = nwal_setMacIface( ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
776                                   trans_id,
777                                   (nwal_AppId) (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no),
778                                   &MacInfo,
779                                   &pTransInfo->handle);
780     if(retValue !=  nwal_OK)
781     {
782         *err = NETAPI_ERR_NWAL_ERR0;
783         netapi_Log ("netapi_netcpCfg - ERROR: nwal_setMacIface returned Error Code %d\n",
784                     retValue);
785         netapip_freeTransInfo(pTransInfo);
786         return -1;
787     }
789     //wait here until its done since scheduler isn't running yet most likely..
790     // todo:  make this handled by scheduler poll later ??
791     if(trans_id != NWAL_TRANSID_SPIN_WAIT)
792     {
793         n->nwal_local.numPendingCfg++;
794         while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
795                 (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_OPEN))
796         {
797             // if response is there, then this poll squirts out in the CTl poll callback, 
798             // which handles the rest (including decrmenting #pending!!
799             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
800         }
801         if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
802         {
803             netapip_freeTransInfo(pTransInfo);
804             *err = NETAPI_ERR_PA_FW;
805             netapi_Log (">netapi_netcpCfgCreateMacInterface - ERROR returned by NETCP PA firmware %d\n",
806                     *err);
807             return -1;
808         }
810     }
811     netapi_Log ("netapi_netcpCfg: MAC i/f %d added\n", iface_no);
812     netapip_netcpCfgInsertMac(&netapi_get_global()->nwal_context, 
813                           p_mac, iface_no, state,vlan,
814                           (void *) pTransInfo->handle);
815     netapip_freeTransInfo(pTransInfo);
816     return  (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no);
819 /********************************************************************
820  * FUNCTION PURPOSE:  API to delete MAC  interface
821  ********************************************************************
822  * DESCRIPTION:  API to delete MAC  interface
823  ********************************************************************/
824 void netapi_netcpCfgDelMac(NETAPI_T h,
825                            int iface_no,
826                            int *err)
828     nwal_RetValue ret;
829     NetapiNwalTransInfo_t *pTransInfo;
830     nwal_TransID_t     trans_id;
831     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
832     void * ifHandle;
834     //get the nwal handle assoicated with this iface
835     ifHandle = netapip_netcpCfgGetMacHandle(&netapi_get_global()->nwal_context, iface_no );
836     if(!ifHandle) 
837     {
838         *err = NETAPI_ERR_BAD_INPUT; return ;
839     }
840     *err =0;
842     //get a transaction id
843     pTransInfo = netapip_getFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
844     if (!pTransInfo)
845     {
846         *err =  NETAPI_ERR_BUSY;
847         return ;
848     }
849     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC;
850     pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING;
851     pTransInfo->inUse = nwal_TRUE;
852     pTransInfo->netapi_handle = h;
854     //issue request
855     ret = nwal_delMacIface(
856                 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
857                 trans_id,
858                 ifHandle);
859     if(ret !=  nwal_OK)
860     {
861         *err = NETAPI_ERR_NWAL_ERR0;
862         netapi_Log ("netapi_netcpCfg - ERROR: nwal_delMacIface returned Error Code %d\n",
863                     ret);
864         netapip_freeTransInfo(pTransInfo);
865         return;
866     }
867     //wait here until its done since scheduler isn't running yet most likely..
868     // todo:  make this handled by scheduler poll later ??
869     if(trans_id != NWAL_TRANSID_SPIN_WAIT)
870     {
871         n->nwal_local.numPendingCfg++;
872         while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
873                 (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_IDLE))
874         {
875             // if response is there, then this poll squirts out in the CTl poll callback, 
876             // which handles the rest (including decrmenting #pending!!
877             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
878         }
879         if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
880         {
881             netapip_freeTransInfo(pTransInfo);
882             *err = NETAPI_ERR_PA_FW;
883             netapi_Log (">netapi_netcpCfgCreateMacInterface - ERROR returned by NETCP PA firmware %d\n",
884                     *err);
885             netapip_netcpCfgDeleteMac(&netapi_get_global()->nwal_context,  iface_no);
886             return;
887         }
888     }
889     netapi_Log ("netapi_netcpCfg: MAC i/f %d deleted\n",iface_no);
890     netapip_freeTransInfo(pTransInfo);
891     //zap the entry
892     netapip_netcpCfgDeleteMac(&netapi_get_global()->nwal_context,  iface_no);
893     return ;
897 /********************************************************************
898  * FUNCTION PURPOSE:  NETAPi internal function to Add IP to MAC interface
899  ********************************************************************
900  * DESCRIPTION:  NETAPi internal function to Add IP to MAC interface
901  ********************************************************************/
902 static NETCP_CFG_IP_T  netapip_netcpCfgAddIpInternal(NETAPI_T  h,
903                                                      int  iface_no,
904                                                      nwal_IpType ipType,
905                                                      nwalIpAddr_t  * ip_addr,
906                                                      nwalIpOpt_t * ip_qualifiers,
907                                                      NETCP_CFG_ROUTE_HANDLE_T  route,/*NULL for default*/
908                                                      void * user_data,
909                                                      int * err,
910                                                      int  flag) /*TRUE: add IP to iface,
911                                                      FALSE: add IP as part of classifier */
912                             {
913     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
914     void * n_handle=NULL;
915     nwalIpParam_t    nwalIpParam= {
916     pa_IPV4,      /* IP Type */
917     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Dest IP */
918     { 0x0,0,0,0},/* IP Options */
919     NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */
920     NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */
921     CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */
922     QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */
923 };
924     nwal_RetValue       retValue;
925     NetapiNwalTransInfo_t *pTransInfo;
926     nwal_TransID_t     trans_id;
927     int ip_slot=-1;
928     NETCP_CFG_IP_T ip_rule_id;
929     NETCP_CFG_IP_T temp;
931     //verify that iface has been configured 
932     if (iface_no != NETCP_CFG_NO_INTERFACE)
933     {
934         if ((iface_no<0) || (iface_no>= TUNE_NETAPI_MAX_NUM_MAC)) {*err = NETAPI_ERR_BAD_INPUT; return -1;}
935     }
937     if (iface_no != NETCP_CFG_NO_INTERFACE)
938     {
939         netapi_Log("netapip_netcpCfgAddIpInternal, in_use %d\n", netapi_get_global()->nwal_context.interfaces[iface_no].in_use);
940         netapi_Log("netcp-cfgAddIpInternal, p 0x%x\n", &netapi_get_global()->nwal_context);
941         if(netapi_get_global()->nwal_context.interfaces[iface_no].in_use)
942         {
943             n_handle =  netapi_get_global()->nwal_context.interfaces[iface_no].nwal_handle;
944         }
945         else
946         {
947             *err = NETAPI_ERR_BAD_INPUT;
948             return -1;
949         }
950     }
951     if (flag) //if adding IP to MAC then reserve a slot to save info
952     {
953         //find free slot for IP & reserve
954          ip_slot= netapip_netcpCfgFindIpSlot(&netapi_get_global()->nwal_context, 
955                                    iface_no);
956         if (ip_slot <0) 
957         {
958             *err= NETAPI_ERR_NOMEM;  //no room 
959             return -1;
960         }
961     }
963     //get a transaction object for config action
964     pTransInfo = netapip_getFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
965     if (!pTransInfo)
966     {
967         *err =  NETAPI_ERR_BUSY;
968         if (flag)
969         {
970             netapip_netcpCfgDeleteIp(&netapi_get_global()->nwal_context,
971                          iface_no,
972                          ip_slot);
973         }
974         return -1;
975     }
976     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;
977     pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
978     pTransInfo->inUse = nwal_TRUE;
979     pTransInfo->netapi_handle = h;
981     //build nwalIpParam
982     memcpy(&nwalIpParam.locIpAddr,ip_addr, sizeof(nwalIpAddr_t));
983     nwalIpParam.ipType=ipType;
984     if(route)
985     {
986         netapip_netcpCfgBuildRoute(route,&nwalIpParam.appRxPktFlowId, &nwalIpParam.appRxPktQueue);
987     }
988     else{} //use nwal defaults
990     if (ip_qualifiers)
991         memcpy(&nwalIpParam.ipOpt,ip_qualifiers, sizeof(nwalIpOpt_t)); 
992     else
993         memset(&nwalIpParam.ipOpt,0, sizeof(nwalIpOpt_t));
995     //build the rule id that will be returned when a packet matches 
996     if (flag)
997         ip_rule_id = NETAPI_NETCP_MATCH_GENERIC_IP | iface_no | ((ip_slot&& NETAPI_NETCP_MATCH_ID_MASK) << NETAPI_NETCP_MATCH_ID_SHIFT);
998     else
999         ip_rule_id = (NETAPI_NETCP_MATCH_CLASS_L3 | iface_no);
1001     retValue = nwal_setIPAddr(   netapi_get_global()->nwal_context.nwalInstHandle,
1002                                   trans_id,
1003                                   (nwal_AppId) (ip_rule_id),
1004                                   n_handle,
1005                                   &nwalIpParam,
1006                                   &pTransInfo->handle);
1008     if(retValue !=  nwal_OK)
1009     {
1010         *err = NETAPI_ERR_NWAL_ERR0;
1011         netapi_Log ("netcp_cfg: nwal_setIP returned Error Code %d\n",
1012                     retValue);
1013         netapip_freeTransInfo(pTransInfo);
1014         //zap the entry
1015         if (flag)
1016         {
1017             netapip_netcpCfgDeleteIp(&netapi_get_global()->nwal_context,
1018                          iface_no,
1019                          ip_slot);
1020         }
1021         return -1;
1022     }
1023     //wait here until its done since scheduler isn't running yet most likely..
1024     // todo:  make this handled by scheduler poll later ??
1025     if(trans_id != NWAL_TRANSID_SPIN_WAIT)
1026     {
1027         n->nwal_local.numPendingCfg++;
1028         while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
1029         (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_OPEN))
1030         {
1031             // if response is there, then this poll squirts out in the CTl poll callback, 
1032             // which handles the rest (including decrmenting #pending!!
1033             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
1034         }
1035         if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
1036         {
1037             netapip_freeTransInfo(pTransInfo);
1038             *err = NETAPI_ERR_PA_FW;
1039             netapi_Log (">netapip_netcpCfgAddIpInternal - ERROR returned by NETCP PA firmware %d\n", *err);
1040             return -1;
1041         }
1042     }
1043     if (flag)
1044     {
1045         netapi_Log ("netcp_cfg: IP added to interface %d (slot%d)\n", iface_no, ip_slot);
1046         netapip_netcpCfgInsertIp(&netapi_get_global()->nwal_context, ipType, 
1047                           ip_addr, ip_qualifiers, iface_no, ip_slot,
1048                           pTransInfo->handle, user_data);
1049     }
1051     temp = (NETCP_CFG_IP_T) pTransInfo->handle;
1052     netapip_freeTransInfo(pTransInfo);
1053     return  (flag ? ip_rule_id:  temp);
1056 /********************************************************************
1057  * FUNCTION PURPOSE:  API to Add IP to MAC interface
1058  ********************************************************************
1059  * DESCRIPTION:  API to Add IP to MAC interface
1060  ********************************************************************/
1061 NETCP_CFG_IP_T  netapi_netcpCfgAddIp(NETAPI_T                  h,
1062                                      int                       iface_no,
1063                                      nwal_IpType               ipType,
1064                                      nwalIpAddr_t*             ip_addr,
1065                                      nwalIpOpt_t*              ip_qualifiers,
1066                                      NETCP_CFG_ROUTE_HANDLE_T  route,  //NULL for default
1067                                      void*                     user_data,
1068                                      int*                      err)
1070     return netapip_netcpCfgAddIpInternal(h, iface_no, ipType, ip_addr, 
1071                                          ip_qualifiers, route, user_data,err, 1);
1074 /********************************************************************
1075  * FUNCTION PURPOSE:  NETAPI internal function to detach IP from MAC interface
1076  ********************************************************************
1077  * DESCRIPTION:  NETAPI internal function to detach IP from MAC interface
1078  ********************************************************************/
1079 static void netapip_netcpCfgDelIpInternal(NETAPI_T h, 
1080                                           int iface_no,
1081                                           nwal_IpType ipType,
1082                                           nwalIpAddr_t  * ip_addr,
1083                                           nwalIpOpt_t * ip_qualifiers, 
1084                                           NETCP_CFG_IP_T  ip_rule_id,
1085                                           int *err, 
1086                                           void * handle,   /* if flag==0, handle must be valid */
1087                                           int flag)        /* flag==0 => delete IP rule that was part of classifier, not interface */
1089     nwal_RetValue ret;
1090     NetapiNwalTransInfo_t *pTransInfo;
1091     nwal_TransID_t     trans_id;
1092     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
1093     void * ifHandle;
1094     int ip_slot = netapi_cfgGetMatchId(ip_rule_id);
1096     //get the nwal handle assoicated with this ip   
1097     if (flag)
1098     {
1099         ifHandle = netapip_netcpCfgGetIpHandle(
1100                                         &netapi_get_global()->nwal_context, iface_no,
1101                                         ip_slot );
1102     }
1103     else 
1104     {
1105         ifHandle = handle;
1106     }
1107     if(!ifHandle)
1108     {
1109         *err = NETAPI_ERR_BAD_INPUT;
1110         return ;
1111     }
1112     *err =0;
1114     //get a transaction id
1115     pTransInfo = netapip_getFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
1116     if (!pTransInfo)
1117     {
1118         *err =  NETAPI_ERR_BUSY;
1119         return;
1120     }
1121     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;
1122     pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING;
1123     pTransInfo->inUse = nwal_TRUE;
1124     pTransInfo->netapi_handle = h;
1125     //issue request
1126     ret = nwal_delIPAddr(
1127                 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
1128                 trans_id,
1129                 ifHandle);
1130     if(ret !=  nwal_OK)
1131     {
1132         *err = NETAPI_ERR_NWAL_ERR0;
1133         netapi_Log ("netcp_cfg - ERROR: nwal_delMacIface returned Error Code %d\n",
1134                     ret);
1135         netapip_freeTransInfo(pTransInfo);
1136         return ;
1137     }
1138     //wait here until its done since scheduler isn't running yet most likely..
1139     // todo:  make this handled by scheduler poll later ??
1140     if(trans_id != NWAL_TRANSID_SPIN_WAIT)
1141     {
1142         n->nwal_local.numPendingCfg++;
1143         while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
1144                 (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_IDLE))
1145         {
1146             // if response is there, then this poll squirts out in the CTl poll callback, 
1147             // which handles the rest (including decrmenting #pending!!
1148             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
1149         }
1150         if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
1151         {
1152             netapip_freeTransInfo(pTransInfo);
1153             *err = NETAPI_ERR_PA_FW;
1154             netapi_Log (">netapip_netcpCfgDelIpInternal - ERROR returned by NETCP PA firmware %d\n", *err);
1155             return;
1156         }
1157     }
1159     netapip_freeTransInfo(pTransInfo);
1161     //zap the entry
1162     if (flag)
1163         netapip_netcpCfgDeleteIp(&netapi_get_global()->nwal_context,  
1164                          iface_no,
1165                          ip_slot);
1166     return ;
1169 /********************************************************************
1170  * FUNCTION PURPOSE:  API to detach IP from MAC interface
1171  ********************************************************************
1172  * DESCRIPTION:  API  to detach IP from MAC interface
1173  ********************************************************************/
1174 void netapi_netcpCfgDelIp(NETAPI_T              h,
1175                           int                   iface_no,
1176                           nwal_IpType           ipType,
1177                           nwalIpAddr_t*         ip_addr,
1178                           nwalIpOpt_t*          ip_qualifiers,
1179                           NETCP_CFG_IP_T        ip_rule_id,
1180                           int*                  err)
1182     netapip_netcpCfgDelIpInternal( h, iface_no, ipType,
1183                   ip_addr, ip_qualifiers, ip_rule_id,
1184                   err, NULL, 1);
1185     return;
1189 /********************************************************************
1190  * FUNCTION PURPOSE:  API to attach a classifier rule to NETCP
1191  ********************************************************************
1192  * DESCRIPTION:  API to attach a classifier rule to NETCP
1193  ********************************************************************/
1194 NETCP_CFG_CLASS_T netapi_netcpCfgAddClass(NETAPI_T                  h,
1195                                           NETCP_CFG_CLASSIFIER_T*   p_class,
1196                                           NETCP_CFG_ROUTE_HANDLE_T  route,
1197                                           int                       action, 
1198                                           void*                     user_data, 
1199                                           int*                      err)
1201     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
1202     void * l3_handle=NULL;  //ip handle
1203     nwal_RetValue       retValue;
1204     NetapiNwalTransInfo_t *pTransInfo;
1205     nwal_TransID_t     trans_id;
1206     int class_slot=-1;
1207     int iface_no;
1208     int ip_slot=-1;
1209     NETCP_CFG_CLASS_T  classHandle;  //returned by us
1210     nwal_appProtoType_t proto;
1211     nwalRxConnCfg_t tempCfg=
1212     {
1213         0,  //nwal_handle: to be filled in
1214         {0}, // l4 ports: to be filled in
1215         0,  //core id (NA)
1216         0, //action
1217         CPPI_PARAM_NOT_SPECIFIED, //flow id
1218         QMSS_PARAM_NOT_SPECIFIED, //dest queue
1219     };
1221     *err = NETAPI_ERR_OK;
1223     if(!p_class)
1224     {
1225         *err=NETAPI_ERR_BAD_INPUT;
1226         return -1;
1227     }
1228     switch(p_class->classType)
1229     {
1230         default:
1231             netapi_Log(">netapi_netcpCfg : classifier type %d not supported\n",p_class->classType);
1232             break;
1233         case(NETCP_CFG_CLASS_TYPE_L3_L4):
1234         case(NETCP_CFG_CLASS_TYPE_L4):
1235             //assume just type l4 only (L2, L3 defined by iface, l3 id )
1236             iface_no = p_class->u.c_l4.iface;
1237             if (p_class->classType== NETCP_CFG_CLASS_TYPE_L4)
1238             {
1239                 ip_slot = netapi_cfgGetMatchId(p_class->u.c_l4.ip);
1240             }
1242             //verify that iface has been configured 
1243             if (iface_no != NETCP_CFG_NO_INTERFACE)
1244             {
1245                 if(!netapi_get_global()->nwal_context.interfaces[iface_no].in_use)
1246                 {
1247                     *err = NETAPI_ERR_BAD_INPUT;
1248                     return -1;
1249                 }
1250             }
1252             if (p_class->classType== NETCP_CFG_CLASS_TYPE_L4)
1253             {
1254                 //verify that ip has been configured and get its handle
1255                 l3_handle = netapip_netcpCfgGetIpHandle(
1256                       &netapi_get_global()->nwal_context, iface_no,
1257                       ip_slot );
1258             }
1259             else
1260             {
1261                 nwalIpParam_t tempParam=
1262                 {
1263                     pa_IPV4,      /* IP Type */
1264                     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Dest IP */
1265                     { 0x0,0,0,0},/* IP Options */
1266                     NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */
1267                     NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */
1268                     CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */
1269                     QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */
1270                 };
1271                 //build nwalIpParam
1272                 memcpy(&tempParam.locIpAddr,p_class->u.c_l3_l4.ip_addr, sizeof(nwalIpAddr_t));
1273                 tempParam.ipType=p_class->u.c_l3_l4.ipType;
1274                 //use nwal defauls for route
1275                 if (p_class->u.c_l3_l4.ip_qualifiers)
1276                     memcpy(&tempParam.ipOpt,p_class->u.c_l3_l4.ip_qualifiers, sizeof(nwalIpOpt_t));
1277                 else
1278                     memset(&tempParam.ipOpt,0, sizeof(nwalIpOpt_t));
1280                 //find if we have a matching L3 handle for IP classifier; if not create it
1281                 retValue =  nwal_getIPAddr (((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
1282                             &tempParam,
1283                             netapip_netcpCfgGetMacHandle(&netapi_get_global()->nwal_context, iface_no ),
1284                             &l3_handle); 
1285                 if (retValue != nwal_TRUE) 
1286                 {
1287                     int ret;
1288                     //**NEW IP RULE  
1289                     //need to attach this IP RULE to the MAC
1290                     l3_handle= (void *) netapip_netcpCfgAddIpInternal(
1291                                       h, iface_no, 
1292                                       p_class->u.c_l3_l4.ipType,
1293                                       p_class->u.c_l3_l4.ip_addr,
1294                                       p_class->u.c_l3_l4.ip_qualifiers,
1295                                       p_class->u.c_l3_l4.p_fail_route,
1296                                       user_data,
1297                                       &ret,
1298                                       FALSE);
1299                     if(!ret)
1300                     {
1301                         l3_handle=NULL;
1302                     }
1303                 }
1304             }
1305             if(!l3_handle)
1306             {
1307                 *err = NETAPI_ERR_BAD_INPUT; 
1308                 return -1 ;
1309             }
1312             //find free slot for CLASS & reserve
1313             class_slot= netapip_netcpCfgFindClassSlot(&netapi_get_global()->nwal_context);
1314             if(class_slot<0) {*err = NETAPI_ERR_NOMEM; return -1;}
1315             classHandle = NETAPI_NETCP_MATCH_CLASS |
1316                           (class_slot << NETAPI_NETCP_MATCH_ID_SHIFT) | 
1317                           (iface_no & NETAPI_NETCP_MATCH_LOGICAL_MAC_IFACE_MASK);
1318             //build request from template
1319             tempCfg.inHandle=l3_handle;
1320             if (p_class->classType== NETCP_CFG_CLASS_TYPE_L4)
1321             {
1322                 memcpy(&tempCfg.appProto,&p_class->u.c_l4.appProto,sizeof(nwalAppProto_t));
1323                 proto = p_class->u.c_l4.proto;
1324             }
1325             else
1326             {
1327                 memcpy(&tempCfg.appProto,&p_class->u.c_l3_l4.appProto,sizeof(nwalAppProto_t));
1328                 proto = p_class->u.c_l3_l4.proto;
1329             }
1331             tempCfg.matchAction = (action==NETCP_CFG_ACTION_TO_SW)  ? NWAL_MATCH_ACTION_HOST : NWAL_MATCH_ACTION_DISCARD;
1332             if (route)
1333             {
1334                 netapip_netcpCfgBuildRoute(route,&tempCfg.appRxPktFlowId, &tempCfg.appRxPktQueue);
1335             }
1338             //get a transaction id
1339             pTransInfo = netapip_getFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
1340             if (!pTransInfo)
1341             {
1342                 *err =  NETAPI_ERR_BUSY; 
1343                 return -1;
1344             }
1345             pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_PORT;
1346             pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
1347             pTransInfo->inUse = nwal_TRUE;
1348             pTransInfo->netapi_handle = h;
1349                 //issue request
1350             retValue = nwal_addConn(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
1351                             trans_id,
1352                             (nwal_AppId) classHandle,
1353                             proto,
1354                             &tempCfg,
1355                             NULL,
1356                             &pTransInfo->handle);
1357             if(retValue !=  nwal_OK)
1358             {
1359                 *err = NETAPI_ERR_NWAL_ERR0;
1360                 netapi_Log ("netcp_cfg - ERROR: nwal_delMacIface returned Error Code %d\n",
1361                         retValue);
1362                 netapip_freeTransInfo(pTransInfo);
1363                 netapip_netcpCfgDeleteClass(&netapi_get_global()->nwal_context, class_slot);
1364                 return -1;
1365             }
1366             //wait here until its done since scheduler isn't running yet most likely..
1367            // todo:  make this handled by scheduler poll later ??
1368             if(trans_id != NWAL_TRANSID_SPIN_WAIT)
1369             {
1370                 n->nwal_local.numPendingCfg++;
1371                 while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
1372                     (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_OPEN))
1373                 {
1374                     // if response is there, then this poll squirts out in the CTl poll callback, 
1375                     // which handles the rest (including decrmenting #pending!!
1376                     nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
1377                 }
1378                 if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
1379                 {
1380                     netapip_freeTransInfo(pTransInfo);
1381                     *err = NETAPI_ERR_PA_FW;
1382                     netapip_netcpCfgDeleteClass(&netapi_get_global()->nwal_context, class_slot);
1383                     netapi_Log (">netcp_cfgAddClass - ERROR returned by NETCP PA firmware %d\n", *err);
1384                     return -1;
1385                 }
1386             }
1387             netapi_Log ("netcp_cfg: L4 Classifer added to interface %d ip %d (slot%d)\n", iface_no, ip_slot, class_slot);
1388             netapip_netcpCfgInsertClass(&netapi_get_global()->nwal_context, 
1389                                    class_slot,
1390                                  p_class->classType, 
1391                                 NULL,  //L2 we have
1392                                 (p_class->classType== NETCP_CFG_CLASS_TYPE_L3_L4? l3_handle : NULL),
1393                                   pTransInfo->handle,
1394                                   user_data);
1396             netapip_freeTransInfo(pTransInfo);
1397             return classHandle;
1398     } //end switch
1400 return -1;
1403 /********************************************************************
1404  * FUNCTION PURPOSE:  API to delete a preconfigured classifier
1405  ********************************************************************
1406  * DESCRIPTION:  API to delete a preconfigured classifier
1407  ********************************************************************/
1408 void netapi_netcpCfgDelClass(NETAPI_T           h,
1409                              NETCP_CFG_CLASS_T  classId,
1410                              int*               err)
1412     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
1413     void * L4_handle;  //class handle -> L4
1414     void * L3_handle;  //class handle -> L3
1415     nwal_RetValue       retValue;
1416     NetapiNwalTransInfo_t *pTransInfo;
1417     nwal_TransID_t     trans_id;
1418     int class_slot=-1;
1420     class_slot = netapi_cfgGetMatchId(classId);
1421     L4_handle=netapip_netcpCfgGetL4Handle(&netapi_get_global()->nwal_context, class_slot);
1422     if(!L4_handle)
1423     {
1424         *err = NETAPI_ERR_BAD_INPUT; 
1425         goto ERR_netapi_netcpCfgDelClass;
1426     }
1427     L3_handle = netapip_netcpCfgGetL3Handle( &netapi_get_global()->nwal_context, class_slot );
1428     /* l3 handle might be NULL,, depending on type of classifier */
1430     netapip_netcpCfgDeleteClass(
1431                         &netapi_get_global()->nwal_context,
1432                         class_slot );
1433     //get a transaction id
1434     pTransInfo = netapip_getFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
1435     if (!pTransInfo)
1436     {
1437         *err =  NETAPI_ERR_BUSY; 
1438         goto ERR_netapi_netcpCfgDelClass;
1439     }
1440     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_PORT;
1441     pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING;
1442     pTransInfo->inUse = nwal_TRUE;
1443     pTransInfo->netapi_handle = h;
1444     //issue request for L4
1445     retValue = nwal_delConn(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
1446                                                   trans_id,
1447                                                 L4_handle);
1448     if(retValue !=  nwal_OK)
1449     {
1450         *err = NETAPI_ERR_NWAL_ERR0;
1451          netapi_Log ("netcp_cfg - ERROR: nwal_delMacIface returned Error Code %d\n", retValue);
1452          netapip_freeTransInfo(pTransInfo);
1453          goto ERR_netapi_netcpCfgDelClass;  /* todo: what about the L3? */
1454     }
1455     //wait here until its done since scheduler isn't running yet most likely..
1456     // todo:  make this handled by scheduler poll later ??
1457     if(trans_id != NWAL_TRANSID_SPIN_WAIT)
1458     {
1459         n->nwal_local.numPendingCfg++;
1460         while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
1461                 (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_IDLE))
1462         {
1463             // if response is there, then this poll squirts out in the CTl poll callback, 
1464             // which handles the rest (including decrmenting #pending!!
1465             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
1466         }
1467     }
1468     if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
1469     {
1470         netapip_freeTransInfo(pTransInfo);
1471         *err = NETAPI_ERR_PA_FW;
1472          netapi_Log (">netapi_netcpCfgDelClass - ERROR returned by NETCP PA firmware %d\n", *err);
1473          goto ERR_netapi_netcpCfgDelClass;
1474     }
1475     netapi_Log ("netcp_cfg: Classifer deleted\n");
1476     pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;
1477     pTransInfo->inUse = nwal_FALSE;
1479     /* delete L3 if we have to */
1480     if (L3_handle)
1481     {
1482         netapip_netcpCfgDelIpInternal( h, 0, 0,
1483                   NULL, NULL, 0,
1484                   err, L3_handle,  0);
1485     }
1486     netapip_freeTransInfo(pTransInfo);
1488 ERR_netapi_netcpCfgDelClass:
1489     return;
1492 /********************************************************************
1493  * FUNCTION PURPOSE:  API to add a flow
1494  ********************************************************************
1495  * DESCRIPTION:  API to add a flow
1496  ********************************************************************/
1497 /*--------------flow management--------*/
1498 // ADD A Flow
1499 NETCP_CFG_FLOW_HANDLE_T netapi_netcpCfgAddFlow(NETAPI_T                 h,
1500                                                int                      n,
1501                                                Pktlib_HeapHandle        handles[],
1502                                                int                      sizes[],
1503                                                NETCP_CFG_FLOW_CONFIG_T* p_cfg,
1504                                                int*                     err )
1506     Cppi_RxFlowCfg  rxFlowCfg;
1507     Uint8           isAlloc;
1508     Qmss_QueueHnd   rxBufQ[TUNE_NETAPI_MAX_BUF_POOLS_IN_FLOW];
1509     Uint32          rxBufSize[TUNE_NETAPI_MAX_BUF_POOLS_IN_FLOW];
1510     int             i;
1511     Cppi_FlowHnd FlowHnd;
1512     int  slot;
1513     NETCP_CFG_FLOW_HANDLE_T retVal;
1515     *err= 0;  /* ok */
1516     if (!p_cfg)
1517     {
1518         *err= NETAPI_ERR_BAD_INPUT;
1519         return NULL;
1520     }
1521     //get a slot to save new flow
1522     slot = netapip_netcpCfgFindFlowSlot(&netapi_get_global()->nwal_context);
1523     if (slot<0) { *err= NETAPI_ERR_NOMEM;  return NULL; }
1525     //configure flow
1526     memset(&rxFlowCfg,0,sizeof(Cppi_RxFlowCfg));
1527     for (i = 0; i < TUNE_NETAPI_MAX_BUF_POOLS_IN_FLOW; i++)
1528     {
1529         if (i >= n)
1530         {
1531             rxBufQ[i] = 0;
1532             rxBufSize[i] = 0;
1533         }
1534         else
1535         {
1536             rxBufQ[i] =   Pktlib_getInternalHeapQueue(handles[i]);
1537             //todo: verity sizes< heapsize
1538             //todo: verify order
1539             rxBufSize[i]= sizes[i];
1540         }
1541        if (i && (rxBufQ[i] <= 0))
1542        {
1543             rxBufQ[i] = rxBufQ[i-1];
1544             rxBufSize[i] = 0;
1545        }
1546     }
1548     /* Configure Rx flow */
1549     rxFlowCfg.flowIdNum      = p_cfg->flow_index;/*CPPI_PARAM_NOT_SPECIFIED*/;
1550     rxFlowCfg.rx_dest_qnum   = netapi_pktioGetQ(p_cfg->p_dest_q);
1551     rxFlowCfg.rx_dest_qmgr   = Qmss_getQueueNumber(rxFlowCfg.rx_dest_qnum).qMgr; 
1552     rxFlowCfg.rx_sop_offset  = p_cfg->recv_offset;
1553     rxFlowCfg.rx_ps_location = Cppi_PSLoc_PS_IN_DESC;
1554     rxFlowCfg.rx_desc_type   = Cppi_DescType_HOST;
1555     rxFlowCfg.rx_error_handling = p_cfg->block;
1557     rxFlowCfg.rx_psinfo_present = 1;
1558     rxFlowCfg.rx_einfo_present  = 1;
1560     rxFlowCfg.rx_dest_tag_lo = 0;
1561     rxFlowCfg.rx_dest_tag_hi = 0;
1562     rxFlowCfg.rx_src_tag_lo  = 0;
1563     rxFlowCfg.rx_src_tag_hi  = 0;
1565     rxFlowCfg.rx_size_thresh0_en = rxBufSize[1] ? 1 : 0;
1566     rxFlowCfg.rx_size_thresh1_en = rxBufSize[2] ? 1 : 0;
1567     rxFlowCfg.rx_size_thresh2_en = rxBufSize[3] ? 1 : 0;
1569   if (p_cfg->dma_index==NETAPI_DMA_NETCP )
1570     rxFlowCfg.rx_dest_tag_lo_sel =0;
1571   else
1572     rxFlowCfg.rx_dest_tag_lo_sel = 0x4;
1573     rxFlowCfg.rx_dest_tag_hi_sel = 0;
1574     rxFlowCfg.rx_src_tag_lo_sel  = 0;
1575     rxFlowCfg.rx_src_tag_hi_sel  = 0;
1577     rxFlowCfg.rx_fdq1_qnum = rxBufQ[1];
1578     rxFlowCfg.rx_fdq1_qmgr = (rxBufQ[1] ? Qmss_getQueueNumber(rxBufQ[1]).qMgr: 0);
1579     rxFlowCfg.rx_fdq2_qnum = rxBufQ[2];
1580     rxFlowCfg.rx_fdq2_qmgr = (rxBufQ[2] ? Qmss_getQueueNumber(rxBufQ[2]).qMgr: 0);
1581     rxFlowCfg.rx_fdq3_qnum = rxBufQ[3];
1582     rxFlowCfg.rx_fdq3_qmgr = (rxBufQ[3] ? Qmss_getQueueNumber(rxBufQ[3]).qMgr: 0);
1584     rxFlowCfg.rx_size_thresh0 = rxBufSize[1] ? rxBufSize[0] : 0;
1585     rxFlowCfg.rx_size_thresh1 = rxBufSize[2] ? rxBufSize[1] : 0;
1586     rxFlowCfg.rx_size_thresh2 = rxBufSize[3] ? rxBufSize[2] : 0;
1588     rxFlowCfg.rx_fdq0_sz0_qnum = rxBufQ[0];
1589     rxFlowCfg.rx_fdq0_sz0_qmgr =  (rxBufQ[0] ? Qmss_getQueueNumber(rxBufQ[0]).qMgr: 0);
1590     rxFlowCfg.rx_fdq0_sz1_qnum = rxBufQ[1];
1591     rxFlowCfg.rx_fdq0_sz1_qmgr =  (rxBufQ[1] ? Qmss_getQueueNumber(rxBufQ[1]).qMgr:0);
1592     rxFlowCfg.rx_fdq0_sz2_qnum = rxBufQ[2];
1593     rxFlowCfg.rx_fdq0_sz2_qmgr =  (rxBufQ[2] ? Qmss_getQueueNumber(rxBufQ[2]).qMgr:0);
1594     rxFlowCfg.rx_fdq0_sz3_qnum = rxBufQ[3];
1595     rxFlowCfg.rx_fdq0_sz3_qmgr =  (rxBufQ[3] ? Qmss_getQueueNumber(rxBufQ[3]).qMgr:0);
1596     {
1597         //todo: replace this with a nwal call to get global cntx info
1598         Cppi_CpDmaInitCfg cpdmaCfg;
1599         Cppi_Handle cppiHnd;
1600         memset(&cpdmaCfg,0,sizeof(Cppi_CpDmaInitCfg));
1601         cpdmaCfg.dmaNum   = (p_cfg->dma_index==NETAPI_DMA_NETCP ) ?Cppi_CpDma_PASS_CPDMA: Cppi_CpDma_QMSS_CPDMA;
1602         cppiHnd= Cppi_open (&cpdmaCfg);
1603         if (cppiHnd == NULL)
1604         {
1605               netapip_netcpCfgDeleteFlow(&netapi_get_global()->nwal_context, slot);
1606               *err= NETAPI_ERR_NORES;
1607               return NULL;
1608         }
1609         FlowHnd = Cppi_configureRxFlow (cppiHnd, &rxFlowCfg, &isAlloc);
1610     }
1611     if (FlowHnd == NULL)
1612     {
1613         *err= NETAPI_ERR_NORES;
1614         netapip_netcpCfgDeleteFlow(&netapi_get_global()->nwal_context, slot);
1615         return (NULL);
1616     }
1618     //update slot
1619     retVal = netapip_netcpCfgInsertFlow(&netapi_get_global()->nwal_context,
1620                                         slot,
1621                                         p_cfg->dma_index,
1622                                         (void*) FlowHnd);
1623     netapi_Log(">netcp cfg:  flow %d created in dma index %d\n",
1624         ((NETCP_CFG_FLOW_T *) retVal)->flowid, p_cfg->dma_index);
1625     return (retVal);
1628 /********************************************************************
1629  * FUNCTION PURPOSE:  API to delete a flow
1630  ********************************************************************
1631  * DESCRIPTION:  API to delete a flow
1632  ********************************************************************/
1633 void netapi_netcpCfgDelFlow(NETAPI_T                h,
1634                             NETCP_CFG_FLOW_HANDLE_T f,
1635                             int*                    err)
1637     int slot;
1638     void * handle;
1639     *err=0;
1640     /* find entry */
1641         slot = netapip_netcpCfgFindFlow(&netapi_get_global()->nwal_context,
1642                      ((NETCP_CFG_FLOW_T *) f) ->flowid,
1643                      ((NETCP_CFG_FLOW_T *) f) ->dma_engine,
1644                      &handle);
1645     if (slot<0)
1646     {
1647         *err = NETAPI_ERR_BAD_INPUT;
1648         return;
1649     }
1651     Cppi_closeRxFlow( (Cppi_FlowHnd) handle);
1652     netapip_netcpCfgDeleteFlow(&netapi_get_global()->nwal_context, slot);
1653     netapi_Log(">netcp cfg:  flow %d (dma index %d) deleted\n",
1654                 ((NETCP_CFG_FLOW_T *) f)->flowid,
1655                 ((NETCP_CFG_FLOW_T *) f)->dma_engine);
1656     return;
1659 /******************************************************************************
1660  * FUNCTION PURPOSE:  API to configure NETCP with global rules for exception packet handling
1661  ******************************************************************************
1662  * DESCRIPTION:  API to configure NETCP with global rules for exception packet handling
1663  *****************************************************************************/
1664 NETCP_CFG_EXCEPTION_PKT_T netapi_netcpCfgExceptions(NETAPI_T                    h,
1665                                                     int                         exception_id,
1666                                                     nwal_matchAction_t          action,
1667                                                     NETCP_CFG_ROUTE_HANDLE_T    p_route)
1669     nwalCtlInfo_t   ctrl;
1670     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
1671     nwal_RetValue retVal = 0;
1672     memset(&ctrl, 0, sizeof(nwalCtlInfo_t));
1674     if (p_route != NULL)
1675     {
1676         netapip_netcpCfgBuildRoute(p_route, &ctrl.appRxPktFlowId,& ctrl.appRxPktQueue);
1677     }
1678     else
1679     {
1680         ctrl.appRxPktFlowId = NWAL_FLOW_NOT_SPECIFIED;
1681         ctrl.appRxPktQueue = NWAL_QUEUE_NOT_SPECIFIED;
1682     }
1684     ctrl.appId = (void*)(NETAPI_NETCP_CFG_MATCH_EXCEPTION | exception_id);
1686     ctrl.matchAction = action;
1688     if (exception_id == NETCP_CFG_ALL_EXCEPTIONS)
1689     {
1690         ctrl.pktCtl = NWAL_CTRL_CFG_ALL_EXCEPTIONS;
1691     }
1692     else
1693     {
1694             ctrl.pa_EROUTE_Id = exception_id;
1695             ctrl.pktCtl = NWAL_CTRL_CFG_SINGLE_EXCEPTION;
1696     }
1698     retVal = nwal_control(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle, &ctrl);
1700     return (NETCP_CFG_EXCEPTION_PKT_T) ctrl.appId;
1703 /*************************************************************************/
1704 /*********************************INTERNAL*******************************/
1705 /************************************************************************/
1707 /********************************************************************
1708  * FUNCTION PURPOSE:  NETAPI internal function, NETCP command reply callback
1709  ********************************************************************
1710  * DESCRIPTION:  NETAPI internal function, NETCP command reply callback
1711  ********************************************************************/
1712 void netapip_netcpCfgNWALCmdCallBack(nwal_AppId        appHandle,
1713                             uint16_t            trans_id,
1714                             nwal_RetValue     ret)
1716     NetapiNwalTransInfo_t * p_trans;
1717     NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL;
1719     if(trans_id == NWAL_TRANSID_SPIN_WAIT)
1720     {
1721         netapi_get_global()->nwal_context.numBogusTransIds++;
1722         return;
1723     }
1725     p_trans= &netapi_get_global()->nwal_context.transInfos[trans_id];
1726     p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;
1728     if(ret != nwal_OK)
1729     {
1730         netapi_Log ("netcp_cfg : netapip_netcpCfgNWALCmdCallBack returned Error Code %d for trans_id %d\n",
1731                     ret, trans_id);
1732         // update error code that is fialed  in p_trans */
1733         //todo: atomic inc
1734         p_trans->state = NETAPI_NWAL_HANDLE_STATE_ERR;
1735         netapi_get_global()->nwal_context.numCmdFail++;
1736     }
1737     else
1738     {
1739         //todo: atomic inc
1740         netapi_get_global()->nwal_context.numCmdPass++;
1741         switch(p_trans->transType)
1742         {
1743             case NETAPI_NWAL_HANDLE_TRANS_MAC:
1744             {
1745                 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
1746                 {
1747                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;
1748                 }
1749                 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
1750                 {
1751                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
1752                 }
1753                 break;
1754             }
1755             case NETAPI_NWAL_HANDLE_TRANS_IP:
1756             {
1757                  if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
1758                 {
1759                     p_trans->state = NETAPI_NWAL_HANDLE_STATE_OPEN;
1760                 }
1761                 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
1762                 {
1763                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
1764                 }
1765                 break;
1766             }
1767             case NETAPI_NWAL_HANDLE_TRANS_PORT:
1768             {
1769                 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
1770                 {
1771                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;
1772                 }
1773                 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
1774                 {
1775                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
1776                 }
1777                 break;
1778             }
1779             case NETAPI_NWAL_HANDLE_TRANS_SA:
1780             {
1781                 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
1782                 {
1783                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;
1784                 }
1785                 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
1786                 {
1787                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
1788                 }
1789                 break;
1790             }
1791             case NETAPI_NWAL_HANDLE_TRANS_SA_POLICY:
1792             {
1793                 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
1794                 {
1795                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;
1796                 }
1797                 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
1798                 {
1799                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
1800                 }
1801                 break;
1802             }
1803             default:
1804             {
1805                 netapi_Log ("netcp cfg> Invalid transaction type %d for trans_id: %d\n",
1806                     p_trans->transType,trans_id);
1807                 break;
1808             }
1809         }
1810     }
1812     p_local->numPendingCfg--;
1814     if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_IDLE)
1815     {
1816         p_trans->inUse = nwal_FALSE;
1817     }
1821 /********************************************************************
1822  * FUNCTION PURPOSE:  NETAPI internal function, PA stats reply callback
1823  ********************************************************************
1824  * DESCRIPTION:  NETAPI internal function, PA stats reply callback
1825  ********************************************************************/
1826 void netapip_netcpCfgNWALCmdPaStatsReply(nwal_AppId        appHandle,
1827                                 nwal_TransID_t    trans_id,
1828                                 paSysStats_t      *stats)
1830     NetapiNwalTransInfo_t * p_trans;
1831     NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL;
1833     if(trans_id == NWAL_TRANSID_SPIN_WAIT)
1834     {
1835         netapi_get_global()->nwal_context.numBogusTransIds++;
1836         return;
1837     }
1839     p_trans= &netapi_get_global()->nwal_context.transInfos[trans_id];
1840     p_trans->inUse = nwal_FALSE;
1841     p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;
1843     //save a local copy  of some stuff*/
1844     p_local->numL2PktsRecvd=stats->classify1.nPackets;
1845     p_local->numL3PktsRecvd=stats->classify1.nIpv4Packets;
1847     //callout result to application !!
1848     if (p_local->stats_cb)
1849     {
1850         (*p_local->stats_cb)(p_trans->netapi_handle,stats);
1851     }