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