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