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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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