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