Home | History | Annotate | Download | only in TNETWArbiter
      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