1 /****************************************************************************
2 **+-----------------------------------------------------------------------+**
3 **| |**
4 **| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved. |**
5 **| All rights reserved. |**
6 **| |**
7 **| Redistribution and use in source and binary forms, with or without |**
8 **| modification, are permitted provided that the following conditions |**
9 **| are met: |**
10 **| |**
11 **| * Redistributions of source code must retain the above copyright |**
12 **| notice, this list of conditions and the following disclaimer. |**
13 **| * Redistributions in binary form must reproduce the above copyright |**
14 **| notice, this list of conditions and the following disclaimer in |**
15 **| the documentation and/or other materials provided with the |**
16 **| distribution. |**
17 **| * Neither the name Texas Instruments nor the names of its |**
18 **| contributors may be used to endorse or promote products derived |**
19 **| from this software without specific prior written permission. |**
20 **| |**
21 **| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |**
22 **| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |**
23 **| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
24 **| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |**
25 **| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
26 **| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |**
27 **| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
28 **| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
29 **| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |**
30 **| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
31 **| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |**
32 **| |**
33 **+-----------------------------------------------------------------------+**
34 ****************************************************************************/
35
36
37 #include "commonTypes.h"
38 #include "memMngrEx.h" /* MSDU */
39 #include "report.h"
40
41 #include "TNETWArb_buffer.h"
42 #include "TNETWArb.h"
43 #include "TNETWIF.h"
44
45
46 /* Each module has its own buffer in the TNETW Arbiter synchronizer */
47
48 /*******************************************************************************
49 **
50 ** Function TNETWArb_init_q
51 **
52 ** Description Called by an application to initialize a buffer queue.
53 **
54 ** Returns void
55 **
56 *******************************************************************************/
TNETWArb_init_q(BUFFER_Q * p_q)57 void TNETWArb_init_q (BUFFER_Q *p_q)
58 {
59 p_q->p_first = p_q->p_last = NULL;
60 p_q->count = 0;
61 }
62
63
64
65 /*******************************************************************************
66 **
67 ** Function TNETWArb_getfirst
68 **
69 ** Description Return a pointer to the first buffer in a queue
70 **
71 ** Returns NULL if queue is empty, else buffer address
72 **
73 *******************************************************************************/
TNETWArb_getfirst(BUFFER_Q * p_q)74 void *TNETWArb_getfirst (BUFFER_Q *p_q)
75 {
76 return (p_q->p_first);
77 }
78
79 /*******************************************************************************
80 **
81 ** Function TNETWArb_getnext
82 **
83 ** Description Return a pointer to the next buffer in a queue
84 **
85 ** Returns NULL if no more buffers in the queue, else next buffer address
86 **
87 *******************************************************************************/
TNETWArb_getnext(void * p_buf)88 void *TNETWArb_getnext (void *p_buf)
89 {
90 BUFFER_HDR_T *p_hdr;
91
92 p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
93
94 if (p_hdr->p_next)
95 {
96 return ((UINT8 *)p_hdr->p_next + BUFFER_HDR_SIZE);
97 }
98 else
99 {
100 return (NULL);
101 }
102 }
103
104
105 /*******************************************************************************
106 **
107 ** Function TNETWArb_remove_from_queue
108 **
109 ** Description Dequeue a buffer from the middle of the queue
110 **
111 ** Returns NULL if queue is empty, else buffer
112 **
113 *******************************************************************************/
TNETWArb_remove_from_queue(BUFFER_Q * p_q,void * p_buf)114 void *TNETWArb_remove_from_queue (BUFFER_Q *p_q, void *p_buf)
115 {
116 BUFFER_HDR_T *p_hdr;
117
118 if (!p_q->count)
119 return (NULL);
120
121 p_hdr = (BUFFER_HDR_T *)(p_q->p_first) - 1;
122
123 if ((void *)(p_hdr + 1) == p_buf)
124 return (TNETWArb_Dequeue (p_q));
125
126 for ( ; p_hdr; p_hdr = p_hdr->p_next)
127 {
128 if ((void *)(p_hdr->p_next + 1) == p_buf)
129 {
130 p_hdr->p_next = ((BUFFER_HDR_T *)p_buf - 1)->p_next;
131 p_q->count--;
132
133 /* Unlink the buffer since it has been removed from the queue */
134 ((BUFFER_HDR_T *)p_buf - 1)->status = BUF_STATUS_UNLINKED;
135
136 return (p_buf);
137 }
138 }
139
140 return (NULL);
141 }
142
143
144
145 /*******************************************************************************
146 **
147 ** Function TNETWArb_Dequeue
148 **
149 ** Description Dequeue a buffer from the head of a queue
150 ** CAUTION This function Is not protected againt reentrance : see GKI_dequeue
151 **
152 ** Returns NULL if queue is empty, else buffer that is dequeued
153 **
154 *******************************************************************************/
TNETWArb_Dequeue(BUFFER_Q * p_q)155 void *TNETWArb_Dequeue (BUFFER_Q *p_q)
156 {
157 BUFFER_HDR_T *p_hdr;
158
159 /*WLAN_OS_REPORT(("\n TNETWArb_Dequeue p_q %x !!!! \n", p_q));*/
160
161 if (!p_q->count)
162 return (NULL);
163
164 p_hdr = (BUFFER_HDR_T *)((UINT8 *)p_q->p_first - BUFFER_HDR_SIZE);
165
166
167 if (p_hdr->status != BUF_STATUS_QUEUED)
168 {
169 WLAN_OS_REPORT(("\n GKI_Dequeue ==> ERROR p_q->p_first %x BUF_STATUS_QUEUED NOT QUEUED!!!! %x\n", p_q->p_first));
170 return NULL;
171 }
172
173
174 /* Keep buffers such that GKI header is invisible
175 */
176 if (p_hdr->p_next)
177 {
178 p_q->p_first = ((UINT8 *)p_hdr->p_next + BUFFER_HDR_SIZE);
179 }
180 else
181 {
182 p_q->p_first = NULL;
183 p_q->p_last = NULL;
184 }
185
186 p_q->count--;
187
188 p_hdr->p_next = NULL;
189 p_hdr->status = BUF_STATUS_UNLINKED;
190
191 return ((UINT8 *)p_hdr + BUFFER_HDR_SIZE);
192 }
193
194
195 /*******************************************************************************
196 **
197 ** Function TNETWArb_Enqueue
198 **
199 ** Description Enqueue a buffer at the tail of the queue.
200 ** CAUTION This function Is not protected againt reentrance
201 **
202 ** Returns void
203 **
204 *******************************************************************************/
TNETWArb_Enqueue(BUFFER_Q * p_q,void * p_buf)205 void TNETWArb_Enqueue (BUFFER_Q *p_q, void *p_buf)
206 {
207 BUFFER_HDR_T *p_hdr;
208
209 p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
210
211
212 if (p_hdr->status != BUF_STATUS_UNLINKED)
213 {
214 WLAN_OS_REPORT(("\n GKI_Enqueue ==> ERROR p_buf %x BUF_STATUS_UNLINKED!!!! %x\n", p_buf));
215 return;
216 }
217
218 /* Since the queue is exposed (C vs C++), keep the pointers in exposed format */
219 if (p_q->p_first)
220 {
221 BUFFER_HDR_T *p_last_hdr = (BUFFER_HDR_T *)((UINT8 *)p_q->p_last - BUFFER_HDR_SIZE);
222
223 p_last_hdr->p_next = p_hdr;
224
225 }
226 else
227 {
228 p_q->p_first = p_buf;
229 }
230
231 p_q->p_last = p_buf;
232 p_q->count++;
233
234 p_hdr->p_next = NULL;
235 p_hdr->status = BUF_STATUS_QUEUED;
236
237
238 }
239
240
241 /*******************************************************************************
242 **
243 ** Function TNETWArb_Enqueue_head
244 **
245 ** Description Enqueue a buffer at the head of the queue
246 **
247 ** Returns void
248 **
249 *******************************************************************************/
TNETWArb_Enqueue_head(BUFFER_Q * p_q,void * p_buf)250 void TNETWArb_Enqueue_head (BUFFER_Q *p_q, void *p_buf)
251 {
252 BUFFER_HDR_T *p_hdr;
253
254
255 p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
256
257 if (p_hdr->status != BUF_STATUS_UNLINKED)
258 {
259 WLAN_OS_REPORT(("\n GKI_Enqueue ==> ERROR p_buf %x BUF_STATUS_UNLINKED!!!! %x\n", p_buf));
260 return;
261 }
262
263 if (p_q->p_first)
264 {
265
266 p_hdr->p_next = (BUFFER_HDR_T *)((UINT8 *)p_q->p_first - BUFFER_HDR_SIZE);
267 p_q->p_first = p_buf;
268 }
269 else
270 {
271 p_q->p_first = p_buf;
272 p_q->p_last = p_buf;
273 p_hdr->p_next = NULL;
274
275
276 }
277
278 p_q->count++;
279
280 p_hdr->status = BUF_STATUS_QUEUED;
281
282 }
283
284
285
286
287
288
289
290
291
292 /************************* NEW GKI FOR WLAN ***********************************/
293
294 /*******************************************************************************
295 **
296 ** Function TNETWArb_buffer_init
297 **
298 ** Description Called once internally by GKI at startup to initialize all
299 ** buffers and free buffer pools.
300 **
301 ** Returns void
302 **
303 *******************************************************************************/
TNETWArb_buffer_init(UINT8 * pTNETWArb_Client_Array)304 void TNETWArb_buffer_init(UINT8 *pTNETWArb_Client_Array)
305 {
306 BUFFER_HDR_T *p_hdr;
307 void *p_buf;
308 UINT8 module_id;
309
310
311 /*
312 ** Resetting the buffer to STATUS_FREE
313 */
314 for (module_id = 0; module_id < NUM_OF_TNETWIF_MODULES; module_id++)
315 {
316 /* Pick up corresponding buffer */
317 p_buf = (void *)(&(pTNETWArb_Client_Array[module_id*(BUFFER_HDR_SIZE+TNETWARB_INSTANCE_SIZE)]) + BUFFER_HDR_SIZE);
318 p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
319
320 p_hdr->p_next = NULL; /* There is no next buffer of the last one*/
321 p_hdr->status = BUF_STATUS_FREE; /* Update the status of the released buffer*/
322 }
323
324 }
325
326
327
328
329 /*******************BUFFER ALLOCATION******************************************/
330
331 /*******************************************************************************
332 **
333 ** Function TNETWArb_getpoolbuf
334 **
335 ** Description Called by an application to get a free buffer from
336 ** a specific buffer pool should be used in sections which no interrupts
337 ** protection is needed.
338 **
339 ** Returns A pointer to the buffer, or NULL if none available
340 **
341 *******************************************************************************/
TNETWArb_getpoolbuf(TI_HANDLE hTNETWArb,UINT8 module_id)342 void *TNETWArb_getpoolbuf (TI_HANDLE hTNETWArb,UINT8 module_id)
343 {
344 /* Handle to TNETW Arbiter struct */
345 TNETWArb_t *pTNETWArb = (TNETWArb_t *)hTNETWArb;
346 BUFFER_HDR_T *p_hdr;
347 void *p_buf;
348
349 p_buf = (void *)((&(pTNETWArb->TNETWArb_Client_Instance_Array[module_id][0])) + BUFFER_HDR_SIZE);
350
351 p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
352
353 if (p_hdr->status != BUF_STATUS_FREE)
354 {
355 /*WLAN_OS_REPORT(("\n GKI_getpoolbuf ==> ERROR p_hdr %x NOT FREE Status %d module_id %d !!!\n", p_hdr,p_hdr->status,module_id));*/
356 return NULL;
357 }
358
359 p_hdr->status = BUF_STATUS_UNLINKED;
360 p_hdr->p_next = NULL;
361
362 return ((void *) ((UINT8 *)p_hdr + BUFFER_HDR_SIZE));
363
364 }
365
366
367 /*******************************************************************************
368 **
369 ** Function TNETWArb_freebuf
370 **
371 ** Description Called by an application to return a buffer to the free pool.
372 ** To be used in sections which no interrupts protection is needed.
373 **
374 ** Returns void
375 **
376 *******************************************************************************/
TNETWArb_freebuf(void * bptr)377 void TNETWArb_freebuf(void *bptr)
378 {
379 BUFFER_HDR_T *p_hdr;
380
381
382 p_hdr = (BUFFER_HDR_T *) ((UINT8 *)bptr - BUFFER_HDR_SIZE);
383
384 if (p_hdr->status != BUF_STATUS_UNLINKED)
385 {
386 WLAN_OS_REPORT(("\n GKI_freebuf ==> ERROR bptr %x BUF_STATUS_UNLINKED!!!! %x\n", bptr));
387 return;
388 }
389
390 /*
391 ** Resetting the buffer to STATUS_FREE
392 */
393 p_hdr->p_next = NULL; /* There is no next buffer of the last one*/
394 p_hdr->status = BUF_STATUS_FREE; /* Update the status of the released buffer*/
395
396 }
397
398
399
400
401