• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
os_memoryAlloc(TI_HANDLE OsContext,UINT32 Size)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 *****************************************************************************************/
os_memoryPreFree(void * ptr)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
os_memoryPreAlloc(TI_HANDLE OsContext,int section,UINT32 Size)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
os_memoryCAlloc(TI_HANDLE OsContext,UINT32 Number,UINT32 Size)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
os_memoryFree(TI_HANDLE OsContext,PVOID pMemPtr,UINT32 Size)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
os_memorySet(TI_HANDLE OsContext,PVOID pMemPtr,INT32 Value,UINT32 Length)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
os_memoryAlloc4HwDma(TI_HANDLE pOsContext,UINT32 Size)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
os_memory4HwDmaFree(TI_HANDLE pOsContext,PVOID pMem_ptr,UINT32 Size)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
os_memoryZero(TI_HANDLE OsContext,PVOID pMemPtr,UINT32 Length)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
os_memoryCopy(TI_HANDLE OsContext,PVOID pDstPtr,PVOID pSrcPtr,UINT32 Size)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
os_memoryCompare(TI_HANDLE OsContext,PUINT8 Buf1,PUINT8 Buf2,INT32 Count)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