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