• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * vendor/amlogic/wifi/dhd_static_buf.c
3  *
4  * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14  * more details.
15  *
16  */
17 
18 #define pr_fmt(fmt) "Wifi: %s: " fmt, __func__
19 
20 #include <linux/module.h>
21 #include <linux/kernel.h>
22 #include <linux/init.h>
23 #include <linux/platform_device.h>
24 #include <linux/delay.h>
25 #include <linux/err.h>
26 #include <linux/skbuff.h>
27 #include "dhd_static_buf.h"
28 
29 #define DHD_STATIC_VERSION_STR "100.10.545.3"
30 
31 #define BCMDHD_SDIO
32 #define BCMDHD_PCIE
33 
34 enum dhd_prealloc_index {
35     DHD_PREALLOC_PROT = 0,
36 #if defined(BCMDHD_SDIO)
37     DHD_PREALLOC_RXBUF = 1,
38     DHD_PREALLOC_DATABUF = 2,
39 #endif
40     DHD_PREALLOC_OSL_BUF = 3,
41     DHD_PREALLOC_SKB_BUF = 4,
42     DHD_PREALLOC_WIPHY_ESCAN0 = 5,
43     DHD_PREALLOC_WIPHY_ESCAN1 = 6,
44     DHD_PREALLOC_DHD_INFO = 7,
45     DHD_PREALLOC_DHD_WLFC_INFO = 8,
46 #ifdef BCMDHD_PCIE
47     DHD_PREALLOC_IF_FLOW_LKUP = 9,
48 #endif
49     DHD_PREALLOC_MEMDUMP_BUF = 10,
50     DHD_PREALLOC_MEMDUMP_RAM = 11,
51     DHD_PREALLOC_DHD_WLFC_HANGER = 12,
52     DHD_PREALLOC_PKTID_MAP = 13,
53     DHD_PREALLOC_PKTID_MAP_IOCTL = 14,
54     DHD_PREALLOC_DHD_LOG_DUMP_BUF = 15,
55     DHD_PREALLOC_DHD_LOG_DUMP_BUF_EX = 16,
56     DHD_PREALLOC_DHD_PKTLOG_DUMP_BUF = 17,
57     DHD_PREALLOC_STAT_REPORT_BUF = 18,
58     DHD_PREALLOC_WL_WEXT_INFO = 19,
59     DHD_PREALLOC_FW_VERBOSE_RING = 20,
60     DHD_PREALLOC_FW_EVENT_RING = 21,
61     DHD_PREALLOC_DHD_EVENT_RING = 22,
62     DHD_PREALLOC_NAN_EVENT_RING = 23,
63     DHD_PREALLOC_MAX
64 };
65 
66 #define STATIC_BUF_MAX_NUM 20
67 #define STATIC_BUF_SIZE (PAGE_SIZE * 2)
68 #define CUSTOM_LOG_DUMP_BUFSIZE_MB 4
69 #define DHD_PREALLOC_PROT_SIZE (16 * 1024)
70 #define DHD_PREALLOC_RXBUF_SIZE (24 * 1024)
71 #define DHD_PREALLOC_DATABUF_SIZE (64 * 1024)
72 #define DHD_PREALLOC_OSL_BUF_SIZE (STATIC_BUF_MAX_NUM * STATIC_BUF_SIZE)
73 #define DHD_PREALLOC_WIPHY_ESCAN0_SIZE (64 * 1024)
74 #define DHD_PREALLOC_DHD_INFO_SIZE (32 * 1024)
75 #define DHD_PREALLOC_MEMDUMP_RAM_SIZE (1290 * 1024)
76 #define DHD_PREALLOC_DHD_WLFC_HANGER_SIZE (73 * 1024)
77 #define DHD_PREALLOC_DHD_LOG_DUMP_BUF_SIZE (1024 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
78 #define DHD_PREALLOC_DHD_LOG_DUMP_BUF_EX_SIZE (8 * 1024)
79 #define DHD_PREALLOC_WL_WEXT_INFO_SIZE (70 * 1024)
80 #ifdef CONFIG_64BIT
81 #define DHD_PREALLOC_IF_FLOW_LKUP_SIZE (20 * 1024 * 2)
82 #else
83 #define DHD_PREALLOC_IF_FLOW_LKUP_SIZE (20 * 1024)
84 #endif
85 #define FW_VERBOSE_RING_SIZE (256 * 1024)
86 #define FW_EVENT_RING_SIZE (64 * 1024)
87 #define DHD_EVENT_RING_SIZE (64 * 1024)
88 #define NAN_EVENT_RING_SIZE (64 * 1024)
89 
90 #if defined(CONFIG_64BIT)
91 #define WLAN_DHD_INFO_BUF_SIZE (24 * 1024)
92 #define WLAN_DHD_WLFC_BUF_SIZE (64 * 1024)
93 #define WLAN_DHD_IF_FLOW_LKUP_SIZE (64 * 1024)
94 #else
95 #define WLAN_DHD_INFO_BUF_SIZE (16 * 1024)
96 #define WLAN_DHD_WLFC_BUF_SIZE (64 * 1024)
97 #define WLAN_DHD_IF_FLOW_LKUP_SIZE (20 * 1024)
98 #endif /* CONFIG_64BIT */
99 #define WLAN_DHD_MEMDUMP_SIZE (800 * 1024)
100 
101 #define DHD_SKB_1PAGE_BUFSIZE (PAGE_SIZE * 1)
102 #define DHD_SKB_2PAGE_BUFSIZE (PAGE_SIZE * 2)
103 #define DHD_SKB_4PAGE_BUFSIZE (PAGE_SIZE * 4)
104 
105 #define DHD_SKB_1PAGE_BUF_NUM 8
106 #define DHD_SKB_2PAGE_BUF_NUM 64
107 #define DHD_SKB_4PAGE_BUF_NUM 1
108 
109 /* The number is defined in linux_osl.c
110  * WLAN_SKB_1_2PAGE_BUF_NUM => STATIC_PKT_1_2PAGE_NUM
111  * WLAN_SKB_BUF_NUM => STATIC_PKT_MAX_NUM
112  */
113 #define WLAN_SKB_1_2PAGE_BUF_NUM ((DHD_SKB_1PAGE_BUF_NUM) + (DHD_SKB_2PAGE_BUF_NUM))
114 #define WLAN_SKB_BUF_NUM ((WLAN_SKB_1_2PAGE_BUF_NUM) + (DHD_SKB_4PAGE_BUF_NUM))
115 
116 void *wlan_static_prot;
117 void *wlan_static_rxbuf;
118 void *wlan_static_databuf;
119 void *wlan_static_osl_buf;
120 void *wlan_static_scan_buf0;
121 void *wlan_static_scan_buf1;
122 void *wlan_static_dhd_info_buf;
123 void *wlan_static_dhd_wlfc_info_buf;
124 void *wlan_static_if_flow_lkup;
125 void *wlan_static_dhd_memdump_ram_buf;
126 void *wlan_static_dhd_wlfc_hanger_buf;
127 void *wlan_static_dhd_log_dump_buf;
128 void *wlan_static_dhd_log_dump_buf_ex;
129 void *wlan_static_wl_escan_info_buf;
130 void *wlan_static_fw_verbose_ring_buf;
131 void *wlan_static_fw_event_ring_buf;
132 void *wlan_static_dhd_event_ring_buf;
133 void *wlan_static_nan_event_ring_buf;
134 
135 static struct sk_buff *wlan_static_skb[WLAN_SKB_BUF_NUM];
136 
bcmdhd_mem_prealloc(int section,unsigned long size)137 void *bcmdhd_mem_prealloc(int section, unsigned long size)
138 {
139     pr_info("sectoin %d, size %ld\n", section, size);
140     if (section == DHD_PREALLOC_PROT) {
141         return wlan_static_prot;
142     }
143 
144 #if defined(BCMDHD_SDIO)
145     if (section == DHD_PREALLOC_RXBUF) {
146         return wlan_static_rxbuf;
147     }
148 
149     if (section == DHD_PREALLOC_DATABUF) {
150         return wlan_static_databuf;
151     }
152 #endif /* BCMDHD_SDIO */
153 
154     if (section == DHD_PREALLOC_SKB_BUF) {
155         return wlan_static_skb;
156     }
157 
158     if (section == DHD_PREALLOC_WIPHY_ESCAN0) {
159         return wlan_static_scan_buf0;
160     }
161 
162     if (section == DHD_PREALLOC_WIPHY_ESCAN1) {
163         return wlan_static_scan_buf1;
164     }
165 
166     if (section == DHD_PREALLOC_OSL_BUF) {
167         if (size > DHD_PREALLOC_OSL_BUF_SIZE) {
168             pr_err("request OSL_BUF(%lu) > %ld\n", size, DHD_PREALLOC_OSL_BUF_SIZE);
169             return NULL;
170         }
171         return wlan_static_osl_buf;
172     }
173 
174     if (section == DHD_PREALLOC_DHD_INFO) {
175         if (size > DHD_PREALLOC_DHD_INFO_SIZE) {
176             pr_err("request DHD_INFO size(%lu) > %d\n", size, DHD_PREALLOC_DHD_INFO_SIZE);
177             return NULL;
178         }
179         return wlan_static_dhd_info_buf;
180     }
181     if (section == DHD_PREALLOC_DHD_WLFC_INFO) {
182         if (size > WLAN_DHD_WLFC_BUF_SIZE) {
183             pr_err("request DHD_WLFC_INFO size(%lu) > %d\n", size, WLAN_DHD_WLFC_BUF_SIZE);
184             return NULL;
185         }
186         return wlan_static_dhd_wlfc_info_buf;
187     }
188 #ifdef BCMDHD_PCIE
189     if (section == DHD_PREALLOC_IF_FLOW_LKUP) {
190         if (size > DHD_PREALLOC_IF_FLOW_LKUP_SIZE) {
191             pr_err("request DHD_IF_FLOW_LKUP size(%lu) > %d\n", size, DHD_PREALLOC_IF_FLOW_LKUP_SIZE);
192             return NULL;
193         }
194 
195         return wlan_static_if_flow_lkup;
196     }
197 #endif /* BCMDHD_PCIE */
198     if (section == DHD_PREALLOC_MEMDUMP_RAM) {
199         if (size > DHD_PREALLOC_MEMDUMP_RAM_SIZE) {
200             pr_err("request DHD_PREALLOC_MEMDUMP_RAM_SIZE(%lu) > %d\n", size, DHD_PREALLOC_MEMDUMP_RAM_SIZE);
201             return NULL;
202         }
203 
204         return wlan_static_dhd_memdump_ram_buf;
205     }
206     if (section == DHD_PREALLOC_DHD_WLFC_HANGER) {
207         if (size > DHD_PREALLOC_DHD_WLFC_HANGER_SIZE) {
208             pr_err("request DHD_WLFC_HANGER size(%lu) > %d\n", size, DHD_PREALLOC_DHD_WLFC_HANGER_SIZE);
209             return NULL;
210         }
211         return wlan_static_dhd_wlfc_hanger_buf;
212     }
213     if (section == DHD_PREALLOC_DHD_LOG_DUMP_BUF) {
214         if (size > DHD_PREALLOC_DHD_LOG_DUMP_BUF_SIZE) {
215             pr_err("request DHD_PREALLOC_DHD_LOG_DUMP_BUF_SIZE(%lu) > %d\n", size, DHD_PREALLOC_DHD_LOG_DUMP_BUF_SIZE);
216             return NULL;
217         }
218 
219         return wlan_static_dhd_log_dump_buf;
220     }
221     if (section == DHD_PREALLOC_DHD_LOG_DUMP_BUF_EX) {
222         if (size > DHD_PREALLOC_DHD_LOG_DUMP_BUF_EX_SIZE) {
223             pr_err("request DHD_PREALLOC_DHD_LOG_DUMP_BUF_EX_SIZE(%lu) > %d\n", size,
224                    DHD_PREALLOC_DHD_LOG_DUMP_BUF_EX_SIZE);
225             return NULL;
226         }
227 
228         return wlan_static_dhd_log_dump_buf_ex;
229     }
230     if (section == DHD_PREALLOC_WL_WEXT_INFO) {
231         if (size > DHD_PREALLOC_WL_WEXT_INFO_SIZE) {
232             pr_err("request DHD_PREALLOC_WL_WEXT_INFO_SIZE(%lu) > %d\n", size, DHD_PREALLOC_WL_WEXT_INFO_SIZE);
233             return NULL;
234         }
235 
236         return wlan_static_wl_escan_info_buf;
237     }
238     if (section == DHD_PREALLOC_FW_VERBOSE_RING) {
239         if (size > FW_VERBOSE_RING_SIZE) {
240             pr_err("request DHD_PREALLOC_FW_VERBOSE_RING(%lu) > %d\n", size, FW_VERBOSE_RING_SIZE);
241             return NULL;
242         }
243 
244         return wlan_static_fw_verbose_ring_buf;
245     }
246     if (section == DHD_PREALLOC_FW_EVENT_RING) {
247         if (size > FW_EVENT_RING_SIZE) {
248             pr_err("request DHD_PREALLOC_FW_EVENT_RING(%lu) > %d\n", size, FW_EVENT_RING_SIZE);
249             return NULL;
250         }
251 
252         return wlan_static_fw_event_ring_buf;
253     }
254     if (section == DHD_PREALLOC_DHD_EVENT_RING) {
255         if (size > DHD_EVENT_RING_SIZE) {
256             pr_err("request DHD_PREALLOC_DHD_EVENT_RING(%lu) > %d\n", size, DHD_EVENT_RING_SIZE);
257             return NULL;
258         }
259 
260         return wlan_static_dhd_event_ring_buf;
261     }
262     if (section == DHD_PREALLOC_NAN_EVENT_RING) {
263         if (size > NAN_EVENT_RING_SIZE) {
264             pr_err("request DHD_PREALLOC_NAN_EVENT_RING(%lu) > %d\n", size, NAN_EVENT_RING_SIZE);
265             return NULL;
266         }
267 
268         return wlan_static_nan_event_ring_buf;
269     }
270     if ((section < 0) || (section > DHD_PREALLOC_MAX)) {
271         pr_err("request section id(%d) is out of max index %d\n", section, DHD_PREALLOC_MAX);
272     }
273 
274     pr_err("%s: failed to alloc section %d, size=%ld\n", __func__, section, size);
275 
276     return NULL;
277 }
278 EXPORT_SYMBOL(bcmdhd_mem_prealloc);
279 
bcmdhd_init_wlan_mem(void)280 int bcmdhd_init_wlan_mem(void)
281 {
282     int i;
283     int j;
284     pr_info("%s(): %s\n", __func__, DHD_STATIC_VERSION_STR);
285 
286     for (i = 0; i < DHD_SKB_1PAGE_BUF_NUM; i++) {
287         wlan_static_skb[i] = dev_alloc_skb(DHD_SKB_1PAGE_BUFSIZE);
288         if (!wlan_static_skb[i]) {
289             goto err_skb_alloc;
290         }
291     }
292 
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);
295         if (!wlan_static_skb[i]) {
296             goto err_skb_alloc;
297         }
298     }
299 
300 #if defined(BCMDHD_SDIO)
301     wlan_static_skb[i] = dev_alloc_skb(DHD_SKB_4PAGE_BUFSIZE);
302     if (!wlan_static_skb[i]) {
303         goto err_skb_alloc;
304     }
305 #endif /* BCMDHD_SDIO */
306 
307     wlan_static_prot = kmalloc(DHD_PREALLOC_PROT_SIZE, GFP_KERNEL);
308     if (!wlan_static_prot) {
309         goto err_mem_alloc;
310     }
311 
312 #if defined(BCMDHD_SDIO)
313     wlan_static_rxbuf = kmalloc(DHD_PREALLOC_RXBUF_SIZE, GFP_KERNEL);
314     if (!wlan_static_rxbuf) {
315         goto err_mem_alloc;
316     }
317 
318     wlan_static_databuf = kmalloc(DHD_PREALLOC_DATABUF_SIZE, GFP_KERNEL);
319     if (!wlan_static_databuf) {
320         goto err_mem_alloc;
321     }
322 #endif /* BCMDHD_SDIO */
323 
324     wlan_static_osl_buf = kmalloc(DHD_PREALLOC_OSL_BUF_SIZE, GFP_KERNEL);
325     if (!wlan_static_osl_buf) {
326         goto err_mem_alloc;
327     }
328 
329     wlan_static_scan_buf0 = kmalloc(DHD_PREALLOC_WIPHY_ESCAN0_SIZE, GFP_KERNEL);
330     if (!wlan_static_scan_buf0) {
331         goto err_mem_alloc;
332     }
333 
334     wlan_static_dhd_info_buf = kmalloc(DHD_PREALLOC_DHD_INFO_SIZE, GFP_KERNEL);
335     if (!wlan_static_dhd_info_buf) {
336         goto err_mem_alloc;
337     }
338 
339     wlan_static_dhd_wlfc_info_buf = kmalloc(WLAN_DHD_WLFC_BUF_SIZE, GFP_KERNEL);
340     if (!wlan_static_dhd_wlfc_info_buf) {
341         goto err_mem_alloc;
342     }
343 
344 #ifdef BCMDHD_PCIE
345     wlan_static_if_flow_lkup = kmalloc(DHD_PREALLOC_IF_FLOW_LKUP_SIZE, GFP_KERNEL);
346     if (!wlan_static_if_flow_lkup) {
347         goto err_mem_alloc;
348     }
349 #endif /* BCMDHD_PCIE */
350 
351     wlan_static_dhd_memdump_ram_buf = kmalloc(DHD_PREALLOC_MEMDUMP_RAM_SIZE, GFP_KERNEL);
352     if (!wlan_static_dhd_memdump_ram_buf) {
353         goto err_mem_alloc;
354     }
355 
356     wlan_static_dhd_wlfc_hanger_buf = kmalloc(DHD_PREALLOC_DHD_WLFC_HANGER_SIZE, GFP_KERNEL);
357     if (!wlan_static_dhd_wlfc_hanger_buf) {
358         goto err_mem_alloc;
359     }
360 
361     wlan_static_dhd_log_dump_buf = kmalloc(DHD_PREALLOC_DHD_LOG_DUMP_BUF_SIZE, GFP_KERNEL);
362     if (!wlan_static_dhd_log_dump_buf) {
363         goto err_mem_alloc;
364     }
365 
366     wlan_static_dhd_log_dump_buf_ex = kmalloc(DHD_PREALLOC_DHD_LOG_DUMP_BUF_EX_SIZE, GFP_KERNEL);
367     if (!wlan_static_dhd_log_dump_buf_ex) {
368         goto err_mem_alloc;
369     }
370 
371     wlan_static_wl_escan_info_buf = kmalloc(DHD_PREALLOC_WL_WEXT_INFO_SIZE, GFP_KERNEL);
372     if (!wlan_static_wl_escan_info_buf) {
373         goto err_mem_alloc;
374     }
375 
376     wlan_static_fw_verbose_ring_buf = kmalloc(FW_VERBOSE_RING_SIZE, GFP_KERNEL);
377     if (!wlan_static_fw_verbose_ring_buf) {
378         goto err_mem_alloc;
379     }
380 
381     wlan_static_fw_event_ring_buf = kmalloc(FW_EVENT_RING_SIZE, GFP_KERNEL);
382     if (!wlan_static_fw_event_ring_buf) {
383         goto err_mem_alloc;
384     }
385 
386     wlan_static_dhd_event_ring_buf = kmalloc(DHD_EVENT_RING_SIZE, GFP_KERNEL);
387     if (!wlan_static_dhd_event_ring_buf) {
388         goto err_mem_alloc;
389     }
390 
391     wlan_static_nan_event_ring_buf = kmalloc(NAN_EVENT_RING_SIZE, GFP_KERNEL);
392     if (!wlan_static_nan_event_ring_buf) {
393         goto err_mem_alloc;
394     }
395 
396     pr_info("bcmdhd_init_wlan_mem prealloc ok\n");
397     return 0;
398 
399 err_mem_alloc:
400 
401     if (wlan_static_prot) {
402         kfree(wlan_static_prot);
403     }
404 
405 #if defined(BCMDHD_SDIO)
406     if (wlan_static_rxbuf) {
407         kfree(wlan_static_rxbuf);
408     }
409 
410     if (wlan_static_databuf) {
411         kfree(wlan_static_databuf);
412     }
413 #endif /* BCMDHD_SDIO */
414 
415     if (wlan_static_osl_buf) {
416         kfree(wlan_static_osl_buf);
417     }
418 
419     if (wlan_static_scan_buf0) {
420         kfree(wlan_static_scan_buf0);
421     }
422 
423     if (wlan_static_scan_buf1) {
424         kfree(wlan_static_scan_buf1);
425     }
426 
427     if (wlan_static_dhd_info_buf) {
428         kfree(wlan_static_dhd_info_buf);
429     }
430 
431     if (wlan_static_dhd_wlfc_info_buf) {
432         kfree(wlan_static_dhd_wlfc_info_buf);
433     }
434 
435 #ifdef BCMDHD_PCIE
436     if (wlan_static_if_flow_lkup) {
437         kfree(wlan_static_if_flow_lkup);
438     }
439 #endif /* BCMDHD_PCIE */
440 
441     if (wlan_static_dhd_memdump_ram_buf) {
442         kfree(wlan_static_dhd_memdump_ram_buf);
443     }
444 
445     if (wlan_static_dhd_wlfc_hanger_buf) {
446         kfree(wlan_static_dhd_wlfc_hanger_buf);
447     }
448 
449     if (wlan_static_dhd_log_dump_buf) {
450         kfree(wlan_static_dhd_log_dump_buf);
451     }
452 
453     if (wlan_static_dhd_log_dump_buf_ex) {
454         kfree(wlan_static_dhd_log_dump_buf_ex);
455     }
456 
457     if (wlan_static_wl_escan_info_buf) {
458         kfree(wlan_static_wl_escan_info_buf);
459     }
460 
461 #ifdef BCMDHD_PCIE
462     if (wlan_static_fw_verbose_ring_buf) {
463         kfree(wlan_static_fw_verbose_ring_buf);
464     }
465 
466     if (wlan_static_fw_event_ring_buf) {
467         kfree(wlan_static_fw_event_ring_buf);
468     }
469 
470     if (wlan_static_dhd_event_ring_buf) {
471         kfree(wlan_static_dhd_event_ring_buf);
472     }
473 
474     if (wlan_static_nan_event_ring_buf) {
475         kfree(wlan_static_nan_event_ring_buf);
476     }
477 #endif /* BCMDHD_PCIE */
478 
479     pr_err("%s: Failed to mem_alloc for WLAN\n", __func__);
480 
481     i = WLAN_SKB_BUF_NUM;
482 
483 err_skb_alloc:
484     pr_err("%s: Failed to skb_alloc for WLAN\n", __func__);
485     for (j = 0; j < i; j++) {
486         dev_kfree_skb(wlan_static_skb[j]);
487     }
488 
489     return -ENOMEM;
490 }
491 EXPORT_SYMBOL(bcmdhd_init_wlan_mem);
492 MODULE_LICENSE("GPL");
493 MODULE_AUTHOR("AMLOGIC");
494 MODULE_DESCRIPTION("wifi device tree driver");
495