summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/bcmdhd.1.88.45.x.cn/dhd_static_buf.c
blob: 31bcde3738692ba07a90324362853aa78074f35b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h> 
#include <linux/platform_device.h> 
#include <linux/delay.h> 
#include <linux/err.h> 
#include <linux/skbuff.h> 
#include <linux/wlan_plat.h> 

#define CONFIG_BROADCOM_WIFI_RESERVED_MEM

#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM

#define WLAN_STATIC_PKT_BUF			4
#define WLAN_STATIC_SCAN_BUF0		5
#define WLAN_STATIC_SCAN_BUF1		6
#define WLAN_STATIC_DHD_INFO		7
#define PREALLOC_WLAN_SEC_NUM		5
#define PREALLOC_WLAN_BUF_NUM		160
#define PREALLOC_WLAN_SECTION_HEADER	24

#define WLAN_SECTION_SIZE_0	(PREALLOC_WLAN_BUF_NUM * 128)
#define WLAN_SECTION_SIZE_1	(PREALLOC_WLAN_BUF_NUM * 128)
#define WLAN_SECTION_SIZE_2	(PREALLOC_WLAN_BUF_NUM * 512)
#define WLAN_SECTION_SIZE_3	(PREALLOC_WLAN_BUF_NUM * 1024)
#define WLAN_SECTION_SIZE_7	(PREALLOC_WLAN_BUF_NUM * 128)

#define DHD_SKB_HDRSIZE			336
#define DHD_SKB_1PAGE_BUFSIZE	((PAGE_SIZE*1)-DHD_SKB_HDRSIZE)
#define DHD_SKB_2PAGE_BUFSIZE	((PAGE_SIZE*2)-DHD_SKB_HDRSIZE)
#define DHD_SKB_4PAGE_BUFSIZE	((PAGE_SIZE*4)-DHD_SKB_HDRSIZE)

#define WLAN_SKB_BUF_NUM	17

static struct sk_buff *wlan_static_skb[WLAN_SKB_BUF_NUM];

struct wlan_mem_prealloc {
	void *mem_ptr;
	unsigned long size;
};

static struct wlan_mem_prealloc wlan_mem_array[PREALLOC_WLAN_SEC_NUM] = {
	{NULL, (WLAN_SECTION_SIZE_0 + PREALLOC_WLAN_SECTION_HEADER)},
	{NULL, (WLAN_SECTION_SIZE_1 + PREALLOC_WLAN_SECTION_HEADER)},
	{NULL, (WLAN_SECTION_SIZE_2 + PREALLOC_WLAN_SECTION_HEADER)},
	{NULL, (WLAN_SECTION_SIZE_3 + PREALLOC_WLAN_SECTION_HEADER)},
	{NULL, (WLAN_SECTION_SIZE_7 + PREALLOC_WLAN_SECTION_HEADER)}
};

void *wlan_static_scan_buf0;
void *wlan_static_scan_buf1;
void *bcmdhd_mem_prealloc(int section, unsigned long size)
{
	if (section == WLAN_STATIC_PKT_BUF) {
		printk("1 %s: section=%d, wlan_static_skb=%p\n",
			__FUNCTION__, section, wlan_static_skb);
		return wlan_static_skb;
	}
	if (section == WLAN_STATIC_SCAN_BUF0) {
		printk("2 %s: section=%d, wlan_static_scan_buf0=%p\n",
			__FUNCTION__, section, wlan_static_scan_buf0);
		return wlan_static_scan_buf0;
	}
	if (section == WLAN_STATIC_SCAN_BUF1) {
		printk("3 %s: section=%d, wlan_static_scan_buf1=%p\n",
			__FUNCTION__, section, wlan_static_scan_buf1);
		return wlan_static_scan_buf1;
	}
	if (section == WLAN_STATIC_DHD_INFO) {
		printk("4 %s: section=%d, wlan_mem_array[4]=%p\n",
			__FUNCTION__, section, wlan_mem_array[4].mem_ptr);
		return wlan_mem_array[4].mem_ptr;
	}
	if ((section < 0) || (section > PREALLOC_WLAN_SEC_NUM)) {
		printk("5 %s: out of section %d\n", __FUNCTION__, section);
		return NULL;
	}

	if (wlan_mem_array[section].size < size) {
		printk("6 %s: wlan_mem_array[section].size=%d, size=%d\n",
			__FUNCTION__, wlan_mem_array[section].size, size);
		return NULL;
	}
	printk("7 %s: wlan_mem_array[section].mem_ptr=%p, size=%d\n",
		__FUNCTION__, wlan_mem_array[section], size);

	return wlan_mem_array[section].mem_ptr;
}

EXPORT_SYMBOL(bcmdhd_mem_prealloc);

int bcmdhd_init_wlan_mem(void) 
{
	int i;
	int j;

	for (i=0; i<8; i++) {
		wlan_static_skb[i] = dev_alloc_skb(DHD_SKB_1PAGE_BUFSIZE);
		if (!wlan_static_skb[i])
			goto err_skb_alloc; 
		printk("1 %s: wlan_static_skb[%d]=%p, size=%d\n",
			__FUNCTION__, i, wlan_static_skb[i], DHD_SKB_1PAGE_BUFSIZE);
	}

	for (; i<16; i++) {
		wlan_static_skb[i] = dev_alloc_skb(DHD_SKB_2PAGE_BUFSIZE);
		if (!wlan_static_skb[i])
			goto err_skb_alloc; 
		printk("2 %s: wlan_static_skb[%d]=%p, size=%d\n",
			__FUNCTION__, i, wlan_static_skb[i], DHD_SKB_2PAGE_BUFSIZE);
	}

	wlan_static_skb[i] = dev_alloc_skb(DHD_SKB_4PAGE_BUFSIZE);
	if (!wlan_static_skb[i])
		goto err_skb_alloc; 
	printk("3 %s: wlan_static_skb[%d]=%p, size=%d\n",
		__FUNCTION__, i, wlan_static_skb[i], DHD_SKB_4PAGE_BUFSIZE);

	for (i=0; i<PREALLOC_WLAN_SEC_NUM; i++) {
		wlan_mem_array[i].mem_ptr =
				kmalloc(wlan_mem_array[i].size, GFP_KERNEL);

		if (!wlan_mem_array[i].mem_ptr)
			goto err_mem_alloc;
		printk("4 %s: wlan_mem_array[%d]=%p, size=%d\n",
			__FUNCTION__, i, wlan_static_skb[i], wlan_mem_array[i].size);
	}

	wlan_static_scan_buf0 = kmalloc (65536, GFP_KERNEL);
	if(!wlan_static_scan_buf0)
		goto err_mem_alloc;
	printk("5 %s: wlan_static_scan_buf0=%p, size=%d\n",
		__FUNCTION__, wlan_static_scan_buf0, 65536);

	wlan_static_scan_buf1 = kmalloc (65536, GFP_KERNEL);
	if(!wlan_static_scan_buf1)
		goto err_mem_alloc;
	printk("6 %s: wlan_static_scan_buf1=%p, size=%d\n",
		__FUNCTION__, wlan_static_scan_buf1, 65536);

	printk("%s: WIFI MEM Allocated\n", __FUNCTION__);
	return 0;

err_mem_alloc:
	pr_err("Failed to mem_alloc for WLAN\n");
	for (j=0; j<i; j++)
		kfree(wlan_mem_array[j].mem_ptr);

	i = WLAN_SKB_BUF_NUM;

err_skb_alloc:
	pr_err("Failed to skb_alloc for WLAN\n");
	for (j=0; j<i; j++)
		dev_kfree_skb(wlan_static_skb[j]);

	return -ENOMEM;
}
#endif /* CONFIG_BROADCOM_WIFI_RESERVED_MEM */

static int __init bcmdhd_wlan_init(void)
{
	printk("%s()\n", __FUNCTION__);

#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
	bcmdhd_init_wlan_mem();
#endif

	return 0;
}

__initcall(bcmdhd_wlan_init);