Home | History | Annotate | Download | only in src
      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 "arch_ti.h"
     38 
     39 #include <linux/stddef.h>
     40 #include <linux/string.h>
     41 #include <linux/time.h>
     42 #include <linux/timer.h>
     43 
     44 #include <linux/module.h>
     45 #include <linux/kernel.h>
     46 #include <linux/netdevice.h>
     47 #include <linux/etherdevice.h>
     48 #include <linux/vmalloc.h>
     49 #include <linux/string.h>
     50 #include <linux/delay.h>
     51 #include <linux/time.h>
     52 #include <linux/list.h>
     53 
     54 #include "osApi.h"
     55 #include "osTIType.h"
     56 #include "esta_drv.h"
     57 
     58 typedef void (*os_free)(void *);
     59 struct os_mem_block
     60 {
     61     struct list_head blk_list;
     62     os_free f_free;
     63     __u32 size;
     64     __u32 signature;
     65 };
     66 #define MEM_BLOCK_START  (('m'<<24) | ('e'<<16) | ('m'<<8) | 's')
     67 #define MEM_BLOCK_END    (('m'<<24) | ('e'<<16) | ('m'<<8) | 'e')
     68 
     69 /****************************************************************************************
     70  *                                                                                      *
     71  *                      OS Memory API                                                   *
     72  *                                                                                      *
     73  ****************************************************************************************/
     74 
     75 /****************************************************************************************
     76  *                        os_memoryAlloc()
     77  ****************************************************************************************
     78 DESCRIPTION:    Allocates resident (nonpaged) system-space memory.
     79 
     80 ARGUMENTS:      OsContext   - our adapter context.
     81                 Size        - Specifies the size, in bytes, to be allocated.
     82 
     83 RETURN:         Pointer to the allocated memory.
     84                 NULL if there is insufficient memory available.
     85 
     86 NOTES:          With the call to vmalloc it is assumed that this function will
     87                 never be called in an interrupt context. vmalloc has the potential to
     88                 sleep the caller while waiting for memory to become available.
     89 
     90 *****************************************************************************************/
     91 PVOID
     92 os_memoryAlloc(
     93         TI_HANDLE OsContext,
     94         UINT32 Size
     95         )
     96 {
     97     struct os_mem_block *blk;
     98     __u32 total_size = Size + sizeof(struct os_mem_block) + sizeof(__u32);
     99 
    100 #ifdef TI_MEM_ALLOC_TRACE
    101     os_printf("MTT:%s:%d ::os_memoryAlloc(0x%p, %lu) : %lu\n",__FUNCTION__, __LINE__,OsContext,Size,total_size);
    102 #endif
    103     if( total_size < Size ) { /* Dm: Security fix */
    104         return NULL;
    105     }
    106     /*
    107         memory optimization issue. Allocate 8 kB and less from the SLAB allocator (2^n)
    108         otherwise allocate from virtual pool.
    109     */
    110     /* 2 pages */
    111     if (total_size < 2 * 4096)
    112     {
    113         if (in_atomic())
    114             blk = kmalloc(total_size, GFP_ATOMIC);
    115         else
    116             blk = kmalloc(total_size, GFP_KERNEL);
    117         if (!blk)
    118             return NULL;
    119         blk->f_free = (os_free)kfree;
    120     }
    121     else
    122     {
    123         /* We expect that the big allocations should be made outside the interrupt,
    124             otherwise fail
    125         */
    126         if (in_atomic())
    127             return NULL;
    128         blk = vmalloc(total_size);
    129         if (!blk)
    130             return NULL;
    131         blk->f_free = (os_free)vfree;
    132     }
    133 
    134     os_profile (OsContext, 4, total_size);
    135 
    136     /*list_add(&blk->blk_list, &drv->mem_blocks);*/
    137     blk->size = Size;
    138     blk->signature = MEM_BLOCK_START;
    139     *(__u32 *)((unsigned char *)blk + total_size - sizeof(__u32)) = MEM_BLOCK_END;
    140     return (PVOID)((char *)blk + sizeof(struct os_mem_block));
    141 }
    142 
    143 /****************************************************************************************
    144  *                        os_memoryPreFree()
    145  ****************************************************************************************
    146 DESCRIPTION:    Frees preallocated by the kernel memory.
    147 
    148 ARGUMENTS:      ptr - pointer to memory
    149 *****************************************************************************************/
    150 void os_memoryPreFree( void *ptr )
    151 {
    152 }
    153 
    154 /****************************************************************************************
    155  *                        os_memoryPreAlloc()
    156  ****************************************************************************************
    157 DESCRIPTION:    Gets system-space memory preallocated by kernel.
    158 
    159 ARGUMENTS:      OsContext   - our adapter context.
    160                 section     - section number
    161                 Size        - Specifies the size, in bytes, to be allocated.
    162 
    163 RETURN:         Pointer to the allocated memory.
    164                 NULL if there is insufficient memory available.
    165 *****************************************************************************************/
    166 PVOID
    167 os_memoryPreAlloc(
    168         TI_HANDLE OsContext,
    169         int section,
    170         UINT32 Size
    171         )
    172 {
    173     struct os_mem_block *blk;
    174     __u32 total_size = Size + sizeof(struct os_mem_block) + sizeof(__u32);
    175 
    176 #ifdef TI_MEM_ALLOC_TRACE
    177     os_printf("MTT:%s:%d ::os_memoryPreAlloc(0x%p, %lu) : %lu\n",__FUNCTION__, __LINE__,OsContext,Size,total_size);
    178 #endif
    179     if( total_size < Size ) { /* Dm: Security fix */
    180         return NULL;
    181     }
    182 
    183     blk = (struct os_mem_block *)wifi_kernel_prealloc( section, total_size );
    184     if( !blk ) {
    185         return os_memoryAlloc(OsContext, Size);
    186     }
    187     blk->f_free = (os_free)os_memoryPreFree;
    188 
    189     os_profile (OsContext, 4, total_size);
    190 
    191     /*list_add(&blk->blk_list, &drv->mem_blocks);*/
    192     blk->size = Size;
    193     blk->signature = MEM_BLOCK_START;
    194     *(__u32 *)((unsigned char *)blk + total_size - sizeof(__u32)) = MEM_BLOCK_END;
    195     return (PVOID)((char *)blk + sizeof(struct os_mem_block));
    196 }
    197 
    198 
    199 /****************************************************************************************
    200  *                        os_memoryCAlloc()
    201  ****************************************************************************************
    202 DESCRIPTION:    Allocates an array in memory with elements initialized to 0.
    203 
    204 ARGUMENTS:		OsContext	-	our adapter context.
    205 				Number		-	Number of elements
    206 				Size		-	Length in bytes of each element
    207 
    208 RETURN:			None
    209 
    210 NOTES:
    211 *****************************************************************************************/
    212 PVOID
    213 os_memoryCAlloc(
    214         TI_HANDLE OsContext,
    215         UINT32 Number,
    216         UINT32 Size
    217         )
    218 {
    219     PVOID pAllocatedMem;
    220     ULONG MemSize;
    221 
    222 #ifdef TI_MEM_ALLOC_TRACE
    223     os_printf("MTT:%s:%d ::os_memoryCAlloc(0x%p, %lu, %lu) : %lu\n",__FUNCTION__,__LINE__,OsContext,Number,Size,Number*Size);
    224 #endif
    225     MemSize = Number * Size;
    226 
    227     if( (Number > 0) && (Size >= (0xFFFFFFFFUL / Number)) ) { /* Dm: Security fix */
    228         return NULL;
    229     }
    230 
    231     pAllocatedMem = os_memoryAlloc(OsContext, MemSize);
    232 
    233     if(!pAllocatedMem)
    234         return NULL;
    235 
    236     memset(pAllocatedMem,0,MemSize);
    237 
    238     return pAllocatedMem;
    239 }
    240 
    241 /****************************************************************************************
    242  *                        os_memoryFree()
    243  ****************************************************************************************
    244 DESCRIPTION:    This function releases a block of memory previously allocated with the
    245                 os_memoryAlloc function.
    246 
    247 
    248 ARGUMENTS:      OsContext   -   our adapter context.
    249                 pMemPtr     -   Pointer to the base virtual address of the allocated memory.
    250                                 This address was returned by the os_memoryAlloc function.
    251                 Size        -   Specifies the size, in bytes, of the memory block to be released.
    252                                 This parameter must be identical to the Length that was passed to
    253                                 os_memoryAlloc.
    254 
    255 RETURN:         None
    256 
    257 NOTES:
    258 *****************************************************************************************/
    259 VOID
    260 os_memoryFree(
    261         TI_HANDLE OsContext,
    262         PVOID pMemPtr,
    263         UINT32 Size
    264         )
    265 {
    266     struct os_mem_block *blk =
    267         (struct os_mem_block *)((char *)pMemPtr - sizeof(struct os_mem_block));
    268 
    269 #ifdef TI_MEM_ALLOC_TRACE
    270     os_printf("MTT:%s:%d ::os_memoryFree(0x%p, 0x%p, %lu) : %d\n",__FUNCTION__,__LINE__,OsContext,pMemPtr,Size,-Size);
    271 #endif
    272     if (blk->signature != MEM_BLOCK_START)
    273     {
    274         printk("\n\n%s: memory block signature is incorrect - 0x%x\n\n\n",
    275                __FUNCTION__, blk->signature);
    276         return;
    277     }
    278     *(char *)(&blk->signature) = '~';
    279     if (*(__u32 *)((unsigned char *)blk + blk->size + sizeof(struct os_mem_block))
    280         != MEM_BLOCK_END)
    281     {
    282         printk("\n\n%s: memory block corruption. Size=%u\n\n\n",
    283                __FUNCTION__, blk->size);
    284     }
    285 
    286     os_profile (OsContext, 5, blk->size + sizeof(struct os_mem_block) + sizeof(__u32));
    287 
    288     blk->f_free(blk);
    289 }
    290 
    291 
    292 /****************************************************************************************
    293  *                        os_memorySet()
    294  ****************************************************************************************
    295 DESCRIPTION:    This function fills a block of memory with given value.
    296 
    297 ARGUMENTS:		OsContext	- our adapter context.
    298 				pMemPtr		- Specifies the base address of a block of memory
    299 				Value		- Specifies the value to set
    300 				Length		- Specifies the size, in bytes, to copy.
    301 
    302 RETURN:			None
    303 
    304 NOTES:
    305 *****************************************************************************************/
    306 VOID
    307 os_memorySet(
    308     TI_HANDLE OsContext,
    309     PVOID pMemPtr,
    310     INT32 Value,
    311     UINT32 Length
    312     )
    313 {
    314    memset(pMemPtr,Value,Length);
    315 }
    316 
    317 /****************************************************************************************
    318  *                        _os_memoryAlloc4HwDma()
    319  ****************************************************************************************
    320 DESCRIPTION:    Allocates resident (nonpaged) system-space memory for DMA operations.
    321 
    322 ARGUMENTS:		OsContext	- our adapter context.
    323 				Size		- Specifies the size, in bytes, to be allocated.
    324 
    325 RETURN:			Pointer to the allocated memory.
    326 				NULL if there is insufficient memory available.
    327 
    328 NOTES:
    329 
    330 *****************************************************************************************/
    331 PVOID
    332 os_memoryAlloc4HwDma(
    333     TI_HANDLE pOsContext,
    334     UINT32 Size
    335     )
    336 {
    337     	struct os_mem_block *blk;
    338     	__u32 total_size = Size + sizeof(struct os_mem_block) + sizeof(__u32);
    339 	/*
    340 		if the size is greater than 2 pages then we cant allocate the memory through kmalloc so the function fails
    341 	*/
    342 	if (Size < 2 * OS_PAGE_SIZE)
    343     	{
    344        	blk = kmalloc(total_size, GFP_ATOMIC);
    345         	if (!blk)
    346 			return NULL;
    347        	blk->f_free = (os_free)kfree;
    348 	}
    349     	else
    350     	{
    351 		printk("\n\n%s: memory cant be allocated-Size = %d\n\n\n",
    352                __FUNCTION__, Size);
    353 		return NULL;
    354     	}
    355 
    356 	blk->size = Size;
    357     	blk->signature = MEM_BLOCK_START;
    358     	*(__u32 *)((unsigned char *)blk + total_size - sizeof(__u32)) = MEM_BLOCK_END;
    359     	return (PVOID)((char *)blk + sizeof(struct os_mem_block));
    360 }
    361 
    362 /****************************************************************************************
    363  *                        _os_memory4HwDmaFree()
    364  ****************************************************************************************
    365 DESCRIPTION:    This function releases a block of memory previously allocated with the
    366 				_os_memoryAlloc4HwDma function.
    367 
    368 
    369 ARGUMENTS:		OsContext	-	our adapter context.
    370 				pMemPtr		-	Pointer to the base virtual address of the allocated memory.
    371 								This address was returned by the os_memoryAlloc function.
    372 				Size		-	Specifies the size, in bytes, of the memory block to be released.
    373 								This parameter must be identical to the Length that was passed to
    374 								os_memoryAlloc.
    375 
    376 RETURN:			None
    377 
    378 NOTES:
    379 *****************************************************************************************/
    380 void
    381 os_memory4HwDmaFree(
    382     TI_HANDLE pOsContext,
    383     PVOID pMem_ptr,
    384     UINT32 Size
    385     )
    386 {
    387     struct os_mem_block *blk =
    388         (struct os_mem_block *)((char *)pMem_ptr - sizeof(struct os_mem_block));
    389 
    390 	if (blk->signature != MEM_BLOCK_START)
    391     {
    392 		printk("\n\n%s: memory block signature is incorrect - 0x%x\n\n\n",
    393                __FUNCTION__, blk->signature);
    394         return;
    395     }
    396     *(char *)(&blk->signature) = '~';
    397     if (*(__u32 *)((unsigned char *)blk + blk->size + sizeof(struct os_mem_block))
    398         != MEM_BLOCK_END)
    399     {
    400 		printk("\n\n%s: memory block corruption. Size=%u\n\n\n",
    401                __FUNCTION__, blk->size);
    402     }
    403 
    404     blk->f_free(blk);
    405 }
    406 
    407 /****************************************************************************************
    408  *                        os_memoryZero()
    409  ****************************************************************************************
    410 DESCRIPTION:    This function fills a block of memory with 0s.
    411 
    412 ARGUMENTS:		OsContext	- our adapter context.
    413 				pMemPtr		- Specifies the base address of a block of memory
    414 				Length		- Specifies how many bytes to fill with 0s.
    415 
    416 RETURN:			None
    417 
    418 NOTES:
    419 *****************************************************************************************/
    420 VOID
    421 os_memoryZero(
    422     TI_HANDLE OsContext,
    423     PVOID pMemPtr,
    424     UINT32 Length
    425     )
    426 {
    427    memset(pMemPtr,0,Length);
    428 }
    429 
    430 
    431 /****************************************************************************************
    432  *                        os_memoryCopy()
    433  ****************************************************************************************
    434 DESCRIPTION:    This function copies a specified number of bytes from one caller-supplied
    435 				location to another.
    436 
    437 ARGUMENTS:		OsContext	- our adapter context.
    438 				pDstPtr		- Destination buffer
    439 				pSrcPtr		- Source buffer
    440 				Size		- Specifies the size, in bytes, to copy.
    441 
    442 RETURN:			None
    443 
    444 NOTES:
    445 *****************************************************************************************/
    446 VOID
    447 os_memoryCopy(
    448     TI_HANDLE OsContext,
    449     PVOID pDstPtr,
    450     PVOID pSrcPtr,
    451     UINT32 Size
    452     )
    453 {
    454    memcpy(pDstPtr,pSrcPtr,Size);
    455 }
    456 
    457 /****************************************************************************************
    458  *                        os_memoryCompare()
    459  ****************************************************************************************
    460 DESCRIPTION:    Compare characters in two buffers.
    461 
    462 ARGUMENTS:		OsContext	- our adapter context.
    463 				Buf1		- First buffer
    464 				Buf2		- Second buffer
    465 				Count		- Number of characters
    466 
    467 RETURN:			The return value indicates the relationship between the buffers:
    468                 < 0 Buf1 less than Buf2
    469                 0 Buf1 identical to Buf2
    470                 > 0 Buf1 greater than Buf2
    471 
    472 NOTES:
    473 *****************************************************************************************/
    474 INT32
    475 os_memoryCompare(
    476         TI_HANDLE OsContext,
    477         PUINT8 Buf1,
    478         PUINT8 Buf2,
    479         INT32 Count
    480         )
    481 {
    482    return memcmp(Buf1, Buf2, Count);
    483 }
    484