9790411d1cf74195a8dfed7c23a6897035e06078
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / esp8089 / esp_premalloc / esp_mem.c
1 #ifdef ESP_PRE_MEM
2
3 #include <linux/slab.h>
4 #include <linux/module.h>
5 #include <linux/skbuff.h>
6 #include <linux/types.h>
7 #include <linux/delay.h>
8
9 #include "esp_mem.h"
10 #include "esp_log.h"
11
12 static u8 *gl_tx_aggr_buf;
13
14 static struct esp_skb_elem gl_sip_skb_arr[SIP_SKB_ARR_NUM];
15
16 int esp_pre_alloc_sip_skb_arr(void)
17 {
18         int i;
19
20         for (i = 0; i < SIP_SKB_ARR_NUM; i++) {
21                 gl_sip_skb_arr[i].skb_p = NULL;
22                 gl_sip_skb_arr[i].skb_size = 0;
23                 atomic_set(&gl_sip_skb_arr[i].inuse, 0);
24         }
25                 
26         /* 8K */
27         for (i = SIP_SKB_SPOS_8K; i < (SIP_SKB_SPOS_8K + SIP_SKB_NUM_8K); i++) {
28                 gl_sip_skb_arr[i].skb_p = __dev_alloc_skb(SIP_SKB_SIZE_8K, GFP_KERNEL);
29                 if (gl_sip_skb_arr[i].skb_p == NULL)
30                         goto _mem_err;
31                 gl_sip_skb_arr[i].skb_size = SIP_SKB_SIZE_8K;
32         }
33
34         /* 16K */
35         for (i = SIP_SKB_SPOS_16K; i < (SIP_SKB_SPOS_16K + SIP_SKB_NUM_16K); i++) {
36                 gl_sip_skb_arr[i].skb_p = __dev_alloc_skb(SIP_SKB_SIZE_16K, GFP_KERNEL);
37                 if (gl_sip_skb_arr[i].skb_p == NULL)
38                         goto _mem_err;
39                 gl_sip_skb_arr[i].skb_size = SIP_SKB_SIZE_16K;
40         }
41
42         /* 32K */
43         for (i = SIP_SKB_SPOS_32K; i < (SIP_SKB_SPOS_32K + SIP_SKB_NUM_32K); i++) {
44                 gl_sip_skb_arr[i].skb_p = __dev_alloc_skb(SIP_SKB_SIZE_32K, GFP_KERNEL);
45                 if (gl_sip_skb_arr[i].skb_p == NULL)
46                         goto _mem_err;
47                 gl_sip_skb_arr[i].skb_size = SIP_SKB_SIZE_32K;
48         }
49
50         return 0;
51
52 _mem_err:
53         loge("alloc sip skb arr [%d] failed\n", i);
54         esp_pre_free_sip_skb_arr();
55         return -ENOMEM;
56 }
57
58 void esp_pre_free_sip_skb_arr(void)
59 {
60         int i;
61
62         for (i = 0; i < SIP_SKB_ARR_NUM; i++) {
63                 if (gl_sip_skb_arr[i].skb_p)
64                         kfree_skb(gl_sip_skb_arr[i].skb_p);
65
66                 gl_sip_skb_arr[i].skb_p = NULL;
67                 gl_sip_skb_arr[i].skb_size = 0;
68                 atomic_set(&gl_sip_skb_arr[i].inuse, 0);
69         }
70 }
71
72 #ifdef ESP_EXT_SHOW_SKB
73 void esp_pre_sip_skb_show(void)
74 {
75         int i;
76
77         for (i = 0; i < SIP_SKB_ARR_NUM; i++)
78                 logi("skb arr[%d]: p[%p] size[%d]  inuse [%d]\n", i, gl_sip_skb_arr[i].skb_p, gl_sip_skb_arr[i].skb_size, atomic_read(&gl_sip_skb_arr[i].inuse));
79         
80 }
81 EXPORT_SYMBOL(esp_pre_sip_skb_show);
82 #endif
83
84 struct sk_buff *esp_get_sip_skb(int size)
85 {
86         int i;
87         int retry = 10;
88
89         do {
90                 if (size <= SIP_SKB_SIZE_8K) {
91                         for (i = SIP_SKB_SPOS_8K; i < (SIP_SKB_SPOS_8K + SIP_SKB_NUM_8K); i++) {
92                                 if (atomic_read(&gl_sip_skb_arr[i].inuse) == 0) {
93                                         atomic_set(&gl_sip_skb_arr[i].inuse, 1);
94                                         logd("%s skb_alloc [%d]\n", __func__, i);
95                                         return gl_sip_skb_arr[i].skb_p;
96                                 } 
97                         }
98                 } else if (size <= SIP_SKB_SIZE_16K) {
99                         for (i = SIP_SKB_SPOS_16K; i < (SIP_SKB_SPOS_16K + SIP_SKB_NUM_16K); i++) {
100                                 if (atomic_read(&gl_sip_skb_arr[i].inuse) == 0) {
101                                         atomic_set(&gl_sip_skb_arr[i].inuse, 1);
102                                         logd("%s skb_alloc [%d]\n", __func__, i);
103                                         return gl_sip_skb_arr[i].skb_p;
104                                 } 
105                         }
106                 } else if (size <= SIP_SKB_SIZE_32K) {
107                         for (i = SIP_SKB_SPOS_32K; i < (SIP_SKB_SPOS_32K + SIP_SKB_NUM_32K); i++) {
108                                 if (atomic_read(&gl_sip_skb_arr[i].inuse) == 0) {
109                                         atomic_set(&gl_sip_skb_arr[i].inuse, 1);
110                                         logd("%s skb_alloc [%d]\n", __func__, i);
111                                         return gl_sip_skb_arr[i].skb_p;
112                                 } 
113                         }
114                 } else {
115                         loge("size[%d] is too large, get skb failed\n", size);
116                         break;
117                 }
118
119                 mdelay(1);
120         } while (--retry > 0);
121
122         if (retry <= 0)
123                 loge("skb is all in use, size[%d]  get skb failed\n", size);
124
125         return NULL;
126 }
127 EXPORT_SYMBOL(esp_get_sip_skb);
128
129 void esp_put_sip_skb(struct sk_buff **skb)
130 {
131         int i;
132
133         for (i = 0; i < SIP_SKB_ARR_NUM; i++) {
134                 if (gl_sip_skb_arr[i].skb_p == *skb) {
135                         gl_sip_skb_arr[i].skb_p->data = gl_sip_skb_arr[i].skb_p->head;
136                         gl_sip_skb_arr[i].skb_p->tail = gl_sip_skb_arr[i].skb_p->head;
137                         gl_sip_skb_arr[i].skb_p->data_len = 0;
138                         gl_sip_skb_arr[i].skb_p->len = 0;
139                         skb_trim(gl_sip_skb_arr[i].skb_p, 0);
140                         atomic_set(&gl_sip_skb_arr[i].inuse, 0);
141                         break;
142                 }
143         }
144
145         if (i == SIP_SKB_ARR_NUM)
146                 loge("warnning : no skb to put\n");
147
148         *skb = NULL; /* set input skb NULL */
149
150         logd("%s skb_free [%d]\n", __func__, i);
151 }
152 EXPORT_SYMBOL(esp_put_sip_skb);
153
154 void *esp_pre_alloc_tx_aggr_buf(void)
155 {
156         int po;
157
158         po = get_order(TX_AGGR_BUF_SIZE);
159         gl_tx_aggr_buf = (u8 *)__get_free_pages(GFP_ATOMIC, po);
160
161         if (gl_tx_aggr_buf == NULL) {
162                 loge("%s no mem for gl_tx_aggr_buf! \n", __func__);
163                 return NULL;
164         }
165
166         return gl_tx_aggr_buf;
167 }
168
169 void esp_pre_free_tx_aggr_buf(void)
170 {
171         int po;
172
173         if (!gl_tx_aggr_buf) {
174                 loge("%s need not free gl_tx_aggr_buf! \n", __func__);
175                 return;
176         }
177
178         po = get_order(TX_AGGR_BUF_SIZE);
179         free_pages((unsigned long)gl_tx_aggr_buf, po);
180         gl_tx_aggr_buf =  NULL;
181 }
182
183 u8* esp_get_tx_aggr_buf(void)
184 {
185         if (!gl_tx_aggr_buf) {
186                 loge(KERN_ERR "%s gl_tx_aggr_buf is NULL failed! \n", __func__);
187                 return NULL;
188         }
189
190         return gl_tx_aggr_buf;
191 }
192 EXPORT_SYMBOL(esp_get_tx_aggr_buf);
193
194 void esp_put_tx_aggr_buf(u8 **p)
195 {
196         *p = NULL; /*input point which return by get~() , then set it null */
197 }
198 EXPORT_SYMBOL(esp_put_tx_aggr_buf);
199
200
201 int esp_indi_pre_mem_init()
202 {
203         int err = 0;
204         
205         if (esp_pre_alloc_tx_aggr_buf() == NULL)
206                 err = -ENOMEM;
207
208         if (esp_pre_alloc_sip_skb_arr() != 0)
209                 err = -ENOMEM;
210
211         return err;
212 }
213
214 void esp_indi_pre_mem_deinit()
215 {
216         esp_pre_free_tx_aggr_buf();
217         esp_pre_free_sip_skb_arr();
218 }
219
220 #endif /* ESP_PRE_MEM */