2 * Platform Dependent file for usage of Preallocted Memory
4 * Copyright (C) 2020, Broadcom.
6 * Unless you and Broadcom execute a separate written software license
7 * agreement governing use of this software, this software is licensed to you
8 * under the terms of the GNU General Public License version 2 (the "GPL"),
9 * available at http://www.broadcom.com/licenses/GPLv2.php, with the
10 * following added to such license:
12 * As a special exception, the copyright holders of this software give you
13 * permission to link this software with independent modules, and to copy and
14 * distribute the resulting executable under terms of your choice, provided that
15 * you also meet, for each linked independent module, the terms and conditions of
16 * the license of that module. An independent module is a module which is not
17 * derived from this software. The special exception does not apply to any
18 * modifications of the software.
21 * <<Broadcom-WL-IPTag/Open:>>
26 #include <linux/device.h>
27 #include <linux/slab.h>
28 #include <linux/miscdevice.h>
29 #include <linux/sched.h>
30 #include <linux/module.h>
32 #include <linux/list.h>
34 #include <linux/workqueue.h>
35 #include <linux/unistd.h>
36 #include <linux/bug.h>
37 #include <linux/skbuff.h>
38 #include <linux/init.h>
40 #ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
42 #define WLAN_STATIC_SCAN_BUF0 5
43 #define WLAN_STATIC_SCAN_BUF1 6
44 #define WLAN_STATIC_DHD_INFO_BUF 7
45 #define WLAN_STATIC_DHD_WLFC_BUF 8
46 #define WLAN_STATIC_DHD_IF_FLOW_LKUP 9
47 #define WLAN_STATIC_DHD_MEMDUMP_RAM 11
48 #define WLAN_STATIC_DHD_WLFC_HANGER 12
49 #define WLAN_STATIC_DHD_PKTID_MAP 13
50 #define WLAN_STATIC_DHD_PKTID_IOCTL_MAP 14
51 #define WLAN_STATIC_DHD_LOG_DUMP_BUF 15
52 #define WLAN_STATIC_DHD_LOG_DUMP_BUF_EX 16
53 #define WLAN_STATIC_DHD_PKTLOG_DUMP_BUF 17
55 #define WLAN_SCAN_BUF_SIZE (64 * 1024)
57 #define WLAN_DHD_INFO_BUF_SIZE (32 * 1024)
58 #define WLAN_DHD_WLFC_BUF_SIZE (64 * 1024)
59 #define WLAN_DHD_IF_FLOW_LKUP_SIZE (64 * 1024)
60 /* Have 2MB ramsize to accomodate future chips */
61 #define WLAN_DHD_MEMDUMP_SIZE (3 * 1024 * 1024)
63 #define PREALLOC_WLAN_SEC_NUM 4
64 #define PREALLOC_WLAN_BUF_NUM 160
65 #define PREALLOC_WLAN_SECTION_HEADER 24
67 #ifdef CONFIG_BCMDHD_PCIE
68 #define DHD_SKB_1PAGE_BUFSIZE (PAGE_SIZE*1)
69 #define DHD_SKB_2PAGE_BUFSIZE (PAGE_SIZE*2)
70 #define DHD_SKB_4PAGE_BUFSIZE (PAGE_SIZE*4)
72 #define WLAN_SECTION_SIZE_0 (PREALLOC_WLAN_BUF_NUM * 128)
73 #define WLAN_SECTION_SIZE_1 0
74 #define WLAN_SECTION_SIZE_2 0
75 #define WLAN_SECTION_SIZE_3 (PREALLOC_WLAN_BUF_NUM * 1024)
77 #define DHD_SKB_1PAGE_BUF_NUM 0
78 #define DHD_SKB_2PAGE_BUF_NUM 128
79 #define DHD_SKB_4PAGE_BUF_NUM 0
82 #define DHD_SKB_HDRSIZE 336
83 #define DHD_SKB_1PAGE_BUFSIZE ((PAGE_SIZE*1)-DHD_SKB_HDRSIZE)
84 #define DHD_SKB_2PAGE_BUFSIZE ((PAGE_SIZE*2)-DHD_SKB_HDRSIZE)
85 #define DHD_SKB_4PAGE_BUFSIZE ((PAGE_SIZE*4)-DHD_SKB_HDRSIZE)
87 #define WLAN_SECTION_SIZE_0 (PREALLOC_WLAN_BUF_NUM * 128)
88 #define WLAN_SECTION_SIZE_1 (PREALLOC_WLAN_BUF_NUM * 128)
89 #define WLAN_SECTION_SIZE_2 (PREALLOC_WLAN_BUF_NUM * 512)
90 #define WLAN_SECTION_SIZE_3 (PREALLOC_WLAN_BUF_NUM * 1024)
92 #define DHD_SKB_1PAGE_BUF_NUM 8
93 #define DHD_SKB_2PAGE_BUF_NUM 8
94 #define DHD_SKB_4PAGE_BUF_NUM 1
95 #endif /* CONFIG_BCMDHD_PCIE */
97 #define WLAN_SKB_1_2PAGE_BUF_NUM ((DHD_SKB_1PAGE_BUF_NUM) + \
98 (DHD_SKB_2PAGE_BUF_NUM))
99 #define WLAN_SKB_BUF_NUM ((WLAN_SKB_1_2PAGE_BUF_NUM) + \
100 (DHD_SKB_4PAGE_BUF_NUM))
102 #define WLAN_MAX_PKTID_ITEMS (8192)
103 #define WLAN_DHD_PKTID_MAP_HDR_SIZE (20 + 4*(WLAN_MAX_PKTID_ITEMS + 1))
104 #define WLAN_DHD_PKTID_MAP_ITEM_SIZE (32)
105 #define WLAN_DHD_PKTID_MAP_SIZE ((WLAN_DHD_PKTID_MAP_HDR_SIZE) + \
106 ((WLAN_MAX_PKTID_ITEMS+1) * WLAN_DHD_PKTID_MAP_ITEM_SIZE))
108 #define WLAN_MAX_PKTID_IOCTL_ITEMS (32)
109 #define WLAN_DHD_PKTID_IOCTL_MAP_HDR_SIZE (20 + 4*(WLAN_MAX_PKTID_IOCTL_ITEMS + 1))
110 #define WLAN_DHD_PKTID_IOCTL_MAP_ITEM_SIZE (32)
111 #define WLAN_DHD_PKTID_IOCTL_MAP_SIZE ((WLAN_DHD_PKTID_IOCTL_MAP_HDR_SIZE) + \
112 ((WLAN_MAX_PKTID_IOCTL_ITEMS+1) * WLAN_DHD_PKTID_IOCTL_MAP_ITEM_SIZE))
114 #define DHD_LOG_DUMP_BUF_SIZE (1024 * 1024 * 4)
115 #define DHD_LOG_DUMP_BUF_EX_SIZE (1024 * 1024 * 2)
117 #define DHD_PKTLOG_DUMP_BUF_SIZE (64 * 1024)
119 #define WLAN_DHD_WLFC_HANGER_MAXITEMS 3072
120 #define WLAN_DHD_WLFC_HANGER_ITEM_SIZE 32
121 #define WLAN_DHD_WLFC_HANGER_SIZE ((WLAN_DHD_WLFC_HANGER_ITEM_SIZE) + \
122 ((WLAN_DHD_WLFC_HANGER_MAXITEMS) * (WLAN_DHD_WLFC_HANGER_ITEM_SIZE)))
124 static struct sk_buff
*wlan_static_skb
[WLAN_SKB_BUF_NUM
];
126 struct wlan_mem_prealloc
{
131 static struct wlan_mem_prealloc wlan_mem_array
[PREALLOC_WLAN_SEC_NUM
] = {
132 {NULL
, (WLAN_SECTION_SIZE_0
+ PREALLOC_WLAN_SECTION_HEADER
)},
133 {NULL
, (WLAN_SECTION_SIZE_1
+ PREALLOC_WLAN_SECTION_HEADER
)},
134 {NULL
, (WLAN_SECTION_SIZE_2
+ PREALLOC_WLAN_SECTION_HEADER
)},
135 {NULL
, (WLAN_SECTION_SIZE_3
+ PREALLOC_WLAN_SECTION_HEADER
)}
138 static void *wlan_static_scan_buf0
= NULL
;
139 static void *wlan_static_scan_buf1
= NULL
;
140 static void *wlan_static_dhd_info_buf
= NULL
;
141 static void *wlan_static_dhd_wlfc_buf
= NULL
;
142 static void *wlan_static_if_flow_lkup
= NULL
;
143 static void *wlan_static_dhd_memdump_ram
= NULL
;
144 static void *wlan_static_dhd_wlfc_hanger
= NULL
;
145 static void *wlan_static_dhd_pktid_map
= NULL
;
146 static void *wlan_static_dhd_pktid_ioctl_map
= NULL
;
147 static void *wlan_static_dhd_log_dump_buf
= NULL
;
148 static void *wlan_static_dhd_log_dump_buf_ex
= NULL
;
149 static void *wlan_static_dhd_pktlog_dump_buf
= NULL
;
152 *dhd_wlan_mem_prealloc(int section
, unsigned long size
)
154 if (section
== PREALLOC_WLAN_SEC_NUM
) {
155 return wlan_static_skb
;
158 if (section
== WLAN_STATIC_SCAN_BUF0
) {
159 return wlan_static_scan_buf0
;
162 if (section
== WLAN_STATIC_SCAN_BUF1
) {
163 return wlan_static_scan_buf1
;
166 if (section
== WLAN_STATIC_DHD_INFO_BUF
) {
167 if (size
> WLAN_DHD_INFO_BUF_SIZE
) {
168 pr_err("request DHD_INFO size(%lu) is bigger than"
169 " static size(%d).\n", size
,
170 WLAN_DHD_INFO_BUF_SIZE
);
173 return wlan_static_dhd_info_buf
;
176 if (section
== WLAN_STATIC_DHD_WLFC_BUF
) {
177 if (size
> WLAN_DHD_WLFC_BUF_SIZE
) {
178 pr_err("request DHD_WLFC size(%lu) is bigger than"
179 " static size(%d).\n",
180 size
, WLAN_DHD_WLFC_BUF_SIZE
);
183 return wlan_static_dhd_wlfc_buf
;
186 if (section
== WLAN_STATIC_DHD_WLFC_HANGER
) {
187 if (size
> WLAN_DHD_WLFC_HANGER_SIZE
) {
188 pr_err("request DHD_WLFC_HANGER size(%lu) is bigger than"
189 " static size(%d).\n",
190 size
, WLAN_DHD_WLFC_HANGER_SIZE
);
193 return wlan_static_dhd_wlfc_hanger
;
196 if (section
== WLAN_STATIC_DHD_IF_FLOW_LKUP
) {
197 if (size
> WLAN_DHD_IF_FLOW_LKUP_SIZE
) {
198 pr_err("request DHD_WLFC size(%lu) is bigger than"
199 " static size(%d).\n",
200 size
, WLAN_DHD_WLFC_BUF_SIZE
);
203 return wlan_static_if_flow_lkup
;
206 if (section
== WLAN_STATIC_DHD_MEMDUMP_RAM
) {
207 if (size
> WLAN_DHD_MEMDUMP_SIZE
) {
208 pr_err("request DHD_MEMDUMP_RAM size(%lu) is bigger"
209 " than static size(%d).\n",
210 size
, WLAN_DHD_MEMDUMP_SIZE
);
213 return wlan_static_dhd_memdump_ram
;
216 if (section
== WLAN_STATIC_DHD_PKTID_MAP
) {
217 if (size
> WLAN_DHD_PKTID_MAP_SIZE
) {
218 pr_err("request DHD_PKTID_MAP size(%lu) is bigger than"
219 " static size(%d).\n",
220 size
, WLAN_DHD_PKTID_MAP_SIZE
);
223 return wlan_static_dhd_pktid_map
;
226 if (section
== WLAN_STATIC_DHD_PKTID_IOCTL_MAP
) {
227 if (size
> WLAN_DHD_PKTID_IOCTL_MAP_SIZE
) {
228 pr_err("request DHD_PKTID_IOCTL_MAP size(%lu) is bigger than"
229 " static size(%d).\n",
230 size
, WLAN_DHD_PKTID_IOCTL_MAP_SIZE
);
233 return wlan_static_dhd_pktid_ioctl_map
;
236 if (section
== WLAN_STATIC_DHD_LOG_DUMP_BUF
) {
237 if (size
> DHD_LOG_DUMP_BUF_SIZE
) {
238 pr_err("request DHD_LOG_DUMP_BUF size(%lu) is bigger then"
239 " static size(%d).\n",
240 size
, DHD_LOG_DUMP_BUF_SIZE
);
243 return wlan_static_dhd_log_dump_buf
;
246 if (section
== WLAN_STATIC_DHD_LOG_DUMP_BUF_EX
) {
247 if (size
> DHD_LOG_DUMP_BUF_EX_SIZE
) {
248 pr_err("request DHD_LOG_DUMP_BUF_EX size(%lu) is bigger then"
249 " static size(%d).\n",
250 size
, DHD_LOG_DUMP_BUF_EX_SIZE
);
253 return wlan_static_dhd_log_dump_buf_ex
;
256 if (section
== WLAN_STATIC_DHD_PKTLOG_DUMP_BUF
) {
257 if (size
> DHD_PKTLOG_DUMP_BUF_SIZE
) {
258 pr_err("request DHD_PKTLOG_DUMP_BUF size(%lu) is bigger then"
259 " static size(%d).\n",
260 size
, DHD_PKTLOG_DUMP_BUF_SIZE
);
263 return wlan_static_dhd_pktlog_dump_buf
;
266 if ((section
< 0) || (section
>= PREALLOC_WLAN_SEC_NUM
)) {
270 if (wlan_mem_array
[section
].size
< size
) {
274 return wlan_mem_array
[section
].mem_ptr
;
276 EXPORT_SYMBOL(dhd_wlan_mem_prealloc
);
279 dhd_init_wlan_mem(void)
284 #if !defined(CONFIG_BCMDHD_PCIE)
285 for (i
= 0; i
< DHD_SKB_1PAGE_BUF_NUM
; i
++) {
286 wlan_static_skb
[i
] = __dev_alloc_skb(DHD_SKB_1PAGE_BUFSIZE
, GFP_KERNEL
);
287 if (!wlan_static_skb
[i
]) {
291 #endif /* !CONFIG_BCMDHD_PCIE */
293 for (i
= DHD_SKB_1PAGE_BUF_NUM
; i
< WLAN_SKB_1_2PAGE_BUF_NUM
; i
++) {
294 wlan_static_skb
[i
] = __dev_alloc_skb(DHD_SKB_2PAGE_BUFSIZE
, GFP_KERNEL
);
295 if (!wlan_static_skb
[i
]) {
300 #if !defined(CONFIG_BCMDHD_PCIE)
301 wlan_static_skb
[i
] = __dev_alloc_skb(DHD_SKB_4PAGE_BUFSIZE
, GFP_KERNEL
);
302 if (!wlan_static_skb
[i
]) {
305 #endif /* !CONFIG_BCMDHD_PCIE */
307 for (i
= 0; i
< PREALLOC_WLAN_SEC_NUM
; i
++) {
308 if (wlan_mem_array
[i
].size
> 0) {
309 wlan_mem_array
[i
].mem_ptr
=
310 kmalloc(wlan_mem_array
[i
].size
, GFP_KERNEL
);
312 if (!wlan_mem_array
[i
].mem_ptr
) {
318 wlan_static_scan_buf0
= kmalloc(WLAN_SCAN_BUF_SIZE
, GFP_KERNEL
);
319 if (!wlan_static_scan_buf0
) {
320 pr_err("Failed to alloc wlan_static_scan_buf0\n");
324 wlan_static_scan_buf1
= kmalloc(WLAN_SCAN_BUF_SIZE
, GFP_KERNEL
);
325 if (!wlan_static_scan_buf1
) {
326 pr_err("Failed to alloc wlan_static_scan_buf1\n");
330 wlan_static_dhd_log_dump_buf
= kmalloc(DHD_LOG_DUMP_BUF_SIZE
, GFP_KERNEL
);
331 if (!wlan_static_dhd_log_dump_buf
) {
332 pr_err("Failed to alloc wlan_static_dhd_log_dump_buf\n");
336 wlan_static_dhd_log_dump_buf_ex
= kmalloc(DHD_LOG_DUMP_BUF_EX_SIZE
, GFP_KERNEL
);
337 if (!wlan_static_dhd_log_dump_buf_ex
) {
338 pr_err("Failed to alloc wlan_static_dhd_log_dump_buf_ex\n");
342 wlan_static_dhd_info_buf
= kmalloc(WLAN_DHD_INFO_BUF_SIZE
, GFP_KERNEL
);
343 if (!wlan_static_dhd_info_buf
) {
344 pr_err("Failed to alloc wlan_static_dhd_info_buf\n");
348 #ifdef CONFIG_BCMDHD_PCIE
349 wlan_static_if_flow_lkup
= kmalloc(WLAN_DHD_IF_FLOW_LKUP_SIZE
,
351 if (!wlan_static_if_flow_lkup
) {
352 pr_err("Failed to alloc wlan_static_if_flow_lkup\n");
356 #ifdef CONFIG_BCMDHD_PREALLOC_PKTIDMAP
357 wlan_static_dhd_pktid_map
= kmalloc(WLAN_DHD_PKTID_MAP_SIZE
,
359 if (!wlan_static_dhd_pktid_map
) {
360 pr_err("Failed to alloc wlan_static_dhd_pktid_map\n");
364 wlan_static_dhd_pktid_ioctl_map
= kmalloc(WLAN_DHD_PKTID_IOCTL_MAP_SIZE
,
366 if (!wlan_static_dhd_pktid_ioctl_map
) {
367 pr_err("Failed to alloc wlan_static_dhd_pktid_ioctl_map\n");
370 #endif /* CONFIG_BCMDHD_PREALLOC_PKTIDMAP */
372 wlan_static_dhd_wlfc_buf
= kmalloc(WLAN_DHD_WLFC_BUF_SIZE
,
374 if (!wlan_static_dhd_wlfc_buf
) {
375 pr_err("Failed to alloc wlan_static_dhd_wlfc_buf\n");
379 wlan_static_dhd_wlfc_hanger
= kmalloc(WLAN_DHD_WLFC_HANGER_SIZE
,
381 if (!wlan_static_dhd_wlfc_hanger
) {
382 pr_err("Failed to alloc wlan_static_dhd_wlfc_hanger\n");
385 #endif /* CONFIG_BCMDHD_PCIE */
387 #ifdef CONFIG_BCMDHD_PREALLOC_MEMDUMP
388 wlan_static_dhd_memdump_ram
= kmalloc(WLAN_DHD_MEMDUMP_SIZE
, GFP_KERNEL
);
389 if (!wlan_static_dhd_memdump_ram
) {
390 pr_err("Failed to alloc wlan_static_dhd_memdump_ram\n");
393 #endif /* CONFIG_BCMDHD_PREALLOC_MEMDUMP */
395 wlan_static_dhd_pktlog_dump_buf
= kmalloc(DHD_PKTLOG_DUMP_BUF_SIZE
, GFP_KERNEL
);
396 if (!wlan_static_dhd_pktlog_dump_buf
) {
397 pr_err("Failed to alloc wlan_static_dhd_pktlog_dump_buf\n");
401 pr_err("%s: WIFI MEM Allocated\n", __FUNCTION__
);
405 #ifdef CONFIG_BCMDHD_PREALLOC_MEMDUMP
406 if (wlan_static_dhd_memdump_ram
) {
407 kfree(wlan_static_dhd_memdump_ram
);
410 #endif /* CONFIG_BCMDHD_PREALLOC_MEMDUMP */
412 #ifdef CONFIG_BCMDHD_PCIE
413 if (wlan_static_if_flow_lkup
) {
414 kfree(wlan_static_if_flow_lkup
);
417 #ifdef CONFIG_BCMDHD_PREALLOC_PKTIDMAP
418 if (wlan_static_dhd_pktid_map
) {
419 kfree(wlan_static_dhd_pktid_map
);
422 if (wlan_static_dhd_pktid_ioctl_map
) {
423 kfree(wlan_static_dhd_pktid_ioctl_map
);
425 #endif /* CONFIG_BCMDHD_PREALLOC_PKTIDMAP */
427 if (wlan_static_dhd_wlfc_buf
) {
428 kfree(wlan_static_dhd_wlfc_buf
);
431 if (wlan_static_dhd_wlfc_hanger
) {
432 kfree(wlan_static_dhd_wlfc_hanger
);
434 #endif /* CONFIG_BCMDHD_PCIE */
435 if (wlan_static_dhd_info_buf
) {
436 kfree(wlan_static_dhd_info_buf
);
439 if (wlan_static_dhd_log_dump_buf
) {
440 kfree(wlan_static_dhd_log_dump_buf
);
443 if (wlan_static_dhd_log_dump_buf_ex
) {
444 kfree(wlan_static_dhd_log_dump_buf_ex
);
447 if (wlan_static_scan_buf1
) {
448 kfree(wlan_static_scan_buf1
);
451 if (wlan_static_scan_buf0
) {
452 kfree(wlan_static_scan_buf0
);
455 if (wlan_static_dhd_pktlog_dump_buf
) {
456 kfree(wlan_static_dhd_pktlog_dump_buf
);
459 pr_err("Failed to mem_alloc for WLAN\n");
461 for (j
= 0; j
< i
; j
++) {
462 kfree(wlan_mem_array
[j
].mem_ptr
);
465 i
= WLAN_SKB_BUF_NUM
;
468 pr_err("Failed to skb_alloc for WLAN\n");
469 for (j
= 0; j
< i
; j
++) {
470 dev_kfree_skb(wlan_static_skb
[j
]);
475 EXPORT_SYMBOL(dhd_init_wlan_mem
);
478 dhd_exit_wlan_mem(void)
482 #ifdef CONFIG_BCMDHD_PREALLOC_MEMDUMP
483 if (wlan_static_dhd_memdump_ram
) {
484 kfree(wlan_static_dhd_memdump_ram
);
487 #endif /* CONFIG_BCMDHD_PREALLOC_MEMDUMP */
489 #ifdef CONFIG_BCMDHD_PCIE
490 if (wlan_static_if_flow_lkup
) {
491 kfree(wlan_static_if_flow_lkup
);
494 #ifdef CONFIG_BCMDHD_PREALLOC_PKTIDMAP
495 if (wlan_static_dhd_pktid_map
) {
496 kfree(wlan_static_dhd_pktid_map
);
499 if (wlan_static_dhd_pktid_ioctl_map
) {
500 kfree(wlan_static_dhd_pktid_ioctl_map
);
502 #endif /* CONFIG_BCMDHD_PREALLOC_PKTIDMAP */
504 if (wlan_static_dhd_wlfc_buf
) {
505 kfree(wlan_static_dhd_wlfc_buf
);
508 if (wlan_static_dhd_wlfc_hanger
) {
509 kfree(wlan_static_dhd_wlfc_hanger
);
511 #endif /* CONFIG_BCMDHD_PCIE */
512 if (wlan_static_dhd_info_buf
) {
513 kfree(wlan_static_dhd_info_buf
);
516 if (wlan_static_dhd_log_dump_buf
) {
517 kfree(wlan_static_dhd_log_dump_buf
);
520 if (wlan_static_dhd_log_dump_buf_ex
) {
521 kfree(wlan_static_dhd_log_dump_buf_ex
);
524 if (wlan_static_scan_buf1
) {
525 kfree(wlan_static_scan_buf1
);
528 if (wlan_static_scan_buf0
) {
529 kfree(wlan_static_scan_buf0
);
532 if (wlan_static_dhd_pktlog_dump_buf
) {
533 kfree(wlan_static_dhd_pktlog_dump_buf
);
536 pr_err("Failed to mem_alloc for WLAN\n");
538 for (i
= 0; i
< PREALLOC_WLAN_SEC_NUM
; i
++) {
539 if (wlan_mem_array
[i
].mem_ptr
) {
540 kfree(wlan_mem_array
[i
].mem_ptr
);
544 pr_err("Failed to skb_alloc for WLAN\n");
545 for (i
= 0; i
< WLAN_SKB_BUF_NUM
; i
++) {
546 dev_kfree_skb(wlan_static_skb
[i
]);
551 EXPORT_SYMBOL(dhd_exit_wlan_mem
);
552 #endif /* CONFIG_BROADCOM_WIFI_RESERVED_MEM */