1*4882a593Smuzhiyun /******************************************************************************
2*4882a593Smuzhiyun *
3*4882a593Smuzhiyun * Copyright(c) 2007 - 2017 Realtek Corporation.
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * This program is free software; you can redistribute it and/or modify it
6*4882a593Smuzhiyun * under the terms of version 2 of the GNU General Public License as
7*4882a593Smuzhiyun * published by the Free Software Foundation.
8*4882a593Smuzhiyun *
9*4882a593Smuzhiyun * This program is distributed in the hope that it will be useful, but WITHOUT
10*4882a593Smuzhiyun * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11*4882a593Smuzhiyun * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12*4882a593Smuzhiyun * more details.
13*4882a593Smuzhiyun *
14*4882a593Smuzhiyun *****************************************************************************/
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun #define _OSDEP_SERVICE_C_
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun #include <drv_types.h>
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun #define RT_TAG '1178'
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun #ifdef DBG_MEMORY_LEAK
24*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
25*4882a593Smuzhiyun atomic_t _malloc_cnt = ATOMIC_INIT(0);
26*4882a593Smuzhiyun atomic_t _malloc_size = ATOMIC_INIT(0);
27*4882a593Smuzhiyun #endif
28*4882a593Smuzhiyun #endif /* DBG_MEMORY_LEAK */
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun #ifdef DBG_MEM_ERR_FREE
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun #if (KERNEL_VERSION(3, 7, 0) <= LINUX_VERSION_CODE)
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun #define DBG_MEM_HASHBITS 10
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun #define DBG_MEM_TYPE_PHY 0
38*4882a593Smuzhiyun #define DBG_MEM_TYPE_VIR 1
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun /*
41*4882a593Smuzhiyun * DBG_MEM_ERR_FREE is only for the debug purpose.
42*4882a593Smuzhiyun *
43*4882a593Smuzhiyun * There is the limitation that this mechanism only can
44*4882a593Smuzhiyun * support one wifi device, and has problem if there
45*4882a593Smuzhiyun * are two or more wifi devices with one driver on
46*4882a593Smuzhiyun * the same system. It's because dbg_mem_ht is global
47*4882a593Smuzhiyun * variable, and if we move this dbg_mem_ht into struct
48*4882a593Smuzhiyun * dvobj_priv to support more wifi devices, the memory
49*4882a593Smuzhiyun * allocation functions, like rtw_malloc(), need to have
50*4882a593Smuzhiyun * the parameter dvobj to get relative hash table, and
51*4882a593Smuzhiyun * then it is the huge changes for the driver currently.
52*4882a593Smuzhiyun *
53*4882a593Smuzhiyun */
54*4882a593Smuzhiyun struct hlist_head dbg_mem_ht[1 << DBG_MEM_HASHBITS];
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun struct hash_mem {
57*4882a593Smuzhiyun void *mem;
58*4882a593Smuzhiyun int sz;
59*4882a593Smuzhiyun int type;
60*4882a593Smuzhiyun struct hlist_node node;
61*4882a593Smuzhiyun };
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun #endif /* LINUX_VERSION_CODE */
64*4882a593Smuzhiyun
rtw_dbg_mem_init(void)65*4882a593Smuzhiyun void rtw_dbg_mem_init(void)
66*4882a593Smuzhiyun {
67*4882a593Smuzhiyun #if (KERNEL_VERSION(3, 7, 0) <= LINUX_VERSION_CODE)
68*4882a593Smuzhiyun hash_init(dbg_mem_ht);
69*4882a593Smuzhiyun #endif /* LINUX_VERSION_CODE */
70*4882a593Smuzhiyun }
71*4882a593Smuzhiyun
rtw_dbg_mem_deinit(void)72*4882a593Smuzhiyun void rtw_dbg_mem_deinit(void)
73*4882a593Smuzhiyun {
74*4882a593Smuzhiyun #if (KERNEL_VERSION(3, 7, 0) <= LINUX_VERSION_CODE)
75*4882a593Smuzhiyun struct hlist_head *head;
76*4882a593Smuzhiyun struct hlist_node *p;
77*4882a593Smuzhiyun int i;
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun for (i = 0; i < HASH_SIZE(dbg_mem_ht); i++) {
80*4882a593Smuzhiyun head = &dbg_mem_ht[i];
81*4882a593Smuzhiyun p = head->first;
82*4882a593Smuzhiyun while (p) {
83*4882a593Smuzhiyun struct hlist_node *prev;
84*4882a593Smuzhiyun struct hash_mem *hm;
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun hm = container_of(p, struct hash_mem, node);
87*4882a593Smuzhiyun prev = p;
88*4882a593Smuzhiyun p = p->next;
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun RTW_ERR("%s: memory leak - 0x%x\n", __func__, hm->mem);
91*4882a593Smuzhiyun hash_del(prev);
92*4882a593Smuzhiyun kfree(hm);
93*4882a593Smuzhiyun }
94*4882a593Smuzhiyun }
95*4882a593Smuzhiyun #endif /* LINUX_VERSION_CODE */
96*4882a593Smuzhiyun }
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun #if (KERNEL_VERSION(3, 7, 0) <= LINUX_VERSION_CODE)
rtw_dbg_mem_find(void * mem)99*4882a593Smuzhiyun struct hash_mem *rtw_dbg_mem_find(void *mem)
100*4882a593Smuzhiyun {
101*4882a593Smuzhiyun struct hash_mem *hm;
102*4882a593Smuzhiyun struct hlist_head *head;
103*4882a593Smuzhiyun struct hlist_node *p;
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun head = &dbg_mem_ht[hash_64((u64)(mem), DBG_MEM_HASHBITS)];
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun p = head->first;
108*4882a593Smuzhiyun while (p) {
109*4882a593Smuzhiyun hm = container_of(p, struct hash_mem, node);
110*4882a593Smuzhiyun if (hm->mem == mem)
111*4882a593Smuzhiyun goto out;
112*4882a593Smuzhiyun p = p->next;
113*4882a593Smuzhiyun }
114*4882a593Smuzhiyun hm = NULL;
115*4882a593Smuzhiyun out:
116*4882a593Smuzhiyun return hm;
117*4882a593Smuzhiyun }
118*4882a593Smuzhiyun
rtw_dbg_mem_alloc(void * mem,int sz,int type)119*4882a593Smuzhiyun void rtw_dbg_mem_alloc(void *mem, int sz, int type)
120*4882a593Smuzhiyun {
121*4882a593Smuzhiyun struct hash_mem *hm;
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun hm = rtw_dbg_mem_find(mem);
124*4882a593Smuzhiyun if (!hm) {
125*4882a593Smuzhiyun hm = (struct hash_mem *)kmalloc(sizeof(*hm), GFP_ATOMIC);
126*4882a593Smuzhiyun hm->mem = mem;
127*4882a593Smuzhiyun hm->sz = sz;
128*4882a593Smuzhiyun hm->type = type;
129*4882a593Smuzhiyun hash_add(dbg_mem_ht, &hm->node, (u64)(mem));
130*4882a593Smuzhiyun } else {
131*4882a593Smuzhiyun RTW_ERR("%s mem(%x) is in hash already\n", __func__, mem);
132*4882a593Smuzhiyun rtw_warn_on(1);
133*4882a593Smuzhiyun }
134*4882a593Smuzhiyun }
135*4882a593Smuzhiyun
rtw_dbg_mem_free(void * mem,int sz,int type)136*4882a593Smuzhiyun bool rtw_dbg_mem_free(void *mem, int sz, int type)
137*4882a593Smuzhiyun {
138*4882a593Smuzhiyun struct hash_mem *hm;
139*4882a593Smuzhiyun bool ret;
140*4882a593Smuzhiyun
141*4882a593Smuzhiyun hm = rtw_dbg_mem_find(mem);
142*4882a593Smuzhiyun if (!hm) {
143*4882a593Smuzhiyun RTW_ERR("%s cannot find allocated memory: %x\n",
144*4882a593Smuzhiyun __func__, mem);
145*4882a593Smuzhiyun rtw_warn_on(1);
146*4882a593Smuzhiyun return false;
147*4882a593Smuzhiyun }
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun if (hm->sz != sz) {
150*4882a593Smuzhiyun RTW_ERR("%s memory (%x) size mismatch free(%d) != alloc(%d)\n",
151*4882a593Smuzhiyun __func__, mem, sz, hm->sz);
152*4882a593Smuzhiyun rtw_warn_on(1);
153*4882a593Smuzhiyun ret = false;
154*4882a593Smuzhiyun goto out;
155*4882a593Smuzhiyun }
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun if (hm->type != type) {
158*4882a593Smuzhiyun RTW_ERR("%s memory (%x) type mismatch free(%d) != alloc(%d)\n",
159*4882a593Smuzhiyun __func__, mem, type, hm->type);
160*4882a593Smuzhiyun rtw_warn_on(1);
161*4882a593Smuzhiyun ret = false;
162*4882a593Smuzhiyun goto out;
163*4882a593Smuzhiyun }
164*4882a593Smuzhiyun ret = true;
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun out:
167*4882a593Smuzhiyun hash_del(&hm->node);
168*4882a593Smuzhiyun kfree(hm);
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun return ret;
171*4882a593Smuzhiyun }
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun #endif /* LINUX_VERSION_CODE */
174*4882a593Smuzhiyun #endif /* DBG_MEM_ERR_FREE */
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun #if defined(PLATFORM_LINUX)
177*4882a593Smuzhiyun /*
178*4882a593Smuzhiyun * Translate the OS dependent @param error_code to OS independent RTW_STATUS_CODE
179*4882a593Smuzhiyun * @return: one of RTW_STATUS_CODE
180*4882a593Smuzhiyun */
RTW_STATUS_CODE(int error_code)181*4882a593Smuzhiyun inline int RTW_STATUS_CODE(int error_code)
182*4882a593Smuzhiyun {
183*4882a593Smuzhiyun if (error_code >= 0)
184*4882a593Smuzhiyun return _SUCCESS;
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun switch (error_code) {
187*4882a593Smuzhiyun /* case -ETIMEDOUT: */
188*4882a593Smuzhiyun /* return RTW_STATUS_TIMEDOUT; */
189*4882a593Smuzhiyun default:
190*4882a593Smuzhiyun return _FAIL;
191*4882a593Smuzhiyun }
192*4882a593Smuzhiyun }
193*4882a593Smuzhiyun #else
RTW_STATUS_CODE(int error_code)194*4882a593Smuzhiyun inline int RTW_STATUS_CODE(int error_code)
195*4882a593Smuzhiyun {
196*4882a593Smuzhiyun return error_code;
197*4882a593Smuzhiyun }
198*4882a593Smuzhiyun #endif
199*4882a593Smuzhiyun
rtw_atoi(u8 * s)200*4882a593Smuzhiyun u32 rtw_atoi(u8 *s)
201*4882a593Smuzhiyun {
202*4882a593Smuzhiyun
203*4882a593Smuzhiyun int num = 0, flag = 0;
204*4882a593Smuzhiyun int i;
205*4882a593Smuzhiyun for (i = 0; i <= strlen(s); i++) {
206*4882a593Smuzhiyun if (s[i] >= '0' && s[i] <= '9')
207*4882a593Smuzhiyun num = num * 10 + s[i] - '0';
208*4882a593Smuzhiyun else if (s[0] == '-' && i == 0)
209*4882a593Smuzhiyun flag = 1;
210*4882a593Smuzhiyun else
211*4882a593Smuzhiyun break;
212*4882a593Smuzhiyun }
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun if (flag == 1)
215*4882a593Smuzhiyun num = num * -1;
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun return num;
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun }
220*4882a593Smuzhiyun
_rtw_vmalloc(u32 sz)221*4882a593Smuzhiyun inline void *_rtw_vmalloc(u32 sz)
222*4882a593Smuzhiyun {
223*4882a593Smuzhiyun void *pbuf;
224*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
225*4882a593Smuzhiyun pbuf = vmalloc(sz);
226*4882a593Smuzhiyun #endif
227*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
228*4882a593Smuzhiyun pbuf = malloc(sz, M_DEVBUF, M_NOWAIT);
229*4882a593Smuzhiyun #endif
230*4882a593Smuzhiyun
231*4882a593Smuzhiyun #ifdef PLATFORM_WINDOWS
232*4882a593Smuzhiyun NdisAllocateMemoryWithTag(&pbuf, sz, RT_TAG);
233*4882a593Smuzhiyun #endif
234*4882a593Smuzhiyun
235*4882a593Smuzhiyun #ifdef DBG_MEM_ERR_FREE
236*4882a593Smuzhiyun if (pbuf)
237*4882a593Smuzhiyun rtw_dbg_mem_alloc(pbuf, sz, DBG_MEM_TYPE_VIR);
238*4882a593Smuzhiyun #endif /* DBG_MEM_ERR_FREE */
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun #ifdef DBG_MEMORY_LEAK
241*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
242*4882a593Smuzhiyun if (pbuf != NULL) {
243*4882a593Smuzhiyun atomic_inc(&_malloc_cnt);
244*4882a593Smuzhiyun atomic_add(sz, &_malloc_size);
245*4882a593Smuzhiyun }
246*4882a593Smuzhiyun #endif
247*4882a593Smuzhiyun #endif /* DBG_MEMORY_LEAK */
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun return pbuf;
250*4882a593Smuzhiyun }
251*4882a593Smuzhiyun
_rtw_zvmalloc(u32 sz)252*4882a593Smuzhiyun inline void *_rtw_zvmalloc(u32 sz)
253*4882a593Smuzhiyun {
254*4882a593Smuzhiyun void *pbuf;
255*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
256*4882a593Smuzhiyun pbuf = _rtw_vmalloc(sz);
257*4882a593Smuzhiyun if (pbuf != NULL)
258*4882a593Smuzhiyun memset(pbuf, 0, sz);
259*4882a593Smuzhiyun #endif
260*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
261*4882a593Smuzhiyun pbuf = malloc(sz, M_DEVBUF, M_ZERO | M_NOWAIT);
262*4882a593Smuzhiyun #endif
263*4882a593Smuzhiyun #ifdef PLATFORM_WINDOWS
264*4882a593Smuzhiyun NdisAllocateMemoryWithTag(&pbuf, sz, RT_TAG);
265*4882a593Smuzhiyun if (pbuf != NULL)
266*4882a593Smuzhiyun NdisFillMemory(pbuf, sz, 0);
267*4882a593Smuzhiyun #endif
268*4882a593Smuzhiyun
269*4882a593Smuzhiyun return pbuf;
270*4882a593Smuzhiyun }
271*4882a593Smuzhiyun
_rtw_vmfree(void * pbuf,u32 sz)272*4882a593Smuzhiyun inline void _rtw_vmfree(void *pbuf, u32 sz)
273*4882a593Smuzhiyun {
274*4882a593Smuzhiyun #ifdef DBG_MEM_ERR_FREE
275*4882a593Smuzhiyun if (!rtw_dbg_mem_free(pbuf, sz, DBG_MEM_TYPE_VIR))
276*4882a593Smuzhiyun return;
277*4882a593Smuzhiyun #endif /* DBG_MEM_ERR_FREE */
278*4882a593Smuzhiyun
279*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
280*4882a593Smuzhiyun vfree(pbuf);
281*4882a593Smuzhiyun #endif
282*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
283*4882a593Smuzhiyun free(pbuf, M_DEVBUF);
284*4882a593Smuzhiyun #endif
285*4882a593Smuzhiyun #ifdef PLATFORM_WINDOWS
286*4882a593Smuzhiyun NdisFreeMemory(pbuf, sz, 0);
287*4882a593Smuzhiyun #endif
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun #ifdef DBG_MEMORY_LEAK
290*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
291*4882a593Smuzhiyun atomic_dec(&_malloc_cnt);
292*4882a593Smuzhiyun atomic_sub(sz, &_malloc_size);
293*4882a593Smuzhiyun #endif
294*4882a593Smuzhiyun #endif /* DBG_MEMORY_LEAK */
295*4882a593Smuzhiyun }
296*4882a593Smuzhiyun
_rtw_malloc(u32 sz)297*4882a593Smuzhiyun void *_rtw_malloc(u32 sz)
298*4882a593Smuzhiyun {
299*4882a593Smuzhiyun void *pbuf = NULL;
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
302*4882a593Smuzhiyun #ifdef RTK_DMP_PLATFORM
303*4882a593Smuzhiyun if (sz > 0x4000)
304*4882a593Smuzhiyun pbuf = dvr_malloc(sz);
305*4882a593Smuzhiyun else
306*4882a593Smuzhiyun #endif
307*4882a593Smuzhiyun pbuf = kmalloc(sz, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
308*4882a593Smuzhiyun
309*4882a593Smuzhiyun #endif
310*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
311*4882a593Smuzhiyun pbuf = malloc(sz, M_DEVBUF, M_NOWAIT);
312*4882a593Smuzhiyun #endif
313*4882a593Smuzhiyun #ifdef PLATFORM_WINDOWS
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun NdisAllocateMemoryWithTag(&pbuf, sz, RT_TAG);
316*4882a593Smuzhiyun
317*4882a593Smuzhiyun #endif
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun #ifdef DBG_MEM_ERR_FREE
320*4882a593Smuzhiyun if (pbuf)
321*4882a593Smuzhiyun rtw_dbg_mem_alloc(pbuf, sz, DBG_MEM_TYPE_PHY);
322*4882a593Smuzhiyun #endif /* DBG_MEM_ERR_FREE */
323*4882a593Smuzhiyun
324*4882a593Smuzhiyun #ifdef DBG_MEMORY_LEAK
325*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
326*4882a593Smuzhiyun if (pbuf != NULL) {
327*4882a593Smuzhiyun atomic_inc(&_malloc_cnt);
328*4882a593Smuzhiyun atomic_add(sz, &_malloc_size);
329*4882a593Smuzhiyun }
330*4882a593Smuzhiyun #endif
331*4882a593Smuzhiyun #endif /* DBG_MEMORY_LEAK */
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun return pbuf;
334*4882a593Smuzhiyun
335*4882a593Smuzhiyun }
336*4882a593Smuzhiyun
337*4882a593Smuzhiyun
_rtw_zmalloc(u32 sz)338*4882a593Smuzhiyun void *_rtw_zmalloc(u32 sz)
339*4882a593Smuzhiyun {
340*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
341*4882a593Smuzhiyun return malloc(sz, M_DEVBUF, M_ZERO | M_NOWAIT);
342*4882a593Smuzhiyun #else /* PLATFORM_FREEBSD */
343*4882a593Smuzhiyun void *pbuf = _rtw_malloc(sz);
344*4882a593Smuzhiyun
345*4882a593Smuzhiyun if (pbuf != NULL) {
346*4882a593Smuzhiyun
347*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
348*4882a593Smuzhiyun memset(pbuf, 0, sz);
349*4882a593Smuzhiyun #endif
350*4882a593Smuzhiyun
351*4882a593Smuzhiyun #ifdef PLATFORM_WINDOWS
352*4882a593Smuzhiyun NdisFillMemory(pbuf, sz, 0);
353*4882a593Smuzhiyun #endif
354*4882a593Smuzhiyun }
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun return pbuf;
357*4882a593Smuzhiyun #endif /* PLATFORM_FREEBSD */
358*4882a593Smuzhiyun }
359*4882a593Smuzhiyun
_rtw_mfree(void * pbuf,u32 sz)360*4882a593Smuzhiyun void _rtw_mfree(void *pbuf, u32 sz)
361*4882a593Smuzhiyun {
362*4882a593Smuzhiyun
363*4882a593Smuzhiyun #ifdef DBG_MEM_ERR_FREE
364*4882a593Smuzhiyun if (!rtw_dbg_mem_free(pbuf, sz, DBG_MEM_TYPE_PHY))
365*4882a593Smuzhiyun return;
366*4882a593Smuzhiyun #endif /* DBG_MEM_ERR_FREE */
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
369*4882a593Smuzhiyun #ifdef RTK_DMP_PLATFORM
370*4882a593Smuzhiyun if (sz > 0x4000)
371*4882a593Smuzhiyun dvr_free(pbuf);
372*4882a593Smuzhiyun else
373*4882a593Smuzhiyun #endif
374*4882a593Smuzhiyun kfree(pbuf);
375*4882a593Smuzhiyun
376*4882a593Smuzhiyun #endif
377*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
378*4882a593Smuzhiyun free(pbuf, M_DEVBUF);
379*4882a593Smuzhiyun #endif
380*4882a593Smuzhiyun #ifdef PLATFORM_WINDOWS
381*4882a593Smuzhiyun
382*4882a593Smuzhiyun NdisFreeMemory(pbuf, sz, 0);
383*4882a593Smuzhiyun
384*4882a593Smuzhiyun #endif
385*4882a593Smuzhiyun
386*4882a593Smuzhiyun #ifdef DBG_MEMORY_LEAK
387*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
388*4882a593Smuzhiyun atomic_dec(&_malloc_cnt);
389*4882a593Smuzhiyun atomic_sub(sz, &_malloc_size);
390*4882a593Smuzhiyun #endif
391*4882a593Smuzhiyun #endif /* DBG_MEMORY_LEAK */
392*4882a593Smuzhiyun
393*4882a593Smuzhiyun }
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
396*4882a593Smuzhiyun /* review again */
dev_alloc_skb(unsigned int size)397*4882a593Smuzhiyun struct sk_buff *dev_alloc_skb(unsigned int size)
398*4882a593Smuzhiyun {
399*4882a593Smuzhiyun struct sk_buff *skb = NULL;
400*4882a593Smuzhiyun u8 *data = NULL;
401*4882a593Smuzhiyun
402*4882a593Smuzhiyun /* skb = _rtw_zmalloc(sizeof(struct sk_buff)); */ /* for skb->len, etc. */
403*4882a593Smuzhiyun skb = _rtw_malloc(sizeof(struct sk_buff));
404*4882a593Smuzhiyun if (!skb)
405*4882a593Smuzhiyun goto out;
406*4882a593Smuzhiyun data = _rtw_malloc(size);
407*4882a593Smuzhiyun if (!data)
408*4882a593Smuzhiyun goto nodata;
409*4882a593Smuzhiyun
410*4882a593Smuzhiyun skb->head = (unsigned char *)data;
411*4882a593Smuzhiyun skb->data = (unsigned char *)data;
412*4882a593Smuzhiyun skb->tail = (unsigned char *)data;
413*4882a593Smuzhiyun skb->end = (unsigned char *)data + size;
414*4882a593Smuzhiyun skb->len = 0;
415*4882a593Smuzhiyun /* printf("%s()-%d: skb=%p, skb->head = %p\n", __FUNCTION__, __LINE__, skb, skb->head); */
416*4882a593Smuzhiyun
417*4882a593Smuzhiyun out:
418*4882a593Smuzhiyun return skb;
419*4882a593Smuzhiyun nodata:
420*4882a593Smuzhiyun _rtw_mfree(skb, sizeof(struct sk_buff));
421*4882a593Smuzhiyun skb = NULL;
422*4882a593Smuzhiyun goto out;
423*4882a593Smuzhiyun
424*4882a593Smuzhiyun }
425*4882a593Smuzhiyun
dev_kfree_skb_any(struct sk_buff * skb)426*4882a593Smuzhiyun void dev_kfree_skb_any(struct sk_buff *skb)
427*4882a593Smuzhiyun {
428*4882a593Smuzhiyun /* printf("%s()-%d: skb->head = %p\n", __FUNCTION__, __LINE__, skb->head); */
429*4882a593Smuzhiyun if (skb->head)
430*4882a593Smuzhiyun _rtw_mfree(skb->head, 0);
431*4882a593Smuzhiyun /* printf("%s()-%d: skb = %p\n", __FUNCTION__, __LINE__, skb); */
432*4882a593Smuzhiyun if (skb)
433*4882a593Smuzhiyun _rtw_mfree(skb, 0);
434*4882a593Smuzhiyun }
skb_clone(const struct sk_buff * skb)435*4882a593Smuzhiyun struct sk_buff *skb_clone(const struct sk_buff *skb)
436*4882a593Smuzhiyun {
437*4882a593Smuzhiyun return NULL;
438*4882a593Smuzhiyun }
439*4882a593Smuzhiyun
440*4882a593Smuzhiyun #endif /* PLATFORM_FREEBSD */
441*4882a593Smuzhiyun
_rtw_skb_alloc(u32 sz)442*4882a593Smuzhiyun inline struct sk_buff *_rtw_skb_alloc(u32 sz)
443*4882a593Smuzhiyun {
444*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
445*4882a593Smuzhiyun return __dev_alloc_skb(sz, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
446*4882a593Smuzhiyun #endif /* PLATFORM_LINUX */
447*4882a593Smuzhiyun
448*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
449*4882a593Smuzhiyun return dev_alloc_skb(sz);
450*4882a593Smuzhiyun #endif /* PLATFORM_FREEBSD */
451*4882a593Smuzhiyun }
452*4882a593Smuzhiyun
_rtw_skb_free(struct sk_buff * skb)453*4882a593Smuzhiyun inline void _rtw_skb_free(struct sk_buff *skb)
454*4882a593Smuzhiyun {
455*4882a593Smuzhiyun dev_kfree_skb_any(skb);
456*4882a593Smuzhiyun }
457*4882a593Smuzhiyun
_rtw_skb_copy(const struct sk_buff * skb)458*4882a593Smuzhiyun inline struct sk_buff *_rtw_skb_copy(const struct sk_buff *skb)
459*4882a593Smuzhiyun {
460*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
461*4882a593Smuzhiyun return skb_copy(skb, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
462*4882a593Smuzhiyun #endif /* PLATFORM_LINUX */
463*4882a593Smuzhiyun
464*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
465*4882a593Smuzhiyun return NULL;
466*4882a593Smuzhiyun #endif /* PLATFORM_FREEBSD */
467*4882a593Smuzhiyun }
468*4882a593Smuzhiyun
_rtw_skb_clone(struct sk_buff * skb)469*4882a593Smuzhiyun inline struct sk_buff *_rtw_skb_clone(struct sk_buff *skb)
470*4882a593Smuzhiyun {
471*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
472*4882a593Smuzhiyun return skb_clone(skb, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
473*4882a593Smuzhiyun #endif /* PLATFORM_LINUX */
474*4882a593Smuzhiyun
475*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
476*4882a593Smuzhiyun return skb_clone(skb);
477*4882a593Smuzhiyun #endif /* PLATFORM_FREEBSD */
478*4882a593Smuzhiyun }
_rtw_pskb_copy(struct sk_buff * skb)479*4882a593Smuzhiyun inline struct sk_buff *_rtw_pskb_copy(struct sk_buff *skb)
480*4882a593Smuzhiyun {
481*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
482*4882a593Smuzhiyun #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36))
483*4882a593Smuzhiyun return pskb_copy(skb, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
484*4882a593Smuzhiyun #else
485*4882a593Smuzhiyun return skb_clone(skb, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
486*4882a593Smuzhiyun #endif
487*4882a593Smuzhiyun #endif /* PLATFORM_LINUX */
488*4882a593Smuzhiyun
489*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
490*4882a593Smuzhiyun return NULL;
491*4882a593Smuzhiyun #endif /* PLATFORM_FREEBSD */
492*4882a593Smuzhiyun }
493*4882a593Smuzhiyun
_rtw_netif_rx(_nic_hdl ndev,struct sk_buff * skb)494*4882a593Smuzhiyun inline int _rtw_netif_rx(_nic_hdl ndev, struct sk_buff *skb)
495*4882a593Smuzhiyun {
496*4882a593Smuzhiyun #if defined(PLATFORM_LINUX)
497*4882a593Smuzhiyun skb->dev = ndev;
498*4882a593Smuzhiyun return netif_rx(skb);
499*4882a593Smuzhiyun #elif defined(PLATFORM_FREEBSD)
500*4882a593Smuzhiyun return (*ndev->if_input)(ndev, skb);
501*4882a593Smuzhiyun #else
502*4882a593Smuzhiyun rtw_warn_on(1);
503*4882a593Smuzhiyun return -1;
504*4882a593Smuzhiyun #endif
505*4882a593Smuzhiyun }
506*4882a593Smuzhiyun
507*4882a593Smuzhiyun #ifdef CONFIG_RTW_NAPI
_rtw_netif_receive_skb(_nic_hdl ndev,struct sk_buff * skb)508*4882a593Smuzhiyun inline int _rtw_netif_receive_skb(_nic_hdl ndev, struct sk_buff *skb)
509*4882a593Smuzhiyun {
510*4882a593Smuzhiyun #if defined(PLATFORM_LINUX)
511*4882a593Smuzhiyun skb->dev = ndev;
512*4882a593Smuzhiyun return netif_receive_skb(skb);
513*4882a593Smuzhiyun #else
514*4882a593Smuzhiyun rtw_warn_on(1);
515*4882a593Smuzhiyun return -1;
516*4882a593Smuzhiyun #endif
517*4882a593Smuzhiyun }
518*4882a593Smuzhiyun
519*4882a593Smuzhiyun #ifdef CONFIG_RTW_GRO
_rtw_napi_gro_receive(struct napi_struct * napi,struct sk_buff * skb)520*4882a593Smuzhiyun inline gro_result_t _rtw_napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
521*4882a593Smuzhiyun {
522*4882a593Smuzhiyun #if defined(PLATFORM_LINUX)
523*4882a593Smuzhiyun return napi_gro_receive(napi, skb);
524*4882a593Smuzhiyun #else
525*4882a593Smuzhiyun rtw_warn_on(1);
526*4882a593Smuzhiyun return -1;
527*4882a593Smuzhiyun #endif
528*4882a593Smuzhiyun }
529*4882a593Smuzhiyun #endif /* CONFIG_RTW_GRO */
530*4882a593Smuzhiyun #endif /* CONFIG_RTW_NAPI */
531*4882a593Smuzhiyun
_rtw_skb_queue_purge(struct sk_buff_head * list)532*4882a593Smuzhiyun void _rtw_skb_queue_purge(struct sk_buff_head *list)
533*4882a593Smuzhiyun {
534*4882a593Smuzhiyun struct sk_buff *skb;
535*4882a593Smuzhiyun
536*4882a593Smuzhiyun while ((skb = skb_dequeue(list)) != NULL)
537*4882a593Smuzhiyun _rtw_skb_free(skb);
538*4882a593Smuzhiyun }
539*4882a593Smuzhiyun
540*4882a593Smuzhiyun #ifdef CONFIG_USB_HCI
_rtw_usb_buffer_alloc(struct usb_device * dev,size_t size,dma_addr_t * dma)541*4882a593Smuzhiyun inline void *_rtw_usb_buffer_alloc(struct usb_device *dev, size_t size, dma_addr_t *dma)
542*4882a593Smuzhiyun {
543*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
544*4882a593Smuzhiyun #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
545*4882a593Smuzhiyun return usb_alloc_coherent(dev, size, (in_interrupt() ? GFP_ATOMIC : GFP_KERNEL), dma);
546*4882a593Smuzhiyun #else
547*4882a593Smuzhiyun return usb_buffer_alloc(dev, size, (in_interrupt() ? GFP_ATOMIC : GFP_KERNEL), dma);
548*4882a593Smuzhiyun #endif
549*4882a593Smuzhiyun #endif /* PLATFORM_LINUX */
550*4882a593Smuzhiyun
551*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
552*4882a593Smuzhiyun return malloc(size, M_USBDEV, M_NOWAIT | M_ZERO);
553*4882a593Smuzhiyun #endif /* PLATFORM_FREEBSD */
554*4882a593Smuzhiyun }
_rtw_usb_buffer_free(struct usb_device * dev,size_t size,void * addr,dma_addr_t dma)555*4882a593Smuzhiyun inline void _rtw_usb_buffer_free(struct usb_device *dev, size_t size, void *addr, dma_addr_t dma)
556*4882a593Smuzhiyun {
557*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
558*4882a593Smuzhiyun #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
559*4882a593Smuzhiyun usb_free_coherent(dev, size, addr, dma);
560*4882a593Smuzhiyun #else
561*4882a593Smuzhiyun usb_buffer_free(dev, size, addr, dma);
562*4882a593Smuzhiyun #endif
563*4882a593Smuzhiyun #endif /* PLATFORM_LINUX */
564*4882a593Smuzhiyun
565*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
566*4882a593Smuzhiyun free(addr, M_USBDEV);
567*4882a593Smuzhiyun #endif /* PLATFORM_FREEBSD */
568*4882a593Smuzhiyun }
569*4882a593Smuzhiyun #endif /* CONFIG_USB_HCI */
570*4882a593Smuzhiyun
571*4882a593Smuzhiyun #if defined(DBG_MEM_ALLOC)
572*4882a593Smuzhiyun
573*4882a593Smuzhiyun struct rtw_mem_stat {
574*4882a593Smuzhiyun ATOMIC_T alloc; /* the memory bytes we allocate currently */
575*4882a593Smuzhiyun ATOMIC_T peak; /* the peak memory bytes we allocate */
576*4882a593Smuzhiyun ATOMIC_T alloc_cnt; /* the alloc count for alloc currently */
577*4882a593Smuzhiyun ATOMIC_T alloc_err_cnt; /* the error times we fail to allocate memory */
578*4882a593Smuzhiyun };
579*4882a593Smuzhiyun
580*4882a593Smuzhiyun struct rtw_mem_stat rtw_mem_type_stat[mstat_tf_idx(MSTAT_TYPE_MAX)];
581*4882a593Smuzhiyun #ifdef RTW_MEM_FUNC_STAT
582*4882a593Smuzhiyun struct rtw_mem_stat rtw_mem_func_stat[mstat_ff_idx(MSTAT_FUNC_MAX)];
583*4882a593Smuzhiyun #endif
584*4882a593Smuzhiyun
585*4882a593Smuzhiyun char *MSTAT_TYPE_str[] = {
586*4882a593Smuzhiyun "VIR",
587*4882a593Smuzhiyun "PHY",
588*4882a593Smuzhiyun "SKB",
589*4882a593Smuzhiyun "USB",
590*4882a593Smuzhiyun };
591*4882a593Smuzhiyun
592*4882a593Smuzhiyun #ifdef RTW_MEM_FUNC_STAT
593*4882a593Smuzhiyun char *MSTAT_FUNC_str[] = {
594*4882a593Smuzhiyun "UNSP",
595*4882a593Smuzhiyun "IO",
596*4882a593Smuzhiyun "TXIO",
597*4882a593Smuzhiyun "RXIO",
598*4882a593Smuzhiyun "TX",
599*4882a593Smuzhiyun "RX",
600*4882a593Smuzhiyun };
601*4882a593Smuzhiyun #endif
602*4882a593Smuzhiyun
rtw_mstat_dump(void * sel)603*4882a593Smuzhiyun void rtw_mstat_dump(void *sel)
604*4882a593Smuzhiyun {
605*4882a593Smuzhiyun int i;
606*4882a593Smuzhiyun int value_t[4][mstat_tf_idx(MSTAT_TYPE_MAX)];
607*4882a593Smuzhiyun #ifdef RTW_MEM_FUNC_STAT
608*4882a593Smuzhiyun int value_f[4][mstat_ff_idx(MSTAT_FUNC_MAX)];
609*4882a593Smuzhiyun #endif
610*4882a593Smuzhiyun
611*4882a593Smuzhiyun for (i = 0; i < mstat_tf_idx(MSTAT_TYPE_MAX); i++) {
612*4882a593Smuzhiyun value_t[0][i] = ATOMIC_READ(&(rtw_mem_type_stat[i].alloc));
613*4882a593Smuzhiyun value_t[1][i] = ATOMIC_READ(&(rtw_mem_type_stat[i].peak));
614*4882a593Smuzhiyun value_t[2][i] = ATOMIC_READ(&(rtw_mem_type_stat[i].alloc_cnt));
615*4882a593Smuzhiyun value_t[3][i] = ATOMIC_READ(&(rtw_mem_type_stat[i].alloc_err_cnt));
616*4882a593Smuzhiyun }
617*4882a593Smuzhiyun
618*4882a593Smuzhiyun #ifdef RTW_MEM_FUNC_STAT
619*4882a593Smuzhiyun for (i = 0; i < mstat_ff_idx(MSTAT_FUNC_MAX); i++) {
620*4882a593Smuzhiyun value_f[0][i] = ATOMIC_READ(&(rtw_mem_func_stat[i].alloc));
621*4882a593Smuzhiyun value_f[1][i] = ATOMIC_READ(&(rtw_mem_func_stat[i].peak));
622*4882a593Smuzhiyun value_f[2][i] = ATOMIC_READ(&(rtw_mem_func_stat[i].alloc_cnt));
623*4882a593Smuzhiyun value_f[3][i] = ATOMIC_READ(&(rtw_mem_func_stat[i].alloc_err_cnt));
624*4882a593Smuzhiyun }
625*4882a593Smuzhiyun #endif
626*4882a593Smuzhiyun
627*4882a593Smuzhiyun RTW_PRINT_SEL(sel, "===================== MSTAT =====================\n");
628*4882a593Smuzhiyun RTW_PRINT_SEL(sel, "%4s %10s %10s %10s %10s\n", "TAG", "alloc", "peak", "aloc_cnt", "err_cnt");
629*4882a593Smuzhiyun RTW_PRINT_SEL(sel, "-------------------------------------------------\n");
630*4882a593Smuzhiyun for (i = 0; i < mstat_tf_idx(MSTAT_TYPE_MAX); i++)
631*4882a593Smuzhiyun RTW_PRINT_SEL(sel, "%4s %10d %10d %10d %10d\n", MSTAT_TYPE_str[i], value_t[0][i], value_t[1][i], value_t[2][i], value_t[3][i]);
632*4882a593Smuzhiyun #ifdef RTW_MEM_FUNC_STAT
633*4882a593Smuzhiyun RTW_PRINT_SEL(sel, "-------------------------------------------------\n");
634*4882a593Smuzhiyun for (i = 0; i < mstat_ff_idx(MSTAT_FUNC_MAX); i++)
635*4882a593Smuzhiyun RTW_PRINT_SEL(sel, "%4s %10d %10d %10d %10d\n", MSTAT_FUNC_str[i], value_f[0][i], value_f[1][i], value_f[2][i], value_f[3][i]);
636*4882a593Smuzhiyun #endif
637*4882a593Smuzhiyun }
638*4882a593Smuzhiyun
rtw_mstat_update(const enum mstat_f flags,const MSTAT_STATUS status,u32 sz)639*4882a593Smuzhiyun void rtw_mstat_update(const enum mstat_f flags, const MSTAT_STATUS status, u32 sz)
640*4882a593Smuzhiyun {
641*4882a593Smuzhiyun static systime update_time = 0;
642*4882a593Smuzhiyun int peak, alloc;
643*4882a593Smuzhiyun int i;
644*4882a593Smuzhiyun
645*4882a593Smuzhiyun /* initialization */
646*4882a593Smuzhiyun if (!update_time) {
647*4882a593Smuzhiyun for (i = 0; i < mstat_tf_idx(MSTAT_TYPE_MAX); i++) {
648*4882a593Smuzhiyun ATOMIC_SET(&(rtw_mem_type_stat[i].alloc), 0);
649*4882a593Smuzhiyun ATOMIC_SET(&(rtw_mem_type_stat[i].peak), 0);
650*4882a593Smuzhiyun ATOMIC_SET(&(rtw_mem_type_stat[i].alloc_cnt), 0);
651*4882a593Smuzhiyun ATOMIC_SET(&(rtw_mem_type_stat[i].alloc_err_cnt), 0);
652*4882a593Smuzhiyun }
653*4882a593Smuzhiyun #ifdef RTW_MEM_FUNC_STAT
654*4882a593Smuzhiyun for (i = 0; i < mstat_ff_idx(MSTAT_FUNC_MAX); i++) {
655*4882a593Smuzhiyun ATOMIC_SET(&(rtw_mem_func_stat[i].alloc), 0);
656*4882a593Smuzhiyun ATOMIC_SET(&(rtw_mem_func_stat[i].peak), 0);
657*4882a593Smuzhiyun ATOMIC_SET(&(rtw_mem_func_stat[i].alloc_cnt), 0);
658*4882a593Smuzhiyun ATOMIC_SET(&(rtw_mem_func_stat[i].alloc_err_cnt), 0);
659*4882a593Smuzhiyun }
660*4882a593Smuzhiyun #endif
661*4882a593Smuzhiyun }
662*4882a593Smuzhiyun
663*4882a593Smuzhiyun switch (status) {
664*4882a593Smuzhiyun case MSTAT_ALLOC_SUCCESS:
665*4882a593Smuzhiyun ATOMIC_INC(&(rtw_mem_type_stat[mstat_tf_idx(flags)].alloc_cnt));
666*4882a593Smuzhiyun alloc = ATOMIC_ADD_RETURN(&(rtw_mem_type_stat[mstat_tf_idx(flags)].alloc), sz);
667*4882a593Smuzhiyun peak = ATOMIC_READ(&(rtw_mem_type_stat[mstat_tf_idx(flags)].peak));
668*4882a593Smuzhiyun if (peak < alloc)
669*4882a593Smuzhiyun ATOMIC_SET(&(rtw_mem_type_stat[mstat_tf_idx(flags)].peak), alloc);
670*4882a593Smuzhiyun
671*4882a593Smuzhiyun #ifdef RTW_MEM_FUNC_STAT
672*4882a593Smuzhiyun ATOMIC_INC(&(rtw_mem_func_stat[mstat_ff_idx(flags)].alloc_cnt));
673*4882a593Smuzhiyun alloc = ATOMIC_ADD_RETURN(&(rtw_mem_func_stat[mstat_ff_idx(flags)].alloc), sz);
674*4882a593Smuzhiyun peak = ATOMIC_READ(&(rtw_mem_func_stat[mstat_ff_idx(flags)].peak));
675*4882a593Smuzhiyun if (peak < alloc)
676*4882a593Smuzhiyun ATOMIC_SET(&(rtw_mem_func_stat[mstat_ff_idx(flags)].peak), alloc);
677*4882a593Smuzhiyun #endif
678*4882a593Smuzhiyun break;
679*4882a593Smuzhiyun
680*4882a593Smuzhiyun case MSTAT_ALLOC_FAIL:
681*4882a593Smuzhiyun ATOMIC_INC(&(rtw_mem_type_stat[mstat_tf_idx(flags)].alloc_err_cnt));
682*4882a593Smuzhiyun #ifdef RTW_MEM_FUNC_STAT
683*4882a593Smuzhiyun ATOMIC_INC(&(rtw_mem_func_stat[mstat_ff_idx(flags)].alloc_err_cnt));
684*4882a593Smuzhiyun #endif
685*4882a593Smuzhiyun break;
686*4882a593Smuzhiyun
687*4882a593Smuzhiyun case MSTAT_FREE:
688*4882a593Smuzhiyun ATOMIC_DEC(&(rtw_mem_type_stat[mstat_tf_idx(flags)].alloc_cnt));
689*4882a593Smuzhiyun ATOMIC_SUB(&(rtw_mem_type_stat[mstat_tf_idx(flags)].alloc), sz);
690*4882a593Smuzhiyun #ifdef RTW_MEM_FUNC_STAT
691*4882a593Smuzhiyun ATOMIC_DEC(&(rtw_mem_func_stat[mstat_ff_idx(flags)].alloc_cnt));
692*4882a593Smuzhiyun ATOMIC_SUB(&(rtw_mem_func_stat[mstat_ff_idx(flags)].alloc), sz);
693*4882a593Smuzhiyun #endif
694*4882a593Smuzhiyun break;
695*4882a593Smuzhiyun };
696*4882a593Smuzhiyun
697*4882a593Smuzhiyun /* if (rtw_get_passing_time_ms(update_time) > 5000) { */
698*4882a593Smuzhiyun /* rtw_mstat_dump(RTW_DBGDUMP); */
699*4882a593Smuzhiyun update_time = rtw_get_current_time();
700*4882a593Smuzhiyun /* } */
701*4882a593Smuzhiyun }
702*4882a593Smuzhiyun
703*4882a593Smuzhiyun #ifndef SIZE_MAX
704*4882a593Smuzhiyun #define SIZE_MAX (~(size_t)0)
705*4882a593Smuzhiyun #endif
706*4882a593Smuzhiyun
707*4882a593Smuzhiyun struct mstat_sniff_rule {
708*4882a593Smuzhiyun enum mstat_f flags;
709*4882a593Smuzhiyun size_t lb;
710*4882a593Smuzhiyun size_t hb;
711*4882a593Smuzhiyun };
712*4882a593Smuzhiyun
713*4882a593Smuzhiyun struct mstat_sniff_rule mstat_sniff_rules[] = {
714*4882a593Smuzhiyun {MSTAT_TYPE_PHY, 4097, SIZE_MAX},
715*4882a593Smuzhiyun };
716*4882a593Smuzhiyun
717*4882a593Smuzhiyun int mstat_sniff_rule_num = sizeof(mstat_sniff_rules) / sizeof(struct mstat_sniff_rule);
718*4882a593Smuzhiyun
match_mstat_sniff_rules(const enum mstat_f flags,const size_t size)719*4882a593Smuzhiyun bool match_mstat_sniff_rules(const enum mstat_f flags, const size_t size)
720*4882a593Smuzhiyun {
721*4882a593Smuzhiyun int i;
722*4882a593Smuzhiyun for (i = 0; i < mstat_sniff_rule_num; i++) {
723*4882a593Smuzhiyun if (mstat_sniff_rules[i].flags == flags
724*4882a593Smuzhiyun && mstat_sniff_rules[i].lb <= size
725*4882a593Smuzhiyun && mstat_sniff_rules[i].hb >= size)
726*4882a593Smuzhiyun return _TRUE;
727*4882a593Smuzhiyun }
728*4882a593Smuzhiyun
729*4882a593Smuzhiyun return _FALSE;
730*4882a593Smuzhiyun }
731*4882a593Smuzhiyun
dbg_rtw_vmalloc(u32 sz,const enum mstat_f flags,const char * func,const int line)732*4882a593Smuzhiyun inline void *dbg_rtw_vmalloc(u32 sz, const enum mstat_f flags, const char *func, const int line)
733*4882a593Smuzhiyun {
734*4882a593Smuzhiyun void *p;
735*4882a593Smuzhiyun
736*4882a593Smuzhiyun if (match_mstat_sniff_rules(flags, sz))
737*4882a593Smuzhiyun RTW_INFO("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, (sz));
738*4882a593Smuzhiyun
739*4882a593Smuzhiyun p = _rtw_vmalloc((sz));
740*4882a593Smuzhiyun
741*4882a593Smuzhiyun rtw_mstat_update(
742*4882a593Smuzhiyun flags
743*4882a593Smuzhiyun , p ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL
744*4882a593Smuzhiyun , sz
745*4882a593Smuzhiyun );
746*4882a593Smuzhiyun
747*4882a593Smuzhiyun return p;
748*4882a593Smuzhiyun }
749*4882a593Smuzhiyun
dbg_rtw_zvmalloc(u32 sz,const enum mstat_f flags,const char * func,const int line)750*4882a593Smuzhiyun inline void *dbg_rtw_zvmalloc(u32 sz, const enum mstat_f flags, const char *func, const int line)
751*4882a593Smuzhiyun {
752*4882a593Smuzhiyun void *p;
753*4882a593Smuzhiyun
754*4882a593Smuzhiyun if (match_mstat_sniff_rules(flags, sz))
755*4882a593Smuzhiyun RTW_INFO("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, (sz));
756*4882a593Smuzhiyun
757*4882a593Smuzhiyun p = _rtw_zvmalloc((sz));
758*4882a593Smuzhiyun
759*4882a593Smuzhiyun rtw_mstat_update(
760*4882a593Smuzhiyun flags
761*4882a593Smuzhiyun , p ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL
762*4882a593Smuzhiyun , sz
763*4882a593Smuzhiyun );
764*4882a593Smuzhiyun
765*4882a593Smuzhiyun return p;
766*4882a593Smuzhiyun }
767*4882a593Smuzhiyun
dbg_rtw_vmfree(void * pbuf,u32 sz,const enum mstat_f flags,const char * func,const int line)768*4882a593Smuzhiyun inline void dbg_rtw_vmfree(void *pbuf, u32 sz, const enum mstat_f flags, const char *func, const int line)
769*4882a593Smuzhiyun {
770*4882a593Smuzhiyun
771*4882a593Smuzhiyun if (match_mstat_sniff_rules(flags, sz))
772*4882a593Smuzhiyun RTW_INFO("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, (sz));
773*4882a593Smuzhiyun
774*4882a593Smuzhiyun _rtw_vmfree((pbuf), (sz));
775*4882a593Smuzhiyun
776*4882a593Smuzhiyun rtw_mstat_update(
777*4882a593Smuzhiyun flags
778*4882a593Smuzhiyun , MSTAT_FREE
779*4882a593Smuzhiyun , sz
780*4882a593Smuzhiyun );
781*4882a593Smuzhiyun }
782*4882a593Smuzhiyun
dbg_rtw_malloc(u32 sz,const enum mstat_f flags,const char * func,const int line)783*4882a593Smuzhiyun inline void *dbg_rtw_malloc(u32 sz, const enum mstat_f flags, const char *func, const int line)
784*4882a593Smuzhiyun {
785*4882a593Smuzhiyun void *p;
786*4882a593Smuzhiyun
787*4882a593Smuzhiyun if (match_mstat_sniff_rules(flags, sz))
788*4882a593Smuzhiyun RTW_INFO("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, (sz));
789*4882a593Smuzhiyun
790*4882a593Smuzhiyun p = _rtw_malloc((sz));
791*4882a593Smuzhiyun
792*4882a593Smuzhiyun rtw_mstat_update(
793*4882a593Smuzhiyun flags
794*4882a593Smuzhiyun , p ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL
795*4882a593Smuzhiyun , sz
796*4882a593Smuzhiyun );
797*4882a593Smuzhiyun
798*4882a593Smuzhiyun return p;
799*4882a593Smuzhiyun }
800*4882a593Smuzhiyun
dbg_rtw_zmalloc(u32 sz,const enum mstat_f flags,const char * func,const int line)801*4882a593Smuzhiyun inline void *dbg_rtw_zmalloc(u32 sz, const enum mstat_f flags, const char *func, const int line)
802*4882a593Smuzhiyun {
803*4882a593Smuzhiyun void *p;
804*4882a593Smuzhiyun
805*4882a593Smuzhiyun if (match_mstat_sniff_rules(flags, sz))
806*4882a593Smuzhiyun RTW_INFO("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, (sz));
807*4882a593Smuzhiyun
808*4882a593Smuzhiyun p = _rtw_zmalloc((sz));
809*4882a593Smuzhiyun
810*4882a593Smuzhiyun rtw_mstat_update(
811*4882a593Smuzhiyun flags
812*4882a593Smuzhiyun , p ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL
813*4882a593Smuzhiyun , sz
814*4882a593Smuzhiyun );
815*4882a593Smuzhiyun
816*4882a593Smuzhiyun return p;
817*4882a593Smuzhiyun }
818*4882a593Smuzhiyun
dbg_rtw_mfree(void * pbuf,u32 sz,const enum mstat_f flags,const char * func,const int line)819*4882a593Smuzhiyun inline void dbg_rtw_mfree(void *pbuf, u32 sz, const enum mstat_f flags, const char *func, const int line)
820*4882a593Smuzhiyun {
821*4882a593Smuzhiyun if (match_mstat_sniff_rules(flags, sz))
822*4882a593Smuzhiyun RTW_INFO("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, (sz));
823*4882a593Smuzhiyun
824*4882a593Smuzhiyun _rtw_mfree((pbuf), (sz));
825*4882a593Smuzhiyun
826*4882a593Smuzhiyun rtw_mstat_update(
827*4882a593Smuzhiyun flags
828*4882a593Smuzhiyun , MSTAT_FREE
829*4882a593Smuzhiyun , sz
830*4882a593Smuzhiyun );
831*4882a593Smuzhiyun }
832*4882a593Smuzhiyun
dbg_rtw_skb_alloc(unsigned int size,const enum mstat_f flags,const char * func,int line)833*4882a593Smuzhiyun inline struct sk_buff *dbg_rtw_skb_alloc(unsigned int size, const enum mstat_f flags, const char *func, int line)
834*4882a593Smuzhiyun {
835*4882a593Smuzhiyun struct sk_buff *skb;
836*4882a593Smuzhiyun unsigned int truesize = 0;
837*4882a593Smuzhiyun
838*4882a593Smuzhiyun skb = _rtw_skb_alloc(size);
839*4882a593Smuzhiyun
840*4882a593Smuzhiyun if (skb)
841*4882a593Smuzhiyun truesize = skb->truesize;
842*4882a593Smuzhiyun
843*4882a593Smuzhiyun if (!skb || truesize < size || match_mstat_sniff_rules(flags, truesize))
844*4882a593Smuzhiyun RTW_INFO("DBG_MEM_ALLOC %s:%d %s(%d), skb:%p, truesize=%u\n", func, line, __FUNCTION__, size, skb, truesize);
845*4882a593Smuzhiyun
846*4882a593Smuzhiyun rtw_mstat_update(
847*4882a593Smuzhiyun flags
848*4882a593Smuzhiyun , skb ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL
849*4882a593Smuzhiyun , truesize
850*4882a593Smuzhiyun );
851*4882a593Smuzhiyun
852*4882a593Smuzhiyun return skb;
853*4882a593Smuzhiyun }
854*4882a593Smuzhiyun
dbg_rtw_skb_free(struct sk_buff * skb,const enum mstat_f flags,const char * func,int line)855*4882a593Smuzhiyun inline void dbg_rtw_skb_free(struct sk_buff *skb, const enum mstat_f flags, const char *func, int line)
856*4882a593Smuzhiyun {
857*4882a593Smuzhiyun unsigned int truesize = skb->truesize;
858*4882a593Smuzhiyun
859*4882a593Smuzhiyun if (match_mstat_sniff_rules(flags, truesize))
860*4882a593Smuzhiyun RTW_INFO("DBG_MEM_ALLOC %s:%d %s, truesize=%u\n", func, line, __FUNCTION__, truesize);
861*4882a593Smuzhiyun
862*4882a593Smuzhiyun _rtw_skb_free(skb);
863*4882a593Smuzhiyun
864*4882a593Smuzhiyun rtw_mstat_update(
865*4882a593Smuzhiyun flags
866*4882a593Smuzhiyun , MSTAT_FREE
867*4882a593Smuzhiyun , truesize
868*4882a593Smuzhiyun );
869*4882a593Smuzhiyun }
870*4882a593Smuzhiyun
dbg_rtw_skb_copy(const struct sk_buff * skb,const enum mstat_f flags,const char * func,const int line)871*4882a593Smuzhiyun inline struct sk_buff *dbg_rtw_skb_copy(const struct sk_buff *skb, const enum mstat_f flags, const char *func, const int line)
872*4882a593Smuzhiyun {
873*4882a593Smuzhiyun struct sk_buff *skb_cp;
874*4882a593Smuzhiyun unsigned int truesize = skb->truesize;
875*4882a593Smuzhiyun unsigned int cp_truesize = 0;
876*4882a593Smuzhiyun
877*4882a593Smuzhiyun skb_cp = _rtw_skb_copy(skb);
878*4882a593Smuzhiyun if (skb_cp)
879*4882a593Smuzhiyun cp_truesize = skb_cp->truesize;
880*4882a593Smuzhiyun
881*4882a593Smuzhiyun if (!skb_cp || cp_truesize < truesize || match_mstat_sniff_rules(flags, cp_truesize))
882*4882a593Smuzhiyun RTW_INFO("DBG_MEM_ALLOC %s:%d %s(%u), skb_cp:%p, cp_truesize=%u\n", func, line, __FUNCTION__, truesize, skb_cp, cp_truesize);
883*4882a593Smuzhiyun
884*4882a593Smuzhiyun rtw_mstat_update(
885*4882a593Smuzhiyun flags
886*4882a593Smuzhiyun , skb_cp ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL
887*4882a593Smuzhiyun , cp_truesize
888*4882a593Smuzhiyun );
889*4882a593Smuzhiyun
890*4882a593Smuzhiyun return skb_cp;
891*4882a593Smuzhiyun }
892*4882a593Smuzhiyun
dbg_rtw_skb_clone(struct sk_buff * skb,const enum mstat_f flags,const char * func,const int line)893*4882a593Smuzhiyun inline struct sk_buff *dbg_rtw_skb_clone(struct sk_buff *skb, const enum mstat_f flags, const char *func, const int line)
894*4882a593Smuzhiyun {
895*4882a593Smuzhiyun struct sk_buff *skb_cl;
896*4882a593Smuzhiyun unsigned int truesize = skb->truesize;
897*4882a593Smuzhiyun unsigned int cl_truesize = 0;
898*4882a593Smuzhiyun
899*4882a593Smuzhiyun skb_cl = _rtw_skb_clone(skb);
900*4882a593Smuzhiyun if (skb_cl)
901*4882a593Smuzhiyun cl_truesize = skb_cl->truesize;
902*4882a593Smuzhiyun
903*4882a593Smuzhiyun if (!skb_cl || cl_truesize < truesize || match_mstat_sniff_rules(flags, cl_truesize))
904*4882a593Smuzhiyun RTW_INFO("DBG_MEM_ALLOC %s:%d %s(%u), skb_cl:%p, cl_truesize=%u\n", func, line, __FUNCTION__, truesize, skb_cl, cl_truesize);
905*4882a593Smuzhiyun
906*4882a593Smuzhiyun rtw_mstat_update(
907*4882a593Smuzhiyun flags
908*4882a593Smuzhiyun , skb_cl ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL
909*4882a593Smuzhiyun , cl_truesize
910*4882a593Smuzhiyun );
911*4882a593Smuzhiyun
912*4882a593Smuzhiyun return skb_cl;
913*4882a593Smuzhiyun }
914*4882a593Smuzhiyun
dbg_rtw_netif_rx(_nic_hdl ndev,struct sk_buff * skb,const enum mstat_f flags,const char * func,int line)915*4882a593Smuzhiyun inline int dbg_rtw_netif_rx(_nic_hdl ndev, struct sk_buff *skb, const enum mstat_f flags, const char *func, int line)
916*4882a593Smuzhiyun {
917*4882a593Smuzhiyun int ret;
918*4882a593Smuzhiyun unsigned int truesize = skb->truesize;
919*4882a593Smuzhiyun
920*4882a593Smuzhiyun if (match_mstat_sniff_rules(flags, truesize))
921*4882a593Smuzhiyun RTW_INFO("DBG_MEM_ALLOC %s:%d %s, truesize=%u\n", func, line, __FUNCTION__, truesize);
922*4882a593Smuzhiyun
923*4882a593Smuzhiyun ret = _rtw_netif_rx(ndev, skb);
924*4882a593Smuzhiyun
925*4882a593Smuzhiyun rtw_mstat_update(
926*4882a593Smuzhiyun flags
927*4882a593Smuzhiyun , MSTAT_FREE
928*4882a593Smuzhiyun , truesize
929*4882a593Smuzhiyun );
930*4882a593Smuzhiyun
931*4882a593Smuzhiyun return ret;
932*4882a593Smuzhiyun }
933*4882a593Smuzhiyun
934*4882a593Smuzhiyun #ifdef CONFIG_RTW_NAPI
dbg_rtw_netif_receive_skb(_nic_hdl ndev,struct sk_buff * skb,const enum mstat_f flags,const char * func,int line)935*4882a593Smuzhiyun inline int dbg_rtw_netif_receive_skb(_nic_hdl ndev, struct sk_buff *skb, const enum mstat_f flags, const char *func, int line)
936*4882a593Smuzhiyun {
937*4882a593Smuzhiyun int ret;
938*4882a593Smuzhiyun unsigned int truesize = skb->truesize;
939*4882a593Smuzhiyun
940*4882a593Smuzhiyun if (match_mstat_sniff_rules(flags, truesize))
941*4882a593Smuzhiyun RTW_INFO("DBG_MEM_ALLOC %s:%d %s, truesize=%u\n", func, line, __FUNCTION__, truesize);
942*4882a593Smuzhiyun
943*4882a593Smuzhiyun ret = _rtw_netif_receive_skb(ndev, skb);
944*4882a593Smuzhiyun
945*4882a593Smuzhiyun rtw_mstat_update(
946*4882a593Smuzhiyun flags
947*4882a593Smuzhiyun , MSTAT_FREE
948*4882a593Smuzhiyun , truesize
949*4882a593Smuzhiyun );
950*4882a593Smuzhiyun
951*4882a593Smuzhiyun return ret;
952*4882a593Smuzhiyun }
953*4882a593Smuzhiyun
954*4882a593Smuzhiyun #ifdef CONFIG_RTW_GRO
dbg_rtw_napi_gro_receive(struct napi_struct * napi,struct sk_buff * skb,const enum mstat_f flags,const char * func,int line)955*4882a593Smuzhiyun inline gro_result_t dbg_rtw_napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb, const enum mstat_f flags, const char *func, int line)
956*4882a593Smuzhiyun {
957*4882a593Smuzhiyun int ret;
958*4882a593Smuzhiyun unsigned int truesize = skb->truesize;
959*4882a593Smuzhiyun
960*4882a593Smuzhiyun if (match_mstat_sniff_rules(flags, truesize))
961*4882a593Smuzhiyun RTW_INFO("DBG_MEM_ALLOC %s:%d %s, truesize=%u\n", func, line, __FUNCTION__, truesize);
962*4882a593Smuzhiyun
963*4882a593Smuzhiyun ret = _rtw_napi_gro_receive(napi, skb);
964*4882a593Smuzhiyun
965*4882a593Smuzhiyun rtw_mstat_update(
966*4882a593Smuzhiyun flags
967*4882a593Smuzhiyun , MSTAT_FREE
968*4882a593Smuzhiyun , truesize
969*4882a593Smuzhiyun );
970*4882a593Smuzhiyun
971*4882a593Smuzhiyun return ret;
972*4882a593Smuzhiyun }
973*4882a593Smuzhiyun #endif /* CONFIG_RTW_GRO */
974*4882a593Smuzhiyun #endif /* CONFIG_RTW_NAPI */
975*4882a593Smuzhiyun
dbg_rtw_skb_queue_purge(struct sk_buff_head * list,enum mstat_f flags,const char * func,int line)976*4882a593Smuzhiyun inline void dbg_rtw_skb_queue_purge(struct sk_buff_head *list, enum mstat_f flags, const char *func, int line)
977*4882a593Smuzhiyun {
978*4882a593Smuzhiyun struct sk_buff *skb;
979*4882a593Smuzhiyun
980*4882a593Smuzhiyun while ((skb = skb_dequeue(list)) != NULL)
981*4882a593Smuzhiyun dbg_rtw_skb_free(skb, flags, func, line);
982*4882a593Smuzhiyun }
983*4882a593Smuzhiyun
984*4882a593Smuzhiyun #ifdef CONFIG_USB_HCI
dbg_rtw_usb_buffer_alloc(struct usb_device * dev,size_t size,dma_addr_t * dma,const enum mstat_f flags,const char * func,int line)985*4882a593Smuzhiyun inline void *dbg_rtw_usb_buffer_alloc(struct usb_device *dev, size_t size, dma_addr_t *dma, const enum mstat_f flags, const char *func, int line)
986*4882a593Smuzhiyun {
987*4882a593Smuzhiyun void *p;
988*4882a593Smuzhiyun
989*4882a593Smuzhiyun if (match_mstat_sniff_rules(flags, size))
990*4882a593Smuzhiyun RTW_INFO("DBG_MEM_ALLOC %s:%d %s(%zu)\n", func, line, __FUNCTION__, size);
991*4882a593Smuzhiyun
992*4882a593Smuzhiyun p = _rtw_usb_buffer_alloc(dev, size, dma);
993*4882a593Smuzhiyun
994*4882a593Smuzhiyun rtw_mstat_update(
995*4882a593Smuzhiyun flags
996*4882a593Smuzhiyun , p ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL
997*4882a593Smuzhiyun , size
998*4882a593Smuzhiyun );
999*4882a593Smuzhiyun
1000*4882a593Smuzhiyun return p;
1001*4882a593Smuzhiyun }
1002*4882a593Smuzhiyun
dbg_rtw_usb_buffer_free(struct usb_device * dev,size_t size,void * addr,dma_addr_t dma,const enum mstat_f flags,const char * func,int line)1003*4882a593Smuzhiyun inline void dbg_rtw_usb_buffer_free(struct usb_device *dev, size_t size, void *addr, dma_addr_t dma, const enum mstat_f flags, const char *func, int line)
1004*4882a593Smuzhiyun {
1005*4882a593Smuzhiyun
1006*4882a593Smuzhiyun if (match_mstat_sniff_rules(flags, size))
1007*4882a593Smuzhiyun RTW_INFO("DBG_MEM_ALLOC %s:%d %s(%zu)\n", func, line, __FUNCTION__, size);
1008*4882a593Smuzhiyun
1009*4882a593Smuzhiyun _rtw_usb_buffer_free(dev, size, addr, dma);
1010*4882a593Smuzhiyun
1011*4882a593Smuzhiyun rtw_mstat_update(
1012*4882a593Smuzhiyun flags
1013*4882a593Smuzhiyun , MSTAT_FREE
1014*4882a593Smuzhiyun , size
1015*4882a593Smuzhiyun );
1016*4882a593Smuzhiyun }
1017*4882a593Smuzhiyun #endif /* CONFIG_USB_HCI */
1018*4882a593Smuzhiyun
1019*4882a593Smuzhiyun #endif /* defined(DBG_MEM_ALLOC) */
1020*4882a593Smuzhiyun
rtw_malloc2d(int h,int w,size_t size)1021*4882a593Smuzhiyun void *rtw_malloc2d(int h, int w, size_t size)
1022*4882a593Smuzhiyun {
1023*4882a593Smuzhiyun int j;
1024*4882a593Smuzhiyun
1025*4882a593Smuzhiyun void **a = (void **) rtw_zmalloc(h * sizeof(void *) + h * w * size);
1026*4882a593Smuzhiyun if (a == NULL) {
1027*4882a593Smuzhiyun RTW_INFO("%s: alloc memory fail!\n", __FUNCTION__);
1028*4882a593Smuzhiyun return NULL;
1029*4882a593Smuzhiyun }
1030*4882a593Smuzhiyun
1031*4882a593Smuzhiyun for (j = 0; j < h; j++)
1032*4882a593Smuzhiyun a[j] = ((char *)(a + h)) + j * w * size;
1033*4882a593Smuzhiyun
1034*4882a593Smuzhiyun return a;
1035*4882a593Smuzhiyun }
1036*4882a593Smuzhiyun
rtw_mfree2d(void * pbuf,int h,int w,int size)1037*4882a593Smuzhiyun void rtw_mfree2d(void *pbuf, int h, int w, int size)
1038*4882a593Smuzhiyun {
1039*4882a593Smuzhiyun rtw_mfree((u8 *)pbuf, h * sizeof(void *) + w * h * size);
1040*4882a593Smuzhiyun }
1041*4882a593Smuzhiyun
rtw_os_pkt_free(_pkt * pkt)1042*4882a593Smuzhiyun inline void rtw_os_pkt_free(_pkt *pkt)
1043*4882a593Smuzhiyun {
1044*4882a593Smuzhiyun #if defined(PLATFORM_LINUX)
1045*4882a593Smuzhiyun rtw_skb_free(pkt);
1046*4882a593Smuzhiyun #elif defined(PLATFORM_FREEBSD)
1047*4882a593Smuzhiyun m_freem(pkt);
1048*4882a593Smuzhiyun #else
1049*4882a593Smuzhiyun #error "TBD\n"
1050*4882a593Smuzhiyun #endif
1051*4882a593Smuzhiyun }
1052*4882a593Smuzhiyun
rtw_os_pkt_copy(_pkt * pkt)1053*4882a593Smuzhiyun inline _pkt *rtw_os_pkt_copy(_pkt *pkt)
1054*4882a593Smuzhiyun {
1055*4882a593Smuzhiyun #if defined(PLATFORM_LINUX)
1056*4882a593Smuzhiyun return rtw_skb_copy(pkt);
1057*4882a593Smuzhiyun #elif defined(PLATFORM_FREEBSD)
1058*4882a593Smuzhiyun return m_dup(pkt, M_NOWAIT);
1059*4882a593Smuzhiyun #else
1060*4882a593Smuzhiyun #error "TBD\n"
1061*4882a593Smuzhiyun #endif
1062*4882a593Smuzhiyun }
1063*4882a593Smuzhiyun
rtw_os_pkt_data(_pkt * pkt)1064*4882a593Smuzhiyun inline void *rtw_os_pkt_data(_pkt *pkt)
1065*4882a593Smuzhiyun {
1066*4882a593Smuzhiyun #if defined(PLATFORM_LINUX)
1067*4882a593Smuzhiyun return pkt->data;
1068*4882a593Smuzhiyun #elif defined(PLATFORM_FREEBSD)
1069*4882a593Smuzhiyun return pkt->m_data;
1070*4882a593Smuzhiyun #else
1071*4882a593Smuzhiyun #error "TBD\n"
1072*4882a593Smuzhiyun #endif
1073*4882a593Smuzhiyun }
1074*4882a593Smuzhiyun
rtw_os_pkt_len(_pkt * pkt)1075*4882a593Smuzhiyun inline u32 rtw_os_pkt_len(_pkt *pkt)
1076*4882a593Smuzhiyun {
1077*4882a593Smuzhiyun #if defined(PLATFORM_LINUX)
1078*4882a593Smuzhiyun return pkt->len;
1079*4882a593Smuzhiyun #elif defined(PLATFORM_FREEBSD)
1080*4882a593Smuzhiyun return pkt->m_pkthdr.len;
1081*4882a593Smuzhiyun #else
1082*4882a593Smuzhiyun #error "TBD\n"
1083*4882a593Smuzhiyun #endif
1084*4882a593Smuzhiyun }
1085*4882a593Smuzhiyun
_rtw_memcpy(void * dst,const void * src,u32 sz)1086*4882a593Smuzhiyun void _rtw_memcpy(void *dst, const void *src, u32 sz)
1087*4882a593Smuzhiyun {
1088*4882a593Smuzhiyun
1089*4882a593Smuzhiyun #if defined(PLATFORM_LINUX) || defined (PLATFORM_FREEBSD)
1090*4882a593Smuzhiyun
1091*4882a593Smuzhiyun memcpy(dst, src, sz);
1092*4882a593Smuzhiyun
1093*4882a593Smuzhiyun #endif
1094*4882a593Smuzhiyun
1095*4882a593Smuzhiyun #ifdef PLATFORM_WINDOWS
1096*4882a593Smuzhiyun
1097*4882a593Smuzhiyun NdisMoveMemory(dst, src, sz);
1098*4882a593Smuzhiyun
1099*4882a593Smuzhiyun #endif
1100*4882a593Smuzhiyun
1101*4882a593Smuzhiyun }
1102*4882a593Smuzhiyun
_rtw_memmove(void * dst,const void * src,u32 sz)1103*4882a593Smuzhiyun inline void _rtw_memmove(void *dst, const void *src, u32 sz)
1104*4882a593Smuzhiyun {
1105*4882a593Smuzhiyun #if defined(PLATFORM_LINUX)
1106*4882a593Smuzhiyun memmove(dst, src, sz);
1107*4882a593Smuzhiyun #else
1108*4882a593Smuzhiyun #error "TBD\n"
1109*4882a593Smuzhiyun #endif
1110*4882a593Smuzhiyun }
1111*4882a593Smuzhiyun
_rtw_memcmp(const void * dst,const void * src,u32 sz)1112*4882a593Smuzhiyun int _rtw_memcmp(const void *dst, const void *src, u32 sz)
1113*4882a593Smuzhiyun {
1114*4882a593Smuzhiyun
1115*4882a593Smuzhiyun #if defined(PLATFORM_LINUX) || defined (PLATFORM_FREEBSD)
1116*4882a593Smuzhiyun /* under Linux/GNU/GLibc, the return value of memcmp for two same mem. chunk is 0 */
1117*4882a593Smuzhiyun
1118*4882a593Smuzhiyun if (!(memcmp(dst, src, sz)))
1119*4882a593Smuzhiyun return _TRUE;
1120*4882a593Smuzhiyun else
1121*4882a593Smuzhiyun return _FALSE;
1122*4882a593Smuzhiyun #endif
1123*4882a593Smuzhiyun
1124*4882a593Smuzhiyun
1125*4882a593Smuzhiyun #ifdef PLATFORM_WINDOWS
1126*4882a593Smuzhiyun /* under Windows, the return value of NdisEqualMemory for two same mem. chunk is 1 */
1127*4882a593Smuzhiyun
1128*4882a593Smuzhiyun if (NdisEqualMemory(dst, src, sz))
1129*4882a593Smuzhiyun return _TRUE;
1130*4882a593Smuzhiyun else
1131*4882a593Smuzhiyun return _FALSE;
1132*4882a593Smuzhiyun
1133*4882a593Smuzhiyun #endif
1134*4882a593Smuzhiyun
1135*4882a593Smuzhiyun
1136*4882a593Smuzhiyun
1137*4882a593Smuzhiyun }
1138*4882a593Smuzhiyun
_rtw_memcmp2(const void * dst,const void * src,u32 sz)1139*4882a593Smuzhiyun int _rtw_memcmp2(const void *dst, const void *src, u32 sz)
1140*4882a593Smuzhiyun {
1141*4882a593Smuzhiyun const unsigned char *p1 = dst, *p2 = src;
1142*4882a593Smuzhiyun
1143*4882a593Smuzhiyun if (sz == 0)
1144*4882a593Smuzhiyun return 0;
1145*4882a593Smuzhiyun
1146*4882a593Smuzhiyun while (*p1 == *p2) {
1147*4882a593Smuzhiyun p1++;
1148*4882a593Smuzhiyun p2++;
1149*4882a593Smuzhiyun sz--;
1150*4882a593Smuzhiyun if (sz == 0)
1151*4882a593Smuzhiyun return 0;
1152*4882a593Smuzhiyun }
1153*4882a593Smuzhiyun
1154*4882a593Smuzhiyun return *p1 - *p2;
1155*4882a593Smuzhiyun }
1156*4882a593Smuzhiyun
_rtw_memset(void * pbuf,int c,u32 sz)1157*4882a593Smuzhiyun void _rtw_memset(void *pbuf, int c, u32 sz)
1158*4882a593Smuzhiyun {
1159*4882a593Smuzhiyun
1160*4882a593Smuzhiyun #if defined(PLATFORM_LINUX) || defined (PLATFORM_FREEBSD)
1161*4882a593Smuzhiyun
1162*4882a593Smuzhiyun memset(pbuf, c, sz);
1163*4882a593Smuzhiyun
1164*4882a593Smuzhiyun #endif
1165*4882a593Smuzhiyun
1166*4882a593Smuzhiyun #ifdef PLATFORM_WINDOWS
1167*4882a593Smuzhiyun #if 0
1168*4882a593Smuzhiyun NdisZeroMemory(pbuf, sz);
1169*4882a593Smuzhiyun if (c != 0)
1170*4882a593Smuzhiyun memset(pbuf, c, sz);
1171*4882a593Smuzhiyun #else
1172*4882a593Smuzhiyun NdisFillMemory(pbuf, sz, c);
1173*4882a593Smuzhiyun #endif
1174*4882a593Smuzhiyun #endif
1175*4882a593Smuzhiyun
1176*4882a593Smuzhiyun }
1177*4882a593Smuzhiyun
1178*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
__list_add(_list * pnew,_list * pprev,_list * pnext)1179*4882a593Smuzhiyun static inline void __list_add(_list *pnew, _list *pprev, _list *pnext)
1180*4882a593Smuzhiyun {
1181*4882a593Smuzhiyun pnext->prev = pnew;
1182*4882a593Smuzhiyun pnew->next = pnext;
1183*4882a593Smuzhiyun pnew->prev = pprev;
1184*4882a593Smuzhiyun pprev->next = pnew;
1185*4882a593Smuzhiyun }
1186*4882a593Smuzhiyun #endif /* PLATFORM_FREEBSD */
1187*4882a593Smuzhiyun
1188*4882a593Smuzhiyun
_rtw_init_listhead(_list * list)1189*4882a593Smuzhiyun void _rtw_init_listhead(_list *list)
1190*4882a593Smuzhiyun {
1191*4882a593Smuzhiyun
1192*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1193*4882a593Smuzhiyun
1194*4882a593Smuzhiyun INIT_LIST_HEAD(list);
1195*4882a593Smuzhiyun
1196*4882a593Smuzhiyun #endif
1197*4882a593Smuzhiyun
1198*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
1199*4882a593Smuzhiyun list->next = list;
1200*4882a593Smuzhiyun list->prev = list;
1201*4882a593Smuzhiyun #endif
1202*4882a593Smuzhiyun #ifdef PLATFORM_WINDOWS
1203*4882a593Smuzhiyun
1204*4882a593Smuzhiyun NdisInitializeListHead(list);
1205*4882a593Smuzhiyun
1206*4882a593Smuzhiyun #endif
1207*4882a593Smuzhiyun
1208*4882a593Smuzhiyun }
1209*4882a593Smuzhiyun
1210*4882a593Smuzhiyun
1211*4882a593Smuzhiyun /*
1212*4882a593Smuzhiyun For the following list_xxx operations,
1213*4882a593Smuzhiyun caller must guarantee the atomic context.
1214*4882a593Smuzhiyun Otherwise, there will be racing condition.
1215*4882a593Smuzhiyun */
rtw_is_list_empty(_list * phead)1216*4882a593Smuzhiyun u32 rtw_is_list_empty(_list *phead)
1217*4882a593Smuzhiyun {
1218*4882a593Smuzhiyun
1219*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1220*4882a593Smuzhiyun
1221*4882a593Smuzhiyun if (list_empty(phead))
1222*4882a593Smuzhiyun return _TRUE;
1223*4882a593Smuzhiyun else
1224*4882a593Smuzhiyun return _FALSE;
1225*4882a593Smuzhiyun
1226*4882a593Smuzhiyun #endif
1227*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
1228*4882a593Smuzhiyun
1229*4882a593Smuzhiyun if (phead->next == phead)
1230*4882a593Smuzhiyun return _TRUE;
1231*4882a593Smuzhiyun else
1232*4882a593Smuzhiyun return _FALSE;
1233*4882a593Smuzhiyun
1234*4882a593Smuzhiyun #endif
1235*4882a593Smuzhiyun
1236*4882a593Smuzhiyun
1237*4882a593Smuzhiyun #ifdef PLATFORM_WINDOWS
1238*4882a593Smuzhiyun
1239*4882a593Smuzhiyun if (IsListEmpty(phead))
1240*4882a593Smuzhiyun return _TRUE;
1241*4882a593Smuzhiyun else
1242*4882a593Smuzhiyun return _FALSE;
1243*4882a593Smuzhiyun
1244*4882a593Smuzhiyun #endif
1245*4882a593Smuzhiyun
1246*4882a593Smuzhiyun
1247*4882a593Smuzhiyun }
1248*4882a593Smuzhiyun
rtw_list_insert_head(_list * plist,_list * phead)1249*4882a593Smuzhiyun void rtw_list_insert_head(_list *plist, _list *phead)
1250*4882a593Smuzhiyun {
1251*4882a593Smuzhiyun
1252*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1253*4882a593Smuzhiyun list_add(plist, phead);
1254*4882a593Smuzhiyun #endif
1255*4882a593Smuzhiyun
1256*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
1257*4882a593Smuzhiyun __list_add(plist, phead, phead->next);
1258*4882a593Smuzhiyun #endif
1259*4882a593Smuzhiyun
1260*4882a593Smuzhiyun #ifdef PLATFORM_WINDOWS
1261*4882a593Smuzhiyun InsertHeadList(phead, plist);
1262*4882a593Smuzhiyun #endif
1263*4882a593Smuzhiyun }
1264*4882a593Smuzhiyun
rtw_list_insert_tail(_list * plist,_list * phead)1265*4882a593Smuzhiyun void rtw_list_insert_tail(_list *plist, _list *phead)
1266*4882a593Smuzhiyun {
1267*4882a593Smuzhiyun
1268*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1269*4882a593Smuzhiyun
1270*4882a593Smuzhiyun list_add_tail(plist, phead);
1271*4882a593Smuzhiyun
1272*4882a593Smuzhiyun #endif
1273*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
1274*4882a593Smuzhiyun
1275*4882a593Smuzhiyun __list_add(plist, phead->prev, phead);
1276*4882a593Smuzhiyun
1277*4882a593Smuzhiyun #endif
1278*4882a593Smuzhiyun #ifdef PLATFORM_WINDOWS
1279*4882a593Smuzhiyun
1280*4882a593Smuzhiyun InsertTailList(phead, plist);
1281*4882a593Smuzhiyun
1282*4882a593Smuzhiyun #endif
1283*4882a593Smuzhiyun
1284*4882a593Smuzhiyun }
1285*4882a593Smuzhiyun
rtw_list_splice(_list * list,_list * head)1286*4882a593Smuzhiyun inline void rtw_list_splice(_list *list, _list *head)
1287*4882a593Smuzhiyun {
1288*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1289*4882a593Smuzhiyun list_splice(list, head);
1290*4882a593Smuzhiyun #else
1291*4882a593Smuzhiyun #error "TBD\n"
1292*4882a593Smuzhiyun #endif
1293*4882a593Smuzhiyun }
1294*4882a593Smuzhiyun
rtw_list_splice_init(_list * list,_list * head)1295*4882a593Smuzhiyun inline void rtw_list_splice_init(_list *list, _list *head)
1296*4882a593Smuzhiyun {
1297*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1298*4882a593Smuzhiyun list_splice_init(list, head);
1299*4882a593Smuzhiyun #else
1300*4882a593Smuzhiyun #error "TBD\n"
1301*4882a593Smuzhiyun #endif
1302*4882a593Smuzhiyun }
1303*4882a593Smuzhiyun
rtw_list_splice_tail(_list * list,_list * head)1304*4882a593Smuzhiyun inline void rtw_list_splice_tail(_list *list, _list *head)
1305*4882a593Smuzhiyun {
1306*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1307*4882a593Smuzhiyun #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27))
1308*4882a593Smuzhiyun if (!list_empty(list))
1309*4882a593Smuzhiyun __list_splice(list, head);
1310*4882a593Smuzhiyun #else
1311*4882a593Smuzhiyun list_splice_tail(list, head);
1312*4882a593Smuzhiyun #endif
1313*4882a593Smuzhiyun #else
1314*4882a593Smuzhiyun #error "TBD\n"
1315*4882a593Smuzhiyun #endif
1316*4882a593Smuzhiyun }
1317*4882a593Smuzhiyun
rtw_hlist_head_init(rtw_hlist_head * h)1318*4882a593Smuzhiyun inline void rtw_hlist_head_init(rtw_hlist_head *h)
1319*4882a593Smuzhiyun {
1320*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1321*4882a593Smuzhiyun INIT_HLIST_HEAD(h);
1322*4882a593Smuzhiyun #else
1323*4882a593Smuzhiyun #error "TBD\n"
1324*4882a593Smuzhiyun #endif
1325*4882a593Smuzhiyun }
1326*4882a593Smuzhiyun
rtw_hlist_add_head(rtw_hlist_node * n,rtw_hlist_head * h)1327*4882a593Smuzhiyun inline void rtw_hlist_add_head(rtw_hlist_node *n, rtw_hlist_head *h)
1328*4882a593Smuzhiyun {
1329*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1330*4882a593Smuzhiyun hlist_add_head(n, h);
1331*4882a593Smuzhiyun #else
1332*4882a593Smuzhiyun #error "TBD\n"
1333*4882a593Smuzhiyun #endif
1334*4882a593Smuzhiyun }
1335*4882a593Smuzhiyun
rtw_hlist_del(rtw_hlist_node * n)1336*4882a593Smuzhiyun inline void rtw_hlist_del(rtw_hlist_node *n)
1337*4882a593Smuzhiyun {
1338*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1339*4882a593Smuzhiyun hlist_del(n);
1340*4882a593Smuzhiyun #else
1341*4882a593Smuzhiyun #error "TBD\n"
1342*4882a593Smuzhiyun #endif
1343*4882a593Smuzhiyun }
1344*4882a593Smuzhiyun
rtw_hlist_add_head_rcu(rtw_hlist_node * n,rtw_hlist_head * h)1345*4882a593Smuzhiyun inline void rtw_hlist_add_head_rcu(rtw_hlist_node *n, rtw_hlist_head *h)
1346*4882a593Smuzhiyun {
1347*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1348*4882a593Smuzhiyun hlist_add_head_rcu(n, h);
1349*4882a593Smuzhiyun #else
1350*4882a593Smuzhiyun #error "TBD\n"
1351*4882a593Smuzhiyun #endif
1352*4882a593Smuzhiyun }
1353*4882a593Smuzhiyun
rtw_hlist_del_rcu(rtw_hlist_node * n)1354*4882a593Smuzhiyun inline void rtw_hlist_del_rcu(rtw_hlist_node *n)
1355*4882a593Smuzhiyun {
1356*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1357*4882a593Smuzhiyun hlist_del_rcu(n);
1358*4882a593Smuzhiyun #else
1359*4882a593Smuzhiyun #error "TBD\n"
1360*4882a593Smuzhiyun #endif
1361*4882a593Smuzhiyun }
1362*4882a593Smuzhiyun
rtw_init_timer(_timer * ptimer,void * padapter,void * pfunc,void * ctx)1363*4882a593Smuzhiyun void rtw_init_timer(_timer *ptimer, void *padapter, void *pfunc, void *ctx)
1364*4882a593Smuzhiyun {
1365*4882a593Smuzhiyun _adapter *adapter = (_adapter *)padapter;
1366*4882a593Smuzhiyun
1367*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1368*4882a593Smuzhiyun _init_timer(ptimer, adapter->pnetdev, pfunc, ctx);
1369*4882a593Smuzhiyun #endif
1370*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
1371*4882a593Smuzhiyun _init_timer(ptimer, adapter->pifp, pfunc, ctx);
1372*4882a593Smuzhiyun #endif
1373*4882a593Smuzhiyun #ifdef PLATFORM_WINDOWS
1374*4882a593Smuzhiyun _init_timer(ptimer, adapter->hndis_adapter, pfunc, ctx);
1375*4882a593Smuzhiyun #endif
1376*4882a593Smuzhiyun }
1377*4882a593Smuzhiyun
1378*4882a593Smuzhiyun /*
1379*4882a593Smuzhiyun
1380*4882a593Smuzhiyun Caller must check if the list is empty before calling rtw_list_delete
1381*4882a593Smuzhiyun
1382*4882a593Smuzhiyun */
1383*4882a593Smuzhiyun
1384*4882a593Smuzhiyun
_rtw_init_sema(_sema * sema,int init_val)1385*4882a593Smuzhiyun void _rtw_init_sema(_sema *sema, int init_val)
1386*4882a593Smuzhiyun {
1387*4882a593Smuzhiyun
1388*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1389*4882a593Smuzhiyun
1390*4882a593Smuzhiyun sema_init(sema, init_val);
1391*4882a593Smuzhiyun
1392*4882a593Smuzhiyun #endif
1393*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
1394*4882a593Smuzhiyun sema_init(sema, init_val, "rtw_drv");
1395*4882a593Smuzhiyun #endif
1396*4882a593Smuzhiyun #ifdef PLATFORM_OS_XP
1397*4882a593Smuzhiyun
1398*4882a593Smuzhiyun KeInitializeSemaphore(sema, init_val, SEMA_UPBND); /* count=0; */
1399*4882a593Smuzhiyun
1400*4882a593Smuzhiyun #endif
1401*4882a593Smuzhiyun
1402*4882a593Smuzhiyun #ifdef PLATFORM_OS_CE
1403*4882a593Smuzhiyun if (*sema == NULL)
1404*4882a593Smuzhiyun *sema = CreateSemaphore(NULL, init_val, SEMA_UPBND, NULL);
1405*4882a593Smuzhiyun #endif
1406*4882a593Smuzhiyun
1407*4882a593Smuzhiyun }
1408*4882a593Smuzhiyun
_rtw_free_sema(_sema * sema)1409*4882a593Smuzhiyun void _rtw_free_sema(_sema *sema)
1410*4882a593Smuzhiyun {
1411*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
1412*4882a593Smuzhiyun sema_destroy(sema);
1413*4882a593Smuzhiyun #endif
1414*4882a593Smuzhiyun #ifdef PLATFORM_OS_CE
1415*4882a593Smuzhiyun CloseHandle(*sema);
1416*4882a593Smuzhiyun #endif
1417*4882a593Smuzhiyun
1418*4882a593Smuzhiyun }
1419*4882a593Smuzhiyun
_rtw_up_sema(_sema * sema)1420*4882a593Smuzhiyun void _rtw_up_sema(_sema *sema)
1421*4882a593Smuzhiyun {
1422*4882a593Smuzhiyun
1423*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1424*4882a593Smuzhiyun
1425*4882a593Smuzhiyun up(sema);
1426*4882a593Smuzhiyun
1427*4882a593Smuzhiyun #endif
1428*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
1429*4882a593Smuzhiyun sema_post(sema);
1430*4882a593Smuzhiyun #endif
1431*4882a593Smuzhiyun #ifdef PLATFORM_OS_XP
1432*4882a593Smuzhiyun
1433*4882a593Smuzhiyun KeReleaseSemaphore(sema, IO_NETWORK_INCREMENT, 1, FALSE);
1434*4882a593Smuzhiyun
1435*4882a593Smuzhiyun #endif
1436*4882a593Smuzhiyun
1437*4882a593Smuzhiyun #ifdef PLATFORM_OS_CE
1438*4882a593Smuzhiyun ReleaseSemaphore(*sema, 1, NULL);
1439*4882a593Smuzhiyun #endif
1440*4882a593Smuzhiyun }
1441*4882a593Smuzhiyun
_rtw_down_sema(_sema * sema)1442*4882a593Smuzhiyun u32 _rtw_down_sema(_sema *sema)
1443*4882a593Smuzhiyun {
1444*4882a593Smuzhiyun
1445*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1446*4882a593Smuzhiyun
1447*4882a593Smuzhiyun if (down_killable(sema))
1448*4882a593Smuzhiyun return _FAIL;
1449*4882a593Smuzhiyun else
1450*4882a593Smuzhiyun return _SUCCESS;
1451*4882a593Smuzhiyun
1452*4882a593Smuzhiyun #endif
1453*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
1454*4882a593Smuzhiyun sema_wait(sema);
1455*4882a593Smuzhiyun return _SUCCESS;
1456*4882a593Smuzhiyun #endif
1457*4882a593Smuzhiyun #ifdef PLATFORM_OS_XP
1458*4882a593Smuzhiyun
1459*4882a593Smuzhiyun if (STATUS_SUCCESS == KeWaitForSingleObject(sema, Executive, KernelMode, TRUE, NULL))
1460*4882a593Smuzhiyun return _SUCCESS;
1461*4882a593Smuzhiyun else
1462*4882a593Smuzhiyun return _FAIL;
1463*4882a593Smuzhiyun #endif
1464*4882a593Smuzhiyun
1465*4882a593Smuzhiyun #ifdef PLATFORM_OS_CE
1466*4882a593Smuzhiyun if (WAIT_OBJECT_0 == WaitForSingleObject(*sema, INFINITE))
1467*4882a593Smuzhiyun return _SUCCESS;
1468*4882a593Smuzhiyun else
1469*4882a593Smuzhiyun return _FAIL;
1470*4882a593Smuzhiyun #endif
1471*4882a593Smuzhiyun }
1472*4882a593Smuzhiyun
thread_exit(_completion * comp)1473*4882a593Smuzhiyun inline void thread_exit(_completion *comp)
1474*4882a593Smuzhiyun {
1475*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1476*4882a593Smuzhiyun complete_and_exit(comp, 0);
1477*4882a593Smuzhiyun #endif
1478*4882a593Smuzhiyun
1479*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
1480*4882a593Smuzhiyun printf("%s", "RTKTHREAD_exit");
1481*4882a593Smuzhiyun #endif
1482*4882a593Smuzhiyun
1483*4882a593Smuzhiyun #ifdef PLATFORM_OS_CE
1484*4882a593Smuzhiyun ExitThread(STATUS_SUCCESS);
1485*4882a593Smuzhiyun #endif
1486*4882a593Smuzhiyun
1487*4882a593Smuzhiyun #ifdef PLATFORM_OS_XP
1488*4882a593Smuzhiyun PsTerminateSystemThread(STATUS_SUCCESS);
1489*4882a593Smuzhiyun #endif
1490*4882a593Smuzhiyun }
1491*4882a593Smuzhiyun
_rtw_init_completion(_completion * comp)1492*4882a593Smuzhiyun inline void _rtw_init_completion(_completion *comp)
1493*4882a593Smuzhiyun {
1494*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1495*4882a593Smuzhiyun init_completion(comp);
1496*4882a593Smuzhiyun #endif
1497*4882a593Smuzhiyun }
_rtw_wait_for_comp_timeout(_completion * comp)1498*4882a593Smuzhiyun inline void _rtw_wait_for_comp_timeout(_completion *comp)
1499*4882a593Smuzhiyun {
1500*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1501*4882a593Smuzhiyun wait_for_completion_timeout(comp, msecs_to_jiffies(3000));
1502*4882a593Smuzhiyun #endif
1503*4882a593Smuzhiyun }
_rtw_wait_for_comp(_completion * comp)1504*4882a593Smuzhiyun inline void _rtw_wait_for_comp(_completion *comp)
1505*4882a593Smuzhiyun {
1506*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1507*4882a593Smuzhiyun wait_for_completion(comp);
1508*4882a593Smuzhiyun #endif
1509*4882a593Smuzhiyun }
1510*4882a593Smuzhiyun
_rtw_mutex_init(_mutex * pmutex)1511*4882a593Smuzhiyun void _rtw_mutex_init(_mutex *pmutex)
1512*4882a593Smuzhiyun {
1513*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1514*4882a593Smuzhiyun
1515*4882a593Smuzhiyun #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
1516*4882a593Smuzhiyun mutex_init(pmutex);
1517*4882a593Smuzhiyun #else
1518*4882a593Smuzhiyun init_MUTEX(pmutex);
1519*4882a593Smuzhiyun #endif
1520*4882a593Smuzhiyun
1521*4882a593Smuzhiyun #endif
1522*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
1523*4882a593Smuzhiyun mtx_init(pmutex, "", NULL, MTX_DEF | MTX_RECURSE);
1524*4882a593Smuzhiyun #endif
1525*4882a593Smuzhiyun #ifdef PLATFORM_OS_XP
1526*4882a593Smuzhiyun
1527*4882a593Smuzhiyun KeInitializeMutex(pmutex, 0);
1528*4882a593Smuzhiyun
1529*4882a593Smuzhiyun #endif
1530*4882a593Smuzhiyun
1531*4882a593Smuzhiyun #ifdef PLATFORM_OS_CE
1532*4882a593Smuzhiyun *pmutex = CreateMutex(NULL, _FALSE, NULL);
1533*4882a593Smuzhiyun #endif
1534*4882a593Smuzhiyun }
1535*4882a593Smuzhiyun
1536*4882a593Smuzhiyun void _rtw_mutex_free(_mutex *pmutex);
_rtw_mutex_free(_mutex * pmutex)1537*4882a593Smuzhiyun void _rtw_mutex_free(_mutex *pmutex)
1538*4882a593Smuzhiyun {
1539*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1540*4882a593Smuzhiyun
1541*4882a593Smuzhiyun #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
1542*4882a593Smuzhiyun mutex_destroy(pmutex);
1543*4882a593Smuzhiyun #else
1544*4882a593Smuzhiyun #endif
1545*4882a593Smuzhiyun
1546*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
1547*4882a593Smuzhiyun sema_destroy(pmutex);
1548*4882a593Smuzhiyun #endif
1549*4882a593Smuzhiyun
1550*4882a593Smuzhiyun #endif
1551*4882a593Smuzhiyun
1552*4882a593Smuzhiyun #ifdef PLATFORM_OS_XP
1553*4882a593Smuzhiyun
1554*4882a593Smuzhiyun #endif
1555*4882a593Smuzhiyun
1556*4882a593Smuzhiyun #ifdef PLATFORM_OS_CE
1557*4882a593Smuzhiyun
1558*4882a593Smuzhiyun #endif
1559*4882a593Smuzhiyun }
1560*4882a593Smuzhiyun
_rtw_spinlock_init(_lock * plock)1561*4882a593Smuzhiyun void _rtw_spinlock_init(_lock *plock)
1562*4882a593Smuzhiyun {
1563*4882a593Smuzhiyun
1564*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1565*4882a593Smuzhiyun
1566*4882a593Smuzhiyun spin_lock_init(plock);
1567*4882a593Smuzhiyun
1568*4882a593Smuzhiyun #endif
1569*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
1570*4882a593Smuzhiyun mtx_init(plock, "", NULL, MTX_DEF | MTX_RECURSE);
1571*4882a593Smuzhiyun #endif
1572*4882a593Smuzhiyun #ifdef PLATFORM_WINDOWS
1573*4882a593Smuzhiyun
1574*4882a593Smuzhiyun NdisAllocateSpinLock(plock);
1575*4882a593Smuzhiyun
1576*4882a593Smuzhiyun #endif
1577*4882a593Smuzhiyun
1578*4882a593Smuzhiyun }
1579*4882a593Smuzhiyun
_rtw_spinlock_free(_lock * plock)1580*4882a593Smuzhiyun void _rtw_spinlock_free(_lock *plock)
1581*4882a593Smuzhiyun {
1582*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
1583*4882a593Smuzhiyun mtx_destroy(plock);
1584*4882a593Smuzhiyun #endif
1585*4882a593Smuzhiyun
1586*4882a593Smuzhiyun #ifdef PLATFORM_WINDOWS
1587*4882a593Smuzhiyun
1588*4882a593Smuzhiyun NdisFreeSpinLock(plock);
1589*4882a593Smuzhiyun
1590*4882a593Smuzhiyun #endif
1591*4882a593Smuzhiyun
1592*4882a593Smuzhiyun }
1593*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
1594*4882a593Smuzhiyun extern PADAPTER prtw_lock;
1595*4882a593Smuzhiyun
rtw_mtx_lock(_lock * plock)1596*4882a593Smuzhiyun void rtw_mtx_lock(_lock *plock)
1597*4882a593Smuzhiyun {
1598*4882a593Smuzhiyun if (prtw_lock)
1599*4882a593Smuzhiyun mtx_lock(&prtw_lock->glock);
1600*4882a593Smuzhiyun else
1601*4882a593Smuzhiyun printf("%s prtw_lock==NULL", __FUNCTION__);
1602*4882a593Smuzhiyun }
rtw_mtx_unlock(_lock * plock)1603*4882a593Smuzhiyun void rtw_mtx_unlock(_lock *plock)
1604*4882a593Smuzhiyun {
1605*4882a593Smuzhiyun if (prtw_lock)
1606*4882a593Smuzhiyun mtx_unlock(&prtw_lock->glock);
1607*4882a593Smuzhiyun else
1608*4882a593Smuzhiyun printf("%s prtw_lock==NULL", __FUNCTION__);
1609*4882a593Smuzhiyun
1610*4882a593Smuzhiyun }
1611*4882a593Smuzhiyun #endif /* PLATFORM_FREEBSD */
1612*4882a593Smuzhiyun
1613*4882a593Smuzhiyun
_rtw_spinlock(_lock * plock)1614*4882a593Smuzhiyun void _rtw_spinlock(_lock *plock)
1615*4882a593Smuzhiyun {
1616*4882a593Smuzhiyun
1617*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1618*4882a593Smuzhiyun
1619*4882a593Smuzhiyun spin_lock(plock);
1620*4882a593Smuzhiyun
1621*4882a593Smuzhiyun #endif
1622*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
1623*4882a593Smuzhiyun mtx_lock(plock);
1624*4882a593Smuzhiyun #endif
1625*4882a593Smuzhiyun #ifdef PLATFORM_WINDOWS
1626*4882a593Smuzhiyun
1627*4882a593Smuzhiyun NdisAcquireSpinLock(plock);
1628*4882a593Smuzhiyun
1629*4882a593Smuzhiyun #endif
1630*4882a593Smuzhiyun
1631*4882a593Smuzhiyun }
1632*4882a593Smuzhiyun
_rtw_spinunlock(_lock * plock)1633*4882a593Smuzhiyun void _rtw_spinunlock(_lock *plock)
1634*4882a593Smuzhiyun {
1635*4882a593Smuzhiyun
1636*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1637*4882a593Smuzhiyun
1638*4882a593Smuzhiyun spin_unlock(plock);
1639*4882a593Smuzhiyun
1640*4882a593Smuzhiyun #endif
1641*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
1642*4882a593Smuzhiyun mtx_unlock(plock);
1643*4882a593Smuzhiyun #endif
1644*4882a593Smuzhiyun #ifdef PLATFORM_WINDOWS
1645*4882a593Smuzhiyun
1646*4882a593Smuzhiyun NdisReleaseSpinLock(plock);
1647*4882a593Smuzhiyun
1648*4882a593Smuzhiyun #endif
1649*4882a593Smuzhiyun }
1650*4882a593Smuzhiyun
1651*4882a593Smuzhiyun
_rtw_spinlock_ex(_lock * plock)1652*4882a593Smuzhiyun void _rtw_spinlock_ex(_lock *plock)
1653*4882a593Smuzhiyun {
1654*4882a593Smuzhiyun
1655*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1656*4882a593Smuzhiyun
1657*4882a593Smuzhiyun spin_lock(plock);
1658*4882a593Smuzhiyun
1659*4882a593Smuzhiyun #endif
1660*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
1661*4882a593Smuzhiyun mtx_lock(plock);
1662*4882a593Smuzhiyun #endif
1663*4882a593Smuzhiyun #ifdef PLATFORM_WINDOWS
1664*4882a593Smuzhiyun
1665*4882a593Smuzhiyun NdisDprAcquireSpinLock(plock);
1666*4882a593Smuzhiyun
1667*4882a593Smuzhiyun #endif
1668*4882a593Smuzhiyun
1669*4882a593Smuzhiyun }
1670*4882a593Smuzhiyun
_rtw_spinunlock_ex(_lock * plock)1671*4882a593Smuzhiyun void _rtw_spinunlock_ex(_lock *plock)
1672*4882a593Smuzhiyun {
1673*4882a593Smuzhiyun
1674*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1675*4882a593Smuzhiyun
1676*4882a593Smuzhiyun spin_unlock(plock);
1677*4882a593Smuzhiyun
1678*4882a593Smuzhiyun #endif
1679*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
1680*4882a593Smuzhiyun mtx_unlock(plock);
1681*4882a593Smuzhiyun #endif
1682*4882a593Smuzhiyun #ifdef PLATFORM_WINDOWS
1683*4882a593Smuzhiyun
1684*4882a593Smuzhiyun NdisDprReleaseSpinLock(plock);
1685*4882a593Smuzhiyun
1686*4882a593Smuzhiyun #endif
1687*4882a593Smuzhiyun }
1688*4882a593Smuzhiyun
1689*4882a593Smuzhiyun
1690*4882a593Smuzhiyun
_rtw_init_queue(_queue * pqueue)1691*4882a593Smuzhiyun void _rtw_init_queue(_queue *pqueue)
1692*4882a593Smuzhiyun {
1693*4882a593Smuzhiyun _rtw_init_listhead(&(pqueue->queue));
1694*4882a593Smuzhiyun _rtw_spinlock_init(&(pqueue->lock));
1695*4882a593Smuzhiyun }
1696*4882a593Smuzhiyun
_rtw_deinit_queue(_queue * pqueue)1697*4882a593Smuzhiyun void _rtw_deinit_queue(_queue *pqueue)
1698*4882a593Smuzhiyun {
1699*4882a593Smuzhiyun _rtw_spinlock_free(&(pqueue->lock));
1700*4882a593Smuzhiyun }
1701*4882a593Smuzhiyun
_rtw_queue_empty(_queue * pqueue)1702*4882a593Smuzhiyun u32 _rtw_queue_empty(_queue *pqueue)
1703*4882a593Smuzhiyun {
1704*4882a593Smuzhiyun return rtw_is_list_empty(&(pqueue->queue));
1705*4882a593Smuzhiyun }
1706*4882a593Smuzhiyun
1707*4882a593Smuzhiyun
rtw_end_of_queue_search(_list * head,_list * plist)1708*4882a593Smuzhiyun u32 rtw_end_of_queue_search(_list *head, _list *plist)
1709*4882a593Smuzhiyun {
1710*4882a593Smuzhiyun if (head == plist)
1711*4882a593Smuzhiyun return _TRUE;
1712*4882a593Smuzhiyun else
1713*4882a593Smuzhiyun return _FALSE;
1714*4882a593Smuzhiyun }
1715*4882a593Smuzhiyun
1716*4882a593Smuzhiyun
_rtw_get_current_time(void)1717*4882a593Smuzhiyun systime _rtw_get_current_time(void)
1718*4882a593Smuzhiyun {
1719*4882a593Smuzhiyun
1720*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1721*4882a593Smuzhiyun return jiffies;
1722*4882a593Smuzhiyun #endif
1723*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
1724*4882a593Smuzhiyun struct timeval tvp;
1725*4882a593Smuzhiyun getmicrotime(&tvp);
1726*4882a593Smuzhiyun return tvp.tv_sec;
1727*4882a593Smuzhiyun #endif
1728*4882a593Smuzhiyun #ifdef PLATFORM_WINDOWS
1729*4882a593Smuzhiyun LARGE_INTEGER SystemTime;
1730*4882a593Smuzhiyun NdisGetCurrentSystemTime(&SystemTime);
1731*4882a593Smuzhiyun return SystemTime.LowPart;/* count of 100-nanosecond intervals */
1732*4882a593Smuzhiyun #endif
1733*4882a593Smuzhiyun }
1734*4882a593Smuzhiyun
_rtw_systime_to_ms(systime stime)1735*4882a593Smuzhiyun inline u32 _rtw_systime_to_ms(systime stime)
1736*4882a593Smuzhiyun {
1737*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1738*4882a593Smuzhiyun return jiffies_to_msecs(stime);
1739*4882a593Smuzhiyun #endif
1740*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
1741*4882a593Smuzhiyun return stime * 1000;
1742*4882a593Smuzhiyun #endif
1743*4882a593Smuzhiyun #ifdef PLATFORM_WINDOWS
1744*4882a593Smuzhiyun return stime / 10000 ;
1745*4882a593Smuzhiyun #endif
1746*4882a593Smuzhiyun }
1747*4882a593Smuzhiyun
_rtw_ms_to_systime(u32 ms)1748*4882a593Smuzhiyun inline systime _rtw_ms_to_systime(u32 ms)
1749*4882a593Smuzhiyun {
1750*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1751*4882a593Smuzhiyun return msecs_to_jiffies(ms);
1752*4882a593Smuzhiyun #endif
1753*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
1754*4882a593Smuzhiyun return ms / 1000;
1755*4882a593Smuzhiyun #endif
1756*4882a593Smuzhiyun #ifdef PLATFORM_WINDOWS
1757*4882a593Smuzhiyun return ms * 10000 ;
1758*4882a593Smuzhiyun #endif
1759*4882a593Smuzhiyun }
1760*4882a593Smuzhiyun
_rtw_us_to_systime(u32 us)1761*4882a593Smuzhiyun inline systime _rtw_us_to_systime(u32 us)
1762*4882a593Smuzhiyun {
1763*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1764*4882a593Smuzhiyun return usecs_to_jiffies(us);
1765*4882a593Smuzhiyun #else
1766*4882a593Smuzhiyun #error "TBD\n"
1767*4882a593Smuzhiyun #endif
1768*4882a593Smuzhiyun }
1769*4882a593Smuzhiyun
1770*4882a593Smuzhiyun /* the input parameter start use the same unit as returned by rtw_get_current_time */
_rtw_get_passing_time_ms(systime start)1771*4882a593Smuzhiyun inline s32 _rtw_get_passing_time_ms(systime start)
1772*4882a593Smuzhiyun {
1773*4882a593Smuzhiyun return _rtw_systime_to_ms(_rtw_get_current_time() - start);
1774*4882a593Smuzhiyun }
1775*4882a593Smuzhiyun
_rtw_get_remaining_time_ms(systime end)1776*4882a593Smuzhiyun inline s32 _rtw_get_remaining_time_ms(systime end)
1777*4882a593Smuzhiyun {
1778*4882a593Smuzhiyun return _rtw_systime_to_ms(end - _rtw_get_current_time());
1779*4882a593Smuzhiyun }
1780*4882a593Smuzhiyun
_rtw_get_time_interval_ms(systime start,systime end)1781*4882a593Smuzhiyun inline s32 _rtw_get_time_interval_ms(systime start, systime end)
1782*4882a593Smuzhiyun {
1783*4882a593Smuzhiyun return _rtw_systime_to_ms(end - start);
1784*4882a593Smuzhiyun }
1785*4882a593Smuzhiyun
_rtw_time_after(systime a,systime b)1786*4882a593Smuzhiyun inline bool _rtw_time_after(systime a, systime b)
1787*4882a593Smuzhiyun {
1788*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1789*4882a593Smuzhiyun return time_after(a, b);
1790*4882a593Smuzhiyun #else
1791*4882a593Smuzhiyun #error "TBD\n"
1792*4882a593Smuzhiyun #endif
1793*4882a593Smuzhiyun }
1794*4882a593Smuzhiyun
rtw_sptime_get(void)1795*4882a593Smuzhiyun sysptime rtw_sptime_get(void)
1796*4882a593Smuzhiyun {
1797*4882a593Smuzhiyun /* CLOCK_MONOTONIC */
1798*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1799*4882a593Smuzhiyun #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0))
1800*4882a593Smuzhiyun struct timespec64 cur;
1801*4882a593Smuzhiyun
1802*4882a593Smuzhiyun ktime_get_ts64(&cur);
1803*4882a593Smuzhiyun return timespec64_to_ktime(cur);
1804*4882a593Smuzhiyun #else
1805*4882a593Smuzhiyun struct timespec cur;
1806*4882a593Smuzhiyun
1807*4882a593Smuzhiyun ktime_get_ts(&cur);
1808*4882a593Smuzhiyun return timespec_to_ktime(cur);
1809*4882a593Smuzhiyun #endif
1810*4882a593Smuzhiyun #else
1811*4882a593Smuzhiyun #error "TBD\n"
1812*4882a593Smuzhiyun #endif
1813*4882a593Smuzhiyun }
1814*4882a593Smuzhiyun
rtw_sptime_set(s64 secs,const u32 nsecs)1815*4882a593Smuzhiyun sysptime rtw_sptime_set(s64 secs, const u32 nsecs)
1816*4882a593Smuzhiyun {
1817*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1818*4882a593Smuzhiyun return ktime_set(secs, nsecs);
1819*4882a593Smuzhiyun #else
1820*4882a593Smuzhiyun #error "TBD\n"
1821*4882a593Smuzhiyun #endif
1822*4882a593Smuzhiyun }
1823*4882a593Smuzhiyun
rtw_sptime_zero(void)1824*4882a593Smuzhiyun sysptime rtw_sptime_zero(void)
1825*4882a593Smuzhiyun {
1826*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1827*4882a593Smuzhiyun return ktime_set(0, 0);
1828*4882a593Smuzhiyun #else
1829*4882a593Smuzhiyun #error "TBD\n"
1830*4882a593Smuzhiyun #endif
1831*4882a593Smuzhiyun }
1832*4882a593Smuzhiyun
1833*4882a593Smuzhiyun /*
1834*4882a593Smuzhiyun * cmp1 < cmp2: return <0
1835*4882a593Smuzhiyun * cmp1 == cmp2: return 0
1836*4882a593Smuzhiyun * cmp1 > cmp2: return >0
1837*4882a593Smuzhiyun */
rtw_sptime_cmp(const sysptime cmp1,const sysptime cmp2)1838*4882a593Smuzhiyun int rtw_sptime_cmp(const sysptime cmp1, const sysptime cmp2)
1839*4882a593Smuzhiyun {
1840*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1841*4882a593Smuzhiyun #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
1842*4882a593Smuzhiyun return ktime_compare(cmp1, cmp2);
1843*4882a593Smuzhiyun #else
1844*4882a593Smuzhiyun if (cmp1.tv64 < cmp2.tv64)
1845*4882a593Smuzhiyun return -1;
1846*4882a593Smuzhiyun if (cmp1.tv64 > cmp2.tv64)
1847*4882a593Smuzhiyun return 1;
1848*4882a593Smuzhiyun return 0;
1849*4882a593Smuzhiyun #endif
1850*4882a593Smuzhiyun #else
1851*4882a593Smuzhiyun #error "TBD\n"
1852*4882a593Smuzhiyun #endif
1853*4882a593Smuzhiyun }
1854*4882a593Smuzhiyun
rtw_sptime_eql(const sysptime cmp1,const sysptime cmp2)1855*4882a593Smuzhiyun bool rtw_sptime_eql(const sysptime cmp1, const sysptime cmp2)
1856*4882a593Smuzhiyun {
1857*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1858*4882a593Smuzhiyun return rtw_sptime_cmp(cmp1, cmp2) == 0;
1859*4882a593Smuzhiyun #else
1860*4882a593Smuzhiyun #error "TBD\n"
1861*4882a593Smuzhiyun #endif
1862*4882a593Smuzhiyun }
1863*4882a593Smuzhiyun
rtw_sptime_is_zero(const sysptime sptime)1864*4882a593Smuzhiyun bool rtw_sptime_is_zero(const sysptime sptime)
1865*4882a593Smuzhiyun {
1866*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1867*4882a593Smuzhiyun return rtw_sptime_cmp(sptime, rtw_sptime_zero()) == 0;
1868*4882a593Smuzhiyun #else
1869*4882a593Smuzhiyun #error "TBD\n"
1870*4882a593Smuzhiyun #endif
1871*4882a593Smuzhiyun }
1872*4882a593Smuzhiyun
1873*4882a593Smuzhiyun /*
1874*4882a593Smuzhiyun * sub = lhs - rhs, in normalized form
1875*4882a593Smuzhiyun */
rtw_sptime_sub(const sysptime lhs,const sysptime rhs)1876*4882a593Smuzhiyun sysptime rtw_sptime_sub(const sysptime lhs, const sysptime rhs)
1877*4882a593Smuzhiyun {
1878*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1879*4882a593Smuzhiyun return ktime_sub(lhs, rhs);
1880*4882a593Smuzhiyun #else
1881*4882a593Smuzhiyun #error "TBD\n"
1882*4882a593Smuzhiyun #endif
1883*4882a593Smuzhiyun }
1884*4882a593Smuzhiyun
1885*4882a593Smuzhiyun /*
1886*4882a593Smuzhiyun * add = lhs + rhs, in normalized form
1887*4882a593Smuzhiyun */
rtw_sptime_add(const sysptime lhs,const sysptime rhs)1888*4882a593Smuzhiyun sysptime rtw_sptime_add(const sysptime lhs, const sysptime rhs)
1889*4882a593Smuzhiyun {
1890*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1891*4882a593Smuzhiyun return ktime_add(lhs, rhs);
1892*4882a593Smuzhiyun #else
1893*4882a593Smuzhiyun #error "TBD\n"
1894*4882a593Smuzhiyun #endif
1895*4882a593Smuzhiyun }
1896*4882a593Smuzhiyun
rtw_sptime_to_ms(const sysptime sptime)1897*4882a593Smuzhiyun s64 rtw_sptime_to_ms(const sysptime sptime)
1898*4882a593Smuzhiyun {
1899*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1900*4882a593Smuzhiyun #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
1901*4882a593Smuzhiyun return ktime_to_ms(sptime);
1902*4882a593Smuzhiyun #else
1903*4882a593Smuzhiyun struct timeval tv = ktime_to_timeval(sptime);
1904*4882a593Smuzhiyun
1905*4882a593Smuzhiyun return (s64) tv.tv_sec * MSEC_PER_SEC + tv.tv_usec / USEC_PER_MSEC;
1906*4882a593Smuzhiyun #endif
1907*4882a593Smuzhiyun #else
1908*4882a593Smuzhiyun #error "TBD\n"
1909*4882a593Smuzhiyun #endif
1910*4882a593Smuzhiyun }
1911*4882a593Smuzhiyun
rtw_ms_to_sptime(u64 ms)1912*4882a593Smuzhiyun sysptime rtw_ms_to_sptime(u64 ms)
1913*4882a593Smuzhiyun {
1914*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1915*4882a593Smuzhiyun return ns_to_ktime(ms * NSEC_PER_MSEC);
1916*4882a593Smuzhiyun #else
1917*4882a593Smuzhiyun #error "TBD\n"
1918*4882a593Smuzhiyun #endif
1919*4882a593Smuzhiyun }
1920*4882a593Smuzhiyun
rtw_sptime_to_us(const sysptime sptime)1921*4882a593Smuzhiyun s64 rtw_sptime_to_us(const sysptime sptime)
1922*4882a593Smuzhiyun {
1923*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1924*4882a593Smuzhiyun #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22))
1925*4882a593Smuzhiyun return ktime_to_us(sptime);
1926*4882a593Smuzhiyun #else
1927*4882a593Smuzhiyun struct timeval tv = ktime_to_timeval(sptime);
1928*4882a593Smuzhiyun
1929*4882a593Smuzhiyun return (s64) tv.tv_sec * USEC_PER_SEC + tv.tv_usec;
1930*4882a593Smuzhiyun #endif
1931*4882a593Smuzhiyun #else
1932*4882a593Smuzhiyun #error "TBD\n"
1933*4882a593Smuzhiyun #endif
1934*4882a593Smuzhiyun }
1935*4882a593Smuzhiyun
rtw_us_to_sptime(u64 us)1936*4882a593Smuzhiyun sysptime rtw_us_to_sptime(u64 us)
1937*4882a593Smuzhiyun {
1938*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1939*4882a593Smuzhiyun return ns_to_ktime(us * NSEC_PER_USEC);
1940*4882a593Smuzhiyun #else
1941*4882a593Smuzhiyun #error "TBD\n"
1942*4882a593Smuzhiyun #endif
1943*4882a593Smuzhiyun }
1944*4882a593Smuzhiyun
rtw_sptime_to_ns(const sysptime sptime)1945*4882a593Smuzhiyun s64 rtw_sptime_to_ns(const sysptime sptime)
1946*4882a593Smuzhiyun {
1947*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1948*4882a593Smuzhiyun return ktime_to_ns(sptime);
1949*4882a593Smuzhiyun #else
1950*4882a593Smuzhiyun #error "TBD\n"
1951*4882a593Smuzhiyun #endif
1952*4882a593Smuzhiyun }
1953*4882a593Smuzhiyun
rtw_ns_to_sptime(u64 ns)1954*4882a593Smuzhiyun sysptime rtw_ns_to_sptime(u64 ns)
1955*4882a593Smuzhiyun {
1956*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
1957*4882a593Smuzhiyun return ns_to_ktime(ns);
1958*4882a593Smuzhiyun #else
1959*4882a593Smuzhiyun #error "TBD\n"
1960*4882a593Smuzhiyun #endif
1961*4882a593Smuzhiyun }
1962*4882a593Smuzhiyun
rtw_sptime_diff_ms(const sysptime start,const sysptime end)1963*4882a593Smuzhiyun s64 rtw_sptime_diff_ms(const sysptime start, const sysptime end)
1964*4882a593Smuzhiyun {
1965*4882a593Smuzhiyun sysptime diff;
1966*4882a593Smuzhiyun
1967*4882a593Smuzhiyun diff = rtw_sptime_sub(end, start);
1968*4882a593Smuzhiyun
1969*4882a593Smuzhiyun return rtw_sptime_to_ms(diff);
1970*4882a593Smuzhiyun }
1971*4882a593Smuzhiyun
rtw_sptime_pass_ms(const sysptime start)1972*4882a593Smuzhiyun s64 rtw_sptime_pass_ms(const sysptime start)
1973*4882a593Smuzhiyun {
1974*4882a593Smuzhiyun sysptime cur, diff;
1975*4882a593Smuzhiyun
1976*4882a593Smuzhiyun cur = rtw_sptime_get();
1977*4882a593Smuzhiyun diff = rtw_sptime_sub(cur, start);
1978*4882a593Smuzhiyun
1979*4882a593Smuzhiyun return rtw_sptime_to_ms(diff);
1980*4882a593Smuzhiyun }
1981*4882a593Smuzhiyun
rtw_sptime_diff_us(const sysptime start,const sysptime end)1982*4882a593Smuzhiyun s64 rtw_sptime_diff_us(const sysptime start, const sysptime end)
1983*4882a593Smuzhiyun {
1984*4882a593Smuzhiyun sysptime diff;
1985*4882a593Smuzhiyun
1986*4882a593Smuzhiyun diff = rtw_sptime_sub(end, start);
1987*4882a593Smuzhiyun
1988*4882a593Smuzhiyun return rtw_sptime_to_us(diff);
1989*4882a593Smuzhiyun }
1990*4882a593Smuzhiyun
rtw_sptime_pass_us(const sysptime start)1991*4882a593Smuzhiyun s64 rtw_sptime_pass_us(const sysptime start)
1992*4882a593Smuzhiyun {
1993*4882a593Smuzhiyun sysptime cur, diff;
1994*4882a593Smuzhiyun
1995*4882a593Smuzhiyun cur = rtw_sptime_get();
1996*4882a593Smuzhiyun diff = rtw_sptime_sub(cur, start);
1997*4882a593Smuzhiyun
1998*4882a593Smuzhiyun return rtw_sptime_to_us(diff);
1999*4882a593Smuzhiyun }
2000*4882a593Smuzhiyun
rtw_sptime_diff_ns(const sysptime start,const sysptime end)2001*4882a593Smuzhiyun s64 rtw_sptime_diff_ns(const sysptime start, const sysptime end)
2002*4882a593Smuzhiyun {
2003*4882a593Smuzhiyun sysptime diff;
2004*4882a593Smuzhiyun
2005*4882a593Smuzhiyun diff = rtw_sptime_sub(end, start);
2006*4882a593Smuzhiyun
2007*4882a593Smuzhiyun return rtw_sptime_to_ns(diff);
2008*4882a593Smuzhiyun }
2009*4882a593Smuzhiyun
rtw_sptime_pass_ns(const sysptime start)2010*4882a593Smuzhiyun s64 rtw_sptime_pass_ns(const sysptime start)
2011*4882a593Smuzhiyun {
2012*4882a593Smuzhiyun sysptime cur, diff;
2013*4882a593Smuzhiyun
2014*4882a593Smuzhiyun cur = rtw_sptime_get();
2015*4882a593Smuzhiyun diff = rtw_sptime_sub(cur, start);
2016*4882a593Smuzhiyun
2017*4882a593Smuzhiyun return rtw_sptime_to_ns(diff);
2018*4882a593Smuzhiyun }
2019*4882a593Smuzhiyun
rtw_sleep_schedulable(int ms)2020*4882a593Smuzhiyun void rtw_sleep_schedulable(int ms)
2021*4882a593Smuzhiyun {
2022*4882a593Smuzhiyun
2023*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
2024*4882a593Smuzhiyun
2025*4882a593Smuzhiyun u32 delta;
2026*4882a593Smuzhiyun
2027*4882a593Smuzhiyun delta = (ms * HZ) / 1000; /* (ms) */
2028*4882a593Smuzhiyun if (delta == 0) {
2029*4882a593Smuzhiyun delta = 1;/* 1 ms */
2030*4882a593Smuzhiyun }
2031*4882a593Smuzhiyun set_current_state(TASK_INTERRUPTIBLE);
2032*4882a593Smuzhiyun schedule_timeout(delta);
2033*4882a593Smuzhiyun return;
2034*4882a593Smuzhiyun
2035*4882a593Smuzhiyun #endif
2036*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
2037*4882a593Smuzhiyun DELAY(ms * 1000);
2038*4882a593Smuzhiyun return ;
2039*4882a593Smuzhiyun #endif
2040*4882a593Smuzhiyun
2041*4882a593Smuzhiyun #ifdef PLATFORM_WINDOWS
2042*4882a593Smuzhiyun
2043*4882a593Smuzhiyun NdisMSleep(ms * 1000); /* (us)*1000=(ms) */
2044*4882a593Smuzhiyun
2045*4882a593Smuzhiyun #endif
2046*4882a593Smuzhiyun
2047*4882a593Smuzhiyun }
2048*4882a593Smuzhiyun
2049*4882a593Smuzhiyun
rtw_msleep_os(int ms)2050*4882a593Smuzhiyun void rtw_msleep_os(int ms)
2051*4882a593Smuzhiyun {
2052*4882a593Smuzhiyun
2053*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
2054*4882a593Smuzhiyun #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36))
2055*4882a593Smuzhiyun if (ms < 20) {
2056*4882a593Smuzhiyun unsigned long us = ms * 1000UL;
2057*4882a593Smuzhiyun usleep_range(us, us + 1000UL);
2058*4882a593Smuzhiyun } else
2059*4882a593Smuzhiyun #endif
2060*4882a593Smuzhiyun msleep((unsigned int)ms);
2061*4882a593Smuzhiyun
2062*4882a593Smuzhiyun #endif
2063*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
2064*4882a593Smuzhiyun /* Delay for delay microseconds */
2065*4882a593Smuzhiyun DELAY(ms * 1000);
2066*4882a593Smuzhiyun return ;
2067*4882a593Smuzhiyun #endif
2068*4882a593Smuzhiyun #ifdef PLATFORM_WINDOWS
2069*4882a593Smuzhiyun
2070*4882a593Smuzhiyun NdisMSleep(ms * 1000); /* (us)*1000=(ms) */
2071*4882a593Smuzhiyun
2072*4882a593Smuzhiyun #endif
2073*4882a593Smuzhiyun
2074*4882a593Smuzhiyun
2075*4882a593Smuzhiyun }
rtw_usleep_os(int us)2076*4882a593Smuzhiyun void rtw_usleep_os(int us)
2077*4882a593Smuzhiyun {
2078*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
2079*4882a593Smuzhiyun
2080*4882a593Smuzhiyun /* msleep((unsigned int)us); */
2081*4882a593Smuzhiyun #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36))
2082*4882a593Smuzhiyun usleep_range(us, us + 1);
2083*4882a593Smuzhiyun #else
2084*4882a593Smuzhiyun if (1 < (us / 1000))
2085*4882a593Smuzhiyun msleep(1);
2086*4882a593Smuzhiyun else
2087*4882a593Smuzhiyun msleep((us / 1000) + 1);
2088*4882a593Smuzhiyun #endif
2089*4882a593Smuzhiyun #endif
2090*4882a593Smuzhiyun
2091*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
2092*4882a593Smuzhiyun /* Delay for delay microseconds */
2093*4882a593Smuzhiyun DELAY(us);
2094*4882a593Smuzhiyun
2095*4882a593Smuzhiyun return ;
2096*4882a593Smuzhiyun #endif
2097*4882a593Smuzhiyun #ifdef PLATFORM_WINDOWS
2098*4882a593Smuzhiyun
2099*4882a593Smuzhiyun NdisMSleep(us); /* (us) */
2100*4882a593Smuzhiyun
2101*4882a593Smuzhiyun #endif
2102*4882a593Smuzhiyun
2103*4882a593Smuzhiyun
2104*4882a593Smuzhiyun }
2105*4882a593Smuzhiyun
2106*4882a593Smuzhiyun
2107*4882a593Smuzhiyun #ifdef DBG_DELAY_OS
_rtw_mdelay_os(int ms,const char * func,const int line)2108*4882a593Smuzhiyun void _rtw_mdelay_os(int ms, const char *func, const int line)
2109*4882a593Smuzhiyun {
2110*4882a593Smuzhiyun #if 0
2111*4882a593Smuzhiyun if (ms > 10)
2112*4882a593Smuzhiyun RTW_INFO("%s:%d %s(%d)\n", func, line, __FUNCTION__, ms);
2113*4882a593Smuzhiyun rtw_msleep_os(ms);
2114*4882a593Smuzhiyun return;
2115*4882a593Smuzhiyun #endif
2116*4882a593Smuzhiyun
2117*4882a593Smuzhiyun
2118*4882a593Smuzhiyun RTW_INFO("%s:%d %s(%d)\n", func, line, __FUNCTION__, ms);
2119*4882a593Smuzhiyun
2120*4882a593Smuzhiyun #if defined(PLATFORM_LINUX)
2121*4882a593Smuzhiyun
2122*4882a593Smuzhiyun mdelay((unsigned long)ms);
2123*4882a593Smuzhiyun
2124*4882a593Smuzhiyun #elif defined(PLATFORM_WINDOWS)
2125*4882a593Smuzhiyun
2126*4882a593Smuzhiyun NdisStallExecution(ms * 1000); /* (us)*1000=(ms) */
2127*4882a593Smuzhiyun
2128*4882a593Smuzhiyun #endif
2129*4882a593Smuzhiyun
2130*4882a593Smuzhiyun
2131*4882a593Smuzhiyun }
_rtw_udelay_os(int us,const char * func,const int line)2132*4882a593Smuzhiyun void _rtw_udelay_os(int us, const char *func, const int line)
2133*4882a593Smuzhiyun {
2134*4882a593Smuzhiyun
2135*4882a593Smuzhiyun #if 0
2136*4882a593Smuzhiyun if (us > 1000) {
2137*4882a593Smuzhiyun RTW_INFO("%s:%d %s(%d)\n", func, line, __FUNCTION__, us);
2138*4882a593Smuzhiyun rtw_usleep_os(us);
2139*4882a593Smuzhiyun return;
2140*4882a593Smuzhiyun }
2141*4882a593Smuzhiyun #endif
2142*4882a593Smuzhiyun
2143*4882a593Smuzhiyun
2144*4882a593Smuzhiyun RTW_INFO("%s:%d %s(%d)\n", func, line, __FUNCTION__, us);
2145*4882a593Smuzhiyun
2146*4882a593Smuzhiyun
2147*4882a593Smuzhiyun #if defined(PLATFORM_LINUX)
2148*4882a593Smuzhiyun
2149*4882a593Smuzhiyun udelay((unsigned long)us);
2150*4882a593Smuzhiyun
2151*4882a593Smuzhiyun #elif defined(PLATFORM_WINDOWS)
2152*4882a593Smuzhiyun
2153*4882a593Smuzhiyun NdisStallExecution(us); /* (us) */
2154*4882a593Smuzhiyun
2155*4882a593Smuzhiyun #endif
2156*4882a593Smuzhiyun
2157*4882a593Smuzhiyun }
2158*4882a593Smuzhiyun #else
rtw_mdelay_os(int ms)2159*4882a593Smuzhiyun void rtw_mdelay_os(int ms)
2160*4882a593Smuzhiyun {
2161*4882a593Smuzhiyun
2162*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
2163*4882a593Smuzhiyun
2164*4882a593Smuzhiyun mdelay((unsigned long)ms);
2165*4882a593Smuzhiyun
2166*4882a593Smuzhiyun #endif
2167*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
2168*4882a593Smuzhiyun DELAY(ms * 1000);
2169*4882a593Smuzhiyun return ;
2170*4882a593Smuzhiyun #endif
2171*4882a593Smuzhiyun #ifdef PLATFORM_WINDOWS
2172*4882a593Smuzhiyun
2173*4882a593Smuzhiyun NdisStallExecution(ms * 1000); /* (us)*1000=(ms) */
2174*4882a593Smuzhiyun
2175*4882a593Smuzhiyun #endif
2176*4882a593Smuzhiyun
2177*4882a593Smuzhiyun
2178*4882a593Smuzhiyun }
rtw_udelay_os(int us)2179*4882a593Smuzhiyun void rtw_udelay_os(int us)
2180*4882a593Smuzhiyun {
2181*4882a593Smuzhiyun
2182*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
2183*4882a593Smuzhiyun
2184*4882a593Smuzhiyun udelay((unsigned long)us);
2185*4882a593Smuzhiyun
2186*4882a593Smuzhiyun #endif
2187*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
2188*4882a593Smuzhiyun /* Delay for delay microseconds */
2189*4882a593Smuzhiyun DELAY(us);
2190*4882a593Smuzhiyun return ;
2191*4882a593Smuzhiyun #endif
2192*4882a593Smuzhiyun #ifdef PLATFORM_WINDOWS
2193*4882a593Smuzhiyun
2194*4882a593Smuzhiyun NdisStallExecution(us); /* (us) */
2195*4882a593Smuzhiyun
2196*4882a593Smuzhiyun #endif
2197*4882a593Smuzhiyun
2198*4882a593Smuzhiyun }
2199*4882a593Smuzhiyun #endif
2200*4882a593Smuzhiyun
rtw_yield_os(void)2201*4882a593Smuzhiyun void rtw_yield_os(void)
2202*4882a593Smuzhiyun {
2203*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
2204*4882a593Smuzhiyun yield();
2205*4882a593Smuzhiyun #endif
2206*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
2207*4882a593Smuzhiyun yield();
2208*4882a593Smuzhiyun #endif
2209*4882a593Smuzhiyun #ifdef PLATFORM_WINDOWS
2210*4882a593Smuzhiyun SwitchToThread();
2211*4882a593Smuzhiyun #endif
2212*4882a593Smuzhiyun }
2213*4882a593Smuzhiyun
2214*4882a593Smuzhiyun const char *_rtw_pwait_type_str[] = {
2215*4882a593Smuzhiyun [RTW_PWAIT_TYPE_MSLEEP] = "MS",
2216*4882a593Smuzhiyun [RTW_PWAIT_TYPE_USLEEP] = "US",
2217*4882a593Smuzhiyun [RTW_PWAIT_TYPE_YIELD] = "Y",
2218*4882a593Smuzhiyun [RTW_PWAIT_TYPE_MDELAY] = "MD",
2219*4882a593Smuzhiyun [RTW_PWAIT_TYPE_UDELAY] = "UD",
2220*4882a593Smuzhiyun [RTW_PWAIT_TYPE_NUM] = "unknown",
2221*4882a593Smuzhiyun };
2222*4882a593Smuzhiyun
rtw_pwctx_yield(int us)2223*4882a593Smuzhiyun static void rtw_pwctx_yield(int us)
2224*4882a593Smuzhiyun {
2225*4882a593Smuzhiyun rtw_yield_os();
2226*4882a593Smuzhiyun }
2227*4882a593Smuzhiyun
2228*4882a593Smuzhiyun static void (*const rtw_pwait_hdl[])(int)= {
2229*4882a593Smuzhiyun [RTW_PWAIT_TYPE_MSLEEP] = rtw_msleep_os,
2230*4882a593Smuzhiyun [RTW_PWAIT_TYPE_USLEEP] = rtw_usleep_os,
2231*4882a593Smuzhiyun [RTW_PWAIT_TYPE_YIELD] = rtw_pwctx_yield,
2232*4882a593Smuzhiyun [RTW_PWAIT_TYPE_MDELAY] = rtw_mdelay_os,
2233*4882a593Smuzhiyun [RTW_PWAIT_TYPE_UDELAY] = rtw_udelay_os,
2234*4882a593Smuzhiyun };
2235*4882a593Smuzhiyun
rtw_pwctx_config(struct rtw_pwait_ctx * pwctx,enum rtw_pwait_type type,s32 time,s32 cnt_lmt)2236*4882a593Smuzhiyun int rtw_pwctx_config(struct rtw_pwait_ctx *pwctx, enum rtw_pwait_type type, s32 time, s32 cnt_lmt)
2237*4882a593Smuzhiyun {
2238*4882a593Smuzhiyun int ret = _FAIL;
2239*4882a593Smuzhiyun
2240*4882a593Smuzhiyun if (!RTW_PWAIT_TYPE_VALID(type))
2241*4882a593Smuzhiyun goto exit;
2242*4882a593Smuzhiyun
2243*4882a593Smuzhiyun pwctx->conf.type = type;
2244*4882a593Smuzhiyun pwctx->conf.wait_time = time;
2245*4882a593Smuzhiyun pwctx->conf.wait_cnt_lmt = cnt_lmt;
2246*4882a593Smuzhiyun pwctx->wait_hdl = rtw_pwait_hdl[type];
2247*4882a593Smuzhiyun
2248*4882a593Smuzhiyun ret = _SUCCESS;
2249*4882a593Smuzhiyun
2250*4882a593Smuzhiyun exit:
2251*4882a593Smuzhiyun return ret;
2252*4882a593Smuzhiyun }
2253*4882a593Smuzhiyun
rtw_macaddr_is_larger(const u8 * a,const u8 * b)2254*4882a593Smuzhiyun bool rtw_macaddr_is_larger(const u8 *a, const u8 *b)
2255*4882a593Smuzhiyun {
2256*4882a593Smuzhiyun u32 va, vb;
2257*4882a593Smuzhiyun
2258*4882a593Smuzhiyun va = be32_to_cpu(*((u32 *)a));
2259*4882a593Smuzhiyun vb = be32_to_cpu(*((u32 *)b));
2260*4882a593Smuzhiyun if (va > vb)
2261*4882a593Smuzhiyun return 1;
2262*4882a593Smuzhiyun else if (va < vb)
2263*4882a593Smuzhiyun return 0;
2264*4882a593Smuzhiyun
2265*4882a593Smuzhiyun return be16_to_cpu(*((u16 *)(a + 4))) > be16_to_cpu(*((u16 *)(b + 4)));
2266*4882a593Smuzhiyun }
2267*4882a593Smuzhiyun
2268*4882a593Smuzhiyun #define RTW_SUSPEND_LOCK_NAME "rtw_wifi"
2269*4882a593Smuzhiyun #define RTW_SUSPEND_TRAFFIC_LOCK_NAME "rtw_wifi_traffic"
2270*4882a593Smuzhiyun #define RTW_SUSPEND_RESUME_LOCK_NAME "rtw_wifi_resume"
2271*4882a593Smuzhiyun #ifdef CONFIG_WAKELOCK
2272*4882a593Smuzhiyun static struct wake_lock rtw_suspend_lock;
2273*4882a593Smuzhiyun static struct wake_lock rtw_suspend_traffic_lock;
2274*4882a593Smuzhiyun static struct wake_lock rtw_suspend_resume_lock;
2275*4882a593Smuzhiyun #elif defined(CONFIG_ANDROID_POWER)
2276*4882a593Smuzhiyun static android_suspend_lock_t rtw_suspend_lock = {
2277*4882a593Smuzhiyun .name = RTW_SUSPEND_LOCK_NAME
2278*4882a593Smuzhiyun };
2279*4882a593Smuzhiyun static android_suspend_lock_t rtw_suspend_traffic_lock = {
2280*4882a593Smuzhiyun .name = RTW_SUSPEND_TRAFFIC_LOCK_NAME
2281*4882a593Smuzhiyun };
2282*4882a593Smuzhiyun static android_suspend_lock_t rtw_suspend_resume_lock = {
2283*4882a593Smuzhiyun .name = RTW_SUSPEND_RESUME_LOCK_NAME
2284*4882a593Smuzhiyun };
2285*4882a593Smuzhiyun #endif
2286*4882a593Smuzhiyun
rtw_suspend_lock_init(void)2287*4882a593Smuzhiyun inline void rtw_suspend_lock_init(void)
2288*4882a593Smuzhiyun {
2289*4882a593Smuzhiyun #ifdef CONFIG_WAKELOCK
2290*4882a593Smuzhiyun wake_lock_init(&rtw_suspend_lock, WAKE_LOCK_SUSPEND, RTW_SUSPEND_LOCK_NAME);
2291*4882a593Smuzhiyun wake_lock_init(&rtw_suspend_traffic_lock, WAKE_LOCK_SUSPEND, RTW_SUSPEND_TRAFFIC_LOCK_NAME);
2292*4882a593Smuzhiyun wake_lock_init(&rtw_suspend_resume_lock, WAKE_LOCK_SUSPEND, RTW_SUSPEND_RESUME_LOCK_NAME);
2293*4882a593Smuzhiyun #elif defined(CONFIG_ANDROID_POWER)
2294*4882a593Smuzhiyun android_init_suspend_lock(&rtw_suspend_lock);
2295*4882a593Smuzhiyun android_init_suspend_lock(&rtw_suspend_traffic_lock);
2296*4882a593Smuzhiyun android_init_suspend_lock(&rtw_suspend_resume_lock);
2297*4882a593Smuzhiyun #endif
2298*4882a593Smuzhiyun }
2299*4882a593Smuzhiyun
rtw_suspend_lock_uninit(void)2300*4882a593Smuzhiyun inline void rtw_suspend_lock_uninit(void)
2301*4882a593Smuzhiyun {
2302*4882a593Smuzhiyun #ifdef CONFIG_WAKELOCK
2303*4882a593Smuzhiyun wake_lock_destroy(&rtw_suspend_lock);
2304*4882a593Smuzhiyun wake_lock_destroy(&rtw_suspend_traffic_lock);
2305*4882a593Smuzhiyun wake_lock_destroy(&rtw_suspend_resume_lock);
2306*4882a593Smuzhiyun #elif defined(CONFIG_ANDROID_POWER)
2307*4882a593Smuzhiyun android_uninit_suspend_lock(&rtw_suspend_lock);
2308*4882a593Smuzhiyun android_uninit_suspend_lock(&rtw_suspend_traffic_lock);
2309*4882a593Smuzhiyun android_uninit_suspend_lock(&rtw_suspend_resume_lock);
2310*4882a593Smuzhiyun #endif
2311*4882a593Smuzhiyun }
2312*4882a593Smuzhiyun
rtw_lock_suspend(void)2313*4882a593Smuzhiyun inline void rtw_lock_suspend(void)
2314*4882a593Smuzhiyun {
2315*4882a593Smuzhiyun #ifdef CONFIG_WAKELOCK
2316*4882a593Smuzhiyun wake_lock(&rtw_suspend_lock);
2317*4882a593Smuzhiyun #elif defined(CONFIG_ANDROID_POWER)
2318*4882a593Smuzhiyun android_lock_suspend(&rtw_suspend_lock);
2319*4882a593Smuzhiyun #endif
2320*4882a593Smuzhiyun
2321*4882a593Smuzhiyun #if defined(CONFIG_WAKELOCK) || defined(CONFIG_ANDROID_POWER)
2322*4882a593Smuzhiyun /* RTW_INFO("####%s: suspend_lock_count:%d####\n", __FUNCTION__, rtw_suspend_lock.stat.count); */
2323*4882a593Smuzhiyun #endif
2324*4882a593Smuzhiyun }
2325*4882a593Smuzhiyun
rtw_unlock_suspend(void)2326*4882a593Smuzhiyun inline void rtw_unlock_suspend(void)
2327*4882a593Smuzhiyun {
2328*4882a593Smuzhiyun #ifdef CONFIG_WAKELOCK
2329*4882a593Smuzhiyun wake_unlock(&rtw_suspend_lock);
2330*4882a593Smuzhiyun #elif defined(CONFIG_ANDROID_POWER)
2331*4882a593Smuzhiyun android_unlock_suspend(&rtw_suspend_lock);
2332*4882a593Smuzhiyun #endif
2333*4882a593Smuzhiyun
2334*4882a593Smuzhiyun #if defined(CONFIG_WAKELOCK) || defined(CONFIG_ANDROID_POWER)
2335*4882a593Smuzhiyun /* RTW_INFO("####%s: suspend_lock_count:%d####\n", __FUNCTION__, rtw_suspend_lock.stat.count); */
2336*4882a593Smuzhiyun #endif
2337*4882a593Smuzhiyun }
2338*4882a593Smuzhiyun
rtw_resume_lock_suspend(void)2339*4882a593Smuzhiyun inline void rtw_resume_lock_suspend(void)
2340*4882a593Smuzhiyun {
2341*4882a593Smuzhiyun #ifdef CONFIG_WAKELOCK
2342*4882a593Smuzhiyun wake_lock(&rtw_suspend_resume_lock);
2343*4882a593Smuzhiyun #elif defined(CONFIG_ANDROID_POWER)
2344*4882a593Smuzhiyun android_lock_suspend(&rtw_suspend_resume_lock);
2345*4882a593Smuzhiyun #endif
2346*4882a593Smuzhiyun
2347*4882a593Smuzhiyun #if defined(CONFIG_WAKELOCK) || defined(CONFIG_ANDROID_POWER)
2348*4882a593Smuzhiyun /* RTW_INFO("####%s: suspend_lock_count:%d####\n", __FUNCTION__, rtw_suspend_lock.stat.count); */
2349*4882a593Smuzhiyun #endif
2350*4882a593Smuzhiyun }
2351*4882a593Smuzhiyun
rtw_resume_unlock_suspend(void)2352*4882a593Smuzhiyun inline void rtw_resume_unlock_suspend(void)
2353*4882a593Smuzhiyun {
2354*4882a593Smuzhiyun #ifdef CONFIG_WAKELOCK
2355*4882a593Smuzhiyun wake_unlock(&rtw_suspend_resume_lock);
2356*4882a593Smuzhiyun #elif defined(CONFIG_ANDROID_POWER)
2357*4882a593Smuzhiyun android_unlock_suspend(&rtw_suspend_resume_lock);
2358*4882a593Smuzhiyun #endif
2359*4882a593Smuzhiyun
2360*4882a593Smuzhiyun #if defined(CONFIG_WAKELOCK) || defined(CONFIG_ANDROID_POWER)
2361*4882a593Smuzhiyun /* RTW_INFO("####%s: suspend_lock_count:%d####\n", __FUNCTION__, rtw_suspend_lock.stat.count); */
2362*4882a593Smuzhiyun #endif
2363*4882a593Smuzhiyun }
2364*4882a593Smuzhiyun
rtw_lock_suspend_timeout(u32 timeout_ms)2365*4882a593Smuzhiyun inline void rtw_lock_suspend_timeout(u32 timeout_ms)
2366*4882a593Smuzhiyun {
2367*4882a593Smuzhiyun #ifdef CONFIG_WAKELOCK
2368*4882a593Smuzhiyun wake_lock_timeout(&rtw_suspend_lock, rtw_ms_to_systime(timeout_ms));
2369*4882a593Smuzhiyun #elif defined(CONFIG_ANDROID_POWER)
2370*4882a593Smuzhiyun android_lock_suspend_auto_expire(&rtw_suspend_lock, rtw_ms_to_systime(timeout_ms));
2371*4882a593Smuzhiyun #endif
2372*4882a593Smuzhiyun }
2373*4882a593Smuzhiyun
2374*4882a593Smuzhiyun
rtw_lock_traffic_suspend_timeout(u32 timeout_ms)2375*4882a593Smuzhiyun inline void rtw_lock_traffic_suspend_timeout(u32 timeout_ms)
2376*4882a593Smuzhiyun {
2377*4882a593Smuzhiyun #ifdef CONFIG_WAKELOCK
2378*4882a593Smuzhiyun wake_lock_timeout(&rtw_suspend_traffic_lock, rtw_ms_to_systime(timeout_ms));
2379*4882a593Smuzhiyun #elif defined(CONFIG_ANDROID_POWER)
2380*4882a593Smuzhiyun android_lock_suspend_auto_expire(&rtw_suspend_traffic_lock, rtw_ms_to_systime(timeout_ms));
2381*4882a593Smuzhiyun #endif
2382*4882a593Smuzhiyun /* RTW_INFO("traffic lock timeout:%d\n", timeout_ms); */
2383*4882a593Smuzhiyun }
2384*4882a593Smuzhiyun
rtw_set_bit(int nr,unsigned long * addr)2385*4882a593Smuzhiyun inline void rtw_set_bit(int nr, unsigned long *addr)
2386*4882a593Smuzhiyun {
2387*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
2388*4882a593Smuzhiyun set_bit(nr, addr);
2389*4882a593Smuzhiyun #else
2390*4882a593Smuzhiyun #error "TBD\n";
2391*4882a593Smuzhiyun #endif
2392*4882a593Smuzhiyun }
2393*4882a593Smuzhiyun
rtw_clear_bit(int nr,unsigned long * addr)2394*4882a593Smuzhiyun inline void rtw_clear_bit(int nr, unsigned long *addr)
2395*4882a593Smuzhiyun {
2396*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
2397*4882a593Smuzhiyun clear_bit(nr, addr);
2398*4882a593Smuzhiyun #else
2399*4882a593Smuzhiyun #error "TBD\n";
2400*4882a593Smuzhiyun #endif
2401*4882a593Smuzhiyun }
2402*4882a593Smuzhiyun
rtw_test_and_clear_bit(int nr,unsigned long * addr)2403*4882a593Smuzhiyun inline int rtw_test_and_clear_bit(int nr, unsigned long *addr)
2404*4882a593Smuzhiyun {
2405*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
2406*4882a593Smuzhiyun return test_and_clear_bit(nr, addr);
2407*4882a593Smuzhiyun #else
2408*4882a593Smuzhiyun #error "TBD\n";
2409*4882a593Smuzhiyun #endif
2410*4882a593Smuzhiyun }
2411*4882a593Smuzhiyun
ATOMIC_SET(ATOMIC_T * v,int i)2412*4882a593Smuzhiyun inline void ATOMIC_SET(ATOMIC_T *v, int i)
2413*4882a593Smuzhiyun {
2414*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
2415*4882a593Smuzhiyun atomic_set(v, i);
2416*4882a593Smuzhiyun #elif defined(PLATFORM_WINDOWS)
2417*4882a593Smuzhiyun *v = i; /* other choice???? */
2418*4882a593Smuzhiyun #elif defined(PLATFORM_FREEBSD)
2419*4882a593Smuzhiyun atomic_set_int(v, i);
2420*4882a593Smuzhiyun #endif
2421*4882a593Smuzhiyun }
2422*4882a593Smuzhiyun
ATOMIC_READ(ATOMIC_T * v)2423*4882a593Smuzhiyun inline int ATOMIC_READ(ATOMIC_T *v)
2424*4882a593Smuzhiyun {
2425*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
2426*4882a593Smuzhiyun return atomic_read(v);
2427*4882a593Smuzhiyun #elif defined(PLATFORM_WINDOWS)
2428*4882a593Smuzhiyun return *v; /* other choice???? */
2429*4882a593Smuzhiyun #elif defined(PLATFORM_FREEBSD)
2430*4882a593Smuzhiyun return atomic_load_acq_32(v);
2431*4882a593Smuzhiyun #endif
2432*4882a593Smuzhiyun }
2433*4882a593Smuzhiyun
ATOMIC_ADD(ATOMIC_T * v,int i)2434*4882a593Smuzhiyun inline void ATOMIC_ADD(ATOMIC_T *v, int i)
2435*4882a593Smuzhiyun {
2436*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
2437*4882a593Smuzhiyun atomic_add(i, v);
2438*4882a593Smuzhiyun #elif defined(PLATFORM_WINDOWS)
2439*4882a593Smuzhiyun InterlockedAdd(v, i);
2440*4882a593Smuzhiyun #elif defined(PLATFORM_FREEBSD)
2441*4882a593Smuzhiyun atomic_add_int(v, i);
2442*4882a593Smuzhiyun #endif
2443*4882a593Smuzhiyun }
ATOMIC_SUB(ATOMIC_T * v,int i)2444*4882a593Smuzhiyun inline void ATOMIC_SUB(ATOMIC_T *v, int i)
2445*4882a593Smuzhiyun {
2446*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
2447*4882a593Smuzhiyun atomic_sub(i, v);
2448*4882a593Smuzhiyun #elif defined(PLATFORM_WINDOWS)
2449*4882a593Smuzhiyun InterlockedAdd(v, -i);
2450*4882a593Smuzhiyun #elif defined(PLATFORM_FREEBSD)
2451*4882a593Smuzhiyun atomic_subtract_int(v, i);
2452*4882a593Smuzhiyun #endif
2453*4882a593Smuzhiyun }
2454*4882a593Smuzhiyun
ATOMIC_INC(ATOMIC_T * v)2455*4882a593Smuzhiyun inline void ATOMIC_INC(ATOMIC_T *v)
2456*4882a593Smuzhiyun {
2457*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
2458*4882a593Smuzhiyun atomic_inc(v);
2459*4882a593Smuzhiyun #elif defined(PLATFORM_WINDOWS)
2460*4882a593Smuzhiyun InterlockedIncrement(v);
2461*4882a593Smuzhiyun #elif defined(PLATFORM_FREEBSD)
2462*4882a593Smuzhiyun atomic_add_int(v, 1);
2463*4882a593Smuzhiyun #endif
2464*4882a593Smuzhiyun }
2465*4882a593Smuzhiyun
ATOMIC_DEC(ATOMIC_T * v)2466*4882a593Smuzhiyun inline void ATOMIC_DEC(ATOMIC_T *v)
2467*4882a593Smuzhiyun {
2468*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
2469*4882a593Smuzhiyun atomic_dec(v);
2470*4882a593Smuzhiyun #elif defined(PLATFORM_WINDOWS)
2471*4882a593Smuzhiyun InterlockedDecrement(v);
2472*4882a593Smuzhiyun #elif defined(PLATFORM_FREEBSD)
2473*4882a593Smuzhiyun atomic_subtract_int(v, 1);
2474*4882a593Smuzhiyun #endif
2475*4882a593Smuzhiyun }
2476*4882a593Smuzhiyun
ATOMIC_ADD_RETURN(ATOMIC_T * v,int i)2477*4882a593Smuzhiyun inline int ATOMIC_ADD_RETURN(ATOMIC_T *v, int i)
2478*4882a593Smuzhiyun {
2479*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
2480*4882a593Smuzhiyun return atomic_add_return(i, v);
2481*4882a593Smuzhiyun #elif defined(PLATFORM_WINDOWS)
2482*4882a593Smuzhiyun return InterlockedAdd(v, i);
2483*4882a593Smuzhiyun #elif defined(PLATFORM_FREEBSD)
2484*4882a593Smuzhiyun atomic_add_int(v, i);
2485*4882a593Smuzhiyun return atomic_load_acq_32(v);
2486*4882a593Smuzhiyun #endif
2487*4882a593Smuzhiyun }
2488*4882a593Smuzhiyun
ATOMIC_SUB_RETURN(ATOMIC_T * v,int i)2489*4882a593Smuzhiyun inline int ATOMIC_SUB_RETURN(ATOMIC_T *v, int i)
2490*4882a593Smuzhiyun {
2491*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
2492*4882a593Smuzhiyun return atomic_sub_return(i, v);
2493*4882a593Smuzhiyun #elif defined(PLATFORM_WINDOWS)
2494*4882a593Smuzhiyun return InterlockedAdd(v, -i);
2495*4882a593Smuzhiyun #elif defined(PLATFORM_FREEBSD)
2496*4882a593Smuzhiyun atomic_subtract_int(v, i);
2497*4882a593Smuzhiyun return atomic_load_acq_32(v);
2498*4882a593Smuzhiyun #endif
2499*4882a593Smuzhiyun }
2500*4882a593Smuzhiyun
ATOMIC_INC_RETURN(ATOMIC_T * v)2501*4882a593Smuzhiyun inline int ATOMIC_INC_RETURN(ATOMIC_T *v)
2502*4882a593Smuzhiyun {
2503*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
2504*4882a593Smuzhiyun return atomic_inc_return(v);
2505*4882a593Smuzhiyun #elif defined(PLATFORM_WINDOWS)
2506*4882a593Smuzhiyun return InterlockedIncrement(v);
2507*4882a593Smuzhiyun #elif defined(PLATFORM_FREEBSD)
2508*4882a593Smuzhiyun atomic_add_int(v, 1);
2509*4882a593Smuzhiyun return atomic_load_acq_32(v);
2510*4882a593Smuzhiyun #endif
2511*4882a593Smuzhiyun }
2512*4882a593Smuzhiyun
ATOMIC_DEC_RETURN(ATOMIC_T * v)2513*4882a593Smuzhiyun inline int ATOMIC_DEC_RETURN(ATOMIC_T *v)
2514*4882a593Smuzhiyun {
2515*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
2516*4882a593Smuzhiyun return atomic_dec_return(v);
2517*4882a593Smuzhiyun #elif defined(PLATFORM_WINDOWS)
2518*4882a593Smuzhiyun return InterlockedDecrement(v);
2519*4882a593Smuzhiyun #elif defined(PLATFORM_FREEBSD)
2520*4882a593Smuzhiyun atomic_subtract_int(v, 1);
2521*4882a593Smuzhiyun return atomic_load_acq_32(v);
2522*4882a593Smuzhiyun #endif
2523*4882a593Smuzhiyun }
2524*4882a593Smuzhiyun
ATOMIC_INC_UNLESS(ATOMIC_T * v,int u)2525*4882a593Smuzhiyun inline bool ATOMIC_INC_UNLESS(ATOMIC_T *v, int u)
2526*4882a593Smuzhiyun {
2527*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
2528*4882a593Smuzhiyun #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 15))
2529*4882a593Smuzhiyun return atomic_add_unless(v, 1, u);
2530*4882a593Smuzhiyun #else
2531*4882a593Smuzhiyun /* only make sure not exceed after this function */
2532*4882a593Smuzhiyun if (ATOMIC_INC_RETURN(v) > u) {
2533*4882a593Smuzhiyun ATOMIC_DEC(v);
2534*4882a593Smuzhiyun return 0;
2535*4882a593Smuzhiyun }
2536*4882a593Smuzhiyun return 1;
2537*4882a593Smuzhiyun #endif
2538*4882a593Smuzhiyun #else
2539*4882a593Smuzhiyun #error "TBD\n"
2540*4882a593Smuzhiyun #endif
2541*4882a593Smuzhiyun }
2542*4882a593Smuzhiyun
2543*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
2544*4882a593Smuzhiyun #if !defined(CONFIG_RTW_ANDROID_GKI)
2545*4882a593Smuzhiyun /*
2546*4882a593Smuzhiyun * Open a file with the specific @param path, @param flag, @param mode
2547*4882a593Smuzhiyun * @param fpp the pointer of struct file pointer to get struct file pointer while file opening is success
2548*4882a593Smuzhiyun * @param path the path of the file to open
2549*4882a593Smuzhiyun * @param flag file operation flags, please refer to linux document
2550*4882a593Smuzhiyun * @param mode please refer to linux document
2551*4882a593Smuzhiyun * @return Linux specific error code
2552*4882a593Smuzhiyun */
openFile(struct file ** fpp,const char * path,int flag,int mode)2553*4882a593Smuzhiyun static int openFile(struct file **fpp, const char *path, int flag, int mode)
2554*4882a593Smuzhiyun {
2555*4882a593Smuzhiyun struct file *fp;
2556*4882a593Smuzhiyun
2557*4882a593Smuzhiyun fp = filp_open(path, flag, mode);
2558*4882a593Smuzhiyun if (IS_ERR(fp)) {
2559*4882a593Smuzhiyun *fpp = NULL;
2560*4882a593Smuzhiyun return PTR_ERR(fp);
2561*4882a593Smuzhiyun } else {
2562*4882a593Smuzhiyun *fpp = fp;
2563*4882a593Smuzhiyun return 0;
2564*4882a593Smuzhiyun }
2565*4882a593Smuzhiyun }
2566*4882a593Smuzhiyun
2567*4882a593Smuzhiyun /*
2568*4882a593Smuzhiyun * Close the file with the specific @param fp
2569*4882a593Smuzhiyun * @param fp the pointer of struct file to close
2570*4882a593Smuzhiyun * @return always 0
2571*4882a593Smuzhiyun */
closeFile(struct file * fp)2572*4882a593Smuzhiyun static int closeFile(struct file *fp)
2573*4882a593Smuzhiyun {
2574*4882a593Smuzhiyun filp_close(fp, NULL);
2575*4882a593Smuzhiyun return 0;
2576*4882a593Smuzhiyun }
2577*4882a593Smuzhiyun
readFile(struct file * fp,char * buf,int len)2578*4882a593Smuzhiyun static int readFile(struct file *fp, char *buf, int len)
2579*4882a593Smuzhiyun {
2580*4882a593Smuzhiyun int rlen = 0, sum = 0;
2581*4882a593Smuzhiyun
2582*4882a593Smuzhiyun #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
2583*4882a593Smuzhiyun if (!(fp->f_mode & FMODE_CAN_READ))
2584*4882a593Smuzhiyun #else
2585*4882a593Smuzhiyun if (!fp->f_op || !fp->f_op->read)
2586*4882a593Smuzhiyun #endif
2587*4882a593Smuzhiyun return -EPERM;
2588*4882a593Smuzhiyun
2589*4882a593Smuzhiyun while (sum < len) {
2590*4882a593Smuzhiyun #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
2591*4882a593Smuzhiyun rlen = kernel_read(fp, buf + sum, len - sum, &fp->f_pos);
2592*4882a593Smuzhiyun #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
2593*4882a593Smuzhiyun rlen = __vfs_read(fp, buf + sum, len - sum, &fp->f_pos);
2594*4882a593Smuzhiyun #else
2595*4882a593Smuzhiyun rlen = fp->f_op->read(fp, buf + sum, len - sum, &fp->f_pos);
2596*4882a593Smuzhiyun #endif
2597*4882a593Smuzhiyun if (rlen > 0)
2598*4882a593Smuzhiyun sum += rlen;
2599*4882a593Smuzhiyun else if (0 != rlen)
2600*4882a593Smuzhiyun return rlen;
2601*4882a593Smuzhiyun else
2602*4882a593Smuzhiyun break;
2603*4882a593Smuzhiyun }
2604*4882a593Smuzhiyun
2605*4882a593Smuzhiyun return sum;
2606*4882a593Smuzhiyun
2607*4882a593Smuzhiyun }
2608*4882a593Smuzhiyun
writeFile(struct file * fp,char * buf,int len)2609*4882a593Smuzhiyun static int writeFile(struct file *fp, char *buf, int len)
2610*4882a593Smuzhiyun {
2611*4882a593Smuzhiyun int wlen = 0, sum = 0;
2612*4882a593Smuzhiyun
2613*4882a593Smuzhiyun #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
2614*4882a593Smuzhiyun if (!(fp->f_mode & FMODE_CAN_WRITE))
2615*4882a593Smuzhiyun #else
2616*4882a593Smuzhiyun if (!fp->f_op || !fp->f_op->write)
2617*4882a593Smuzhiyun #endif
2618*4882a593Smuzhiyun return -EPERM;
2619*4882a593Smuzhiyun
2620*4882a593Smuzhiyun while (sum < len) {
2621*4882a593Smuzhiyun #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
2622*4882a593Smuzhiyun wlen = kernel_write(fp, buf + sum, len - sum, &fp->f_pos);
2623*4882a593Smuzhiyun #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
2624*4882a593Smuzhiyun wlen = __vfs_write(fp, buf + sum, len - sum, &fp->f_pos);
2625*4882a593Smuzhiyun #else
2626*4882a593Smuzhiyun wlen = fp->f_op->write(fp, buf + sum, len - sum, &fp->f_pos);
2627*4882a593Smuzhiyun #endif
2628*4882a593Smuzhiyun if (wlen > 0)
2629*4882a593Smuzhiyun sum += wlen;
2630*4882a593Smuzhiyun else if (0 != wlen)
2631*4882a593Smuzhiyun return wlen;
2632*4882a593Smuzhiyun else
2633*4882a593Smuzhiyun break;
2634*4882a593Smuzhiyun }
2635*4882a593Smuzhiyun
2636*4882a593Smuzhiyun return sum;
2637*4882a593Smuzhiyun
2638*4882a593Smuzhiyun }
2639*4882a593Smuzhiyun
2640*4882a593Smuzhiyun /*
2641*4882a593Smuzhiyun * Test if the specifi @param pathname is a direct and readable
2642*4882a593Smuzhiyun * If readable, @param sz is not used
2643*4882a593Smuzhiyun * @param pathname the name of the path to test
2644*4882a593Smuzhiyun * @return Linux specific error code
2645*4882a593Smuzhiyun */
isDirReadable(const char * pathname,u32 * sz)2646*4882a593Smuzhiyun static int isDirReadable(const char *pathname, u32 *sz)
2647*4882a593Smuzhiyun {
2648*4882a593Smuzhiyun struct path path;
2649*4882a593Smuzhiyun int error = 0;
2650*4882a593Smuzhiyun
2651*4882a593Smuzhiyun return kern_path(pathname, LOOKUP_FOLLOW, &path);
2652*4882a593Smuzhiyun }
2653*4882a593Smuzhiyun
2654*4882a593Smuzhiyun /*
2655*4882a593Smuzhiyun * Test if the specifi @param path is a file and readable
2656*4882a593Smuzhiyun * If readable, @param sz is got
2657*4882a593Smuzhiyun * @param path the path of the file to test
2658*4882a593Smuzhiyun * @return Linux specific error code
2659*4882a593Smuzhiyun */
isFileReadable(const char * path,u32 * sz)2660*4882a593Smuzhiyun static int isFileReadable(const char *path, u32 *sz)
2661*4882a593Smuzhiyun {
2662*4882a593Smuzhiyun struct file *fp;
2663*4882a593Smuzhiyun int ret = 0;
2664*4882a593Smuzhiyun #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0))
2665*4882a593Smuzhiyun mm_segment_t oldfs;
2666*4882a593Smuzhiyun #endif
2667*4882a593Smuzhiyun char buf;
2668*4882a593Smuzhiyun
2669*4882a593Smuzhiyun fp = filp_open(path, O_RDONLY, 0);
2670*4882a593Smuzhiyun if (IS_ERR(fp))
2671*4882a593Smuzhiyun ret = PTR_ERR(fp);
2672*4882a593Smuzhiyun else {
2673*4882a593Smuzhiyun #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0))
2674*4882a593Smuzhiyun oldfs = get_fs();
2675*4882a593Smuzhiyun #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0))
2676*4882a593Smuzhiyun set_fs(KERNEL_DS);
2677*4882a593Smuzhiyun #else
2678*4882a593Smuzhiyun set_fs(get_ds());
2679*4882a593Smuzhiyun #endif
2680*4882a593Smuzhiyun #endif
2681*4882a593Smuzhiyun
2682*4882a593Smuzhiyun if (1 != readFile(fp, &buf, 1))
2683*4882a593Smuzhiyun ret = PTR_ERR(fp);
2684*4882a593Smuzhiyun
2685*4882a593Smuzhiyun if (ret == 0 && sz) {
2686*4882a593Smuzhiyun #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
2687*4882a593Smuzhiyun *sz = i_size_read(fp->f_path.dentry->d_inode);
2688*4882a593Smuzhiyun #else
2689*4882a593Smuzhiyun *sz = i_size_read(fp->f_dentry->d_inode);
2690*4882a593Smuzhiyun #endif
2691*4882a593Smuzhiyun }
2692*4882a593Smuzhiyun
2693*4882a593Smuzhiyun #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0))
2694*4882a593Smuzhiyun set_fs(oldfs);
2695*4882a593Smuzhiyun #endif
2696*4882a593Smuzhiyun filp_close(fp, NULL);
2697*4882a593Smuzhiyun }
2698*4882a593Smuzhiyun return ret;
2699*4882a593Smuzhiyun }
2700*4882a593Smuzhiyun
2701*4882a593Smuzhiyun /*
2702*4882a593Smuzhiyun * Open the file with @param path and wirte @param sz byte of data starting from @param buf into the file
2703*4882a593Smuzhiyun * @param path the path of the file to open and write
2704*4882a593Smuzhiyun * @param buf the starting address of the data to write into file
2705*4882a593Smuzhiyun * @param sz how many bytes to write at most
2706*4882a593Smuzhiyun * @return the byte we've written, or Linux specific error code
2707*4882a593Smuzhiyun */
storeToFile(const char * path,u8 * buf,u32 sz)2708*4882a593Smuzhiyun static int storeToFile(const char *path, u8 *buf, u32 sz)
2709*4882a593Smuzhiyun {
2710*4882a593Smuzhiyun int ret = 0;
2711*4882a593Smuzhiyun #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0))
2712*4882a593Smuzhiyun mm_segment_t oldfs;
2713*4882a593Smuzhiyun #endif
2714*4882a593Smuzhiyun struct file *fp;
2715*4882a593Smuzhiyun
2716*4882a593Smuzhiyun if (path && buf) {
2717*4882a593Smuzhiyun ret = openFile(&fp, path, O_CREAT | O_WRONLY, 0666);
2718*4882a593Smuzhiyun if (0 == ret) {
2719*4882a593Smuzhiyun RTW_INFO("%s openFile path:%s fp=%p\n", __FUNCTION__, path , fp);
2720*4882a593Smuzhiyun
2721*4882a593Smuzhiyun #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0))
2722*4882a593Smuzhiyun oldfs = get_fs();
2723*4882a593Smuzhiyun #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0))
2724*4882a593Smuzhiyun set_fs(KERNEL_DS);
2725*4882a593Smuzhiyun #else
2726*4882a593Smuzhiyun set_fs(get_ds());
2727*4882a593Smuzhiyun #endif
2728*4882a593Smuzhiyun #endif
2729*4882a593Smuzhiyun
2730*4882a593Smuzhiyun ret = writeFile(fp, buf, sz);
2731*4882a593Smuzhiyun
2732*4882a593Smuzhiyun #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0))
2733*4882a593Smuzhiyun set_fs(oldfs);
2734*4882a593Smuzhiyun #endif
2735*4882a593Smuzhiyun closeFile(fp);
2736*4882a593Smuzhiyun
2737*4882a593Smuzhiyun RTW_INFO("%s writeFile, ret:%d\n", __FUNCTION__, ret);
2738*4882a593Smuzhiyun
2739*4882a593Smuzhiyun } else
2740*4882a593Smuzhiyun RTW_INFO("%s openFile path:%s Fail, ret:%d\n", __FUNCTION__, path, ret);
2741*4882a593Smuzhiyun } else {
2742*4882a593Smuzhiyun RTW_INFO("%s NULL pointer\n", __FUNCTION__);
2743*4882a593Smuzhiyun ret = -EINVAL;
2744*4882a593Smuzhiyun }
2745*4882a593Smuzhiyun return ret;
2746*4882a593Smuzhiyun }
2747*4882a593Smuzhiyun #endif /* !defined(CONFIG_RTW_ANDROID_GKI)*/
2748*4882a593Smuzhiyun #endif /* PLATFORM_LINUX */
2749*4882a593Smuzhiyun
2750*4882a593Smuzhiyun #if !defined(CONFIG_RTW_ANDROID_GKI)
2751*4882a593Smuzhiyun /*
2752*4882a593Smuzhiyun * Test if the specifi @param path is a direct and readable
2753*4882a593Smuzhiyun * @param path the path of the direct to test
2754*4882a593Smuzhiyun * @return _TRUE or _FALSE
2755*4882a593Smuzhiyun */
rtw_is_dir_readable(const char * path)2756*4882a593Smuzhiyun int rtw_is_dir_readable(const char *path)
2757*4882a593Smuzhiyun {
2758*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
2759*4882a593Smuzhiyun if (isDirReadable(path, NULL) == 0)
2760*4882a593Smuzhiyun return _TRUE;
2761*4882a593Smuzhiyun else
2762*4882a593Smuzhiyun return _FALSE;
2763*4882a593Smuzhiyun #else
2764*4882a593Smuzhiyun /* Todo... */
2765*4882a593Smuzhiyun return _FALSE;
2766*4882a593Smuzhiyun #endif
2767*4882a593Smuzhiyun }
2768*4882a593Smuzhiyun #endif /* !defined(CONFIG_RTW_ANDROID_GKI) */
2769*4882a593Smuzhiyun
2770*4882a593Smuzhiyun /*
2771*4882a593Smuzhiyun * Open the file with @param path and retrive the file content into memory starting from @param buf for @param sz at most
2772*4882a593Smuzhiyun * @param path the path of the file to open and read
2773*4882a593Smuzhiyun * @param buf the starting address of the buffer to store file content
2774*4882a593Smuzhiyun * @param sz how many bytes to read at most
2775*4882a593Smuzhiyun * @return the byte we've read, or Linux specific error code
2776*4882a593Smuzhiyun */
retriveFromFile(const char * path,u8 * buf,u32 sz)2777*4882a593Smuzhiyun static int retriveFromFile(const char *path, u8 *buf, u32 sz)
2778*4882a593Smuzhiyun {
2779*4882a593Smuzhiyun #if defined(CONFIG_RTW_ANDROID_GKI)
2780*4882a593Smuzhiyun int ret = -EINVAL;
2781*4882a593Smuzhiyun const struct firmware *fw = NULL;
2782*4882a593Smuzhiyun char* const delim = "/";
2783*4882a593Smuzhiyun char *name, *token, *cur, *path_tmp = NULL;
2784*4882a593Smuzhiyun
2785*4882a593Smuzhiyun
2786*4882a593Smuzhiyun if (path == NULL || buf == NULL) {
2787*4882a593Smuzhiyun RTW_ERR("%s() NULL pointer\n", __func__);
2788*4882a593Smuzhiyun goto err;
2789*4882a593Smuzhiyun }
2790*4882a593Smuzhiyun
2791*4882a593Smuzhiyun path_tmp = kstrdup(path, GFP_KERNEL);
2792*4882a593Smuzhiyun if (path_tmp == NULL) {
2793*4882a593Smuzhiyun RTW_ERR("%s() cannot copy path for parsing file name\n", __func__);
2794*4882a593Smuzhiyun goto err;
2795*4882a593Smuzhiyun }
2796*4882a593Smuzhiyun
2797*4882a593Smuzhiyun /* parsing file name from path */
2798*4882a593Smuzhiyun cur = path_tmp;
2799*4882a593Smuzhiyun token = strsep(&cur, delim);
2800*4882a593Smuzhiyun while (token != NULL) {
2801*4882a593Smuzhiyun token = strsep(&cur, delim);
2802*4882a593Smuzhiyun if(token)
2803*4882a593Smuzhiyun name = token;
2804*4882a593Smuzhiyun }
2805*4882a593Smuzhiyun
2806*4882a593Smuzhiyun if (name == NULL) {
2807*4882a593Smuzhiyun RTW_ERR("%s() parsing file name fail\n", __func__);
2808*4882a593Smuzhiyun goto err;
2809*4882a593Smuzhiyun }
2810*4882a593Smuzhiyun
2811*4882a593Smuzhiyun /* request_firmware() will find file in /vendor/firmware but not in path */
2812*4882a593Smuzhiyun ret = request_firmware(&fw, name, NULL);
2813*4882a593Smuzhiyun if (ret == 0) {
2814*4882a593Smuzhiyun RTW_INFO("%s() Success. retrieve file : %s, file size : %zu\n", __func__, name, fw->size);
2815*4882a593Smuzhiyun
2816*4882a593Smuzhiyun if ((u32)fw->size < sz) {
2817*4882a593Smuzhiyun _rtw_memcpy(buf, fw->data, (u32)fw->size);
2818*4882a593Smuzhiyun ret = (u32)fw->size;
2819*4882a593Smuzhiyun goto exit;
2820*4882a593Smuzhiyun } else {
2821*4882a593Smuzhiyun RTW_ERR("%s() file size : %zu exceed buf size : %u\n", __func__, fw->size, sz);
2822*4882a593Smuzhiyun ret = -EFBIG;
2823*4882a593Smuzhiyun goto err;
2824*4882a593Smuzhiyun }
2825*4882a593Smuzhiyun } else {
2826*4882a593Smuzhiyun RTW_ERR("%s() Fail. retrieve file : %s, error : %d\n", __func__, name, ret);
2827*4882a593Smuzhiyun goto err;
2828*4882a593Smuzhiyun }
2829*4882a593Smuzhiyun
2830*4882a593Smuzhiyun
2831*4882a593Smuzhiyun
2832*4882a593Smuzhiyun err:
2833*4882a593Smuzhiyun RTW_ERR("%s() Fail. retrieve file : %s, error : %d\n", __func__, path, ret);
2834*4882a593Smuzhiyun exit:
2835*4882a593Smuzhiyun if (path_tmp)
2836*4882a593Smuzhiyun kfree(path_tmp);
2837*4882a593Smuzhiyun if (fw)
2838*4882a593Smuzhiyun release_firmware(fw);
2839*4882a593Smuzhiyun return ret;
2840*4882a593Smuzhiyun #else /* !defined(CONFIG_RTW_ANDROID_GKI) */
2841*4882a593Smuzhiyun int ret = -1;
2842*4882a593Smuzhiyun #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0))
2843*4882a593Smuzhiyun mm_segment_t oldfs;
2844*4882a593Smuzhiyun #endif
2845*4882a593Smuzhiyun struct file *fp;
2846*4882a593Smuzhiyun
2847*4882a593Smuzhiyun if (path && buf) {
2848*4882a593Smuzhiyun ret = openFile(&fp, path, O_RDONLY, 0);
2849*4882a593Smuzhiyun if (0 == ret) {
2850*4882a593Smuzhiyun RTW_INFO("%s openFile path:%s fp=%p\n", __FUNCTION__, path , fp);
2851*4882a593Smuzhiyun
2852*4882a593Smuzhiyun #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0))
2853*4882a593Smuzhiyun oldfs = get_fs();
2854*4882a593Smuzhiyun #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0))
2855*4882a593Smuzhiyun set_fs(KERNEL_DS);
2856*4882a593Smuzhiyun #else
2857*4882a593Smuzhiyun set_fs(get_ds());
2858*4882a593Smuzhiyun #endif
2859*4882a593Smuzhiyun #endif
2860*4882a593Smuzhiyun
2861*4882a593Smuzhiyun ret = readFile(fp, buf, sz);
2862*4882a593Smuzhiyun
2863*4882a593Smuzhiyun #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0))
2864*4882a593Smuzhiyun set_fs(oldfs);
2865*4882a593Smuzhiyun #endif
2866*4882a593Smuzhiyun closeFile(fp);
2867*4882a593Smuzhiyun
2868*4882a593Smuzhiyun RTW_INFO("%s readFile, ret:%d\n", __FUNCTION__, ret);
2869*4882a593Smuzhiyun
2870*4882a593Smuzhiyun } else
2871*4882a593Smuzhiyun RTW_INFO("%s openFile path:%s Fail, ret:%d\n", __FUNCTION__, path, ret);
2872*4882a593Smuzhiyun } else {
2873*4882a593Smuzhiyun RTW_INFO("%s NULL pointer\n", __FUNCTION__);
2874*4882a593Smuzhiyun ret = -EINVAL;
2875*4882a593Smuzhiyun }
2876*4882a593Smuzhiyun return ret;
2877*4882a593Smuzhiyun #endif /* defined(CONFIG_RTW_ANDROID_GKI) */
2878*4882a593Smuzhiyun }
2879*4882a593Smuzhiyun
2880*4882a593Smuzhiyun /*
2881*4882a593Smuzhiyun * Test if the specifi @param path is a file and readable
2882*4882a593Smuzhiyun * @param path the path of the file to test
2883*4882a593Smuzhiyun * @return _TRUE or _FALSE
2884*4882a593Smuzhiyun */
rtw_is_file_readable(const char * path)2885*4882a593Smuzhiyun int rtw_is_file_readable(const char *path)
2886*4882a593Smuzhiyun {
2887*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
2888*4882a593Smuzhiyun #if !defined(CONFIG_RTW_ANDROID_GKI)
2889*4882a593Smuzhiyun if (isFileReadable(path, NULL) == 0)
2890*4882a593Smuzhiyun return _TRUE;
2891*4882a593Smuzhiyun else
2892*4882a593Smuzhiyun return _FALSE;
2893*4882a593Smuzhiyun #else
2894*4882a593Smuzhiyun RTW_INFO("%s() Android GKI prohibbit kernel_read, return _TRUE\n", __func__);
2895*4882a593Smuzhiyun return _TRUE;
2896*4882a593Smuzhiyun #endif /* !defined(CONFIG_RTW_ANDROID_GKI) */
2897*4882a593Smuzhiyun #else
2898*4882a593Smuzhiyun /* Todo... */
2899*4882a593Smuzhiyun return _FALSE;
2900*4882a593Smuzhiyun #endif
2901*4882a593Smuzhiyun }
2902*4882a593Smuzhiyun
2903*4882a593Smuzhiyun /*
2904*4882a593Smuzhiyun * Test if the specifi @param path is a file and readable.
2905*4882a593Smuzhiyun * If readable, @param sz is got
2906*4882a593Smuzhiyun * @param path the path of the file to test
2907*4882a593Smuzhiyun * @return _TRUE or _FALSE
2908*4882a593Smuzhiyun */
rtw_is_file_readable_with_size(const char * path,u32 * sz)2909*4882a593Smuzhiyun int rtw_is_file_readable_with_size(const char *path, u32 *sz)
2910*4882a593Smuzhiyun {
2911*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
2912*4882a593Smuzhiyun #if !defined(CONFIG_RTW_ANDROID_GKI)
2913*4882a593Smuzhiyun if (isFileReadable(path, sz) == 0)
2914*4882a593Smuzhiyun return _TRUE;
2915*4882a593Smuzhiyun else
2916*4882a593Smuzhiyun return _FALSE;
2917*4882a593Smuzhiyun #else
2918*4882a593Smuzhiyun RTW_INFO("%s() Android GKI prohibbit kernel_read, return _TRUE\n", __func__);
2919*4882a593Smuzhiyun *sz = 0;
2920*4882a593Smuzhiyun return _TRUE;
2921*4882a593Smuzhiyun #endif /* !defined(CONFIG_RTW_ANDROID_GKI) */
2922*4882a593Smuzhiyun #else
2923*4882a593Smuzhiyun /* Todo... */
2924*4882a593Smuzhiyun return _FALSE;
2925*4882a593Smuzhiyun #endif
2926*4882a593Smuzhiyun }
2927*4882a593Smuzhiyun
2928*4882a593Smuzhiyun /*
2929*4882a593Smuzhiyun * Test if the specifi @param path is a readable file with valid size.
2930*4882a593Smuzhiyun * If readable, @param sz is got
2931*4882a593Smuzhiyun * @param path the path of the file to test
2932*4882a593Smuzhiyun * @return _TRUE or _FALSE
2933*4882a593Smuzhiyun */
rtw_readable_file_sz_chk(const char * path,u32 sz)2934*4882a593Smuzhiyun int rtw_readable_file_sz_chk(const char *path, u32 sz)
2935*4882a593Smuzhiyun {
2936*4882a593Smuzhiyun u32 fsz;
2937*4882a593Smuzhiyun
2938*4882a593Smuzhiyun if (rtw_is_file_readable_with_size(path, &fsz) == _FALSE)
2939*4882a593Smuzhiyun return _FALSE;
2940*4882a593Smuzhiyun
2941*4882a593Smuzhiyun if (fsz > sz)
2942*4882a593Smuzhiyun return _FALSE;
2943*4882a593Smuzhiyun
2944*4882a593Smuzhiyun return _TRUE;
2945*4882a593Smuzhiyun }
2946*4882a593Smuzhiyun
2947*4882a593Smuzhiyun /*
2948*4882a593Smuzhiyun * Open the file with @param path and retrive the file content into memory starting from @param buf for @param sz at most
2949*4882a593Smuzhiyun * @param path the path of the file to open and read
2950*4882a593Smuzhiyun * @param buf the starting address of the buffer to store file content
2951*4882a593Smuzhiyun * @param sz how many bytes to read at most
2952*4882a593Smuzhiyun * @return the byte we've read
2953*4882a593Smuzhiyun */
rtw_retrieve_from_file(const char * path,u8 * buf,u32 sz)2954*4882a593Smuzhiyun int rtw_retrieve_from_file(const char *path, u8 *buf, u32 sz)
2955*4882a593Smuzhiyun {
2956*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
2957*4882a593Smuzhiyun int ret = retriveFromFile(path, buf, sz);
2958*4882a593Smuzhiyun return ret >= 0 ? ret : 0;
2959*4882a593Smuzhiyun #else
2960*4882a593Smuzhiyun /* Todo... */
2961*4882a593Smuzhiyun return 0;
2962*4882a593Smuzhiyun #endif
2963*4882a593Smuzhiyun }
2964*4882a593Smuzhiyun
2965*4882a593Smuzhiyun #if !defined(CONFIG_RTW_ANDROID_GKI)
2966*4882a593Smuzhiyun /*
2967*4882a593Smuzhiyun * Open the file with @param path and wirte @param sz byte of data starting from @param buf into the file
2968*4882a593Smuzhiyun * @param path the path of the file to open and write
2969*4882a593Smuzhiyun * @param buf the starting address of the data to write into file
2970*4882a593Smuzhiyun * @param sz how many bytes to write at most
2971*4882a593Smuzhiyun * @return the byte we've written
2972*4882a593Smuzhiyun */
rtw_store_to_file(const char * path,u8 * buf,u32 sz)2973*4882a593Smuzhiyun int rtw_store_to_file(const char *path, u8 *buf, u32 sz)
2974*4882a593Smuzhiyun {
2975*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
2976*4882a593Smuzhiyun int ret = storeToFile(path, buf, sz);
2977*4882a593Smuzhiyun return ret >= 0 ? ret : 0;
2978*4882a593Smuzhiyun #else
2979*4882a593Smuzhiyun /* Todo... */
2980*4882a593Smuzhiyun return 0;
2981*4882a593Smuzhiyun #endif
2982*4882a593Smuzhiyun }
2983*4882a593Smuzhiyun #endif /* !defined(CONFIG_RTW_ANDROID_GKI) */
2984*4882a593Smuzhiyun
2985*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
rtw_alloc_etherdev_with_old_priv(int sizeof_priv,void * old_priv)2986*4882a593Smuzhiyun struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv, void *old_priv)
2987*4882a593Smuzhiyun {
2988*4882a593Smuzhiyun struct net_device *pnetdev;
2989*4882a593Smuzhiyun struct rtw_netdev_priv_indicator *pnpi;
2990*4882a593Smuzhiyun
2991*4882a593Smuzhiyun #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
2992*4882a593Smuzhiyun pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
2993*4882a593Smuzhiyun #else
2994*4882a593Smuzhiyun pnetdev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
2995*4882a593Smuzhiyun #endif
2996*4882a593Smuzhiyun if (!pnetdev)
2997*4882a593Smuzhiyun goto RETURN;
2998*4882a593Smuzhiyun
2999*4882a593Smuzhiyun pnpi = netdev_priv(pnetdev);
3000*4882a593Smuzhiyun pnpi->priv = old_priv;
3001*4882a593Smuzhiyun pnpi->sizeof_priv = sizeof_priv;
3002*4882a593Smuzhiyun
3003*4882a593Smuzhiyun RETURN:
3004*4882a593Smuzhiyun return pnetdev;
3005*4882a593Smuzhiyun }
3006*4882a593Smuzhiyun
rtw_alloc_etherdev(int sizeof_priv)3007*4882a593Smuzhiyun struct net_device *rtw_alloc_etherdev(int sizeof_priv)
3008*4882a593Smuzhiyun {
3009*4882a593Smuzhiyun struct net_device *pnetdev;
3010*4882a593Smuzhiyun struct rtw_netdev_priv_indicator *pnpi;
3011*4882a593Smuzhiyun
3012*4882a593Smuzhiyun #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
3013*4882a593Smuzhiyun pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
3014*4882a593Smuzhiyun #else
3015*4882a593Smuzhiyun pnetdev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
3016*4882a593Smuzhiyun #endif
3017*4882a593Smuzhiyun if (!pnetdev)
3018*4882a593Smuzhiyun goto RETURN;
3019*4882a593Smuzhiyun
3020*4882a593Smuzhiyun pnpi = netdev_priv(pnetdev);
3021*4882a593Smuzhiyun
3022*4882a593Smuzhiyun pnpi->priv = rtw_zvmalloc(sizeof_priv);
3023*4882a593Smuzhiyun if (!pnpi->priv) {
3024*4882a593Smuzhiyun free_netdev(pnetdev);
3025*4882a593Smuzhiyun pnetdev = NULL;
3026*4882a593Smuzhiyun goto RETURN;
3027*4882a593Smuzhiyun }
3028*4882a593Smuzhiyun
3029*4882a593Smuzhiyun pnpi->sizeof_priv = sizeof_priv;
3030*4882a593Smuzhiyun RETURN:
3031*4882a593Smuzhiyun return pnetdev;
3032*4882a593Smuzhiyun }
3033*4882a593Smuzhiyun
rtw_free_netdev(struct net_device * netdev)3034*4882a593Smuzhiyun void rtw_free_netdev(struct net_device *netdev)
3035*4882a593Smuzhiyun {
3036*4882a593Smuzhiyun struct rtw_netdev_priv_indicator *pnpi;
3037*4882a593Smuzhiyun
3038*4882a593Smuzhiyun if (!netdev)
3039*4882a593Smuzhiyun goto RETURN;
3040*4882a593Smuzhiyun
3041*4882a593Smuzhiyun pnpi = netdev_priv(netdev);
3042*4882a593Smuzhiyun
3043*4882a593Smuzhiyun if (!pnpi->priv)
3044*4882a593Smuzhiyun goto RETURN;
3045*4882a593Smuzhiyun
3046*4882a593Smuzhiyun free_netdev(netdev);
3047*4882a593Smuzhiyun
3048*4882a593Smuzhiyun RETURN:
3049*4882a593Smuzhiyun return;
3050*4882a593Smuzhiyun }
3051*4882a593Smuzhiyun
3052*4882a593Smuzhiyun #endif
3053*4882a593Smuzhiyun
3054*4882a593Smuzhiyun #ifdef PLATFORM_FREEBSD
3055*4882a593Smuzhiyun /*
3056*4882a593Smuzhiyun * Copy a buffer from userspace and write into kernel address
3057*4882a593Smuzhiyun * space.
3058*4882a593Smuzhiyun *
3059*4882a593Smuzhiyun * This emulation just calls the FreeBSD copyin function (to
3060*4882a593Smuzhiyun * copy data from user space buffer into a kernel space buffer)
3061*4882a593Smuzhiyun * and is designed to be used with the above io_write_wrapper.
3062*4882a593Smuzhiyun *
3063*4882a593Smuzhiyun * This function should return the number of bytes not copied.
3064*4882a593Smuzhiyun * I.e. success results in a zero value.
3065*4882a593Smuzhiyun * Negative error values are not returned.
3066*4882a593Smuzhiyun */
3067*4882a593Smuzhiyun unsigned long
copy_from_user(void * to,const void * from,unsigned long n)3068*4882a593Smuzhiyun copy_from_user(void *to, const void *from, unsigned long n)
3069*4882a593Smuzhiyun {
3070*4882a593Smuzhiyun if (copyin(from, to, n) != 0) {
3071*4882a593Smuzhiyun /* Any errors will be treated as a failure
3072*4882a593Smuzhiyun to copy any of the requested bytes */
3073*4882a593Smuzhiyun return n;
3074*4882a593Smuzhiyun }
3075*4882a593Smuzhiyun
3076*4882a593Smuzhiyun return 0;
3077*4882a593Smuzhiyun }
3078*4882a593Smuzhiyun
3079*4882a593Smuzhiyun unsigned long
copy_to_user(void * to,const void * from,unsigned long n)3080*4882a593Smuzhiyun copy_to_user(void *to, const void *from, unsigned long n)
3081*4882a593Smuzhiyun {
3082*4882a593Smuzhiyun if (copyout(from, to, n) != 0) {
3083*4882a593Smuzhiyun /* Any errors will be treated as a failure
3084*4882a593Smuzhiyun to copy any of the requested bytes */
3085*4882a593Smuzhiyun return n;
3086*4882a593Smuzhiyun }
3087*4882a593Smuzhiyun
3088*4882a593Smuzhiyun return 0;
3089*4882a593Smuzhiyun }
3090*4882a593Smuzhiyun
3091*4882a593Smuzhiyun
3092*4882a593Smuzhiyun /*
3093*4882a593Smuzhiyun * The usb_register and usb_deregister functions are used to register
3094*4882a593Smuzhiyun * usb drivers with the usb subsystem. In this compatibility layer
3095*4882a593Smuzhiyun * emulation a list of drivers (struct usb_driver) is maintained
3096*4882a593Smuzhiyun * and is used for probing/attaching etc.
3097*4882a593Smuzhiyun *
3098*4882a593Smuzhiyun * usb_register and usb_deregister simply call these functions.
3099*4882a593Smuzhiyun */
3100*4882a593Smuzhiyun int
usb_register(struct usb_driver * driver)3101*4882a593Smuzhiyun usb_register(struct usb_driver *driver)
3102*4882a593Smuzhiyun {
3103*4882a593Smuzhiyun rtw_usb_linux_register(driver);
3104*4882a593Smuzhiyun return 0;
3105*4882a593Smuzhiyun }
3106*4882a593Smuzhiyun
3107*4882a593Smuzhiyun
3108*4882a593Smuzhiyun int
usb_deregister(struct usb_driver * driver)3109*4882a593Smuzhiyun usb_deregister(struct usb_driver *driver)
3110*4882a593Smuzhiyun {
3111*4882a593Smuzhiyun rtw_usb_linux_deregister(driver);
3112*4882a593Smuzhiyun return 0;
3113*4882a593Smuzhiyun }
3114*4882a593Smuzhiyun
module_init_exit_wrapper(void * arg)3115*4882a593Smuzhiyun void module_init_exit_wrapper(void *arg)
3116*4882a593Smuzhiyun {
3117*4882a593Smuzhiyun int (*func)(void) = arg;
3118*4882a593Smuzhiyun func();
3119*4882a593Smuzhiyun return;
3120*4882a593Smuzhiyun }
3121*4882a593Smuzhiyun
3122*4882a593Smuzhiyun #endif /* PLATFORM_FREEBSD */
3123*4882a593Smuzhiyun
3124*4882a593Smuzhiyun #ifdef CONFIG_PLATFORM_SPRD
3125*4882a593Smuzhiyun #ifdef do_div
3126*4882a593Smuzhiyun #undef do_div
3127*4882a593Smuzhiyun #endif
3128*4882a593Smuzhiyun #include <asm-generic/div64.h>
3129*4882a593Smuzhiyun #endif
3130*4882a593Smuzhiyun
rtw_modular64(u64 x,u64 y)3131*4882a593Smuzhiyun u64 rtw_modular64(u64 x, u64 y)
3132*4882a593Smuzhiyun {
3133*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
3134*4882a593Smuzhiyun return do_div(x, y);
3135*4882a593Smuzhiyun #elif defined(PLATFORM_WINDOWS)
3136*4882a593Smuzhiyun return x % y;
3137*4882a593Smuzhiyun #elif defined(PLATFORM_FREEBSD)
3138*4882a593Smuzhiyun return x % y;
3139*4882a593Smuzhiyun #endif
3140*4882a593Smuzhiyun }
3141*4882a593Smuzhiyun
rtw_division64(u64 x,u64 y)3142*4882a593Smuzhiyun u64 rtw_division64(u64 x, u64 y)
3143*4882a593Smuzhiyun {
3144*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
3145*4882a593Smuzhiyun do_div(x, y);
3146*4882a593Smuzhiyun return x;
3147*4882a593Smuzhiyun #elif defined(PLATFORM_WINDOWS)
3148*4882a593Smuzhiyun return x / y;
3149*4882a593Smuzhiyun #elif defined(PLATFORM_FREEBSD)
3150*4882a593Smuzhiyun return x / y;
3151*4882a593Smuzhiyun #endif
3152*4882a593Smuzhiyun }
3153*4882a593Smuzhiyun
rtw_random32(void)3154*4882a593Smuzhiyun inline u32 rtw_random32(void)
3155*4882a593Smuzhiyun {
3156*4882a593Smuzhiyun #ifdef PLATFORM_LINUX
3157*4882a593Smuzhiyun #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
3158*4882a593Smuzhiyun return prandom_u32();
3159*4882a593Smuzhiyun #elif (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18))
3160*4882a593Smuzhiyun u32 random_int;
3161*4882a593Smuzhiyun get_random_bytes(&random_int , 4);
3162*4882a593Smuzhiyun return random_int;
3163*4882a593Smuzhiyun #else
3164*4882a593Smuzhiyun return random32();
3165*4882a593Smuzhiyun #endif
3166*4882a593Smuzhiyun #elif defined(PLATFORM_WINDOWS)
3167*4882a593Smuzhiyun #error "to be implemented\n"
3168*4882a593Smuzhiyun #elif defined(PLATFORM_FREEBSD)
3169*4882a593Smuzhiyun #error "to be implemented\n"
3170*4882a593Smuzhiyun #endif
3171*4882a593Smuzhiyun }
3172*4882a593Smuzhiyun
rtw_buf_free(u8 ** buf,u32 * buf_len)3173*4882a593Smuzhiyun void rtw_buf_free(u8 **buf, u32 *buf_len)
3174*4882a593Smuzhiyun {
3175*4882a593Smuzhiyun u32 ori_len;
3176*4882a593Smuzhiyun
3177*4882a593Smuzhiyun if (!buf || !buf_len)
3178*4882a593Smuzhiyun return;
3179*4882a593Smuzhiyun
3180*4882a593Smuzhiyun ori_len = *buf_len;
3181*4882a593Smuzhiyun
3182*4882a593Smuzhiyun if (*buf) {
3183*4882a593Smuzhiyun u32 tmp_buf_len = *buf_len;
3184*4882a593Smuzhiyun *buf_len = 0;
3185*4882a593Smuzhiyun rtw_mfree(*buf, tmp_buf_len);
3186*4882a593Smuzhiyun *buf = NULL;
3187*4882a593Smuzhiyun }
3188*4882a593Smuzhiyun }
3189*4882a593Smuzhiyun
rtw_buf_update(u8 ** buf,u32 * buf_len,const u8 * src,u32 src_len)3190*4882a593Smuzhiyun void rtw_buf_update(u8 **buf, u32 *buf_len, const u8 *src, u32 src_len)
3191*4882a593Smuzhiyun {
3192*4882a593Smuzhiyun u32 ori_len = 0, dup_len = 0;
3193*4882a593Smuzhiyun u8 *ori = NULL;
3194*4882a593Smuzhiyun u8 *dup = NULL;
3195*4882a593Smuzhiyun
3196*4882a593Smuzhiyun if (!buf || !buf_len)
3197*4882a593Smuzhiyun return;
3198*4882a593Smuzhiyun
3199*4882a593Smuzhiyun if (!src || !src_len)
3200*4882a593Smuzhiyun goto keep_ori;
3201*4882a593Smuzhiyun
3202*4882a593Smuzhiyun /* duplicate src */
3203*4882a593Smuzhiyun dup = rtw_malloc(src_len);
3204*4882a593Smuzhiyun if (dup) {
3205*4882a593Smuzhiyun dup_len = src_len;
3206*4882a593Smuzhiyun _rtw_memcpy(dup, src, dup_len);
3207*4882a593Smuzhiyun }
3208*4882a593Smuzhiyun
3209*4882a593Smuzhiyun keep_ori:
3210*4882a593Smuzhiyun ori = *buf;
3211*4882a593Smuzhiyun ori_len = *buf_len;
3212*4882a593Smuzhiyun
3213*4882a593Smuzhiyun /* replace buf with dup */
3214*4882a593Smuzhiyun *buf_len = 0;
3215*4882a593Smuzhiyun *buf = dup;
3216*4882a593Smuzhiyun *buf_len = dup_len;
3217*4882a593Smuzhiyun
3218*4882a593Smuzhiyun /* free ori */
3219*4882a593Smuzhiyun if (ori && ori_len > 0)
3220*4882a593Smuzhiyun rtw_mfree(ori, ori_len);
3221*4882a593Smuzhiyun }
3222*4882a593Smuzhiyun
3223*4882a593Smuzhiyun
3224*4882a593Smuzhiyun /**
3225*4882a593Smuzhiyun * rtw_cbuf_full - test if cbuf is full
3226*4882a593Smuzhiyun * @cbuf: pointer of struct rtw_cbuf
3227*4882a593Smuzhiyun *
3228*4882a593Smuzhiyun * Returns: _TRUE if cbuf is full
3229*4882a593Smuzhiyun */
rtw_cbuf_full(struct rtw_cbuf * cbuf)3230*4882a593Smuzhiyun inline bool rtw_cbuf_full(struct rtw_cbuf *cbuf)
3231*4882a593Smuzhiyun {
3232*4882a593Smuzhiyun return (cbuf->write == cbuf->read - 1) ? _TRUE : _FALSE;
3233*4882a593Smuzhiyun }
3234*4882a593Smuzhiyun
3235*4882a593Smuzhiyun /**
3236*4882a593Smuzhiyun * rtw_cbuf_empty - test if cbuf is empty
3237*4882a593Smuzhiyun * @cbuf: pointer of struct rtw_cbuf
3238*4882a593Smuzhiyun *
3239*4882a593Smuzhiyun * Returns: _TRUE if cbuf is empty
3240*4882a593Smuzhiyun */
rtw_cbuf_empty(struct rtw_cbuf * cbuf)3241*4882a593Smuzhiyun inline bool rtw_cbuf_empty(struct rtw_cbuf *cbuf)
3242*4882a593Smuzhiyun {
3243*4882a593Smuzhiyun return (cbuf->write == cbuf->read) ? _TRUE : _FALSE;
3244*4882a593Smuzhiyun }
3245*4882a593Smuzhiyun
3246*4882a593Smuzhiyun /**
3247*4882a593Smuzhiyun * rtw_cbuf_push - push a pointer into cbuf
3248*4882a593Smuzhiyun * @cbuf: pointer of struct rtw_cbuf
3249*4882a593Smuzhiyun * @buf: pointer to push in
3250*4882a593Smuzhiyun *
3251*4882a593Smuzhiyun * Lock free operation, be careful of the use scheme
3252*4882a593Smuzhiyun * Returns: _TRUE push success
3253*4882a593Smuzhiyun */
rtw_cbuf_push(struct rtw_cbuf * cbuf,void * buf)3254*4882a593Smuzhiyun bool rtw_cbuf_push(struct rtw_cbuf *cbuf, void *buf)
3255*4882a593Smuzhiyun {
3256*4882a593Smuzhiyun if (rtw_cbuf_full(cbuf))
3257*4882a593Smuzhiyun return _FAIL;
3258*4882a593Smuzhiyun
3259*4882a593Smuzhiyun if (0)
3260*4882a593Smuzhiyun RTW_INFO("%s on %u\n", __func__, cbuf->write);
3261*4882a593Smuzhiyun cbuf->bufs[cbuf->write] = buf;
3262*4882a593Smuzhiyun cbuf->write = (cbuf->write + 1) % cbuf->size;
3263*4882a593Smuzhiyun
3264*4882a593Smuzhiyun return _SUCCESS;
3265*4882a593Smuzhiyun }
3266*4882a593Smuzhiyun
3267*4882a593Smuzhiyun /**
3268*4882a593Smuzhiyun * rtw_cbuf_pop - pop a pointer from cbuf
3269*4882a593Smuzhiyun * @cbuf: pointer of struct rtw_cbuf
3270*4882a593Smuzhiyun *
3271*4882a593Smuzhiyun * Lock free operation, be careful of the use scheme
3272*4882a593Smuzhiyun * Returns: pointer popped out
3273*4882a593Smuzhiyun */
rtw_cbuf_pop(struct rtw_cbuf * cbuf)3274*4882a593Smuzhiyun void *rtw_cbuf_pop(struct rtw_cbuf *cbuf)
3275*4882a593Smuzhiyun {
3276*4882a593Smuzhiyun void *buf;
3277*4882a593Smuzhiyun if (rtw_cbuf_empty(cbuf))
3278*4882a593Smuzhiyun return NULL;
3279*4882a593Smuzhiyun
3280*4882a593Smuzhiyun if (0)
3281*4882a593Smuzhiyun RTW_INFO("%s on %u\n", __func__, cbuf->read);
3282*4882a593Smuzhiyun buf = cbuf->bufs[cbuf->read];
3283*4882a593Smuzhiyun cbuf->read = (cbuf->read + 1) % cbuf->size;
3284*4882a593Smuzhiyun
3285*4882a593Smuzhiyun return buf;
3286*4882a593Smuzhiyun }
3287*4882a593Smuzhiyun
3288*4882a593Smuzhiyun /**
3289*4882a593Smuzhiyun * rtw_cbuf_alloc - allocte a rtw_cbuf with given size and do initialization
3290*4882a593Smuzhiyun * @size: size of pointer
3291*4882a593Smuzhiyun *
3292*4882a593Smuzhiyun * Returns: pointer of srtuct rtw_cbuf, NULL for allocation failure
3293*4882a593Smuzhiyun */
rtw_cbuf_alloc(u32 size)3294*4882a593Smuzhiyun struct rtw_cbuf *rtw_cbuf_alloc(u32 size)
3295*4882a593Smuzhiyun {
3296*4882a593Smuzhiyun struct rtw_cbuf *cbuf;
3297*4882a593Smuzhiyun
3298*4882a593Smuzhiyun cbuf = (struct rtw_cbuf *)rtw_malloc(sizeof(*cbuf) + sizeof(void *) * size);
3299*4882a593Smuzhiyun
3300*4882a593Smuzhiyun if (cbuf) {
3301*4882a593Smuzhiyun cbuf->write = cbuf->read = 0;
3302*4882a593Smuzhiyun cbuf->size = size;
3303*4882a593Smuzhiyun }
3304*4882a593Smuzhiyun
3305*4882a593Smuzhiyun return cbuf;
3306*4882a593Smuzhiyun }
3307*4882a593Smuzhiyun
3308*4882a593Smuzhiyun /**
3309*4882a593Smuzhiyun * rtw_cbuf_free - free the given rtw_cbuf
3310*4882a593Smuzhiyun * @cbuf: pointer of struct rtw_cbuf to free
3311*4882a593Smuzhiyun */
rtw_cbuf_free(struct rtw_cbuf * cbuf)3312*4882a593Smuzhiyun void rtw_cbuf_free(struct rtw_cbuf *cbuf)
3313*4882a593Smuzhiyun {
3314*4882a593Smuzhiyun rtw_mfree((u8 *)cbuf, sizeof(*cbuf) + sizeof(void *) * cbuf->size);
3315*4882a593Smuzhiyun }
3316*4882a593Smuzhiyun
3317*4882a593Smuzhiyun /**
3318*4882a593Smuzhiyun * map_readN - read a range of map data
3319*4882a593Smuzhiyun * @map: map to read
3320*4882a593Smuzhiyun * @offset: start address to read
3321*4882a593Smuzhiyun * @len: length to read
3322*4882a593Smuzhiyun * @buf: pointer of buffer to store data read
3323*4882a593Smuzhiyun *
3324*4882a593Smuzhiyun * Returns: _SUCCESS or _FAIL
3325*4882a593Smuzhiyun */
map_readN(const struct map_t * map,u16 offset,u16 len,u8 * buf)3326*4882a593Smuzhiyun int map_readN(const struct map_t *map, u16 offset, u16 len, u8 *buf)
3327*4882a593Smuzhiyun {
3328*4882a593Smuzhiyun const struct map_seg_t *seg;
3329*4882a593Smuzhiyun int ret = _FAIL;
3330*4882a593Smuzhiyun int i;
3331*4882a593Smuzhiyun
3332*4882a593Smuzhiyun if (len == 0) {
3333*4882a593Smuzhiyun rtw_warn_on(1);
3334*4882a593Smuzhiyun goto exit;
3335*4882a593Smuzhiyun }
3336*4882a593Smuzhiyun
3337*4882a593Smuzhiyun if (offset + len > map->len) {
3338*4882a593Smuzhiyun rtw_warn_on(1);
3339*4882a593Smuzhiyun goto exit;
3340*4882a593Smuzhiyun }
3341*4882a593Smuzhiyun
3342*4882a593Smuzhiyun _rtw_memset(buf, map->init_value, len);
3343*4882a593Smuzhiyun
3344*4882a593Smuzhiyun for (i = 0; i < map->seg_num; i++) {
3345*4882a593Smuzhiyun u8 *c_dst, *c_src;
3346*4882a593Smuzhiyun u16 c_len;
3347*4882a593Smuzhiyun
3348*4882a593Smuzhiyun seg = map->segs + i;
3349*4882a593Smuzhiyun if (seg->sa + seg->len <= offset || seg->sa >= offset + len)
3350*4882a593Smuzhiyun continue;
3351*4882a593Smuzhiyun
3352*4882a593Smuzhiyun if (seg->sa >= offset) {
3353*4882a593Smuzhiyun c_dst = buf + (seg->sa - offset);
3354*4882a593Smuzhiyun c_src = seg->c;
3355*4882a593Smuzhiyun if (seg->sa + seg->len <= offset + len)
3356*4882a593Smuzhiyun c_len = seg->len;
3357*4882a593Smuzhiyun else
3358*4882a593Smuzhiyun c_len = offset + len - seg->sa;
3359*4882a593Smuzhiyun } else {
3360*4882a593Smuzhiyun c_dst = buf;
3361*4882a593Smuzhiyun c_src = seg->c + (offset - seg->sa);
3362*4882a593Smuzhiyun if (seg->sa + seg->len >= offset + len)
3363*4882a593Smuzhiyun c_len = len;
3364*4882a593Smuzhiyun else
3365*4882a593Smuzhiyun c_len = seg->sa + seg->len - offset;
3366*4882a593Smuzhiyun }
3367*4882a593Smuzhiyun
3368*4882a593Smuzhiyun _rtw_memcpy(c_dst, c_src, c_len);
3369*4882a593Smuzhiyun }
3370*4882a593Smuzhiyun
3371*4882a593Smuzhiyun exit:
3372*4882a593Smuzhiyun return ret;
3373*4882a593Smuzhiyun }
3374*4882a593Smuzhiyun
3375*4882a593Smuzhiyun /**
3376*4882a593Smuzhiyun * map_read8 - read 1 byte of map data
3377*4882a593Smuzhiyun * @map: map to read
3378*4882a593Smuzhiyun * @offset: address to read
3379*4882a593Smuzhiyun *
3380*4882a593Smuzhiyun * Returns: value of data of specified offset. map.init_value if offset is out of range
3381*4882a593Smuzhiyun */
map_read8(const struct map_t * map,u16 offset)3382*4882a593Smuzhiyun u8 map_read8(const struct map_t *map, u16 offset)
3383*4882a593Smuzhiyun {
3384*4882a593Smuzhiyun const struct map_seg_t *seg;
3385*4882a593Smuzhiyun u8 val = map->init_value;
3386*4882a593Smuzhiyun int i;
3387*4882a593Smuzhiyun
3388*4882a593Smuzhiyun if (offset + 1 > map->len) {
3389*4882a593Smuzhiyun rtw_warn_on(1);
3390*4882a593Smuzhiyun goto exit;
3391*4882a593Smuzhiyun }
3392*4882a593Smuzhiyun
3393*4882a593Smuzhiyun for (i = 0; i < map->seg_num; i++) {
3394*4882a593Smuzhiyun seg = map->segs + i;
3395*4882a593Smuzhiyun if (seg->sa + seg->len <= offset || seg->sa >= offset + 1)
3396*4882a593Smuzhiyun continue;
3397*4882a593Smuzhiyun
3398*4882a593Smuzhiyun val = *(seg->c + offset - seg->sa);
3399*4882a593Smuzhiyun break;
3400*4882a593Smuzhiyun }
3401*4882a593Smuzhiyun
3402*4882a593Smuzhiyun exit:
3403*4882a593Smuzhiyun return val;
3404*4882a593Smuzhiyun }
3405*4882a593Smuzhiyun
3406*4882a593Smuzhiyun #ifdef CONFIG_RTW_MESH
rtw_blacklist_add(_queue * blist,const u8 * addr,u32 timeout_ms)3407*4882a593Smuzhiyun int rtw_blacklist_add(_queue *blist, const u8 *addr, u32 timeout_ms)
3408*4882a593Smuzhiyun {
3409*4882a593Smuzhiyun struct blacklist_ent *ent;
3410*4882a593Smuzhiyun _list *list, *head;
3411*4882a593Smuzhiyun u8 exist = _FALSE, timeout = _FALSE;
3412*4882a593Smuzhiyun
3413*4882a593Smuzhiyun enter_critical_bh(&blist->lock);
3414*4882a593Smuzhiyun
3415*4882a593Smuzhiyun head = &blist->queue;
3416*4882a593Smuzhiyun list = get_next(head);
3417*4882a593Smuzhiyun while (rtw_end_of_queue_search(head, list) == _FALSE) {
3418*4882a593Smuzhiyun ent = LIST_CONTAINOR(list, struct blacklist_ent, list);
3419*4882a593Smuzhiyun list = get_next(list);
3420*4882a593Smuzhiyun
3421*4882a593Smuzhiyun if (_rtw_memcmp(ent->addr, addr, ETH_ALEN) == _TRUE) {
3422*4882a593Smuzhiyun exist = _TRUE;
3423*4882a593Smuzhiyun if (rtw_time_after(rtw_get_current_time(), ent->exp_time))
3424*4882a593Smuzhiyun timeout = _TRUE;
3425*4882a593Smuzhiyun ent->exp_time = rtw_get_current_time()
3426*4882a593Smuzhiyun + rtw_ms_to_systime(timeout_ms);
3427*4882a593Smuzhiyun break;
3428*4882a593Smuzhiyun }
3429*4882a593Smuzhiyun
3430*4882a593Smuzhiyun if (rtw_time_after(rtw_get_current_time(), ent->exp_time)) {
3431*4882a593Smuzhiyun rtw_list_delete(&ent->list);
3432*4882a593Smuzhiyun rtw_mfree(ent, sizeof(struct blacklist_ent));
3433*4882a593Smuzhiyun }
3434*4882a593Smuzhiyun }
3435*4882a593Smuzhiyun
3436*4882a593Smuzhiyun if (exist == _FALSE) {
3437*4882a593Smuzhiyun ent = rtw_malloc(sizeof(struct blacklist_ent));
3438*4882a593Smuzhiyun if (ent) {
3439*4882a593Smuzhiyun _rtw_memcpy(ent->addr, addr, ETH_ALEN);
3440*4882a593Smuzhiyun ent->exp_time = rtw_get_current_time()
3441*4882a593Smuzhiyun + rtw_ms_to_systime(timeout_ms);
3442*4882a593Smuzhiyun rtw_list_insert_tail(&ent->list, head);
3443*4882a593Smuzhiyun }
3444*4882a593Smuzhiyun }
3445*4882a593Smuzhiyun
3446*4882a593Smuzhiyun exit_critical_bh(&blist->lock);
3447*4882a593Smuzhiyun
3448*4882a593Smuzhiyun return (exist == _TRUE && timeout == _FALSE) ? RTW_ALREADY : (ent ? _SUCCESS : _FAIL);
3449*4882a593Smuzhiyun }
3450*4882a593Smuzhiyun
rtw_blacklist_del(_queue * blist,const u8 * addr)3451*4882a593Smuzhiyun int rtw_blacklist_del(_queue *blist, const u8 *addr)
3452*4882a593Smuzhiyun {
3453*4882a593Smuzhiyun struct blacklist_ent *ent = NULL;
3454*4882a593Smuzhiyun _list *list, *head;
3455*4882a593Smuzhiyun u8 exist = _FALSE;
3456*4882a593Smuzhiyun
3457*4882a593Smuzhiyun enter_critical_bh(&blist->lock);
3458*4882a593Smuzhiyun head = &blist->queue;
3459*4882a593Smuzhiyun list = get_next(head);
3460*4882a593Smuzhiyun while (rtw_end_of_queue_search(head, list) == _FALSE) {
3461*4882a593Smuzhiyun ent = LIST_CONTAINOR(list, struct blacklist_ent, list);
3462*4882a593Smuzhiyun list = get_next(list);
3463*4882a593Smuzhiyun
3464*4882a593Smuzhiyun if (_rtw_memcmp(ent->addr, addr, ETH_ALEN) == _TRUE) {
3465*4882a593Smuzhiyun rtw_list_delete(&ent->list);
3466*4882a593Smuzhiyun rtw_mfree(ent, sizeof(struct blacklist_ent));
3467*4882a593Smuzhiyun exist = _TRUE;
3468*4882a593Smuzhiyun break;
3469*4882a593Smuzhiyun }
3470*4882a593Smuzhiyun
3471*4882a593Smuzhiyun if (rtw_time_after(rtw_get_current_time(), ent->exp_time)) {
3472*4882a593Smuzhiyun rtw_list_delete(&ent->list);
3473*4882a593Smuzhiyun rtw_mfree(ent, sizeof(struct blacklist_ent));
3474*4882a593Smuzhiyun }
3475*4882a593Smuzhiyun }
3476*4882a593Smuzhiyun
3477*4882a593Smuzhiyun exit_critical_bh(&blist->lock);
3478*4882a593Smuzhiyun
3479*4882a593Smuzhiyun return exist == _TRUE ? _SUCCESS : RTW_ALREADY;
3480*4882a593Smuzhiyun }
3481*4882a593Smuzhiyun
rtw_blacklist_search(_queue * blist,const u8 * addr)3482*4882a593Smuzhiyun int rtw_blacklist_search(_queue *blist, const u8 *addr)
3483*4882a593Smuzhiyun {
3484*4882a593Smuzhiyun struct blacklist_ent *ent = NULL;
3485*4882a593Smuzhiyun _list *list, *head;
3486*4882a593Smuzhiyun u8 exist = _FALSE;
3487*4882a593Smuzhiyun
3488*4882a593Smuzhiyun enter_critical_bh(&blist->lock);
3489*4882a593Smuzhiyun head = &blist->queue;
3490*4882a593Smuzhiyun list = get_next(head);
3491*4882a593Smuzhiyun while (rtw_end_of_queue_search(head, list) == _FALSE) {
3492*4882a593Smuzhiyun ent = LIST_CONTAINOR(list, struct blacklist_ent, list);
3493*4882a593Smuzhiyun list = get_next(list);
3494*4882a593Smuzhiyun
3495*4882a593Smuzhiyun if (_rtw_memcmp(ent->addr, addr, ETH_ALEN) == _TRUE) {
3496*4882a593Smuzhiyun if (rtw_time_after(rtw_get_current_time(), ent->exp_time)) {
3497*4882a593Smuzhiyun rtw_list_delete(&ent->list);
3498*4882a593Smuzhiyun rtw_mfree(ent, sizeof(struct blacklist_ent));
3499*4882a593Smuzhiyun } else
3500*4882a593Smuzhiyun exist = _TRUE;
3501*4882a593Smuzhiyun break;
3502*4882a593Smuzhiyun }
3503*4882a593Smuzhiyun
3504*4882a593Smuzhiyun if (rtw_time_after(rtw_get_current_time(), ent->exp_time)) {
3505*4882a593Smuzhiyun rtw_list_delete(&ent->list);
3506*4882a593Smuzhiyun rtw_mfree(ent, sizeof(struct blacklist_ent));
3507*4882a593Smuzhiyun }
3508*4882a593Smuzhiyun }
3509*4882a593Smuzhiyun
3510*4882a593Smuzhiyun exit_critical_bh(&blist->lock);
3511*4882a593Smuzhiyun
3512*4882a593Smuzhiyun return exist;
3513*4882a593Smuzhiyun }
3514*4882a593Smuzhiyun
rtw_blacklist_flush(_queue * blist)3515*4882a593Smuzhiyun void rtw_blacklist_flush(_queue *blist)
3516*4882a593Smuzhiyun {
3517*4882a593Smuzhiyun struct blacklist_ent *ent;
3518*4882a593Smuzhiyun _list *list, *head;
3519*4882a593Smuzhiyun _list tmp;
3520*4882a593Smuzhiyun
3521*4882a593Smuzhiyun _rtw_init_listhead(&tmp);
3522*4882a593Smuzhiyun
3523*4882a593Smuzhiyun enter_critical_bh(&blist->lock);
3524*4882a593Smuzhiyun rtw_list_splice_init(&blist->queue, &tmp);
3525*4882a593Smuzhiyun exit_critical_bh(&blist->lock);
3526*4882a593Smuzhiyun
3527*4882a593Smuzhiyun head = &tmp;
3528*4882a593Smuzhiyun list = get_next(head);
3529*4882a593Smuzhiyun while (rtw_end_of_queue_search(head, list) == _FALSE) {
3530*4882a593Smuzhiyun ent = LIST_CONTAINOR(list, struct blacklist_ent, list);
3531*4882a593Smuzhiyun list = get_next(list);
3532*4882a593Smuzhiyun rtw_list_delete(&ent->list);
3533*4882a593Smuzhiyun rtw_mfree(ent, sizeof(struct blacklist_ent));
3534*4882a593Smuzhiyun }
3535*4882a593Smuzhiyun }
3536*4882a593Smuzhiyun
dump_blacklist(void * sel,_queue * blist,const char * title)3537*4882a593Smuzhiyun void dump_blacklist(void *sel, _queue *blist, const char *title)
3538*4882a593Smuzhiyun {
3539*4882a593Smuzhiyun struct blacklist_ent *ent = NULL;
3540*4882a593Smuzhiyun _list *list, *head;
3541*4882a593Smuzhiyun
3542*4882a593Smuzhiyun enter_critical_bh(&blist->lock);
3543*4882a593Smuzhiyun head = &blist->queue;
3544*4882a593Smuzhiyun list = get_next(head);
3545*4882a593Smuzhiyun
3546*4882a593Smuzhiyun if (rtw_end_of_queue_search(head, list) == _FALSE) {
3547*4882a593Smuzhiyun if (title)
3548*4882a593Smuzhiyun RTW_PRINT_SEL(sel, "%s:\n", title);
3549*4882a593Smuzhiyun
3550*4882a593Smuzhiyun while (rtw_end_of_queue_search(head, list) == _FALSE) {
3551*4882a593Smuzhiyun ent = LIST_CONTAINOR(list, struct blacklist_ent, list);
3552*4882a593Smuzhiyun list = get_next(list);
3553*4882a593Smuzhiyun
3554*4882a593Smuzhiyun if (rtw_time_after(rtw_get_current_time(), ent->exp_time))
3555*4882a593Smuzhiyun RTW_PRINT_SEL(sel, MAC_FMT" expired\n", MAC_ARG(ent->addr));
3556*4882a593Smuzhiyun else
3557*4882a593Smuzhiyun RTW_PRINT_SEL(sel, MAC_FMT" %u\n", MAC_ARG(ent->addr)
3558*4882a593Smuzhiyun , rtw_get_remaining_time_ms(ent->exp_time));
3559*4882a593Smuzhiyun }
3560*4882a593Smuzhiyun
3561*4882a593Smuzhiyun }
3562*4882a593Smuzhiyun exit_critical_bh(&blist->lock);
3563*4882a593Smuzhiyun }
3564*4882a593Smuzhiyun #endif
3565*4882a593Smuzhiyun
3566*4882a593Smuzhiyun /**
3567*4882a593Smuzhiyun * is_null -
3568*4882a593Smuzhiyun *
3569*4882a593Smuzhiyun * Return TRUE if c is null character
3570*4882a593Smuzhiyun * FALSE otherwise.
3571*4882a593Smuzhiyun */
is_null(char c)3572*4882a593Smuzhiyun inline BOOLEAN is_null(char c)
3573*4882a593Smuzhiyun {
3574*4882a593Smuzhiyun if (c == '\0')
3575*4882a593Smuzhiyun return _TRUE;
3576*4882a593Smuzhiyun else
3577*4882a593Smuzhiyun return _FALSE;
3578*4882a593Smuzhiyun }
3579*4882a593Smuzhiyun
is_all_null(char * c,int len)3580*4882a593Smuzhiyun inline BOOLEAN is_all_null(char *c, int len)
3581*4882a593Smuzhiyun {
3582*4882a593Smuzhiyun for (; len > 0; len--)
3583*4882a593Smuzhiyun if (c[len - 1] != '\0')
3584*4882a593Smuzhiyun return _FALSE;
3585*4882a593Smuzhiyun
3586*4882a593Smuzhiyun return _TRUE;
3587*4882a593Smuzhiyun }
3588*4882a593Smuzhiyun
3589*4882a593Smuzhiyun /**
3590*4882a593Smuzhiyun * is_eol -
3591*4882a593Smuzhiyun *
3592*4882a593Smuzhiyun * Return TRUE if c is represent for EOL (end of line)
3593*4882a593Smuzhiyun * FALSE otherwise.
3594*4882a593Smuzhiyun */
is_eol(char c)3595*4882a593Smuzhiyun inline BOOLEAN is_eol(char c)
3596*4882a593Smuzhiyun {
3597*4882a593Smuzhiyun if (c == '\r' || c == '\n')
3598*4882a593Smuzhiyun return _TRUE;
3599*4882a593Smuzhiyun else
3600*4882a593Smuzhiyun return _FALSE;
3601*4882a593Smuzhiyun }
3602*4882a593Smuzhiyun
3603*4882a593Smuzhiyun /**
3604*4882a593Smuzhiyun * is_space -
3605*4882a593Smuzhiyun *
3606*4882a593Smuzhiyun * Return TRUE if c is represent for space
3607*4882a593Smuzhiyun * FALSE otherwise.
3608*4882a593Smuzhiyun */
is_space(char c)3609*4882a593Smuzhiyun inline BOOLEAN is_space(char c)
3610*4882a593Smuzhiyun {
3611*4882a593Smuzhiyun if (c == ' ' || c == '\t')
3612*4882a593Smuzhiyun return _TRUE;
3613*4882a593Smuzhiyun else
3614*4882a593Smuzhiyun return _FALSE;
3615*4882a593Smuzhiyun }
3616*4882a593Smuzhiyun
3617*4882a593Smuzhiyun /**
3618*4882a593Smuzhiyun * is_decimal -
3619*4882a593Smuzhiyun *
3620*4882a593Smuzhiyun * Return TRUE if chTmp is represent for decimal digit
3621*4882a593Smuzhiyun * FALSE otherwise.
3622*4882a593Smuzhiyun */
is_decimal(char chTmp)3623*4882a593Smuzhiyun inline BOOLEAN is_decimal(char chTmp)
3624*4882a593Smuzhiyun {
3625*4882a593Smuzhiyun if ((chTmp >= '0' && chTmp <= '9'))
3626*4882a593Smuzhiyun return _TRUE;
3627*4882a593Smuzhiyun else
3628*4882a593Smuzhiyun return _FALSE;
3629*4882a593Smuzhiyun }
3630*4882a593Smuzhiyun
3631*4882a593Smuzhiyun /**
3632*4882a593Smuzhiyun * IsHexDigit -
3633*4882a593Smuzhiyun *
3634*4882a593Smuzhiyun * Return TRUE if chTmp is represent for hex digit
3635*4882a593Smuzhiyun * FALSE otherwise.
3636*4882a593Smuzhiyun */
IsHexDigit(char chTmp)3637*4882a593Smuzhiyun inline BOOLEAN IsHexDigit(char chTmp)
3638*4882a593Smuzhiyun {
3639*4882a593Smuzhiyun if ((chTmp >= '0' && chTmp <= '9') ||
3640*4882a593Smuzhiyun (chTmp >= 'a' && chTmp <= 'f') ||
3641*4882a593Smuzhiyun (chTmp >= 'A' && chTmp <= 'F'))
3642*4882a593Smuzhiyun return _TRUE;
3643*4882a593Smuzhiyun else
3644*4882a593Smuzhiyun return _FALSE;
3645*4882a593Smuzhiyun }
3646*4882a593Smuzhiyun
3647*4882a593Smuzhiyun /**
3648*4882a593Smuzhiyun * is_alpha -
3649*4882a593Smuzhiyun *
3650*4882a593Smuzhiyun * Return TRUE if chTmp is represent for alphabet
3651*4882a593Smuzhiyun * FALSE otherwise.
3652*4882a593Smuzhiyun */
is_alpha(char chTmp)3653*4882a593Smuzhiyun inline BOOLEAN is_alpha(char chTmp)
3654*4882a593Smuzhiyun {
3655*4882a593Smuzhiyun if ((chTmp >= 'a' && chTmp <= 'z') ||
3656*4882a593Smuzhiyun (chTmp >= 'A' && chTmp <= 'Z'))
3657*4882a593Smuzhiyun return _TRUE;
3658*4882a593Smuzhiyun else
3659*4882a593Smuzhiyun return _FALSE;
3660*4882a593Smuzhiyun }
3661*4882a593Smuzhiyun
alpha_to_upper(char c)3662*4882a593Smuzhiyun inline char alpha_to_upper(char c)
3663*4882a593Smuzhiyun {
3664*4882a593Smuzhiyun if ((c >= 'a' && c <= 'z'))
3665*4882a593Smuzhiyun c = 'A' + (c - 'a');
3666*4882a593Smuzhiyun return c;
3667*4882a593Smuzhiyun }
3668*4882a593Smuzhiyun
hex2num_i(char c)3669*4882a593Smuzhiyun int hex2num_i(char c)
3670*4882a593Smuzhiyun {
3671*4882a593Smuzhiyun if (c >= '0' && c <= '9')
3672*4882a593Smuzhiyun return c - '0';
3673*4882a593Smuzhiyun if (c >= 'a' && c <= 'f')
3674*4882a593Smuzhiyun return c - 'a' + 10;
3675*4882a593Smuzhiyun if (c >= 'A' && c <= 'F')
3676*4882a593Smuzhiyun return c - 'A' + 10;
3677*4882a593Smuzhiyun return -1;
3678*4882a593Smuzhiyun }
3679*4882a593Smuzhiyun
hex2byte_i(const char * hex)3680*4882a593Smuzhiyun int hex2byte_i(const char *hex)
3681*4882a593Smuzhiyun {
3682*4882a593Smuzhiyun int a, b;
3683*4882a593Smuzhiyun a = hex2num_i(*hex++);
3684*4882a593Smuzhiyun if (a < 0)
3685*4882a593Smuzhiyun return -1;
3686*4882a593Smuzhiyun b = hex2num_i(*hex++);
3687*4882a593Smuzhiyun if (b < 0)
3688*4882a593Smuzhiyun return -1;
3689*4882a593Smuzhiyun return (a << 4) | b;
3690*4882a593Smuzhiyun }
3691*4882a593Smuzhiyun
hexstr2bin(const char * hex,u8 * buf,size_t len)3692*4882a593Smuzhiyun int hexstr2bin(const char *hex, u8 *buf, size_t len)
3693*4882a593Smuzhiyun {
3694*4882a593Smuzhiyun size_t i;
3695*4882a593Smuzhiyun int a;
3696*4882a593Smuzhiyun const char *ipos = hex;
3697*4882a593Smuzhiyun u8 *opos = buf;
3698*4882a593Smuzhiyun
3699*4882a593Smuzhiyun for (i = 0; i < len; i++) {
3700*4882a593Smuzhiyun a = hex2byte_i(ipos);
3701*4882a593Smuzhiyun if (a < 0)
3702*4882a593Smuzhiyun return -1;
3703*4882a593Smuzhiyun *opos++ = a;
3704*4882a593Smuzhiyun ipos += 2;
3705*4882a593Smuzhiyun }
3706*4882a593Smuzhiyun return 0;
3707*4882a593Smuzhiyun }
3708*4882a593Smuzhiyun
3709*4882a593Smuzhiyun /**
3710*4882a593Smuzhiyun * hwaddr_aton - Convert ASCII string to MAC address
3711*4882a593Smuzhiyun * @txt: MAC address as a string (e.g., "00:11:22:33:44:55")
3712*4882a593Smuzhiyun * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
3713*4882a593Smuzhiyun * Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
3714*4882a593Smuzhiyun */
hwaddr_aton_i(const char * txt,u8 * addr)3715*4882a593Smuzhiyun int hwaddr_aton_i(const char *txt, u8 *addr)
3716*4882a593Smuzhiyun {
3717*4882a593Smuzhiyun int i;
3718*4882a593Smuzhiyun
3719*4882a593Smuzhiyun for (i = 0; i < 6; i++) {
3720*4882a593Smuzhiyun int a, b;
3721*4882a593Smuzhiyun
3722*4882a593Smuzhiyun a = hex2num_i(*txt++);
3723*4882a593Smuzhiyun if (a < 0)
3724*4882a593Smuzhiyun return -1;
3725*4882a593Smuzhiyun b = hex2num_i(*txt++);
3726*4882a593Smuzhiyun if (b < 0)
3727*4882a593Smuzhiyun return -1;
3728*4882a593Smuzhiyun *addr++ = (a << 4) | b;
3729*4882a593Smuzhiyun if (i < 5 && *txt++ != ':')
3730*4882a593Smuzhiyun return -1;
3731*4882a593Smuzhiyun }
3732*4882a593Smuzhiyun
3733*4882a593Smuzhiyun return 0;
3734*4882a593Smuzhiyun }
3735*4882a593Smuzhiyun
3736