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