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