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: rev 0.0.1
11 *
12 * Copyright (c) Texas Instruments Incorporated 2010-2011
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 ******************************************************/
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <unistd.h>
46 #include <string.h>
47 #include "netapi.h"
48 #include "netcp_cfg.h"
49 #include "netapi_loc.h"
51 /******************************************************************
52 ********************Utility*************************************
53 *******************************************************************/
56 //get a free transaction id
57 NetapiNwalTransInfo_t * netapip_GetFreeTransInfo(NETAPI_GLOBAL_T *p_global, nwal_TransID_t *pTransId)
58 {
59 uint16_t count=0;
61 count=0;
62 while(count < TUNE_NETAPI_MAX_NUM_TRANS)
63 {
64 if((p_global->nwal_context.transInfos[count].inUse) != nwal_TRUE)
65 {
66 p_global->nwal_context.transInfos[count].inUse = nwal_TRUE;
67 *pTransId = count;
68 return(&p_global->nwal_context.transInfos[count]);
69 }
70 count++;
71 }
73 /* trouble. need to wait for one to free up*/
74 /* to do: handle this by forcing a poll of cntrl queue*/
75 printf(">netcp_cfg: trying to get free transaction slot but all full!!\n");
76 return NULL;
78 }
79 //internal: build route
80 void netcp_cfgp_build_route(NETCP_CFG_ROUTE_T * p_route, int16_t * p_flow, Qmss_QueueHnd * p_q)
81 {
82 if (!p_route) return;
83 if (p_route->p_flow) *p_flow= p_route->p_flow->flowid;
84 else *p_flow = CPPI_PARAM_NOT_SPECIFIED;
85 if (p_route->p_dest_q) *p_q = pktio_get_q(p_route->p_dest_q);
86 else *p_q=QMSS_PARAM_NOT_SPECIFIED;
87 }
88 /*-----------------------------------------------------------*/
89 /*----------------database management stuff-------------------*/
90 /*-----------------------------------------------------------*/
92 /*=====================Policies=============================*/
93 //internal: find a free slot for an SA
94 int netcp_cfgp_find_policy_slot( NETAPI_NWAL_GLOBAL_CONTEXT_T *p, int tunnel)
95 {
96 int i;
97 if ((tunnel <0 ) || (tunnel >=TUNE_NETAPI_MAX_SA)) return -1;
99 //find a free entry
100 for(i=0;i<TUNE_NETAPI_MAX_POLICY;i++)
101 {
102 if (!p->policy[i].in_use)
103 {
104 p->policy[i].in_use = 2; //pending
105 p->policy[i].tunnel= tunnel; //save tunnel this is linked to
106 return i;
107 }
108 }
109 return -1;
110 }
112 //internal: delete a policy from list
113 void netcp_cfgp_delete_policy(
114 NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
115 int policy_slot )
116 {
117 if ((policy_slot <0 ) || (policy_slot >= TUNE_NETAPI_MAX_POLICY))
118 {
119 return ;
120 }
121 p->policy[policy_slot].in_use=0;
122 return;
123 }
125 //internal: insert an policy into the list
126 void netcp_cfgp_insert_policy(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
127 int policy_slot, //we 'reserved it already'
128 void * handle)
129 {
130 p->policy[policy_slot].in_use=1;
131 p->policy[policy_slot].nwal_handle = handle;
132 return;
133 }
135 //internal: return nwal_handle for policy
136 void *netcp_cfgp_get_policy( NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
137 int policy_slot)
138 {
139 if ((policy_slot <0 ) || (policy_slot >= TUNE_NETAPI_MAX_POLICY)) return NULL;
140 if (!p->policy[policy_slot].in_use) return NULL;
141 return p->policy[policy_slot].nwal_handle;
142 }
146 /*======================SAs==================================*/
147 //internal: find a free slot for an SA
148 int netcp_cfgp_find_sa_slot( NETAPI_NWAL_GLOBAL_CONTEXT_T *p, int iface)
149 {
150 int i;
151 if (iface != NETCP_CFG_NO_INTERFACE)
152 {
153 if ((iface <0 ) || (iface >=TUNE_NETAPI_MAX_NUM_MAC)) return -1;
154 }
155 //find a free entry
156 for(i=0;i<TUNE_NETAPI_MAX_SA;i++)
157 {
158 if (!p->tunnel[i].in_use)
159 {
160 p->tunnel[i].in_use = 2; //pending
161 p->tunnel[i].iface= iface; //save iface
162 return i;
163 }
164 }
165 return -1;
166 }
167 //internal: delete an SAr from list
168 void netcp_cfgp_delete_sa(
169 NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
170 int sa_slot )
171 {
172 if ((sa_slot <0 ) || (sa_slot >= TUNE_NETAPI_MAX_SA))
173 {
174 return ;
175 }
176 p->tunnel[sa_slot].in_use=0;
177 return;
178 }
180 //internal: insert an SA into the list
181 void netcp_cfgp_insert_sa(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
182 int sa_slot, //we 'reserved it already'
183 int dir,
184 int mode,
185 void * temp1,
186 void * temp2,
187 void * handle_inflow,
188 void * handle_sideband)
189 {
190 p->tunnel[sa_slot].in_use=1;
191 p->tunnel[sa_slot].inbound = dir;
192 p->tunnel[sa_slot].sa_mode = mode;
193 p->tunnel[sa_slot].sa_handle_inflow = handle_inflow;
194 p->tunnel[sa_slot].sa_handle_sideband = handle_sideband;
195 return;
196 }
198 //internal: return nwal_handles for SA
199 void *netcp_cfgp_get_sa_handles( NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
200 int sa_slot, void ** p_sideband)
201 {
202 if ((sa_slot <0 ) || (sa_slot >= TUNE_NETAPI_MAX_SA)) return NULL;
203 if (!p->tunnel[sa_slot].in_use) return NULL;
204 *p_sideband = p->tunnel[sa_slot].sa_handle_sideband;
205 return p->tunnel[sa_slot].sa_handle_inflow;
206 }
209 /*==============================fLOWS=============================*/
210 //internal: find a free slot for a flow
211 static int netcp_cfgp_find_flow_slot( NETAPI_NWAL_GLOBAL_CONTEXT_T *p)
212 {
213 int i;
214 //find a free entry
215 for(i=0;i<TUNE_NETAPI_MAX_FLOWS;i++)
216 {
217 if (!p->flows[i].in_use)
218 {
219 p->flows[i].in_use = 2; //pending
220 return i;
221 }
222 }
223 return -1;
224 }
226 //internal: clear flow slot
227 static void netcp_cfgp_delete_flow(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,int slot)
228 {
229 if ((slot >=0 ) && (slot < TUNE_NETAPI_MAX_FLOWS))
230 {
231 p->flows[slot].in_use = 0;
232 }
233 }
235 //internal: insert a flow into flow slot
236 static NETCP_CFG_FLOW_HANDLE_T netcp_cfgp_insert_flow(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
237 int slot, //we 'reserved it already'
238 void * handle) //cppi flow handle. Save this for delete
239 {
240 p->flows[slot].in_use=1;
241 p->flows[slot].handle = handle;
242 p->flows[slot].flow.flowid = Cppi_getFlowId(handle);
243 return (NETCP_CFG_FLOW_HANDLE_T) &p->flows[slot].flow;
244 }
246 //find entry matching the flowid. return slot# and the cppi handle
247 static int netcp_cfgp_find_flow(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
248 int flowid,
249 void ** handle)
250 {
251 int i;
252 *handle=NULL;
253 for(i=0;i<TUNE_NETAPI_MAX_FLOWS;i++)
254 {
255 if ((p->flows[i].in_use)&&(p->flows[i].flow.flowid == flowid))
256 {
257 *handle = p->flows[i].handle;
258 return i;
259 }
260 }
261 return -1;
262 }
265 /*============================IP ADDRESSES==========================*/
267 //internal: find a free slot for IP rule
268 static int netcp_cfgp_find_ip_slot(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
269 int iface_no)
270 {
271 int i;
273 //find a free entry
274 for(i=0;i<TUNE_NETAPI_MAX_NUM_IP;i++)
275 {
276 if (!p->ips[i].in_use)
277 {
278 p->ips[i].in_use = 2; //pending
279 return i;
280 }
281 }
282 return -1;
283 }
286 //internal: insert an IP address into iface
287 static void netcp_cfgp_insert_ip(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
288 nwal_IpType ipType,
289 nwalIpAddr_t *ip_addr,
290 nwalIpOpt_t *ip_qualifiers,
291 int iface_no,
292 int ip_slot, //we 'reserved it already'
293 void * handle)
294 {
295 p->ips[ip_slot].in_use=1;
296 memcpy(&p->ips[ip_slot].ip_addr, ip_addr, sizeof(nwalIpAddr_t));
297 if(ip_qualifiers)
298 memcpy(&p->ips[ip_slot].ip_qualifiers, ip_qualifiers, sizeof(nwalIpOpt_t));
299 else
300 memset(&p->ips[ip_slot].ip_qualifiers, 0, sizeof(nwalIpOpt_t));
301 p->ips[ip_slot].ip_type = ipType;
302 p->ips[ip_slot].nwal_handle = handle;
303 return;
304 }
307 //internal: free IP slot associated with ip address
308 static void netcp_cfgp_delete_ip(
309 NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
310 int iface_no,
311 int ip_slot )
312 {
313 if ((ip_slot <0)||(ip_slot>TUNE_NETAPI_MAX_NUM_IP)) return ;
314 p->ips[ip_slot].in_use=0;
315 return;
316 }
319 //internal: get IP handle associated with ip address
320 static void *netcp_cfgp_get_ip_handle(
321 NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
322 int iface_no,
323 int ip_slot )
324 {
325 if ((ip_slot <0)||(ip_slot>=TUNE_NETAPI_MAX_NUM_IP)) return NULL;
326 if (!p->ips[ip_slot].in_use) return NULL;
327 return (void *) p->ips[ip_slot].nwal_handle;
328 }
330 /*==========================MAC INTERFACES======================*/
331 //internal: insert interface info into global context
332 static void netcp_cfgp_insert_mac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p, unsigned char * p_mac,
333 int iface_no, int state, NETCP_CFG_VLAN_T vlan, void * handle)
334 {
335 if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_NUM_MAC))
336 {
337 memset(&p->interfaces[iface_no],0,sizeof(NETCP_INTERFACE_T));
338 p->interfaces[iface_no].in_use = 1;
339 memcpy(&p->interfaces[iface_no].mac[0], p_mac,6);
340 p->interfaces[iface_no].state = state;
341 //todo p->interfaces[iface_no].vlan = vlan;
342 p->interfaces[iface_no].nwal_handle = handle; //save handle assoicated with this rule
343 }
344 else printf(">netcp_cfg insert interface # out of range %d\n",iface_no);
346 }
348 //internal: get handle associated with interface
349 void* netcp_cfgp_get_mac_handle(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,int iface_no)
350 {
351 if (iface_no == NETCP_CFG_NO_INTERFACE) return NULL;
352 if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_NUM_MAC))
353 {
354 return NULL;
355 }
356 else if ( p->interfaces[iface_no].in_use)
357 {
358 return (void *) p->interfaces[iface_no].nwal_handle;
359 }
360 //no valid entry in slot
361 return NULL;
362 }
363 //internal: clear inteface entry
364 static void netcp_cfgp_delete_mac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,int iface_no)
365 {
366 if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_NUM_MAC))
367 {
368 p->interfaces[iface_no].in_use = 0;
369 }
370 }
373 /*========================CLASSIFIERS==========================*/
374 //internal: find a free slot for classifier rule
375 static int netcp_cfgp_find_class_slot( NETAPI_NWAL_GLOBAL_CONTEXT_T *p)
376 {
377 int i;
378 //find a free entry
379 for(i=0;i<TUNE_NETAPI_MAX_CLASSIFIERS;i++)
380 {
381 if (!p->classi[i].in_use)
382 {
383 p->classi[i].in_use = 2; //pending
384 return i;
385 }
386 }
387 return -1;
388 }
390 //internal: delete a classifer from list
391 static void netcp_cfgp_delete_class(
392 NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
393 int class_slot )
394 {
395 if ((class_slot <0 ) || (class_slot >= TUNE_NETAPI_MAX_CLASSIFIERS))
396 {
397 return ;
398 }
399 p->classi[class_slot].in_use=0;
400 return;
401 }
403 //internal: insert a classifier into list
404 static void netcp_cfgp_insert_class(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
405 int class_slot, //we 'reserved it already'
406 int class_type,
407 void * L2_handle,
408 void * L3_handle,
409 void * L4_handle)
410 {
411 p->classi[class_slot].in_use=1;
412 p->classi[class_slot].nwal_L2_handle = L2_handle;
413 p->classi[class_slot].nwal_L3_handle = L3_handle;
414 p->classi[class_slot].nwal_L4_handle = L4_handle;
415 p->classi[class_slot].class_type = class_type;
416 return;
417 }
419 //internal: return L4 nwal_handle for class
420 static void *netcp_cfgp_get_l4_handle( NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
421 int class_slot)
422 {
423 if ((class_slot <0 ) || (class_slot >= TUNE_NETAPI_MAX_CLASSIFIERS)) return NULL;
424 if (!p->classi[class_slot].in_use) return NULL;
425 return p->classi[class_slot].nwal_L4_handle;
426 }
428 //internal: return L3 nwal_handle for class
429 static void *netcp_cfgp_get_l3_handle( NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
430 int class_slot)
431 {
432 if ((class_slot <0 ) || (class_slot >= TUNE_NETAPI_MAX_CLASSIFIERS)) return NULL;
433 if (!p->classi[class_slot].in_use) return NULL;
434 return p->classi[class_slot].nwal_L3_handle;
435 }
438 /***********************************************************************************/
439 /****************************************API****************************************/
440 /***********************************************************************************/
443 /*****************************************************************
444 * Queury Stats
445 ****************************************************************/
446 void netcp_cfgReqStats(NETAPI_T h, NETCP_CFG_STATS_CB cb, int doClear, int *err)
447 {
448 nwal_RetValue ret;
449 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
450 NetapiNwalTransInfo_t *pTransInfo;
451 nwal_TransID_t transId;
452 if ((!n) || (!cb)) {*err = NETAPI_ERR_BAD_INPUT; return ;}
453 *err =0;
456 pTransInfo = netapip_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &transId);
457 if (!pTransInfo) { *err = NETAPI_ERR_BUSY; return ;}
458 pTransInfo->transType = NETAPI_NWAL_HANDLE_STAT_REQUEST;
459 pTransInfo->netapi_handle = h;
460 n->nwal_local.stats_cb = cb;
461 ret = nwal_getPAStats( ((NETAPI_GLOBAL_T *) n->global)->nwal_context.nwalInstHandle,
462 transId,
463 NULL,
464 doClear);
465 if(ret != nwal_OK)
466 {
467 pTransInfo->inUse = nwal_FALSE;
468 *err = NETAPI_ERR_BUSY; //no resources??
469 printf("> netcp_cfg reqStats failed, err=%d\n",ret);
470 }
472 }
473 /*****************************************************************
474 * CREATE A MAC INTERFACE
475 ****************************************************************/
476 NETCP_CFG_MACIF_T netcp_cfgCreateMacInterface(
477 NETAPI_T h,
478 uint8_t *p_mac,
479 int iface_no,
480 int switch_port,
481 NETCP_CFG_ROUTE_HANDLE_T route,
482 NETCP_CFG_VLAN_T vlan, //future
483 int state, //0=down, 1=up //ignored
484 int * err
485 )
486 {
487 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
488 nwalMacParam_t MacInfo= {
489 0, /* validParams */
490 0, /* ifNum */
491 0, /* vlanId */
492 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* Local mac */
493 NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE, /* Continue parsing to next route for match */
494 NWAL_NEXT_ROUTE_FAIL_ACTION_HOST, /* For next route fail action by default is route to host */
495 CPPI_PARAM_NOT_SPECIFIED, /* Use default flow configured to NWAL if packet is routed to host */
496 QMSS_PARAM_NOT_SPECIFIED /* Use default queue configured to NWAL if packet is routed to host */
497 };
499 nwal_RetValue retValue;
500 NetapiNwalTransInfo_t *pTransInfo;
501 nwal_TransID_t trans_id;
503 if ((!n) || (!p_mac)) {*err = NETAPI_ERR_BAD_INPUT; return -1;}
504 *err =0;
506 pTransInfo = netapip_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
507 if (!pTransInfo) { *err = NETAPI_ERR_BUSY; return -1;}
508 pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC;
509 pTransInfo->netapi_handle = h;
511 /* set up MacInfo */
512 memcpy(&MacInfo.macAddr,p_mac,6);
513 /* todo: vlan */
514 MacInfo.ifNum = switch_port; /* todo: check for 0/1 relative*/
516 if (route != NULL)
517 {
518 netcp_cfgp_build_route(route,&MacInfo.appRxPktFlowId, &MacInfo.appRxPktQueue);
519 }
520 pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
521 retValue = nwal_setMacIface( ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
522 trans_id,
523 (nwal_AppId) (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no),
524 &MacInfo,
525 &pTransInfo->handle);
526 if(retValue != nwal_OK)
527 {
528 *err = NETAPI_ERR_NWAL_ERR0;
529 printf (">netcp cfg - ERROR: nwal_setMacIface returned Error Code %d\n",
530 retValue);
531 pTransInfo->inUse = nwal_FALSE;
532 return -1;
533 }
534 //pTransInfo->inUse = nwal_FALSE;
536 //wait here until its done since scheduler isn't running yet most likely..
537 // todo: make this handled by scheduler poll later ??
538 if(trans_id != NWAL_TRANSID_SPIN_WAIT)
539 {
540 n->nwal_local.numPendingCfg++;
541 while ((volatile) n->nwal_local.numPendingCfg)
542 {
543 // if response is there, then this poll squirts out in the CTl poll callback,
544 // which handles the rest (including decrmenting #pending!!
545 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
546 }
547 }
548 printf (">netcp cfg: MAC i/f %d added\n", iface_no);
549 netcp_cfgp_insert_mac(&netapi_get_global()->nwal_context,
550 p_mac, iface_no, state,vlan,
551 (void *) pTransInfo->handle);
552 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;
553 pTransInfo->inUse = nwal_FALSE;
554 return (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no);
555 }
558 /*****************************************************************/
559 /***************Delete a mac interface****************************/
560 /*****************************************************************/
561 void netcp_cfgDelMac(NETAPI_T h,int iface_no, int *err)
562 {
563 nwal_RetValue ret;
564 NetapiNwalTransInfo_t *pTransInfo;
565 nwal_TransID_t trans_id;
566 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
567 void * ifHandle;
569 //get the nwal handle assoicated with this iface
570 ifHandle = netcp_cfgp_get_mac_handle(&netapi_get_global()->nwal_context, iface_no );
571 if(!ifHandle)
572 {*err = NETAPI_ERR_BAD_INPUT; return ;}
573 *err =0;
575 //get a transaction id
576 pTransInfo = netapip_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
577 if (!pTransInfo) { *err = NETAPI_ERR_BUSY; return ;}
578 pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC;
579 pTransInfo->netapi_handle = h;
580 //issue request
581 ret = nwal_delMacIface(
582 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
583 trans_id,
584 ifHandle);
585 if(ret != nwal_OK)
586 {
587 *err = NETAPI_ERR_NWAL_ERR0;
588 printf (">netcp cfg - ERROR: nwal_delMacIface returned Error Code %d\n",
589 ret);
590 pTransInfo->inUse = nwal_FALSE;
591 return ;
592 }
593 //wait here until its done since scheduler isn't running yet most likely..
594 // todo: make this handled by scheduler poll later ??
595 if(trans_id != NWAL_TRANSID_SPIN_WAIT)
596 {
597 n->nwal_local.numPendingCfg++;
598 while ((volatile) n->nwal_local.numPendingCfg)
599 {
600 // if response is there, then this poll squirts out in the CTl poll callback,
601 // which handles the rest (including decrmenting #pending!!
602 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
603 }
604 }
605 printf (">netcp cfg: MAC i/f %d deleted\n",iface_no);
606 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;
607 pTransInfo->inUse = nwal_FALSE;
608 //zap the entry
609 netcp_cfgp_delete_mac(&netapi_get_global()->nwal_context, iface_no);
610 return ;
611 }
614 /*****************************************************************/
615 /***************Add IP to MAC interface (internal)****************/
616 /*****************************************************************/
617 static NETCP_CFG_IP_T netcp_cfgAddIpInternal(
618 NETAPI_T h,
619 int iface_no,
620 nwal_IpType ipType,
621 nwalIpAddr_t * ip_addr,
622 nwalIpOpt_t * ip_qualifiers,
623 NETCP_CFG_ROUTE_HANDLE_T route, //NULL for default
624 int * err,
625 int flag) //TRUE: add IP to iface. False: add IP as part of classifier
626 {
627 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
628 void * n_handle=NULL;
629 nwalIpParam_t nwalIpParam= {
630 pa_IPV4, /* IP Type */
631 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Dest IP */
632 { 0x0,0,0,0},/* IP Options */
633 NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE, /* Continue parsing to next route for match */
634 NWAL_NEXT_ROUTE_FAIL_ACTION_HOST, /* For next route fail action by default is route to host */
635 CPPI_PARAM_NOT_SPECIFIED, /* Use default flow configured to NWAL if packet is routed to host */
636 QMSS_PARAM_NOT_SPECIFIED /* Use default queue configured to NWAL if packet is routed to host */
637 };
638 nwal_RetValue retValue;
639 NetapiNwalTransInfo_t *pTransInfo;
640 nwal_TransID_t trans_id;
641 int ip_slot=-1;
642 NETCP_CFG_IP_T ip_rule_id;
643 NETCP_CFG_IP_T temp;
645 //verify that iface has been configured
646 if (iface_no != NETCP_CFG_NO_INTERFACE)
647 {
648 if ((iface_no<0) || (iface_no>= TUNE_NETAPI_MAX_NUM_MAC)) {*err = NETAPI_ERR_BAD_INPUT; return -1;}
649 }
651 if (iface_no != NETCP_CFG_NO_INTERFACE)
652 {
653 if(netapi_get_global()->nwal_context.interfaces[iface_no].in_use)
654 {
655 n_handle = netapi_get_global()->nwal_context.interfaces[iface_no].nwal_handle;
656 }
657 else
658 {
659 *err = NETAPI_ERR_BAD_INPUT;
660 return -1;
661 }
662 }
663 if (flag) //if adding IP to MAC then reserve a slot to save info
664 {
665 //find free slot for IP & reserve
666 ip_slot= netcp_cfgp_find_ip_slot(&netapi_get_global()->nwal_context,
667 iface_no);
668 if (ip_slot <0)
669 {
670 *err= NETAPI_ERR_NOMEM; //no room
671 return -1;
672 }
673 }
675 //get a transaction object for config action
676 pTransInfo = netapip_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
677 if (!pTransInfo) { *err = NETAPI_ERR_BUSY; return -1;}
678 pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;
679 pTransInfo->netapi_handle = h;
681 //build nwalIpParam
682 memcpy(&nwalIpParam.locIpAddr,ip_addr, sizeof(nwalIpAddr_t));
683 nwalIpParam.ipType=ipType;
684 if(route)
685 {
686 netcp_cfgp_build_route(route,&nwalIpParam.appRxPktFlowId, &nwalIpParam.appRxPktQueue);
687 }
688 else{} //use nwal defaults
689 if (ip_qualifiers)
690 memcpy(&nwalIpParam.ipOpt,ip_qualifiers, sizeof(nwalIpOpt_t));
691 else
692 memset(&nwalIpParam.ipOpt,0, sizeof(nwalIpOpt_t));
694 //build the rule id that will be returned when a packet matches
695 if (flag)
696 ip_rule_id = NETAPI_NETCP_MATCH_GENERIC_IP | iface_no | ((ip_slot&&0xff)<<8);
697 else
698 ip_rule_id = (NETAPI_NETCP_MATCH_CLASS_L3 | iface_no);
700 //perform config action
701 pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
702 retValue = nwal_setIPAddr( netapi_get_global()->nwal_context.nwalInstHandle,
703 trans_id,
704 (nwal_AppId) (ip_rule_id),
705 n_handle,
706 &nwalIpParam,
707 &pTransInfo->handle);
709 if(retValue != nwal_OK)
710 {
711 *err = NETAPI_ERR_NWAL_ERR0;
712 printf (">netcp cfg: nwal_setIP returned Error Code %d\n",
713 retValue);
714 pTransInfo->inUse = nwal_FALSE;
715 //zap the entry
716 if (flag)
717 {
718 netcp_cfgp_delete_ip(&netapi_get_global()->nwal_context,
719 iface_no,
720 ip_slot);
721 }
722 return -1;
723 }
724 //wait here until its done since scheduler isn't running yet most likely..
725 // todo: make this handled by scheduler poll later ??
726 if(trans_id != NWAL_TRANSID_SPIN_WAIT)
727 {
728 n->nwal_local.numPendingCfg++;
729 while ((volatile) n->nwal_local.numPendingCfg)
730 {
731 // if response is there, then this poll squirts out in the CTl poll callback,
732 // which handles the rest (including decrmenting #pending!!
733 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
734 }
735 }
736 if (flag)
737 {
738 printf (">netcp cfg: IP added to interface %d (slot%d)\n", iface_no, ip_slot);
739 netcp_cfgp_insert_ip(&netapi_get_global()->nwal_context, ipType,
740 ip_addr, ip_qualifiers, iface_no, ip_slot,
741 pTransInfo->handle);
742 }
743 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;
744 temp = (NETCP_CFG_IP_T) pTransInfo->handle;
745 pTransInfo->inUse = nwal_FALSE;
746 return (flag ? ip_rule_id: temp);
747 }
748 /*****************************************************************/
749 /***************Add IP to MAC interface **************************/
750 /*****************************************************************/
751 NETCP_CFG_IP_T netcp_cfgAddIp(
752 NETAPI_T h,
753 int iface_no,
754 nwal_IpType ipType,
755 nwalIpAddr_t * ip_addr,
756 nwalIpOpt_t * ip_qualifiers,
757 NETCP_CFG_ROUTE_HANDLE_T route, //NULL for default
758 int * err
759 )
760 {
761 return netcp_cfgAddIpInternal(
762 h, iface_no, ipType, ip_addr, ip_qualifiers, route, err,
763 1);
764 }
766 /*****************************************************************/
767 /***************Delete an attached IP*****************************/
768 /*****************************************************************/
769 static void netcp_cfgDelIpInternal(NETAPI_T h, int iface_no, nwal_IpType ipType,
770 nwalIpAddr_t * ip_addr,
771 nwalIpOpt_t * ip_qualifiers,
772 NETCP_CFG_IP_T ip_rule_id,
773 int *err,
774 void * handle, /* if flag==0, handle must be valid */
775 int flag) /* flag==0 => delete IP rule that was part of classifier, not interface */
776 {
777 nwal_RetValue ret;
778 NetapiNwalTransInfo_t *pTransInfo;
779 nwal_TransID_t trans_id;
780 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
781 void * ifHandle;
782 int ip_slot = (ip_rule_id>>8)&0xff;
784 //get the nwal handle assoicated with this ip
785 if (flag)
786 {
787 ifHandle = netcp_cfgp_get_ip_handle(
788 &netapi_get_global()->nwal_context, iface_no,
789 ip_slot );
790 }
791 else
792 {
793 ifHandle = handle;
794 }
795 if(!ifHandle)
796 {*err = NETAPI_ERR_BAD_INPUT; return ;}
797 *err =0;
799 //get a transaction id
800 pTransInfo = netapip_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
801 if (!pTransInfo) { *err = NETAPI_ERR_BUSY; return ;}
802 pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;
803 pTransInfo->netapi_handle = h;
804 //issue request
805 ret = nwal_delIPAddr(
806 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
807 trans_id,
808 ifHandle);
809 if(ret != nwal_OK)
810 {
811 *err = NETAPI_ERR_NWAL_ERR0;
812 printf (">netcp cfg - ERROR: nwal_delMacIface returned Error Code %d\n",
813 ret);
814 pTransInfo->inUse = nwal_FALSE;
815 return ;
816 }
817 //wait here until its done since scheduler isn't running yet most likely..
818 // todo: make this handled by scheduler poll later ??
819 if(trans_id != NWAL_TRANSID_SPIN_WAIT)
820 {
821 n->nwal_local.numPendingCfg++;
822 while ((volatile) n->nwal_local.numPendingCfg)
823 {
824 // if response is there, then this poll squirts out in the CTl poll callback,
825 // which handles the rest (including decrmenting #pending!!
826 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
827 }
828 }
829 if (flag)
830 printf (">netcp cfg: attached IP deleted\n");
831 else
832 printf (">netcp cfg: Classifier IP rule deleted\n");
833 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;
834 pTransInfo->inUse = nwal_FALSE;
836 //zap the entry
837 if (flag)
838 netcp_cfgp_delete_ip(&netapi_get_global()->nwal_context,
839 iface_no,
840 ip_slot);
841 return ;
842 }
844 /*****************************************************************/
845 /***************Delete an attached IP*****************************/
846 /*****************************************************************/
847 void netcp_cfgDelIp(NETAPI_T h, int iface_no, nwal_IpType ipType,
848 nwalIpAddr_t * ip_addr,
849 nwalIpOpt_t * ip_qualifiers,
850 NETCP_CFG_IP_T ip_rule_id,
851 int *err)
852 {
853 netcp_cfgDelIpInternal( h, iface_no, ipType,
854 ip_addr, ip_qualifiers, ip_rule_id,
855 err, NULL, 1);
856 return;
857 }
860 /**
861 * @def netcp_cfgAddClass
862 * @brief add a classifier rule into NETCP
863 **/
864 NETCP_CFG_CLASS_T netcp_cfgAddClass(NETAPI_T h,
865 NETCP_CFG_CLASSIFIER_T *p_class,
866 NETCP_CFG_ROUTE_HANDLE_T route,
867 int action, int * err)
868 {
869 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
870 void * l3_handle=NULL; //ip handle
871 nwal_RetValue retValue;
872 NetapiNwalTransInfo_t *pTransInfo;
873 nwal_TransID_t trans_id;
874 int class_slot=-1;
875 int iface_no;
876 int ip_slot=-1;
877 NETCP_CFG_CLASS_T classHandle; //returned by us
878 nwal_appProtoType_t proto;
879 nwalRxConnCfg_t tempCfg={
880 0, //nwal_handle: to be filled in
881 {0}, // l4 ports: to be filled in
882 0, //core id (NA)
883 0, //action
884 CPPI_PARAM_NOT_SPECIFIED, //flow id
885 QMSS_PARAM_NOT_SPECIFIED, //dest queue
886 };
888 if(!p_class) { *err=NETAPI_ERR_BAD_INPUT; return -1;}
889 switch(p_class->classType)
890 {
891 default:
892 printf(">netcp_cfg : classifier type %d not supported\n",p_class->classType);
893 break;
894 case(NETCP_CFG_CLASS_TYPE_L3_L4):
895 case(NETCP_CFG_CLASS_TYPE_L4):
896 //assume just type l4 only (L2, L3 defined by iface, l3 id )
897 iface_no = p_class->u.c_l4.iface;
898 if (p_class->classType== NETCP_CFG_CLASS_TYPE_L4)
899 {
900 ip_slot = (p_class->u.c_l4.ip>>8)&0xff;
901 }
903 //verify that iface has been configured
904 if (iface_no != NETCP_CFG_NO_INTERFACE)
905 {
906 if(!netapi_get_global()->nwal_context.interfaces[iface_no].in_use)
907 {
908 *err = NETAPI_ERR_BAD_INPUT;
909 return -1;
910 }
911 }
913 if (p_class->classType== NETCP_CFG_CLASS_TYPE_L4)
914 {
915 //verify that ip has been configured and get its handle
916 l3_handle = netcp_cfgp_get_ip_handle(
917 &netapi_get_global()->nwal_context, iface_no,
918 ip_slot );
919 }
920 else
921 {
922 nwalIpParam_t tempParam={
923 pa_IPV4, /* IP Type */
924 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Dest IP */
925 { 0x0,0,0,0},/* IP Options */
926 NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE, /* Continue parsing to next route for match */
927 NWAL_NEXT_ROUTE_FAIL_ACTION_HOST, /* For next route fail action by default is route to host */
928 CPPI_PARAM_NOT_SPECIFIED, /* Use default flow configured to NWAL if packet is routed to host */
929 QMSS_PARAM_NOT_SPECIFIED /* Use default queue configured to NWAL if packet is routed to host */
930 };
931 //build nwalIpParam
932 memcpy(&tempParam.locIpAddr,p_class->u.c_l3_l4.ip_addr, sizeof(nwalIpAddr_t));
933 tempParam.ipType=p_class->u.c_l3_l4.ipType;
934 //use nwal defauls for route
935 if (p_class->u.c_l3_l4.ip_qualifiers)
936 memcpy(&tempParam.ipOpt,p_class->u.c_l3_l4.ip_qualifiers, sizeof(nwalIpOpt_t));
937 else
938 memset(&tempParam.ipOpt,0, sizeof(nwalIpOpt_t));
941 //find if we have a matching L3 handle for IP classifier; if not create it
942 retValue = nwal_getIPAddr (((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
943 &tempParam,
944 netcp_cfgp_get_mac_handle(&netapi_get_global()->nwal_context, iface_no ),
945 &l3_handle);
946 if (retValue != nwal_TRUE)
947 {
948 int ret;
949 //**NEW IP RULE
950 //need to attach this IP RULE to the MAC
951 l3_handle= (void *) netcp_cfgAddIpInternal(
952 h, iface_no,
953 p_class->u.c_l3_l4.ipType,
954 p_class->u.c_l3_l4.ip_addr,
955 p_class->u.c_l3_l4.ip_qualifiers,
956 p_class->u.c_l3_l4.p_fail_route,
957 &ret,
958 FALSE);
959 if(!ret)
960 {
961 l3_handle=NULL;
962 }
963 }
964 }
965 if(!l3_handle)
966 {*err = NETAPI_ERR_BAD_INPUT; return -1 ;}
969 //find free slot for CLASS & reserve
970 class_slot= netcp_cfgp_find_class_slot(&netapi_get_global()->nwal_context);
971 if(class_slot<0) {*err = NETAPI_ERR_NOMEM; return -1;}
972 classHandle = NETAPI_NETCP_MATCH_CLASS | (class_slot<<8) | (iface_no&0xff);
973 //build request from template
974 tempCfg.inHandle=l3_handle;
975 if (p_class->classType== NETCP_CFG_CLASS_TYPE_L4)
976 {
977 memcpy(&tempCfg.appProto,&p_class->u.c_l4.appProto,sizeof(nwalAppProto_t));
978 proto = p_class->u.c_l4.proto;
979 }
980 else
981 {
982 memcpy(&tempCfg.appProto,&p_class->u.c_l3_l4.appProto,sizeof(nwalAppProto_t));
983 proto = p_class->u.c_l3_l4.proto;
984 }
986 tempCfg.matchAction = (action==NETCP_CFG_ACTION_TO_SW) ? NWAL_MATCH_ACTION_HOST : NWAL_MATCH_ACTION_DISCARD;
987 if (route)
988 {
989 netcp_cfgp_build_route(route,&tempCfg.appRxPktFlowId, &tempCfg.appRxPktQueue);
990 }
992 //get a transaction id
993 pTransInfo = netapip_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
994 if (!pTransInfo) { *err = NETAPI_ERR_BUSY; return -1 ;}
995 pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP; /* todo: fix this to TRANS_L4*/
996 pTransInfo->netapi_handle = h;
997 //issue request
998 retValue = nwal_addConn(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
999 trans_id,
1000 (nwal_AppId) classHandle,
1001 proto,
1002 &tempCfg,
1003 NULL,
1004 &pTransInfo->handle);
1005 if(retValue != nwal_OK)
1006 {
1007 *err = NETAPI_ERR_NWAL_ERR0;
1008 printf (">netcp cfg - ERROR: nwal_addConn returned Error Code %d\n",
1009 retValue);
1010 pTransInfo->inUse = nwal_FALSE;
1011 netcp_cfgp_delete_class(&netapi_get_global()->nwal_context, class_slot);
1012 return -1;
1013 }
1014 //wait here until its done since scheduler isn't running yet most likely..
1015 // todo: make this handled by scheduler poll later ??
1016 if(trans_id != NWAL_TRANSID_SPIN_WAIT)
1017 {
1018 n->nwal_local.numPendingCfg++;
1019 while ((volatile) n->nwal_local.numPendingCfg)
1020 {
1021 // if response is there, then this poll squirts out in the CTl poll callback,
1022 // which handles the rest (including decrmenting #pending!!
1023 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
1024 }
1025 }
1026 printf (">netcp cfg: L4 Classifer added to interface %d ip %d (slot%d)\n", iface_no, ip_slot, class_slot);
1027 netcp_cfgp_insert_class(&netapi_get_global()->nwal_context,
1028 class_slot,
1029 p_class->classType,
1030 NULL, //L2 we have
1031 (p_class->classType== NETCP_CFG_CLASS_TYPE_L3_L4? l3_handle : NULL),
1032 pTransInfo->handle);
1033 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;
1034 return classHandle;
1035 } //end switch
1036 return -1;
1037 }
1039 //delete classifier
1040 void netcp_cfgDelClass(NETAPI_T h,
1041 NETCP_CFG_CLASS_T classId,
1042 int *err)
1043 {
1044 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
1045 void * L4_handle; //class handle -> L4
1046 void * L3_handle; //class handle -> L3
1047 nwal_RetValue retValue;
1048 NetapiNwalTransInfo_t *pTransInfo;
1049 nwal_TransID_t trans_id;
1050 int class_slot=-1;
1051 //int iface;
1052 //int ip_slot;
1054 class_slot = (classId>>8)&0xffff;
1055 L4_handle=netcp_cfgp_get_l4_handle(
1056 &netapi_get_global()->nwal_context,
1057 class_slot );
1058 if(!L4_handle) {*err = NETAPI_ERR_BAD_INPUT; return ;}
1059 L3_handle = netcp_cfgp_get_l3_handle(
1060 &netapi_get_global()->nwal_context,
1061 class_slot );
1062 /* l3 handle might be NULL,, depending on type of classifier */
1064 netcp_cfgp_delete_class(
1065 &netapi_get_global()->nwal_context,
1066 class_slot );
1067 //get a transaction id
1068 pTransInfo = netapip_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
1069 if (!pTransInfo) { *err = NETAPI_ERR_BUSY; return ;}
1070 pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;
1071 pTransInfo->netapi_handle = h;
1072 //issue request for L4
1073 retValue = nwal_delConn(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
1074 trans_id,
1075 L4_handle);
1076 if(retValue != nwal_OK)
1077 {
1078 *err = NETAPI_ERR_NWAL_ERR0;
1079 printf (">netcp cfg - ERROR: nwal_delConn returned Error Code %d\n",
1080 retValue);
1081 pTransInfo->inUse = nwal_FALSE;
1082 return ; /* todo: what about the L3? */
1083 }
1084 //wait here until its done since scheduler isn't running yet most likely..
1085 // todo: make this handled by scheduler poll later ??
1086 if(trans_id != NWAL_TRANSID_SPIN_WAIT)
1087 {
1088 n->nwal_local.numPendingCfg++;
1089 while ((volatile) n->nwal_local.numPendingCfg)
1090 {
1091 // if response is there, then this poll squirts out in the CTl poll callback,
1092 // which handles the rest (including decrmenting #pending!!
1093 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
1094 }
1095 }
1096 printf (">netcp cfg: Classifer deleted\n");
1097 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;
1098 pTransInfo->inUse = nwal_FALSE;
1100 /* delete L3 if we have to */
1101 if (L3_handle)
1102 {
1103 netcp_cfgDelIpInternal( h, 0, 0,
1104 NULL, NULL, 0,
1105 err, L3_handle, 0);
1106 }
1107 return ;
1108 }
1111 /*--------------flow management--------*/
1112 // ADD A Flow
1113 NETCP_CFG_FLOW_HANDLE_T netcp_cfgAddFlow(NETAPI_T h,
1114 int n,
1115 Pktlib_HeapHandle handles[],
1116 int sizes[],
1117 int byte_offset,
1118 int * err )
1119 {
1120 Cppi_RxFlowCfg rxFlowCfg;
1121 Uint8 isAlloc;
1122 Qmss_QueueHnd rxBufQ[TUNE_NETAPI_MAX_BUF_POOLS_IN_FLOW];
1123 Uint32 rxBufSize[TUNE_NETAPI_MAX_BUF_POOLS_IN_FLOW];
1124 int i;
1125 Cppi_FlowHnd FlowHnd;
1126 int slot;
1127 NETCP_CFG_FLOW_HANDLE_T retVal;
1129 *err= 0; /* ok */
1130 //get a slot to save new flow
1131 slot = netcp_cfgp_find_flow_slot(&netapi_get_global()->nwal_context);
1132 if (slot<0) { *err= NETAPI_ERR_NOMEM; return NULL; }
1134 //configure flow
1135 memset(&rxFlowCfg,0,sizeof(Cppi_RxFlowCfg));
1136 for (i = 0; i < TUNE_NETAPI_MAX_BUF_POOLS_IN_FLOW; i++)
1137 {
1138 if (i >= n)
1139 {
1140 rxBufQ[i] = 0;
1141 rxBufSize[i] = 0;
1142 } else
1143 {
1144 rxBufQ[i] = Pktlib_getInternalHeapQueue(handles[i]);
1145 //todo: verity sizes< heapsize
1146 //todo: verify order
1147 rxBufSize[i]= sizes[i];
1148 }
1149 if (i && (rxBufQ[i] <= 0))
1150 {
1151 rxBufQ[i] = rxBufQ[i-1];
1152 rxBufSize[i] = 0;
1153 }
1154 }
1155 /* Configure Rx flow */
1156 rxFlowCfg.flowIdNum = CPPI_PARAM_NOT_SPECIFIED;
1157 rxFlowCfg.rx_dest_qnum = 100; //DANGEROUS> TODO PUT VALID Q HERE
1158 rxFlowCfg.rx_dest_qmgr = 0;
1159 rxFlowCfg.rx_sop_offset = byte_offset;
1160 rxFlowCfg.rx_ps_location = Cppi_PSLoc_PS_IN_DESC;
1161 rxFlowCfg.rx_desc_type = Cppi_DescType_HOST;
1162 rxFlowCfg.rx_error_handling = 0;
1164 rxFlowCfg.rx_psinfo_present = 1;
1165 rxFlowCfg.rx_einfo_present = 1;
1167 rxFlowCfg.rx_dest_tag_lo = 0;
1168 rxFlowCfg.rx_dest_tag_hi = 0;
1169 rxFlowCfg.rx_src_tag_lo = 0;
1170 rxFlowCfg.rx_src_tag_hi = 0;
1172 rxFlowCfg.rx_size_thresh0_en = rxBufSize[1] ? 1 : 0;
1173 rxFlowCfg.rx_size_thresh1_en = rxBufSize[2] ? 1 : 0;
1174 rxFlowCfg.rx_size_thresh2_en = rxBufSize[3] ? 1 : 0;
1176 rxFlowCfg.rx_dest_tag_lo_sel = 0;
1177 rxFlowCfg.rx_dest_tag_hi_sel = 0;
1178 rxFlowCfg.rx_src_tag_lo_sel = 0;
1179 rxFlowCfg.rx_src_tag_hi_sel = 0;
1181 rxFlowCfg.rx_fdq1_qnum = rxBufQ[1];
1182 rxFlowCfg.rx_fdq1_qmgr = 0;
1183 rxFlowCfg.rx_fdq2_qnum = rxBufQ[2];
1185 rxFlowCfg.rx_fdq2_qmgr = 0;
1186 rxFlowCfg.rx_fdq3_qnum = rxBufQ[3];
1188 rxFlowCfg.rx_fdq3_qmgr = 0;
1190 rxFlowCfg.rx_size_thresh0 = rxBufSize[1] ? rxBufSize[0] : 0;
1191 rxFlowCfg.rx_size_thresh1 = rxBufSize[2] ? rxBufSize[1] : 0;
1192 rxFlowCfg.rx_size_thresh2 = rxBufSize[3] ? rxBufSize[2] : 0;
1194 rxFlowCfg.rx_fdq0_sz0_qnum = rxBufQ[0];
1195 rxFlowCfg.rx_fdq0_sz0_qmgr = 0;
1196 rxFlowCfg.rx_fdq0_sz1_qnum = rxBufQ[1];
1197 rxFlowCfg.rx_fdq0_sz1_qmgr = 0;
1198 rxFlowCfg.rx_fdq0_sz2_qnum = rxBufQ[2];
1199 rxFlowCfg.rx_fdq0_sz2_qmgr = 0;
1200 rxFlowCfg.rx_fdq0_sz3_qnum = rxBufQ[3];
1201 rxFlowCfg.rx_fdq0_sz3_qmgr = 0;
1203 {
1204 //todo: replace this with a nwal call to get global cntx info
1205 Cppi_CpDmaInitCfg cpdmaCfg;
1206 memset(&cpdmaCfg,0,sizeof(Cppi_CpDmaInitCfg));
1207 cpdmaCfg.dmaNum = Cppi_CpDma_PASS_CPDMA;
1208 FlowHnd =
1209 Cppi_configureRxFlow (Cppi_open (&cpdmaCfg), &rxFlowCfg, &isAlloc);
1210 }
1211 if (FlowHnd == NULL)
1212 {
1213 *err= NETAPI_ERR_NORES;
1214 netcp_cfgp_delete_flow(&netapi_get_global()->nwal_context, slot);
1215 return (NULL);
1216 }
1218 //update slot
1219 retVal = netcp_cfgp_insert_flow(&netapi_get_global()->nwal_context, slot, (void*) FlowHnd);
1220 printf(">netcp cfg: flow %d created\n", ((NETCP_CFG_FLOW_T *) retVal)->flowid);
1221 return ( retVal);
1225 }
1227 //Delete a flow
1228 void netcp_cfgDelFlow(NETAPI_T h , NETCP_CFG_FLOW_HANDLE_T f , int * err)
1229 {
1230 int slot;
1231 void * handle;
1232 *err=0;
1233 /* find entry */
1234 slot = netcp_cfgp_find_flow(&netapi_get_global()->nwal_context, ((NETCP_CFG_FLOW_T *) f) ->flowid, &handle);
1235 if (slot<0) {*err = NETAPI_ERR_BAD_INPUT; return;}
1237 Cppi_closeRxFlow( (Cppi_FlowHnd) handle);
1238 netcp_cfgp_delete_flow(&netapi_get_global()->nwal_context, slot);
1239 printf(">netcp cfg: flow %d deleted\n", ((NETCP_CFG_FLOW_T *) f)->flowid);
1240 return;
1241 }
1244 /*************************************************************************/
1245 /*********************************INTERNAL*******************************/
1246 /************************************************************************/
1248 /***************************************************************
1249 ********************NETCP CMD Reply Callback******************
1250 ***************************************************************/
1251 void netapi_NWALCmdCallBack (nwal_AppId appHandle,
1252 uint16_t trans_id,
1253 nwal_RetValue ret)
1254 {
1255 NetapiNwalTransInfo_t * p_trans;
1256 NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL;
1258 if(trans_id == NWAL_TRANSID_SPIN_WAIT)
1259 {
1260 netapi_get_global()->nwal_context.numBogusTransIds++;
1261 return;
1262 }
1264 p_trans= &netapi_get_global()->nwal_context.transInfos[trans_id];
1265 p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;
1267 if(ret != nwal_OK)
1268 {
1269 printf (">netcp cfg : NWALCmdCallBack returned Error Code %d\n",
1270 ret);
1271 // update error code that is fialed in p_trans */
1272 //todo: atomic inc
1273 netapi_get_global()->nwal_context.numCmdFail++;
1274 }
1275 else
1276 {
1277 //todo: atomic inc
1278 netapi_get_global()->nwal_context.numCmdPass++;
1279 switch(p_trans->transType)
1280 {
1281 case NETAPI_NWAL_HANDLE_TRANS_MAC:
1282 {
1283 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
1284 {
1285 p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;
1286 }
1287 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
1288 {
1289 p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
1290 }
1291 break;
1292 }
1293 case NETAPI_NWAL_HANDLE_TRANS_IP:
1294 {
1295 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
1296 {
1297 p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;
1298 }
1299 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
1300 {
1301 p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
1302 }
1303 break;
1304 }
1305 case NETAPI_NWAL_HANDLE_TRANS_PORT:
1306 {
1307 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
1308 {
1309 p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;
1310 }
1311 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
1312 {
1313 p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
1314 }
1315 break;
1316 }
1317 case NETAPI_NWAL_HANDLE_TRANS_SA:
1318 {
1319 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
1320 {
1321 p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;
1322 }
1323 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
1324 {
1325 p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
1326 }
1327 break;
1328 }
1329 case NETAPI_NWAL_HANDLE_TRANS_SA_POLICY:
1330 {
1331 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
1332 {
1333 p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;
1334 }
1335 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
1336 {
1337 p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
1338 }
1339 break;
1340 }
1341 default:
1342 {
1343 printf ("netcp cfg> Invalid transaction type %d for trans_id: %d\n",
1344 p_trans->transType,trans_id);
1345 break;
1346 }
1347 }
1348 }
1350 p_local->numPendingCfg--;
1352 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_IDLE)
1353 {
1354 p_trans->inUse = nwal_FALSE;
1355 }
1357 }
1360 /*******************************************************/
1361 /**************stats reply callback**********************/
1362 /*******************************************************/
1363 void netapi_NWALCmdPaStatsReply (nwal_AppId appHandle,
1364 nwal_TransID_t trans_id,
1365 paSysStats_t *stats)
1366 {
1367 NetapiNwalTransInfo_t * p_trans;
1368 NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL;
1370 if(trans_id == NWAL_TRANSID_SPIN_WAIT)
1371 {
1372 netapi_get_global()->nwal_context.numBogusTransIds++;
1373 return;
1374 }
1376 p_trans= &netapi_get_global()->nwal_context.transInfos[trans_id];
1377 p_trans->inUse = nwal_FALSE;
1378 p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;
1380 //save a local copy of some stuff*/
1381 p_local->numL2PktsRecvd=stats->classify1.nPackets;
1382 p_local->numL3PktsRecvd=stats->classify1.nIpv4Packets;
1383 #if 0
1384 p_local->numL4PktsRecvd=stats->;
1385 p_local->numL4PktsSent=stats->;
1386 p_local->TxErrDrop=stats->;
1387 #endif
1388 //callout result to application !!
1389 if (p_local->stats_cb) (*p_local->stats_cb)(p_trans->netapi_handle,stats);
1391 }