1 /******************************************************************************
2 *
3 * Copyright(c) 2019 Realtek Corporation.
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 #define _OSDEP_SERVICE_LINUX_C_
16 #include <drv_types.h>
17
18 #ifdef DBG_MEMORY_LEAK
19 ATOMIC_T _malloc_cnt = ATOMIC_INIT(0);
20 ATOMIC_T _malloc_size = ATOMIC_INIT(0);
21 #endif /* DBG_MEMORY_LEAK */
22
23 /*
24 * Translate the OS dependent @param error_code to OS independent RTW_STATUS_CODE
25 * @return: one of RTW_STATUS_CODE
26 */
RTW_STATUS_CODE(int error_code)27 inline int RTW_STATUS_CODE(int error_code)
28 {
29 if (error_code >= 0)
30 return _SUCCESS;
31
32 switch (error_code) {
33 /* case -ETIMEDOUT: */
34 /* return RTW_STATUS_TIMEDOUT; */
35 default:
36 return _FAIL;
37 }
38 }
39
_rtw_skb_queue_purge(struct sk_buff_head * list)40 void _rtw_skb_queue_purge(struct sk_buff_head *list)
41 {
42 struct sk_buff *skb;
43
44 while ((skb = skb_dequeue(list)) != NULL)
45 _rtw_skb_free(skb);
46 }
47
_rtw_memcpy(void * dst,const void * src,u32 sz)48 void _rtw_memcpy(void *dst, const void *src, u32 sz)
49 {
50 memcpy(dst, src, sz);
51 }
52
_rtw_memmove(void * dst,const void * src,u32 sz)53 inline void _rtw_memmove(void *dst, const void *src, u32 sz)
54 {
55 memmove(dst, src, sz);
56 }
57
_rtw_memcmp(const void * dst,const void * src,u32 sz)58 int _rtw_memcmp(const void *dst, const void *src, u32 sz)
59 {
60 /* under Linux/GNU/GLibc, the return value of memcmp for two same mem. chunk is 0 */
61 if (!(memcmp(dst, src, sz)))
62 return _TRUE;
63 else
64 return _FALSE;
65 }
66
_rtw_memset(void * pbuf,int c,u32 sz)67 void _rtw_memset(void *pbuf, int c, u32 sz)
68 {
69 memset(pbuf, c, sz);
70 }
71
_rtw_init_listhead(_list * list)72 void _rtw_init_listhead(_list *list)
73 {
74 INIT_LIST_HEAD(list);
75 }
76 /*
77 For the following list_xxx operations,
78 caller must guarantee the atomic context.
79 Otherwise, there will be racing condition.
80 */
rtw_is_list_empty(_list * phead)81 u32 rtw_is_list_empty(_list *phead)
82 {
83 if (list_empty(phead))
84 return _TRUE;
85 else
86 return _FALSE;
87 }
88
rtw_list_insert_head(_list * plist,_list * phead)89 void rtw_list_insert_head(_list *plist, _list *phead)
90 {
91 list_add(plist, phead);
92 }
93
rtw_list_insert_tail(_list * plist,_list * phead)94 void rtw_list_insert_tail(_list *plist, _list *phead)
95 {
96 list_add_tail(plist, phead);
97 }
98
rtw_list_splice(_list * list,_list * head)99 inline void rtw_list_splice(_list *list, _list *head)
100 {
101 list_splice(list, head);
102 }
103
rtw_list_splice_init(_list * list,_list * head)104 inline void rtw_list_splice_init(_list *list, _list *head)
105 {
106 list_splice_init(list, head);
107 }
108
rtw_list_splice_tail(_list * list,_list * head)109 inline void rtw_list_splice_tail(_list *list, _list *head)
110 {
111 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27))
112 if (!list_empty(list))
113 __list_splice(list, head);
114 #else
115 list_splice_tail(list, head);
116 #endif
117 }
118
rtw_hlist_head_init(rtw_hlist_head * h)119 inline void rtw_hlist_head_init(rtw_hlist_head *h)
120 {
121 INIT_HLIST_HEAD(h);
122 }
123
rtw_hlist_add_head(rtw_hlist_node * n,rtw_hlist_head * h)124 inline void rtw_hlist_add_head(rtw_hlist_node *n, rtw_hlist_head *h)
125 {
126 hlist_add_head(n, h);
127 }
128
rtw_hlist_del(rtw_hlist_node * n)129 inline void rtw_hlist_del(rtw_hlist_node *n)
130 {
131 hlist_del(n);
132 }
133
rtw_hlist_add_head_rcu(rtw_hlist_node * n,rtw_hlist_head * h)134 inline void rtw_hlist_add_head_rcu(rtw_hlist_node *n, rtw_hlist_head *h)
135 {
136 hlist_add_head_rcu(n, h);
137 }
138
rtw_hlist_del_rcu(rtw_hlist_node * n)139 inline void rtw_hlist_del_rcu(rtw_hlist_node *n)
140 {
141 hlist_del_rcu(n);
142 }
143
rtw_init_timer(_timer * ptimer,void * pfunc,void * ctx)144 void rtw_init_timer(_timer *ptimer, void *pfunc, void *ctx)
145 {
146 _init_timer(ptimer, pfunc, ctx);
147 }
148
_rtw_get_current_time(void)149 systime _rtw_get_current_time(void)
150 {
151 return jiffies;
152 }
153
_rtw_systime_to_ms(systime stime)154 inline u32 _rtw_systime_to_ms(systime stime)
155 {
156 return jiffies_to_msecs(stime);
157 }
158
_rtw_systime_to_us(systime stime)159 inline u32 _rtw_systime_to_us(systime stime)
160 {
161 return jiffies_to_usecs(stime);
162 }
163
_rtw_ms_to_systime(u32 ms)164 inline systime _rtw_ms_to_systime(u32 ms)
165 {
166 return msecs_to_jiffies(ms);
167 }
168
_rtw_us_to_systime(u32 us)169 inline systime _rtw_us_to_systime(u32 us)
170 {
171 return usecs_to_jiffies(us);
172 }
173
_rtw_time_after(systime a,systime b)174 inline bool _rtw_time_after(systime a, systime b)
175 {
176 return time_after(a, b);
177 }
178
rtw_sleep_schedulable(int ms)179 void rtw_sleep_schedulable(int ms)
180 {
181 u32 delta;
182
183 delta = (ms * HZ) / 1000; /* (ms) */
184 if (delta == 0) {
185 delta = 1;/* 1 ms */
186 }
187 set_current_state(TASK_INTERRUPTIBLE);
188 schedule_timeout(delta);
189 return;
190 }
191
rtw_msleep_os(int ms)192 void rtw_msleep_os(int ms)
193 {
194 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36))
195 if (ms < 20) {
196 unsigned long us = ms * 1000UL;
197 usleep_range(us, us + 1000UL);
198 } else
199 #endif
200 msleep((unsigned int)ms);
201
202 }
rtw_usleep_os(int us)203 void rtw_usleep_os(int us)
204 {
205 /* msleep((unsigned int)us); */
206 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36))
207 usleep_range(us, us + 1);
208 #else
209 if (1 < (us / 1000))
210 msleep(1);
211 else
212 msleep((us / 1000) + 1);
213 #endif
214 }
215
216
217 #ifdef DBG_DELAY_OS
_rtw_mdelay_os(int ms,const char * func,const int line)218 void _rtw_mdelay_os(int ms, const char *func, const int line)
219 {
220 RTW_INFO("%s:%d %s(%d)\n", func, line, __FUNCTION__, ms);
221 mdelay((unsigned long)ms);
222 }
_rtw_udelay_os(int us,const char * func,const int line)223 void _rtw_udelay_os(int us, const char *func, const int line)
224 {
225 RTW_INFO("%s:%d %s(%d)\n", func, line, __FUNCTION__, us);
226 udelay((unsigned long)us);
227 }
228 #else
rtw_mdelay_os(int ms)229 void rtw_mdelay_os(int ms)
230 {
231 mdelay((unsigned long)ms);
232 }
rtw_udelay_os(int us)233 void rtw_udelay_os(int us)
234 {
235 udelay((unsigned long)us);
236 }
237 #endif
238
rtw_yield_os(void)239 void rtw_yield_os(void)
240 {
241 yield();
242 }
243
244
245 #define RTW_SUSPEND_LOCK_NAME "rtw_wifi"
246 #define RTW_SUSPEND_TRAFFIC_LOCK_NAME "rtw_wifi_traffic"
247 #define RTW_SUSPEND_RESUME_LOCK_NAME "rtw_wifi_resume"
248
249 #ifdef CONFIG_WAKELOCK
250 static struct wake_lock rtw_suspend_lock;
251 static struct wake_lock rtw_suspend_traffic_lock;
252 static struct wake_lock rtw_suspend_resume_lock;
253 #elif defined(CONFIG_ANDROID_POWER)
254 static android_suspend_lock_t rtw_suspend_lock = {
255 .name = RTW_SUSPEND_LOCK_NAME
256 };
257 static android_suspend_lock_t rtw_suspend_traffic_lock = {
258 .name = RTW_SUSPEND_TRAFFIC_LOCK_NAME
259 };
260 static android_suspend_lock_t rtw_suspend_resume_lock = {
261 .name = RTW_SUSPEND_RESUME_LOCK_NAME
262 };
263 #endif
264
rtw_suspend_lock_init(void)265 inline void rtw_suspend_lock_init(void)
266 {
267 #ifdef CONFIG_WAKELOCK
268 wake_lock_init(&rtw_suspend_lock, WAKE_LOCK_SUSPEND, RTW_SUSPEND_LOCK_NAME);
269 wake_lock_init(&rtw_suspend_traffic_lock, WAKE_LOCK_SUSPEND, RTW_SUSPEND_TRAFFIC_LOCK_NAME);
270 wake_lock_init(&rtw_suspend_resume_lock, WAKE_LOCK_SUSPEND, RTW_SUSPEND_RESUME_LOCK_NAME);
271 #elif defined(CONFIG_ANDROID_POWER)
272 android_init_suspend_lock(&rtw_suspend_lock);
273 android_init_suspend_lock(&rtw_suspend_traffic_lock);
274 android_init_suspend_lock(&rtw_suspend_resume_lock);
275 #endif
276 }
277
rtw_suspend_lock_uninit(void)278 inline void rtw_suspend_lock_uninit(void)
279 {
280 #ifdef CONFIG_WAKELOCK
281 wake_lock_destroy(&rtw_suspend_lock);
282 wake_lock_destroy(&rtw_suspend_traffic_lock);
283 wake_lock_destroy(&rtw_suspend_resume_lock);
284 #elif defined(CONFIG_ANDROID_POWER)
285 android_uninit_suspend_lock(&rtw_suspend_lock);
286 android_uninit_suspend_lock(&rtw_suspend_traffic_lock);
287 android_uninit_suspend_lock(&rtw_suspend_resume_lock);
288 #endif
289 }
290
rtw_lock_suspend(void)291 inline void rtw_lock_suspend(void)
292 {
293 #ifdef CONFIG_WAKELOCK
294 wake_lock(&rtw_suspend_lock);
295 #elif defined(CONFIG_ANDROID_POWER)
296 android_lock_suspend(&rtw_suspend_lock);
297 #endif
298
299 #if defined(CONFIG_WAKELOCK) || defined(CONFIG_ANDROID_POWER)
300 /* RTW_INFO("####%s: suspend_lock_count:%d####\n", __FUNCTION__, rtw_suspend_lock.stat.count); */
301 #endif
302 }
303
rtw_unlock_suspend(void)304 inline void rtw_unlock_suspend(void)
305 {
306 #ifdef CONFIG_WAKELOCK
307 wake_unlock(&rtw_suspend_lock);
308 #elif defined(CONFIG_ANDROID_POWER)
309 android_unlock_suspend(&rtw_suspend_lock);
310 #endif
311
312 #if defined(CONFIG_WAKELOCK) || defined(CONFIG_ANDROID_POWER)
313 /* RTW_INFO("####%s: suspend_lock_count:%d####\n", __FUNCTION__, rtw_suspend_lock.stat.count); */
314 #endif
315 }
316
rtw_resume_lock_suspend(void)317 inline void rtw_resume_lock_suspend(void)
318 {
319 #ifdef CONFIG_WAKELOCK
320 wake_lock(&rtw_suspend_resume_lock);
321 #elif defined(CONFIG_ANDROID_POWER)
322 android_lock_suspend(&rtw_suspend_resume_lock);
323 #endif
324
325 #if defined(CONFIG_WAKELOCK) || defined(CONFIG_ANDROID_POWER)
326 /* RTW_INFO("####%s: suspend_lock_count:%d####\n", __FUNCTION__, rtw_suspend_lock.stat.count); */
327 #endif
328 }
329
rtw_resume_unlock_suspend(void)330 inline void rtw_resume_unlock_suspend(void)
331 {
332 #ifdef CONFIG_WAKELOCK
333 wake_unlock(&rtw_suspend_resume_lock);
334 #elif defined(CONFIG_ANDROID_POWER)
335 android_unlock_suspend(&rtw_suspend_resume_lock);
336 #endif
337
338 #if defined(CONFIG_WAKELOCK) || defined(CONFIG_ANDROID_POWER)
339 /* RTW_INFO("####%s: suspend_lock_count:%d####\n", __FUNCTION__, rtw_suspend_lock.stat.count); */
340 #endif
341 }
342
rtw_lock_suspend_timeout(u32 timeout_ms)343 inline void rtw_lock_suspend_timeout(u32 timeout_ms)
344 {
345 #ifdef CONFIG_WAKELOCK
346 wake_lock_timeout(&rtw_suspend_lock, rtw_ms_to_systime(timeout_ms));
347 #elif defined(CONFIG_ANDROID_POWER)
348 android_lock_suspend_auto_expire(&rtw_suspend_lock, rtw_ms_to_systime(timeout_ms));
349 #endif
350 }
351
rtw_lock_traffic_suspend_timeout(u32 timeout_ms)352 inline void rtw_lock_traffic_suspend_timeout(u32 timeout_ms)
353 {
354 #ifdef CONFIG_WAKELOCK
355 wake_lock_timeout(&rtw_suspend_traffic_lock, rtw_ms_to_systime(timeout_ms));
356 #elif defined(CONFIG_ANDROID_POWER)
357 android_lock_suspend_auto_expire(&rtw_suspend_traffic_lock, rtw_ms_to_systime(timeout_ms));
358 #endif
359 /* RTW_INFO("traffic lock timeout:%d\n", timeout_ms); */
360 }
361
rtw_set_bit(int nr,unsigned long * addr)362 inline void rtw_set_bit(int nr, unsigned long *addr)
363 {
364 set_bit(nr, addr);
365 }
366
rtw_clear_bit(int nr,unsigned long * addr)367 inline void rtw_clear_bit(int nr, unsigned long *addr)
368 {
369 clear_bit(nr, addr);
370 }
371
rtw_test_and_clear_bit(int nr,unsigned long * addr)372 inline int rtw_test_and_clear_bit(int nr, unsigned long *addr)
373 {
374 return test_and_clear_bit(nr, addr);
375 }
rtw_test_and_set_bit(int nr,unsigned long * addr)376 inline int rtw_test_and_set_bit(int nr, unsigned long *addr)
377 {
378 return test_and_set_bit(nr, addr);
379 }
380 /*
381 * Open a file with the specific @param path, @param flag, @param mode
382 * @param fpp the pointer of struct file pointer to get struct file pointer while file opening is success
383 * @param path the path of the file to open
384 * @param flag file operation flags, please refer to linux document
385 * @param mode please refer to linux document
386 * @return Linux specific error code
387 */
openFile(struct file ** fpp,const char * path,int flag,int mode)388 static int openFile(struct file **fpp, const char *path, int flag, int mode)
389 {
390 struct file *fp;
391
392 fp = filp_open(path, flag, mode);
393 if (IS_ERR(fp)) {
394 *fpp = NULL;
395 return PTR_ERR(fp);
396 } else {
397 *fpp = fp;
398 return 0;
399 }
400 }
401
402 /*
403 * Close the file with the specific @param fp
404 * @param fp the pointer of struct file to close
405 * @return always 0
406 */
closeFile(struct file * fp)407 static int closeFile(struct file *fp)
408 {
409 filp_close(fp, NULL);
410 return 0;
411 }
412
readFile(struct file * fp,char * buf,int len)413 static int readFile(struct file *fp, char *buf, int len)
414 {
415 int rlen = 0, sum = 0;
416
417 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
418 if (!(fp->f_mode & FMODE_CAN_READ))
419 #else
420 if (!fp->f_op || !fp->f_op->read)
421 #endif
422 return -EPERM;
423
424 while (sum < len) {
425 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
426 rlen = kernel_read(fp, buf + sum, len - sum, &fp->f_pos);
427 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
428 rlen = __vfs_read(fp, buf + sum, len - sum, &fp->f_pos);
429 #else
430 rlen = fp->f_op->read(fp, buf + sum, len - sum, &fp->f_pos);
431 #endif
432 if (rlen > 0)
433 sum += rlen;
434 else if (0 != rlen)
435 return rlen;
436 else
437 break;
438 }
439
440 return sum;
441
442 }
443
444 #ifndef CONFIG_RTW_ANDROID
writeFile(struct file * fp,char * buf,int len)445 static int writeFile(struct file *fp, char *buf, int len)
446 {
447 int wlen = 0, sum = 0;
448
449 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
450 if (!(fp->f_mode & FMODE_CAN_WRITE))
451 #else
452 if (!fp->f_op || !fp->f_op->write)
453 #endif
454 return -EPERM;
455
456 while (sum < len) {
457 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
458 wlen = kernel_write(fp, buf + sum, len - sum, &fp->f_pos);
459 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
460 wlen = __vfs_write(fp, buf + sum, len - sum, &fp->f_pos);
461 #else
462 wlen = fp->f_op->write(fp, buf + sum, len - sum, &fp->f_pos);
463 #endif
464 if (wlen > 0)
465 sum += wlen;
466 else if (0 != wlen)
467 return wlen;
468 else
469 break;
470 }
471
472 return sum;
473
474 }
475
476 /*
477 * Test if the specifi @param pathname is a direct and readable
478 * If readable, @param sz is not used
479 * @param pathname the name of the path to test
480 * @return Linux specific error code
481 */
isDirReadable(const char * pathname,u32 * sz)482 static int isDirReadable(const char *pathname, u32 *sz)
483 {
484 struct path path;
485 int error = 0;
486
487 return kern_path(pathname, LOOKUP_FOLLOW, &path);
488 }
489 #endif /* CONFIG_RTW_ANDROID */
490
491 /*
492 * Test if the specifi @param path is a file and readable
493 * If readable, @param sz is got
494 * @param path the path of the file to test
495 * @return Linux specific error code
496 */
isFileReadable(const char * path,u32 * sz)497 static int isFileReadable(const char *path, u32 *sz)
498 {
499 struct file *fp;
500 int ret = 0;
501 #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0))
502 mm_segment_t oldfs;
503 #endif
504 char buf;
505
506 fp = filp_open(path, O_RDONLY, 0);
507 if (IS_ERR(fp))
508 ret = PTR_ERR(fp);
509 else {
510 #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0))
511 oldfs = get_fs();
512 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0))
513 set_fs(KERNEL_DS);
514 #else
515 set_fs(get_ds());
516 #endif
517 #endif
518
519 if (1 != readFile(fp, &buf, 1))
520 ret = PTR_ERR(fp);
521
522 if (ret == 0 && sz) {
523 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
524 *sz = i_size_read(fp->f_path.dentry->d_inode);
525 #else
526 *sz = i_size_read(fp->f_dentry->d_inode);
527 #endif
528 }
529
530 #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0))
531 set_fs(oldfs);
532 #endif
533 filp_close(fp, NULL);
534 }
535 return ret;
536 }
537
538 /*
539 * Open the file with @param path and retrive the file content into memory starting from @param buf for @param sz at most
540 * @param path the path of the file to open and read
541 * @param buf the starting address of the buffer to store file content
542 * @param sz how many bytes to read at most
543 * @return the byte we've read, or Linux specific error code
544 */
retriveFromFile(const char * path,u8 * buf,u32 sz)545 static int retriveFromFile(const char *path, u8 *buf, u32 sz)
546 {
547 int ret = -1;
548 #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0))
549 mm_segment_t oldfs;
550 #endif
551 struct file *fp;
552
553 if (path && buf) {
554 ret = openFile(&fp, path, O_RDONLY, 0);
555 if (0 == ret) {
556 RTW_INFO("%s openFile path:%s fp=%p\n", __FUNCTION__, path , fp);
557
558 #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0))
559 oldfs = get_fs();
560 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0))
561 set_fs(KERNEL_DS);
562 #else
563 set_fs(get_ds());
564 #endif
565 #endif
566
567 ret = readFile(fp, buf, sz);
568
569 #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0))
570 set_fs(oldfs);
571 #endif
572 closeFile(fp);
573
574 RTW_INFO("%s readFile, ret:%d\n", __FUNCTION__, ret);
575
576 } else
577 RTW_INFO("%s openFile path:%s Fail, ret:%d\n", __FUNCTION__, path, ret);
578 } else {
579 RTW_INFO("%s NULL pointer\n", __FUNCTION__);
580 ret = -EINVAL;
581 }
582 return ret;
583 }
584
585 #ifndef CONFIG_RTW_ANDROID
586 /*
587 * Open the file with @param path and wirte @param sz byte of data starting from @param buf into the file
588 * @param path the path of the file to open and write
589 * @param buf the starting address of the data to write into file
590 * @param sz how many bytes to write at most
591 * @return the byte we've written, or Linux specific error code
592 */
storeToFile(const char * path,u8 * buf,u32 sz)593 static int storeToFile(const char *path, u8 *buf, u32 sz)
594 {
595 int ret = 0;
596 #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0))
597 mm_segment_t oldfs;
598 #endif
599 struct file *fp;
600
601 if (path && buf) {
602 ret = openFile(&fp, path, O_CREAT | O_WRONLY, 0666);
603 if (0 == ret) {
604 RTW_INFO("%s openFile path:%s fp=%p\n", __FUNCTION__, path , fp);
605
606 #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0))
607 oldfs = get_fs();
608 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0))
609 set_fs(KERNEL_DS);
610 #else
611 set_fs(get_ds());
612 #endif
613 #endif
614
615 ret = writeFile(fp, buf, sz);
616
617 #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0))
618 set_fs(oldfs);
619 #endif
620 closeFile(fp);
621
622 RTW_INFO("%s writeFile, ret:%d\n", __FUNCTION__, ret);
623
624 } else
625 RTW_INFO("%s openFile path:%s Fail, ret:%d\n", __FUNCTION__, path, ret);
626 } else {
627 RTW_INFO("%s NULL pointer\n", __FUNCTION__);
628 ret = -EINVAL;
629 }
630 return ret;
631 }
632
633 /*
634 * Test if the specifi @param path is a direct and readable
635 * @param path the path of the direct to test
636 * @return _TRUE or _FALSE
637 */
rtw_is_dir_readable(const char * path)638 int rtw_is_dir_readable(const char *path)
639 {
640 if (isDirReadable(path, NULL) == 0)
641 return _TRUE;
642 else
643 return _FALSE;
644 }
645 #endif /* CONFIG_RTW_ANDROID */
646
647 /*
648 * Test if the specifi @param path is a file and readable
649 * @param path the path of the file to test
650 * @return _TRUE or _FALSE
651 */
rtw_is_file_readable(const char * path)652 int rtw_is_file_readable(const char *path)
653 {
654 if (isFileReadable(path, NULL) == 0)
655 return _TRUE;
656 else
657 return _FALSE;
658 }
659
660 /*
661 * Test if the specifi @param path is a file and readable.
662 * If readable, @param sz is got
663 * @param path the path of the file to test
664 * @return _TRUE or _FALSE
665 */
rtw_is_file_readable_with_size(const char * path,u32 * sz)666 int rtw_is_file_readable_with_size(const char *path, u32 *sz)
667 {
668 if (isFileReadable(path, sz) == 0)
669 return _TRUE;
670 else
671 return _FALSE;
672 }
673
674
675 /*
676 * Open the file with @param path and retrive the file content into memory starting from @param buf for @param sz at most
677 * @param path the path of the file to open and read
678 * @param buf the starting address of the buffer to store file content
679 * @param sz how many bytes to read at most
680 * @return the byte we've read
681 */
rtw_retrieve_from_file(const char * path,u8 * buf,u32 sz)682 int rtw_retrieve_from_file(const char *path, u8 *buf, u32 sz)
683 {
684 int ret = retriveFromFile(path, buf, sz);
685 return ret >= 0 ? ret : 0;
686 }
687
688 #ifndef CONFIG_RTW_ANDROID
689 /*
690 * Open the file with @param path and wirte @param sz byte of data starting from @param buf into the file
691 * @param path the path of the file to open and write
692 * @param buf the starting address of the data to write into file
693 * @param sz how many bytes to write at most
694 * @return the byte we've written
695 */
rtw_store_to_file(const char * path,u8 * buf,u32 sz)696 int rtw_store_to_file(const char *path, u8 *buf, u32 sz)
697 {
698 int ret = storeToFile(path, buf, sz);
699 return ret >= 0 ? ret : 0;
700 }
701 #endif /* CONFIG_RTW_ANDROID */
702
rtw_alloc_etherdev_with_old_priv(int sizeof_priv,void * old_priv)703 struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv, void *old_priv)
704 {
705 struct net_device *pnetdev;
706 struct rtw_netdev_priv_indicator *pnpi;
707
708 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
709 pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
710 #else
711 pnetdev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
712 #endif
713 if (!pnetdev)
714 goto RETURN;
715
716 pnpi = netdev_priv(pnetdev);
717 pnpi->priv = old_priv;
718 pnpi->sizeof_priv = sizeof_priv;
719
720 RETURN:
721 return pnetdev;
722 }
723
rtw_alloc_etherdev(int sizeof_priv)724 struct net_device *rtw_alloc_etherdev(int sizeof_priv)
725 {
726 struct net_device *pnetdev;
727 struct rtw_netdev_priv_indicator *pnpi;
728
729 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
730 pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
731 #else
732 pnetdev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
733 #endif
734 if (!pnetdev)
735 goto RETURN;
736
737 pnpi = netdev_priv(pnetdev);
738
739 pnpi->priv = rtw_zvmalloc(sizeof_priv);
740 if (!pnpi->priv) {
741 free_netdev(pnetdev);
742 pnetdev = NULL;
743 goto RETURN;
744 }
745
746 pnpi->sizeof_priv = sizeof_priv;
747 RETURN:
748 return pnetdev;
749 }
750
rtw_free_netdev(struct net_device * netdev)751 void rtw_free_netdev(struct net_device *netdev)
752 {
753 struct rtw_netdev_priv_indicator *pnpi;
754
755 if (!netdev)
756 goto RETURN;
757
758 pnpi = netdev_priv(netdev);
759
760 if (!pnpi->priv)
761 goto RETURN;
762
763 free_netdev(netdev);
764
765 RETURN:
766 return;
767 }
768
rtw_change_ifname(_adapter * padapter,const char * ifname)769 int rtw_change_ifname(_adapter *padapter, const char *ifname)
770 {
771 struct dvobj_priv *dvobj;
772 struct net_device *pnetdev;
773 struct net_device *cur_pnetdev;
774 struct rereg_nd_name_data *rereg_priv;
775 int ret;
776 u8 rtnl_lock_needed;
777
778 if (!padapter)
779 goto error;
780
781 dvobj = adapter_to_dvobj(padapter);
782 cur_pnetdev = padapter->pnetdev;
783 rereg_priv = &padapter->rereg_nd_name_priv;
784
785 /* free the old_pnetdev */
786 if (rereg_priv->old_pnetdev) {
787 free_netdev(rereg_priv->old_pnetdev);
788 rereg_priv->old_pnetdev = NULL;
789 }
790
791 rtnl_lock_needed = rtw_rtnl_lock_needed(dvobj);
792
793 if (rtnl_lock_needed)
794 unregister_netdev(cur_pnetdev);
795 else
796 unregister_netdevice(cur_pnetdev);
797
798 rereg_priv->old_pnetdev = cur_pnetdev;
799
800 pnetdev = rtw_init_netdev(padapter);
801 if (!pnetdev) {
802 ret = -1;
803 goto error;
804 }
805
806 SET_NETDEV_DEV(pnetdev, dvobj_to_dev(adapter_to_dvobj(padapter)));
807
808 rtw_init_netdev_name(pnetdev, ifname);
809
810 _rtw_memcpy(pnetdev->dev_addr, adapter_mac_addr(padapter), ETH_ALEN);
811
812 if (rtnl_lock_needed)
813 ret = register_netdev(pnetdev);
814 else
815 ret = register_netdevice(pnetdev);
816
817 if (ret != 0) {
818 goto error;
819 }
820
821 return 0;
822
823 error:
824
825 return -1;
826
827 }
828
829 #ifdef CONFIG_PLATFORM_SPRD
830 #ifdef do_div
831 #undef do_div
832 #endif
833 #include <asm-generic/div64.h>
834 #endif
835
rtw_modular64(u64 x,u64 y)836 u64 rtw_modular64(u64 x, u64 y)
837 {
838 return do_div(x, y);
839 }
840
rtw_division64(u64 x,u64 y)841 u64 rtw_division64(u64 x, u64 y)
842 {
843 do_div(x, y);
844 return x;
845 }
846
rtw_random32(void)847 inline u32 rtw_random32(void)
848 {
849 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
850 return prandom_u32();
851 #elif (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18))
852 u32 random_int;
853 get_random_bytes(&random_int , 4);
854 return random_int;
855 #else
856 return random32();
857 #endif
858 }
859