blob: 58148ff7a953f006da8e20e3b139b748e2dee3f0 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Hanumantha Reddy Pothula72342952015-02-26 14:43:54 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam1ed83fc2014-02-19 01:15:45 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080020 */
Kiet Lam1ed83fc2014-02-19 01:15:45 -080021
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
Jeff Johnson295189b2012-06-20 16:38:30 -070028/*===========================================================================
29 @file vos_memory.c
30
31 @brief Virtual Operating System Services Memory API
32
33
Jeff Johnson295189b2012-06-20 16:38:30 -070034===========================================================================*/
35
36/*===========================================================================
37
38 EDIT HISTORY FOR FILE
39
40
41 This section contains comments describing changes made to the module.
42 Notice that changes are listed in reverse chronological order.
43
44
45 $Header:$ $DateTime: $ $Author: $
46
47
48 when who what, where, why
49 -------- --- --------------------------------------------------------
50
51===========================================================================*/
52
53/*---------------------------------------------------------------------------
54 * Include Files
55 * ------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -070056#include "vos_memory.h"
57#include "vos_trace.h"
Abhishek Singh837adf22015-10-01 17:37:37 +053058#include "vos_api.h"
Hanumantha Reddy Pothula72342952015-02-26 14:43:54 +053059#include <vmalloc.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070060
Mohit Khanna49a87a82012-09-11 18:03:14 -070061#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC
62#include <linux/wcnss_wlan.h>
63#define WCNSS_PRE_ALLOC_GET_THRESHOLD (4*1024)
64#endif
Abhishek Singh76179a92015-10-19 14:23:24 +053065#define VOS_GET_MEMORY_TIME_THRESHOLD 3000
Mohit Khanna49a87a82012-09-11 18:03:14 -070066
Jeff Johnson295189b2012-06-20 16:38:30 -070067#ifdef MEMORY_DEBUG
68#include "wlan_hdd_dp_utils.h"
69
70hdd_list_t vosMemList;
71
72static v_U8_t WLAN_MEM_HEADER[] = {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68 };
73static v_U8_t WLAN_MEM_TAIL[] = {0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87};
Arif Hussaind5218912013-12-05 01:10:55 -080074static int memory_dbug_flag;
Jeff Johnson295189b2012-06-20 16:38:30 -070075
76struct s_vos_mem_struct
77{
78 hdd_list_node_t pNode;
79 char* fileName;
80 unsigned int lineNum;
81 unsigned int size;
82 v_U8_t header[8];
83};
84#endif
85
86/*---------------------------------------------------------------------------
87 * Preprocessor Definitions and Constants
88 * ------------------------------------------------------------------------*/
89
90/*---------------------------------------------------------------------------
91 * Type Declarations
92 * ------------------------------------------------------------------------*/
93
94/*---------------------------------------------------------------------------
95 * Data definitions
96 * ------------------------------------------------------------------------*/
97
98/*---------------------------------------------------------------------------
99 * External Function implementation
100 * ------------------------------------------------------------------------*/
101#ifdef MEMORY_DEBUG
102void vos_mem_init()
103{
104 /* Initalizing the list with maximum size of 60000 */
105 hdd_list_init(&vosMemList, 60000);
Arif Hussaind5218912013-12-05 01:10:55 -0800106 memory_dbug_flag = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -0700107 return;
108}
109
110void vos_mem_clean()
111{
112 v_SIZE_t listSize;
113 hdd_list_size(&vosMemList, &listSize);
114
115 if(listSize)
116 {
117 hdd_list_node_t* pNode;
118 VOS_STATUS vosStatus;
119
120 struct s_vos_mem_struct* memStruct;
Manjunathappa Prakash0e7e3472013-11-22 15:38:14 -0800121 char* prev_mleak_file = "";
122 unsigned int prev_mleak_lineNum = 0;
123 unsigned int prev_mleak_sz = 0;
124 unsigned int mleak_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700125
126 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700127 "%s: List is not Empty. listSize %d ", __func__, (int)listSize);
Jeff Johnson295189b2012-06-20 16:38:30 -0700128
129 do
130 {
131 spin_lock(&vosMemList.lock);
132 vosStatus = hdd_list_remove_front(&vosMemList, &pNode);
133 spin_unlock(&vosMemList.lock);
134 if(VOS_STATUS_SUCCESS == vosStatus)
135 {
136 memStruct = (struct s_vos_mem_struct*)pNode;
Manjunathappa Prakash0e7e3472013-11-22 15:38:14 -0800137
138 /* Take care to log only once multiple memory leaks from
139 * the same place */
140 if(strcmp(prev_mleak_file, memStruct->fileName) ||
141 (prev_mleak_lineNum != memStruct->lineNum) ||
142 (prev_mleak_sz != memStruct->size))
143 {
144 if(mleak_cnt != 0)
145 {
146 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
147 "%d Time Memory Leak@ File %s, @Line %d, size %d",
148 mleak_cnt, prev_mleak_file, prev_mleak_lineNum,
149 prev_mleak_sz);
150 }
151 prev_mleak_file = memStruct->fileName;
152 prev_mleak_lineNum = memStruct->lineNum;
153 prev_mleak_sz = memStruct->size;
154 mleak_cnt = 0;
155 }
156 mleak_cnt++;
157
Jeff Johnson295189b2012-06-20 16:38:30 -0700158 kfree((v_VOID_t*)memStruct);
159 }
160 }while(vosStatus == VOS_STATUS_SUCCESS);
lukez092ea1a2013-03-15 14:53:55 -0700161
Manjunathappa Prakash0e7e3472013-11-22 15:38:14 -0800162 /* Print last memory leak from the module */
163 if(mleak_cnt)
164 {
165 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
166 "%d Time memory Leak@ File %s, @Line %d, size %d",
167 mleak_cnt, prev_mleak_file, prev_mleak_lineNum,
168 prev_mleak_sz);
169 }
170
171
lukez092ea1a2013-03-15 14:53:55 -0700172#ifdef CONFIG_HALT_KMEMLEAK
173 BUG_ON(0);
174#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700175 }
176}
177
178void vos_mem_exit()
179{
Arif Hussaind5218912013-12-05 01:10:55 -0800180 if (memory_dbug_flag)
181 {
182 vos_mem_clean();
183 hdd_list_destroy(&vosMemList);
184 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700185}
186
187v_VOID_t * vos_mem_malloc_debug( v_SIZE_t size, char* fileName, v_U32_t lineNum)
188{
189 struct s_vos_mem_struct* memStruct;
190 v_VOID_t* memPtr = NULL;
191 v_SIZE_t new_size;
Atul Mittal93d46592014-03-14 13:42:06 +0530192 int flags = GFP_KERNEL;
193 unsigned long IrqFlags;
Abhishek Singh76179a92015-10-19 14:23:24 +0530194 unsigned long time_before_kmalloc;
Atul Mittal93d46592014-03-14 13:42:06 +0530195
Jeff Johnson295189b2012-06-20 16:38:30 -0700196
Hanumantha Reddy Pothulaf7d308c2015-03-24 13:44:52 +0530197 if (size > (1024*1024) || size == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -0700198 {
199 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Hanumantha Reddy Pothulaf7d308c2015-03-24 13:44:52 +0530200 "%s: called with invalid arg %u !!!", __func__, size);
Jeff Johnson295189b2012-06-20 16:38:30 -0700201 return NULL;
202 }
Madan Mohan Koyyalamudi5c0fe232013-09-16 22:21:26 +0530203
Nirav Shah20aec4a2015-08-24 14:55:13 +0530204 if (in_interrupt() || irqs_disabled() || in_atomic())
Jeff Johnson295189b2012-06-20 16:38:30 -0700205 {
Atul Mittal1119d0b2014-03-25 12:14:37 +0530206 flags = GFP_ATOMIC;
Jeff Johnson295189b2012-06-20 16:38:30 -0700207 }
208
Arif Hussaind5218912013-12-05 01:10:55 -0800209 if (!memory_dbug_flag)
210 {
211#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC
212 v_VOID_t* pmem;
213 if (size > WCNSS_PRE_ALLOC_GET_THRESHOLD)
214 {
215 pmem = wcnss_prealloc_get(size);
216 if (NULL != pmem)
217 return pmem;
218 }
219#endif
Abhishek Singh76179a92015-10-19 14:23:24 +0530220 time_before_kmalloc = vos_timer_get_system_time();
Abhishek Singh837adf22015-10-01 17:37:37 +0530221 memPtr = kmalloc(size, flags);
Abhishek Singh76179a92015-10-19 14:23:24 +0530222
223 /* If time taken by kmalloc is greater than VOS_GET_MEMORY_TIME_THRESHOLD
224 * msec */
225 if (vos_timer_get_system_time() - time_before_kmalloc >=
226 VOS_GET_MEMORY_TIME_THRESHOLD)
227 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Abhishek Singhb4808502015-12-14 11:44:30 +0530228 "%s: kmalloc took %lu msec for size %d called from %pS at line %d",
229 __func__,
230 vos_timer_get_system_time() - time_before_kmalloc,
231 size, (void *)_RET_IP_, lineNum);
Abhishek Singh837adf22015-10-01 17:37:37 +0530232 if ((flags != GFP_ATOMIC) && (NULL == memPtr))
233 {
234 WARN_ON(1);
235 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
236 WLAN_LOG_INDICATOR_HOST_ONLY,
237 WLAN_LOG_REASON_MALLOC_FAIL,
238 false, true);
239 }
240 return memPtr;
Arif Hussaind5218912013-12-05 01:10:55 -0800241 }
242
Jeff Johnson295189b2012-06-20 16:38:30 -0700243 new_size = size + sizeof(struct s_vos_mem_struct) + 8;
244
Abhishek Singh76179a92015-10-19 14:23:24 +0530245 time_before_kmalloc = vos_timer_get_system_time();
Atul Mittal93d46592014-03-14 13:42:06 +0530246 memStruct = (struct s_vos_mem_struct*)kmalloc(new_size, flags);
Abhishek Singh76179a92015-10-19 14:23:24 +0530247 /* If time taken by kmalloc is greater than VOS_GET_MEMORY_TIME_THRESHOLD
248 * msec */
249 if (vos_timer_get_system_time() - time_before_kmalloc >=
250 VOS_GET_MEMORY_TIME_THRESHOLD)
251 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Abhishek Singhb4808502015-12-14 11:44:30 +0530252 "%s: kmalloc took %lu msec for size %d called from %pS at line %d",
253 __func__,
254 vos_timer_get_system_time() - time_before_kmalloc,
255 size, (void *)_RET_IP_, lineNum);
Jeff Johnson295189b2012-06-20 16:38:30 -0700256
257 if(memStruct != NULL)
258 {
259 VOS_STATUS vosStatus;
260
261 memStruct->fileName = fileName;
262 memStruct->lineNum = lineNum;
263 memStruct->size = size;
264
265 vos_mem_copy(&memStruct->header[0], &WLAN_MEM_HEADER[0], sizeof(WLAN_MEM_HEADER));
266 vos_mem_copy( (v_U8_t*)(memStruct + 1) + size, &WLAN_MEM_TAIL[0], sizeof(WLAN_MEM_TAIL));
267
Atul Mittal93d46592014-03-14 13:42:06 +0530268 spin_lock_irqsave(&vosMemList.lock, IrqFlags);
Jeff Johnson295189b2012-06-20 16:38:30 -0700269 vosStatus = hdd_list_insert_front(&vosMemList, &memStruct->pNode);
Atul Mittal93d46592014-03-14 13:42:06 +0530270 spin_unlock_irqrestore(&vosMemList.lock, IrqFlags);
Jeff Johnson295189b2012-06-20 16:38:30 -0700271 if(VOS_STATUS_SUCCESS != vosStatus)
272 {
273 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -0800274 "%s: Unable to insert node into List vosStatus %d", __func__, vosStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -0700275 }
276
277 memPtr = (v_VOID_t*)(memStruct + 1);
278 }
Abhishek Singh837adf22015-10-01 17:37:37 +0530279 if ((flags != GFP_ATOMIC) && (NULL == memStruct))
280 {
281 WARN_ON(1);
282 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
283 WLAN_LOG_INDICATOR_HOST_ONLY,
284 WLAN_LOG_REASON_MALLOC_FAIL,
285 false, true);
286 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700287 return memPtr;
288}
289
290v_VOID_t vos_mem_free( v_VOID_t *ptr )
291{
Madan Mohan Koyyalamudi5c0fe232013-09-16 22:21:26 +0530292
Atul Mittal93d46592014-03-14 13:42:06 +0530293 unsigned long IrqFlags;
Arif Hussaind5218912013-12-05 01:10:55 -0800294 if (ptr == NULL)
295 return;
296
Arif Hussaind5218912013-12-05 01:10:55 -0800297 if (!memory_dbug_flag)
298 {
299#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC
300 if (wcnss_prealloc_put(ptr))
301 return;
302#endif
303 kfree(ptr);
304 }
305 else
Jeff Johnson295189b2012-06-20 16:38:30 -0700306 {
307 VOS_STATUS vosStatus;
308 struct s_vos_mem_struct* memStruct = ((struct s_vos_mem_struct*)ptr) - 1;
309
Atul Mittal93d46592014-03-14 13:42:06 +0530310 spin_lock_irqsave(&vosMemList.lock, IrqFlags);
Jeff Johnson295189b2012-06-20 16:38:30 -0700311 vosStatus = hdd_list_remove_node(&vosMemList, &memStruct->pNode);
Atul Mittal1119d0b2014-03-25 12:14:37 +0530312 spin_unlock_irqrestore(&vosMemList.lock, IrqFlags);
Jeff Johnson295189b2012-06-20 16:38:30 -0700313
314 if(VOS_STATUS_SUCCESS == vosStatus)
315 {
316 if(0 == vos_mem_compare(memStruct->header, &WLAN_MEM_HEADER[0], sizeof(WLAN_MEM_HEADER)) )
317 {
318 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
319 "Memory Header is corrupted. MemInfo: Filename %s, LineNum %d",
320 memStruct->fileName, (int)memStruct->lineNum);
321 }
322 if(0 == vos_mem_compare( (v_U8_t*)ptr + memStruct->size, &WLAN_MEM_TAIL[0], sizeof(WLAN_MEM_TAIL ) ) )
323 {
324 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
325 "Memory Trailer is corrupted. MemInfo: Filename %s, LineNum %d",
326 memStruct->fileName, (int)memStruct->lineNum);
327 }
328 kfree((v_VOID_t*)memStruct);
329 }
330 else
331 {
332 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700333 "%s: Unallocated memory (double free?)", __func__);
Pradeep Kumar Goudaguntab6c426a2014-03-19 16:23:44 +0530334 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -0700335 }
336 }
337}
338#else
339v_VOID_t * vos_mem_malloc( v_SIZE_t size )
340{
Atul Mittal93d46592014-03-14 13:42:06 +0530341 int flags = GFP_KERNEL;
Abhishek Singh837adf22015-10-01 17:37:37 +0530342 v_VOID_t* memPtr = NULL;
Mohit Khanna49a87a82012-09-11 18:03:14 -0700343#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC
344 v_VOID_t* pmem;
345#endif
Abhishek Singh76179a92015-10-19 14:23:24 +0530346 unsigned long time_before_kmalloc;
347
Hanumantha Reddy Pothulaf7d308c2015-03-24 13:44:52 +0530348 if (size > (1024*1024) || size == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -0700349 {
Hanumantha Reddy Pothulaf7d308c2015-03-24 13:44:52 +0530350 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
351 "%s: called with invalid arg %u !!!", __func__, size);
Jeff Johnson295189b2012-06-20 16:38:30 -0700352 return NULL;
353 }
Atul Mittal93d46592014-03-14 13:42:06 +0530354 if (in_interrupt() || irqs_disabled() || in_atomic())
Jeff Johnson295189b2012-06-20 16:38:30 -0700355 {
Atul Mittal93d46592014-03-14 13:42:06 +0530356 flags = GFP_ATOMIC;
Jeff Johnson295189b2012-06-20 16:38:30 -0700357 }
Mohit Khanna49a87a82012-09-11 18:03:14 -0700358#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC
359 if(size > WCNSS_PRE_ALLOC_GET_THRESHOLD)
360 {
361 pmem = wcnss_prealloc_get(size);
362 if(NULL != pmem)
363 return pmem;
364 }
365#endif
Abhishek Singh76179a92015-10-19 14:23:24 +0530366 time_before_kmalloc = vos_timer_get_system_time();
Abhishek Singh837adf22015-10-01 17:37:37 +0530367 memPtr = kmalloc(size, flags);
Abhishek Singh76179a92015-10-19 14:23:24 +0530368 /* If time taken by kmalloc is greater than VOS_GET_MEMORY_TIME_THRESHOLD
369 * msec */
370 if (vos_timer_get_system_time() - time_before_kmalloc >=
371 VOS_GET_MEMORY_TIME_THRESHOLD)
372 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Abhishek Singhb4808502015-12-14 11:44:30 +0530373 "%s: kmalloc took %lu msec for size %d from %pS",
374 __func__,
375 vos_timer_get_system_time() - time_before_kmalloc,
376 size, (void *)_RET_IP_);
Abhishek Singh76179a92015-10-19 14:23:24 +0530377
Abhishek Singh837adf22015-10-01 17:37:37 +0530378 if ((flags != GFP_ATOMIC) && (NULL == memPtr))
379 {
380 WARN_ON(1);
381 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
382 WLAN_LOG_INDICATOR_HOST_ONLY,
383 WLAN_LOG_REASON_MALLOC_FAIL,
384 false, true);
385 }
386 return memPtr;
387
Jeff Johnson295189b2012-06-20 16:38:30 -0700388}
389
390v_VOID_t vos_mem_free( v_VOID_t *ptr )
391{
392 if (ptr == NULL)
393 return;
Mohit Khanna49a87a82012-09-11 18:03:14 -0700394
Mohit Khanna49a87a82012-09-11 18:03:14 -0700395#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC
396 if(wcnss_prealloc_put(ptr))
397 return;
398#endif
399
Jeff Johnson295189b2012-06-20 16:38:30 -0700400 kfree(ptr);
401}
402#endif
403
Hanumantha Reddy Pothula72342952015-02-26 14:43:54 +0530404v_VOID_t * vos_mem_vmalloc(v_SIZE_t size)
405{
406 if (size == 0 || size >= (1024*1024))
407 {
408 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
409 "%s invalid size: %u", __func__, size);
410 return NULL;
411 }
412
413 return vmalloc(size);
414}
415
416v_VOID_t vos_mem_vfree(void *addr)
417{
418 if (addr == NULL)
419 {
420 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
421 "%s NULL address passed to free", __func__);
422 return;
423 }
424
425 vfree(addr);
426 return;
427}
428
Jeff Johnson295189b2012-06-20 16:38:30 -0700429v_VOID_t vos_mem_set( v_VOID_t *ptr, v_SIZE_t numBytes, v_BYTE_t value )
430{
431 if (ptr == NULL)
432 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700433 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s called with NULL parameter ptr", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700434 return;
435 }
436 memset(ptr, value, numBytes);
437}
438
439v_VOID_t vos_mem_zero( v_VOID_t *ptr, v_SIZE_t numBytes )
440{
441 if (0 == numBytes)
442 {
443 // special case where ptr can be NULL
444 return;
445 }
446
447 if (ptr == NULL)
448 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700449 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s called with NULL parameter ptr", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700450 return;
451 }
452 memset(ptr, 0, numBytes);
453
454}
455
Jeff Johnson295189b2012-06-20 16:38:30 -0700456v_VOID_t vos_mem_copy( v_VOID_t *pDst, const v_VOID_t *pSrc, v_SIZE_t numBytes )
457{
458 if (0 == numBytes)
459 {
460 // special case where pDst or pSrc can be NULL
461 return;
462 }
463
464 if ((pDst == NULL) || (pSrc==NULL))
465 {
466 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
467 "%s called with NULL parameter, source:%p destination:%p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700468 __func__, pSrc, pDst);
Jeff Johnson295189b2012-06-20 16:38:30 -0700469 VOS_ASSERT(0);
470 return;
471 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700472 memcpy(pDst, pSrc, numBytes);
Jeff Johnson295189b2012-06-20 16:38:30 -0700473}
474
475v_VOID_t vos_mem_move( v_VOID_t *pDst, const v_VOID_t *pSrc, v_SIZE_t numBytes )
476{
477 if (0 == numBytes)
478 {
479 // special case where pDst or pSrc can be NULL
480 return;
481 }
482
483 if ((pDst == NULL) || (pSrc==NULL))
484 {
485 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
486 "%s called with NULL parameter, source:%p destination:%p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700487 __func__, pSrc, pDst);
Jeff Johnson295189b2012-06-20 16:38:30 -0700488 VOS_ASSERT(0);
489 return;
490 }
491 memmove(pDst, pSrc, numBytes);
492}
493
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +0530494v_BOOL_t vos_mem_compare(
495#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
496 const v_VOID_t *pMemory1,
497#else
498 v_VOID_t *pMemory1,
499#endif
500#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
501 const v_VOID_t *pMemory2,
502#else
503 v_VOID_t *pMemory2,
504#endif
505 v_U32_t numBytes )
Jeff Johnson295189b2012-06-20 16:38:30 -0700506{
507 if (0 == numBytes)
508 {
509 // special case where pMemory1 or pMemory2 can be NULL
510 return VOS_TRUE;
511 }
512
513 if ((pMemory1 == NULL) || (pMemory2==NULL))
514 {
515 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
516 "%s called with NULL parameter, p1:%p p2:%p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700517 __func__, pMemory1, pMemory2);
Jeff Johnson295189b2012-06-20 16:38:30 -0700518 VOS_ASSERT(0);
519 return VOS_FALSE;
520 }
521 return (memcmp(pMemory1, pMemory2, numBytes)?VOS_FALSE:VOS_TRUE);
522}
523
524
525v_SINT_t vos_mem_compare2( v_VOID_t *pMemory1, v_VOID_t *pMemory2, v_U32_t numBytes )
526
527{
528 return( (v_SINT_t) memcmp( pMemory1, pMemory2, numBytes ) );
529}
530
531/*----------------------------------------------------------------------------
532
533 \brief vos_mem_dma_malloc() - vOSS DMA Memory Allocation
534
535 This function will dynamicallly allocate the specified number of bytes of
536 memory. This memory will have special attributes making it DMA friendly i.e.
537 it will exist in contiguous, 32-byte aligned uncached memory. A normal
538 vos_mem_malloc does not yield memory with these attributes.
539
540 NOTE: the special DMA friendly memory is very scarce and this API must be
541 used sparingly
542
543 On WM, there is nothing special about this memory. SDHC allocates the
544 DMA friendly buffer and copies the data into it
545
546 \param size - the number of bytes of memory to allocate.
547
548 \return Upon successful allocate, returns a non-NULL pointer to the
549 allocated memory. If this function is unable to allocate the amount of
550 memory specified (for any reason) it returns NULL.
551
552 \sa
553
554 --------------------------------------------------------------------------*/
555#ifdef MEMORY_DEBUG
556v_VOID_t * vos_mem_dma_malloc_debug( v_SIZE_t size, char* fileName, v_U32_t lineNum)
557{
558 struct s_vos_mem_struct* memStruct;
559 v_VOID_t* memPtr = NULL;
560 v_SIZE_t new_size;
561
562 if (in_interrupt())
563 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700564 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s cannot be called from interrupt context!!!", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700565 return NULL;
566 }
567
Arif Hussaind5218912013-12-05 01:10:55 -0800568 if (!memory_dbug_flag)
569 return kmalloc(size, GFP_KERNEL);
570
Jeff Johnson295189b2012-06-20 16:38:30 -0700571 new_size = size + sizeof(struct s_vos_mem_struct) + 8;
572
573 memStruct = (struct s_vos_mem_struct*)kmalloc(new_size,GFP_KERNEL);
574
575 if(memStruct != NULL)
576 {
577 VOS_STATUS vosStatus;
578
579 memStruct->fileName = fileName;
580 memStruct->lineNum = lineNum;
581 memStruct->size = size;
582
583 vos_mem_copy(&memStruct->header[0], &WLAN_MEM_HEADER[0], sizeof(WLAN_MEM_HEADER));
584 vos_mem_copy( (v_U8_t*)(memStruct + 1) + size, &WLAN_MEM_TAIL[0], sizeof(WLAN_MEM_TAIL));
585
586 spin_lock(&vosMemList.lock);
587 vosStatus = hdd_list_insert_front(&vosMemList, &memStruct->pNode);
588 spin_unlock(&vosMemList.lock);
589 if(VOS_STATUS_SUCCESS != vosStatus)
590 {
591 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Arif Hussain02882402013-11-17 21:55:29 -0800592 "%s: Unable to insert node into List vosStatus %d", __func__, vosStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -0700593 }
594
595 memPtr = (v_VOID_t*)(memStruct + 1);
596 }
597
598 return memPtr;
599}
600
601v_VOID_t vos_mem_dma_free( v_VOID_t *ptr )
602{
Arif Hussaind5218912013-12-05 01:10:55 -0800603 if (ptr == NULL)
604 return;
605
606 if (memory_dbug_flag)
Jeff Johnson295189b2012-06-20 16:38:30 -0700607 {
608 VOS_STATUS vosStatus;
609 struct s_vos_mem_struct* memStruct = ((struct s_vos_mem_struct*)ptr) - 1;
610
611 spin_lock(&vosMemList.lock);
612 vosStatus = hdd_list_remove_node(&vosMemList, &memStruct->pNode);
613 spin_unlock(&vosMemList.lock);
614
615 if(VOS_STATUS_SUCCESS == vosStatus)
616 {
617 if(0 == vos_mem_compare(memStruct->header, &WLAN_MEM_HEADER[0], sizeof(WLAN_MEM_HEADER)) )
618 {
619 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
620 "Memory Header is corrupted. MemInfo: Filename %s, LineNum %d",
621 memStruct->fileName, (int)memStruct->lineNum);
622 }
623 if(0 == vos_mem_compare( (v_U8_t*)ptr + memStruct->size, &WLAN_MEM_TAIL[0], sizeof(WLAN_MEM_TAIL ) ) )
624 {
625 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
626 "Memory Trailer is corrupted. MemInfo: Filename %s, LineNum %d",
627 memStruct->fileName, (int)memStruct->lineNum);
628 }
629 kfree((v_VOID_t*)memStruct);
630 }
631 }
Arif Hussaind5218912013-12-05 01:10:55 -0800632 else
633 kfree(ptr);
Jeff Johnson295189b2012-06-20 16:38:30 -0700634}
635#else
636v_VOID_t* vos_mem_dma_malloc( v_SIZE_t size )
637{
638 if (in_interrupt())
639 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700640 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s cannot be called from interrupt context!!!", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700641 return NULL;
642 }
643 return kmalloc(size, GFP_KERNEL);
644}
645
646/*----------------------------------------------------------------------------
647
648 \brief vos_mem_dma_free() - vOSS DMA Free Memory
649
650 This function will free special DMA friendly memory pointed to by 'ptr'.
651
652 On WM, there is nothing special about the memory being free'd. SDHC will
653 take care of free'ing the DMA friendly buffer
654
655 \param ptr - pointer to the starting address of the memory to be
656 free'd.
657
658 \return Nothing
659
660 \sa
661
662 --------------------------------------------------------------------------*/
663v_VOID_t vos_mem_dma_free( v_VOID_t *ptr )
664{
665 if (ptr == NULL)
666 return;
667 kfree(ptr);
668}
669#endif