]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - drivers/staging/rtl8723bs/os_dep/osdep_service.c
MAINTAINERS: Update MAX77802 PMIC entry
[mirror_ubuntu-artful-kernel.git] / drivers / staging / rtl8723bs / os_dep / osdep_service.c
1 /******************************************************************************
2 *
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 ******************************************************************************/
15
16
17 #define _OSDEP_SERVICE_C_
18
19 #include <drv_types.h>
20 #include <rtw_debug.h>
21
22 /*
23 * Translate the OS dependent @param error_code to OS independent RTW_STATUS_CODE
24 * @return: one of RTW_STATUS_CODE
25 */
26 inline int RTW_STATUS_CODE(int error_code)
27 {
28 if (error_code >= 0)
29 return _SUCCESS;
30 return _FAIL;
31 }
32
33 u8 *_rtw_malloc(u32 sz)
34 {
35 u8 *pbuf = NULL;
36
37 pbuf = kmalloc(sz, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
38
39 return pbuf;
40 }
41
42 u8 *_rtw_zmalloc(u32 sz)
43 {
44 u8 *pbuf = _rtw_malloc(sz);
45
46 if (pbuf != NULL) {
47 memset(pbuf, 0, sz);
48 }
49
50 return pbuf;
51 }
52
53 inline struct sk_buff *_rtw_skb_alloc(u32 sz)
54 {
55 return __dev_alloc_skb(sz, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
56 }
57
58 inline struct sk_buff *_rtw_skb_copy(const struct sk_buff *skb)
59 {
60 return skb_copy(skb, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
61 }
62
63 inline struct sk_buff *_rtw_skb_clone(struct sk_buff *skb)
64 {
65 return skb_clone(skb, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
66 }
67
68 inline int _rtw_netif_rx(_nic_hdl ndev, struct sk_buff *skb)
69 {
70 skb->dev = ndev;
71 return netif_rx(skb);
72 }
73
74 void rtw_init_timer(_timer *ptimer, void *padapter, void *pfunc)
75 {
76 struct adapter *adapter = (struct adapter *)padapter;
77
78 _init_timer(ptimer, adapter->pnetdev, pfunc, adapter);
79 }
80
81 void _rtw_init_queue(struct __queue *pqueue)
82 {
83 INIT_LIST_HEAD(&(pqueue->queue));
84
85 spin_lock_init(&(pqueue->lock));
86 }
87
88 /*
89 * Open a file with the specific @param path, @param flag, @param mode
90 * @param fpp the pointer of struct file pointer to get struct file pointer while file opening is success
91 * @param path the path of the file to open
92 * @param flag file operation flags, please refer to linux document
93 * @param mode please refer to linux document
94 * @return Linux specific error code
95 */
96 static int openFile(struct file **fpp, char *path, int flag, int mode)
97 {
98 struct file *fp;
99
100 fp =filp_open(path, flag, mode);
101 if (IS_ERR(fp)) {
102 *fpp = NULL;
103 return PTR_ERR(fp);
104 }
105 else {
106 *fpp =fp;
107 return 0;
108 }
109 }
110
111 /*
112 * Close the file with the specific @param fp
113 * @param fp the pointer of struct file to close
114 * @return always 0
115 */
116 static int closeFile(struct file *fp)
117 {
118 filp_close(fp, NULL);
119 return 0;
120 }
121
122 static int readFile(struct file *fp, char *buf, int len)
123 {
124 int rlen = 0, sum = 0;
125
126 if (!fp->f_op || !fp->f_op->read)
127 return -EPERM;
128
129 while (sum<len) {
130 rlen =fp->f_op->read(fp, (char __force __user *)buf+sum, len-sum, &fp->f_pos);
131 if (rlen>0)
132 sum+=rlen;
133 else if (0 != rlen)
134 return rlen;
135 else
136 break;
137 }
138
139 return sum;
140
141 }
142
143 /*
144 * Test if the specifi @param path is a file and readable
145 * @param path the path of the file to test
146 * @return Linux specific error code
147 */
148 static int isFileReadable(char *path)
149 {
150 struct file *fp;
151 int ret = 0;
152 mm_segment_t oldfs;
153 char buf;
154
155 fp =filp_open(path, O_RDONLY, 0);
156 if (IS_ERR(fp)) {
157 ret = PTR_ERR(fp);
158 }
159 else {
160 oldfs = get_fs(); set_fs(get_ds());
161
162 if (1!=readFile(fp, &buf, 1))
163 ret = PTR_ERR(fp);
164
165 set_fs(oldfs);
166 filp_close(fp, NULL);
167 }
168 return ret;
169 }
170
171 /*
172 * Open the file with @param path and retrive the file content into memory starting from @param buf for @param sz at most
173 * @param path the path of the file to open and read
174 * @param buf the starting address of the buffer to store file content
175 * @param sz how many bytes to read at most
176 * @return the byte we've read, or Linux specific error code
177 */
178 static int retriveFromFile(char *path, u8 *buf, u32 sz)
179 {
180 int ret =-1;
181 mm_segment_t oldfs;
182 struct file *fp;
183
184 if (path && buf) {
185 if (0 == (ret =openFile(&fp, path, O_RDONLY, 0))) {
186 DBG_871X("%s openFile path:%s fp =%p\n", __func__, path , fp);
187
188 oldfs = get_fs(); set_fs(get_ds());
189 ret =readFile(fp, buf, sz);
190 set_fs(oldfs);
191 closeFile(fp);
192
193 DBG_871X("%s readFile, ret:%d\n", __func__, ret);
194
195 } else {
196 DBG_871X("%s openFile path:%s Fail, ret:%d\n", __func__, path, ret);
197 }
198 } else {
199 DBG_871X("%s NULL pointer\n", __func__);
200 ret = -EINVAL;
201 }
202 return ret;
203 }
204
205 /*
206 * Test if the specifi @param path is a file and readable
207 * @param path the path of the file to test
208 * @return true or false
209 */
210 int rtw_is_file_readable(char *path)
211 {
212 if (isFileReadable(path) == 0)
213 return true;
214 else
215 return false;
216 }
217
218 /*
219 * Open the file with @param path and retrive the file content into memory starting from @param buf for @param sz at most
220 * @param path the path of the file to open and read
221 * @param buf the starting address of the buffer to store file content
222 * @param sz how many bytes to read at most
223 * @return the byte we've read
224 */
225 int rtw_retrive_from_file(char *path, u8 *buf, u32 sz)
226 {
227 int ret =retriveFromFile(path, buf, sz);
228 return ret>= 0?ret:0;
229 }
230
231 struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv, void *old_priv)
232 {
233 struct net_device *pnetdev;
234 struct rtw_netdev_priv_indicator *pnpi;
235
236 pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
237 if (!pnetdev)
238 goto RETURN;
239
240 pnpi = netdev_priv(pnetdev);
241 pnpi->priv =old_priv;
242 pnpi->sizeof_priv =sizeof_priv;
243
244 RETURN:
245 return pnetdev;
246 }
247
248 struct net_device *rtw_alloc_etherdev(int sizeof_priv)
249 {
250 struct net_device *pnetdev;
251 struct rtw_netdev_priv_indicator *pnpi;
252
253 pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
254 if (!pnetdev)
255 goto RETURN;
256
257 pnpi = netdev_priv(pnetdev);
258
259 pnpi->priv = vzalloc(sizeof_priv);
260 if (!pnpi->priv) {
261 free_netdev(pnetdev);
262 pnetdev = NULL;
263 goto RETURN;
264 }
265
266 pnpi->sizeof_priv =sizeof_priv;
267 RETURN:
268 return pnetdev;
269 }
270
271 void rtw_free_netdev(struct net_device * netdev)
272 {
273 struct rtw_netdev_priv_indicator *pnpi;
274
275 if (!netdev)
276 goto RETURN;
277
278 pnpi = netdev_priv(netdev);
279
280 if (!pnpi->priv)
281 goto RETURN;
282
283 vfree(pnpi->priv);
284 free_netdev(netdev);
285
286 RETURN:
287 return;
288 }
289
290 int rtw_change_ifname(struct adapter *padapter, const char *ifname)
291 {
292 struct net_device *pnetdev;
293 struct net_device *cur_pnetdev;
294 struct rereg_nd_name_data *rereg_priv;
295 int ret;
296
297 if (!padapter)
298 goto error;
299
300 cur_pnetdev = padapter->pnetdev;
301 rereg_priv = &padapter->rereg_nd_name_priv;
302
303 /* free the old_pnetdev */
304 if (rereg_priv->old_pnetdev) {
305 free_netdev(rereg_priv->old_pnetdev);
306 rereg_priv->old_pnetdev = NULL;
307 }
308
309 if (!rtnl_is_locked())
310 unregister_netdev(cur_pnetdev);
311 else
312 unregister_netdevice(cur_pnetdev);
313
314 rereg_priv->old_pnetdev =cur_pnetdev;
315
316 pnetdev = rtw_init_netdev(padapter);
317 if (!pnetdev) {
318 ret = -1;
319 goto error;
320 }
321
322 SET_NETDEV_DEV(pnetdev, dvobj_to_dev(adapter_to_dvobj(padapter)));
323
324 rtw_init_netdev_name(pnetdev, ifname);
325
326 memcpy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr, ETH_ALEN);
327
328 if (!rtnl_is_locked())
329 ret = register_netdev(pnetdev);
330 else
331 ret = register_netdevice(pnetdev);
332
333 if (ret != 0) {
334 RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("register_netdev() failed\n"));
335 goto error;
336 }
337
338 return 0;
339
340 error:
341
342 return -1;
343
344 }
345
346 u64 rtw_modular64(u64 x, u64 y)
347 {
348 return do_div(x, y);
349 }
350
351 void rtw_buf_free(u8 **buf, u32 *buf_len)
352 {
353 u32 ori_len;
354
355 if (!buf || !buf_len)
356 return;
357
358 ori_len = *buf_len;
359
360 if (*buf) {
361 *buf_len = 0;
362 kfree(*buf);
363 *buf = NULL;
364 }
365 }
366
367 void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len)
368 {
369 u32 ori_len = 0, dup_len = 0;
370 u8 *ori = NULL;
371 u8 *dup = NULL;
372
373 if (!buf || !buf_len)
374 return;
375
376 if (!src || !src_len)
377 goto keep_ori;
378
379 /* duplicate src */
380 dup = rtw_malloc(src_len);
381 if (dup) {
382 dup_len = src_len;
383 memcpy(dup, src, dup_len);
384 }
385
386 keep_ori:
387 ori = *buf;
388 ori_len = *buf_len;
389
390 /* replace buf with dup */
391 *buf_len = 0;
392 *buf = dup;
393 *buf_len = dup_len;
394
395 /* free ori */
396 if (ori && ori_len > 0)
397 kfree(ori);
398 }
399
400
401 /**
402 * rtw_cbuf_full - test if cbuf is full
403 * @cbuf: pointer of struct rtw_cbuf
404 *
405 * Returns: true if cbuf is full
406 */
407 inline bool rtw_cbuf_full(struct rtw_cbuf *cbuf)
408 {
409 return (cbuf->write == cbuf->read-1)? true : false;
410 }
411
412 /**
413 * rtw_cbuf_empty - test if cbuf is empty
414 * @cbuf: pointer of struct rtw_cbuf
415 *
416 * Returns: true if cbuf is empty
417 */
418 inline bool rtw_cbuf_empty(struct rtw_cbuf *cbuf)
419 {
420 return (cbuf->write == cbuf->read)? true : false;
421 }
422
423 /**
424 * rtw_cbuf_push - push a pointer into cbuf
425 * @cbuf: pointer of struct rtw_cbuf
426 * @buf: pointer to push in
427 *
428 * Lock free operation, be careful of the use scheme
429 * Returns: true push success
430 */
431 bool rtw_cbuf_push(struct rtw_cbuf *cbuf, void *buf)
432 {
433 if (rtw_cbuf_full(cbuf))
434 return _FAIL;
435
436 DBG_871X("%s on %u\n", __func__, cbuf->write);
437 cbuf->bufs[cbuf->write] = buf;
438 cbuf->write = (cbuf->write+1)%cbuf->size;
439
440 return _SUCCESS;
441 }
442
443 /**
444 * rtw_cbuf_pop - pop a pointer from cbuf
445 * @cbuf: pointer of struct rtw_cbuf
446 *
447 * Lock free operation, be careful of the use scheme
448 * Returns: pointer popped out
449 */
450 void *rtw_cbuf_pop(struct rtw_cbuf *cbuf)
451 {
452 void *buf;
453 if (rtw_cbuf_empty(cbuf))
454 return NULL;
455
456 DBG_871X("%s on %u\n", __func__, cbuf->read);
457 buf = cbuf->bufs[cbuf->read];
458 cbuf->read = (cbuf->read+1)%cbuf->size;
459
460 return buf;
461 }
462
463 /**
464 * rtw_cbuf_alloc - allocte a rtw_cbuf with given size and do initialization
465 * @size: size of pointer
466 *
467 * Returns: pointer of srtuct rtw_cbuf, NULL for allocation failure
468 */
469 struct rtw_cbuf *rtw_cbuf_alloc(u32 size)
470 {
471 struct rtw_cbuf *cbuf;
472
473 cbuf = (struct rtw_cbuf *)rtw_malloc(sizeof(*cbuf) + sizeof(void*)*size);
474
475 if (cbuf) {
476 cbuf->write = cbuf->read = 0;
477 cbuf->size = size;
478 }
479
480 return cbuf;
481 }