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