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