1 /***********************************************************************
2 * FILE: netapi.c
3 * Purpose: Main initialization and shutdown routines of NETAPI
4 * user space transport library.
5 ***********************************************************************
6 * FILE: netapi.c
7 *
8 * DESCRIPTION: netapi main source file for user space transport
9 * library
10 *
11 * REVISION HISTORY:
12 *
13 * Copyright (c) Texas Instruments Incorporated 2013
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 *
19 * Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 *
22 * Redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the
25 * distribution.
26 *
27 * Neither the name of Texas Instruments Incorporated nor the names of
28 * its contributors may be used to endorse or promote products derived
29 * from this software without specific prior written permission.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
36 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
37 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
38 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
39 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
41 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43 * *****************************/
45 #include <unistd.h>
46 #include "netapi.h"
47 #include "netapi_loc.h"
49 static NETAPI_CFG_T netapi_default_cfg=
50 {
51 TUNE_NETAPI_PERM_MEM_SZ,
52 0, //start of packet offset for hw to place data on rx for default flow
53 TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM, //max number of descriptors in system
54 TUNE_NETAPI_NUM_GLOBAL_DESC, //total we will use
55 TUNE_NETAPI_DEFAULT_NUM_BUFFERS, //#descriptors+buffers in default heap
56 TUNE_NETAPI_DEFAULT_NUM_SOLO_DESCRIPTORS, //#descriptors w/o buffers in default heap
57 TUNE_NETAPI_DEFAULT_BUFFER_SIZE, //size of buffers in default heap
58 0,0
59 };
61 /* Global variablesto hold virtual address of various subsystems */
62 hplib_virtualAddrInfo_T netapi_VM_VirtAddr[HPLIB_MAX_MEM_POOLS];
64 /* Global variables which needs to be populated with memory pool attributes
65 which is passed to HPLIB for memory pool initialization*/
66 hplib_memPoolAttr_T netapi_VM_MempoolAttr[HPLIB_MAX_MEM_POOLS];
67 unsigned char *netapi_VM_QMemLocalDescRam;
68 unsigned char *netapi_VM_QMemGlobalDescRam;
69 unsigned char *netapi_VM_SaContextVaddr;
71 Pktlib_HeapIfTable netapi_pktlib_ifTable;
72 NETAPI_GLOBAL_T netapi_global;
73 NETAPI_GLOBAL_T * netapi_get_global(){ return &netapi_global;}
75 /* utility API for NETAPI user to get pktlib if table to use if he creates his own heap */
76 Pktlib_HeapIfTable *netapi_getPktlibIfTable(void) {return &netapi_pktlib_ifTable;}
79 /********************************************************************
80 * FUNCTION PURPOSE: API instantiates the NETAPI and allocated global resources.
81 ********************************************************************
82 * DESCRIPTION: API instantiates the NETAPI and allocated global resources.
83 ********************************************************************/
84 NETAPI_T netapi_init(int master, NETAPI_CFG_T * p_cfg)
85 {
86 int i;
87 int err;
88 int exception_id = 7;
89 NETAPI_HANDLE_T * p = (NETAPI_HANDLE_T *) calloc(1,sizeof(NETAPI_HANDLE_T));
90 NETAPI_HANDLE_T * p_master;
91 if (!p) return NULL;
92 p->master = master;
94 /* create space for our local pktios */
95 for(i=0;i<TUNE_NETAPI_MAX_PKTIO; i++)
96 {
97 p->pktios[i] = calloc(1,sizeof(PKTIO_HANDLE_T));
98 if (!p->pktios[i])
99 {
100 return NULL;
101 }
102 }
104 #ifdef NETAPI_INCLUDE_SCHED
105 /* create space for scheduler */
106 p->p_sched = calloc(1,sizeof(NETAPI_SCHED_HANDLE_T));
107 if (!p->p_sched)
108 {
109 goto ERR_netapi_init;
110 }
111 #endif
113 /* Global init for SYS_MATER */
114 if (master==NETAPI_SYS_MASTER)
115 {
116 if (p_cfg)
117 {
118 memcpy(&netapi_global.cfg,p_cfg, sizeof(NETAPI_CFG_T));
119 }
120 else
121 {
122 memcpy(&netapi_global.cfg,&netapi_default_cfg, sizeof(NETAPI_CFG_T));
123 }
124 for(i=0;i<TUNE_NETAPI_MAX_PKTIO;i++)
125 {
126 netapi_global.pktios[i].qn.qNum=-1;
127 netapi_global.pktios[i].name[0]='\0';
128 }
129 }
130 //this goes to shared memory eventually
131 p->global = (void *) &netapi_global;
133 //save master's handle back in global; else for slave retrieve p_master
134 if (master==NETAPI_SYS_MASTER)
135 {
136 netapi_global.p_master = p;
137 }
138 else
139 {
140 /* get system master reqquired for core and no master */
141 p_master=(NETAPI_HANDLE_T *)netapi_global.p_master;
142 }
144 /* system init */
145 if(master==NETAPI_SYS_MASTER)
146 {
147 err = netapip_systemInit(p);
148 netapi_netcpCfgExceptions(p, NETCP_CFG_ALL_EXCEPTIONS, NETCP_CFG_ACTION_TO_SW, (NETCP_CFG_ROUTE_HANDLE_T) NULL);
149 if (err<0)
150 {
151 goto ERR_netapi_init;
152 }
153 /* create pktio channels for tx,rx */
154 }
155 else if (master==NETAPI_NO_MASTER)
156 {
157 //dalmt ->simple trial. Just copy master's packetio list for now
158 p->n_pktios = p_master->n_pktios;
159 memcpy(&p->pktios[0],&p_master->pktios[0],TUNE_NETAPI_MAX_PKTIO*sizeof(PKTIO_HANDLE_T));
160 p->nwal_local=p_master->nwal_local;
161 }
162 /* this is the NETAPI_CORE_MASTER case */
163 else if (master==NETAPI_CORE_MASTER)
164 {
166 /* Start the QMSS. */
167 if (netapip_startQm() != 1)
168 {
169 goto ERR_netapi_init;
170 }
171 netapip_startNwal(p_master->netcp_heap,
172 p_master->netcp_control_rx_heap,
173 p_master->netcp_control_tx_heap,
174 &p->nwal_local,
175 &netapi_global.cfg,
176 &netapi_global.nwal_context);
177 }
178 else
179 {
180 netapi_Log("netapi_init: no master specified\n");
181 goto ERR_netapi_init;
182 }
184 return (NETAPI_T) p;
186 ERR_netapi_init:
187 for(i=0;i<TUNE_NETAPI_MAX_PKTIO; i++)
188 {
189 if (p->pktios[i])
190 {
191 free(p->pktios[i]);
192 }
193 }
194 #ifdef NETAPI_INCLUDE_SCHED
195 if (p->p_sched)
196 {
197 free(p->p_sched);
198 }
199 #endif
200 return NULL;
201 }
203 /********************************************************************
204 * FUNCTION PURPOSE: API de-allocates all global resources allocated as part
205 * of ref netapi_init
206 ********************************************************************
207 * DESCRIPTION: API de-allocates all global resources allocated as part
208 * of ref netapi_init
209 ********************************************************************/
210 void netapi_shutdown(NETAPI_T h)
211 {
212 int i;
213 NETAPI_HANDLE_T * p = (NETAPI_HANDLE_T *) h;
214 if (!p) return;
216 netapi_Log("netapi: WARNING shutdown may not be fully implemented\n");
217 if (p->master ==NETAPI_SYS_MASTER)
218 {
219 /* close nwal */
220 nwal_delete(netapi_global.nwal_context.nwalInstHandle);
222 /* close heaps */
223 netapi_closeHeap(h, p->netcp_heap);
224 netapi_closeHeap(h, p->netcp_control_rx_heap);
225 netapi_closeHeap(h, p->netcp_control_tx_heap);
226 netapi_closeHeap(h, netapi_get_global()->nwal_context.pa2sa_heap);
227 netapi_closeHeap(h, netapi_get_global()->nwal_context.sa2pa_heap);
229 //loop over registered heaps
230 for(i=0;i<TUNE_NETAPI_MAX_HEAPS;i++)
231 {
232 if (p->createdHeaps[i]) {netapi_closeHeap(h,p->createdHeaps[i]);p->createdHeaps[i]=NULL;}
233 }
234 netapip_cleanupAtStart(); //clear 1st 50 not-specified queues..
235 hplib_vmTeardown();
236 }
237 free(p);
238 return;
239 }
241 /***********************************************************************
242 * FUNCTION PURPOSE: API is used to poll for NETCP configuration response messages.
243 ************************************************************************
244 * DESCRIPTION: This API is used to poll the netapi internal heaps and any
245 * application-created heaps that have been registered with
246 * the netapi instance. The poll function checks the garbage collection
247 * queue associated with the heap and returns descriptors and buffers
248 * when appropriate to the main free queue.
249 ***********************************************************************/
250 void netapi_pollHeapGarbage(NETAPI_T h)
251 {
252 int i;
253 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
254 Pktlib_garbageCollection(n->netcp_heap);
255 //no need to do garbage collection on other internal heaps
256 for(i=0;i<TUNE_NETAPI_MAX_HEAPS;i++)
257 {
258 if (n->createdHeaps[i])
259 {
260 Pktlib_garbageCollection(n->createdHeaps[i]);
261 }
262 }
263 }
265 /****************************************************************************
266 * FUNCTION PURPOSE: API is used to poll for NETCP configuration response messages.
267 ****************************************************************************
268 * DESCRIPTION: This API is used to poll the netapi internal heaps and any
269 * application-created heaps that have been registered with the
270 * netapi instance. The poll function checks the garbage collection
271 * queue associated with the heap and returns descriptors and buffers
272 * when appropriate to the main free queue.
273 ***************************************************************************/
274 void netapi_netcpPoll(NETAPI_T p)
275 {
276 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) p;
277 nwal_pollCtl( ((NETAPI_GLOBAL_T *) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
278 }