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