Add support for etherType field for netapi_netcpCfgCraeteMacInterface
[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_HANDLE_T *p_handle,
59                                                  NETAPI_PROC_GLOBAL_T *p_proc_global,
60                                                  nwal_TransID_t *pTransId)
61 {
62     uint16_t    count=0;
64     count=0;
65     p_handle->spinLock.lock(&pnetapiShm->netapi_netcp_cfg_lock);
66     while(count < TUNE_NETAPI_MAX_NUM_TRANS)
67     {
68         if((p_proc_global->nwal_context.transInfos[count].inUse) != nwal_TRUE)
69         {
70             p_proc_global->nwal_context.transInfos[count].inUse = nwal_TRUE;
71             *pTransId = count;
72             p_handle->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_lock);
73             return(&p_proc_global->nwal_context.transInfos[count]);
74         }
75         count++;
76     }
77     p_handle->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_lock);
78     /* trouble.  need to wait for one to free up*/
79     /* to do: handle this by forcing a poll of cntrl queue*/
80     netapi_Log(">netcp_cfg: trying to get free transaction slot but all full!!\n");
81     return NULL;
83 }
85 /********************************************************************
86  * FUNCTION PURPOSE:  Netapi internal function to free a transaction id
87  ********************************************************************
88  * DESCRIPTION:  Netapi internal function to free a transaction id
89  ********************************************************************/
90 void netapip_freeTransInfo(NetapiNwalTransInfo_t *pTransInfo)
91 {
92     pTransInfo->inUse = nwal_FALSE;
93     pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;
94     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_NONE;
95 }
96 /********************************************************************
97  * FUNCTION PURPOSE:  Netapi internal function to build a route
98  ********************************************************************
99  * DESCRIPTION:  Netapi internal function to build a route
100  ********************************************************************/
101 void netapip_netcpCfgBuildRoute(NETCP_CFG_ROUTE_T * p_route,
102                                 int16_t *p_flow,
103                                 Qmss_QueueHnd *p_q,
104                                 nwalRouteType_t *p_type)
106     if (!p_route) return;
107     if (p_route->p_flow)  *p_flow= p_route->p_flow->flowid;
108     else *p_flow = CPPI_PARAM_NOT_SPECIFIED;
110     if (p_route->p_dest_q) *p_q = netapi_pktioGetQ(p_route->p_dest_q);
111     else *p_q=QMSS_PARAM_NOT_SPECIFIED;
113     *p_type = p_route->routeType;
117 /******************************************************/
118 /*----------------database management stuff           */
119 /******************************************************/
121 /*=====================POLICIES=============================*/
123 /********************************************************************
124  * FUNCTION PURPOSE:  Netapi internal function to find a free slot for an SA
125  ********************************************************************
126  * DESCRIPTION:  Netapi internal function to find a free slot for an SA
127  ********************************************************************/
128 int netapip_netcpCfgFindPolicySlot(NETAPI_HANDLE_T *p_handle,
129                                    NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
130                                    int tunnel)
132     int i;
133     if ((tunnel <0 ) || (tunnel >=TUNE_NETAPI_MAX_SA))
134         return -1;
136     p_handle->spinLock.lock(&pnetapiShm->netapi_netcp_cfg_lock);
137     //find a free entry
138     for(i=0;i<TUNE_NETAPI_MAX_POLICY;i++)
139     {
140         if (!p->policy[i].in_use)
141         {
142             p->policy[i].in_use = 2; //pending
143             p->policy[i].tunnel= tunnel; //save tunnel this is linked to
144             p_handle->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_lock);
145             return i;
146         }
147     }
148     p_handle->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_lock);
149     return -1;
152 /********************************************************************
153  * FUNCTION PURPOSE:  Netapi internal function to delete a policy from policy list
154  ********************************************************************
155  * DESCRIPTION:  Netapi internal function to delete a policy from policy list
156  ********************************************************************/
157 void netapip_netcpCfgDeletePolicy(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
158                                   int policy_slot)
160     if ((policy_slot <0 ) || (policy_slot >= TUNE_NETAPI_MAX_POLICY))
161     {
162         return ;
163     }
164     p->policy[policy_slot].in_use=0;
165     return;
168 /********************************************************************
169  * FUNCTION PURPOSE:  Netapi internal function to insert a policy to the policy list
170  ********************************************************************
171  * DESCRIPTION:  Netapi internal function to insert a policy to the policy list
172  ********************************************************************/
173 void netapip_netcpCfgInsertPolicy(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
174                                   int policy_slot,
175                                   void * handle,
176                                   void * user_data)
178     p->policy[policy_slot].in_use=1;
179     p->policy[policy_slot].nwal_handle = handle;
180     p->policy[policy_slot].user_data = user_data;
181     return;
184 /************************************************************************
185  * FUNCTION PURPOSE:  Netapi internal function which returns NWAL handle for a policy
186  ************************************************************************
187  * DESCRIPTION:  Netapi internal function which returns NWAL handle for a policy
188  ************************************************************************/
189 void *netapip_netcpCfgGetPolicy(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
190                                 int policy_slot)
192     if ((policy_slot <0 ) || (policy_slot >= TUNE_NETAPI_MAX_POLICY))
193         return NULL;
194     if (!p->policy[policy_slot].in_use)
195         return NULL;
196     return p->policy[policy_slot].nwal_handle;
199 /********************************************************************
200  * FUNCTION PURPOSE:  Netapi internal function to find a free slot in SA list for a SA
201  ********************************************************************
202  * DESCRIPTION:  Netapi internal function to find a free slot in SA list for an SA
203  ********************************************************************/
204 int netapip_netcpCfgFindSaSlot(NETAPI_HANDLE_T *p_handle,
205                                NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
206                                int iface)
207 {                                    
208    int i;
209    if (iface != NETCP_CFG_NO_INTERFACE)
210    {
211    if ((iface <0 ) || (iface >=TUNE_NETAPI_MAX_NUM_MAC)) return -1;
212    }
213    p_handle->spinLock.lock(&pnetapiShm->netapi_netcp_cfg_lock);
214    //find a free entry
215    for(i=0;i<TUNE_NETAPI_MAX_SA;i++)
216    {                       
217        if (!p->tunnel[i].in_use)
218        {
219            p->tunnel[i].in_use = 2; //pending
220            p->tunnel[i].iface= iface; //save iface
221            p_handle->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_lock);
222            return i;
223        }
224    }
225    p_handle->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_lock);
226    return -1;
229 /********************************************************************
230  * FUNCTION PURPOSE:  Netapi internal function to delete an SA from SA list
231  ********************************************************************
232  * DESCRIPTION: Netapi internal function to delete an SA from SA list 
233  ********************************************************************/
234 void netapip_netcpCfgDeleteSa(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
235                               int sa_slot)
237     if ((sa_slot <0 ) || (sa_slot >= TUNE_NETAPI_MAX_SA))
238     {
239         return ;
240     }
241     p->tunnel[sa_slot].in_use=0;
242     return;
246 /****************************************************************************
247  * FUNCTION PURPOSE:  Internal function to retrieve SB command info template
248  **************************************************************************
249  * DESCRIPTION:  Internal function to retrieve SB command info template
250  ***************************************************************************/
251 nwalTxDmPSCmdInfo_t* netapip_netcpCfgGetSaSBInfo(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
252                                                  NETCP_CFG_SA_T    sa_app_id)
254      int sa_slot = netapi_cfgGetMatchId(sa_app_id);
255     if ((sa_slot <0 ) || (sa_slot >= TUNE_NETAPI_MAX_SA))
256     {
257         return NULL;
258     }
259     return (&p->tunnel[sa_slot].dmPSCmdInfo);
262 /****************************************************************************
263  * FUNCTION PURPOSE:  Internal function to retrieve Inflow mode 
264  *                    software information required to transmit packet
265  **************************************************************************
266  * DESCRIPTION:  Internal function to retrieve Inflow mode 
267  *                    software information required to transmit packet
268  ***************************************************************************/
269 int netapip_netcpCfgGetSaInflowInfo(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
270                                     NETCP_CFG_SA_T    sa_app_id,
271                                     uint32_t *swInfo0,
272                                     uint32_t *swInfo1)
274     int sa_slot = netapi_cfgGetMatchId(sa_app_id);
275     if ((sa_slot <0 ) || (sa_slot >= TUNE_NETAPI_MAX_SA))
276     {
277         return 0;
278     }
279     *swInfo0 = p->tunnel[sa_slot].swInfo0;
280     *swInfo1 = p->tunnel[sa_slot].swInfo1;
281     return 1;
284 /********************************************************************
285  * FUNCTION PURPOSE:  Netapi internal function to insert an SA to the SA list
286  ********************************************************************
287  * DESCRIPTION: Netapi internal function to insert an SA to the SA list 
288  ********************************************************************/
289 void netapip_netcpCfgInsertSa(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
290                               int sa_slot,
291                               int dir,
292                               int mode,
293                               void * temp1,
294                               void * temp2,
295                               void * handle_inflow,
296                               void * handle_sideband,
297                               nwalTxDmPSCmdInfo_t *dmPSCmdInfo,
298                               uint32_t swInfo0,
299                               uint32_t swInfo1,
300                               void* user_data)
302     p->tunnel[sa_slot].in_use=1;
303     p->tunnel[sa_slot].inbound = dir;
304     p->tunnel[sa_slot].sa_mode = mode;
305     p->tunnel[sa_slot].sa_handle_inflow = handle_inflow;
306     p->tunnel[sa_slot].sa_handle_sideband = handle_sideband;
307     p->tunnel[sa_slot].swInfo0 = swInfo0;
308     p->tunnel[sa_slot].swInfo1 = swInfo1;
309     p->tunnel[sa_slot].user_data = user_data;
310     //netapi_Log("netapip_netcpCfgInsertSa: swInfo0 0x%x, swInfo1: 0x%x, user data: %d\n",
311 //        p->tunnel[sa_slot].swInfo0, p->tunnel[sa_slot].swInfo1, (uint32_t)p->tunnel[sa_slot].user_data);
313     if (dmPSCmdInfo)
314     {
315         memcpy(&p->tunnel[sa_slot].dmPSCmdInfo, dmPSCmdInfo, sizeof(nwalTxDmPSCmdInfo_t));
316     }
317     return;
320 /********************************************************************
321  * FUNCTION PURPOSE:  Netapi internal function to return NWAL handles for an SA
322  ********************************************************************
323  * DESCRIPTION: Netapi internal function to return NWAL handles for an SA
324  ********************************************************************/
325  void *netapip_netcpCfgGetSaHandles(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
326                                     int sa_slot,
327                                     void ** p_sideband)
329     if ((sa_slot <0 ) || (sa_slot >= TUNE_NETAPI_MAX_SA))
330         return NULL;
331     if (!p->tunnel[sa_slot].in_use)
332         return NULL;
333     *p_sideband = p->tunnel[sa_slot].sa_handle_sideband;
334     return p->tunnel[sa_slot].sa_handle_inflow;
338 /*==============================FLOWS=============================*/
340 /********************************************************************
341  * FUNCTION PURPOSE:  Netapi internal function to find a free slot for a flow
342  ********************************************************************
343  * DESCRIPTION: Netapi internal function to find a free slot for a flow
344  ********************************************************************/
345 static int netapip_netcpCfgFindFlowSlot(NETAPI_HANDLE_T *p_handle,
346                                         NETAPI_NWAL_GLOBAL_CONTEXT_T *p)
348     int i;
349     //find a free entry
350     p_handle->spinLock.lock(&pnetapiShm->netapi_netcp_cfg_lock);
351     for(i=0;i<TUNE_NETAPI_MAX_FLOWS;i++)
352     {
353         if (!p->flows[i].in_use)
354         {
355             p->flows[i].in_use = 2; /* pending */
356             p_handle->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_lock);
357             return i;
358         }
359     }
360    p_handle->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_lock);
361     return -1;
364 /********************************************************************
365  * FUNCTION PURPOSE:  Netapi internal function to find delete a flow from flow list
366  ********************************************************************
367  * DESCRIPTION: Netapi internal function to find delete a flow from flow list
368  ********************************************************************/
369 static void netapip_netcpCfgDeleteFlow(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
370                                        int slot)
372     if ((slot >=0 ) && (slot < TUNE_NETAPI_MAX_FLOWS))
373     {
374         p->flows[slot].in_use = 0;
375     }
378 /********************************************************************
379  * FUNCTION PURPOSE:  Netapi internal function to  insert a flow to the  flow list
380  ********************************************************************
381  * DESCRIPTION: Netapi internal function to  delete a flow from flow list
382  ********************************************************************/
383 static NETCP_CFG_FLOW_HANDLE_T netapip_netcpCfgInsertFlow(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
384                                                           int slot,
385                                                           int dma_engine,
386                                                           void * handle)
388     p->flows[slot].in_use=1;
389     p->flows[slot].handle = handle;
390     p->flows[slot].flow.flowid  = Cppi_getFlowId(handle);
391     p->flows[slot].flow.dma_engine  = dma_engine;
392         return (NETCP_CFG_FLOW_HANDLE_T) &p->flows[slot].flow;
395 /********************************************************************
396  * FUNCTION PURPOSE:  Netapi internal function to find entry matching the flowid
397  ********************************************************************
398  * DESCRIPTION: Netapi internal function to find entry matching the flowid. Returns
399  * the slot number and the cPPI handle.
400  ********************************************************************/
401 static int netapip_netcpCfgFindFlow(NETAPI_HANDLE_T *p_handle,
402                                     NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
403                                     int flowid,  
404                                     int dma_engine,
405                                     void ** handle) 
407     int i;
408     *handle=NULL;
409     p_handle->spinLock.lock(&pnetapiShm->netapi_netcp_cfg_lock);
410     for(i=0;i<TUNE_NETAPI_MAX_FLOWS;i++)
411     {
412        if ((p->flows[i].in_use)&&
413            (p->flows[i].flow.flowid == flowid)&&
414            (p->flows[i].flow.dma_engine == dma_engine))
415         {
416             *handle = p->flows[i].handle;
417              p_handle->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_lock);
418             return i;
419         }
420     }
421     p_handle->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_lock);
422     return -1;
427 /*============================IP ADDRESSES==========================*/
429 /***************************************************************************
430  * FUNCTION PURPOSE:  Netapi internal function to find a free slot for IP rule in IP slot list
431  ***************************************************************************
432  * DESCRIPTION: NNetapi internal function to find a free slot for IP rule in IP slot list
433  ***************************************************************************/
434 static int netapip_netcpCfgFindIpSlot(NETAPI_HANDLE_T *p_handle,
435                                       NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
436                                       int iface_no)
438     int i;
440     //find a free entry
441     p_handle->spinLock.lock(&pnetapiShm->netapi_netcp_cfg_lock);
442     for(i=0;i<TUNE_NETAPI_MAX_NUM_IP;i++)
443     {
444         if (!p->ips[i].in_use)
445         {
446             p->ips[i].in_use = 2; //pending
447             p_handle->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_lock);
448             return i;
449         }
450     }
451     p_handle->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_lock);
452     return -1;
455 /***************************************************************************
456  * FUNCTION PURPOSE:  Netapi internal function to insert an IP address into interface
457  ***************************************************************************
458  * DESCRIPTION: Netapi internal function to insert an IP address into interface
459  ***************************************************************************/
460 static void netapip_netcpCfgInsertIp(NETAPI_NWAL_GLOBAL_CONTEXT_T *p, 
461                                      nwal_IpType ipType,
462                                      nwalIpAddr_t *ip_addr, 
463                                      nwalIpOpt_t *ip_qualifiers, 
464                                      int iface_no,
465                                      int ip_slot,
466                                      void * handle,
467                                      void * user_data)
469     p->ips[ip_slot].in_use=1;
470     memcpy(&p->ips[ip_slot].ip_addr, ip_addr, sizeof(nwalIpAddr_t));
471     if(ip_qualifiers)
472     {
473         memcpy(&p->ips[ip_slot].ip_qualifiers, ip_qualifiers, sizeof(nwalIpOpt_t));
474     }
475     else
476     {
477         memset(&p->ips[ip_slot].ip_qualifiers, 0, sizeof(nwalIpOpt_t));
478     }
479     p->ips[ip_slot].ip_type = ipType;
480     p->ips[ip_slot].nwal_handle = handle;
481     p->ips[ip_slot].user_data = user_data;
484 /***************************************************************************
485  * FUNCTION PURPOSE:  Netapi internal function to free IP slot associated with IP address
486  ***************************************************************************
487  * DESCRIPTION: Netapi internal function to free IP slot associated with IP address
488  ***************************************************************************/
489 static void netapip_netcpCfgDeleteIp(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
490                                      int iface_no,
491                                      int ip_slot)
493     if ((ip_slot >=0) &&(ip_slot < TUNE_NETAPI_MAX_NUM_IP))
494     {
495         p->ips[ip_slot].in_use=0;
496     }
499 /***************************************************************************
500  * FUNCTION PURPOSE:  Netapi internal function to get IP handle associated with IP address
501  ***************************************************************************
502  * DESCRIPTION: Netapi internal function to get IP handle associated with IP address
503  ***************************************************************************/
504 static void *netapip_netcpCfgGetIpHandle(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
505                                          int iface_no,
506                                          int ip_slot)
508     if ((ip_slot <0)||(ip_slot>=TUNE_NETAPI_MAX_NUM_IP))
509         return NULL;
510     if (!p->ips[ip_slot].in_use)
511         return NULL;
512     return (void *) p->ips[ip_slot].nwal_handle;
515 /*==========================MAC INTERFACES======================*/
519 /*******************************************************************************
520  * FUNCTION PURPOSE:  Netapi internal function to insert an interface to the interface list
521  *******************************************************************************
522  * DESCRIPTION:  Netapi internal function to insert an interface to the interface list
523  *******************************************************************************/
524 static void netapip_netcpCfgInsertMac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
525                                       unsigned char * p_mac,
526                                       int iface_no, 
527                                       int state, NETCP_CFG_VLAN_T vlan, 
528                                       void * handle)
530     if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_NUM_MAC))
531     {
532         memset(&p->interfaces[iface_no],0,sizeof(NETCP_INTERFACE_T));
533         p->interfaces[iface_no].in_use = 1;
534         memcpy(&p->interfaces[iface_no].mac[0], p_mac,6);
535         p->interfaces[iface_no].state = state;
536         //todo p->interfaces[iface_no].vlan = vlan;
537         p->interfaces[iface_no].nwal_handle = handle; //save handle assoicated with this rule
538         netapi_Log("netapip_netcpCfgInsertMac, global context 0x%x\n", p);
539     }
540     else 
541         netapi_Log(">netapip_netcpCfgInsertMac insert interface # out of range %d\n",iface_no);
545 /*******************************************************************************
546  * FUNCTION PURPOSE:  Netapi internal function to get handle associated with interface
547  *******************************************************************************
548  * DESCRIPTION:  Netapi internal function to get handle associated with interface
549  *******************************************************************************/
550 void* netapip_netcpCfgGetMacHandle(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
551                                    int iface_no)
553     if (iface_no == NETCP_CFG_NO_INTERFACE)
554     {
555         return NULL;
556     }
557     if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_NUM_MAC))
558     {
559         return NULL;
560     }
561     else if ( p->interfaces[iface_no].in_use)
562     {
563       return (void *) p->interfaces[iface_no].nwal_handle;
564     }
565     //no valid entry in slot
566     return NULL;
568 /*******************************************************************************
569  * FUNCTION PURPOSE:  Netapi internal function to delete interface from interface list
570  *******************************************************************************
571  * DESCRIPTION:  Netapi internal function to delete interface from interface list
572  *******************************************************************************/
573 static void netapip_netcpCfgDeleteMac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
574                                       int iface_no)
576     if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_NUM_MAC))
577     {
578         p->interfaces[iface_no].in_use = 0;
579     }
582 /*========================CLASSIFIERS==========================*/
584 /*******************************************************************************
585  * FUNCTION PURPOSE:  Netapi internal function to find a free slot for classifier rule
586  *******************************************************************************
587  * DESCRIPTION:  Netapi internal function to find a free slot for classifier rule
588  *******************************************************************************/
589 static int netapip_netcpCfgFindClassSlot(NETAPI_HANDLE_T *p_handle,
590                                          NETAPI_NWAL_GLOBAL_CONTEXT_T *p)
592     int i;
593     p_handle->spinLock.lock(&pnetapiShm->netapi_netcp_cfg_lock);
594     for(i=0;i<TUNE_NETAPI_MAX_CLASSIFIERS;i++)
595     {
596         if (!p->classi[i].in_use)
597         {
598             p->classi[i].in_use = 2; //pending
599             p_handle->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_lock);
600             return i;
601         }
602     }
603     p_handle->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_lock);
604     return -1;
606 /*******************************************************************************
607  * FUNCTION PURPOSE:  Netapi internal function to find a delete a classifer from classifer list
608  *******************************************************************************
609  * DESCRIPTION:  Netapi internal function to find a delete a classifer from classifer list
610  *******************************************************************************/
611 static void netapip_netcpCfgDeleteClass(
612          NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
613          int class_slot )
615     if ((class_slot <0 ) || (class_slot >= TUNE_NETAPI_MAX_CLASSIFIERS))
616     {
617         return;
618     }
619     p->classi[class_slot].in_use=0;
622 /*******************************************************************************
623  * FUNCTION PURPOSE:  Netapi internal function to find a insert a classifer to classifer list
624  *******************************************************************************
625  * DESCRIPTION:  Netapi internal function to find a insert a classifer to classifer list
626  *******************************************************************************/
627 static void netapip_netcpCfgInsertClass(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
628                                         int class_slot,
629                                         int class_type,
630                                         void * L2_handle,
631                                         void * L3_handle,
632                                         void * L4_handle,
633                                         void * user_data)
635     if ((class_slot >=0 ) && (class_slot < TUNE_NETAPI_MAX_CLASSIFIERS))
636     {
637         p->classi[class_slot].in_use=1;
638         p->classi[class_slot].nwal_L2_handle = L2_handle;
639         p->classi[class_slot].nwal_L3_handle = L3_handle;
640         p->classi[class_slot].nwal_L4_handle = L4_handle;
641         p->classi[class_slot].class_type = class_type;
642         p->classi[class_slot].user_data = user_data;
643     }
646 /*******************************************************************************
647  * FUNCTION PURPOSE:  Netapi internal function to get L4 nwal handle for classifier
648  *******************************************************************************
649  * DESCRIPTION:  Netapi internal function to get L4 nwal handle for classifier
650  *******************************************************************************/
651 static void *netapip_netcpCfgGetL4Handle(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
652                                          int class_slot)
654     if ((class_slot <0 ) || (class_slot >= TUNE_NETAPI_MAX_CLASSIFIERS))
655     {
656         return NULL;
657     }
658     if (!p->classi[class_slot].in_use)
659     {
660         return NULL;
661     }
662     return p->classi[class_slot].nwal_L4_handle;
667 /*******************************************************************************
668  * FUNCTION PURPOSE:  Netapi internal function to get L3 nwal handle for classifier
669  *******************************************************************************
670  * DESCRIPTION:  Netapi internal function to get L3 nwal handle for classifier
671  *******************************************************************************/
672 static int cfgOkToDeleteL3ClassiHandle(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
673                                          void*  l3_handle)
675     int i;
676     int count=0;
678     if(l3_handle == NULL)
679         return NETAPI_FALSE;
680     for(i=0; i< TUNE_NETAPI_MAX_CLASSIFIERS;i++)
681     {
682         if (!p->classi[i].in_use)
683         {
684             continue;
685         }
686         if (l3_handle == p->classi[i].nwal_L3_handle)
687         {
688             count++;
689         }
690     }
691     if (count > 0)
692         return NETAPI_FALSE;
694     return NETAPI_TRUE;
697 /*******************************************************************************
698  * FUNCTION PURPOSE:  Netapi internal function to get L3 nwal handle for classifier
699  *******************************************************************************
700  * DESCRIPTION:  Netapi internal function to get L3 nwal handle for classifier
701  *******************************************************************************/
702 static void *netapip_netcpCfgGetL3Handle(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
703                                          int class_slot)
705     if ((class_slot <0 ) || (class_slot >= TUNE_NETAPI_MAX_CLASSIFIERS))
706     {
707         return NULL;
708     }
709     if (!p->classi[class_slot].in_use)
710     {
711         return NULL;
712     }
713     return p->classi[class_slot].nwal_L3_handle;
717 /***********************************************************************************/
718 /****************************************API****************************************/
719 /***********************************************************************************/
722 /********************************************************************
723  * FUNCTION PURPOSE:  API to request statistics from NETCP
724  ********************************************************************
725  * DESCRIPTION:  API to request statistics from NETCP
726  ********************************************************************/
727 void netapi_netcpCfgReqStats(NETAPI_T  h, 
728                              NETCP_CFG_STATS_CB cb,
729                              int doClear,
730                              int *err)
732     nwal_RetValue ret;
733     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
734     NetapiNwalTransInfo_t *pTransInfo;
735     nwal_TransID_t     transId;
737     paSysStats_t netcp_stats;
738     if ((!n) || (!cb))
739     {
740         *err = NETAPI_ERR_BAD_INPUT;
741         return ;
742     }
743     *err =0;
745     pTransInfo = netapip_getFreeTransInfo(n,
746                                           (NETAPI_PROC_GLOBAL_T *) n->proc_global,
747                                           &transId);
748     if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return ;}
749     pTransInfo->transType = NETAPI_NWAL_HANDLE_STAT_REQUEST;
750     pTransInfo->netapi_handle = h;
751     n->nwal_local.stats_cb = cb;
753     memset(&netcp_stats, 0, sizeof(paSysStats_t));
754     ret = nwal_getPAStats( ((NETAPI_GLOBAL_T *) n->global)->nwal_context.nwalInstHandle,
755                               transId,
756                               &netcp_stats,
757                               doClear);
758     if(ret !=  nwal_OK)
759     {
760         *err = NETAPI_ERR_BUSY;  //no resources??
761         netapi_Log("> netapi_netcpCfg reqStats failed, err=%d\n",ret);
762         netapip_freeTransInfo(pTransInfo);
763         return;
764     }
765 #if defined(DEVICE_K2E) || defined(DEVICE_K2L)
766     if (cb)
767     {
768         cb(h, &netcp_stats);
769     }
770 #endif
771     netapip_freeTransInfo(pTransInfo);
773 /********************************************************************
774  * FUNCTION PURPOSE:  API to create a MAC interface
775  ********************************************************************
776  * DESCRIPTION:  API to create a MAC interface
777  ********************************************************************/
778 NETCP_CFG_MACIF_T  netapi_netcpCfgCreateMacInterface(NETAPI_T  h,
779                                                      uint8_t *p_mac,
780                                                      uint8_t *p_mac_remote,
781                                                      int  iface_no, 
782                                                      int switch_port, 
783                                                      NETCP_CFG_ROUTE_HANDLE_T  route,
784                                                      NETCP_CFG_VLAN_T  vlan,  //future
785                                                      uint16_t etherType,
786                                                      int state,  //0=down, 1=up  //ignored
787                                                      int * err)
789     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
790     nwalMacParam_t   macInfo=
791     {
792         0,      /* validParams */
793         0,      /* ifNum */
794         0,      /* vlanId      */
795         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },      /* Local mac */
796         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },      /* Remote mac */
797         NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */
798         NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */
799         CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */
800         QMSS_PARAM_NOT_SPECIFIED,                     /* Use default queue configured to NWAL if packet is routed to host */
801         0,
802         0
803     };
805     nwal_RetValue       retValue;
806     NetapiNwalTransInfo_t *pTransInfo;
807     nwal_TransID_t     trans_id;
809     if ((!n) || (!p_mac)) {*err = NETAPI_ERR_BAD_INPUT; return -1;}
810     *err =0;
812     pTransInfo = netapip_getFreeTransInfo(n,
813                                           (NETAPI_PROC_GLOBAL_T *) n->proc_global,
814                                           &trans_id);
815     if (!pTransInfo)
816     {
817         *err =  NETAPI_ERR_BUSY;
818         return -1;
819     }
820     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC;
821     pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
822     pTransInfo->inUse = nwal_TRUE;
823     pTransInfo->netapi_handle = h;
825     /* set up MacInfo */
826     memcpy(&macInfo.macAddr,p_mac,6);
827     if(p_mac_remote)
828     {
829         macInfo.validParams |=  NWAL_SET_MAC_VALID_PARAM_REMOTE_MAC;
830         memcpy(&macInfo.remMacAddr,p_mac_remote,6);
831     }
832     /* todo: vlan */
833     if (switch_port)
834     {
835         macInfo.validParams |= NWAL_SET_MAC_VALID_PARAM_IFNUM ;
836         macInfo.ifNum = switch_port;
837     }
839     if(etherType)
840     {
841         macInfo.validParams |= NWAL_SET_MAC_VALID_PARAM_ETHER_TYPE;
842         macInfo.etherType = etherType;
843     }
845     if (route != NULL)
846     {
847         if((route->valid_params & NETCP_CFG_VALID_PARAM_ROUTE_TYPE) ==
848             NETCP_CFG_VALID_PARAM_ROUTE_TYPE)
849         {
850            macInfo.validParams |= 
851                     NWAL_SET_MAC_VALID_PARAM_ROUTE_TYPE;
852         }
853         netapip_netcpCfgBuildRoute(route,
854                                    &macInfo.appRxPktFlowId,
855                                    &macInfo.appRxPktQueue,
856                                    &macInfo.routeType);
857     }
858     retValue = nwal_setMacIface( ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
859                                   trans_id,
860                                   (nwal_AppId) (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no),
861                                   &macInfo,
862                                   &pTransInfo->handle);
863     if(retValue !=  nwal_OK)
864     {
865         *err = NETAPI_ERR_NWAL_ERR0;
866         netapi_Log ("netapi_netcpCfg - ERROR: nwal_setMacIface returned Error Code %d\n",
867                     retValue);
868         netapip_freeTransInfo(pTransInfo);
869         return -1;
870     }
872     //wait here until its done since scheduler isn't running yet most likely..
873     // todo:  make this handled by scheduler poll later ??
874     if(trans_id != NWAL_TRANSID_SPIN_WAIT)
875     {
876         n->nwal_local.numPendingCfg++;
877         while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
878                 (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_OPEN))
879         {
880             // if response is there, then this poll squirts out in the CTl poll callback, 
881             // which handles the rest (including decrmenting #pending!!
882             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
883         }
884         if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
885         {
886             netapip_freeTransInfo(pTransInfo);
887             *err = NETAPI_ERR_PA_FW;
888             netapi_Log (">netapi_netcpCfgCreateMacInterface - ERROR returned by NETCP PA firmware %d\n",
889                     *err);
890             return -1;
891         }
893     }
894     netapi_Log ("netapi_netcpCfg: MAC i/f %d added\n", iface_no);
895     netapip_netcpCfgInsertMac(&netapi_get_global()->nwal_context, 
896                           p_mac, iface_no, state,vlan,
897                           (void *) pTransInfo->handle);
898     netapip_freeTransInfo(pTransInfo);
899     return  (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no);
902 /********************************************************************
903  * FUNCTION PURPOSE:  API to delete MAC  interface
904  ********************************************************************
905  * DESCRIPTION:  API to delete MAC  interface
906  ********************************************************************/
907 void netapi_netcpCfgDelMac(NETAPI_T h,
908                            int iface_no,
909                            int *err)
911     nwal_RetValue ret;
912     NetapiNwalTransInfo_t *pTransInfo;
913     nwal_TransID_t     trans_id;
914     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
915     void * ifHandle;
917     //get the nwal handle assoicated with this iface
918     ifHandle = netapip_netcpCfgGetMacHandle(&netapi_get_global()->nwal_context, iface_no );
919     if(!ifHandle) 
920     {
921         *err = NETAPI_ERR_BAD_INPUT; return ;
922     }
923     *err =0;
925     //get a transaction id
926     pTransInfo = netapip_getFreeTransInfo(n,
927                                           (NETAPI_PROC_GLOBAL_T *) n->proc_global,
928                                           &trans_id);
929     if (!pTransInfo)
930     {
931         *err =  NETAPI_ERR_BUSY;
932         return ;
933     }
934     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC;
935     pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING;
936     pTransInfo->inUse = nwal_TRUE;
937     pTransInfo->netapi_handle = h;
939     //issue request
940     ret = nwal_delMacIface(
941                 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
942                 trans_id,
943                 ifHandle);
944     if(ret !=  nwal_OK)
945     {
946         *err = NETAPI_ERR_NWAL_ERR0;
947         netapi_Log ("netapi_netcpCfg - ERROR: nwal_delMacIface returned Error Code %d\n",
948                     ret);
949         netapip_freeTransInfo(pTransInfo);
950         return;
951     }
952     //wait here until its done since scheduler isn't running yet most likely..
953     // todo:  make this handled by scheduler poll later ??
954     if(trans_id != NWAL_TRANSID_SPIN_WAIT)
955     {
956         n->nwal_local.numPendingCfg++;
957         while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
958                 (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_IDLE))
959         {
960             // if response is there, then this poll squirts out in the CTl poll callback, 
961             // which handles the rest (including decrmenting #pending!!
962             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
963         }
964         if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
965         {
966             netapip_freeTransInfo(pTransInfo);
967             *err = NETAPI_ERR_PA_FW;
968             netapi_Log (">netapi_netcpCfgCreateMacInterface - ERROR returned by NETCP PA firmware %d\n",
969                     *err);
970             netapip_netcpCfgDeleteMac(&netapi_get_global()->nwal_context,  iface_no);
971             return;
972         }
973     }
974     netapi_Log ("netapi_netcpCfg: MAC i/f %d deleted\n",iface_no);
975     netapip_freeTransInfo(pTransInfo);
976     //zap the entry
977     netapip_netcpCfgDeleteMac(&netapi_get_global()->nwal_context,  iface_no);
978     return ;
982 /********************************************************************
983  * FUNCTION PURPOSE:  NETAPi internal function to Add IP to MAC interface
984  ********************************************************************
985  * DESCRIPTION:  NETAPi internal function to Add IP to MAC interface
986  ********************************************************************/
987 static NETCP_CFG_IP_T  netapip_netcpCfgAddIpInternal(NETAPI_T  h,
988                                                      int  iface_no,
989                                                      nwal_IpType ipType,
990                                                      nwalIpAddr_t  * ip_addr,
991                                                      nwalIpAddr_t  *ip_rem_addr,
992                                                      nwalIpOpt_t * ip_qualifiers,
993                                                      NETCP_CFG_ROUTE_HANDLE_T  route,/*NULL for default*/
994                                                      void * user_data,
995                                                      int * err,
996                                                      int  flag) /*TRUE: add IP to iface,
997                                                      FALSE: add IP as part of classifier */
999     static unsigned char zeroIP6[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1000     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
1001     void * n_handle=NULL;
1002     nwalIpParam_t    nwalIpParam= {
1003     0,
1004     pa_IPV4,      /* IP Type */
1005     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Dest IP */
1006     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Source IP */
1007     { 0x0,0,0,0},/* IP Options */
1008     NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */
1009     NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */
1010     CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */
1011     QMSS_PARAM_NOT_SPECIFIED,                     /* Use default queue configured to NWAL if packet is routed to host */
1012     0
1013 };
1014     nwal_RetValue       retValue;
1015     NetapiNwalTransInfo_t *pTransInfo;
1016     nwal_TransID_t     trans_id;
1017     int ip_slot=-1;
1018     NETCP_CFG_IP_T ip_rule_id;
1019     NETCP_CFG_IP_T temp;
1021     //verify that iface has been configured 
1022     if (iface_no != NETCP_CFG_NO_INTERFACE)
1023     {
1024         if ((iface_no<0) || (iface_no>= TUNE_NETAPI_MAX_NUM_MAC)) {*err = NETAPI_ERR_BAD_INPUT; return -1;}
1025     }
1027     if (iface_no != NETCP_CFG_NO_INTERFACE)
1028     {
1029         netapi_Log("netapip_netcpCfgAddIpInternal, in_use %d\n", netapi_get_global()->nwal_context.interfaces[iface_no].in_use);
1030         netapi_Log("netapip_netcpCfgAddIpInternal, p 0x%x\n", &netapi_get_global()->nwal_context);
1031         if(netapi_get_global()->nwal_context.interfaces[iface_no].in_use)
1032         {
1033             n_handle =  netapi_get_global()->nwal_context.interfaces[iface_no].nwal_handle;
1034         }
1035         else
1036         {
1037             *err = NETAPI_ERR_BAD_INPUT;
1038             return -1;
1039         }
1040     }
1041     if (flag) //if adding IP to MAC then reserve a slot to save info
1042     {
1043         //find free slot for IP & reserve
1044          ip_slot= netapip_netcpCfgFindIpSlot(n,
1045                                              &netapi_get_global()->nwal_context, 
1046                                              iface_no);
1047         if (ip_slot <0) 
1048         {
1049             *err= NETAPI_ERR_NOMEM;  //no room 
1050             return -1;
1051         }
1052     }
1054     //get a transaction object for config action
1055     pTransInfo = netapip_getFreeTransInfo(n, 
1056                                           (NETAPI_PROC_GLOBAL_T *) n->proc_global,
1057                                           &trans_id);
1058     if (!pTransInfo)
1059     {
1060         *err =  NETAPI_ERR_BUSY;
1061         if (flag)
1062         {
1063             netapip_netcpCfgDeleteIp(&netapi_get_global()->nwal_context,
1064                          iface_no,
1065                          ip_slot);
1066         }
1067         return -1;
1068     }
1069     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;
1070     pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
1071     pTransInfo->inUse = nwal_TRUE;
1072     pTransInfo->netapi_handle = h;
1074     //build nwalIpParam
1075     memcpy(&nwalIpParam.locIpAddr,ip_addr, sizeof(nwalIpAddr_t));
1076     if (ip_rem_addr)
1077     {
1078         if (ipType == nwal_IPV4)
1079         {
1080             if(memcmp(ip_rem_addr, zeroIP6, sizeof(nwalIpv4Addr_t)))
1081             {
1082                 nwalIpParam.validParams |= NWAL_SET_IP_VALID_PARAM_REMOTE_IP;
1083                 memcpy(&nwalIpParam.remIpAddr,ip_rem_addr, sizeof(nwalIpAddr_t));
1084             }
1085         }
1086         else
1087         {
1088             if(memcmp(ip_rem_addr, zeroIP6, sizeof(nwalIpv6Addr_t)))
1089             {
1090                 nwalIpParam.validParams |= NWAL_SET_IP_VALID_PARAM_REMOTE_IP;
1091                 memcpy(&nwalIpParam.remIpAddr,ip_rem_addr, sizeof(nwalIpAddr_t));
1092             }
1093         }
1094     }
1095     nwalIpParam.ipType=ipType;
1096     if(route)
1097     {
1098         if((route->valid_params & NETCP_CFG_VALID_PARAM_ROUTE_TYPE) ==
1099             NETCP_CFG_VALID_PARAM_ROUTE_TYPE)
1100         {
1101            nwalIpParam.validParams |= 
1102                     NWAL_SET_IP_VALID_PARAM_ROUTE_TYPE;
1103         }
1104         netapip_netcpCfgBuildRoute(route,
1105                                    &nwalIpParam.appRxPktFlowId,
1106                                    &nwalIpParam.appRxPktQueue,
1107                                    &nwalIpParam.routeType);
1108     }
1109     else{} //use nwal defaults
1111     if (ip_qualifiers)
1112         memcpy(&nwalIpParam.ipOpt,ip_qualifiers, sizeof(nwalIpOpt_t)); 
1113     else
1114         memset(&nwalIpParam.ipOpt,0, sizeof(nwalIpOpt_t));
1116     //build the rule id that will be returned when a packet matches 
1117     if (flag)
1118         ip_rule_id = NETAPI_NETCP_MATCH_GENERIC_IP | iface_no | ((ip_slot&& NETAPI_NETCP_MATCH_ID_MASK) << NETAPI_NETCP_MATCH_ID_SHIFT);
1119     else
1120         ip_rule_id = (NETAPI_NETCP_MATCH_CLASS_L3 | iface_no);
1122     retValue = nwal_setIPAddr(   netapi_get_global()->nwal_context.nwalInstHandle,
1123                                   trans_id,
1124                                   (nwal_AppId) (ip_rule_id),
1125                                   n_handle,
1126                                   &nwalIpParam,
1127                                   &pTransInfo->handle);
1129     if(retValue !=  nwal_OK)
1130     {
1131         *err = NETAPI_ERR_NWAL_ERR0;
1132         netapi_Log ("netcp_cfg: nwal_setIP returned Error Code %d\n",
1133                     retValue);
1134         netapip_freeTransInfo(pTransInfo);
1135         //zap the entry
1136         if (flag)
1137         {
1138             netapip_netcpCfgDeleteIp(&netapi_get_global()->nwal_context,
1139                          iface_no,
1140                          ip_slot);
1141         }
1142         return -1;
1143     }
1144     //wait here until its done since scheduler isn't running yet most likely..
1145     // todo:  make this handled by scheduler poll later ??
1146     if(trans_id != NWAL_TRANSID_SPIN_WAIT)
1147     {
1148         n->nwal_local.numPendingCfg++;
1149         while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
1150         (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_OPEN))
1151         {
1152             // if response is there, then this poll squirts out in the CTl poll callback, 
1153             // which handles the rest (including decrmenting #pending!!
1154             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
1155         }
1156         if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
1157         {
1158             netapip_freeTransInfo(pTransInfo);
1159             *err = NETAPI_ERR_PA_FW;
1160             netapi_Log ("netapip_netcpCfgAddIpInternal - ERROR returned by NETCP PA firmware %d\n", *err);
1161             return -1;
1162         }
1163     }
1164     if (flag)
1165     {
1166         netapi_Log ("netcp_cfg: IP added to interface %d (slot%d)\n", iface_no, ip_slot);
1167         netapip_netcpCfgInsertIp(&netapi_get_global()->nwal_context,
1168                                  ipType, 
1169                                  ip_addr,
1170                                  ip_qualifiers,
1171                                  iface_no,
1172                                  ip_slot,
1173                                  pTransInfo->handle,
1174                                  user_data);
1175     }
1177     temp = (NETCP_CFG_IP_T) pTransInfo->handle;
1178     netapip_freeTransInfo(pTransInfo);
1179     return  (flag ? ip_rule_id:  temp);
1182 /********************************************************************
1183  * FUNCTION PURPOSE:  API to Add IP to MAC interface
1184  ********************************************************************
1185  * DESCRIPTION:  API to Add IP to MAC interface
1186  ********************************************************************/
1187 NETCP_CFG_IP_T  netapi_netcpCfgAddIp(NETAPI_T                  h,
1188                                      int                       iface_no,
1189                                      nwal_IpType               ipType,
1190                                      nwalIpAddr_t*             ip_addr,
1191                                      nwalIpAddr_t*             ip_rem_addr,
1192                                      nwalIpOpt_t*              ip_qualifiers,
1193                                      NETCP_CFG_ROUTE_HANDLE_T  route,  //NULL for default
1194                                      void*                     user_data,
1195                                      int*                      err)
1197     return netapip_netcpCfgAddIpInternal(h,
1198                                          iface_no,
1199                                          ipType,
1200                                          ip_addr,
1201                                          ip_rem_addr,
1202                                          ip_qualifiers, 
1203                                          route, 
1204                                          user_data,
1205                                          err,
1206                                          1);
1210 /********************************************************************
1211  * FUNCTION PURPOSE:  NETAPI internal function to detach IP from MAC interface
1212  ********************************************************************
1213  * DESCRIPTION:  NETAPI internal function to detach IP from MAC interface
1214  ********************************************************************/
1215 static void netapip_netcpCfgDelIpInternal(NETAPI_T h, 
1216                                           int iface_no,
1217                                           nwal_IpType ipType,
1218                                           nwalIpAddr_t  * ip_addr,
1219                                           nwalIpOpt_t * ip_qualifiers, 
1220                                           NETCP_CFG_IP_T  ip_rule_id,
1221                                           int *err, 
1222                                           void * handle,   /* if flag==0, handle must be valid */
1223                                           int flag)        /* flag==0 => delete IP rule that was part of classifier, not interface */
1225     nwal_RetValue ret;
1226     NetapiNwalTransInfo_t *pTransInfo;
1227     nwal_TransID_t     trans_id;
1228     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
1229     void * ifHandle;
1230     int ip_slot = netapi_cfgGetMatchId(ip_rule_id);
1231     /* get the nwal handle assoicated with this ip */
1232     if (flag)
1233     {
1234         ifHandle = netapip_netcpCfgGetIpHandle(&netapi_get_global()->nwal_context,
1235                                                 iface_no,
1236                                                 ip_slot);
1237     }
1238     else 
1239     {
1240         ifHandle = handle;
1241     }
1242     if(!ifHandle)
1243     {
1244         *err = NETAPI_ERR_BAD_INPUT;
1245         return ;
1246     }
1247     *err =0;
1249     //get a transaction id
1250     pTransInfo = netapip_getFreeTransInfo(n,
1251                                           (NETAPI_PROC_GLOBAL_T *) n->proc_global,
1252                                           &trans_id);
1253     if (!pTransInfo)
1254     {
1255         *err =  NETAPI_ERR_BUSY;
1256         return;
1257     }
1258     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;
1259     pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING;
1260     pTransInfo->inUse = nwal_TRUE;
1261     pTransInfo->netapi_handle = h;
1262     //issue request
1263     ret = nwal_delIPAddr(
1264                 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
1265                 trans_id,
1266                 ifHandle);
1267     if(ret !=  nwal_OK)
1268     {
1269         *err = NETAPI_ERR_NWAL_ERR0;
1270         netapi_Log ("netcp_cfg - ERROR: nwal_delMacIface returned Error Code %d\n",
1271                     ret);
1272         netapip_freeTransInfo(pTransInfo);
1273         return ;
1274     }
1275     //wait here until its done since scheduler isn't running yet most likely..
1276     // todo:  make this handled by scheduler poll later ??
1277     if(trans_id != NWAL_TRANSID_SPIN_WAIT)
1278     {
1279         n->nwal_local.numPendingCfg++;
1280         while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
1281                 (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_IDLE))
1282         {
1283             // if response is there, then this poll squirts out in the CTl poll callback, 
1284             // which handles the rest (including decrmenting #pending!!
1285             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
1286         }
1287         if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
1288         {
1289             netapip_freeTransInfo(pTransInfo);
1290             *err = NETAPI_ERR_PA_FW;
1291             netapi_Log ("netapip_netcpCfgDelIpInternal - ERROR returned by NETCP PA firmware %d\n", *err);
1292             return;
1293         }
1294     }
1296     netapip_freeTransInfo(pTransInfo);
1298     //zap the entry
1299     if (flag)
1300         netapip_netcpCfgDeleteIp(&netapi_get_global()->nwal_context,  
1301                          iface_no,
1302                          ip_slot);
1303     return ;
1306 /********************************************************************
1307  * FUNCTION PURPOSE:  API to detach IP from MAC interface
1308  ********************************************************************
1309  * DESCRIPTION:  API  to detach IP from MAC interface
1310  ********************************************************************/
1311 void netapi_netcpCfgDelIp(NETAPI_T              h,
1312                           int                   iface_no,
1313                           nwal_IpType           ipType,
1314                           nwalIpAddr_t*         ip_addr,
1315                           nwalIpOpt_t*          ip_qualifiers,
1316                           NETCP_CFG_IP_T        ip_rule_id,
1317                           int*                  err)
1319     netapip_netcpCfgDelIpInternal( h, iface_no, ipType,
1320                   ip_addr, ip_qualifiers, ip_rule_id,
1321                   err, NULL, 1);
1322     return;
1326 /********************************************************************
1327  * FUNCTION PURPOSE:  API to attach a classifier rule to NETCP
1328  ********************************************************************
1329  * DESCRIPTION:  API to attach a classifier rule to NETCP
1330  ********************************************************************/
1331 NETCP_CFG_CLASS_T netapi_netcpCfgAddClass(NETAPI_T                  h,
1332                                           NETCP_CFG_CLASSIFIER_T*   p_class,
1333                                           NETCP_CFG_ROUTE_HANDLE_T  route,
1334                                           int                       action, 
1335                                           void*                     user_data, 
1336                                           int*                      err)
1338     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
1339     void * l3_handle=NULL;  //ip handle
1340     nwal_RetValue       retValue;
1341     NetapiNwalTransInfo_t *pTransInfo;
1342     nwal_TransID_t     trans_id;
1343     int class_slot=-1;
1344     int iface_no;
1345     int ip_slot=-1;
1346     NETCP_CFG_CLASS_T  classHandle;  //returned by us
1347     nwal_appProtoType_t proto;
1348     nwalRxConnCfg_t tempCfg=
1349     {
1350         0,  //nwal_handle: to be filled in
1351         0, // l4 ports: to be filled in
1352         0,  //core id (NA)
1353         0, //action
1354         CPPI_PARAM_NOT_SPECIFIED, //flow id
1355         QMSS_PARAM_NOT_SPECIFIED, //dest queue
1356         0,
1357         0, // l4 ports: to be filled in
1358     };
1360     *err = NETAPI_ERR_OK;
1362     if(!p_class)
1363     {
1364         *err=NETAPI_ERR_BAD_INPUT;
1365         return -1;
1366     }
1367     switch(p_class->classType)
1368     {
1369         default:
1370             netapi_Log(">netapi_netcpCfg : classifier type %d not supported\n",p_class->classType);
1371             break;
1372         case(NETCP_CFG_CLASS_TYPE_L3_L4):
1373             n->spinLock.lock(&pnetapiShm->netapi_netcp_cfg_l3_classi_lock);
1374         case(NETCP_CFG_CLASS_TYPE_L4):
1375             //assume just type l4 only (L2, L3 defined by iface, l3 id )
1376             iface_no = p_class->u.c_l4.iface;
1377             if (p_class->classType== NETCP_CFG_CLASS_TYPE_L4)
1378             {
1379                 ip_slot = netapi_cfgGetMatchId(p_class->u.c_l4.ip);
1380             }
1382             //verify that iface has been configured 
1383             if (iface_no != NETCP_CFG_NO_INTERFACE)
1384             {
1385                 if(!netapi_get_global()->nwal_context.interfaces[iface_no].in_use)
1386                 {
1387                     *err = NETAPI_ERR_BAD_INPUT;
1388                     if(p_class->classType== NETCP_CFG_CLASS_TYPE_L3_L4)
1389                         n->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_l3_classi_lock);
1390                     return -1;
1391                 }
1392             }
1394             if (p_class->classType== NETCP_CFG_CLASS_TYPE_L4)
1395             {
1396                 //verify that ip has been configured and get its handle
1397                 l3_handle = netapip_netcpCfgGetIpHandle(
1398                       &netapi_get_global()->nwal_context, iface_no,
1399                       ip_slot );
1400             }
1401             else
1402             {
1403                 nwalIpParam_t tempParam=
1404                 {
1405                     0,
1406                     pa_IPV4,      /* IP Type */
1407                     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Dest IP */
1408                     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Source IP */
1409                     { 0x0,0,0,0},/* IP Options */
1410                     NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */
1411                     NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */
1412                     CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */
1413                     QMSS_PARAM_NOT_SPECIFIED,                    /* Use default queue configured to NWAL if packet is routed to host */
1414                     0
1415                 };
1416                 //build nwalIpParam
1417                 memcpy(&tempParam.locIpAddr,p_class->u.c_l3_l4.ip_addr, sizeof(nwalIpAddr_t));
1418                 tempParam.ipType=p_class->u.c_l3_l4.ipType;
1419                 //use nwal defauls for route
1420                 if (p_class->u.c_l3_l4.ip_qualifiers)
1421                     memcpy(&tempParam.ipOpt,p_class->u.c_l3_l4.ip_qualifiers, sizeof(nwalIpOpt_t));
1422                 else
1423                     memset(&tempParam.ipOpt,0, sizeof(nwalIpOpt_t));
1425                 //find if we have a matching L3 handle for IP classifier; if not create it
1426                 retValue =  nwal_getIPAddr (((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
1427                             &tempParam,
1428                             netapip_netcpCfgGetMacHandle(&netapi_get_global()->nwal_context, iface_no ),
1429                             &l3_handle); 
1430                 if (retValue != nwal_TRUE) 
1431                 {
1432                     int ret;
1433                     //**NEW IP RULE  
1434                     //need to attach this IP RULE to the MAC
1435                     l3_handle= (void *) netapip_netcpCfgAddIpInternal(
1436                                       h, iface_no, 
1437                                       p_class->u.c_l3_l4.ipType,
1438                                       p_class->u.c_l3_l4.ip_addr,
1439                                       NULL,
1440                                       p_class->u.c_l3_l4.ip_qualifiers,
1441                                       p_class->u.c_l3_l4.p_fail_route,
1442                                       user_data,
1443                                       &ret,
1444                                       NETAPI_FALSE);
1445                     if(!ret)
1446                     {
1447                         l3_handle=NULL;
1448                     }
1449                 }
1450             }
1451             if(!l3_handle)
1452             {
1453                 *err = NETAPI_ERR_BAD_INPUT; 
1454                 if(p_class->classType == NETCP_CFG_CLASS_TYPE_L3_L4)
1455                         n->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_l3_classi_lock);
1456                 return -1 ;
1457             }
1459             //find free slot for CLASS & reserve
1460             class_slot= netapip_netcpCfgFindClassSlot(n,
1461                                                       &netapi_get_global()->nwal_context);
1462             if(class_slot<0) 
1463             {
1464                 *err = NETAPI_ERR_NOMEM;
1465                 if(p_class->classType == NETCP_CFG_CLASS_TYPE_L3_L4)
1466                         n->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_l3_classi_lock);
1467                 return -1;
1468                 }
1469             classHandle = NETAPI_NETCP_MATCH_CLASS |
1470                           (class_slot << NETAPI_NETCP_MATCH_ID_SHIFT) | 
1471                           (iface_no & NETAPI_NETCP_MATCH_LOGICAL_MAC_IFACE_MASK);
1472             //build request from template
1473             tempCfg.inHandle=l3_handle;
1474             if (p_class->classType== NETCP_CFG_CLASS_TYPE_L4)
1475             {
1476                 memcpy(&tempCfg.appProto,&p_class->u.c_l4.appProto,sizeof(nwalAppProto_t));
1477                 proto = p_class->u.c_l4.proto;
1478             }
1479             else
1480             {
1481                 memcpy(&tempCfg.appProto,&p_class->u.c_l3_l4.appProto,sizeof(nwalAppProto_t));
1482                 proto = p_class->u.c_l3_l4.proto;
1483             }
1485             tempCfg.matchAction = (action==NETCP_CFG_ACTION_TO_SW)  ? NWAL_MATCH_ACTION_HOST : NWAL_MATCH_ACTION_DISCARD;
1486             if (route)
1487             {
1488                 if((route->valid_params & NETCP_CFG_VALID_PARAM_ROUTE_TYPE) ==
1489                     NETCP_CFG_VALID_PARAM_ROUTE_TYPE)
1490                 {
1491                     tempCfg.validParams |= 
1492                         NWAL_SET_CONN_VALID_PARAM_ROUTE_TYPE;
1493                 }
1494                 netapip_netcpCfgBuildRoute(route,
1495                                            &tempCfg.appRxPktFlowId,
1496                                            &tempCfg.appRxPktQueue,
1497                                            &tempCfg.routeType);
1498             }
1501             //get a transaction id
1502             pTransInfo = netapip_getFreeTransInfo(n,
1503                                                   (NETAPI_PROC_GLOBAL_T *) n->proc_global,
1504                                                   &trans_id);
1505             if (!pTransInfo)
1506             {
1507                 *err =  NETAPI_ERR_BUSY;
1508                 if(p_class->classType == NETCP_CFG_CLASS_TYPE_L3_L4)
1509                     n->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_l3_classi_lock);
1510                 return -1;
1511             }
1512             pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_PORT;
1513             pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
1514             pTransInfo->inUse = nwal_TRUE;
1515             pTransInfo->netapi_handle = h;
1516                 //issue request
1517             retValue = nwal_addConn(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
1518                             trans_id,
1519                             (nwal_AppId) classHandle,
1520                             proto,
1521                             &tempCfg,
1522                             NULL,
1523                             &pTransInfo->handle);
1524             if(retValue !=  nwal_OK)
1525             {
1526                 *err = NETAPI_ERR_NWAL_ERR0;
1527                 netapi_Log ("netcp_cfg - ERROR: nwal_delMacIface returned Error Code %d\n",
1528                         retValue);
1529                 netapip_freeTransInfo(pTransInfo);
1530                 netapip_netcpCfgDeleteClass(&netapi_get_global()->nwal_context, class_slot);
1531                 if(p_class->classType== NETCP_CFG_CLASS_TYPE_L3_L4)
1532                     n->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_l3_classi_lock);
1533                 return -1;
1534             }
1535             //wait here until its done since scheduler isn't running yet most likely..
1536            // todo:  make this handled by scheduler poll later ??
1537             if(trans_id != NWAL_TRANSID_SPIN_WAIT)
1538             {
1539                 n->nwal_local.numPendingCfg++;
1540                 while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
1541                     (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_OPEN))
1542                 {
1543                     // if response is there, then this poll squirts out in the CTl poll callback, 
1544                     // which handles the rest (including decrmenting #pending!!
1545                     nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
1546                 }
1547                 if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
1548                 {
1549                     netapip_freeTransInfo(pTransInfo);
1550                     *err = NETAPI_ERR_PA_FW;
1551                     netapip_netcpCfgDeleteClass(&netapi_get_global()->nwal_context, class_slot);
1552                     netapi_Log (">netcp_cfgAddClass - ERROR returned by NETCP PA firmware %d\n", *err);
1553                     if(p_class->classType== NETCP_CFG_CLASS_TYPE_L3_L4)
1554                         n->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_l3_classi_lock);
1555                     return -1;
1556                 }
1557             }
1558             netapi_Log ("netcp_cfg: L4 Classifer added to interface %d ip %d (slot%d)\n", iface_no, ip_slot, class_slot);
1559             netapip_netcpCfgInsertClass(&netapi_get_global()->nwal_context, 
1560                                    class_slot,
1561                                  p_class->classType, 
1562                                 NULL,  //L2 we have
1563                                 (p_class->classType== NETCP_CFG_CLASS_TYPE_L3_L4? l3_handle : NULL),
1564                                   pTransInfo->handle,
1565                                   user_data);
1567             netapip_freeTransInfo(pTransInfo);
1568             if(p_class->classType== NETCP_CFG_CLASS_TYPE_L3_L4)
1569                 n->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_l3_classi_lock);
1570             return classHandle;
1571     } //end switch
1573 return -1;
1576 /********************************************************************
1577  * FUNCTION PURPOSE:  API to delete a preconfigured classifier
1578  ********************************************************************
1579  * DESCRIPTION:  API to delete a preconfigured classifier
1580  ********************************************************************/
1581 void netapi_netcpCfgDelClass(NETAPI_T           h,
1582                              NETCP_CFG_CLASS_T  classId,
1583                              int*               err)
1585     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
1586     void *L4_handle = NULL;  //class handle -> L4
1587     void *L3_handle = NULL;  //class handle -> L3
1588     nwal_RetValue       retValue;
1589     NetapiNwalTransInfo_t *pTransInfo;
1590     nwal_TransID_t     trans_id;
1591     int class_slot=-1;
1593     class_slot = netapi_cfgGetMatchId(classId);
1594     L4_handle=netapip_netcpCfgGetL4Handle(&netapi_get_global()->nwal_context, class_slot);
1595     if(!L4_handle)
1596     {
1597         *err = NETAPI_ERR_BAD_INPUT; 
1598         goto ERR_netapi_netcpCfgDelClass;
1599     }
1600     L3_handle = netapip_netcpCfgGetL3Handle( &netapi_get_global()->nwal_context,
1601                                             class_slot);
1602     /* l3 handle might be NULL, depending on type of classifier */
1604     if(L3_handle)
1605     {
1606         // grab l3 lock
1607         n->spinLock.lock(&pnetapiShm->netapi_netcp_cfg_l3_classi_lock);
1608     }
1609     netapip_netcpCfgDeleteClass(
1610                         &netapi_get_global()->nwal_context,
1611                         class_slot );
1612     //get a transaction id
1613     pTransInfo = netapip_getFreeTransInfo(n,
1614                                           (NETAPI_PROC_GLOBAL_T *) n->proc_global,
1615                                           &trans_id);
1616     if (!pTransInfo)
1617     {
1618         *err =  NETAPI_ERR_BUSY; 
1619         goto ERR_netapi_netcpCfgDelClass;
1620     }
1621     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_PORT;
1622     pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING;
1623     pTransInfo->inUse = nwal_TRUE;
1624     pTransInfo->netapi_handle = h;
1625     //issue request for L4
1626     retValue = nwal_delConn(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
1627                                                  trans_id,
1628                                                  L4_handle);
1629     if(retValue !=  nwal_OK)
1630     {
1631         *err = NETAPI_ERR_NWAL_ERR0;
1632          netapi_Log ("netcp_cfg - ERROR: nwal_delMacIface returned Error Code %d\n", retValue);
1633          netapip_freeTransInfo(pTransInfo);
1634          goto ERR_netapi_netcpCfgDelClass;  /* todo: what about the L3? */
1635     }
1636     //wait here until its done since scheduler isn't running yet most likely..
1637     // todo:  make this handled by scheduler poll later ??
1638     if(trans_id != NWAL_TRANSID_SPIN_WAIT)
1639     {
1640         n->nwal_local.numPendingCfg++;
1641         while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
1642                 (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_IDLE))
1643         {
1644             // if response is there, then this poll squirts out in the CTl poll callback, 
1645             // which handles the rest (including decrmenting #pending!!
1646             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
1647         }
1648     }
1649     if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
1650     {
1651         netapip_freeTransInfo(pTransInfo);
1652         *err = NETAPI_ERR_PA_FW;
1653          netapi_Log (">netapi_netcpCfgDelClass - ERROR returned by NETCP PA firmware %d\n", *err);
1654          goto ERR_netapi_netcpCfgDelClass;
1655     }
1656     netapi_Log ("netcp_cfg: Classifer deleted\n");
1657     pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;
1658     pTransInfo->inUse = nwal_FALSE;
1660     /* delete L3 if we have to */
1661     if (cfgOkToDeleteL3ClassiHandle(h, L3_handle))
1662     {
1663         netapip_netcpCfgDelIpInternal(h,
1664                                       0,
1665                                       0,
1666                                       NULL,
1667                                       NULL,
1668                                       0,
1669                                       err,
1670                                       L3_handle,
1671                                       0);
1672     }
1673     netapip_freeTransInfo(pTransInfo);
1675 ERR_netapi_netcpCfgDelClass:
1676     if(L3_handle)
1677         n->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_l3_classi_lock);
1679     return;
1682 /********************************************************************
1683  * FUNCTION PURPOSE:  API to add a flow
1684  ********************************************************************
1685  * DESCRIPTION:  API to add a flow
1686  ********************************************************************/
1687 /*--------------flow management--------*/
1688 // ADD A Flow
1689 NETCP_CFG_FLOW_HANDLE_T netapi_netcpCfgAddFlow(NETAPI_T                 h,
1690                                                int                      n,
1691                                                Pktlib_HeapHandle        handles[],
1692                                                int                      sizes[],
1693                                                NETCP_CFG_FLOW_CONFIG_T* p_cfg,
1694                                                int*                     err )
1696     Cppi_RxFlowCfg  rxFlowCfg;
1697     Uint8           isAlloc;
1698     Qmss_QueueHnd   rxBufQ[TUNE_NETAPI_MAX_BUF_POOLS_IN_FLOW];
1699     Uint32          rxBufSize[TUNE_NETAPI_MAX_BUF_POOLS_IN_FLOW];
1700     int             i;
1701     Cppi_FlowHnd FlowHnd;
1702     int  slot;
1703     NETCP_CFG_FLOW_HANDLE_T retVal;
1704     NETAPI_HANDLE_T * pHandle = (NETAPI_HANDLE_T *) h;
1705     *err= 0;  /* ok */
1706     if (!p_cfg)
1707     {
1708         *err= NETAPI_ERR_BAD_INPUT;
1709         return NULL;
1710     }
1711     //get a slot to save new flow
1712     slot = netapip_netcpCfgFindFlowSlot(pHandle,
1713                                         &netapi_get_global()->nwal_context);
1715     if (slot<0) { *err= NETAPI_ERR_NOMEM;  return NULL; }
1717     //configure flow
1718     memset(&rxFlowCfg,0,sizeof(Cppi_RxFlowCfg));
1719     for (i = 0; i < TUNE_NETAPI_MAX_BUF_POOLS_IN_FLOW; i++)
1720     {
1721         if (i >= n)
1722         {
1723             rxBufQ[i] = 0;
1724             rxBufSize[i] = 0;
1725         }
1726         else
1727         {
1728             rxBufQ[i] =   Pktlib_getInternalHeapQueue(handles[i]);
1729             //todo: verity sizes< heapsize
1730             //todo: verify order
1731             rxBufSize[i]= sizes[i];
1732         }
1733        if (i && (rxBufQ[i] <= 0))
1734        {
1735             rxBufQ[i] = rxBufQ[i-1];
1736             rxBufSize[i] = 0;
1737        }
1738     }
1740     /* Configure Rx flow */
1741     rxFlowCfg.flowIdNum      = p_cfg->flow_index;/*CPPI_PARAM_NOT_SPECIFIED*/;
1742     rxFlowCfg.rx_dest_qnum   = netapi_pktioGetQ(p_cfg->p_dest_q);
1743     rxFlowCfg.rx_dest_qmgr   = Qmss_getQueueNumber(rxFlowCfg.rx_dest_qnum).qMgr; 
1744     rxFlowCfg.rx_sop_offset  = p_cfg->recv_offset;
1745     rxFlowCfg.rx_ps_location = Cppi_PSLoc_PS_IN_DESC;
1746     rxFlowCfg.rx_desc_type   = Cppi_DescType_HOST;
1747     rxFlowCfg.rx_error_handling = p_cfg->block;
1749     rxFlowCfg.rx_psinfo_present = 1;
1750     rxFlowCfg.rx_einfo_present  = 1;
1752     rxFlowCfg.rx_dest_tag_lo = 0;
1753     rxFlowCfg.rx_dest_tag_hi = 0;
1754     rxFlowCfg.rx_src_tag_lo  = 0;
1755     rxFlowCfg.rx_src_tag_hi  = 0;
1757     rxFlowCfg.rx_size_thresh0_en = rxBufSize[1] ? 1 : 0;
1758     rxFlowCfg.rx_size_thresh1_en = rxBufSize[2] ? 1 : 0;
1759     rxFlowCfg.rx_size_thresh2_en = rxBufSize[3] ? 1 : 0;
1761   if (p_cfg->dma_index==NETAPI_DMA_NETCP )
1762     rxFlowCfg.rx_dest_tag_lo_sel =0;
1763   else
1764     rxFlowCfg.rx_dest_tag_lo_sel = 0x4;
1765     rxFlowCfg.rx_dest_tag_hi_sel = 0;
1766     rxFlowCfg.rx_src_tag_lo_sel  = 0;
1767     rxFlowCfg.rx_src_tag_hi_sel  = 0;
1769     rxFlowCfg.rx_fdq1_qnum = rxBufQ[1];
1770     rxFlowCfg.rx_fdq1_qmgr = (rxBufQ[1] ? Qmss_getQueueNumber(rxBufQ[1]).qMgr: 0);
1771     rxFlowCfg.rx_fdq2_qnum = rxBufQ[2];
1772     rxFlowCfg.rx_fdq2_qmgr = (rxBufQ[2] ? Qmss_getQueueNumber(rxBufQ[2]).qMgr: 0);
1773     rxFlowCfg.rx_fdq3_qnum = rxBufQ[3];
1774     rxFlowCfg.rx_fdq3_qmgr = (rxBufQ[3] ? Qmss_getQueueNumber(rxBufQ[3]).qMgr: 0);
1776     rxFlowCfg.rx_size_thresh0 = rxBufSize[1] ? rxBufSize[0] : 0;
1777     rxFlowCfg.rx_size_thresh1 = rxBufSize[2] ? rxBufSize[1] : 0;
1778     rxFlowCfg.rx_size_thresh2 = rxBufSize[3] ? rxBufSize[2] : 0;
1780     rxFlowCfg.rx_fdq0_sz0_qnum = rxBufQ[0];
1781     rxFlowCfg.rx_fdq0_sz0_qmgr =  (rxBufQ[0] ? Qmss_getQueueNumber(rxBufQ[0]).qMgr: 0);
1782     rxFlowCfg.rx_fdq0_sz1_qnum = rxBufQ[1];
1783     rxFlowCfg.rx_fdq0_sz1_qmgr =  (rxBufQ[1] ? Qmss_getQueueNumber(rxBufQ[1]).qMgr:0);
1784     rxFlowCfg.rx_fdq0_sz2_qnum = rxBufQ[2];
1785     rxFlowCfg.rx_fdq0_sz2_qmgr =  (rxBufQ[2] ? Qmss_getQueueNumber(rxBufQ[2]).qMgr:0);
1786     rxFlowCfg.rx_fdq0_sz3_qnum = rxBufQ[3];
1787     rxFlowCfg.rx_fdq0_sz3_qmgr =  (rxBufQ[3] ? Qmss_getQueueNumber(rxBufQ[3]).qMgr:0);
1788     {
1789         //todo: replace this with a nwal call to get global cntx info
1790         Cppi_CpDmaInitCfg cpdmaCfg;
1791         Cppi_Handle cppiHnd;
1792         memset(&cpdmaCfg,0,sizeof(Cppi_CpDmaInitCfg));
1793         cpdmaCfg.dmaNum   = (p_cfg->dma_index==NETAPI_DMA_NETCP ) ?Cppi_CpDma_PASS_CPDMA: Cppi_CpDma_QMSS_CPDMA;
1794         cppiHnd= Cppi_open (&cpdmaCfg);
1795         if (cppiHnd == NULL)
1796         {
1797               netapip_netcpCfgDeleteFlow(&netapi_get_global()->nwal_context, slot);
1798               *err= NETAPI_ERR_NORES;
1799               return NULL;
1800         }
1801         FlowHnd = Cppi_configureRxFlow (cppiHnd, &rxFlowCfg, &isAlloc);
1802     }
1803     if (FlowHnd == NULL)
1804     {
1805         *err= NETAPI_ERR_NORES;
1806         netapip_netcpCfgDeleteFlow(&netapi_get_global()->nwal_context, slot);
1807         return (NULL);
1808     }
1810     //update slot
1811     retVal = netapip_netcpCfgInsertFlow(&netapi_get_global()->nwal_context,
1812                                         slot,
1813                                         p_cfg->dma_index,
1814                                         (void*) FlowHnd);
1815     netapi_Log(">netcp cfg:  flow %d created in dma index %d\n",
1816         ((NETCP_CFG_FLOW_T *) retVal)->flowid, p_cfg->dma_index);
1817     return (retVal);
1820 /********************************************************************
1821  * FUNCTION PURPOSE:  API to delete a flow
1822  ********************************************************************
1823  * DESCRIPTION:  API to delete a flow
1824  ********************************************************************/
1825 void netapi_netcpCfgDelFlow(NETAPI_T                h,
1826                             NETCP_CFG_FLOW_HANDLE_T f,
1827                             int*                    err)
1829     int slot;
1830     void * handle;
1831     *err=0;
1832     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
1833     /* find entry */
1834         slot = netapip_netcpCfgFindFlow(n,
1835                                         &netapi_get_global()->nwal_context,
1836                                         ((NETCP_CFG_FLOW_T *) f) ->flowid,
1837                                         ((NETCP_CFG_FLOW_T *) f) ->dma_engine,
1838                                         &handle);
1839     if (slot<0)
1840     {
1841         *err = NETAPI_ERR_BAD_INPUT;
1842         return;
1843     }
1844     if ((Cppi_closeRxFlow( (Cppi_FlowHnd) handle)) == 0)
1845     {
1846         netapip_netcpCfgDeleteFlow(&netapi_get_global()->nwal_context,
1847                                slot);
1848     }
1849     return;
1852 /******************************************************************************
1853  * FUNCTION PURPOSE:  API to configure NETCP with global rules for exception packet handling
1854  ******************************************************************************
1855  * DESCRIPTION:  API to configure NETCP with global rules for exception packet handling
1856  *****************************************************************************/
1857 NETCP_CFG_EXCEPTION_PKT_T netapi_netcpCfgExceptions(NETAPI_T                    h,
1858                                                     int                         exception_id,
1859                                                     nwal_matchAction_t          action,
1860                                                     NETCP_CFG_ROUTE_HANDLE_T    p_route)
1862     nwalCtlInfo_t   ctrl;
1863     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
1864     nwal_RetValue retVal = 0;
1865     memset(&ctrl, 0, sizeof(nwalCtlInfo_t));
1867     if (p_route != NULL)
1868     {
1869         if((p_route->valid_params & NETCP_CFG_VALID_PARAM_ROUTE_TYPE) ==
1870             NETCP_CFG_VALID_PARAM_ROUTE_TYPE)
1871         {
1872            ctrl.validParams |= 
1873                     NWAL_CONTROL_VALID_PARAM_ROUTE_TYPE;
1874            ctrl.routeType = p_route->routeType;
1875         }
1876         netapip_netcpCfgBuildRoute(p_route,
1877                                    &ctrl.appRxPktFlowId,
1878                                    &ctrl.appRxPktQueue,
1879                                    &ctrl.routeType);
1880     }
1881     else
1882     {
1883         ctrl.appRxPktFlowId = NWAL_FLOW_NOT_SPECIFIED;
1884         ctrl.appRxPktQueue = NWAL_QUEUE_NOT_SPECIFIED;
1885     }
1887     ctrl.appId = (void*)(NETAPI_NETCP_CFG_MATCH_EXCEPTION | exception_id);
1889     ctrl.matchAction = action;
1891     if (exception_id == NETCP_CFG_ALL_EXCEPTIONS)
1892     {
1893         ctrl.pktCtl = NWAL_CTRL_CFG_ALL_EXCEPTIONS;
1894     }
1895     else
1896     {
1897             ctrl.pa_EROUTE_Id = exception_id;
1898             ctrl.pktCtl = NWAL_CTRL_CFG_SINGLE_EXCEPTION;
1899     }
1901     retVal = nwal_control(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle, &ctrl);
1904     return (NETCP_CFG_EXCEPTION_PKT_T) ctrl.appId;
1907 /*************************************************************************/
1908 /*********************************INTERNAL*******************************/
1909 /************************************************************************/
1911 /********************************************************************
1912  * FUNCTION PURPOSE:  NETAPI internal function, NETCP command reply callback
1913  ********************************************************************
1914  * DESCRIPTION:  NETAPI internal function, NETCP command reply callback
1915  ********************************************************************/
1916 void netapip_netcpCfgNWALCmdCallBack(nwal_AppId        appHandle,
1917                             uint16_t            trans_id,
1918                             nwal_RetValue     ret)
1920     NetapiNwalTransInfo_t * p_trans;
1921     NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL;
1923     if(trans_id == NWAL_TRANSID_SPIN_WAIT)
1924     {
1925         netapi_get_proc_global()->nwal_context.numBogusTransIds++;
1926         return;
1927     }
1929     p_trans= &netapi_get_proc_global()->nwal_context.transInfos[trans_id];
1930     p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;
1932     if(ret != nwal_OK)
1933     {
1934         netapi_Log ("netcp_cfg : netapip_netcpCfgNWALCmdCallBack returned Error Code %d for trans_id %d\n",
1935                     ret, trans_id);
1936         // update error code that is fialed  in p_trans */
1937         //todo: atomic inc
1938         p_trans->state = NETAPI_NWAL_HANDLE_STATE_ERR;
1939         netapi_get_proc_global()->nwal_context.numCmdFail++;
1940     }
1941     else
1942     {
1943         //todo: atomic inc
1944         netapi_get_proc_global()->nwal_context.numCmdPass++;
1945         switch(p_trans->transType)
1946         {
1947             case NETAPI_NWAL_HANDLE_TRANS_MAC:
1948             {
1949                 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
1950                 {
1951                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;
1952                 }
1953                 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
1954                 {
1955                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
1956                 }
1957                 break;
1958             }
1959             case NETAPI_NWAL_HANDLE_TRANS_IP:
1960             {
1961                  if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
1962                 {
1963                     p_trans->state = NETAPI_NWAL_HANDLE_STATE_OPEN;
1964                 }
1965                 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
1966                 {
1967                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
1968                 }
1969                 break;
1970             }
1971             case NETAPI_NWAL_HANDLE_TRANS_PORT:
1972             {
1973                 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
1974                 {
1975                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;
1976                 }
1977                 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
1978                 {
1979                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
1980                 }
1981                 break;
1982             }
1983             case NETAPI_NWAL_HANDLE_TRANS_SA:
1984             {
1985                 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
1986                 {
1987                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;
1988                 }
1989                 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
1990                 {
1991                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
1992                 }
1993                 break;
1994             }
1995             case NETAPI_NWAL_HANDLE_TRANS_SA_POLICY:
1996             {
1997                 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
1998                 {
1999                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;
2000                 }
2001                 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
2002                 {
2003                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
2004                 }
2005                 break;
2006             }
2007             default:
2008             {
2009                 netapi_Log ("netcp cfg> Invalid transaction type %d for trans_id: %d\n",
2010                     p_trans->transType,trans_id);
2011                 break;
2012             }
2013         }
2014     }
2016     p_local->numPendingCfg--;
2018     if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_IDLE)
2019     {
2020         p_trans->inUse = nwal_FALSE;
2021     }
2025 /********************************************************************
2026  * FUNCTION PURPOSE:  NETAPI internal function, PA stats reply callback
2027  ********************************************************************
2028  * DESCRIPTION:  NETAPI internal function, PA stats reply callback
2029  ********************************************************************/
2030 void netapip_netcpCfgNWALCmdPaStatsReply(nwal_AppId        appHandle,
2031                                 nwal_TransID_t    trans_id,
2032                                 paSysStats_t      *stats)
2034     NetapiNwalTransInfo_t * p_trans;
2035     NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL;
2037     if(trans_id == NWAL_TRANSID_SPIN_WAIT)
2038     {
2039         netapi_get_proc_global()->nwal_context.numBogusTransIds++;
2040         return;
2041     }
2043     p_trans= &netapi_get_proc_global()->nwal_context.transInfos[trans_id];
2044     p_trans->inUse = nwal_FALSE;
2045     p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;
2047     //save a local copy  of some stuff*/
2048     p_local->numL2PktsRecvd=stats->classify1.nPackets;
2049     p_local->numL3PktsRecvd=stats->classify1.nIpv4Packets;
2051     //callout result to application !!
2052     if (p_local->stats_cb)
2053     {
2054         (*p_local->stats_cb)(p_trans->netapi_handle,stats);
2055     }