657885c94deca9c764dad3a430be886decf726af
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 }
484 /***************************************************************************
485 * FUNCTION PURPOSE: Netapi internal function to free IP slot associated with IP address
486 ***************************************************************************
487 * DESCRIPTION: Netapi internal function to free IP slot associated with IP address
488 ***************************************************************************/
489 static void netapip_netcpCfgDeleteIp(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
490 int iface_no,
491 int ip_slot)
492 {
493 if ((ip_slot >=0) &&(ip_slot < TUNE_NETAPI_MAX_NUM_IP))
494 {
495 p->ips[ip_slot].in_use=0;
496 }
497 }
499 /***************************************************************************
500 * FUNCTION PURPOSE: Netapi internal function to get IP handle associated with IP address
501 ***************************************************************************
502 * DESCRIPTION: Netapi internal function to get IP handle associated with IP address
503 ***************************************************************************/
504 static void *netapip_netcpCfgGetIpHandle(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
505 int iface_no,
506 int ip_slot)
507 {
508 if ((ip_slot <0)||(ip_slot>=TUNE_NETAPI_MAX_NUM_IP))
509 return NULL;
510 if (!p->ips[ip_slot].in_use)
511 return NULL;
512 return (void *) p->ips[ip_slot].nwal_handle;
513 }
515 /*==========================MAC INTERFACES======================*/
519 /*******************************************************************************
520 * FUNCTION PURPOSE: Netapi internal function to insert an interface to the interface list
521 *******************************************************************************
522 * DESCRIPTION: Netapi internal function to insert an interface to the interface list
523 *******************************************************************************/
524 static void netapip_netcpCfgInsertMac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
525 unsigned char * p_mac,
526 int iface_no,
527 int state, NETCP_CFG_VLAN_T vlan,
528 void * handle)
529 {
530 if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_NUM_MAC))
531 {
532 memset(&p->interfaces[iface_no],0,sizeof(NETCP_INTERFACE_T));
533 p->interfaces[iface_no].in_use = 1;
534 memcpy(&p->interfaces[iface_no].mac[0], p_mac,6);
535 p->interfaces[iface_no].state = state;
536 //todo p->interfaces[iface_no].vlan = vlan;
537 p->interfaces[iface_no].nwal_handle = handle; //save handle assoicated with this rule
538 netapi_Log("netapip_netcpCfgInsertMac, global context 0x%x\n", p);
539 }
540 else
541 netapi_Log(">netapip_netcpCfgInsertMac insert interface # out of range %d\n",iface_no);
543 }
545 /*******************************************************************************
546 * FUNCTION PURPOSE: Netapi internal function to get handle associated with interface
547 *******************************************************************************
548 * DESCRIPTION: Netapi internal function to get handle associated with interface
549 *******************************************************************************/
550 void* netapip_netcpCfgGetMacHandle(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
551 int iface_no)
552 {
553 if (iface_no == NETCP_CFG_NO_INTERFACE)
554 {
555 return NULL;
556 }
557 if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_NUM_MAC))
558 {
559 return NULL;
560 }
561 else if ( p->interfaces[iface_no].in_use)
562 {
563 return (void *) p->interfaces[iface_no].nwal_handle;
564 }
565 //no valid entry in slot
566 return NULL;
567 }
568 /*******************************************************************************
569 * FUNCTION PURPOSE: Netapi internal function to delete interface from interface list
570 *******************************************************************************
571 * DESCRIPTION: Netapi internal function to delete interface from interface list
572 *******************************************************************************/
573 static void netapip_netcpCfgDeleteMac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
574 int iface_no)
575 {
576 if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_NUM_MAC))
577 {
578 p->interfaces[iface_no].in_use = 0;
579 }
580 }
582 /*========================CLASSIFIERS==========================*/
584 /*******************************************************************************
585 * FUNCTION PURPOSE: Netapi internal function to find a free slot for classifier rule
586 *******************************************************************************
587 * DESCRIPTION: Netapi internal function to find a free slot for classifier rule
588 *******************************************************************************/
589 static int netapip_netcpCfgFindClassSlot(NETAPI_HANDLE_T *p_handle,
590 NETAPI_NWAL_GLOBAL_CONTEXT_T *p)
591 {
592 int i;
593 p_handle->spinLock.lock(&pnetapiShm->netapi_netcp_cfg_lock);
594 for(i=0;i<TUNE_NETAPI_MAX_CLASSIFIERS;i++)
595 {
596 if (!p->classi[i].in_use)
597 {
598 p->classi[i].in_use = 2; //pending
599 p_handle->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_lock);
600 return i;
601 }
602 }
603 p_handle->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_lock);
604 return -1;
605 }
606 /*******************************************************************************
607 * FUNCTION PURPOSE: Netapi internal function to find a delete a classifer from classifer list
608 *******************************************************************************
609 * DESCRIPTION: Netapi internal function to find a delete a classifer from classifer list
610 *******************************************************************************/
611 static void netapip_netcpCfgDeleteClass(
612 NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
613 int class_slot )
614 {
615 if ((class_slot <0 ) || (class_slot >= TUNE_NETAPI_MAX_CLASSIFIERS))
616 {
617 return;
618 }
619 p->classi[class_slot].in_use=0;
620 }
622 /*******************************************************************************
623 * FUNCTION PURPOSE: Netapi internal function to find a insert a classifer to classifer list
624 *******************************************************************************
625 * DESCRIPTION: Netapi internal function to find a insert a classifer to classifer list
626 *******************************************************************************/
627 static void netapip_netcpCfgInsertClass(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
628 int class_slot,
629 int class_type,
630 void * L2_handle,
631 void * L3_handle,
632 void * L4_handle,
633 void * user_data)
634 {
635 if ((class_slot >=0 ) && (class_slot < TUNE_NETAPI_MAX_CLASSIFIERS))
636 {
637 p->classi[class_slot].in_use=1;
638 p->classi[class_slot].nwal_L2_handle = L2_handle;
639 p->classi[class_slot].nwal_L3_handle = L3_handle;
640 p->classi[class_slot].nwal_L4_handle = L4_handle;
641 p->classi[class_slot].class_type = class_type;
642 p->classi[class_slot].user_data = user_data;
643 }
644 }
646 /*******************************************************************************
647 * FUNCTION PURPOSE: Netapi internal function to get L4 nwal handle for classifier
648 *******************************************************************************
649 * DESCRIPTION: Netapi internal function to get L4 nwal handle for classifier
650 *******************************************************************************/
651 static void *netapip_netcpCfgGetL4Handle(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
652 int class_slot)
653 {
654 if ((class_slot <0 ) || (class_slot >= TUNE_NETAPI_MAX_CLASSIFIERS))
655 {
656 return NULL;
657 }
658 if (!p->classi[class_slot].in_use)
659 {
660 return NULL;
661 }
662 return p->classi[class_slot].nwal_L4_handle;
663 }
667 /*******************************************************************************
668 * FUNCTION PURPOSE: Netapi internal function to get L3 nwal handle for classifier
669 *******************************************************************************
670 * DESCRIPTION: Netapi internal function to get L3 nwal handle for classifier
671 *******************************************************************************/
672 static int cfgOkToDeleteL3ClassiHandle(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
673 void* l3_handle)
674 {
675 int i;
676 int count=0;
678 if(l3_handle == NULL)
679 return NETAPI_FALSE;
680 for(i=0; i< TUNE_NETAPI_MAX_CLASSIFIERS;i++)
681 {
682 if (!p->classi[i].in_use)
683 {
684 continue;
685 }
686 if (l3_handle == p->classi[i].nwal_L3_handle)
687 {
688 count++;
689 }
690 }
691 if (count > 0)
692 return NETAPI_FALSE;
694 return NETAPI_TRUE;
695 }
697 /*******************************************************************************
698 * FUNCTION PURPOSE: Netapi internal function to get L3 nwal handle for classifier
699 *******************************************************************************
700 * DESCRIPTION: Netapi internal function to get L3 nwal handle for classifier
701 *******************************************************************************/
702 static void *netapip_netcpCfgGetL3Handle(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
703 int class_slot)
704 {
705 if ((class_slot <0 ) || (class_slot >= TUNE_NETAPI_MAX_CLASSIFIERS))
706 {
707 return NULL;
708 }
709 if (!p->classi[class_slot].in_use)
710 {
711 return NULL;
712 }
713 return p->classi[class_slot].nwal_L3_handle;
714 }
717 /***********************************************************************************/
718 /****************************************API****************************************/
719 /***********************************************************************************/
722 /********************************************************************
723 * FUNCTION PURPOSE: API to request statistics from NETCP
724 ********************************************************************
725 * DESCRIPTION: API to request statistics from NETCP
726 ********************************************************************/
727 void netapi_netcpCfgReqStats(NETAPI_T h,
728 NETCP_CFG_STATS_CB cb,
729 int doClear,
730 int *err)
731 {
732 nwal_RetValue ret;
733 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
734 NetapiNwalTransInfo_t *pTransInfo;
735 nwal_TransID_t transId;
737 paSysStats_t netcp_stats;
738 if ((!n) || (!cb))
739 {
740 *err = NETAPI_ERR_BAD_INPUT;
741 return ;
742 }
743 *err =0;
745 pTransInfo = netapip_getFreeTransInfo(n,
746 (NETAPI_PROC_GLOBAL_T *) n->proc_global,
747 &transId);
748 if (!pTransInfo) { *err = NETAPI_ERR_BUSY; return ;}
749 pTransInfo->transType = NETAPI_NWAL_HANDLE_STAT_REQUEST;
750 pTransInfo->netapi_handle = h;
751 n->nwal_local.stats_cb = cb;
753 memset(&netcp_stats, 0, sizeof(paSysStats_t));
754 ret = nwal_getPAStats( ((NETAPI_GLOBAL_T *) n->global)->nwal_context.nwalInstHandle,
755 transId,
756 &netcp_stats,
757 doClear);
758 if(ret != nwal_OK)
759 {
760 *err = NETAPI_ERR_BUSY; //no resources??
761 netapi_Log("> netapi_netcpCfg reqStats failed, err=%d\n",ret);
762 netapip_freeTransInfo(pTransInfo);
763 return;
764 }
765 #if defined(DEVICE_K2E) || defined(DEVICE_K2L)
766 if (cb)
767 {
768 cb(h, &netcp_stats);
769 }
770 #endif
771 netapip_freeTransInfo(pTransInfo);
772 }
773 /********************************************************************
774 * FUNCTION PURPOSE: API to create a MAC interface
775 ********************************************************************
776 * DESCRIPTION: API to create a MAC interface
777 ********************************************************************/
778 NETCP_CFG_MACIF_T netapi_netcpCfgCreateMacInterface(NETAPI_T h,
779 uint8_t *p_mac,
780 uint8_t *p_mac_remote,
781 int iface_no, /* index, from 0 to n */
782 int switch_port,
783 NETCP_CFG_ROUTE_HANDLE_T route,
784 NETCP_CFG_VLAN_T vlan, //future
785 uint16_t etherType,
786 int state, //0=down, 1=up //ignored
787 int * err)
788 {
789 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
790 nwalMacParam_t macInfo=
791 {
792 0, /* validParams */
793 0, /* ifNum */
794 0, /* vlanId */
795 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* Local mac */
796 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* Remote mac */
797 NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE, /* Continue parsing to next route for match */
798 NWAL_NEXT_ROUTE_FAIL_ACTION_HOST, /* For next route fail action by default is route to host */
799 CPPI_PARAM_NOT_SPECIFIED, /* Use default flow configured to NWAL if packet is routed to host */
800 QMSS_PARAM_NOT_SPECIFIED, /* Use default queue configured to NWAL if packet is routed to host */
801 0,
802 0,
803 0
804 };
806 nwal_RetValue retValue;
807 NetapiNwalTransInfo_t *pTransInfo;
808 nwal_TransID_t trans_id;
809 nwal_AppId appId;
810 if ((!n) || (!p_mac)) {*err = NETAPI_ERR_BAD_INPUT; return -1;}
811 *err =0;
813 pTransInfo = netapip_getFreeTransInfo(n,
814 (NETAPI_PROC_GLOBAL_T *) n->proc_global,
815 &trans_id);
816 if (!pTransInfo)
817 {
818 *err = NETAPI_ERR_BUSY;
819 return -1;
820 }
821 pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC;
822 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
823 pTransInfo->inUse = nwal_TRUE;
824 pTransInfo->netapi_handle = h;
826 /* set up MacInfo */
827 memcpy(&macInfo.macAddr,p_mac,6);
829 if(p_mac_remote)
830 {
831 macInfo.validParams |= NWAL_SET_MAC_VALID_PARAM_REMOTE_MAC;
832 memcpy(&macInfo.remMacAddr,p_mac_remote,6);
833 }
834 /* todo: vlan */
835 if (switch_port)
836 {
837 macInfo.validParams |= NWAL_SET_MAC_VALID_PARAM_IFNUM ;
838 macInfo.ifNum = switch_port;
839 }
841 if(etherType)
842 {
843 macInfo.validParams |= NWAL_SET_MAC_VALID_PARAM_ETHER_TYPE;
844 macInfo.etherType = etherType;
845 }
847 if (route != NULL)
848 {
849 if((route->valid_params & NETCP_CFG_VALID_PARAM_ROUTE_TYPE) ==
850 NETCP_CFG_VALID_PARAM_ROUTE_TYPE)
851 {
852 macInfo.validParams |=
853 NWAL_SET_MAC_VALID_PARAM_ROUTE_TYPE;
855 if(route->routeType == NWAL_ROUTE_PKTTYPE_EQOS)
856 {
857 macInfo.egress_switch_port = route->egress_swith_port;
858 //macInfo.appRxPktFlowId = route->p_flow;
859 //macInfo.appRxPktQueue = route->p_dest_q;
860 macInfo.routeType = NWAL_ROUTE_PKTTYPE_EQOS;
861 macInfo.matchAction = NWAL_MATCH_ACTION_HOST;
862 }
863 }
865 netapip_netcpCfgBuildRoute(route,
866 &macInfo.appRxPktFlowId,
867 &macInfo.appRxPktQueue,
868 &macInfo.routeType);
869 }
872 appId = (nwal_AppId) (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no);
874 retValue = nwal_setMacIface( ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
875 trans_id,
876 appId,
877 &macInfo,
878 &pTransInfo->handle);
879 if(retValue != nwal_OK)
880 {
881 *err = NETAPI_ERR_NWAL_ERR0;
882 netapi_Log ("netapi_netcpCfg - ERROR: nwal_setMacIface returned Error Code %d\n",
883 retValue);
884 netapip_freeTransInfo(pTransInfo);
885 return -1;
886 }
888 //wait here until its done since scheduler isn't running yet most likely..
889 // todo: make this handled by scheduler poll later ??
890 if(trans_id != NWAL_TRANSID_SPIN_WAIT)
891 {
892 n->nwal_local.numPendingCfg++;
893 while ((pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
894 (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_OPEN))
895 {
896 // if response is there, then this poll squirts out in the CTl poll callback,
897 // which handles the rest (including decrmenting #pending!!
898 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
899 }
900 if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
901 {
902 netapip_freeTransInfo(pTransInfo);
903 *err = NETAPI_ERR_PA_FW;
904 netapi_Log (">netapi_netcpCfgCreateMacInterface - ERROR returned by NETCP PA firmware %d\n",
905 *err);
906 return -1;
907 }
909 }
910 netapi_Log ("netapi_netcpCfg: MAC i/f %d added\n", iface_no);
911 netapip_netcpCfgInsertMac(&netapi_get_global()->nwal_context,
912 p_mac, iface_no, state,vlan,
913 (void *) pTransInfo->handle);
914 netapip_freeTransInfo(pTransInfo);
915 return (NETCP_CFG_MACIF_T)appId;
916 }
918 /********************************************************************
919 * FUNCTION PURPOSE: API to delete MAC interface
920 ********************************************************************
921 * DESCRIPTION: API to delete MAC interface
922 ********************************************************************/
923 void netapi_netcpCfgDelMac(NETAPI_T h,
924 int iface_no,
925 int *err)
926 {
927 nwal_RetValue ret;
928 NetapiNwalTransInfo_t *pTransInfo;
929 nwal_TransID_t trans_id;
930 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
931 void * ifHandle;
933 //get the nwal handle assoicated with this iface
934 ifHandle = netapip_netcpCfgGetMacHandle(&netapi_get_global()->nwal_context, iface_no );
935 if(!ifHandle)
936 {
937 *err = NETAPI_ERR_BAD_INPUT; return ;
938 }
939 *err =0;
941 //get a transaction id
942 pTransInfo = netapip_getFreeTransInfo(n,
943 (NETAPI_PROC_GLOBAL_T *) n->proc_global,
944 &trans_id);
945 if (!pTransInfo)
946 {
947 *err = NETAPI_ERR_BUSY;
948 return ;
949 }
950 pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC;
951 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING;
952 pTransInfo->inUse = nwal_TRUE;
953 pTransInfo->netapi_handle = h;
955 //issue request
956 ret = nwal_delMacIface(
957 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
958 trans_id,
959 ifHandle);
960 if(ret != nwal_OK)
961 {
962 *err = NETAPI_ERR_NWAL_ERR0;
963 netapi_Log ("netapi_netcpCfg - ERROR: nwal_delMacIface returned Error Code %d\n",
964 ret);
965 netapip_freeTransInfo(pTransInfo);
966 return;
967 }
968 //wait here until its done since scheduler isn't running yet most likely..
969 // todo: make this handled by scheduler poll later ??
970 if(trans_id != NWAL_TRANSID_SPIN_WAIT)
971 {
972 n->nwal_local.numPendingCfg++;
973 while ((pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
974 (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_IDLE))
975 {
976 // if response is there, then this poll squirts out in the CTl poll callback,
977 // which handles the rest (including decrmenting #pending!!
978 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
979 }
980 if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
981 {
982 netapip_freeTransInfo(pTransInfo);
983 *err = NETAPI_ERR_PA_FW;
984 netapi_Log (">netapi_netcpCfgCreateMacInterface - ERROR returned by NETCP PA firmware %d\n",
985 *err);
986 netapip_netcpCfgDeleteMac(&netapi_get_global()->nwal_context, iface_no);
987 return;
988 }
989 }
990 netapi_Log ("netapi_netcpCfg: MAC i/f %d deleted\n",iface_no);
991 netapip_freeTransInfo(pTransInfo);
992 //zap the entry
993 netapip_netcpCfgDeleteMac(&netapi_get_global()->nwal_context, iface_no);
994 return ;
995 }
998 /********************************************************************
999 * FUNCTION PURPOSE: NETAPi internal function to Add IP to MAC interface
1000 ********************************************************************
1001 * DESCRIPTION: NETAPi internal function to Add IP to MAC interface
1002 ********************************************************************/
1003 static NETCP_CFG_IP_T netapip_netcpCfgAddIpInternal(NETAPI_T h,
1004 int iface_no,
1005 nwal_IpType ipType,
1006 nwalIpAddr_t * ip_addr,
1007 nwalIpAddr_t *ip_rem_addr,
1008 nwalIpOpt_t * ip_qualifiers,
1009 NETCP_CFG_ROUTE_HANDLE_T route,/*NULL for default*/
1010 void * user_data,
1011 int * err,
1012 int flag) /*TRUE: add IP to iface,
1013 FALSE: add IP as part of classifier */
1014 {
1015 static unsigned char zeroIP6[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1016 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
1017 void * n_handle=NULL;
1018 nwalIpParam_t nwalIpParam= {
1019 0,
1020 pa_IPV4, /* IP Type */
1021 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Dest IP */
1022 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Source IP */
1023 { 0x0,0,0,0},/* IP Options */
1024 NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE, /* Continue parsing to next route for match */
1025 NWAL_NEXT_ROUTE_FAIL_ACTION_HOST, /* For next route fail action by default is route to host */
1026 CPPI_PARAM_NOT_SPECIFIED, /* Use default flow configured to NWAL if packet is routed to host */
1027 QMSS_PARAM_NOT_SPECIFIED, /* Use default queue configured to NWAL if packet is routed to host */
1028 0
1029 };
1030 nwal_RetValue retValue;
1031 NetapiNwalTransInfo_t *pTransInfo;
1032 nwal_TransID_t trans_id;
1033 int ip_slot=-1;
1034 NETCP_CFG_IP_T ip_rule_id;
1035 NETCP_CFG_IP_T temp;
1037 //verify that iface has been configured
1038 if (iface_no != NETCP_CFG_NO_INTERFACE)
1039 {
1040 if ((iface_no<0) || (iface_no>= TUNE_NETAPI_MAX_NUM_MAC)) {*err = NETAPI_ERR_BAD_INPUT; return -1;}
1041 }
1043 if (iface_no != NETCP_CFG_NO_INTERFACE)
1044 {
1045 netapi_Log("netapip_netcpCfgAddIpInternal, in_use %d\n", netapi_get_global()->nwal_context.interfaces[iface_no].in_use);
1046 netapi_Log("netapip_netcpCfgAddIpInternal, p 0x%x\n", &netapi_get_global()->nwal_context);
1047 if(netapi_get_global()->nwal_context.interfaces[iface_no].in_use)
1048 {
1049 n_handle = netapi_get_global()->nwal_context.interfaces[iface_no].nwal_handle;
1050 }
1051 else
1052 {
1053 *err = NETAPI_ERR_BAD_INPUT;
1054 return -1;
1055 }
1056 }
1057 if (flag) //if adding IP to MAC then reserve a slot to save info
1058 {
1059 //find free slot for IP & reserve
1060 ip_slot= netapip_netcpCfgFindIpSlot(n,
1061 &netapi_get_global()->nwal_context,
1062 iface_no);
1063 if (ip_slot <0)
1064 {
1065 *err= NETAPI_ERR_NOMEM; //no room
1066 return -1;
1067 }
1068 }
1070 //get a transaction object for config action
1071 pTransInfo = netapip_getFreeTransInfo(n,
1072 (NETAPI_PROC_GLOBAL_T *) n->proc_global,
1073 &trans_id);
1074 if (!pTransInfo)
1075 {
1076 *err = NETAPI_ERR_BUSY;
1077 if (flag)
1078 {
1079 netapip_netcpCfgDeleteIp(&netapi_get_global()->nwal_context,
1080 iface_no,
1081 ip_slot);
1082 }
1083 return -1;
1084 }
1085 pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;
1086 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
1087 pTransInfo->inUse = nwal_TRUE;
1088 pTransInfo->netapi_handle = h;
1090 //build nwalIpParam
1091 memcpy(&nwalIpParam.locIpAddr,ip_addr, sizeof(nwalIpAddr_t));
1092 if (ip_rem_addr)
1093 {
1094 if (ipType == nwal_IPV4)
1095 {
1096 if(memcmp(ip_rem_addr, zeroIP6, sizeof(nwalIpv4Addr_t)))
1097 {
1098 nwalIpParam.validParams |= NWAL_SET_IP_VALID_PARAM_REMOTE_IP;
1099 memcpy(&nwalIpParam.remIpAddr,ip_rem_addr, sizeof(nwalIpAddr_t));
1100 }
1101 }
1102 else
1103 {
1104 if(memcmp(ip_rem_addr, zeroIP6, sizeof(nwalIpv6Addr_t)))
1105 {
1106 nwalIpParam.validParams |= NWAL_SET_IP_VALID_PARAM_REMOTE_IP;
1107 memcpy(&nwalIpParam.remIpAddr,ip_rem_addr, sizeof(nwalIpAddr_t));
1108 }
1109 }
1110 }
1111 nwalIpParam.ipType=ipType;
1112 if(route)
1113 {
1114 if((route->valid_params & NETCP_CFG_VALID_PARAM_ROUTE_TYPE) ==
1115 NETCP_CFG_VALID_PARAM_ROUTE_TYPE)
1116 {
1117 nwalIpParam.validParams |=
1118 NWAL_SET_IP_VALID_PARAM_ROUTE_TYPE;
1119 }
1120 netapip_netcpCfgBuildRoute(route,
1121 &nwalIpParam.appRxPktFlowId,
1122 &nwalIpParam.appRxPktQueue,
1123 &nwalIpParam.routeType);
1124 }
1125 else{} //use nwal defaults
1127 if (ip_qualifiers)
1128 memcpy(&nwalIpParam.ipOpt,ip_qualifiers, sizeof(nwalIpOpt_t));
1129 else
1130 memset(&nwalIpParam.ipOpt,0, sizeof(nwalIpOpt_t));
1132 //build the rule id that will be returned when a packet matches
1133 if (flag)
1134 ip_rule_id = NETAPI_NETCP_MATCH_GENERIC_IP | iface_no | ((ip_slot&& NETAPI_NETCP_MATCH_ID_MASK) << NETAPI_NETCP_MATCH_ID_SHIFT);
1135 else
1136 ip_rule_id = (NETAPI_NETCP_MATCH_CLASS_L3 | iface_no);
1138 retValue = nwal_setIPAddr( netapi_get_global()->nwal_context.nwalInstHandle,
1139 trans_id,
1140 (nwal_AppId) (ip_rule_id),
1141 n_handle,
1142 &nwalIpParam,
1143 &pTransInfo->handle);
1145 if(retValue != nwal_OK)
1146 {
1147 *err = NETAPI_ERR_NWAL_ERR0;
1148 netapi_Log ("netcp_cfg: nwal_setIP returned Error Code %d\n",
1149 retValue);
1150 netapip_freeTransInfo(pTransInfo);
1151 //zap the entry
1152 if (flag)
1153 {
1154 netapip_netcpCfgDeleteIp(&netapi_get_global()->nwal_context,
1155 iface_no,
1156 ip_slot);
1157 }
1158 return -1;
1159 }
1160 //wait here until its done since scheduler isn't running yet most likely..
1161 // todo: make this handled by scheduler poll later ??
1162 if(trans_id != NWAL_TRANSID_SPIN_WAIT)
1163 {
1164 n->nwal_local.numPendingCfg++;
1165 while ((pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
1166 (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_OPEN))
1167 {
1168 // if response is there, then this poll squirts out in the CTl poll callback,
1169 // which handles the rest (including decrmenting #pending!!
1170 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
1171 }
1172 if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
1173 {
1174 netapip_freeTransInfo(pTransInfo);
1175 *err = NETAPI_ERR_PA_FW;
1176 netapi_Log ("netapip_netcpCfgAddIpInternal - ERROR returned by NETCP PA firmware %d\n", *err);
1177 return -1;
1178 }
1179 }
1180 if (flag)
1181 {
1182 netapi_Log ("netcp_cfg: IP added to interface %d (slot%d)\n", iface_no, ip_slot);
1183 netapip_netcpCfgInsertIp(&netapi_get_global()->nwal_context,
1184 ipType,
1185 ip_addr,
1186 ip_qualifiers,
1187 iface_no,
1188 ip_slot,
1189 pTransInfo->handle,
1190 user_data);
1191 }
1193 temp = (NETCP_CFG_IP_T) pTransInfo->handle;
1194 netapip_freeTransInfo(pTransInfo);
1195 return (flag ? ip_rule_id: temp);
1196 }
1198 /********************************************************************
1199 * FUNCTION PURPOSE: API to Add IP to MAC interface
1200 ********************************************************************
1201 * DESCRIPTION: API to Add IP to MAC interface
1202 ********************************************************************/
1203 NETCP_CFG_IP_T netapi_netcpCfgAddIp(NETAPI_T h,
1204 int iface_no,
1205 nwal_IpType ipType,
1206 nwalIpAddr_t* ip_addr,
1207 nwalIpAddr_t* ip_rem_addr,
1208 nwalIpOpt_t* ip_qualifiers,
1209 NETCP_CFG_ROUTE_HANDLE_T route, //NULL for default
1210 void* user_data,
1211 int* err)
1212 {
1213 return netapip_netcpCfgAddIpInternal(h,
1214 iface_no,
1215 ipType,
1216 ip_addr,
1217 ip_rem_addr,
1218 ip_qualifiers,
1219 route,
1220 user_data,
1221 err,
1222 1);
1223 }
1226 /********************************************************************
1227 * FUNCTION PURPOSE: NETAPI internal function to detach IP from MAC interface
1228 ********************************************************************
1229 * DESCRIPTION: NETAPI internal function to detach IP from MAC interface
1230 ********************************************************************/
1231 static void netapip_netcpCfgDelIpInternal(NETAPI_T h,
1232 int iface_no,
1233 nwal_IpType ipType,
1234 nwalIpAddr_t * ip_addr,
1235 nwalIpOpt_t * ip_qualifiers,
1236 NETCP_CFG_IP_T ip_rule_id,
1237 int *err,
1238 void * handle, /* if flag==0, handle must be valid */
1239 int flag) /* flag==0 => delete IP rule that was part of classifier, not interface */
1240 {
1241 nwal_RetValue ret;
1242 NetapiNwalTransInfo_t *pTransInfo;
1243 nwal_TransID_t trans_id;
1244 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
1245 void * ifHandle;
1246 int ip_slot = netapi_cfgGetMatchId(ip_rule_id);
1247 /* get the nwal handle assoicated with this ip */
1248 if (flag)
1249 {
1250 ifHandle = netapip_netcpCfgGetIpHandle(&netapi_get_global()->nwal_context,
1251 iface_no,
1252 ip_slot);
1253 }
1254 else
1255 {
1256 ifHandle = handle;
1257 }
1258 if(!ifHandle)
1259 {
1260 *err = NETAPI_ERR_BAD_INPUT;
1261 return ;
1262 }
1263 *err =0;
1265 //get a transaction id
1266 pTransInfo = netapip_getFreeTransInfo(n,
1267 (NETAPI_PROC_GLOBAL_T *) n->proc_global,
1268 &trans_id);
1269 if (!pTransInfo)
1270 {
1271 *err = NETAPI_ERR_BUSY;
1272 return;
1273 }
1274 pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;
1275 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING;
1276 pTransInfo->inUse = nwal_TRUE;
1277 pTransInfo->netapi_handle = h;
1278 //issue request
1279 ret = nwal_delIPAddr(
1280 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
1281 trans_id,
1282 ifHandle);
1283 if(ret != nwal_OK)
1284 {
1285 *err = NETAPI_ERR_NWAL_ERR0;
1286 netapi_Log ("netcp_cfg - ERROR: nwal_delMacIface returned Error Code %d\n",
1287 ret);
1288 netapip_freeTransInfo(pTransInfo);
1289 return ;
1290 }
1291 //wait here until its done since scheduler isn't running yet most likely..
1292 // todo: make this handled by scheduler poll later ??
1293 if(trans_id != NWAL_TRANSID_SPIN_WAIT)
1294 {
1295 n->nwal_local.numPendingCfg++;
1296 while ((pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
1297 (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_IDLE))
1298 {
1299 // if response is there, then this poll squirts out in the CTl poll callback,
1300 // which handles the rest (including decrmenting #pending!!
1301 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
1302 }
1303 if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
1304 {
1305 netapip_freeTransInfo(pTransInfo);
1306 *err = NETAPI_ERR_PA_FW;
1307 netapi_Log ("netapip_netcpCfgDelIpInternal - ERROR returned by NETCP PA firmware %d\n", *err);
1308 return;
1309 }
1310 }
1312 netapip_freeTransInfo(pTransInfo);
1314 //zap the entry
1315 if (flag)
1316 netapip_netcpCfgDeleteIp(&netapi_get_global()->nwal_context,
1317 iface_no,
1318 ip_slot);
1319 return ;
1320 }
1322 /********************************************************************
1323 * FUNCTION PURPOSE: API to detach IP from MAC interface
1324 ********************************************************************
1325 * DESCRIPTION: API to detach IP from MAC interface
1326 ********************************************************************/
1327 void netapi_netcpCfgDelIp(NETAPI_T h,
1328 int iface_no,
1329 nwal_IpType ipType,
1330 nwalIpAddr_t* ip_addr,
1331 nwalIpOpt_t* ip_qualifiers,
1332 NETCP_CFG_IP_T ip_rule_id,
1333 int* err)
1334 {
1335 netapip_netcpCfgDelIpInternal( h, iface_no, ipType,
1336 ip_addr, ip_qualifiers, ip_rule_id,
1337 err, NULL, 1);
1338 return;
1339 }
1342 /********************************************************************
1343 * FUNCTION PURPOSE: API to attach a classifier rule to NETCP
1344 ********************************************************************
1345 * DESCRIPTION: API to attach a classifier rule to NETCP
1346 ********************************************************************/
1347 NETCP_CFG_CLASS_T netapi_netcpCfgAddClass(NETAPI_T h,
1348 NETCP_CFG_CLASSIFIER_T* p_class,
1349 NETCP_CFG_ROUTE_HANDLE_T route,
1350 int action,
1351 void* user_data,
1352 int* err)
1353 {
1354 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
1355 void * l3_handle=NULL; //ip handle
1356 nwal_RetValue retValue;
1357 NetapiNwalTransInfo_t *pTransInfo;
1358 nwal_TransID_t trans_id;
1359 int class_slot=-1;
1360 int iface_no;
1361 int ip_slot=-1;
1362 NETCP_CFG_CLASS_T classHandle; //returned by us
1363 nwal_appProtoType_t proto;
1364 nwalRxConnCfg_t tempCfg=
1365 {
1366 0, //nwal_handle: to be filled in
1367 0, // l4 ports: to be filled in
1368 0, //core id (NA)
1369 0, //action
1370 CPPI_PARAM_NOT_SPECIFIED, //flow id
1371 QMSS_PARAM_NOT_SPECIFIED, //dest queue
1372 0,
1373 0, // l4 ports: to be filled in
1374 };
1376 *err = NETAPI_ERR_OK;
1378 if(!p_class)
1379 {
1380 *err=NETAPI_ERR_BAD_INPUT;
1381 return -1;
1382 }
1383 switch(p_class->classType)
1384 {
1385 default:
1386 netapi_Log(">netapi_netcpCfg : classifier type %d not supported\n",p_class->classType);
1387 break;
1388 case(NETCP_CFG_CLASS_TYPE_L3_L4):
1389 n->spinLock.lock(&pnetapiShm->netapi_netcp_cfg_l3_classi_lock);
1390 case(NETCP_CFG_CLASS_TYPE_L4):
1391 //assume just type l4 only (L2, L3 defined by iface, l3 id )
1392 iface_no = p_class->u.c_l4.iface;
1393 if (p_class->classType== NETCP_CFG_CLASS_TYPE_L4)
1394 {
1395 ip_slot = netapi_cfgGetMatchId(p_class->u.c_l4.ip);
1396 }
1398 //verify that iface has been configured
1399 if (iface_no != NETCP_CFG_NO_INTERFACE)
1400 {
1401 if(!netapi_get_global()->nwal_context.interfaces[iface_no].in_use)
1402 {
1403 *err = NETAPI_ERR_BAD_INPUT;
1404 if(p_class->classType== NETCP_CFG_CLASS_TYPE_L3_L4)
1405 n->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_l3_classi_lock);
1406 return -1;
1407 }
1408 }
1410 if (p_class->classType== NETCP_CFG_CLASS_TYPE_L4)
1411 {
1412 //verify that ip has been configured and get its handle
1413 l3_handle = netapip_netcpCfgGetIpHandle(
1414 &netapi_get_global()->nwal_context, iface_no,
1415 ip_slot );
1416 }
1417 else
1418 {
1419 nwalIpParam_t tempParam=
1420 {
1421 0,
1422 pa_IPV4, /* IP Type */
1423 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Dest IP */
1424 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Source IP */
1425 { 0x0,0,0,0},/* IP Options */
1426 NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE, /* Continue parsing to next route for match */
1427 NWAL_NEXT_ROUTE_FAIL_ACTION_HOST, /* For next route fail action by default is route to host */
1428 CPPI_PARAM_NOT_SPECIFIED, /* Use default flow configured to NWAL if packet is routed to host */
1429 QMSS_PARAM_NOT_SPECIFIED, /* Use default queue configured to NWAL if packet is routed to host */
1430 0
1431 };
1432 //build nwalIpParam
1433 memcpy(&tempParam.locIpAddr,p_class->u.c_l3_l4.ip_addr, sizeof(nwalIpAddr_t));
1434 tempParam.ipType=p_class->u.c_l3_l4.ipType;
1435 //use nwal defauls for route
1436 if (p_class->u.c_l3_l4.ip_qualifiers)
1437 memcpy(&tempParam.ipOpt,p_class->u.c_l3_l4.ip_qualifiers, sizeof(nwalIpOpt_t));
1438 else
1439 memset(&tempParam.ipOpt,0, sizeof(nwalIpOpt_t));
1441 //find if we have a matching L3 handle for IP classifier; if not create it
1442 retValue = nwal_getIPAddr (((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
1443 &tempParam,
1444 netapip_netcpCfgGetMacHandle(&netapi_get_global()->nwal_context, iface_no ),
1445 &l3_handle);
1446 if (retValue != nwal_TRUE)
1447 {
1448 int ret;
1449 //**NEW IP RULE
1450 //need to attach this IP RULE to the MAC
1451 l3_handle= (void *) netapip_netcpCfgAddIpInternal(
1452 h, iface_no,
1453 p_class->u.c_l3_l4.ipType,
1454 p_class->u.c_l3_l4.ip_addr,
1455 NULL,
1456 p_class->u.c_l3_l4.ip_qualifiers,
1457 p_class->u.c_l3_l4.p_fail_route,
1458 user_data,
1459 &ret,
1460 NETAPI_FALSE);
1461 if(!ret)
1462 {
1463 l3_handle=NULL;
1464 }
1465 }
1466 }
1467 if(!l3_handle)
1468 {
1469 *err = NETAPI_ERR_BAD_INPUT;
1470 if(p_class->classType == NETCP_CFG_CLASS_TYPE_L3_L4)
1471 n->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_l3_classi_lock);
1472 return -1 ;
1473 }
1475 //find free slot for CLASS & reserve
1476 class_slot= netapip_netcpCfgFindClassSlot(n,
1477 &netapi_get_global()->nwal_context);
1478 if(class_slot<0)
1479 {
1480 *err = NETAPI_ERR_NOMEM;
1481 if(p_class->classType == NETCP_CFG_CLASS_TYPE_L3_L4)
1482 n->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_l3_classi_lock);
1483 return -1;
1484 }
1485 classHandle = NETAPI_NETCP_MATCH_CLASS |
1486 (class_slot << NETAPI_NETCP_MATCH_ID_SHIFT) |
1487 (iface_no & NETAPI_NETCP_MATCH_LOGICAL_MAC_IFACE_MASK);
1488 //build request from template
1489 tempCfg.inHandle=l3_handle;
1490 if (p_class->classType== NETCP_CFG_CLASS_TYPE_L4)
1491 {
1492 memcpy(&tempCfg.appProto,&p_class->u.c_l4.appProto,sizeof(nwalAppProto_t));
1493 proto = p_class->u.c_l4.proto;
1494 }
1495 else
1496 {
1497 memcpy(&tempCfg.appProto,&p_class->u.c_l3_l4.appProto,sizeof(nwalAppProto_t));
1498 proto = p_class->u.c_l3_l4.proto;
1499 }
1501 tempCfg.matchAction = (action==NETCP_CFG_ACTION_TO_SW) ? NWAL_MATCH_ACTION_HOST : NWAL_MATCH_ACTION_DISCARD;
1502 if (route)
1503 {
1504 if((route->valid_params & NETCP_CFG_VALID_PARAM_ROUTE_TYPE) ==
1505 NETCP_CFG_VALID_PARAM_ROUTE_TYPE)
1506 {
1507 tempCfg.validParams |=
1508 NWAL_SET_CONN_VALID_PARAM_ROUTE_TYPE;
1509 }
1510 netapip_netcpCfgBuildRoute(route,
1511 &tempCfg.appRxPktFlowId,
1512 &tempCfg.appRxPktQueue,
1513 &tempCfg.routeType);
1514 }
1517 //get a transaction id
1518 pTransInfo = netapip_getFreeTransInfo(n,
1519 (NETAPI_PROC_GLOBAL_T *) n->proc_global,
1520 &trans_id);
1521 if (!pTransInfo)
1522 {
1523 *err = NETAPI_ERR_BUSY;
1524 if(p_class->classType == NETCP_CFG_CLASS_TYPE_L3_L4)
1525 n->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_l3_classi_lock);
1526 return -1;
1527 }
1528 pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_PORT;
1529 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
1530 pTransInfo->inUse = nwal_TRUE;
1531 pTransInfo->netapi_handle = h;
1532 //issue request
1533 retValue = nwal_addConn(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
1534 trans_id,
1535 (nwal_AppId) classHandle,
1536 proto,
1537 &tempCfg,
1538 NULL,
1539 &pTransInfo->handle);
1540 if(retValue != nwal_OK)
1541 {
1542 *err = NETAPI_ERR_NWAL_ERR0;
1543 netapi_Log ("netcp_cfg - ERROR: nwal_delMacIface returned Error Code %d\n",
1544 retValue);
1545 netapip_freeTransInfo(pTransInfo);
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 //wait here until its done since scheduler isn't running yet most likely..
1552 // todo: make this handled by scheduler poll later ??
1553 if(trans_id != NWAL_TRANSID_SPIN_WAIT)
1554 {
1555 n->nwal_local.numPendingCfg++;
1556 while ((pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
1557 (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_OPEN))
1558 {
1559 // if response is there, then this poll squirts out in the CTl poll callback,
1560 // which handles the rest (including decrmenting #pending!!
1561 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
1562 }
1563 if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
1564 {
1565 netapip_freeTransInfo(pTransInfo);
1566 *err = NETAPI_ERR_PA_FW;
1567 netapip_netcpCfgDeleteClass(&netapi_get_global()->nwal_context, class_slot);
1568 netapi_Log (">netcp_cfgAddClass - ERROR returned by NETCP PA firmware %d\n", *err);
1569 if(p_class->classType== NETCP_CFG_CLASS_TYPE_L3_L4)
1570 n->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_l3_classi_lock);
1571 return -1;
1572 }
1573 }
1574 netapi_Log ("netcp_cfg: L4 Classifer added to interface %d ip %d (slot%d)\n", iface_no, ip_slot, class_slot);
1575 netapip_netcpCfgInsertClass(&netapi_get_global()->nwal_context,
1576 class_slot,
1577 p_class->classType,
1578 NULL, //L2 we have
1579 (p_class->classType== NETCP_CFG_CLASS_TYPE_L3_L4? l3_handle : NULL),
1580 pTransInfo->handle,
1581 user_data);
1583 netapip_freeTransInfo(pTransInfo);
1584 if(p_class->classType== NETCP_CFG_CLASS_TYPE_L3_L4)
1585 n->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_l3_classi_lock);
1586 return classHandle;
1587 } //end switch
1589 return -1;
1590 }
1592 /********************************************************************
1593 * FUNCTION PURPOSE: API to delete a preconfigured classifier
1594 ********************************************************************
1595 * DESCRIPTION: API to delete a preconfigured classifier
1596 ********************************************************************/
1597 void netapi_netcpCfgDelClass(NETAPI_T h,
1598 NETCP_CFG_CLASS_T classId,
1599 int* err)
1600 {
1601 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
1602 void *L4_handle = NULL; //class handle -> L4
1603 void *L3_handle = NULL; //class handle -> L3
1604 nwal_RetValue retValue;
1605 NetapiNwalTransInfo_t *pTransInfo;
1606 nwal_TransID_t trans_id;
1607 int class_slot=-1;
1609 class_slot = netapi_cfgGetMatchId(classId);
1610 L4_handle=netapip_netcpCfgGetL4Handle(&netapi_get_global()->nwal_context, class_slot);
1611 if(!L4_handle)
1612 {
1613 *err = NETAPI_ERR_BAD_INPUT;
1614 goto ERR_netapi_netcpCfgDelClass;
1615 }
1616 L3_handle = netapip_netcpCfgGetL3Handle( &netapi_get_global()->nwal_context,
1617 class_slot);
1618 /* l3 handle might be NULL, depending on type of classifier */
1620 if(L3_handle)
1621 {
1622 // grab l3 lock
1623 n->spinLock.lock(&pnetapiShm->netapi_netcp_cfg_l3_classi_lock);
1624 }
1625 netapip_netcpCfgDeleteClass(
1626 &netapi_get_global()->nwal_context,
1627 class_slot );
1628 //get a transaction id
1629 pTransInfo = netapip_getFreeTransInfo(n,
1630 (NETAPI_PROC_GLOBAL_T *) n->proc_global,
1631 &trans_id);
1632 if (!pTransInfo)
1633 {
1634 *err = NETAPI_ERR_BUSY;
1635 goto ERR_netapi_netcpCfgDelClass;
1636 }
1637 pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_PORT;
1638 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING;
1639 pTransInfo->inUse = nwal_TRUE;
1640 pTransInfo->netapi_handle = h;
1641 //issue request for L4
1642 retValue = nwal_delConn(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
1643 trans_id,
1644 L4_handle);
1645 if(retValue != nwal_OK)
1646 {
1647 *err = NETAPI_ERR_NWAL_ERR0;
1648 netapi_Log ("netcp_cfg - ERROR: nwal_delMacIface returned Error Code %d\n", retValue);
1649 netapip_freeTransInfo(pTransInfo);
1650 goto ERR_netapi_netcpCfgDelClass; /* todo: what about the L3? */
1651 }
1652 //wait here until its done since scheduler isn't running yet most likely..
1653 // todo: make this handled by scheduler poll later ??
1654 if(trans_id != NWAL_TRANSID_SPIN_WAIT)
1655 {
1656 n->nwal_local.numPendingCfg++;
1657 while ((pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
1658 (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_IDLE))
1659 {
1660 // if response is there, then this poll squirts out in the CTl poll callback,
1661 // which handles the rest (including decrmenting #pending!!
1662 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
1663 }
1664 }
1665 if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
1666 {
1667 netapip_freeTransInfo(pTransInfo);
1668 *err = NETAPI_ERR_PA_FW;
1669 netapi_Log (">netapi_netcpCfgDelClass - ERROR returned by NETCP PA firmware %d\n", *err);
1670 goto ERR_netapi_netcpCfgDelClass;
1671 }
1672 netapi_Log ("netcp_cfg: Classifer deleted\n");
1673 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;
1674 pTransInfo->inUse = nwal_FALSE;
1676 /* delete L3 if we have to */
1677 if (cfgOkToDeleteL3ClassiHandle(h, L3_handle))
1678 {
1679 netapip_netcpCfgDelIpInternal(h,
1680 0,
1681 0,
1682 NULL,
1683 NULL,
1684 0,
1685 err,
1686 L3_handle,
1687 0);
1688 }
1689 netapip_freeTransInfo(pTransInfo);
1691 ERR_netapi_netcpCfgDelClass:
1692 if(L3_handle)
1693 n->spinLock.unlock(&pnetapiShm->netapi_netcp_cfg_l3_classi_lock);
1695 return;
1696 }
1698 /********************************************************************
1699 * FUNCTION PURPOSE: API to add a flow
1700 ********************************************************************
1701 * DESCRIPTION: API to add a flow
1702 ********************************************************************/
1703 /*--------------flow management--------*/
1704 // ADD A Flow
1705 NETCP_CFG_FLOW_HANDLE_T netapi_netcpCfgAddFlow(NETAPI_T h,
1706 int n,
1707 Pktlib_HeapHandle handles[],
1708 int sizes[],
1709 NETCP_CFG_FLOW_CONFIG_T* p_cfg,
1710 int* err )
1711 {
1712 Cppi_RxFlowCfg rxFlowCfg;
1713 Uint8 isAlloc;
1714 Qmss_QueueHnd rxBufQ[TUNE_NETAPI_MAX_BUF_POOLS_IN_FLOW];
1715 Uint32 rxBufSize[TUNE_NETAPI_MAX_BUF_POOLS_IN_FLOW];
1716 int i;
1717 Cppi_FlowHnd FlowHnd;
1718 int slot;
1719 NETCP_CFG_FLOW_HANDLE_T retVal;
1720 NETAPI_HANDLE_T * pHandle = (NETAPI_HANDLE_T *) h;
1721 *err= 0; /* ok */
1722 if (!p_cfg)
1723 {
1724 *err= NETAPI_ERR_BAD_INPUT;
1725 return NULL;
1726 }
1727 //get a slot to save new flow
1728 slot = netapip_netcpCfgFindFlowSlot(pHandle,
1729 &netapi_get_global()->nwal_context);
1731 if (slot<0) { *err= NETAPI_ERR_NOMEM; return NULL; }
1733 //configure flow
1734 memset(&rxFlowCfg,0,sizeof(Cppi_RxFlowCfg));
1735 for (i = 0; i < TUNE_NETAPI_MAX_BUF_POOLS_IN_FLOW; i++)
1736 {
1737 if (i >= n)
1738 {
1739 rxBufQ[i] = 0;
1740 rxBufSize[i] = 0;
1741 }
1742 else
1743 {
1744 rxBufQ[i] = Pktlib_getInternalHeapQueue(handles[i]);
1745 //todo: verity sizes< heapsize
1746 //todo: verify order
1747 rxBufSize[i]= sizes[i];
1748 }
1749 if (i && (rxBufQ[i] <= 0))
1750 {
1751 rxBufQ[i] = rxBufQ[i-1];
1752 rxBufSize[i] = 0;
1753 }
1754 }
1756 /* Configure Rx flow */
1757 rxFlowCfg.flowIdNum = p_cfg->flow_index;/*CPPI_PARAM_NOT_SPECIFIED*/;
1758 rxFlowCfg.rx_dest_qnum = netapi_pktioGetQ(p_cfg->p_dest_q);
1759 rxFlowCfg.rx_dest_qmgr = Qmss_getQueueNumber(rxFlowCfg.rx_dest_qnum).qMgr;
1760 rxFlowCfg.rx_sop_offset = p_cfg->recv_offset;
1761 rxFlowCfg.rx_ps_location = Cppi_PSLoc_PS_IN_DESC;
1762 rxFlowCfg.rx_desc_type = Cppi_DescType_HOST;
1763 rxFlowCfg.rx_error_handling = p_cfg->block;
1765 rxFlowCfg.rx_psinfo_present = 1;
1766 rxFlowCfg.rx_einfo_present = 1;
1768 rxFlowCfg.rx_dest_tag_lo = 0;
1769 rxFlowCfg.rx_dest_tag_hi = 0;
1770 rxFlowCfg.rx_src_tag_lo = 0;
1771 rxFlowCfg.rx_src_tag_hi = 0;
1773 rxFlowCfg.rx_size_thresh0_en = rxBufSize[1] ? 1 : 0;
1774 rxFlowCfg.rx_size_thresh1_en = rxBufSize[2] ? 1 : 0;
1775 rxFlowCfg.rx_size_thresh2_en = rxBufSize[3] ? 1 : 0;
1777 if (p_cfg->dma_index==NETAPI_DMA_NETCP )
1778 rxFlowCfg.rx_dest_tag_lo_sel =0;
1779 else
1780 rxFlowCfg.rx_dest_tag_lo_sel = 0x4;
1781 rxFlowCfg.rx_dest_tag_hi_sel = 0;
1782 rxFlowCfg.rx_src_tag_lo_sel = 0;
1783 rxFlowCfg.rx_src_tag_hi_sel = 0;
1785 rxFlowCfg.rx_fdq1_qnum = rxBufQ[1];
1786 rxFlowCfg.rx_fdq1_qmgr = (rxBufQ[1] ? Qmss_getQueueNumber(rxBufQ[1]).qMgr: 0);
1787 rxFlowCfg.rx_fdq2_qnum = rxBufQ[2];
1788 rxFlowCfg.rx_fdq2_qmgr = (rxBufQ[2] ? Qmss_getQueueNumber(rxBufQ[2]).qMgr: 0);
1789 rxFlowCfg.rx_fdq3_qnum = rxBufQ[3];
1790 rxFlowCfg.rx_fdq3_qmgr = (rxBufQ[3] ? Qmss_getQueueNumber(rxBufQ[3]).qMgr: 0);
1792 rxFlowCfg.rx_size_thresh0 = rxBufSize[1] ? rxBufSize[0] : 0;
1793 rxFlowCfg.rx_size_thresh1 = rxBufSize[2] ? rxBufSize[1] : 0;
1794 rxFlowCfg.rx_size_thresh2 = rxBufSize[3] ? rxBufSize[2] : 0;
1796 rxFlowCfg.rx_fdq0_sz0_qnum = rxBufQ[0];
1797 rxFlowCfg.rx_fdq0_sz0_qmgr = (rxBufQ[0] ? Qmss_getQueueNumber(rxBufQ[0]).qMgr: 0);
1798 rxFlowCfg.rx_fdq0_sz1_qnum = rxBufQ[1];
1799 rxFlowCfg.rx_fdq0_sz1_qmgr = (rxBufQ[1] ? Qmss_getQueueNumber(rxBufQ[1]).qMgr:0);
1800 rxFlowCfg.rx_fdq0_sz2_qnum = rxBufQ[2];
1801 rxFlowCfg.rx_fdq0_sz2_qmgr = (rxBufQ[2] ? Qmss_getQueueNumber(rxBufQ[2]).qMgr:0);
1802 rxFlowCfg.rx_fdq0_sz3_qnum = rxBufQ[3];
1803 rxFlowCfg.rx_fdq0_sz3_qmgr = (rxBufQ[3] ? Qmss_getQueueNumber(rxBufQ[3]).qMgr:0);
1804 {
1805 //todo: replace this with a nwal call to get global cntx info
1806 Cppi_CpDmaInitCfg cpdmaCfg;
1807 Cppi_Handle cppiHnd;
1808 memset(&cpdmaCfg,0,sizeof(Cppi_CpDmaInitCfg));
1809 cpdmaCfg.dmaNum = (p_cfg->dma_index==NETAPI_DMA_NETCP ) ?Cppi_CpDma_PASS_CPDMA: Cppi_CpDma_QMSS_CPDMA;
1810 cppiHnd= Cppi_open (&cpdmaCfg);
1811 if (cppiHnd == NULL)
1812 {
1813 netapip_netcpCfgDeleteFlow(&netapi_get_global()->nwal_context, slot);
1814 *err= NETAPI_ERR_NORES;
1815 return NULL;
1816 }
1817 FlowHnd = Cppi_configureRxFlow (cppiHnd, &rxFlowCfg, &isAlloc);
1818 }
1819 if (FlowHnd == NULL)
1820 {
1821 *err= NETAPI_ERR_NORES;
1822 netapip_netcpCfgDeleteFlow(&netapi_get_global()->nwal_context, slot);
1823 return (NULL);
1824 }
1826 //update slot
1827 retVal = netapip_netcpCfgInsertFlow(&netapi_get_global()->nwal_context,
1828 slot,
1829 p_cfg->dma_index,
1830 (void*) FlowHnd);
1831 netapi_Log(">netcp cfg: flow %d created in dma index %d\n",
1832 ((NETCP_CFG_FLOW_T *) retVal)->flowid, p_cfg->dma_index);
1833 return (retVal);
1834 }
1836 /********************************************************************
1837 * FUNCTION PURPOSE: API to delete a flow
1838 ********************************************************************
1839 * DESCRIPTION: API to delete a flow
1840 ********************************************************************/
1841 void netapi_netcpCfgDelFlow(NETAPI_T h,
1842 NETCP_CFG_FLOW_HANDLE_T f,
1843 int* err)
1844 {
1845 int slot;
1846 void * handle;
1847 *err=0;
1848 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
1849 /* find entry */
1850 slot = netapip_netcpCfgFindFlow(n,
1851 &netapi_get_global()->nwal_context,
1852 ((NETCP_CFG_FLOW_T *) f) ->flowid,
1853 ((NETCP_CFG_FLOW_T *) f) ->dma_engine,
1854 &handle);
1855 if (slot<0)
1856 {
1857 *err = NETAPI_ERR_BAD_INPUT;
1858 return;
1859 }
1860 if ((Cppi_closeRxFlow( (Cppi_FlowHnd) handle)) == 0)
1861 {
1862 netapip_netcpCfgDeleteFlow(&netapi_get_global()->nwal_context,
1863 slot);
1864 }
1865 return;
1866 }
1868 /******************************************************************************
1869 * FUNCTION PURPOSE: API to configure NETCP with global rules for exception packet handling
1870 ******************************************************************************
1871 * DESCRIPTION: API to configure NETCP with global rules for exception packet handling
1872 *****************************************************************************/
1873 NETCP_CFG_EXCEPTION_PKT_T netapi_netcpCfgExceptions(NETAPI_T h,
1874 int exception_id,
1875 nwal_matchAction_t action,
1876 NETCP_CFG_ROUTE_HANDLE_T p_route)
1877 {
1878 nwalCtlInfo_t ctrl;
1879 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
1880 nwal_RetValue retVal = 0;
1881 memset(&ctrl, 0, sizeof(nwalCtlInfo_t));
1883 if (p_route != NULL)
1884 {
1885 if((p_route->valid_params & NETCP_CFG_VALID_PARAM_ROUTE_TYPE) ==
1886 NETCP_CFG_VALID_PARAM_ROUTE_TYPE)
1887 {
1888 ctrl.validParams |=
1889 NWAL_CONTROL_VALID_PARAM_ROUTE_TYPE;
1890 ctrl.routeType = p_route->routeType;
1891 }
1892 netapip_netcpCfgBuildRoute(p_route,
1893 &ctrl.appRxPktFlowId,
1894 &ctrl.appRxPktQueue,
1895 &ctrl.routeType);
1896 }
1897 else
1898 {
1899 ctrl.appRxPktFlowId = NWAL_FLOW_NOT_SPECIFIED;
1900 ctrl.appRxPktQueue = NWAL_QUEUE_NOT_SPECIFIED;
1901 }
1903 ctrl.appId = (void*)(NETAPI_NETCP_CFG_MATCH_EXCEPTION | exception_id);
1905 ctrl.matchAction = action;
1907 if (exception_id == NETCP_CFG_ALL_EXCEPTIONS)
1908 {
1909 ctrl.pktCtl = NWAL_CTRL_CFG_ALL_EXCEPTIONS;
1910 }
1911 else
1912 {
1913 ctrl.pa_EROUTE_Id = exception_id;
1914 ctrl.pktCtl = NWAL_CTRL_CFG_SINGLE_EXCEPTION;
1915 }
1917 retVal = nwal_control(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle, &ctrl);
1920 return (NETCP_CFG_EXCEPTION_PKT_T) ctrl.appId;
1921 }
1923 /*************************************************************************/
1924 /*********************************INTERNAL*******************************/
1925 /************************************************************************/
1927 /********************************************************************
1928 * FUNCTION PURPOSE: NETAPI internal function, NETCP command reply callback
1929 ********************************************************************
1930 * DESCRIPTION: NETAPI internal function, NETCP command reply callback
1931 ********************************************************************/
1932 void netapip_netcpCfgNWALCmdCallBack(nwal_AppId appHandle,
1933 uint16_t trans_id,
1934 nwal_RetValue ret)
1935 {
1936 NetapiNwalTransInfo_t * p_trans;
1937 NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL;
1939 if(trans_id == NWAL_TRANSID_SPIN_WAIT)
1940 {
1941 netapi_get_proc_global()->nwal_context.numBogusTransIds++;
1942 return;
1943 }
1945 p_trans= &netapi_get_proc_global()->nwal_context.transInfos[trans_id];
1946 p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;
1948 if(ret != nwal_OK)
1949 {
1950 netapi_Log ("netcp_cfg : netapip_netcpCfgNWALCmdCallBack returned Error Code %d for trans_id %d\n",
1951 ret, trans_id);
1952 // update error code that is fialed in p_trans */
1953 //todo: atomic inc
1954 p_trans->state = NETAPI_NWAL_HANDLE_STATE_ERR;
1955 netapi_get_proc_global()->nwal_context.numCmdFail++;
1956 }
1957 else
1958 {
1959 //todo: atomic inc
1960 netapi_get_proc_global()->nwal_context.numCmdPass++;
1961 switch(p_trans->transType)
1962 {
1963 case NETAPI_NWAL_HANDLE_TRANS_MAC:
1964 {
1965 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
1966 {
1967 p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;
1968 }
1969 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
1970 {
1971 p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
1972 }
1973 break;
1974 }
1975 case NETAPI_NWAL_HANDLE_TRANS_IP:
1976 {
1977 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
1978 {
1979 p_trans->state = NETAPI_NWAL_HANDLE_STATE_OPEN;
1980 }
1981 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
1982 {
1983 p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
1984 }
1985 break;
1986 }
1987 case NETAPI_NWAL_HANDLE_TRANS_PORT:
1988 {
1989 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
1990 {
1991 p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;
1992 }
1993 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
1994 {
1995 p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
1996 }
1997 break;
1998 }
1999 case NETAPI_NWAL_HANDLE_TRANS_SA:
2000 {
2001 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
2002 {
2003 p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;
2004 }
2005 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
2006 {
2007 p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
2008 }
2009 break;
2010 }
2011 case NETAPI_NWAL_HANDLE_TRANS_SA_POLICY:
2012 {
2013 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
2014 {
2015 p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;
2016 }
2017 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
2018 {
2019 p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
2020 }
2021 break;
2022 }
2023 default:
2024 {
2025 netapi_Log ("netcp cfg> Invalid transaction type %d for trans_id: %d\n",
2026 p_trans->transType,trans_id);
2027 break;
2028 }
2029 }
2030 }
2032 p_local->numPendingCfg--;
2034 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_IDLE)
2035 {
2036 p_trans->inUse = nwal_FALSE;
2037 }
2038 }
2041 /********************************************************************
2042 * FUNCTION PURPOSE: NETAPI internal function, PA stats reply callback
2043 ********************************************************************
2044 * DESCRIPTION: NETAPI internal function, PA stats reply callback
2045 ********************************************************************/
2046 void netapip_netcpCfgNWALCmdPaStatsReply(nwal_AppId appHandle,
2047 nwal_TransID_t trans_id,
2048 paSysStats_t *stats)
2049 {
2050 NetapiNwalTransInfo_t * p_trans;
2051 NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL;
2053 if(trans_id == NWAL_TRANSID_SPIN_WAIT)
2054 {
2055 netapi_get_proc_global()->nwal_context.numBogusTransIds++;
2056 return;
2057 }
2059 p_trans= &netapi_get_proc_global()->nwal_context.transInfos[trans_id];
2060 p_trans->inUse = nwal_FALSE;
2061 p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;
2063 //save a local copy of some stuff*/
2064 p_local->numL2PktsRecvd=stats->classify1.nPackets;
2065 p_local->numL3PktsRecvd=stats->classify1.nIpv4Packets;
2067 //callout result to application !!
2068 if (p_local->stats_cb)
2069 {
2070 (*p_local->stats_cb)(p_trans->netapi_handle,stats);
2071 }
2072 }