blob: e1c62b73f155c2cbcbd1dc4357d640bfd3268bba [file] [log] [blame]
Dmitry Shmidt66eb9fa2011-05-24 11:14:33 -07001/*
2 * Linux-specific abstractions to gain some independence from linux kernel versions.
3 * Pave over some 2.2 versus 2.4 versus 2.6 kernel differences.
4 *
5 * Copyright (C) 1999-2011, Broadcom Corporation
6 *
7 * Unless you and Broadcom execute a separate written software license
8 * agreement governing use of this software, this software is licensed to you
9 * under the terms of the GNU General Public License version 2 (the "GPL"),
10 * available at http://www.broadcom.com/licenses/GPLv2.php, with the
11 * following added to such license:
12 *
13 * As a special exception, the copyright holders of this software give you
14 * permission to link this software with independent modules, and to copy and
15 * distribute the resulting executable under terms of your choice, provided that
16 * you also meet, for each linked independent module, the terms and conditions of
17 * the license of that module. An independent module is a module which is not
18 * derived from this software. The special exception does not apply to any
19 * modifications of the software.
20 *
21 * Notwithstanding the above, under no circumstances may you combine this
22 * software in any way with any other Broadcom software provided under a license
23 * other than the GPL, without Broadcom's express prior written consent.
24 *
25 * $Id: linuxver.h,v 13.53.2.2 2010-12-22 23:47:26 Exp $
26 */
27
28
29#ifndef _linuxver_h_
30#define _linuxver_h_
31
32#include <linux/version.h>
33#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0))
34#include <linux/config.h>
35#else
36#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33))
37#include <generated/autoconf.h>
38#else
39#include <linux/autoconf.h>
40#endif
41#endif
42#include <linux/module.h>
43
44#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0))
45
46#ifdef __UNDEF_NO_VERSION__
47#undef __NO_VERSION__
48#else
49#define __NO_VERSION__
50#endif
51#endif
52
53#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
54#define module_param(_name_, _type_, _perm_) MODULE_PARM(_name_, "i")
55#define module_param_string(_name_, _string_, _size_, _perm_) \
56 MODULE_PARM(_string_, "c" __MODULE_STRING(_size_))
57#endif
58
59
60#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 9))
61#include <linux/malloc.h>
62#else
63#include <linux/slab.h>
64#endif
65
66#include <linux/types.h>
67#include <linux/init.h>
68#include <linux/mm.h>
69#include <linux/string.h>
70#include <linux/pci.h>
71#include <linux/interrupt.h>
72#include <linux/netdevice.h>
Chih-Wei Huangf44baeb2011-08-04 10:09:43 -070073#include <linux/semaphore.h>
Dmitry Shmidt66eb9fa2011-05-24 11:14:33 -070074#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
75#undef IP_TOS
76#endif
77#include <asm/io.h>
78
79#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 41))
80#include <linux/workqueue.h>
81#else
82#include <linux/tqueue.h>
83#ifndef work_struct
84#define work_struct tq_struct
85#endif
86#ifndef INIT_WORK
87#define INIT_WORK(_work, _func, _data) INIT_TQUEUE((_work), (_func), (_data))
88#endif
89#ifndef schedule_work
90#define schedule_work(_work) schedule_task((_work))
91#endif
92#ifndef flush_scheduled_work
93#define flush_scheduled_work() flush_scheduled_tasks()
94#endif
95#endif
96
97#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
98#define MY_INIT_WORK(_work, _func) INIT_WORK(_work, _func)
99#else
100#define MY_INIT_WORK(_work, _func) INIT_WORK(_work, _func, _work)
101typedef void (*work_func_t)(void *work);
102#endif
103
104#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0))
105
106#ifndef IRQ_NONE
107typedef void irqreturn_t;
108#define IRQ_NONE
109#define IRQ_HANDLED
110#define IRQ_RETVAL(x)
111#endif
112#else
113typedef irqreturn_t(*FN_ISR) (int irq, void *dev_id, struct pt_regs *ptregs);
114#endif
115
116#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
117#define IRQF_SHARED SA_SHIRQ
118#endif
119
120#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 17)
121#ifdef CONFIG_NET_RADIO
122#define CONFIG_WIRELESS_EXT
123#endif
124#endif
125
126#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 67)
Dmitry Shmidt66eb9fa2011-05-24 11:14:33 -0700127#define MOD_INC_USE_COUNT
128#define MOD_DEC_USE_COUNT
129#endif
Dmitry Shmidt66eb9fa2011-05-24 11:14:33 -0700130
131#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
132#include <linux/sched.h>
133#endif
134
135#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
136#include <net/lib80211.h>
137#endif
Howard M. Hartecf77d4c2011-05-27 16:07:36 -0700138#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
Dmitry Shmidt66eb9fa2011-05-24 11:14:33 -0700139#include <linux/ieee80211.h>
140#else
141#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14)
142#include <net/ieee80211.h>
143#endif
144#endif
145
146
147#ifndef __exit
148#define __exit
149#endif
150#ifndef __devexit
151#define __devexit
152#endif
153#ifndef __devinit
154#define __devinit __init
155#endif
156#ifndef __devinitdata
157#define __devinitdata
158#endif
159#ifndef __devexit_p
160#define __devexit_p(x) x
161#endif
162
163#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0))
164
165#define pci_get_drvdata(dev) (dev)->sysdata
166#define pci_set_drvdata(dev, value) (dev)->sysdata = (value)
167
168
169
170struct pci_device_id {
171 unsigned int vendor, device;
172 unsigned int subvendor, subdevice;
173 unsigned int class, class_mask;
174 unsigned long driver_data;
175};
176
177struct pci_driver {
178 struct list_head node;
179 char *name;
180 const struct pci_device_id *id_table;
181 int (*probe)(struct pci_dev *dev,
182 const struct pci_device_id *id);
183 void (*remove)(struct pci_dev *dev);
184 void (*suspend)(struct pci_dev *dev);
185 void (*resume)(struct pci_dev *dev);
186};
187
188#define MODULE_DEVICE_TABLE(type, name)
189#define PCI_ANY_ID (~0)
190
191
192#define pci_module_init pci_register_driver
193extern int pci_register_driver(struct pci_driver *drv);
194extern void pci_unregister_driver(struct pci_driver *drv);
195
196#endif
197
198#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18))
199#define pci_module_init pci_register_driver
200#endif
201
202#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18))
203#ifdef MODULE
204#define module_init(x) int init_module(void) { return x(); }
205#define module_exit(x) void cleanup_module(void) { x(); }
206#else
207#define module_init(x) __initcall(x);
208#define module_exit(x) __exitcall(x);
209#endif
210#endif
211
212#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)
213#define WL_USE_NETDEV_OPS
214#else
215#undef WL_USE_NETDEV_OPS
216#endif
217
218#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)) && defined(CONFIG_RFKILL_INPUT)
219#define WL_CONFIG_RFKILL_INPUT
220#else
221#undef WL_CONFIG_RFKILL_INPUT
222#endif
223
224#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 48))
225#define list_for_each(pos, head) \
226 for (pos = (head)->next; pos != (head); pos = pos->next)
227#endif
228
229#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 13))
230#define pci_resource_start(dev, bar) ((dev)->base_address[(bar)])
231#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 44))
232#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start)
233#endif
234
235#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 23))
236#define pci_enable_device(dev) do { } while (0)
237#endif
238
239#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 14))
240#define net_device device
241#endif
242
243#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 42))
244
245
246
247#ifndef PCI_DMA_TODEVICE
248#define PCI_DMA_TODEVICE 1
249#define PCI_DMA_FROMDEVICE 2
250#endif
251
252typedef u32 dma_addr_t;
253
254
255static inline int get_order(unsigned long size)
256{
257 int order;
258
259 size = (size-1) >> (PAGE_SHIFT-1);
260 order = -1;
261 do {
262 size >>= 1;
263 order++;
264 } while (size);
265 return order;
266}
267
268static inline void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
269 dma_addr_t *dma_handle)
270{
271 void *ret;
272 int gfp = GFP_ATOMIC | GFP_DMA;
273
274 ret = (void *)__get_free_pages(gfp, get_order(size));
275
276 if (ret != NULL) {
277 memset(ret, 0, size);
278 *dma_handle = virt_to_bus(ret);
279 }
280 return ret;
281}
282static inline void pci_free_consistent(struct pci_dev *hwdev, size_t size,
283 void *vaddr, dma_addr_t dma_handle)
284{
285 free_pages((unsigned long)vaddr, get_order(size));
286}
287#define pci_map_single(cookie, address, size, dir) virt_to_bus(address)
288#define pci_unmap_single(cookie, address, size, dir)
289
290#endif
291
292#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 43))
293
294#define dev_kfree_skb_any(a) dev_kfree_skb(a)
295#define netif_down(dev) do { (dev)->start = 0; } while (0)
296
297
298#ifndef _COMPAT_NETDEVICE_H
299
300
301
302#define dev_kfree_skb_irq(a) dev_kfree_skb(a)
303#define netif_wake_queue(dev) \
304 do { clear_bit(0, &(dev)->tbusy); mark_bh(NET_BH); } while (0)
305#define netif_stop_queue(dev) set_bit(0, &(dev)->tbusy)
306
307static inline void netif_start_queue(struct net_device *dev)
308{
309 dev->tbusy = 0;
310 dev->interrupt = 0;
311 dev->start = 1;
312}
313
314#define netif_queue_stopped(dev) (dev)->tbusy
315#define netif_running(dev) (dev)->start
316
317#endif
318
319#define netif_device_attach(dev) netif_start_queue(dev)
320#define netif_device_detach(dev) netif_stop_queue(dev)
321
322
323#define tasklet_struct tq_struct
324static inline void tasklet_schedule(struct tasklet_struct *tasklet)
325{
326 queue_task(tasklet, &tq_immediate);
327 mark_bh(IMMEDIATE_BH);
328}
329
330static inline void tasklet_init(struct tasklet_struct *tasklet,
331 void (*func)(unsigned long),
332 unsigned long data)
333{
334 tasklet->next = NULL;
335 tasklet->sync = 0;
336 tasklet->routine = (void (*)(void *))func;
337 tasklet->data = (void *)data;
338}
339#define tasklet_kill(tasklet) { do {} while (0); }
340
341
342#define del_timer_sync(timer) del_timer(timer)
343
344#else
345
346#define netif_down(dev)
347
348#endif
349
350#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 3))
351
352
353#define PREPARE_TQUEUE(_tq, _routine, _data) \
354 do { \
355 (_tq)->routine = _routine; \
356 (_tq)->data = _data; \
357 } while (0)
358
359
360#define INIT_TQUEUE(_tq, _routine, _data) \
361 do { \
362 INIT_LIST_HEAD(&(_tq)->list); \
363 (_tq)->sync = 0; \
364 PREPARE_TQUEUE((_tq), (_routine), (_data)); \
365 } while (0)
366
367#endif
368
369
370#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 9)
371#define PCI_SAVE_STATE(a, b) pci_save_state(a)
372#define PCI_RESTORE_STATE(a, b) pci_restore_state(a)
373#else
374#define PCI_SAVE_STATE(a, b) pci_save_state(a, b)
375#define PCI_RESTORE_STATE(a, b) pci_restore_state(a, b)
376#endif
377
378#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 6))
379static inline int
380pci_save_state(struct pci_dev *dev, u32 *buffer)
381{
382 int i;
383 if (buffer) {
384 for (i = 0; i < 16; i++)
385 pci_read_config_dword(dev, i * 4, &buffer[i]);
386 }
387 return 0;
388}
389
390static inline int
391pci_restore_state(struct pci_dev *dev, u32 *buffer)
392{
393 int i;
394
395 if (buffer) {
396 for (i = 0; i < 16; i++)
397 pci_write_config_dword(dev, i * 4, buffer[i]);
398 }
399
400 else {
401 for (i = 0; i < 6; i ++)
402 pci_write_config_dword(dev,
403 PCI_BASE_ADDRESS_0 + (i * 4),
404 pci_resource_start(dev, i));
405 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
406 }
407 return 0;
408}
409#endif
410
411
412#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 19))
413#define read_c0_count() read_32bit_cp0_register(CP0_COUNT)
414#endif
415
416
417#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24))
418#ifndef SET_MODULE_OWNER
419#define SET_MODULE_OWNER(dev) do {} while (0)
420#define OLD_MOD_INC_USE_COUNT MOD_INC_USE_COUNT
421#define OLD_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT
422#else
423#define OLD_MOD_INC_USE_COUNT do {} while (0)
424#define OLD_MOD_DEC_USE_COUNT do {} while (0)
425#endif
426#else
427#ifndef SET_MODULE_OWNER
428#define SET_MODULE_OWNER(dev) do {} while (0)
429#endif
430#ifndef MOD_INC_USE_COUNT
431#define MOD_INC_USE_COUNT do {} while (0)
432#endif
433#ifndef MOD_DEC_USE_COUNT
434#define MOD_DEC_USE_COUNT do {} while (0)
435#endif
436#define OLD_MOD_INC_USE_COUNT MOD_INC_USE_COUNT
437#define OLD_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT
438#endif
439
440#ifndef SET_NETDEV_DEV
441#define SET_NETDEV_DEV(net, pdev) do {} while (0)
442#endif
443
444#ifndef HAVE_FREE_NETDEV
445#define free_netdev(dev) kfree(dev)
446#endif
447
448#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0))
449
450#define af_packet_priv data
451#endif
452
453
454#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11)
455#define DRV_SUSPEND_STATE_TYPE pm_message_t
456#else
457#define DRV_SUSPEND_STATE_TYPE uint32
458#endif
459
460#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
461#define CHECKSUM_HW CHECKSUM_PARTIAL
462#endif
463
464typedef struct {
465 void *parent;
466 struct task_struct *p_task;
467 long thr_pid;
468 int prio;
469 struct semaphore sema;
470 bool terminated;
471 struct completion completed;
472} tsk_ctl_t;
473
474
475
476
477#ifdef DHD_DEBUG
478#define DBG_THR(x) printk x
479#else
480#define DBG_THR(x)
481#endif
482
Dmitry Shmidt66eb9fa2011-05-24 11:14:33 -0700483#define SMP_RD_BARRIER_DEPENDS(x) smp_rmb(x)
Dmitry Shmidt66eb9fa2011-05-24 11:14:33 -0700484
485
486#define PROC_START(thread_func, owner, tsk_ctl, flags) \
487{ \
488 sema_init(&((tsk_ctl)->sema), 0); \
489 init_completion(&((tsk_ctl)->completed)); \
490 (tsk_ctl)->parent = owner; \
491 (tsk_ctl)->terminated = FALSE; \
492 (tsk_ctl)->thr_pid = kernel_thread(thread_func, tsk_ctl, flags); \
493 if ((tsk_ctl)->thr_pid > 0) \
494 wait_for_completion(&((tsk_ctl)->completed)); \
495 DBG_THR(("%s thr:%lx started\n", __FUNCTION__, (tsk_ctl)->thr_pid)); \
496}
497
498#define PROC_STOP(tsk_ctl) \
499{ \
500 (tsk_ctl)->terminated = TRUE; \
501 smp_wmb(); \
502 up(&((tsk_ctl)->sema)); \
503 wait_for_completion(&((tsk_ctl)->completed)); \
504 DBG_THR(("%s thr:%lx terminated OK\n", __FUNCTION__, (tsk_ctl)->thr_pid)); \
505 (tsk_ctl)->thr_pid = -1; \
506}
507
508
509
510#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31))
511#define KILL_PROC(nr, sig) \
512{ \
513struct task_struct *tsk; \
514struct pid *pid; \
515pid = find_get_pid((pid_t)nr); \
516tsk = pid_task(pid, PIDTYPE_PID); \
517if (tsk) send_sig(sig, tsk, 1); \
518}
519#else
520#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && (LINUX_VERSION_CODE <= \
521 KERNEL_VERSION(2, 6, 30))
522#define KILL_PROC(pid, sig) \
523{ \
524 struct task_struct *tsk; \
525 tsk = find_task_by_vpid(pid); \
526 if (tsk) send_sig(sig, tsk, 1); \
527}
528#else
529#define KILL_PROC(pid, sig) \
530{ \
531 kill_proc(pid, sig, 1); \
532}
533#endif
534#endif
535
536#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
537#include <linux/time.h>
538#include <linux/wait.h>
539#else
540#include <linux/sched.h>
541
542#define __wait_event_interruptible_timeout(wq, condition, ret) \
543do { \
544 wait_queue_t __wait; \
545 init_waitqueue_entry(&__wait, current); \
546 \
547 add_wait_queue(&wq, &__wait); \
548 for (;;) { \
549 set_current_state(TASK_INTERRUPTIBLE); \
550 if (condition) \
551 break; \
552 if (!signal_pending(current)) { \
553 ret = schedule_timeout(ret); \
554 if (!ret) \
555 break; \
556 continue; \
557 } \
558 ret = -ERESTARTSYS; \
559 break; \
560 } \
561 current->state = TASK_RUNNING; \
562 remove_wait_queue(&wq, &__wait); \
563} while (0)
564
565#define wait_event_interruptible_timeout(wq, condition, timeout) \
566({ \
567 long __ret = timeout; \
568 if (!(condition)) \
569 __wait_event_interruptible_timeout(wq, condition, __ret); \
570 __ret; \
571})
572
573#endif
574
575#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
576#define WL_DEV_IF(dev) ((wl_if_t*)netdev_priv(dev))
577#else
578#define WL_DEV_IF(dev) ((wl_if_t*)(dev)->priv)
579#endif
580
581#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
582#define WL_ISR(i, d, p) wl_isr((i), (d))
583#else
584#define WL_ISR(i, d, p) wl_isr((i), (d), (p))
585#endif
586
587#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0))
588#define netdev_priv(dev) dev->priv
589#endif
590
591#endif