1 /******************************************************************************
3 * Copyright(c) 2007 - 2013 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 ******************************************************************************/
20 #ifndef __OSDEP_LINUX_SERVICE_H_
21 #define __OSDEP_LINUX_SERVICE_H_
23 #include <linux/version.h>
24 #include <linux/spinlock.h>
25 #include <linux/compiler.h>
26 #include <linux/kernel.h>
27 #include <linux/errno.h>
28 #include <linux/init.h>
29 #include <linux/slab.h>
30 #include <linux/module.h>
31 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 5))
32 #include <linux/kref.h>
34 /* #include <linux/smp_lock.h> */
35 #include <linux/netdevice.h>
36 #include <linux/skbuff.h>
37 #include <linux/circ_buf.h>
38 #include <asm/uaccess.h>
39 #include <asm/byteorder.h>
40 #include <asm/atomic.h>
42 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26))
43 #include <asm/semaphore.h>
45 #include <linux/semaphore.h>
47 #include <linux/sem.h>
48 #include <linux/sched.h>
49 #include <linux/etherdevice.h>
50 #include <linux/wireless.h>
51 #include <net/iw_handler.h>
52 #include <linux/if_arp.h>
53 #include <linux/rtnetlink.h>
54 #include <linux/delay.h>
55 #include <linux/interrupt.h> /* for struct tasklet_struct */
57 #include <linux/kthread.h>
58 #include <linux/list.h>
59 #include <linux/vmalloc.h>
61 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 5, 41))
62 #include <linux/tqueue.h>
65 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0))
66 #include <uapi/linux/limits.h>
68 #include <linux/limits.h>
71 #ifdef RTK_DMP_PLATFORM
72 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 12))
73 #include <linux/pageremap.h>
78 #ifdef CONFIG_NET_RADIO
79 #define CONFIG_WIRELESS_EXT
83 #include <net/ieee80211_radiotap.h>
85 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24))
86 #include <linux/ieee80211.h>
89 #ifdef CONFIG_IOCTL_CFG80211
90 /* #include <linux/ieee80211.h> */
91 #include <net/cfg80211.h>
92 #endif /* CONFIG_IOCTL_CFG80211 */
94 #ifdef CONFIG_TCP_CSUM_OFFLOAD_TX
96 #include <linux/udp.h>
99 #ifdef CONFIG_HAS_EARLYSUSPEND
100 #include <linux/earlysuspend.h>
101 #endif /* CONFIG_HAS_EARLYSUSPEND */
103 #ifdef CONFIG_EFUSE_CONFIG_FILE
104 #include <linux/fs.h>
107 #ifdef CONFIG_USB_HCI
108 #include <linux/usb.h>
109 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 21))
110 #include <linux/usb_ch9.h>
112 #include <linux/usb/ch9.h>
116 #ifdef CONFIG_BT_COEXIST_SOCKET_TRX
117 #include <net/sock.h>
119 #include <linux/udp.h>
120 #include <linux/in.h>
121 #include <linux/netlink.h>
122 #endif /* CONFIG_BT_COEXIST_SOCKET_TRX */
124 #ifdef CONFIG_USB_HCI
125 typedef struct urb *PURB;
126 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22))
127 #ifdef CONFIG_USB_SUSPEND
128 #define CONFIG_AUTOSUSPEND 1
133 #if defined(CONFIG_RTW_GRO) && (!defined(CONFIG_RTW_NAPI))
135 #error "Enable NAPI before enable GRO\n"
137 #elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) && defined(CONFIG_RTW_NAPI))
139 #error "Linux Kernel version too old (should newer than 2.6.29)\n"
144 typedef struct semaphore _sema;
145 typedef spinlock_t _lock;
146 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
147 typedef struct mutex _mutex;
149 typedef struct semaphore _mutex;
151 typedef struct timer_list _timer;
154 struct list_head queue;
158 typedef struct sk_buff _pkt;
159 typedef unsigned char _buffer;
161 typedef struct __queue _queue;
162 typedef struct list_head _list;
163 typedef int _OS_STATUS;
164 /* typedef u32 _irqL; */
165 typedef unsigned long _irqL;
166 typedef struct net_device *_nic_hdl;
168 typedef void *_thread_hdl_;
169 typedef int thread_return;
170 typedef void *thread_context;
172 #define thread_exit() complete_and_exit(NULL, 0)
174 typedef void timer_hdl_return;
175 typedef void *timer_hdl_context;
177 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 41))
178 typedef struct work_struct _workitem;
180 typedef struct tq_struct _workitem;
183 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24))
184 #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
187 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22))
188 /* Porting from linux kernel, for compatible with old kernel. */
189 static inline unsigned char *skb_tail_pointer(const struct sk_buff *skb)
194 static inline void skb_reset_tail_pointer(struct sk_buff *skb)
196 skb->tail = skb->data;
199 static inline void skb_set_tail_pointer(struct sk_buff *skb, const int offset)
201 skb->tail = skb->data + offset;
204 static inline unsigned char *skb_end_pointer(const struct sk_buff *skb)
210 __inline static _list *get_next(_list *list)
215 __inline static _list *get_list_head(_queue *queue)
217 return &(queue->queue);
221 #define LIST_CONTAINOR(ptr, type, member) \
222 ((type *)((char *)(ptr)-(SIZE_T)(&((type *)0)->member)))
225 __inline static void _enter_critical(_lock *plock, _irqL *pirqL)
227 spin_lock_irqsave(plock, *pirqL);
230 __inline static void _exit_critical(_lock *plock, _irqL *pirqL)
232 spin_unlock_irqrestore(plock, *pirqL);
235 __inline static void _enter_critical_ex(_lock *plock, _irqL *pirqL)
237 spin_lock_irqsave(plock, *pirqL);
240 __inline static void _exit_critical_ex(_lock *plock, _irqL *pirqL)
242 spin_unlock_irqrestore(plock, *pirqL);
245 __inline static void _enter_critical_bh(_lock *plock, _irqL *pirqL)
250 __inline static void _exit_critical_bh(_lock *plock, _irqL *pirqL)
252 spin_unlock_bh(plock);
255 __inline static int _enter_critical_mutex(_mutex *pmutex, _irqL *pirqL)
258 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
259 /* mutex_lock(pmutex); */
260 ret = mutex_lock_interruptible(pmutex);
262 ret = down_interruptible(pmutex);
268 __inline static void _exit_critical_mutex(_mutex *pmutex, _irqL *pirqL)
270 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
271 mutex_unlock(pmutex);
277 __inline static void rtw_list_delete(_list *plist)
279 list_del_init(plist);
282 #define RTW_TIMER_HDL_ARGS void *FunctionContext
284 __inline static void _init_timer(_timer *ptimer, _nic_hdl nic_hdl, void *pfunc, void *cntx)
286 /* setup_timer(ptimer, pfunc,(u32)cntx); */
287 ptimer->function = pfunc;
288 ptimer->data = (unsigned long)cntx;
292 __inline static void _set_timer(_timer *ptimer, u32 delay_time)
294 mod_timer(ptimer , (jiffies + (delay_time * HZ / 1000)));
297 __inline static void _cancel_timer(_timer *ptimer, u8 *bcancelled)
299 del_timer_sync(ptimer);
304 static inline void _init_workitem(_workitem *pwork, void *pfunc, void *cntx)
306 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20))
307 INIT_WORK(pwork, pfunc);
308 #elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 41))
309 INIT_WORK(pwork, pfunc, pwork);
311 INIT_TQUEUE(pwork, pfunc, pwork);
315 __inline static void _set_workitem(_workitem *pwork)
317 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 41))
318 schedule_work(pwork);
320 schedule_task(pwork);
324 __inline static void _cancel_workitem_sync(_workitem *pwork)
326 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22))
327 cancel_work_sync(pwork);
328 #elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 41))
329 flush_scheduled_work();
331 flush_scheduled_tasks();
335 * Global Mutex: can only be used at PASSIVE level.
338 #define ACQUIRE_GLOBAL_MUTEX(_MutexCounter) \
340 while (atomic_inc_return((atomic_t *)&(_MutexCounter)) != 1) { \
341 atomic_dec((atomic_t *)&(_MutexCounter)); \
346 #define RELEASE_GLOBAL_MUTEX(_MutexCounter) \
348 atomic_dec((atomic_t *)&(_MutexCounter)); \
351 static inline int rtw_netif_queue_stopped(struct net_device *pnetdev)
353 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
354 return (netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 0)) &&
355 netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 1)) &&
356 netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 2)) &&
357 netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 3)));
359 return netif_queue_stopped(pnetdev);
363 static inline void rtw_netif_wake_queue(struct net_device *pnetdev)
365 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
366 netif_tx_wake_all_queues(pnetdev);
368 netif_wake_queue(pnetdev);
372 static inline void rtw_netif_start_queue(struct net_device *pnetdev)
374 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
375 netif_tx_start_all_queues(pnetdev);
377 netif_start_queue(pnetdev);
381 static inline void rtw_netif_stop_queue(struct net_device *pnetdev)
383 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
384 netif_tx_stop_all_queues(pnetdev);
386 netif_stop_queue(pnetdev);
389 static inline void rtw_netif_carrier_on(struct net_device *pnetdev)
391 netif_device_attach(pnetdev);
392 netif_carrier_on(pnetdev);
394 static inline int rtw_merge_string(char *dst, int dst_len, const char *src1, const char *src2)
397 len += snprintf(dst + len, dst_len - len, "%s", src1);
398 len += snprintf(dst + len, dst_len - len, "%s", src2);
403 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
404 #define rtw_signal_process(pid, sig) kill_pid(find_vpid((pid)), (sig), 1)
405 #else /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
406 #define rtw_signal_process(pid, sig) kill_proc((pid), (sig), 1)
407 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
410 /* Suspend lock prevent system from going suspend */
411 #ifdef CONFIG_WAKELOCK
412 #include <linux/wakelock.h>
413 #elif defined(CONFIG_ANDROID_POWER)
414 #include <linux/android_power.h>
417 /* limitation of path length */
418 #define PATH_LENGTH_MAX PATH_MAX
420 /* Atomic integer operations */
421 #define ATOMIC_T atomic_t
423 #define rtw_netdev_priv(netdev) (((struct rtw_netdev_priv_indicator *)netdev_priv(netdev))->priv)
425 #define NDEV_FMT "%s"
426 #define NDEV_ARG(ndev) ndev->name
427 #define ADPT_FMT "%s"
428 #define ADPT_ARG(adapter) (adapter->pnetdev ? adapter->pnetdev->name : NULL)
429 #define FUNC_NDEV_FMT "%s(%s)"
430 #define FUNC_NDEV_ARG(ndev) __func__, ndev->name
431 #define FUNC_ADPT_FMT "%s(%s)"
432 #define FUNC_ADPT_ARG(adapter) __func__, (adapter->pnetdev ? adapter->pnetdev->name : NULL)
434 struct rtw_netdev_priv_indicator {
438 struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv, void *old_priv);
439 extern struct net_device *rtw_alloc_etherdev(int sizeof_priv);
441 #define STRUCT_PACKED __attribute__ ((packed))