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