This is the initial commit.
[keystone-rtos/netapi.git] / ti / runtime / netapi / src / netcp_cfg.c
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  ******************************************************/
44 #include "netapi.h"
45 #include "netcp_cfg.h"
46 #include "netapi_loc.h"
48 /******************************************************************
49  ********************Utility*************************************
50 *******************************************************************/
53 //get a free transaction id
54 static NetapiNwalTransInfo_t *  netapi_GetFreeTransInfo(NETAPI_GLOBAL_T *p_global, nwal_TransID_t *pTransId)
55 {
56          uint16_t    count=0;
58         count=0;
59         while(count < TUNE_NETAPI_MAX_NUM_TRANS)
60         {
61             if((p_global->nwal_context.transInfos[count].inUse) != nwal_TRUE)
62             {
63                 p_global->nwal_context.transInfos[count].inUse = nwal_TRUE;
64                 *pTransId = count;
65                 return(&p_global->nwal_context.transInfos[count]);
66             }
67             count++;
68         }
69          
70         /* trouble.  need to wait for one to free up*/
71         /* to do: handle this by forcing a poll of cntrl queue*/
72         printf("netapi>> trying to get free transaction slot but all full!!\n");
73         return NULL;
75 }
76 //internal:  insert an IP address into iface
77 void netcp_cfgp_insert_ip(NETAPI_NWAL_GLOBAL_CONTEXT_T *p, 
78                           nwal_IpType ipType,
79                           nwalIpAddr_t *ip_addr, 
80                           nwalIpOpt_t *ip_qualifiers, 
81                           int iface_no,
82                           void * handle)
83 {
84 int i;
85 for(i=0;i<TUNE_NETAPI_MAX_IP_PER_INTERFACE;i++)
86 {
87    if (!p->interfaces[iface_no].ips[i].in_use)
88    {
89         p->interfaces[iface_no].ips[i].in_use=1;
90         memcpy(&p->interfaces[iface_no].ips[i].ip_addr, ip_addr, sizeof(nwalIpAddr_t));
91         if(ip_qualifiers)
92         memcpy(&p->interfaces[iface_no].ips[i].ip_qualifiers, ip_qualifiers, sizeof(nwalIpOpt_t));
93         else
94         memset(&p->interfaces[iface_no].ips[i].ip_qualifiers, 0, sizeof(nwalIpOpt_t));
95         p->interfaces[iface_no].ips[i].ip_type = ipType;
96         p->interfaces[iface_no].ips[i].nwal_handle = handle;
97         return;
98    }
99 }
100 printf("netcp_cfg> add ip:  no room in table\n");
105 //internal: instert interface info into global context
106 void netcp_cfgp_insert_mac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p, unsigned char * p_mac, 
107                            int iface_no, int state, NETCP_CFG_VLAN_T vlan, void * handle)
109    if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_INTERFACES))
110    {
111         memset(&p->interfaces[iface_no],0,sizeof(NETCP_INTERFACE_T));
112         p->interfaces[iface_no].in_use = 1;
113         memcpy(&p->interfaces[iface_no].mac[0], p_mac,6);
114         p->interfaces[iface_no].state = state;
115         //todo p->interfaces[iface_no].vlan = vlan;
116         p->interfaces[iface_no].nwal_handle = handle; //save handle assoicated with this rule
117    }
118    else printf("netcp_cfg> insert interface # out of range %d\n",iface_no);
121 //internal: clear inteface entry
122 void netcp_cfgp_delete_mac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,int iface_no)  
124    if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_INTERFACES))
125    {
126         p->interfaces[iface_no].in_use = 0;
127    }
128    else printf("netcp_cfg> delete interface # out of range %d\n",iface_no);
133 //internal:
135 /***********************************************************************************/
136 /****************************************API****************************************/
137 /***********************************************************************************/
140 /*****************************************************************
141  *  Queury Stats
142  ****************************************************************/
143 void netcp_cfgReqStats(NETAPI_T  h, NETCP_CFG_STATS_CB cb, int doClear, int *err) 
145 nwal_RetValue ret;
146 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
147 NetapiNwalTransInfo_t *pTransInfo;
148 nwal_TransID_t     transId;
149 if ((!n) || (!cb)) {*err = NETAPI_ERR_BAD_INPUT; return ;}
150 *err =0;
152 pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &transId);
153 if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return ;}
154 pTransInfo->transType = NETAPI_NWAL_HANDLE_STAT_REQUEST;
155 pTransInfo->netapi_handle = h;
156 n->nwal_local.stats_cb = cb;
157 ret = nwal_getPAStats( ((NETAPI_GLOBAL_T *) n->global)->nwal_context.nwalInstHandle,
158                           transId,
159                           NULL,
160                           doClear);
161 if(ret !=  nwal_OK)
163    pTransInfo->inUse = nwal_FALSE;
164    *err = NETAPI_ERR_BUSY;  //no resources??
165    printf("reqStats-> failed, err=%d\n",ret);
169 /*****************************************************************
170  *  CREATE A MAC INTERFACE
171  ****************************************************************/
172 NETCP_CFG_MACIF_T  netcp_cfgCreateMacInterface(
173                   NETAPI_T  h,
174                   uint8_t *p_mac,
175                   int  iface_no, 
176                   int switch_port, 
177                   NETCP_CFG_ROUTE_HANDLE_T  route,
178                   NETCP_CFG_VLAN_T  vlan,  //future
179                   int state,  //0=down, 1=up  //ignored
180                   int * err
181                   )
183 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
184 nwalMacParam_t   MacInfo= {
185     0,      /* validParams */
186     0,      /* ifNum */
187     0,      /* vlanId      */
188     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },      /* Local mac */
189     NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */
190     NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */
191     CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */
192     QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */
193 };
195 nwal_RetValue       retValue;
196 NetapiNwalTransInfo_t *pTransInfo;
197 nwal_TransID_t     trans_id;
199     if ((!n) || (!p_mac)) {*err = NETAPI_ERR_BAD_INPUT; return NULL;}
200     *err =0;
202     pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
203     if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return NULL;}
204     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC;
205     pTransInfo->netapi_handle = h; 
207     /* set up MacInfo */
208     memcpy(&MacInfo.macAddr,p_mac,6); 
209     /* todo: vlan */
210     MacInfo.ifNum = switch_port;  /* todo: check for 0/1 relative*/
212 #if 0  //todo
213     if (route != NULL)
214     {
215         MacInfo.appRxPktFlowId = ((NETCP_CFG_FLOW_T *)(route.flow))->flowid;
216         MacInfo.appRxPktQueue = PKTIO_GET_Q(route->p_dest_q);
217         //handle action ??
218     }
219 #endif
220     pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
221     retValue = nwal_setMacIface( ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
222                                   trans_id,
223                                   (nwal_AppId) (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no),
224                                   &MacInfo,
225                                   &pTransInfo->handle);
226     if(retValue !=  nwal_OK)
227     {
228         *err = NETAPI_ERR_NWAL_ERR0;
229         printf ("ERROR: nwal_setMacIface returned Error Code %d\n",
230                     retValue);
231         pTransInfo->inUse = nwal_FALSE;
232         return NULL;
233     }
234     //pTransInfo->inUse = nwal_FALSE;
235     printf ("MAC Open sent with  trans_id: %d\n",trans_id);
237     //wait here until its done since scheduler isn't running yet most likely..
238     // todo:  make this handled by scheduler poll later ??
239     if(trans_id != NWAL_TRANSID_SPIN_WAIT)
240     {
241         n->nwal_local.numPendingCfg++;
242         while ((volatile) n->nwal_local.numPendingCfg)
243         {
244             // if response is there, then this poll squirts out in the CTl poll callback, 
245             // which handles the rest (including decrmenting #pending!!
246             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
247         }
248     }
249     printf ("MAC i/f added\n");
250     netcp_cfgp_insert_mac(&netapi_get_global()->nwal_context, 
251                           p_mac, iface_no, state,vlan,
252                           (void *) pTransInfo->handle);
253     pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;
254     pTransInfo->inUse = nwal_FALSE;
255     return NULL;
259 /*****************************************************************/
260 /***************Delete a mac interface****************************/
261 /*****************************************************************/
262 void netcp_cfgDelMac(NETAPI_T h,int iface_no,  int *err)
265     *err =0;
267     netcp_cfgp_delete_mac(&netapi_get_global()->nwal_context,  iface_no);
268     printf("netcp_cfg>  del mac not fully implemented \n");
269     return;
273 /*****************************************************************/
274 /***************Add IP to MAC interface****************************/
275 /*****************************************************************/
276 NETCP_CFG_IP_T  netcp_addIp(
277                   NETAPI_T  h,
278                   int  iface_no,
279                   nwal_IpType ipType,
280                   nwalIpAddr_t  * ip_addr,
281                   nwalIpOpt_t * ip_qualifiers,
282                   NETCP_CFG_ROUTE_HANDLE_T  route,  //NULL for default
283                   int * err
284                   )
286 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
287 void * n_handle;
288 nwalIpParam_t    nwalIpParam= {
289     pa_IPV4,      /* IP Type */
290     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Dest IP */
291     { 0x0,0,0,0},/* IP Options */
292     NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */
293     NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */
294     CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */
295     QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */
296 };
297 nwal_RetValue       retValue;
298 NetapiNwalTransInfo_t *pTransInfo;
299 nwal_TransID_t     trans_id;
302      //verify that iface has been configurred 
303      if ((iface_no<0) || (iface_no>= TUNE_NETAPI_MAX_INTERFACES)) {*err = NETAPI_ERR_BAD_INPUT; return NULL;}
305      if(netapi_get_global()->nwal_context.interfaces[iface_no].in_use)
306      {
307         n_handle =  netapi_get_global()->nwal_context.interfaces[iface_no].nwal_handle;
308      }
309      else
310      {
311         *err = NETAPI_ERR_BAD_INPUT;
312         return NULL;
313      }
315      //get a transaction object for config action
316     pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
317     if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return NULL;}
318     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;
319     pTransInfo->netapi_handle = h;
321      //build nwalIpParam
322      memcpy(&nwalIpParam.locIpAddr,ip_addr, sizeof(nwalIpAddr_t));
323      nwalIpParam.ipType=ipType;
324      if(route)
325      {
326           //todo: support app defined routes
327      } 
328      else{} //use nwal defaults
329      if (ip_qualifiers)
330         memcpy(&nwalIpParam.ipOpt,ip_qualifiers, sizeof(nwalIpOpt_t)); 
331      else
332         memset(&nwalIpParam.ipOpt,0, sizeof(nwalIpOpt_t));
334      //perform config action
335      pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
336      retValue = nwal_setIPAddr(   netapi_get_global()->nwal_context.nwalInstHandle,
337                                   trans_id,
338                                   (nwal_AppId) (NETAPI_NETCP_MATCH_GENERIC_IP | iface_no),
339                                   n_handle,
340                                   &nwalIpParam,
341                                   &pTransInfo->handle);
343     if(retValue !=  nwal_OK)
344     {
345         *err = NETAPI_ERR_NWAL_ERR0;
346         printf ("ERROR: nwal_setMacIface returned Error Code %d\n",
347                     retValue);
348         pTransInfo->inUse = nwal_FALSE;
349         return NULL;
350     }
351     //pTransInfo->inUse = nwal_FALSE;
352     printf ("MAC Open sent with  trans_id: %d\n",trans_id);
354     //wait here until its done since scheduler isn't running yet most likely..
355     // todo:  make this handled by scheduler poll later ??
356     if(trans_id != NWAL_TRANSID_SPIN_WAIT)
357     {
358         n->nwal_local.numPendingCfg++;
359         while ((volatile) n->nwal_local.numPendingCfg)
360         {
361             // if response is there, then this poll squirts out in the CTl poll callback, 
362             // which handles the rest (including decrmenting #pending!!
363             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
364         }
365     }
366     printf ("IP added\n");
367     netcp_cfgp_insert_ip(&netapi_get_global()->nwal_context, ipType, 
368                           ip_addr, ip_qualifiers, iface_no, 
369                           pTransInfo->handle);
370     pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;
371     pTransInfo->inUse = nwal_FALSE;
372     return NULL;
378 /*************************************************************************/
379 /*********************************INTERNAL*******************************/
380 /************************************************************************/
382 /***************************************************************
383  ********************METCP CMD Reply Callback******************
384  ***************************************************************/
385 void netapi_NWALCmdCallBack (nwal_AppId        appHandle,
386                           uint16_t            trans_id,
387                           nwal_RetValue     ret)
389     NetapiNwalTransInfo_t * p_trans;
390     NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL;
392     if(trans_id == NWAL_TRANSID_SPIN_WAIT)
393     {
394         printf("ERROR:  callback found SPIN_WAIT transaction id. SO CANT FIND OUT WHO WE ARE]n");
395         netapi_get_global()->nwal_context.numBogusTransIds++;
396         return;
397     }
399     p_trans= &netapi_get_global()->nwal_context.transInfos[trans_id];
400     p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;
402     if(ret != nwal_OK)
403     {
404         printf ("ERROR: NWALCmdCallBack returned Error Code %d\n",
405                     ret);
406         //todo: atomic inc
407         netapi_get_global()->nwal_context.numCmdFail++;
408     }
409     else
410     {
411         //todo: atomic inc
412         netapi_get_global()->nwal_context.numCmdPass++;
413         switch(p_trans->transType)
414         {
415             case NETAPI_NWAL_HANDLE_TRANS_MAC:
416             {
417                 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
418                 {
419                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;
420                 }
421                 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
422                 {
423                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
424                 }
425                 break;
426             }
427             case NETAPI_NWAL_HANDLE_TRANS_IP:
428             {
429                  if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
430                 {
431                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;
432                 }
433                 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
434                 {
435                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
436                 }
437                 break;
438             }
439 #if 0
440             case TEST_NWAL_HANDLE_TRANS_PORT:
441             {
442                 if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING)
443                 {
444                     testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN;
445                 }
446                 else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING)
447                 {
448                     testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE;
449                 }
450                 break;
451             }
452             case TEST_NWAL_HANDLE_TRANS_SEC_ASSOC:
453             {
454                 if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING)
455                 {
456                     testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN;
457                 }
458                 else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING)
459                 {
460                     System_printf ("Set Security Assoc  Close ACK received for trans_id: %d\n",
461                                 testNwLocContext.transInfos[trans_id].transType,trans_id);
462                     nwal_SystemFlush();
463                     testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE;
464                 }
465                 break;
466             }
467 case TEST_NWAL_HANDLE_TRANS_SEC_POLICY:
468             {
469                 if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING)
470                 {
471                     testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN;
472                 }
473                 else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING)
474                 {
475                     System_printf ("Set Security Policy  Close ACK received for trans_id: %d\n",
476                                 testNwLocContext.transInfos[trans_id].transType,trans_id);
477                     nwal_SystemFlush();
478                     testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE;
479                 }
480                 break;
481             }
482 #endif
483             default:
484             {
485                 printf ("ERROR: Invalid transaction type %d for trans_id: %d\n",
486                     p_trans->transType,trans_id);
487                 break;
488             }
489         }
490     }
492     p_local->numPendingCfg--;
494     if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_IDLE)
495     {
496         p_trans->inUse = nwal_FALSE;
497     }
502 /*******************************************************/
503 /**************stats reply callback**********************/
504 /*******************************************************/
505 void netapi_NWALCmdPaStatsReply (nwal_AppId        appHandle,
506                               nwal_TransID_t    trans_id,
507                               paSysStats_t      *stats)
509     NetapiNwalTransInfo_t * p_trans;
510     NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL;
511   
512     printf("stats reply for transid %d\n", trans_id);
513     if(trans_id == NWAL_TRANSID_SPIN_WAIT)
514     {
515         printf("ERROR:  callback found SPIN_WAIT transaction id. SO CANT FIND OUT WHO WE ARE]n");
516         netapi_get_global()->nwal_context.numBogusTransIds++;
517         return;
518     }
520     p_trans= &netapi_get_global()->nwal_context.transInfos[trans_id];
521     p_trans->inUse = nwal_FALSE;
522     p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;
524     //save a local copy  of some stuff*/
525     p_local->numL2PktsRecvd=stats->classify1.nPackets;
526     p_local->numL3PktsRecvd=stats->classify1.nIpv4Packets;
527 #if 0
528     p_local->numL4PktsRecvd=stats->;
529     p_local->numL4PktsSent=stats->;
530     p_local->TxErrDrop=stats->;
531 #endif
532     //callout result to application !!
533     if (p_local->stats_cb) (*p_local->stats_cb)(p_trans->netapi_handle,stats);
534     
535