added docs dir
[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  ******************************************************/
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 static NetapiNwalTransInfo_t *  netapi_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         }
72          
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:  insert an IP address into iface
80 void netcp_cfgp_insert_ip(NETAPI_NWAL_GLOBAL_CONTEXT_T *p, 
81                           nwal_IpType ipType,
82                           nwalIpAddr_t *ip_addr, 
83                           nwalIpOpt_t *ip_qualifiers, 
84                           int iface_no,
85                           void * handle)
86 {
87 int i;
88 for(i=0;i<TUNE_NETAPI_MAX_IP_PER_INTERFACE;i++)
89 {
90    if (!p->interfaces[iface_no].ips[i].in_use)
91    {
92         p->interfaces[iface_no].ips[i].in_use=1;
93         memcpy(&p->interfaces[iface_no].ips[i].ip_addr, ip_addr, sizeof(nwalIpAddr_t));
94         if(ip_qualifiers)
95         memcpy(&p->interfaces[iface_no].ips[i].ip_qualifiers, ip_qualifiers, sizeof(nwalIpOpt_t));
96         else
97         memset(&p->interfaces[iface_no].ips[i].ip_qualifiers, 0, sizeof(nwalIpOpt_t));
98         p->interfaces[iface_no].ips[i].ip_type = ipType;
99         p->interfaces[iface_no].ips[i].nwal_handle = handle;
100         return;
101    }
103 printf(">netcp_cfg - add ip:  no room in table\n");
108 //internal: instert interface info into global context
109 void netcp_cfgp_insert_mac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p, unsigned char * p_mac, 
110                            int iface_no, int state, NETCP_CFG_VLAN_T vlan, void * handle)
112    if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_INTERFACES))
113    {
114         memset(&p->interfaces[iface_no],0,sizeof(NETCP_INTERFACE_T));
115         p->interfaces[iface_no].in_use = 1;
116         memcpy(&p->interfaces[iface_no].mac[0], p_mac,6);
117         p->interfaces[iface_no].state = state;
118         //todo p->interfaces[iface_no].vlan = vlan;
119         p->interfaces[iface_no].nwal_handle = handle; //save handle assoicated with this rule
120    }
121    else printf(">netcp_cfg insert interface # out of range %d\n",iface_no);
124 //internal: clear inteface entry
125 void netcp_cfgp_delete_mac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,int iface_no)  
127    if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_INTERFACES))
128    {
129         p->interfaces[iface_no].in_use = 0;
130    }
131    else printf(">netcp_cfg delete interface # out of range %d\n",iface_no);
136 //internal:
138 /***********************************************************************************/
139 /****************************************API****************************************/
140 /***********************************************************************************/
143 /*****************************************************************
144  *  Queury Stats
145  ****************************************************************/
146 void netcp_cfgReqStats(NETAPI_T  h, NETCP_CFG_STATS_CB cb, int doClear, int *err) 
148 nwal_RetValue ret;
149 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
150 NetapiNwalTransInfo_t *pTransInfo;
151 nwal_TransID_t     transId;
152 if ((!n) || (!cb)) {*err = NETAPI_ERR_BAD_INPUT; return ;}
153 *err =0;
155 pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &transId);
156 if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return ;}
157 pTransInfo->transType = NETAPI_NWAL_HANDLE_STAT_REQUEST;
158 pTransInfo->netapi_handle = h;
159 n->nwal_local.stats_cb = cb;
160 ret = nwal_getPAStats( ((NETAPI_GLOBAL_T *) n->global)->nwal_context.nwalInstHandle,
161                           transId,
162                           NULL,
163                           doClear);
164 if(ret !=  nwal_OK)
166    pTransInfo->inUse = nwal_FALSE;
167    *err = NETAPI_ERR_BUSY;  //no resources??
168    printf("> netcp_cfg reqStats failed, err=%d\n",ret);
172 /*****************************************************************
173  *  CREATE A MAC INTERFACE
174  ****************************************************************/
175 NETCP_CFG_MACIF_T  netcp_cfgCreateMacInterface(
176                   NETAPI_T  h,
177                   uint8_t *p_mac,
178                   int  iface_no, 
179                   int switch_port, 
180                   NETCP_CFG_ROUTE_HANDLE_T  route,
181                   NETCP_CFG_VLAN_T  vlan,  //future
182                   int state,  //0=down, 1=up  //ignored
183                   int * err
184                   )
186 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
187 nwalMacParam_t   MacInfo= {
188     0,      /* validParams */
189     0,      /* ifNum */
190     0,      /* vlanId      */
191     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },      /* Local mac */
192     NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */
193     NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */
194     CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */
195     QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */
196 };
198 nwal_RetValue       retValue;
199 NetapiNwalTransInfo_t *pTransInfo;
200 nwal_TransID_t     trans_id;
202     if ((!n) || (!p_mac)) {*err = NETAPI_ERR_BAD_INPUT; return -1;}
203     *err =0;
205     pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
206     if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return -1;}
207     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC;
208     pTransInfo->netapi_handle = h; 
210     /* set up MacInfo */
211     memcpy(&MacInfo.macAddr,p_mac,6); 
212     /* todo: vlan */
213     MacInfo.ifNum = switch_port;  /* todo: check for 0/1 relative*/
215 #if 0  //todo
216     if (route != NULL)
217     {
218         MacInfo.appRxPktFlowId = ((NETCP_CFG_FLOW_T *)(route.flow))->flowid;
219         MacInfo.appRxPktQueue = PKTIO_GET_Q(route->p_dest_q);
220         //handle action ??
221     }
222 #endif
223     pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
224     retValue = nwal_setMacIface( ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
225                                   trans_id,
226                                   (nwal_AppId) (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no),
227                                   &MacInfo,
228                                   &pTransInfo->handle);
229     if(retValue !=  nwal_OK)
230     {
231         *err = NETAPI_ERR_NWAL_ERR0;
232         printf (">netcp cfg - ERROR: nwal_setMacIface returned Error Code %d\n",
233                     retValue);
234         pTransInfo->inUse = nwal_FALSE;
235         return -1;
236     }
237     //pTransInfo->inUse = nwal_FALSE;
239     //wait here until its done since scheduler isn't running yet most likely..
240     // todo:  make this handled by scheduler poll later ??
241     if(trans_id != NWAL_TRANSID_SPIN_WAIT)
242     {
243         n->nwal_local.numPendingCfg++;
244         while ((volatile) n->nwal_local.numPendingCfg)
245         {
246             // if response is there, then this poll squirts out in the CTl poll callback, 
247             // which handles the rest (including decrmenting #pending!!
248             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
249         }
250     }
251     printf (">netcp cfg: MAC i/f added\n");
252     netcp_cfgp_insert_mac(&netapi_get_global()->nwal_context, 
253                           p_mac, iface_no, state,vlan,
254                           (void *) pTransInfo->handle);
255     pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;
256     pTransInfo->inUse = nwal_FALSE;
257     return  (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no);
261 /*****************************************************************/
262 /***************Delete a mac interface****************************/
263 /*****************************************************************/
264 void netcp_cfgDelMac(NETAPI_T h,int iface_no,  int *err)
267     *err =0;
269     netcp_cfgp_delete_mac(&netapi_get_global()->nwal_context,  iface_no);
270     printf(">netcp_cfg:  del mac not fully implemented \n");
271     return;
275 /*****************************************************************/
276 /***************Add IP to MAC interface****************************/
277 /*****************************************************************/
278 NETCP_CFG_IP_T  netcp_addIp(
279                   NETAPI_T  h,
280                   int  iface_no,
281                   nwal_IpType ipType,
282                   nwalIpAddr_t  * ip_addr,
283                   nwalIpOpt_t * ip_qualifiers,
284                   NETCP_CFG_ROUTE_HANDLE_T  route,  //NULL for default
285                   int * err
286                   )
288 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
289 void * n_handle;
290 nwalIpParam_t    nwalIpParam= {
291     pa_IPV4,      /* IP Type */
292     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Dest IP */
293     { 0x0,0,0,0},/* IP Options */
294     NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */
295     NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */
296     CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */
297     QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */
298 };
299 nwal_RetValue       retValue;
300 NetapiNwalTransInfo_t *pTransInfo;
301 nwal_TransID_t     trans_id;
304      //verify that iface has been configurred 
305      if ((iface_no<0) || (iface_no>= TUNE_NETAPI_MAX_INTERFACES)) {*err = NETAPI_ERR_BAD_INPUT; return -1;}
307      if(netapi_get_global()->nwal_context.interfaces[iface_no].in_use)
308      {
309         n_handle =  netapi_get_global()->nwal_context.interfaces[iface_no].nwal_handle;
310      }
311      else
312      {
313         *err = NETAPI_ERR_BAD_INPUT;
314         return -1;
315      }
317      //get a transaction object for config action
318     pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
319     if (!pTransInfo) { *err =  NETAPI_ERR_BUSY; return -1;}
320     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;
321     pTransInfo->netapi_handle = h;
323      //build nwalIpParam
324      memcpy(&nwalIpParam.locIpAddr,ip_addr, sizeof(nwalIpAddr_t));
325      nwalIpParam.ipType=ipType;
326      if(route)
327      {
328           //todo: support app defined routes
329      } 
330      else{} //use nwal defaults
331      if (ip_qualifiers)
332         memcpy(&nwalIpParam.ipOpt,ip_qualifiers, sizeof(nwalIpOpt_t)); 
333      else
334         memset(&nwalIpParam.ipOpt,0, sizeof(nwalIpOpt_t));
336      //perform config action
337      pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
338      retValue = nwal_setIPAddr(   netapi_get_global()->nwal_context.nwalInstHandle,
339                                   trans_id,
340                                   (nwal_AppId) (NETAPI_NETCP_MATCH_GENERIC_IP | iface_no),
341                                   n_handle,
342                                   &nwalIpParam,
343                                   &pTransInfo->handle);
345     if(retValue !=  nwal_OK)
346     {
347         *err = NETAPI_ERR_NWAL_ERR0;
348         printf (">netcp cfg: nwal_setIP returned Error Code %d\n",
349                     retValue);
350         pTransInfo->inUse = nwal_FALSE;
351         return -1;
352     }
353     //wait here until its done since scheduler isn't running yet most likely..
354     // todo:  make this handled by scheduler poll later ??
355     if(trans_id != NWAL_TRANSID_SPIN_WAIT)
356     {
357         n->nwal_local.numPendingCfg++;
358         while ((volatile) n->nwal_local.numPendingCfg)
359         {
360             // if response is there, then this poll squirts out in the CTl poll callback, 
361             // which handles the rest (including decrmenting #pending!!
362             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
363         }
364     }
365     printf (">netcp cfg: IP added\n");
366     netcp_cfgp_insert_ip(&netapi_get_global()->nwal_context, ipType, 
367                           ip_addr, ip_qualifiers, iface_no, 
368                           pTransInfo->handle);
369     pTransInfo->state =  NETAPI_NWAL_HANDLE_STATE_IDLE;
370     pTransInfo->inUse = nwal_FALSE;
371     return  (NETAPI_NETCP_MATCH_GENERIC_IP | iface_no);
376 /*************************************************************************/
377 /*********************************INTERNAL*******************************/
378 /************************************************************************/
380 /***************************************************************
381  ********************METCP CMD Reply Callback******************
382  ***************************************************************/
383 void netapi_NWALCmdCallBack (nwal_AppId        appHandle,
384                           uint16_t            trans_id,
385                           nwal_RetValue     ret)
387     NetapiNwalTransInfo_t * p_trans;
388     NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL;
390     if(trans_id == NWAL_TRANSID_SPIN_WAIT)
391     {
392         netapi_get_global()->nwal_context.numBogusTransIds++;
393         return;
394     }
396     p_trans= &netapi_get_global()->nwal_context.transInfos[trans_id];
397     p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;
399     if(ret != nwal_OK)
400     {
401         printf (">netcp cfg : NWALCmdCallBack returned Error Code %d\n",
402                     ret);
403         //todo: atomic inc
404         netapi_get_global()->nwal_context.numCmdFail++;
405     }
406     else
407     {
408         //todo: atomic inc
409         netapi_get_global()->nwal_context.numCmdPass++;
410         switch(p_trans->transType)
411         {
412             case NETAPI_NWAL_HANDLE_TRANS_MAC:
413             {
414                 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
415                 {
416                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;
417                 }
418                 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
419                 {
420                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
421                 }
422                 break;
423             }
424             case NETAPI_NWAL_HANDLE_TRANS_IP:
425             {
426                  if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)
427                 {
428                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;
429                 }
430                 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)
431                 {
432                     p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;
433                 }
434                 break;
435             }
436 #if 0
437             case TEST_NWAL_HANDLE_TRANS_PORT:
438             {
439                 if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING)
440                 {
441                     testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN;
442                 }
443                 else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING)
444                 {
445                     testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE;
446                 }
447                 break;
448             }
449             case TEST_NWAL_HANDLE_TRANS_SEC_ASSOC:
450             {
451                 if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING)
452                 {
453                     testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN;
454                 }
455                 else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING)
456                 {
457                     System_printf ("Set Security Assoc  Close ACK received for trans_id: %d\n",
458                                 testNwLocContext.transInfos[trans_id].transType,trans_id);
459                     nwal_SystemFlush();
460                     testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE;
461                 }
462                 break;
463             }
464 case TEST_NWAL_HANDLE_TRANS_SEC_POLICY:
465             {
466                 if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING)
467                 {
468                     testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN;
469                 }
470                 else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING)
471                 {
472                     System_printf ("Set Security Policy  Close ACK received for trans_id: %d\n",
473                                 testNwLocContext.transInfos[trans_id].transType,trans_id);
474                     nwal_SystemFlush();
475                     testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE;
476                 }
477                 break;
478             }
479 #endif
480             default:
481             {
482                 printf ("netcp cfg> Invalid transaction type %d for trans_id: %d\n",
483                     p_trans->transType,trans_id);
484                 break;
485             }
486         }
487     }
489     p_local->numPendingCfg--;
491     if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_IDLE)
492     {
493         p_trans->inUse = nwal_FALSE;
494     }
499 /*******************************************************/
500 /**************stats reply callback**********************/
501 /*******************************************************/
502 void netapi_NWALCmdPaStatsReply (nwal_AppId        appHandle,
503                               nwal_TransID_t    trans_id,
504                               paSysStats_t      *stats)
506     NetapiNwalTransInfo_t * p_trans;
507     NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL;
508   
509     if(trans_id == NWAL_TRANSID_SPIN_WAIT)
510     {
511         netapi_get_global()->nwal_context.numBogusTransIds++;
512         return;
513     }
515     p_trans= &netapi_get_global()->nwal_context.transInfos[trans_id];
516     p_trans->inUse = nwal_FALSE;
517     p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;
519     //save a local copy  of some stuff*/
520     p_local->numL2PktsRecvd=stats->classify1.nPackets;
521     p_local->numL3PktsRecvd=stats->classify1.nIpv4Packets;
522 #if 0
523     p_local->numL4PktsRecvd=stats->;
524     p_local->numL4PktsSent=stats->;
525     p_local->TxErrDrop=stats->;
526 #endif
527     //callout result to application !!
528     if (p_local->stats_cb) (*p_local->stats_cb)(p_trans->netapi_handle,stats);
529     
530