1 /******************************************************************************
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
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.
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
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 ******************************************************************************/
22 #define _OSDEP_SERVICE_C_
25 #include <osdep_service.h>
26 #include <drv_types.h>
27 #include <recv_osdep.h>
28 #include <linux/vmalloc.h>
33 * Translate the OS dependent @param error_code to OS independent RTW_STATUS_CODE
34 * @return: one of RTW_STATUS_CODE
36 inline int RTW_STATUS_CODE(int error_code){
42 // return RTW_STATUS_TIMEDOUT;
52 for (i=0;i<=strlen(s);i++)
54 if (s[i] >= '0' && s[i] <= '9')
55 num = num * 10 + s[i] -'0';
56 else if (s[0] == '-' && i==0)
69 inline u8* _rtw_vmalloc(u32 sz)
77 inline u8* _rtw_zvmalloc(u32 sz)
80 pbuf = _rtw_vmalloc(sz);
86 inline void _rtw_vmfree(u8 *pbuf, u32 sz)
91 u8* _rtw_malloc(u32 sz)
96 pbuf = kmalloc(sz,in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
100 u8* _rtw_zmalloc(u32 sz)
102 u8 *pbuf = _rtw_malloc(sz);
109 void _rtw_mfree(u8 *pbuf, u32 sz)
114 void* rtw_malloc2d(int h, int w, int size)
118 void **a = (void **) rtw_zmalloc( h*sizeof(void *) + h*w*size );
121 DBG_871X("%s: alloc memory fail!\n", __FUNCTION__);
125 for ( j=0; j<h; j++ )
126 a[j] = ((char *)(a+h)) + j*w*size;
131 void rtw_mfree2d(void *pbuf, int h, int w, int size)
133 rtw_mfree((u8 *)pbuf, h*sizeof(void*) + w*h*size);
136 int _rtw_memcmp(void *dst, void *src, u32 sz)
138 //under Linux/GNU/GLibc, the return value of memcmp for two same mem. chunk is 0
139 if (!(memcmp(dst, src, sz)))
145 void _rtw_init_listhead(_list *list)
147 INIT_LIST_HEAD(list);
151 For the following list_xxx operations,
152 caller must guarantee the atomic context.
153 Otherwise, there will be racing condition.
155 u32 rtw_is_list_empty(_list *phead)
157 if (list_empty(phead))
163 void rtw_list_insert_head(_list *plist, _list *phead)
165 list_add(plist, phead);
168 void rtw_list_insert_tail(_list *plist, _list *phead)
170 list_add_tail(plist, phead);
175 Caller must check if the list is empty before calling rtw_list_delete
180 void _rtw_init_sema(_sema *sema, int init_val)
182 sema_init(sema, init_val);
185 void _rtw_free_sema(_sema *sema)
189 void _rtw_up_sema(_sema *sema)
194 u32 _rtw_down_sema(_sema *sema)
196 if (down_interruptible(sema))
202 void _rtw_mutex_init(_mutex *pmutex)
204 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
211 void _rtw_mutex_free(_mutex *pmutex)
213 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
214 mutex_destroy(pmutex);
218 void _rtw_spinlock_init(_lock *plock)
220 spin_lock_init(plock);
223 void _rtw_spinlock_free(_lock *plock)
227 void _rtw_spinlock(_lock *plock)
232 void _rtw_spinunlock(_lock *plock)
237 void _rtw_spinlock_ex(_lock *plock)
242 void _rtw_spinunlock_ex(_lock *plock)
247 void _rtw_init_queue(_queue *pqueue)
249 _rtw_init_listhead(&(pqueue->queue));
251 _rtw_spinlock_init(&(pqueue->lock));
254 u32 _rtw_queue_empty(_queue *pqueue)
256 return (rtw_is_list_empty(&(pqueue->queue)));
260 u32 rtw_end_of_queue_search(_list *head, _list *plist)
268 u32 rtw_get_current_time(void)
273 inline u32 rtw_systime_to_ms(u32 systime)
275 return systime * 1000 / HZ;
278 inline u32 rtw_ms_to_systime(u32 ms)
280 return ms * HZ / 1000;
283 // the input parameter start use the same unit as returned by rtw_get_current_time
284 inline s32 rtw_get_passing_time_ms(u32 start)
286 return rtw_systime_to_ms(jiffies-start);
289 inline s32 rtw_get_time_interval_ms(u32 start, u32 end)
291 return rtw_systime_to_ms(end-start);
294 void rtw_sleep_schedulable(int ms)
298 delta = (ms * HZ)/1000;//(ms)
302 set_current_state(TASK_INTERRUPTIBLE);
303 if (schedule_timeout(delta) != 0) {
309 void rtw_msleep_os(int ms)
311 msleep((unsigned int)ms);
314 void rtw_usleep_os(int us)
316 // msleep((unsigned int)us);
320 msleep( (us/1000) + 1);
324 void _rtw_mdelay_os(int ms, const char *func, const int line)
326 DBG_871X("%s:%d %s(%d)\n", func, line, __FUNCTION__, ms);
328 mdelay((unsigned long)ms);
331 void _rtw_udelay_os(int us, const char *func, const int line)
333 DBG_871X("%s:%d %s(%d)\n", func, line, __FUNCTION__, us);
335 udelay((unsigned long)us);
338 void rtw_mdelay_os(int ms)
340 mdelay((unsigned long)ms);
342 void rtw_udelay_os(int us)
344 udelay((unsigned long)us);
353 #define RTW_SUSPEND_LOCK_NAME "rtw_wifi"
355 #ifdef CONFIG_WAKELOCK
356 static struct wake_lock rtw_suspend_lock;
357 #elif defined(CONFIG_ANDROID_POWER)
358 static android_suspend_lock_t rtw_suspend_lock ={
359 .name = RTW_SUSPEND_LOCK_NAME
363 inline void rtw_suspend_lock_init()
365 #ifdef CONFIG_WAKELOCK
366 wake_lock_init(&rtw_suspend_lock, WAKE_LOCK_SUSPEND, RTW_SUSPEND_LOCK_NAME);
367 #elif defined(CONFIG_ANDROID_POWER)
368 android_init_suspend_lock(&rtw_suspend_lock);
372 inline void rtw_suspend_lock_uninit()
374 #ifdef CONFIG_WAKELOCK
375 wake_lock_destroy(&rtw_suspend_lock);
376 #elif defined(CONFIG_ANDROID_POWER)
377 android_uninit_suspend_lock(&rtw_suspend_lock);
381 inline void rtw_lock_suspend()
383 #ifdef CONFIG_WAKELOCK
384 wake_lock(&rtw_suspend_lock);
385 #elif defined(CONFIG_ANDROID_POWER)
386 android_lock_suspend(&rtw_suspend_lock);
389 #if defined(CONFIG_WAKELOCK) || defined(CONFIG_ANDROID_POWER)
390 //DBG_871X("####%s: suspend_lock_count:%d####\n", __FUNCTION__, rtw_suspend_lock.stat.count);
394 inline void rtw_unlock_suspend()
396 #ifdef CONFIG_WAKELOCK
397 wake_unlock(&rtw_suspend_lock);
398 #elif defined(CONFIG_ANDROID_POWER)
399 android_unlock_suspend(&rtw_suspend_lock);
402 #if defined(CONFIG_WAKELOCK) || defined(CONFIG_ANDROID_POWER)
403 //DBG_871X("####%s: suspend_lock_count:%d####\n", __FUNCTION__, rtw_suspend_lock.stat.count);
408 inline void rtw_lock_suspend_timeout(long timeout)
410 #ifdef CONFIG_WAKELOCK
411 wake_lock_timeout(&rtw_suspend_lock, timeout);
412 #elif defined(CONFIG_ANDROID_POWER)
413 android_lock_suspend_auto_expire(&rtw_suspend_lock, timeout);
416 #endif //CONFIG_WOWLAN
418 inline void ATOMIC_SET(ATOMIC_T *v, int i)
423 inline int ATOMIC_READ(ATOMIC_T *v)
425 return atomic_read(v);
428 inline void ATOMIC_ADD(ATOMIC_T *v, int i)
432 inline void ATOMIC_SUB(ATOMIC_T *v, int i)
437 inline void ATOMIC_INC(ATOMIC_T *v)
442 inline void ATOMIC_DEC(ATOMIC_T *v)
447 inline int ATOMIC_ADD_RETURN(ATOMIC_T *v, int i)
449 return atomic_add_return(i,v);
452 inline int ATOMIC_SUB_RETURN(ATOMIC_T *v, int i)
454 return atomic_sub_return(i,v);
457 inline int ATOMIC_INC_RETURN(ATOMIC_T *v)
459 return atomic_inc_return(v);
462 inline int ATOMIC_DEC_RETURN(ATOMIC_T *v)
464 return atomic_dec_return(v);
468 * Open a file with the specific @param path, @param flag, @param mode
469 * @param fpp the pointer of struct file pointer to get struct file pointer while file opening is success
470 * @param path the path of the file to open
471 * @param flag file operation flags, please refer to linux document
472 * @param mode please refer to linux document
473 * @return Linux specific error code
475 static int openFile(struct file **fpp, char *path, int flag, int mode)
479 fp=filp_open(path, flag, mode);
491 * Close the file with the specific @param fp
492 * @param fp the pointer of struct file to close
495 static int closeFile(struct file *fp)
501 static int readFile(struct file *fp,char *buf,int len)
505 if (!fp->f_op || !fp->f_op->read)
509 rlen=fp->f_op->read(fp,buf+sum,len-sum, &fp->f_pos);
522 static int writeFile(struct file *fp,char *buf,int len)
526 if (!fp->f_op || !fp->f_op->write)
530 wlen=fp->f_op->write(fp,buf+sum,len-sum, &fp->f_pos);
544 * Test if the specifi @param path is a file and readable
545 * @param path the path of the file to test
546 * @return Linux specific error code
548 static int isFileReadable(char *path)
555 fp=filp_open(path, O_RDONLY, 0);
560 oldfs = get_fs(); set_fs(get_ds());
562 if (1!=readFile(fp, &buf, 1))
572 * Open the file with @param path and retrive the file content into memory starting from @param buf for @param sz at most
573 * @param path the path of the file to open and read
574 * @param buf the starting address of the buffer to store file content
575 * @param sz how many bytes to read at most
576 * @return the byte we've read, or Linux specific error code
578 static int retriveFromFile(char *path, u8* buf, u32 sz)
585 if ( 0 == (ret=openFile(&fp,path, O_RDONLY, 0)) ){
586 DBG_871X("%s openFile path:%s fp=%p\n",__FUNCTION__, path ,fp);
588 oldfs = get_fs(); set_fs(get_ds());
589 ret=readFile(fp, buf, sz);
593 DBG_871X("%s readFile, ret:%d\n",__FUNCTION__, ret);
596 DBG_871X("%s openFile path:%s Fail, ret:%d\n",__FUNCTION__, path, ret);
599 DBG_871X("%s NULL pointer\n",__FUNCTION__);
606 * Open the file with @param path and wirte @param sz byte of data starting from @param buf into the file
607 * @param path the path of the file to open and write
608 * @param buf the starting address of the data to write into file
609 * @param sz how many bytes to write at most
610 * @return the byte we've written, or Linux specific error code
612 static int storeToFile(char *path, u8* buf, u32 sz)
619 if ( 0 == (ret=openFile(&fp, path, O_CREAT|O_WRONLY, 0666)) ) {
620 DBG_871X("%s openFile path:%s fp=%p\n",__FUNCTION__, path ,fp);
622 oldfs = get_fs(); set_fs(get_ds());
623 ret=writeFile(fp, buf, sz);
627 DBG_871X("%s writeFile, ret:%d\n",__FUNCTION__, ret);
630 DBG_871X("%s openFile path:%s Fail, ret:%d\n",__FUNCTION__, path, ret);
633 DBG_871X("%s NULL pointer\n",__FUNCTION__);
640 * Test if the specifi @param path is a file and readable
641 * @param path the path of the file to test
642 * @return true or false
644 int rtw_is_file_readable(char *path)
646 if (isFileReadable(path) == 0)
653 * Open the file with @param path and retrive the file content into memory starting from @param buf for @param sz at most
654 * @param path the path of the file to open and read
655 * @param buf the starting address of the buffer to store file content
656 * @param sz how many bytes to read at most
657 * @return the byte we've read
659 int rtw_retrive_from_file(char *path, u8* buf, u32 sz)
661 int ret =retriveFromFile(path, buf, sz);
666 * Open the file with @param path and wirte @param sz byte of data starting from @param buf into the file
667 * @param path the path of the file to open and write
668 * @param buf the starting address of the data to write into file
669 * @param sz how many bytes to write at most
670 * @return the byte we've written
672 int rtw_store_to_file(char *path, u8* buf, u32 sz)
674 int ret =storeToFile(path, buf, sz);
678 #if 1 //#ifdef MEM_ALLOC_REFINE_ADAPTOR
679 struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv, void *old_priv)
681 struct net_device *pnetdev;
682 struct rtw_netdev_priv_indicator *pnpi;
684 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
685 pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
687 pnetdev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
692 pnpi = netdev_priv(pnetdev);
694 pnpi->sizeof_priv=sizeof_priv;
700 struct net_device *rtw_alloc_etherdev(int sizeof_priv)
702 struct net_device *pnetdev;
703 struct rtw_netdev_priv_indicator *pnpi;
705 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
706 pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
708 pnetdev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
713 pnpi = netdev_priv(pnetdev);
715 pnpi->priv = rtw_zvmalloc(sizeof_priv);
717 free_netdev(pnetdev);
722 pnpi->sizeof_priv=sizeof_priv;
727 void rtw_free_netdev(struct net_device * netdev)
729 struct rtw_netdev_priv_indicator *pnpi;
734 pnpi = netdev_priv(netdev);
739 rtw_vmfree(pnpi->priv, pnpi->sizeof_priv);
747 * Jeff: this function should be called under ioctl (rtnl_lock is accquired) while
748 * LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)
750 int rtw_change_ifname(_adapter *padapter, const char *ifname)
752 struct net_device *pnetdev;
753 struct net_device *cur_pnetdev = padapter->pnetdev;
754 struct rereg_nd_name_data *rereg_priv;
760 rereg_priv = &padapter->rereg_nd_name_priv;
762 //free the old_pnetdev
763 if (rereg_priv->old_pnetdev) {
764 free_netdev(rereg_priv->old_pnetdev);
765 rereg_priv->old_pnetdev = NULL;
768 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))
769 if (!rtnl_is_locked())
770 unregister_netdev(cur_pnetdev);
773 unregister_netdevice(cur_pnetdev);
775 rtw_proc_remove_one(cur_pnetdev);
777 rereg_priv->old_pnetdev=cur_pnetdev;
779 pnetdev = rtw_init_netdev(padapter);
785 SET_NETDEV_DEV(pnetdev, dvobj_to_dev(adapter_to_dvobj(padapter)));
787 rtw_init_netdev_name(pnetdev, ifname);
789 memcpy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr, ETH_ALEN);
791 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))
792 if (!rtnl_is_locked())
793 ret = register_netdev(pnetdev);
796 ret = register_netdevice(pnetdev);
799 RT_TRACE(_module_hci_intfs_c_,_drv_err_,("register_netdev() failed\n"));
803 rtw_proc_init_one(pnetdev);
812 #endif //MEM_ALLOC_REFINE_ADAPTOR
814 u64 rtw_modular64(u64 x, u64 y)
819 u64 rtw_division64(u64 x, u64 y)
825 void rtw_buf_free(u8 **buf, u32 *buf_len)
829 if (!buf || !buf_len)
836 _rtw_mfree(*buf, *buf_len);
841 void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len)
843 u32 ori_len = 0, dup_len = 0;
847 if (!buf || !buf_len)
850 if (!src || !src_len)
854 dup = rtw_malloc(src_len);
857 memcpy(dup, src, dup_len);
864 /* replace buf with dup */
870 if (ori && ori_len > 0)
871 _rtw_mfree(ori, ori_len);