From c61563095e22d5ff7b7b7852d26cca1bb3fd893c Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 8 Mar 2012 17:57:51 -0800 Subject: usb: gadget: adb: do not set error flag when dequeuing req When an ep_out req is dequeued because of userspace freezing, don't set the error flag. Change-Id: I680f1a1059b8ac2244aaa069e7d42dc44abf98e9 Signed-off-by: Colin Cross --- drivers/usb/gadget/f_adb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/f_adb.c b/drivers/usb/gadget/f_adb.c index 4433a4dbdfb..3827715f832 100644 --- a/drivers/usb/gadget/f_adb.c +++ b/drivers/usb/gadget/f_adb.c @@ -205,7 +205,7 @@ static void adb_complete_out(struct usb_ep *ep, struct usb_request *req) struct adb_dev *dev = _adb_dev; dev->rx_done = 1; - if (req->status != 0) + if (req->status != 0 && req->status != -ECONNRESET) dev->error = 1; wake_up(&dev->read_wq); -- cgit v1.2.3 From d4b3901d57fc08bf85d8cefe500adbc52f7b21c8 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Fri, 9 Mar 2012 20:07:04 -0800 Subject: android: persistent_ram: fix section mismatch in clients persistent_ram clients will call the init functions from their probe functions, which need to be __devinit, not __init. Change the persistent_ram init functions to be __devinit. Change-Id: If92338f7c8d57dd34b286ff7705a96c078477ba4 Signed-off-by: Colin Cross --- drivers/staging/android/persistent_ram.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/android/persistent_ram.c b/drivers/staging/android/persistent_ram.c index d8d8290945a..f0f51197c3d 100644 --- a/drivers/staging/android/persistent_ram.c +++ b/drivers/staging/android/persistent_ram.c @@ -34,7 +34,7 @@ struct persistent_ram_buffer { #define PERSISTENT_RAM_SIG (0x43474244) /* DBGC */ -static __initdata LIST_HEAD(persistent_ram_list); +static __devinitdata LIST_HEAD(persistent_ram_list); static inline size_t buffer_size(struct persistent_ram_zone *prz) { @@ -266,7 +266,7 @@ static void notrace persistent_ram_update(struct persistent_ram_zone *prz, persistent_ram_update_ecc(prz, start, count); } -static void __init +static void __devinit persistent_ram_save_old(struct persistent_ram_zone *prz) { struct persistent_ram_buffer *buffer = prz->buffer; @@ -372,7 +372,7 @@ static int persistent_ram_buffer_map(phys_addr_t start, phys_addr_t size, return 0; } -static int __init persistent_ram_buffer_init(const char *name, +static int __devinit persistent_ram_buffer_init(const char *name, struct persistent_ram_zone *prz) { int i; @@ -394,7 +394,7 @@ static int __init persistent_ram_buffer_init(const char *name, return -EINVAL; } -static __init +static __devinit struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc) { struct persistent_ram_zone *prz; @@ -441,7 +441,7 @@ struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc) return prz; } -struct persistent_ram_zone * __init +struct persistent_ram_zone * __devinit persistent_ram_init_ringbuffer(struct device *dev, bool ecc) { return __persistent_ram_init(dev, ecc); -- cgit v1.2.3 From aadbb1aa3544b7b494850f6870829c66c0fb686c Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Fri, 9 Mar 2012 20:10:41 -0800 Subject: android: ram_console: fix section mismatch in probe function ram_console_driver_probe can be called after __init, change it to __devinit. Change-Id: I2442532386d81ed7bfae2528a2200483f89c8c37 Signed-off-by: Colin Cross --- drivers/staging/android/ram_console.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/android/ram_console.c b/drivers/staging/android/ram_console.c index 233d652684c..942e39df40c 100644 --- a/drivers/staging/android/ram_console.c +++ b/drivers/staging/android/ram_console.c @@ -50,7 +50,7 @@ void ram_console_enable_console(int enabled) ram_console.flags &= ~CON_ENABLED; } -static int ram_console_driver_probe(struct platform_device *pdev) +static int __devinit ram_console_driver_probe(struct platform_device *pdev) { struct ram_console_platform_data *pdata = pdev->dev.platform_data; struct persistent_ram_zone *prz; -- cgit v1.2.3 From cccdf6b6f91ac4ff005997e1066c05c060efdcaf Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Tue, 13 Mar 2012 13:14:31 -0700 Subject: android: persistent_trace: fix section mismatch warning persistent_trace_probe can be calls persistent_ram init functions that are __devinit, mark it __devinit as well. Change-Id: I8f3cfb1bc443d143dc838b2bced2d191b3bf52d7 Signed-off-by: Colin Cross --- drivers/staging/android/trace_persistent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/android/trace_persistent.c b/drivers/staging/android/trace_persistent.c index 377d4d98995..7c3e9499fba 100644 --- a/drivers/staging/android/trace_persistent.c +++ b/drivers/staging/android/trace_persistent.c @@ -202,7 +202,7 @@ static const struct file_operations persistent_trace_old_fops = { .release = seq_release, }; -static int persistent_trace_probe(struct platform_device *pdev) +static int __devinit persistent_trace_probe(struct platform_device *pdev) { struct dentry *d; int ret; -- cgit v1.2.3 From b09af38c2ddc105752a457aeecfb524f2c4b35b2 Mon Sep 17 00:00:00 2001 From: "Torne (Richard Coles)" Date: Wed, 14 Mar 2012 15:08:26 -0700 Subject: mmc: sdhci: remove too large timeout warning Some MMC cards specify timeouts that are larger than the highest possible timeout in the host controller. sdhci is the only host controller driver which complains about this; remove the warning to match the behaviour of the other drivers. Signed-off-by: Dmitry Shmidt --- drivers/mmc/host/sdhci.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 8d66706824a..700f9f84aec 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -679,11 +679,8 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd) break; } - if (count >= 0xF) { - pr_warning("%s: Too large timeout requested for CMD%d!\n", - mmc_hostname(host->mmc), cmd->opcode); + if (count >= 0xF) count = 0xE; - } return count; } -- cgit v1.2.3 From 0141d53c807d25804407b5c0665cb38d8974aa78 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 14 Mar 2012 16:28:45 -0700 Subject: ARM: fiq_debugger: fix compiling for v3.3 Call kernel_restart instead of arch_reset, the ARM reset handling has changed. Remove localtimer irq printing, they now show up in the regular irq stats. Change-Id: I523da343b292c5711f3e1cbfd766d32eea2da84e Signed-off-by: Colin Cross --- arch/arm/common/fiq_debugger.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/arch/arm/common/fiq_debugger.c b/arch/arm/common/fiq_debugger.c index 3ed18ae2ed8..0e33748edd6 100644 --- a/arch/arm/common/fiq_debugger.c +++ b/arch/arm/common/fiq_debugger.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -37,8 +38,6 @@ #include #include -#include - #include #include "fiq_debugger_ringbuf.h" @@ -357,7 +356,6 @@ static void dump_allregs(struct fiq_debugger_state *state, unsigned *regs) static void dump_irqs(struct fiq_debugger_state *state) { int n; - unsigned int cpu; debug_printf(state, "irqnr total since-last status name\n"); for (n = 0; n < NR_IRQS; n++) { @@ -371,16 +369,6 @@ static void dump_irqs(struct fiq_debugger_state *state) (act && act->name) ? act->name : "???"); state->last_irqs[n] = kstat_irqs(n); } - - for (cpu = 0; cpu < NR_CPUS; cpu++) { - - debug_printf(state, "LOC %d: %10u %11u\n", cpu, - __IRQ_STAT(cpu, local_timer_irqs), - __IRQ_STAT(cpu, local_timer_irqs) - - state->last_local_timer_irqs[cpu]); - state->last_local_timer_irqs[cpu] = - __IRQ_STAT(cpu, local_timer_irqs); - } } struct stacktrace_state { @@ -605,7 +593,7 @@ static bool debug_fiq_exec(struct fiq_debugger_state *state, } else if (!strcmp(cmd, "bt")) { dump_stacktrace(state, (struct pt_regs *)regs, 100, svc_sp); } else if (!strcmp(cmd, "reboot")) { - arch_reset(0, 0); + kernel_restart(NULL); } else if (!strcmp(cmd, "irqs")) { dump_irqs(state); } else if (!strcmp(cmd, "kmsg")) { -- cgit v1.2.3 From a09e9e5ca6fe8b3b99f85fc927214a8054629842 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 14 Mar 2012 16:29:47 -0700 Subject: ARM: fiq_debugger: add support for reboot commands Pass the rest of the reboot command to kernel_restart to allow reboot bootloader to work from FIQ debugger. Change-Id: I4e7b366a69268dda17ffcf4c84f2373d15cb1271 Signed-off-by: Colin Cross --- arch/arm/common/fiq_debugger.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/arch/arm/common/fiq_debugger.c b/arch/arm/common/fiq_debugger.c index 0e33748edd6..3f75495fab0 100644 --- a/arch/arm/common/fiq_debugger.c +++ b/arch/arm/common/fiq_debugger.c @@ -592,8 +592,17 @@ static bool debug_fiq_exec(struct fiq_debugger_state *state, dump_allregs(state, regs); } else if (!strcmp(cmd, "bt")) { dump_stacktrace(state, (struct pt_regs *)regs, 100, svc_sp); - } else if (!strcmp(cmd, "reboot")) { - kernel_restart(NULL); + } else if (!strncmp(cmd, "reboot", 6)) { + cmd += 6; + while (*cmd == ' ') + cmd++; + if (*cmd) { + char tmp_cmd[32]; + strlcpy(tmp_cmd, cmd, sizeof(tmp_cmd)); + kernel_restart(tmp_cmd); + } else { + kernel_restart(NULL); + } } else if (!strcmp(cmd, "irqs")) { dump_irqs(state); } else if (!strcmp(cmd, "kmsg")) { -- cgit v1.2.3 From 3b69e2c043602f8d66a06d4f2ff344c9a3e0d2ec Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 15 Mar 2012 12:57:20 -0700 Subject: ARM: fiq_debugger: add debug_putc Convert all the calls to state->pdata->uart_putc to a debug_putc helper. Change-Id: Idc007bd170ff1b51d0325e238105ae0c86d23777 Signed-off-by: Colin Cross --- arch/arm/common/fiq_debugger.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/arch/arm/common/fiq_debugger.c b/arch/arm/common/fiq_debugger.c index 3f75495fab0..909ef56596e 100644 --- a/arch/arm/common/fiq_debugger.c +++ b/arch/arm/common/fiq_debugger.c @@ -174,13 +174,18 @@ static void debug_uart_flush(struct fiq_debugger_state *state) state->pdata->uart_flush(state->pdev); } +static void debug_putc(struct fiq_debugger_state *state, char c) +{ + state->pdata->uart_putc(state->pdev, c); +} + static void debug_puts(struct fiq_debugger_state *state, char *s) { unsigned c; while ((c = *s++)) { if (c == '\n') - state->pdata->uart_putc(state->pdev, '\r'); - state->pdata->uart_putc(state->pdev, c); + debug_putc(state, '\r'); + debug_putc(state, c); } } @@ -777,19 +782,19 @@ static bool debug_handle_uart_interrupt(struct fiq_debugger_state *state, } else if ((c >= ' ') && (c < 127)) { if (state->debug_count < (DEBUG_MAX - 1)) { state->debug_buf[state->debug_count++] = c; - state->pdata->uart_putc(state->pdev, c); + debug_putc(state, c); } } else if ((c == 8) || (c == 127)) { if (state->debug_count > 0) { state->debug_count--; - state->pdata->uart_putc(state->pdev, 8); - state->pdata->uart_putc(state->pdev, ' '); - state->pdata->uart_putc(state->pdev, 8); + debug_putc(state, 8); + debug_putc(state, ' '); + debug_putc(state, 8); } } else if ((c == 13) || (c == 10)) { if (c == '\r' || (c == '\n' && last_c != '\r')) { - state->pdata->uart_putc(state->pdev, '\r'); - state->pdata->uart_putc(state->pdev, '\n'); + debug_putc(state, '\r'); + debug_putc(state, '\n'); } if (state->debug_count) { state->debug_buf[state->debug_count] = 0; @@ -898,8 +903,8 @@ static void debug_console_write(struct console *co, debug_uart_enable(state); while (count--) { if (*s == '\n') - state->pdata->uart_putc(state->pdev, '\r'); - state->pdata->uart_putc(state->pdev, *s++); + debug_putc(state, '\r'); + debug_putc(state, *s++); } debug_uart_flush(state); debug_uart_disable(state); @@ -941,7 +946,7 @@ int fiq_tty_write(struct tty_struct *tty, const unsigned char *buf, int count) debug_uart_enable(state); for (i = 0; i < count; i++) - state->pdata->uart_putc(state->pdev, *buf++); + debug_putc(state, *buf++); debug_uart_disable(state); return count; -- cgit v1.2.3 From 4a8d92b38f1e6f21881bf7a6c83aaaf336edde78 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 14 Mar 2012 19:23:29 -0700 Subject: ARM: fiq_debugger: add support for kgdb Adds polling tty ops to the fiq debugger console tty, which allows kgdb to run against an fiq debugger console. Add a check in do_sysrq to prevent enabling kgdb from the fiq debugger unless a flag (writable only by root) has been set. This should make it safe to enable KGDB on a production device. Also add a shortcut to enable the console and kgdb together, to allow kgdb to be enabled when the shell on the console is not responding. Change-Id: Ifc65239ca96c9887431a6a36b9b44a539002f544 Signed-off-by: Colin Cross --- arch/arm/common/fiq_debugger.c | 73 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/arch/arm/common/fiq_debugger.c b/arch/arm/common/fiq_debugger.c index 909ef56596e..1f64d7dc83b 100644 --- a/arch/arm/common/fiq_debugger.c +++ b/arch/arm/common/fiq_debugger.c @@ -106,9 +106,12 @@ static bool initial_debug_enable; static bool initial_console_enable; #endif +static bool fiq_kgdb_enable; + module_param_named(no_sleep, initial_no_sleep, bool, 0644); module_param_named(debug_enable, initial_debug_enable, bool, 0644); module_param_named(console_enable, initial_console_enable, bool, 0644); +module_param_named(kgdb_enable, fiq_kgdb_enable, bool, 0644); #ifdef CONFIG_FIQ_DEBUGGER_WAKEUP_IRQ_ALWAYS_ON static inline void enable_wakeup_irq(struct fiq_debugger_state *state) {} @@ -526,11 +529,29 @@ static void end_syslog_dump(struct fiq_debugger_state *state) static void do_sysrq(struct fiq_debugger_state *state, char rq) { + if ((rq == 'g' || rq == 'G') && !fiq_kgdb_enable) { + debug_printf(state, "sysrq-g blocked\n"); + return; + } begin_syslog_dump(state); handle_sysrq(rq); end_syslog_dump(state); } +#ifdef CONFIG_KGDB +static void do_kgdb(struct fiq_debugger_state *state) +{ + if (!fiq_kgdb_enable) { + debug_printf(state, "kgdb through fiq debugger not enabled\n"); + return; + } + + debug_printf(state, "enabling console and triggering kgdb\n"); + state->console_enable = true; + handle_sysrq('g'); +} +#endif + /* This function CANNOT be called in FIQ context */ static void debug_irq_exec(struct fiq_debugger_state *state, char *cmd) { @@ -540,6 +561,10 @@ static void debug_irq_exec(struct fiq_debugger_state *state, char *cmd) do_sysrq(state, 'h'); if (!strncmp(cmd, "sysrq ", 6)) do_sysrq(state, cmd[6]); +#ifdef CONFIG_KGDB + if (!strcmp(cmd, "kgdb")) + do_kgdb(state); +#endif } static void debug_help(struct fiq_debugger_state *state) @@ -561,6 +586,9 @@ static void debug_help(struct fiq_debugger_state *state) debug_printf(state, " ps Process list\n" " sysrq sysrq options\n" " sysrq Execute sysrq with \n"); +#ifdef CONFIG_KGDB + debug_printf(state, " kgdb Enter kernel debugger\n"); +#endif } static void take_affinity(void *info) @@ -724,7 +752,8 @@ static void debug_handle_irq_context(struct fiq_debugger_state *state) #endif if (state->debug_busy) { debug_irq_exec(state, state->debug_cmd); - debug_prompt(state); + if (!state->console_enable) + debug_prompt(state); state->debug_busy = 0; } } @@ -957,11 +986,53 @@ int fiq_tty_write_room(struct tty_struct *tty) return 1024; } +#ifdef CONFIG_CONSOLE_POLL +static int fiq_tty_poll_init(struct tty_driver *driver, int line, char *options) +{ + return 0; +} + +static int fiq_tty_poll_get_char(struct tty_driver *driver, int line) +{ + struct fiq_debugger_state *state = driver->ttys[line]->driver_data; + int c = NO_POLL_CHAR; + + debug_uart_enable(state); + if (debug_have_fiq(state)) { + int count = fiq_debugger_ringbuf_level(state->tty_rbuf); + if (count > 0) { + c = fiq_debugger_ringbuf_peek(state->tty_rbuf, 0); + fiq_debugger_ringbuf_consume(state->tty_rbuf, 1); + } + } else { + c = debug_getc(state); + if (c == FIQ_DEBUGGER_NO_CHAR) + c = NO_POLL_CHAR; + } + debug_uart_disable(state); + + return c; +} + +static void fiq_tty_poll_put_char(struct tty_driver *driver, int line, char ch) +{ + struct fiq_debugger_state *state = driver->ttys[line]->driver_data; + debug_uart_enable(state); + debug_putc(state, ch); + debug_uart_disable(state); +} +#endif + static const struct tty_operations fiq_tty_driver_ops = { .write = fiq_tty_write, .write_room = fiq_tty_write_room, .open = fiq_tty_open, .close = fiq_tty_close, +#ifdef CONFIG_CONSOLE_POLL + .poll_init = fiq_tty_poll_init, + .poll_get_char = fiq_tty_poll_get_char, + .poll_put_char = fiq_tty_poll_put_char, +#endif }; static int fiq_debugger_tty_init(struct fiq_debugger_state *state) -- cgit v1.2.3 From 04172d07afdfc963a588cb792acd297ae1f25223 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 14 Mar 2012 19:26:53 -0700 Subject: kdb: support new lines without carriage returns kdb expects carriage returns through the serial port to terminate commands. Modify it to accept the first seen carriage return or new line as a terminator, but not treat \r\n as two terminators. Change-Id: I06166017e7703d24310eefcb71c3a7d427088db7 Signed-off-by: Colin Cross --- kernel/debug/kdb/kdb_io.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/kernel/debug/kdb/kdb_io.c b/kernel/debug/kdb/kdb_io.c index 4802eb5840e..37066f06698 100644 --- a/kernel/debug/kdb/kdb_io.c +++ b/kernel/debug/kdb/kdb_io.c @@ -216,7 +216,7 @@ static char *kdb_read(char *buffer, size_t bufsize) int i; int diag, dtab_count; int key; - + static int last_crlf; diag = kdbgetintenv("DTABCOUNT", &dtab_count); if (diag) @@ -237,6 +237,9 @@ poll_again: return buffer; if (key != 9) tab = 0; + if (key != 10 && key != 13) + last_crlf = 0; + switch (key) { case 8: /* backspace */ if (cp > buffer) { @@ -254,7 +257,12 @@ poll_again: *cp = tmp; } break; - case 13: /* enter */ + case 10: /* new line */ + case 13: /* carriage return */ + /* handle \n after \r */ + if (last_crlf && last_crlf != key) + break; + last_crlf = key; *lastchar++ = '\n'; *lastchar++ = '\0'; if (!KDB_STATE(KGDB_TRANS)) { -- cgit v1.2.3 From 10c41e43e1703e11ebbf4707af3174850163024b Mon Sep 17 00:00:00 2001 From: Dmitry Shmidt Date: Fri, 16 Mar 2012 12:52:00 -0700 Subject: net: wireless: bcmdhd: Update to version 6.10.67.2 Signed-off-by: Dmitry Shmidt --- drivers/net/wireless/bcmdhd/Kconfig | 9 +- drivers/net/wireless/bcmdhd/Makefile | 28 +- drivers/net/wireless/bcmdhd/aiutils.c | 184 +- drivers/net/wireless/bcmdhd/bcmevent.c | 17 +- drivers/net/wireless/bcmdhd/bcmsdh.c | 42 +- drivers/net/wireless/bcmdhd/bcmsdh_linux.c | 29 +- drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c | 35 +- drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c | 48 +- drivers/net/wireless/bcmdhd/bcmutils.c | 616 +- drivers/net/wireless/bcmdhd/bcmwifi.c | 668 +- drivers/net/wireless/bcmdhd/dhd.h | 43 +- drivers/net/wireless/bcmdhd/dhd_bta.h | 6 +- drivers/net/wireless/bcmdhd/dhd_bus.h | 13 +- drivers/net/wireless/bcmdhd/dhd_cdc.c | 601 +- drivers/net/wireless/bcmdhd/dhd_cfg80211.c | 5 +- drivers/net/wireless/bcmdhd/dhd_cfg80211.h | 4 +- drivers/net/wireless/bcmdhd/dhd_common.c | 98 +- drivers/net/wireless/bcmdhd/dhd_custom_gpio.c | 10 +- drivers/net/wireless/bcmdhd/dhd_dbg.h | 11 +- drivers/net/wireless/bcmdhd/dhd_linux.c | 406 +- drivers/net/wireless/bcmdhd/dhd_linux_sched.c | 6 +- drivers/net/wireless/bcmdhd/dhd_proto.h | 14 +- drivers/net/wireless/bcmdhd/dhd_sdio.c | 847 +- drivers/net/wireless/bcmdhd/dhd_wlfc.h | 8 +- drivers/net/wireless/bcmdhd/dngl_stats.h | 6 +- drivers/net/wireless/bcmdhd/dngl_wlhdr.h | 6 +- drivers/net/wireless/bcmdhd/hndpmu.c | 7 +- drivers/net/wireless/bcmdhd/include/Makefile | 2 +- drivers/net/wireless/bcmdhd/include/aidmp.h | 10 +- .../wireless/bcmdhd/include/bcm_android_types.h | 44 + drivers/net/wireless/bcmdhd/include/bcm_cfg.h | 29 + .../net/wireless/bcmdhd/include/bcm_mpool_pub.h | 361 + drivers/net/wireless/bcmdhd/include/bcmcdc.h | 54 +- drivers/net/wireless/bcmdhd/include/bcmdefs.h | 58 +- drivers/net/wireless/bcmdhd/include/bcmdevs.h | 386 +- drivers/net/wireless/bcmdhd/include/bcmendian.h | 7 +- drivers/net/wireless/bcmdhd/include/bcmnvram.h | 136 + drivers/net/wireless/bcmdhd/include/bcmpcispi.h | 6 +- drivers/net/wireless/bcmdhd/include/bcmperf.h | 6 +- drivers/net/wireless/bcmdhd/include/bcmsdbus.h | 9 +- drivers/net/wireless/bcmdhd/include/bcmsdh.h | 31 +- drivers/net/wireless/bcmdhd/include/bcmsdh_sdmmc.h | 6 +- drivers/net/wireless/bcmdhd/include/bcmsdpcm.h | 6 +- drivers/net/wireless/bcmdhd/include/bcmsdspi.h | 6 +- drivers/net/wireless/bcmdhd/include/bcmsdstd.h | 8 +- drivers/net/wireless/bcmdhd/include/bcmspi.h | 6 +- drivers/net/wireless/bcmdhd/include/bcmspibrcm.h | 139 + drivers/net/wireless/bcmdhd/include/bcmsrom_fmt.h | 554 ++ drivers/net/wireless/bcmdhd/include/bcmsrom_tbl.h | 837 ++ drivers/net/wireless/bcmdhd/include/bcmutils.h | 157 +- drivers/net/wireless/bcmdhd/include/bcmwifi.h | 210 +- drivers/net/wireless/bcmdhd/include/dbus.h | 568 ++ drivers/net/wireless/bcmdhd/include/dhdioctl.h | 8 +- drivers/net/wireless/bcmdhd/include/epivers.h | 23 +- drivers/net/wireless/bcmdhd/include/hndpmu.h | 8 +- .../net/wireless/bcmdhd/include/hndrte_armtrap.h | 38 +- drivers/net/wireless/bcmdhd/include/hndrte_cons.h | 7 +- drivers/net/wireless/bcmdhd/include/hndsoc.h | 36 +- drivers/net/wireless/bcmdhd/include/linux_osl.h | 95 +- drivers/net/wireless/bcmdhd/include/linuxver.h | 29 +- drivers/net/wireless/bcmdhd/include/miniopt.h | 6 +- drivers/net/wireless/bcmdhd/include/msgtrace.h | 8 +- drivers/net/wireless/bcmdhd/include/osl.h | 13 +- .../wireless/bcmdhd/include/packed_section_end.h | 7 +- .../wireless/bcmdhd/include/packed_section_start.h | 9 +- drivers/net/wireless/bcmdhd/include/pcicfg.h | 54 +- drivers/net/wireless/bcmdhd/include/proto/802.11.h | 2282 ++--- .../net/wireless/bcmdhd/include/proto/802.11_bta.h | 6 +- .../net/wireless/bcmdhd/include/proto/802.11e.h | 6 +- drivers/net/wireless/bcmdhd/include/proto/802.1d.h | 7 +- drivers/net/wireless/bcmdhd/include/proto/bcmeth.h | 7 +- .../net/wireless/bcmdhd/include/proto/bcmevent.h | 49 +- drivers/net/wireless/bcmdhd/include/proto/bcmip.h | 64 +- .../net/wireless/bcmdhd/include/proto/bcmipv6.h | 104 + .../net/wireless/bcmdhd/include/proto/bt_amp_hci.h | 7 +- drivers/net/wireless/bcmdhd/include/proto/eapol.h | 26 +- .../net/wireless/bcmdhd/include/proto/ethernet.h | 25 +- drivers/net/wireless/bcmdhd/include/proto/p2p.h | 634 +- drivers/net/wireless/bcmdhd/include/proto/sdspi.h | 7 +- drivers/net/wireless/bcmdhd/include/proto/vlan.h | 7 +- drivers/net/wireless/bcmdhd/include/proto/wpa.h | 45 +- drivers/net/wireless/bcmdhd/include/proto/wps.h | 379 + drivers/net/wireless/bcmdhd/include/rwl_wifi.h | 96 + drivers/net/wireless/bcmdhd/include/sbchipc.h | 498 +- drivers/net/wireless/bcmdhd/include/sbconfig.h | 7 +- drivers/net/wireless/bcmdhd/include/sbhnddma.h | 67 +- drivers/net/wireless/bcmdhd/include/sbpcmcia.h | 7 +- drivers/net/wireless/bcmdhd/include/sbsdio.h | 27 +- drivers/net/wireless/bcmdhd/include/sbsdpcmdev.h | 6 +- drivers/net/wireless/bcmdhd/include/sbsocram.h | 31 +- drivers/net/wireless/bcmdhd/include/sdio.h | 15 +- drivers/net/wireless/bcmdhd/include/sdioh.h | 7 +- drivers/net/wireless/bcmdhd/include/sdiovar.h | 6 +- drivers/net/wireless/bcmdhd/include/siutils.h | 55 +- drivers/net/wireless/bcmdhd/include/spid.h | 153 + drivers/net/wireless/bcmdhd/include/trxhdr.h | 18 +- drivers/net/wireless/bcmdhd/include/typedefs.h | 10 +- drivers/net/wireless/bcmdhd/include/usbrdl.h | 203 + .../net/wireless/bcmdhd/include/wlc_clm_rates.h | 255 + .../net/wireless/bcmdhd/include/wlc_extlog_idstr.h | 117 + drivers/net/wireless/bcmdhd/include/wlfc_proto.h | 46 +- drivers/net/wireless/bcmdhd/include/wlioctl.h | 5489 +++++++---- drivers/net/wireless/bcmdhd/linux_osl.c | 289 +- drivers/net/wireless/bcmdhd/sbutils.c | 15 +- drivers/net/wireless/bcmdhd/siutils.c | 598 +- drivers/net/wireless/bcmdhd/siutils_priv.h | 31 +- drivers/net/wireless/bcmdhd/wl_android.c | 102 +- drivers/net/wireless/bcmdhd/wl_android.h | 12 +- drivers/net/wireless/bcmdhd/wl_cfg80211.c | 853 +- drivers/net/wireless/bcmdhd/wl_cfg80211.h | 23 +- drivers/net/wireless/bcmdhd/wl_cfgp2p.c | 118 +- drivers/net/wireless/bcmdhd/wl_cfgp2p.h | 15 +- drivers/net/wireless/bcmdhd/wl_dbg.h | 30 +- drivers/net/wireless/bcmdhd/wl_iw.c | 9580 +++++--------------- drivers/net/wireless/bcmdhd/wl_iw.h | 214 +- drivers/net/wireless/bcmdhd/wl_linux_mon.c | 26 +- drivers/net/wireless/bcmdhd/wldev_common.c | 14 +- drivers/net/wireless/bcmdhd/wldev_common.h | 4 +- 118 files changed, 17332 insertions(+), 13104 deletions(-) create mode 100644 drivers/net/wireless/bcmdhd/include/bcm_android_types.h create mode 100644 drivers/net/wireless/bcmdhd/include/bcm_cfg.h create mode 100644 drivers/net/wireless/bcmdhd/include/bcm_mpool_pub.h create mode 100644 drivers/net/wireless/bcmdhd/include/bcmnvram.h create mode 100644 drivers/net/wireless/bcmdhd/include/bcmspibrcm.h create mode 100644 drivers/net/wireless/bcmdhd/include/bcmsrom_fmt.h create mode 100644 drivers/net/wireless/bcmdhd/include/bcmsrom_tbl.h create mode 100644 drivers/net/wireless/bcmdhd/include/dbus.h create mode 100644 drivers/net/wireless/bcmdhd/include/proto/bcmipv6.h create mode 100644 drivers/net/wireless/bcmdhd/include/proto/wps.h create mode 100644 drivers/net/wireless/bcmdhd/include/rwl_wifi.h create mode 100644 drivers/net/wireless/bcmdhd/include/spid.h create mode 100644 drivers/net/wireless/bcmdhd/include/usbrdl.h create mode 100644 drivers/net/wireless/bcmdhd/include/wlc_clm_rates.h create mode 100644 drivers/net/wireless/bcmdhd/include/wlc_extlog_idstr.h diff --git a/drivers/net/wireless/bcmdhd/Kconfig b/drivers/net/wireless/bcmdhd/Kconfig index 205c813681a..231ae187f40 100644 --- a/drivers/net/wireless/bcmdhd/Kconfig +++ b/drivers/net/wireless/bcmdhd/Kconfig @@ -37,4 +37,11 @@ config DHD_USE_STATIC_BUF depends on BCMDHD default n ---help--- - Use memory preallocated in platform \ No newline at end of file + Use memory preallocated in platform + +config DHD_USE_SCHED_SCAN + bool "Use CFG80211 sched scan" + depends on BCMDHD && CFG80211 + default n + ---help--- + Use CFG80211 sched scan diff --git a/drivers/net/wireless/bcmdhd/Makefile b/drivers/net/wireless/bcmdhd/Makefile index 17f07ca3a30..96c38733056 100644 --- a/drivers/net/wireless/bcmdhd/Makefile +++ b/drivers/net/wireless/bcmdhd/Makefile @@ -1,28 +1,36 @@ # bcmdhd +# -DDHDTHREAD -DDHD_GPL -DDHD_SCHED -DDHD_DEBUG -DSDTEST -DBDC -DTOE \ +# -DDHD_BCMEVENTS -DSHOW_EVENTS -DDONGLEOVERLAYS -DBCMDBG \ +# -DCUSTOMER_HW2 -DOOB_INTR_ONLY -DHW_OOB \ +# -DMMC_SDIO_ABORT -DBCMSDIO -DBCMLXSDMMC -DBCMPLATFORM_BUS -DWLP2P \ +# -DNEW_COMPAT_WIRELESS -DWIFI_ACT_FRAME -DARP_OFFLOAD_SUPPORT \ +# -DKEEP_ALIVE -DCSCAN -DGET_CUSTOM_MAC_ENABLE -DPKT_FILTER_SUPPORT \ +# -DEMBEDDED_PLATFORM -DENABLE_INSMOD_NO_FW_LOAD -DPNO_SUPPORT \ + DHDCFLAGS = -Wall -Wstrict-prototypes -Dlinux -DBCMDRIVER \ - -DBCMDONGLEHOST -DUNRELEASEDCHIP -DBCMDMA32 -DWLBTAMP -DBCMFILEIMAGE \ - -DDHDTHREAD -DDHD_GPL -DDHD_SCHED -DDHD_DEBUG -DSDTEST -DBDC -DTOE \ - -DDHD_BCMEVENTS -DSHOW_EVENTS -DDONGLEOVERLAYS -DBCMDBG \ - -DCUSTOMER_HW2 -DCUSTOM_OOB_GPIO_NUM=2 -DOOB_INTR_ONLY -DHW_OOB \ + -DBCMDONGLEHOST -DUNRELEASEDCHIP -DBCMDMA32 -DBCMFILEIMAGE \ + -DDHDTHREAD -DDHD_DEBUG -DSDTEST -DBDC -DTOE \ + -DDHD_BCMEVENTS -DSHOW_EVENTS -DPROP_TXSTATUS -DBCMDBG \ + -DCUSTOMER_HW2 -DOOB_INTR_ONLY -DHW_OOB \ -DMMC_SDIO_ABORT -DBCMSDIO -DBCMLXSDMMC -DBCMPLATFORM_BUS -DWLP2P \ - -DNEW_COMPAT_WIRELESS -DWIFI_ACT_FRAME -DARP_OFFLOAD_SUPPORT \ - -DKEEP_ALIVE -DCSCAN -DGET_CUSTOM_MAC_ENABLE -DPKT_FILTER_SUPPORT \ + -DWIFI_ACT_FRAME -DARP_OFFLOAD_SUPPORT \ + -DKEEP_ALIVE -DGET_CUSTOM_MAC_ENABLE -DPKT_FILTER_SUPPORT \ -DEMBEDDED_PLATFORM -DENABLE_INSMOD_NO_FW_LOAD -DPNO_SUPPORT \ -Idrivers/net/wireless/bcmdhd -Idrivers/net/wireless/bcmdhd/include DHDOFILES = aiutils.o bcmsdh_sdmmc_linux.o dhd_linux.o siutils.o bcmutils.o \ - dhd_linux_sched.o bcmwifi.o dhd_sdio.o bcmevent.o dhd_bta.o hndpmu.o \ + dhd_linux_sched.o bcmwifi.o dhd_sdio.o bcmevent.o hndpmu.o \ bcmsdh.o dhd_cdc.o bcmsdh_linux.o dhd_common.o linux_osl.o \ - bcmsdh_sdmmc.o dhd_custom_gpio.o sbutils.o wldev_common.o wl_android.o dhd_cfg80211.o + bcmsdh_sdmmc.o dhd_custom_gpio.o sbutils.o wldev_common.o wl_android.o obj-$(CONFIG_BCMDHD) += bcmdhd.o bcmdhd-objs += $(DHDOFILES) ifneq ($(CONFIG_WIRELESS_EXT),) bcmdhd-objs += wl_iw.o -DHDCFLAGS += -DSOFTAP +DHDCFLAGS += -DSOFTAP -DUSE_IW endif ifneq ($(CONFIG_CFG80211),) -bcmdhd-objs += wl_cfg80211.o wl_cfgp2p.o wl_linux_mon.o +bcmdhd-objs += wl_cfg80211.o wl_cfgp2p.o wl_linux_mon.o dhd_cfg80211.o DHDCFLAGS += -DWL_CFG80211 endif EXTRA_CFLAGS = $(DHDCFLAGS) diff --git a/drivers/net/wireless/bcmdhd/aiutils.c b/drivers/net/wireless/bcmdhd/aiutils.c index 059df890792..4361a44774a 100644 --- a/drivers/net/wireless/bcmdhd/aiutils.c +++ b/drivers/net/wireless/bcmdhd/aiutils.c @@ -2,9 +2,9 @@ * Misc utility routines for accessing chip-specific features * of the SiliconBackplane-based Broadcom chips. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -22,10 +22,9 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: aiutils.c,v 1.26.2.1 2010-03-09 18:41:21 Exp $ + * $Id: aiutils.c 309193 2012-01-19 00:03:57Z $ */ - - +#include #include #include #include @@ -37,7 +36,10 @@ #include "siutils_priv.h" - +#define BCM47162_DMP() (0) +#define BCM5357_DMP() (0) +#define remap_coreid(sih, coreid) (coreid) +#define remap_corerev(sih, corerev) (corerev) @@ -116,6 +118,7 @@ ai_hwfixup(si_info_t *sii) } + void ai_scan(si_t *sih, void *regs, uint devid) { @@ -157,7 +160,6 @@ ai_scan(si_t *sih, void *regs, uint devid) while (eromptr < eromlim) { uint32 cia, cib, cid, mfg, crev, nmw, nsw, nmp, nsp; uint32 mpd, asd, addrl, addrh, sizel, sizeh; - uint32 *base; uint i, j, idx; bool br; @@ -170,7 +172,7 @@ ai_scan(si_t *sih, void *regs, uint devid) ai_hwfixup(sii); return; } - base = eromptr - 1; + cib = get_erom_ent(sih, &eromptr, 0, 0); if ((cib & ER_TAG) != ER_CI) { @@ -186,9 +188,13 @@ ai_scan(si_t *sih, void *regs, uint devid) nmp = (cib & CIB_NMP_MASK) >> CIB_NMP_SHIFT; nsp = (cib & CIB_NSP_MASK) >> CIB_NSP_SHIFT; +#ifdef BCMDBG_SI SI_VMSG(("Found component 0x%04x/0x%04x rev %d at erom addr 0x%p, with nmw = %d, " "nsw = %d, nmp = %d & nsp = %d\n", - mfg, cid, crev, base, nmw, nsw, nmp, nsp)); + mfg, cid, crev, eromptr - 1, nmw, nsw, nmp, nsp)); +#else + BCM_REFERENCE(crev); +#endif if (((mfg == MFGID_ARM) && (cid == DEF_AI_COMP)) || (nsp == 0)) continue; @@ -201,14 +207,15 @@ ai_scan(si_t *sih, void *regs, uint devid) sii->oob_router = addrl; } } - continue; + if (cid != GMAC_COMMON_4706_CORE_ID) + continue; } idx = sii->numcores; sii->cia[idx] = cia; sii->cib[idx] = cib; - sii->coreid[idx] = cid; + sii->coreid[idx] = remap_coreid(sih, cid); for (i = 0; i < nmp; i++) { mpd = get_erom_ent(sih, &eromptr, ER_VALID, ER_VALID); @@ -254,9 +261,13 @@ ai_scan(si_t *sih, void *regs, uint devid) for (i = 1; i < nsp; i++) { j = 0; do { - asd = get_asd(sih, &eromptr, i, j++, AD_ST_SLAVE, &addrl, &addrh, + asd = get_asd(sih, &eromptr, i, j, AD_ST_SLAVE, &addrl, &addrh, &sizel, &sizeh); - } while (asd != 0); + + if (asd == 0) + break; + j++; + } while (1); if (j == 0) { SI_ERROR((" SP %d has no address descriptors\n", i)); goto error; @@ -296,6 +307,7 @@ ai_scan(si_t *sih, void *regs, uint devid) sii->wrapba[idx] = addrl; } + if (br) continue; @@ -316,13 +328,15 @@ void * ai_setcoreidx(si_t *sih, uint coreidx) { si_info_t *sii = SI_INFO(sih); - uint32 addr = sii->coresba[coreidx]; - uint32 wrap = sii->wrapba[coreidx]; + uint32 addr, wrap; void *regs; - if (coreidx >= sii->numcores) + if (coreidx >= MIN(sii->numcores, SI_MAXCORES)) return (NULL); + addr = sii->coresba[coreidx]; + wrap = sii->wrapba[coreidx]; + ASSERT((sii->intrsenabled_fn == NULL) || !(*(sii)->intrsenabled_fn)((sii)->intr_arg)); @@ -361,6 +375,91 @@ ai_setcoreidx(si_t *sih, uint coreidx) return regs; } +void +ai_coreaddrspaceX(si_t *sih, uint asidx, uint32 *addr, uint32 *size) +{ + si_info_t *sii = SI_INFO(sih); + chipcregs_t *cc = NULL; + uint32 erombase, *eromptr, *eromlim; + uint i, j, cidx; + uint32 cia, cib, nmp, nsp; + uint32 asd, addrl, addrh, sizel, sizeh; + + for (i = 0; i < sii->numcores; i++) { + if (sii->coreid[i] == CC_CORE_ID) { + cc = (chipcregs_t *)sii->regs[i]; + break; + } + } + if (cc == NULL) + goto error; + + erombase = R_REG(sii->osh, &cc->eromptr); + eromptr = (uint32 *)REG_MAP(erombase, SI_CORE_SIZE); + eromlim = eromptr + (ER_REMAPCONTROL / sizeof(uint32)); + + cidx = sii->curidx; + cia = sii->cia[cidx]; + cib = sii->cib[cidx]; + + nmp = (cib & CIB_NMP_MASK) >> CIB_NMP_SHIFT; + nsp = (cib & CIB_NSP_MASK) >> CIB_NSP_SHIFT; + + + while (eromptr < eromlim) { + if ((get_erom_ent(sih, &eromptr, ER_TAG, ER_CI) == cia) && + (get_erom_ent(sih, &eromptr, 0, 0) == cib)) { + break; + } + } + + + for (i = 0; i < nmp; i++) + get_erom_ent(sih, &eromptr, ER_VALID, ER_VALID); + + + asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, &addrl, &addrh, &sizel, &sizeh); + if (asd == 0) { + + asd = get_asd(sih, &eromptr, 0, 0, AD_ST_BRIDGE, &addrl, &addrh, + &sizel, &sizeh); + } + + j = 1; + do { + asd = get_asd(sih, &eromptr, 0, j, AD_ST_SLAVE, &addrl, &addrh, + &sizel, &sizeh); + j++; + } while (asd != 0); + + + for (i = 1; i < nsp; i++) { + j = 0; + do { + asd = get_asd(sih, &eromptr, i, j, AD_ST_SLAVE, &addrl, &addrh, + &sizel, &sizeh); + if (asd == 0) + break; + + if (!asidx--) { + *addr = addrl; + *size = sizel; + return; + } + j++; + } while (1); + + if (j == 0) { + SI_ERROR((" SP %d has no address descriptors\n", i)); + break; + } + } + +error: + *size = 0; + return; +} + int ai_numaddrspaces(si_t *sih) @@ -417,6 +516,14 @@ ai_flag(si_t *sih) aidmp_t *ai; sii = SI_INFO(sih); + if (BCM47162_DMP()) { + SI_ERROR(("%s: Attempting to read MIPS DMP registers on 47162a0", __FUNCTION__)); + return sii->curidx; + } + if (BCM5357_DMP()) { + SI_ERROR(("%s: Attempting to read USB20H DMP registers on 5357b0\n", __FUNCTION__)); + return sii->curidx; + } ai = sii->curwrap; return (R_REG(sii->osh, &ai->oobselouta30) & 0x1f); @@ -462,7 +569,7 @@ ai_corerev(si_t *sih) sii = SI_INFO(sih); cib = sii->cib[sii->curidx]; - return ((cib & CIB_REV_MASK) >> CIB_REV_SHIFT); + return remap_corerev(sih, (cib & CIB_REV_MASK) >> CIB_REV_SHIFT); } bool @@ -579,9 +686,12 @@ ai_core_disable(si_t *sih, uint32 bits) W_REG(sii->osh, &ai->ioctrl, bits); dummy = R_REG(sii->osh, &ai->ioctrl); + BCM_REFERENCE(dummy); OSL_DELAY(10); W_REG(sii->osh, &ai->resetctrl, AIRC_RESET); + dummy = R_REG(sii->osh, &ai->resetctrl); + BCM_REFERENCE(dummy); OSL_DELAY(1); } @@ -603,15 +713,19 @@ ai_core_reset(si_t *sih, uint32 bits, uint32 resetbits) W_REG(sii->osh, &ai->ioctrl, (bits | SICF_FGC | SICF_CLOCK_EN)); dummy = R_REG(sii->osh, &ai->ioctrl); + BCM_REFERENCE(dummy); + W_REG(sii->osh, &ai->resetctrl, 0); + dummy = R_REG(sii->osh, &ai->resetctrl); + BCM_REFERENCE(dummy); OSL_DELAY(1); W_REG(sii->osh, &ai->ioctrl, (bits | SICF_CLOCK_EN)); dummy = R_REG(sii->osh, &ai->ioctrl); + BCM_REFERENCE(dummy); OSL_DELAY(1); } - void ai_core_cflags_wo(si_t *sih, uint32 mask, uint32 val) { @@ -620,6 +734,18 @@ ai_core_cflags_wo(si_t *sih, uint32 mask, uint32 val) uint32 w; sii = SI_INFO(sih); + + if (BCM47162_DMP()) { + SI_ERROR(("%s: Accessing MIPS DMP register (ioctrl) on 47162a0", + __FUNCTION__)); + return; + } + if (BCM5357_DMP()) { + SI_ERROR(("%s: Accessing USB20H DMP register (ioctrl) on 5357\n", + __FUNCTION__)); + return; + } + ASSERT(GOODREGS(sii->curwrap)); ai = sii->curwrap; @@ -639,6 +765,17 @@ ai_core_cflags(si_t *sih, uint32 mask, uint32 val) uint32 w; sii = SI_INFO(sih); + if (BCM47162_DMP()) { + SI_ERROR(("%s: Accessing MIPS DMP register (ioctrl) on 47162a0", + __FUNCTION__)); + return 0; + } + if (BCM5357_DMP()) { + SI_ERROR(("%s: Accessing USB20H DMP register (ioctrl) on 5357\n", + __FUNCTION__)); + return 0; + } + ASSERT(GOODREGS(sii->curwrap)); ai = sii->curwrap; @@ -660,6 +797,17 @@ ai_core_sflags(si_t *sih, uint32 mask, uint32 val) uint32 w; sii = SI_INFO(sih); + if (BCM47162_DMP()) { + SI_ERROR(("%s: Accessing MIPS DMP register (iostatus) on 47162a0", + __FUNCTION__)); + return 0; + } + if (BCM5357_DMP()) { + SI_ERROR(("%s: Accessing USB20H DMP register (iostatus) on 5357\n", + __FUNCTION__)); + return 0; + } + ASSERT(GOODREGS(sii->curwrap)); ai = sii->curwrap; diff --git a/drivers/net/wireless/bcmdhd/bcmevent.c b/drivers/net/wireless/bcmdhd/bcmevent.c index 6a25d9a5a57..3d805d0b838 100644 --- a/drivers/net/wireless/bcmdhd/bcmevent.c +++ b/drivers/net/wireless/bcmdhd/bcmevent.c @@ -1,9 +1,9 @@ /* * bcmevent read-only data shared by kernel or app layers * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -20,7 +20,7 @@ * Notwithstanding the above, under no circumstances may you combine this * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. - * $Id: bcmevent.c,v 1.8.2.7 2011-02-01 06:23:39 $ + * $Id: bcmevent.c 300516 2011-12-04 17:39:44Z $ */ #include @@ -29,7 +29,7 @@ #include #include -#if WLC_E_LAST != 87 +#if WLC_E_LAST != 89 #error "You need to add an entry to bcmevent_names[] for the new event" #endif @@ -83,7 +83,9 @@ const bcmevent_name_t bcmevent_names[] = { { WLC_E_UNICAST_DECODE_ERROR, "UNICAST_DECODE_ERROR" }, { WLC_E_MULTICAST_DECODE_ERROR, "MULTICAST_DECODE_ERROR" }, { WLC_E_TRACE, "TRACE" }, +#ifdef WLBTAMP { WLC_E_BTA_HCI_EVENT, "BTA_HCI_EVENT" }, +#endif { WLC_E_IF, "IF" }, #ifdef WLP2P { WLC_E_P2P_DISC_LISTEN_COMPLETE, "WLC_E_P2P_DISC_LISTEN_COMPLETE" }, @@ -96,6 +98,10 @@ const bcmevent_name_t bcmevent_names[] = { { WLC_E_ACTION_FRAME_RX, "ACTION_FRAME_RX" }, { WLC_E_ACTION_FRAME_COMPLETE, "ACTION_FRAME_COMPLETE" }, #endif +#ifdef BCMWAPI_WAI + { WLC_E_WAI_STA_EVENT, "WAI_STA_EVENT" }, + { WLC_E_WAI_MSG, "WAI_MSG" }, +#endif /* BCMWAPI_WAI */ { WLC_E_ESCAN_RESULT, "WLC_E_ESCAN_RESULT" }, { WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE, "WLC_E_AF_OFF_CHAN_COMPLETE" }, #ifdef WLP2P @@ -112,7 +118,7 @@ const bcmevent_name_t bcmevent_names[] = { { WLC_E_HTSFSYNC, "HTSF_SYNC_EVENT" }, #endif { WLC_E_OVERLAY_REQ, "OVERLAY_REQ_EVENT" }, - { WLC_E_CSA_COMPLETE_IND, "WLC_E_CSA_COMPLETE_IND" }, + { WLC_E_CSA_COMPLETE_IND, "WLC_E_CSA_COMPLETE_IND"}, { WLC_E_EXCESS_PM_WAKE_EVENT, "EXCESS_PM_WAKE_EVENT" }, { WLC_E_PFN_SCAN_NONE, "PFN_SCAN_NONE" }, { WLC_E_PFN_SCAN_ALLGONE, "PFN_SCAN_ALLGONE" }, @@ -123,5 +129,4 @@ const bcmevent_name_t bcmevent_names[] = { { WLC_E_ASSOC_RESP_IE, "ASSOC_RESP_IE" } }; - const int bcmevent_names_size = ARRAYSIZE(bcmevent_names); diff --git a/drivers/net/wireless/bcmdhd/bcmsdh.c b/drivers/net/wireless/bcmdhd/bcmsdh.c index 918c8e648f1..6e1a6b0e214 100644 --- a/drivers/net/wireless/bcmdhd/bcmsdh.c +++ b/drivers/net/wireless/bcmdhd/bcmsdh.c @@ -2,9 +2,9 @@ * BCMSDH interface glue * implement bcmsdh API for SDIOH driver * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -22,7 +22,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: bcmsdh.c 275784 2011-08-04 22:41:49Z $ + * $Id: bcmsdh.c 300445 2011-12-03 05:37:20Z $ */ /** @@ -688,3 +688,39 @@ bcmsdh_sleep(void *sdh, bool enab) return BCME_UNSUPPORTED; #endif } + +int +bcmsdh_gpio_init(void *sdh) +{ + bcmsdh_info_t *p = (bcmsdh_info_t *)sdh; + sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh); + + return sdioh_gpio_init(sd); +} + +bool +bcmsdh_gpioin(void *sdh, uint32 gpio) +{ + bcmsdh_info_t *p = (bcmsdh_info_t *)sdh; + sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh); + + return sdioh_gpioin(sd, gpio); +} + +int +bcmsdh_gpioouten(void *sdh, uint32 gpio) +{ + bcmsdh_info_t *p = (bcmsdh_info_t *)sdh; + sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh); + + return sdioh_gpioouten(sd, gpio); +} + +int +bcmsdh_gpioout(void *sdh, uint32 gpio, bool enab) +{ + bcmsdh_info_t *p = (bcmsdh_info_t *)sdh; + sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh); + + return sdioh_gpioout(sd, gpio, enab); +} diff --git a/drivers/net/wireless/bcmdhd/bcmsdh_linux.c b/drivers/net/wireless/bcmdhd/bcmsdh_linux.c index e01b6f8a2d4..9c9856ad75b 100644 --- a/drivers/net/wireless/bcmdhd/bcmsdh_linux.c +++ b/drivers/net/wireless/bcmdhd/bcmsdh_linux.c @@ -1,9 +1,9 @@ /* * SDIO access interface for drivers - linux specific (pci only) * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: bcmsdh_linux.c 308641 2012-01-17 02:18:02Z $ + * $Id: bcmsdh_linux.c 309796 2012-01-20 18:21:51Z $ */ /** @@ -512,6 +512,28 @@ bcmsdh_pci_remove(struct pci_dev *pdev) extern int sdio_function_init(void); +extern int sdio_func_reg_notify(void* semaphore); +extern void sdio_func_unreg_notify(void); + +int bcmsdh_reg_sdio_notify(void* semaphore) +{ + int ret = -1; + +#ifdef BCMLXSDMMC + ret = sdio_func_reg_notify(semaphore); +#endif + + return ret; +} + +void bcmsdh_unreg_sdio_notify(void) +{ +#ifdef BCMLXSDMMC + sdio_func_unreg_notify(); +#endif + +} + int bcmsdh_register(bcmsdh_driver_t *driver) { @@ -626,7 +648,6 @@ void *bcmsdh_get_drvdata(void) return NULL; return dev_get_drvdata(sdhcinfo->dev); } - void bcmsdh_set_irq(int flag) { if (sdhcinfo->oob_irq_registered && sdhcinfo->oob_irq_enable_flag != flag) { diff --git a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c index 6a8ff9431e9..23a1f96ddd7 100644 --- a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c +++ b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c @@ -1,9 +1,9 @@ /* * BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: bcmsdh_sdmmc.c 301794 2011-12-08 20:41:35Z $ + * $Id: bcmsdh_sdmmc.c 309548 2012-01-20 01:13:08Z $ */ #include @@ -1232,8 +1232,10 @@ sdioh_start(sdioh_info_t *si, int stage) 2.6.27. The implementation prior to that is buggy, and needs broadcom's patch for it */ - if ((ret = sdio_reset_comm(gInstance->func[0]->card))) + if ((ret = sdio_reset_comm(gInstance->func[0]->card))) { sd_err(("%s Failed, error = %d\n", __FUNCTION__, ret)); + return ret; + } else { sd->num_funcs = 2; sd->sd_blockmode = TRUE; @@ -1320,3 +1322,28 @@ sdioh_waitlockfree(sdioh_info_t *sd) { return (1); } + + +SDIOH_API_RC +sdioh_gpioouten(sdioh_info_t *sd, uint32 gpio) +{ + return SDIOH_API_RC_FAIL; +} + +SDIOH_API_RC +sdioh_gpioout(sdioh_info_t *sd, uint32 gpio, bool enab) +{ + return SDIOH_API_RC_FAIL; +} + +bool +sdioh_gpioin(sdioh_info_t *sd, uint32 gpio) +{ + return FALSE; +} + +SDIOH_API_RC +sdioh_gpio_init(sdioh_info_t *sd) +{ + return SDIOH_API_RC_FAIL; +} diff --git a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c index 83f4d3df671..30c7fd7e690 100644 --- a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c +++ b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c @@ -1,9 +1,9 @@ /* * BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: bcmsdh_sdmmc_linux.c 308645 2012-01-17 02:33:26Z $ + * $Id: bcmsdh_sdmmc_linux.c 309548 2012-01-20 01:13:08Z $ */ #include @@ -61,10 +61,14 @@ #if !defined(SDIO_DEVICE_ID_BROADCOM_4334) #define SDIO_DEVICE_ID_BROADCOM_4334 0x4334 #endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4334) */ +#if !defined(SDIO_DEVICE_ID_BROADCOM_4324) +#define SDIO_DEVICE_ID_BROADCOM_4324 0x4324 +#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4324) */ #if !defined(SDIO_DEVICE_ID_BROADCOM_43239) #define SDIO_DEVICE_ID_BROADCOM_43239 43239 #endif /* !defined(SDIO_DEVICE_ID_BROADCOM_43239) */ + #include #include @@ -98,7 +102,6 @@ PBCMSDH_SDMMC_INSTANCE gInstance; extern int bcmsdh_probe(struct device *dev); extern int bcmsdh_remove(struct device *dev); - extern volatile bool dhd_mmc_suspend; static int bcmsdh_sdmmc_probe(struct sdio_func *func, @@ -164,6 +167,7 @@ static const struct sdio_device_id bcmsdh_sdmmc_ids[] = { { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4319) }, { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330) }, { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334) }, + { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4324) }, { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43239) }, { SDIO_DEVICE_CLASS(SDIO_CLASS_NONE) }, { /* end: all zeroes */ }, @@ -213,6 +217,38 @@ static const struct dev_pm_ops bcmsdh_sdmmc_pm_ops = { }; #endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM) */ + +static struct semaphore *notify_semaphore = NULL; + +static int dummy_probe(struct sdio_func *func, + const struct sdio_device_id *id) +{ + up(notify_semaphore); + return 0; +} + +static void dummy_remove(struct sdio_func *func) +{ +} + +static struct sdio_driver dummy_sdmmc_driver = { + .probe = dummy_probe, + .remove = dummy_remove, + .name = "dummy_sdmmc", + .id_table = bcmsdh_sdmmc_ids, + }; + +int sdio_func_reg_notify(void* semaphore) +{ + notify_semaphore = semaphore; + return sdio_register_driver(&dummy_sdmmc_driver); +} + +void sdio_func_unreg_notify(void) +{ + sdio_unregister_driver(&dummy_sdmmc_driver); +} + static struct sdio_driver bcmsdh_sdmmc_driver = { .probe = bcmsdh_sdmmc_probe, .remove = bcmsdh_sdmmc_remove, @@ -220,10 +256,10 @@ static struct sdio_driver bcmsdh_sdmmc_driver = { .id_table = bcmsdh_sdmmc_ids, #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM) .drv = { - .pm = &bcmsdh_sdmmc_pm_ops, + .pm = &bcmsdh_sdmmc_pm_ops, }, #endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM) */ -}; + }; struct sdos_info { sdioh_info_t *sd; diff --git a/drivers/net/wireless/bcmdhd/bcmutils.c b/drivers/net/wireless/bcmdhd/bcmutils.c index 6b578e65364..32ac0693848 100644 --- a/drivers/net/wireless/bcmdhd/bcmutils.c +++ b/drivers/net/wireless/bcmdhd/bcmutils.c @@ -1,9 +1,9 @@ /* * Driver O/S-independent utility routines * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -20,18 +20,17 @@ * Notwithstanding the above, under no circumstances may you combine this * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. - * $Id: bcmutils.c,v 1.277.2.18 2011-01-26 02:32:08 $ + * $Id: bcmutils.c 309397 2012-01-19 15:36:59Z $ */ +#include #include #include #include - #ifdef BCMDRIVER #include #include -#include #else /* !BCMDRIVER */ @@ -53,9 +52,9 @@ #include #include #include - void *_bcmutils_dummy_fn = NULL; + #ifdef BCMDRIVER @@ -67,7 +66,7 @@ pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf) uint n, ret = 0; if (len < 0) - len = 4096; /* "infinite" */ + len = 4096; /* "infinite" */ /* skip 'offset' bytes */ for (; p && offset; p = PKTNEXT(osh, p)) { @@ -128,10 +127,14 @@ uint BCMFASTPATH pkttotlen(osl_t *osh, void *p) { uint total; + int len; total = 0; - for (; p; p = PKTNEXT(osh, p)) - total += PKTLEN(osh, p); + for (; p; p = PKTNEXT(osh, p)) { + len = PKTLEN(osh, p); + total += len; + } + return (total); } @@ -158,6 +161,52 @@ pktsegcnt(osl_t *osh, void *p) } +/* count segments of a chained packet */ +uint BCMFASTPATH +pktsegcnt_war(osl_t *osh, void *p) +{ + uint cnt; + uint8 *pktdata; + uint len, remain, align64; + + for (cnt = 0; p; p = PKTNEXT(osh, p)) { + cnt++; + len = PKTLEN(osh, p); + if (len > 128) { + pktdata = (uint8 *)PKTDATA(osh, p); /* starting address of data */ + align64 = (uint)((uintptr)pktdata & 0x3f); /* aligned to 64B */ + align64 = (64 - align64) & 0x3f; + len -= align64; /* bytes from aligned 64B to end */ + /* if aligned to 128B, check for MOD 128 between 1 to 4B */ + remain = len % 128; + if (remain > 0 && remain <= 4) + cnt++; /* add extra seg */ + } + } + + return cnt; +} + +uint8 * BCMFASTPATH +pktoffset(osl_t *osh, void *p, uint offset) +{ + uint total = pkttotlen(osh, p); + uint pkt_off = 0, len = 0; + uint8 *pdata = (uint8 *) PKTDATA(osh, p); + + if (offset > total) + return NULL; + + for (; p; p = PKTNEXT(osh, p)) { + pdata = (uint8 *) PKTDATA(osh, p); + pkt_off = offset - len; + len += PKTLEN(osh, p); + if (len > offset) + break; + } + return (uint8*) (pdata+pkt_off); +} + /* * osl multiple-precedence packet queue * hi_prec is always >= the number of the highest non-empty precedence @@ -244,6 +293,32 @@ pktq_pdeq(struct pktq *pq, int prec) return p; } +void * BCMFASTPATH +pktq_pdeq_prev(struct pktq *pq, int prec, void *prev_p) +{ + struct pktq_prec *q; + void *p; + + ASSERT(prec >= 0 && prec < pq->num_prec); + + q = &pq->q[prec]; + + if (prev_p == NULL) + return NULL; + + if ((p = PKTLINK(prev_p)) == NULL) + return NULL; + + q->len--; + + pq->len--; + + PKTSETLINK(prev_p, PKTLINK(p)); + PKTSETLINK(p, NULL); + + return p; +} + void * BCMFASTPATH pktq_pdeq_tail(struct pktq *pq, int prec) { @@ -356,6 +431,15 @@ pktq_init(struct pktq *pq, int num_prec, int max_len) pq->q[prec].max = pq->max; } +void +pktq_set_max_plen(struct pktq *pq, int prec, int max_len) +{ + ASSERT(prec >= 0 && prec < pq->num_prec); + + if (prec < pq->num_prec) + pq->q[prec].max = (uint16)max_len; +} + void * BCMFASTPATH pktq_deq(struct pktq *pq, int *prec_out) { @@ -468,6 +552,14 @@ void pktq_flush(osl_t *osh, struct pktq *pq, bool dir, ifpkt_cb_t fn, int arg) { int prec; + + /* Optimize flush, if pktq len = 0, just return. + * pktq len of 0 means pktq's prec q's are all empty. + */ + if (pq->len == 0) { + return; + } + for (prec = 0; prec < pq->num_prec; prec++) pktq_pflush(osh, pq, prec, dir, fn, arg); if (fn == NULL) @@ -489,6 +581,35 @@ pktq_mlen(struct pktq *pq, uint prec_bmp) return len; } +/* Priority peek from a specific set of precedences */ +void * BCMFASTPATH +pktq_mpeek(struct pktq *pq, uint prec_bmp, int *prec_out) +{ + struct pktq_prec *q; + void *p; + int prec; + + if (pq->len == 0) + { + return NULL; + } + while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) + pq->hi_prec--; + + while ((prec_bmp & (1 << prec)) == 0 || pq->q[prec].head == NULL) + if (prec-- == 0) + return NULL; + + q = &pq->q[prec]; + + if ((p = q->head) == NULL) + return NULL; + + if (prec_out) + *prec_out = prec; + + return p; +} /* Priority dequeue from a specific set of precedences */ void * BCMFASTPATH pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out) @@ -531,43 +652,43 @@ pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out) const unsigned char bcm_ctype[] = { - _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 0-7 */ + _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 0-7 */ _BCM_C, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C, - _BCM_C, /* 8-15 */ - _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 16-23 */ - _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 24-31 */ - _BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 32-39 */ - _BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 40-47 */ - _BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D, /* 48-55 */ - _BCM_D,_BCM_D,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 56-63 */ + _BCM_C, /* 8-15 */ + _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 16-23 */ + _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 24-31 */ + _BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 32-39 */ + _BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 40-47 */ + _BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D, /* 48-55 */ + _BCM_D,_BCM_D,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 56-63 */ _BCM_P, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U, /* 64-71 */ - _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 72-79 */ - _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 80-87 */ - _BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 88-95 */ + _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 72-79 */ + _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 80-87 */ + _BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 88-95 */ _BCM_P, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L, /* 96-103 */ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 104-111 */ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 112-119 */ _BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_C, /* 120-127 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 128-143 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 144-159 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 128-143 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 144-159 */ _BCM_S|_BCM_SP, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, - _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 160-175 */ + _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 160-175 */ _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, - _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 176-191 */ + _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 176-191 */ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, - _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, /* 192-207 */ + _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, /* 192-207 */ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_P, _BCM_U, _BCM_U, _BCM_U, - _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_L, /* 208-223 */ + _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_L, /* 208-223 */ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, - _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, /* 224-239 */ + _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, /* 224-239 */ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_P, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L /* 240-255 */ }; ulong -bcm_strtoul(char *cp, char **endp, uint base) +bcm_strtoul(const char *cp, char **endp, uint base) { ulong result, last_result = 0, value; bool minus; @@ -602,8 +723,7 @@ bcm_strtoul(char *cp, char **endp, uint base) result = 0; while (bcm_isxdigit(*cp) && - (value = bcm_isdigit(*cp) ? *cp-'0' : bcm_toupper(*cp)-'A'+10) < base) - { + (value = bcm_isdigit(*cp) ? *cp-'0' : bcm_toupper(*cp)-'A'+10) < base) { result = result*base + value; /* Detected overflow */ if (result < last_result && !minus) @@ -616,37 +736,37 @@ bcm_strtoul(char *cp, char **endp, uint base) result = (ulong)(-(long)result); if (endp) - *endp = (char *)cp; + *endp = DISCARD_QUAL(cp, char); return (result); } int -bcm_atoi(char *s) +bcm_atoi(const char *s) { return (int)bcm_strtoul(s, NULL, 10); } /* return pointer to location of substring 'needle' in 'haystack' */ -char* -bcmstrstr(char *haystack, char *needle) +char * +bcmstrstr(const char *haystack, const char *needle) { int len, nlen; int i; if ((haystack == NULL) || (needle == NULL)) - return (haystack); + return DISCARD_QUAL(haystack, char); nlen = strlen(needle); len = strlen(haystack) - nlen + 1; for (i = 0; i < len; i++) if (memcmp(needle, &haystack[i], nlen) == 0) - return (&haystack[i]); + return DISCARD_QUAL(&haystack[i], char); return (NULL); } -char* +char * bcmstrcat(char *dest, const char *src) { char *p; @@ -659,7 +779,7 @@ bcmstrcat(char *dest, const char *src) return (dest); } -char* +char * bcmstrncat(char *dest, const char *src, uint size) { char *endp; @@ -829,12 +949,14 @@ bcmstrnicmp(const char* s1, const char* s2, int cnt) /* parse a xx:xx:xx:xx:xx:xx format ethernet address */ int -bcm_ether_atoe(char *p, struct ether_addr *ea) +bcm_ether_atoe(const char *p, struct ether_addr *ea) { int i = 0; + char *ep; for (;;) { - ea->octet[i++] = (char) bcm_strtoul(p, &p, 16); + ea->octet[i++] = (char) bcm_strtoul(p, &ep, 16); + p = ep; if (!*p++ || i == 6) break; } @@ -875,10 +997,23 @@ wchar2ascii(char *abuf, ushort *wbuf, ushort wbuflen, ulong abuflen) char * bcm_ether_ntoa(const struct ether_addr *ea, char *buf) { - static const char template[] = "%02x:%02x:%02x:%02x:%02x:%02x"; - snprintf(buf, 18, template, - ea->octet[0]&0xff, ea->octet[1]&0xff, ea->octet[2]&0xff, - ea->octet[3]&0xff, ea->octet[4]&0xff, ea->octet[5]&0xff); + static const char hex[] = + { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' + }; + const uint8 *octet = ea->octet; + char *p = buf; + int i; + + for (i = 0; i < 6; i++, octet++) { + *p++ = hex[(*octet >> 4) & 0xf]; + *p++ = hex[*octet & 0xf]; + *p++ = ':'; + } + + *(p-1) = '\0'; + return (buf); } @@ -886,7 +1021,7 @@ char * bcm_ip_ntoa(struct ipv4_addr *ia, char *buf) { snprintf(buf, 16, "%d.%d.%d.%d", - ia->addr[0], ia->addr[1], ia->addr[2], ia->addr[3]); + ia->addr[0], ia->addr[1], ia->addr[2], ia->addr[3]); return (buf); } @@ -919,7 +1054,7 @@ prpkt(const char *msg, osl_t *osh, void *p0) for (p = p0; p; p = PKTNEXT(osh, p)) prhex(NULL, PKTDATA(osh, p), PKTLEN(osh, p)); } -#endif +#endif /* Takes an Ethernet frame and sets out-of-bound PKTPRIO. * Also updates the inplace vlan tag if requested. @@ -934,7 +1069,7 @@ pktsetprio(void *pkt, bool update_vtag) int priority = 0; int rc = 0; - pktdata = (uint8 *) PKTDATA(NULL, pkt); + pktdata = (uint8 *)PKTDATA(NULL, pkt); ASSERT(ISALIGNED((uintptr)pktdata, sizeof(uint16))); eh = (struct ether_header *) pktdata; @@ -1010,7 +1145,6 @@ bcmerrorstr(int bcmerror) - /* iovar table lookup */ const bcm_iovar_t* bcm_iovar_lookup(const bcm_iovar_t *table, const char *name) @@ -1082,7 +1216,7 @@ bcm_iovar_lencheck(const bcm_iovar_t *vi, void *arg, int len, bool set) return bcmerror; } -#endif /* BCMDRIVER */ +#endif /* BCMDRIVER */ /******************************************************************************* @@ -1108,38 +1242,38 @@ bcm_iovar_lencheck(const bcm_iovar_t *vi, void *arg, int len, bool set) */ static const uint8 crc8_table[256] = { - 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B, - 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21, - 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF, - 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5, - 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14, - 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E, - 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80, - 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA, - 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95, - 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF, - 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01, - 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B, - 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA, - 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0, - 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E, - 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34, - 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0, - 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A, - 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54, - 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E, - 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF, - 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5, - 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B, - 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61, - 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E, - 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74, - 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA, - 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0, - 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41, - 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B, - 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5, - 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F + 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B, + 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21, + 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF, + 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5, + 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14, + 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E, + 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80, + 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA, + 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95, + 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF, + 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01, + 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B, + 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA, + 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0, + 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E, + 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34, + 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0, + 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A, + 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54, + 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E, + 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF, + 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5, + 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B, + 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61, + 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E, + 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74, + 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA, + 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0, + 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41, + 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B, + 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5, + 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F }; #define CRC_INNER_LOOP(n, c, x) \ @@ -1147,9 +1281,9 @@ static const uint8 crc8_table[256] = { uint8 hndcrc8( - uint8 *pdata, /* pointer to array of data to process */ - uint nbytes, /* number of input data bytes to process */ - uint8 crc /* either CRC8_INIT_VALUE or previous return value */ + uint8 *pdata, /* pointer to array of data to process */ + uint nbytes, /* number of input data bytes to process */ + uint8 crc /* either CRC8_INIT_VALUE or previous return value */ ) { /* hard code the crc loop instead of using CRC_INNER_LOOP macro @@ -1184,45 +1318,45 @@ hndcrc8( */ static const uint16 crc16_table[256] = { - 0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF, - 0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7, - 0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E, - 0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876, - 0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD, - 0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5, - 0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C, - 0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974, - 0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB, - 0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3, - 0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A, - 0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72, - 0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9, - 0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1, - 0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738, - 0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70, - 0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7, - 0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF, - 0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036, - 0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E, - 0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5, - 0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD, - 0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134, - 0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C, - 0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3, - 0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB, - 0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232, - 0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A, - 0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1, - 0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9, - 0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330, - 0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78 + 0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF, + 0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7, + 0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E, + 0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876, + 0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD, + 0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5, + 0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C, + 0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974, + 0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB, + 0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3, + 0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A, + 0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72, + 0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9, + 0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1, + 0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738, + 0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70, + 0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7, + 0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF, + 0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036, + 0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E, + 0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5, + 0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD, + 0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134, + 0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C, + 0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3, + 0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB, + 0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232, + 0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A, + 0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1, + 0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9, + 0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330, + 0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78 }; uint16 hndcrc16( - uint8 *pdata, /* pointer to array of data to process */ - uint nbytes, /* number of input data bytes to process */ - uint16 crc /* either CRC16_INIT_VALUE or previous return value */ + uint8 *pdata, /* pointer to array of data to process */ + uint nbytes, /* number of input data bytes to process */ + uint16 crc /* either CRC16_INIT_VALUE or previous return value */ ) { while (nbytes-- > 0) @@ -1231,70 +1365,70 @@ hndcrc16( } static const uint32 crc32_table[256] = { - 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, - 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, - 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, - 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, - 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, - 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, - 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, - 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, - 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, - 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, - 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, - 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, - 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, - 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, - 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, - 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, - 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, - 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, - 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, - 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, - 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, - 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, - 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, - 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, - 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, - 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, - 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, - 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, - 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, - 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, - 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, - 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, - 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, - 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, - 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, - 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, - 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, - 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, - 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, - 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, - 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, - 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, - 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, - 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, - 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, - 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, - 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, - 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, - 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, - 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, - 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, - 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, - 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, - 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, - 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, - 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, - 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, - 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, - 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, - 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, - 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, - 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, - 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, - 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, + 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, + 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, + 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, + 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, + 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, + 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, + 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, + 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, + 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, + 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, + 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, + 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, + 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, + 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, + 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, + 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, + 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, + 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, + 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, + 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, + 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, + 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, + 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, + 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, + 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, + 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, + 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, + 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, + 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, + 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, + 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, + 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D }; /* @@ -1305,44 +1439,17 @@ uint32 hndcrc32(uint8 *pdata, uint nbytes, uint32 crc) { uint8 *pend; -#ifdef __mips__ - uint8 tmp[4]; - ulong *tptr = (ulong *)tmp; - - /* in case the beginning of the buffer isn't aligned */ - pend = (uint8 *)((uint)(pdata + 3) & 0xfffffffc); - nbytes -= (pend - pdata); - while (pdata < pend) - CRC_INNER_LOOP(32, crc, *pdata++); - - /* handle bulk of data as 32-bit words */ - pend = pdata + (nbytes & 0xfffffffc); - while (pdata < pend) { - *tptr = *(ulong *)pdata; - pdata += sizeof(ulong *); - CRC_INNER_LOOP(32, crc, tmp[0]); - CRC_INNER_LOOP(32, crc, tmp[1]); - CRC_INNER_LOOP(32, crc, tmp[2]); - CRC_INNER_LOOP(32, crc, tmp[3]); - } - - /* 1-3 bytes at end of buffer */ - pend = pdata + (nbytes & 0x03); - while (pdata < pend) - CRC_INNER_LOOP(32, crc, *pdata++); -#else pend = pdata + nbytes; while (pdata < pend) CRC_INNER_LOOP(32, crc, *pdata++); -#endif /* __mips__ */ return crc; } #ifdef notdef -#define CLEN 1499 /* CRC Length */ -#define CBUFSIZ (CLEN+4) -#define CNBUFS 5 /* # of bufs */ +#define CLEN 1499 /* CRC Length */ +#define CBUFSIZ (CLEN+4) +#define CNBUFS 5 /* # of bufs */ void testcrc32(void) @@ -1395,7 +1502,7 @@ bcm_next_tlv(bcm_tlv_t *elt, int *buflen) /* advance to next elt */ len = elt->len; elt = (bcm_tlv_t*)(elt->data + len); - *buflen -= (2 + len); + *buflen -= (TLV_HDR_LEN + len); /* validate next elt */ if (!bcm_valid_tlv(elt, *buflen)) @@ -1419,15 +1526,16 @@ bcm_parse_tlvs(void *buf, int buflen, uint key) totlen = buflen; /* find tagged parameter */ - while (totlen >= 2) { + while (totlen >= TLV_HDR_LEN) { int len = elt->len; /* validate remaining totlen */ - if ((elt->id == key) && (totlen >= (len + 2))) + if ((elt->id == key) && + (totlen >= (len + TLV_HDR_LEN))) return (elt); - elt = (bcm_tlv_t*)((uint8*)elt + (len + 2)); - totlen -= (len + 2); + elt = (bcm_tlv_t*)((uint8*)elt + (len + TLV_HDR_LEN)); + totlen -= (len + TLV_HDR_LEN); } return NULL; @@ -1449,7 +1557,7 @@ bcm_parse_ordered_tlvs(void *buf, int buflen, uint key) totlen = buflen; /* find tagged parameter */ - while (totlen >= 2) { + while (totlen >= TLV_HDR_LEN) { uint id = elt->id; int len = elt->len; @@ -1458,11 +1566,12 @@ bcm_parse_ordered_tlvs(void *buf, int buflen, uint key) return (NULL); /* validate remaining totlen */ - if ((id == key) && (totlen >= (len + 2))) + if ((id == key) && + (totlen >= (len + TLV_HDR_LEN))) return (elt); - elt = (bcm_tlv_t*)((uint8*)elt + (len + 2)); - totlen -= (len + 2); + elt = (bcm_tlv_t*)((uint8*)elt + (len + TLV_HDR_LEN)); + totlen -= (len + TLV_HDR_LEN); } return NULL; } @@ -1491,7 +1600,7 @@ bcm_format_flags(const bcm_bit_desc_t *bd, uint32 flags, char* buf, int len) /* print any unnamed bits */ snprintf(hexstr, 16, "0x%X", flags); name = hexstr; - flags = 0; /* exit loop */ + flags = 0; /* exit loop */ } else if ((flags & bit) == 0) continue; flags &= ~bit; @@ -1509,22 +1618,18 @@ bcm_format_flags(const bcm_bit_desc_t *bd, uint32 flags, char* buf, int len) /* copy btwn flag space and NULL char */ if (flags != 0) p += snprintf(p, 2, " "); - len -= slen; } /* indicate the str was too short */ if (flags != 0) { if (len < 2) - p -= 2 - len; /* overwrite last char */ + p -= 2 - len; /* overwrite last char */ p += snprintf(p, 2, ">"); } return (int)(p - buf); } -#endif -#if defined(WLMSG_PRHDRS) || defined(WLMSG_PRPKT) || defined(WLMSG_ASSOC) || \ - defined(DHD_DEBUG) || defined(WLMEDIA_PEAKRATE) /* print bytes formatted as hex to a string. return the resulting string length */ int bcm_format_hex(char *str, const void *bytes, int len) @@ -1556,7 +1661,7 @@ prhex(const char *msg, uchar *buf, uint nbytes) p = line; for (i = 0; i < nbytes; i++) { if (i % 16 == 0) { - nchar = snprintf(p, len, " %04d: ", i); /* line prefix */ + nchar = snprintf(p, len, " %04d: ", i); /* line prefix */ p += nchar; len -= nchar; } @@ -1567,7 +1672,7 @@ prhex(const char *msg, uchar *buf, uint nbytes) } if (i % 16 == 15) { - printf("%s\n", line); /* flush line */ + printf("%s\n", line); /* flush line */ p = line; len = sizeof(line); } @@ -1590,6 +1695,9 @@ static const char *crypto_algo_names[] = { "UNDEF", "UNDEF", "UNDEF", +#ifdef BCMWAPI_WPI + "WAPI", +#endif /* BCMWAPI_WPI */ "UNDEF" }; @@ -1665,7 +1773,7 @@ bcmdumpfields(bcmutl_rdreg_rtn read_rtn, void *arg0, uint arg1, struct fielddesc if (cur_ptr->nameandfmt == NULL) break; len = snprintf(buf, bufsize, cur_ptr->nameandfmt, - read_rtn(arg0, arg1, cur_ptr->offset)); + read_rtn(arg0, arg1, cur_ptr->offset)); /* check for snprintf overflow or error */ if (len < 0 || (uint32)len >= bufsize) len = bufsize - 1; @@ -1702,8 +1810,8 @@ bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen) * a uint16. */ -#define QDBM_OFFSET 153 /* Offset for first entry */ -#define QDBM_TABLE_LEN 40 /* Table size */ +#define QDBM_OFFSET 153 /* Offset for first entry */ +#define QDBM_TABLE_LEN 40 /* Table size */ /* Smallest mW value that will round up to the first table entry, QDBM_OFFSET. * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2 @@ -1717,12 +1825,12 @@ bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen) #define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */ static const uint16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = { -/* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */ -/* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000, -/* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849, -/* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119, -/* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811, -/* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096 +/* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */ +/* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000, +/* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849, +/* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119, +/* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811, +/* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096 }; uint16 @@ -1772,9 +1880,8 @@ bcm_mw_to_qdbm(uint16 mw) for (qdbm = 0; qdbm < QDBM_TABLE_LEN-1; qdbm++) { boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm+1] - - nqdBm_to_mW_map[qdbm])/2; - if (mw_uint < boundary) - break; + nqdBm_to_mW_map[qdbm])/2; + if (mw_uint < boundary) break; } qdbm += (uint8)offset; @@ -1816,13 +1923,17 @@ bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...) int r; va_start(ap, fmt); + r = vsnprintf(b->buf, b->size, fmt, ap); /* Non Ansi C99 compliant returns -1, * Ansi compliant return r >= b->size, * bcmstdlib returns 0, handle all */ - if ((r == -1) || (r >= (int)b->size) || (r == 0)) { + /* r == 0 is also the case when strlen(fmt) is zero. + * typically the case when "" is passed as argument. + */ + if ((r == -1) || (r >= (int)b->size)) { b->size = 0; } else { b->size -= r; @@ -1834,6 +1945,19 @@ bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...) return r; } +void +bcm_bprhex(struct bcmstrbuf *b, const char *msg, bool newline, uint8 *buf, int len) +{ + int i; + + if (msg != NULL && msg[0] != '\0') + bcm_bprintf(b, "%s", msg); + for (i = 0; i < len; i ++) + bcm_bprintf(b, "%02X", buf[i]); + if (newline) + bcm_bprintf(b, "\n"); +} + void bcm_inc_bytes(uchar *num, int num_bytes, uint8 amount) { @@ -1848,7 +1972,7 @@ bcm_inc_bytes(uchar *num, int num_bytes, uint8 amount) } int -bcm_cmp_bytes(uchar *arg1, uchar *arg2, uint8 nbytes) +bcm_cmp_bytes(const uchar *arg1, const uchar *arg2, uint8 nbytes) { int i; @@ -1860,7 +1984,7 @@ bcm_cmp_bytes(uchar *arg1, uchar *arg2, uint8 nbytes) } void -bcm_print_bytes(char *name, const uchar *data, int len) +bcm_print_bytes(const char *name, const uchar *data, int len) { int i; int per_line = 0; @@ -1878,7 +2002,7 @@ bcm_print_bytes(char *name, const uchar *data, int len) } #if defined(WLTINYDUMP) || defined(WLMSG_INFORM) || defined(WLMSG_ASSOC) || \ defined(WLMSG_PRPKT) || defined(WLMSG_WSEC) -#define SSID_FMT_BUF_LEN ((4 * DOT11_MAX_SSID_LEN) + 1) +#define SSID_FMT_BUF_LEN ((4 * DOT11_MAX_SSID_LEN) + 1) int bcm_format_ssid(char* buf, const uchar ssid[], uint ssid_len) diff --git a/drivers/net/wireless/bcmdhd/bcmwifi.c b/drivers/net/wireless/bcmdhd/bcmwifi.c index 70722170bdf..bc975e8be1b 100644 --- a/drivers/net/wireless/bcmdhd/bcmwifi.c +++ b/drivers/net/wireless/bcmdhd/bcmwifi.c @@ -3,9 +3,9 @@ * Contents are wifi-specific, used by any kernel or app-level * software that might want wifi things as it grows. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -22,10 +22,10 @@ * Notwithstanding the above, under no circumstances may you combine this * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. - * $Id: bcmwifi.c,v 1.31.8.1 2010-08-03 17:47:05 Exp $ + * $Id: bcmwifi.c 309193 2012-01-19 00:03:57Z $ */ - +#include #include #ifdef BCMDRIVER @@ -47,6 +47,10 @@ #include #endif +#ifndef D11AC_IOTYPES + + + @@ -84,7 +88,7 @@ wf_chspec_ntoa(chanspec_t chspec, char *buf) chanspec_t -wf_chspec_aton(char *a) +wf_chspec_aton(const char *a) { char *endp = NULL; uint channel, band, bw, ctl_sb; @@ -157,7 +161,7 @@ wf_chspec_malformed(chanspec_t chanspec) return TRUE; - if (CHSPEC_IS20_UNCOND(chanspec)) { + if (CHSPEC_IS20(chanspec)) { if (!CHSPEC_SB_NONE(chanspec)) return TRUE; } else { @@ -217,6 +221,658 @@ wf_chspec_ctlchspec(chanspec_t chspec) return ctl_chspec; } +#else + + + + + + +static const char *wf_chspec_bw_str[] = +{ + "5", + "10", + "20", + "40", + "80", + "160", + "80+80", + "na" +}; + +static const uint8 wf_chspec_bw_mhz[] = +{5, 10, 20, 40, 80, 160, 160}; + +#define WF_NUM_BW \ + (sizeof(wf_chspec_bw_mhz)/sizeof(uint8)) + + +static const uint8 wf_5g_40m_chans[] = +{38, 46, 54, 62, 102, 110, 118, 126, 134, 142, 151, 159}; +#define WF_NUM_5G_40M_CHANS \ + (sizeof(wf_5g_40m_chans)/sizeof(uint8)) + + +static const uint8 wf_5g_80m_chans[] = +{42, 58, 106, 122, 138, 155}; +#define WF_NUM_5G_80M_CHANS \ + (sizeof(wf_5g_80m_chans)/sizeof(uint8)) + + +static const uint8 wf_5g_160m_chans[] = +{50, 114}; +#define WF_NUM_5G_160M_CHANS \ + (sizeof(wf_5g_160m_chans)/sizeof(uint8)) + + + +static uint +bw_chspec_to_mhz(chanspec_t chspec) +{ + uint bw; + + bw = (chspec & WL_CHANSPEC_BW_MASK) >> WL_CHANSPEC_BW_SHIFT; + return (bw >= WF_NUM_BW ? 0 : wf_chspec_bw_mhz[bw]); +} + + +static uint8 +center_chan_to_edge(uint bw) +{ + + return (uint8)(((bw - 20) / 2) / 5); +} + + +static uint8 +channel_low_edge(uint center_ch, uint bw) +{ + return (uint8)(center_ch - center_chan_to_edge(bw)); +} + + +static int +channel_to_sb(uint center_ch, uint ctl_ch, uint bw) +{ + uint lowest = channel_low_edge(center_ch, bw); + uint sb; + + if ((ctl_ch - lowest) % 4) { + + return -1; + } + + sb = ((ctl_ch - lowest) / 4); + + + if (sb >= (bw / 20)) { + + return -1; + } + + return sb; +} + + +static uint8 +channel_to_ctl_chan(uint center_ch, uint bw, uint sb) +{ + return (uint8)(channel_low_edge(center_ch, bw) + sb * 4); +} + + +static int +channel_80mhz_to_id(uint ch) +{ + uint i; + for (i = 0; i < WF_NUM_5G_80M_CHANS; i ++) { + if (ch == wf_5g_80m_chans[i]) + return i; + } + + return -1; +} + + +char * +wf_chspec_ntoa(chanspec_t chspec, char *buf) +{ + const char *band; + uint ctl_chan; + + if (wf_chspec_malformed(chspec)) + return NULL; + + band = ""; + + + if ((CHSPEC_IS2G(chspec) && CHSPEC_CHANNEL(chspec) > CH_MAX_2G_CHANNEL) || + (CHSPEC_IS5G(chspec) && CHSPEC_CHANNEL(chspec) <= CH_MAX_2G_CHANNEL)) + band = (CHSPEC_IS2G(chspec)) ? "2g" : "5g"; + + + ctl_chan = wf_chspec_ctlchan(chspec); + + + if (CHSPEC_IS20(chspec)) { + snprintf(buf, CHANSPEC_STR_LEN, "%s%d", band, ctl_chan); + } else if (!CHSPEC_IS8080(chspec)) { + const char *bw; + const char *sb = ""; + + bw = wf_chspec_bw_str[(chspec & WL_CHANSPEC_BW_MASK) >> WL_CHANSPEC_BW_SHIFT]; + +#ifdef CHANSPEC_NEW_40MHZ_FORMAT + + if (CHSPEC_IS40(chspec) && CHSPEC_IS2G(chspec)) { + sb = CHSPEC_SB_UPPER(chspec) ? "u" : "l"; + } + + snprintf(buf, CHANSPEC_STR_LEN, "%s%d/%s%s", band, ctl_chan, bw, sb); +#else + + if (CHSPEC_IS40(chspec)) { + sb = CHSPEC_SB_UPPER(chspec) ? "u" : "l"; + snprintf(buf, CHANSPEC_STR_LEN, "%s%d%s", band, ctl_chan, sb); + } else { + snprintf(buf, CHANSPEC_STR_LEN, "%s%d/%s", band, ctl_chan, bw); + } +#endif + + } else { + + uint chan1 = (chspec & WL_CHANSPEC_CHAN1_MASK) >> WL_CHANSPEC_CHAN1_SHIFT; + uint chan2 = (chspec & WL_CHANSPEC_CHAN2_MASK) >> WL_CHANSPEC_CHAN2_SHIFT; + + + chan1 = (chan1 < WF_NUM_5G_80M_CHANS) ? wf_5g_80m_chans[chan1] : 0; + chan2 = (chan2 < WF_NUM_5G_80M_CHANS) ? wf_5g_80m_chans[chan2] : 0; + + + snprintf(buf, CHANSPEC_STR_LEN, "%d/80+80/%d-%d", ctl_chan, chan1, chan2); + } + + return (buf); +} + +static int +read_uint(const char **p, unsigned int *num) +{ + unsigned long val; + char *endp = NULL; + + val = strtoul(*p, &endp, 10); + + if (endp == *p) + return 0; + + + *p = endp; + + *num = (unsigned int)val; + + return 1; +} + + +chanspec_t +wf_chspec_aton(const char *a) +{ + chanspec_t chspec; + uint chspec_ch, chspec_band, bw, chspec_bw, chspec_sb; + uint num, ctl_ch; + uint ch1, ch2; + char c, sb_ul = '\0'; + int i; + + bw = 20; + chspec_sb = 0; + chspec_ch = ch1 = ch2 = 0; + + + if (!read_uint(&a, &num)) + return 0; + + + c = tolower(a[0]); + if (c == 'g') { + a ++; + + + if (num == 2) + chspec_band = WL_CHANSPEC_BAND_2G; + else if (num == 5) + chspec_band = WL_CHANSPEC_BAND_5G; + else + return 0; + + + if (!read_uint(&a, &ctl_ch)) + return 0; + + c = tolower(a[0]); + } + else { + + ctl_ch = num; + chspec_band = ((ctl_ch <= CH_MAX_2G_CHANNEL) ? + WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G); + } + + if (c == '\0') { + + chspec_bw = WL_CHANSPEC_BW_20; + goto done_read; + } + + a ++; + + + if (c == 'u' || c == 'l') { + sb_ul = c; + chspec_bw = WL_CHANSPEC_BW_40; + goto done_read; + } + + + if (c != '/') + return 0; + + + if (!read_uint(&a, &bw)) + return 0; + + + if (bw == 20) { + chspec_bw = WL_CHANSPEC_BW_20; + } else if (bw == 40) { + chspec_bw = WL_CHANSPEC_BW_40; + } else if (bw == 80) { + chspec_bw = WL_CHANSPEC_BW_80; + } else if (bw == 160) { + chspec_bw = WL_CHANSPEC_BW_160; + } else { + return 0; + } + + + + c = tolower(a[0]); + + + if (chspec_band == WL_CHANSPEC_BAND_2G && bw == 40) { + if (c == 'u' || c == 'l') { + a ++; + sb_ul = c; + goto done_read; + } + } + + + if (c == '+') { + + static const char *plus80 = "80/"; + + + chspec_bw = WL_CHANSPEC_BW_8080; + + a ++; + + + for (i = 0; i < 3; i++) { + if (*a++ != *plus80++) { + return 0; + } + } + + + if (!read_uint(&a, &ch1)) + return 0; + + + if (a[0] != '-') + return 0; + a ++; + + + if (!read_uint(&a, &ch2)) + return 0; + } + +done_read: + + while (a[0] == ' ') { + a ++; + } + + + if (a[0] != '\0') + return 0; + + + + + if (sb_ul != '\0') { + if (sb_ul == 'l') { + chspec_ch = UPPER_20_SB(ctl_ch); + chspec_sb = WL_CHANSPEC_CTL_SB_LLL; + } else if (sb_ul == 'u') { + chspec_ch = LOWER_20_SB(ctl_ch); + chspec_sb = WL_CHANSPEC_CTL_SB_LLU; + } + } + + else if (chspec_bw == WL_CHANSPEC_BW_20) { + chspec_ch = ctl_ch; + chspec_sb = 0; + } + + else if (chspec_bw != WL_CHANSPEC_BW_8080) { + + const uint8 *center_ch = NULL; + int num_ch = 0; + int sb = -1; + + if (chspec_bw == WL_CHANSPEC_BW_40) { + center_ch = wf_5g_40m_chans; + num_ch = WF_NUM_5G_40M_CHANS; + } else if (chspec_bw == WL_CHANSPEC_BW_80) { + center_ch = wf_5g_80m_chans; + num_ch = WF_NUM_5G_80M_CHANS; + } else if (chspec_bw == WL_CHANSPEC_BW_160) { + center_ch = wf_5g_160m_chans; + num_ch = WF_NUM_5G_160M_CHANS; + } else { + return 0; + } + + for (i = 0; i < num_ch; i ++) { + sb = channel_to_sb(center_ch[i], ctl_ch, bw); + if (sb >= 0) { + chspec_ch = center_ch[i]; + chspec_sb = sb << WL_CHANSPEC_CTL_SB_SHIFT; + break; + } + } + + + if (sb < 0) { + return 0; + } + } + + else { + int ch1_id = 0, ch2_id = 0; + int sb; + + ch1_id = channel_80mhz_to_id(ch1); + ch2_id = channel_80mhz_to_id(ch2); + + + if (ch1 >= ch2 || ch1_id < 0 || ch2_id < 0) + return 0; + + + chspec_ch = (((uint16)ch1_id << WL_CHANSPEC_CHAN1_SHIFT) | + ((uint16)ch2_id << WL_CHANSPEC_CHAN2_SHIFT)); + + + + + sb = channel_to_sb(ch1, ctl_ch, bw); + if (sb < 0) { + + sb = channel_to_sb(ch2, ctl_ch, bw); + if (sb < 0) { + + return 0; + } + + sb += 4; + } + + chspec_sb = sb << WL_CHANSPEC_CTL_SB_SHIFT; + } + + chspec = (chspec_ch | chspec_band | chspec_bw | chspec_sb); + + if (wf_chspec_malformed(chspec)) + return 0; + + return chspec; +} + + +bool +wf_chspec_malformed(chanspec_t chanspec) +{ + uint chspec_bw = CHSPEC_BW(chanspec); + uint chspec_ch = CHSPEC_CHANNEL(chanspec); + + + if (CHSPEC_IS2G(chanspec)) { + + if (chspec_bw != WL_CHANSPEC_BW_20 && + chspec_bw != WL_CHANSPEC_BW_40) { + return TRUE; + } + } else if (CHSPEC_IS5G(chanspec)) { + if (chspec_bw == WL_CHANSPEC_BW_8080) { + uint ch1_id, ch2_id; + + + ch1_id = CHSPEC_CHAN1(chanspec); + ch2_id = CHSPEC_CHAN2(chanspec); + if (ch1_id >= WF_NUM_5G_80M_CHANS || ch2_id >= WF_NUM_5G_80M_CHANS) + return TRUE; + + + if (ch2_id <= ch1_id) + return TRUE; + } else if (chspec_bw == WL_CHANSPEC_BW_20 || chspec_bw == WL_CHANSPEC_BW_40 || + chspec_bw == WL_CHANSPEC_BW_80 || chspec_bw == WL_CHANSPEC_BW_160) { + + if (chspec_ch > MAXCHANNEL) { + return TRUE; + } + } else { + + return TRUE; + } + } else { + + return TRUE; + } + + + if (chspec_bw == WL_CHANSPEC_BW_20) { + if (CHSPEC_CTL_SB(chanspec) != WL_CHANSPEC_CTL_SB_LLL) + return TRUE; + } else if (chspec_bw == WL_CHANSPEC_BW_40) { + if (CHSPEC_CTL_SB(chanspec) > WL_CHANSPEC_CTL_SB_LLU) + return TRUE; + } else if (chspec_bw == WL_CHANSPEC_BW_80) { + if (CHSPEC_CTL_SB(chanspec) > WL_CHANSPEC_CTL_SB_LUU) + return TRUE; + } + + return FALSE; +} + + +bool +wf_chspec_valid(chanspec_t chanspec) +{ + uint chspec_bw = CHSPEC_BW(chanspec); + uint chspec_ch = CHSPEC_CHANNEL(chanspec); + + if (wf_chspec_malformed(chanspec)) + return FALSE; + + if (CHSPEC_IS2G(chanspec)) { + + if (chspec_bw == WL_CHANSPEC_BW_20) { + if (chspec_ch >= 1 && chspec_ch <= 14) + return TRUE; + } else if (chspec_bw == WL_CHANSPEC_BW_40) { + if (chspec_ch >= 3 && chspec_ch <= 11) + return TRUE; + } + } else if (CHSPEC_IS5G(chanspec)) { + if (chspec_bw == WL_CHANSPEC_BW_8080) { + uint16 ch1, ch2; + + ch1 = wf_5g_80m_chans[CHSPEC_CHAN1(chanspec)]; + ch2 = wf_5g_80m_chans[CHSPEC_CHAN2(chanspec)]; + + + if (ch2 > ch1 + CH_80MHZ_APART) + return TRUE; + } else { + const uint8 *center_ch; + uint num_ch, i; + + if (chspec_bw == WL_CHANSPEC_BW_20 || chspec_bw == WL_CHANSPEC_BW_40) { + center_ch = wf_5g_40m_chans; + num_ch = WF_NUM_5G_40M_CHANS; + } else if (chspec_bw == WL_CHANSPEC_BW_80) { + center_ch = wf_5g_80m_chans; + num_ch = WF_NUM_5G_80M_CHANS; + } else if (chspec_bw == WL_CHANSPEC_BW_160) { + center_ch = wf_5g_160m_chans; + num_ch = WF_NUM_5G_160M_CHANS; + } else { + + return FALSE; + } + + + if (chspec_bw == WL_CHANSPEC_BW_20) { + + for (i = 0; i < num_ch; i ++) { + if (chspec_ch == (uint)LOWER_20_SB(center_ch[i]) || + chspec_ch == (uint)UPPER_20_SB(center_ch[i])) + break; + } + + if (i == num_ch) { + + if (chspec_ch == 34 || chspec_ch == 38 || + chspec_ch == 42 || chspec_ch == 46) + i = 0; + } + } else { + + for (i = 0; i < num_ch; i ++) { + if (chspec_ch == center_ch[i]) + break; + } + } + + if (i < num_ch) { + + return TRUE; + } + } + } + + return FALSE; +} + + +uint8 +wf_chspec_ctlchan(chanspec_t chspec) +{ + uint center_chan; + uint bw_mhz; + uint sb; + + ASSERT(!wf_chspec_malformed(chspec)); + + + if (CHSPEC_IS20(chspec)) { + return CHSPEC_CHANNEL(chspec); + } else { + sb = CHSPEC_CTL_SB(chspec) >> WL_CHANSPEC_CTL_SB_SHIFT; + + if (CHSPEC_IS8080(chspec)) { + bw_mhz = 80; + + if (sb < 4) { + center_chan = CHSPEC_CHAN1(chspec); + } + else { + center_chan = CHSPEC_CHAN2(chspec); + sb -= 4; + } + + + center_chan = wf_5g_80m_chans[center_chan]; + } + else { + bw_mhz = bw_chspec_to_mhz(chspec); + center_chan = CHSPEC_CHANNEL(chspec) >> WL_CHANSPEC_CHAN_SHIFT; + } + + return (channel_to_ctl_chan(center_chan, bw_mhz, sb)); + } +} + + +chanspec_t +wf_chspec_ctlchspec(chanspec_t chspec) +{ + chanspec_t ctl_chspec = chspec; + uint8 ctl_chan; + + ASSERT(!wf_chspec_malformed(chspec)); + + + if (!CHSPEC_IS20(chspec)) { + ctl_chan = wf_chspec_ctlchan(chspec); + ctl_chspec = ctl_chan | WL_CHANSPEC_BW_20; + ctl_chspec |= CHSPEC_BAND(chspec); + } + return ctl_chspec; +} + +#endif + + +extern chanspec_t wf_chspec_primary40_chspec(chanspec_t chspec) +{ + chanspec_t chspec40 = chspec; + uint center_chan; + uint sb; + + ASSERT(!wf_chspec_malformed(chspec)); + + if (CHSPEC_IS80(chspec)) { + center_chan = CHSPEC_CHANNEL(chspec); + sb = CHSPEC_CTL_SB(chspec); + + if (sb == WL_CHANSPEC_CTL_SB_UL) { + + sb = WL_CHANSPEC_CTL_SB_L; + center_chan += CH_20MHZ_APART; + } else if (sb == WL_CHANSPEC_CTL_SB_UU) { + + sb = WL_CHANSPEC_CTL_SB_U; + center_chan += CH_20MHZ_APART; + } else { + + + center_chan -= CH_20MHZ_APART; + } + + + chspec40 = (WL_CHANSPEC_BAND_5G | WL_CHANSPEC_BW_40 | + sb | center_chan); + } + + return chspec40; +} + int wf_mhz2channel(uint freq, uint start_factor) diff --git a/drivers/net/wireless/bcmdhd/dhd.h b/drivers/net/wireless/bcmdhd/dhd.h index 25e74f44a53..16d1d355882 100644 --- a/drivers/net/wireless/bcmdhd/dhd.h +++ b/drivers/net/wireless/bcmdhd/dhd.h @@ -4,9 +4,9 @@ * Provides type definitions and function prototypes used to link the * DHD OS, bus, and protocol modules. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -24,7 +24,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: dhd.h 306879 2012-01-09 21:33:03Z $ + * $Id: dhd.h 309548 2012-01-20 01:13:08Z $ */ /**************** @@ -34,9 +34,6 @@ #ifndef _dhd_h_ #define _dhd_h_ -#if defined(CHROMIUMOS_COMPAT_WIRELESS) -#include -#endif #include #include #include @@ -59,6 +56,7 @@ int setScheduler(struct task_struct *p, int policy, struct sched_param *param); #define ALL_INTERFACES 0xff #include +#include /* Forward decls */ @@ -74,6 +72,7 @@ enum dhd_bus_state { DHD_BUS_DATA /* Ready for frame transfers */ }; + /* Firmware requested operation mode */ #define STA_MASK 0x0001 #define HOSTAPD_MASK 0x0002 @@ -86,6 +85,13 @@ enum dhd_bus_state { #define DHD_SCAN_ACTIVE_TIME 40 /* ms : Embedded default Active setting from DHD Driver */ #define DHD_SCAN_PASSIVE_TIME 130 /* ms: Embedded default Passive setting from DHD Driver */ +#ifndef POWERUP_MAX_RETRY +#define POWERUP_MAX_RETRY (10) /* how many times we retry to power up the chip */ +#endif +#ifndef POWERUP_WAIT_MS +#define POWERUP_WAIT_MS (2000) /* ms: time out in waiting wifi to come up */ +#endif + enum dhd_bus_wake_state { WAKE_LOCK_OFF, WAKE_LOCK_PRIV, @@ -138,6 +144,17 @@ void dhd_os_prefree(void *osh, void *addr, uint size); #define DHD_SDALIGN 32 #endif +/* host reordering packts logic */ +/* followed the structure to hold the reorder buffers (void **p) */ +typedef struct reorder_info { + void **p; + uint8 flow_id; + uint8 cur_idx; + uint8 exp_idx; + uint8 max_idx; + uint8 pend_pkts; +} reorder_info_t; + /* Common structure for module and instance linkage */ typedef struct dhd_pub { /* Linkage ponters */ @@ -189,6 +206,8 @@ typedef struct dhd_pub { /* Last error from dongle */ int dongle_error; + uint8 country_code[WLC_CNTRY_BUF_SZ]; + /* Suspend disable flag and "in suspend" flag */ int suspend_disable_flag; /* "1" to disable all extra powersaving during suspend */ int in_suspend; /* flag set to 1 when early suspend called */ @@ -206,14 +225,16 @@ typedef struct dhd_pub { int op_mode; /* STA, HostAPD, WFD, SoftAP */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_HAS_WAKELOCK) - struct wake_lock wakelock[WAKE_LOCK_MAX]; + struct wake_lock wakelock[WAKE_LOCK_MAX]; #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined (CONFIG_HAS_WAKELOCK) */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 struct mutex wl_start_stop_lock; /* lock/unlock for Android start/stop */ struct mutex wl_softap_lock; /* lock/unlock for any SoftAP/STA settings */ #endif +#ifdef WLBTAMP uint16 maxdatablks; +#endif /* WLBTAMP */ #ifdef PROP_TXSTATUS int wlfc_enabled; void* wlfc_state; @@ -225,6 +246,7 @@ typedef struct dhd_pub { #ifdef WLMEDIA_HTSF uint8 htsfdlystat_sz; /* Size of delay stats, max 255B */ #endif + struct reorder_info *reorder_bufs[WLHOST_REORDERDATA_MAXFLOWS]; } dhd_pub_t; typedef struct dhd_cmn { @@ -243,7 +265,7 @@ typedef struct dhd_cmn { SMP_RD_BARRIER_DEPENDS(); \ wait_event_interruptible_timeout(a, !dhd_mmc_suspend, HZ/100); \ } \ - } while (0) + } while (0) #define DHD_PM_RESUME_WAIT(a) _DHD_PM_RESUME_WAIT(a, 200) #define DHD_PM_RESUME_WAIT_FOREVER(a) _DHD_PM_RESUME_WAIT(a, ~0) #define DHD_PM_RESUME_RETURN_ERROR(a) do { if (dhd_mmc_suspend) return a; } while (0) @@ -316,7 +338,6 @@ inline static void MUTEX_UNLOCK_SOFTAP_SET(dhd_pub_t * dhdp) #define DHD_OS_WAKE_UNLOCK(pub) dhd_os_wake_unlock(pub) #define DHD_OS_WAKE_LOCK_TIMEOUT(pub) dhd_os_wake_lock_timeout(pub) #define DHD_OS_WAKE_LOCK_TIMEOUT_ENABLE(pub, val) dhd_os_wake_lock_timeout_enable(pub, val) - #define DHD_PACKET_TIMEOUT_MS 1000 #define DHD_EVENT_TIMEOUT_MS 1500 @@ -419,7 +440,6 @@ extern int dhd_custom_get_mac_address(unsigned char *buf); extern void dhd_os_sdunlock_sndup_rxq(dhd_pub_t * pub); extern void dhd_os_sdlock_eventq(dhd_pub_t * pub); extern void dhd_os_sdunlock_eventq(dhd_pub_t * pub); -extern bool dhd_os_check_hang(dhd_pub_t *dhdp, int ifidx, int ret); #ifdef PNO_SUPPORT extern int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled); @@ -443,6 +463,7 @@ extern int net_os_rxfilter_add_remove(struct net_device *dev, int val, int num); extern int dhd_get_dtim_skip(dhd_pub_t *dhd); extern bool dhd_check_ap_wfd_mode_set(dhd_pub_t *dhd); +extern bool dhd_os_check_hang(dhd_pub_t *dhdp, int ifidx, int ret); #ifdef DHD_DEBUG extern int write_to_file(dhd_pub_t *dhd, uint8 *buf, int size); @@ -477,7 +498,6 @@ extern int dhd_wl_ioctl_cmd(dhd_pub_t *dhd_pub, int cmd, void *arg, int len, uin extern struct dhd_cmn *dhd_common_init(osl_t *osh); extern void dhd_common_deinit(dhd_pub_t *dhd_pub, dhd_cmn_t *sa_cmn); -extern int dhd_do_driver_init(struct net_device *net); extern int dhd_add_if(struct dhd_info *dhd, int ifidx, void *handle, char *name, uint8 *mac_addr, uint32 flags, uint8 bssidx); extern void dhd_del_if(struct dhd_info *dhd, int ifidx); @@ -535,6 +555,7 @@ extern uint dhd_console_ms; extern uint wl_msg_level; #endif /* defined(DHD_DEBUG) */ + /* Use interrupts */ extern uint dhd_intr; diff --git a/drivers/net/wireless/bcmdhd/dhd_bta.h b/drivers/net/wireless/bcmdhd/dhd_bta.h index 07d9cebb883..0337f15d285 100644 --- a/drivers/net/wireless/bcmdhd/dhd_bta.h +++ b/drivers/net/wireless/bcmdhd/dhd_bta.h @@ -1,9 +1,9 @@ /* * BT-AMP support routines * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: dhd_bta.h,v 1.2 2009-02-26 22:35:56 Exp $ + * $Id: dhd_bta.h 291086 2011-10-21 01:17:24Z $ */ #ifndef __dhd_bta_h__ #define __dhd_bta_h__ diff --git a/drivers/net/wireless/bcmdhd/dhd_bus.h b/drivers/net/wireless/bcmdhd/dhd_bus.h index bccb8b6603f..5eb914979ba 100644 --- a/drivers/net/wireless/bcmdhd/dhd_bus.h +++ b/drivers/net/wireless/bcmdhd/dhd_bus.h @@ -4,9 +4,9 @@ * Provides type definitions and function prototypes used to link the * DHD OS, bus, and protocol modules. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -24,7 +24,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: dhd_bus.h,v 1.14.28.1 2010-12-23 01:13:17 Exp $ + * $Id: dhd_bus.h 309567 2012-01-20 01:40:54Z $ */ #ifndef _dhd_bus_h_ @@ -51,8 +51,9 @@ extern int dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex); /* Get the Bus Idle Time */ extern void dhd_bus_getidletime(dhd_pub_t *dhdp, int *idletime); -/* Set the Bus Idle Time*/ +/* Set the Bus Idle Time */ extern void dhd_bus_setidletime(dhd_pub_t *dhdp, int idle_time); + /* Send a data frame to the dongle. Callee disposes of txp. */ extern int dhd_bus_txdata(struct dhd_bus *bus, void *txp); @@ -96,4 +97,8 @@ extern void *dhd_bus_pub(struct dhd_bus *bus); extern void *dhd_bus_txq(struct dhd_bus *bus); extern uint dhd_bus_hdrlen(struct dhd_bus *bus); +/* Register a dummy SDIO client driver in order to be notified of new SDIO device */ +extern int dhd_bus_reg_sdio_notify(void* semaphore); +extern void dhd_bus_unreg_sdio_notify(void); + #endif /* _dhd_bus_h_ */ diff --git a/drivers/net/wireless/bcmdhd/dhd_cdc.c b/drivers/net/wireless/bcmdhd/dhd_cdc.c index d01853c71a2..60c7fe433f5 100644 --- a/drivers/net/wireless/bcmdhd/dhd_cdc.c +++ b/drivers/net/wireless/bcmdhd/dhd_cdc.c @@ -1,9 +1,9 @@ /* * DHD Protocol Module for CDC and BDC. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: dhd_cdc.c 303389 2011-12-16 09:30:48Z $ + * $Id: dhd_cdc.c 304241 2011-12-21 16:43:50Z $ * * BDC is like CDC, except it includes a header for data packets to convey * packet priority over the bus, and flags (e.g. to indicate checksum status @@ -53,7 +53,7 @@ * defined in dhd_sdio.c (amount of header tha might be added) * plus any space that might be needed for alignment padding. */ -#define ROUND_UP_MARGIN 2048 /* Biggest SDIO block size possible for +#define ROUND_UP_MARGIN 2048 /* Biggest SDIO block size possible for * round off at the end of buffer */ @@ -78,7 +78,6 @@ typedef struct dhd_prot { unsigned char buf[WLC_IOCTL_MAXLEN + ROUND_UP_MARGIN]; } dhd_prot_t; -extern int dhd_dbus_txdata(dhd_pub_t *dhdp, void *pktbuf); static int dhdcdc_msg(dhd_pub_t *dhd) @@ -109,7 +108,7 @@ static int dhdcdc_cmplt(dhd_pub_t *dhd, uint32 id, uint32 len) { int ret; - int cdc_len = len+sizeof(cdc_ioctl_t); + int cdc_len = len + sizeof(cdc_ioctl_t); dhd_prot_t *prot = dhd->prot; DHD_TRACE(("%s: Enter\n", __FUNCTION__)); @@ -167,7 +166,7 @@ dhdcdc_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len, uin if ((ret = dhdcdc_msg(dhd)) < 0) { if (!dhd->hang_was_sent) - DHD_ERROR(("dhdcdc_query_ioctl: dhdcdc_msg failed w/status %d\n", ret)); + DHD_ERROR(("dhdcdc_query_ioctl: dhdcdc_msg failed w/status %d\n", ret)); goto done; } @@ -1397,13 +1396,41 @@ dhd_wlfc_enque_sendq(void* state, int prec, void* p) } int -_dhd_wlfc_handle_packet_commit(athost_wl_status_info_t* ctx, int ac, - dhd_wlfc_commit_info_t *commit_info, f_commitpkt_t fcommit, void* commit_ctx) +dhd_wlfc_commit_packets(void* state, f_commitpkt_t fcommit, void* commit_ctx) { + int ac; + int credit; + uint8 ac_fifo_credit_spent; + uint8 needs_hdr; uint32 hslot; + void* p; int rc; + athost_wl_status_info_t* ctx = (athost_wl_status_info_t*)state; + wlfc_mac_descriptor_t* mac_entry; + + if ((state == NULL) || + (fcommit == NULL)) { + WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); + return BCME_BADARG; + } /* + Commit packets for regular AC traffic. Higher priority first. + + -NOTE: + If the bus between the host and firmware is overwhelmed by the + traffic from host, it is possible that higher priority traffic + starves the lower priority queue. If that occurs often, we may + have to employ weighted round-robin or ucode scheme to avoid + low priority packet starvation. + */ + for (ac = AC_COUNT; ac >= 0; ac--) { + for (credit = 0; credit < ctx->FIFO_credit[ac];) { + p = _dhd_wlfc_deque_delayedq(ctx, ac, &ac_fifo_credit_spent, &needs_hdr, + &mac_entry); + if (p == NULL) + break; + /* if ac_fifo_credit_spent = 0 This packet will not count against the FIFO credit. @@ -1416,254 +1443,77 @@ _dhd_wlfc_handle_packet_commit(athost_wl_status_info_t* ctx, int ac, This is a normal packet and it counts against the FIFO credit count. */ - DHD_PKTTAG_SETCREDITCHECK(PKTTAG(commit_info->p), commit_info->ac_fifo_credit_spent); - rc = _dhd_wlfc_pretx_pktprocess(ctx, commit_info->mac_entry, commit_info->p, - commit_info->needs_hdr, &hslot); + DHD_PKTTAG_SETCREDITCHECK(PKTTAG(p), ac_fifo_credit_spent); + rc = _dhd_wlfc_pretx_pktprocess(ctx, mac_entry, p, needs_hdr, &hslot); if (rc == BCME_OK) - rc = fcommit(commit_ctx, commit_info->p); + rc = fcommit(commit_ctx, p); else ctx->stats.generic_error++; if (rc == BCME_OK) { ctx->stats.pkt2bus++; - if (commit_info->ac_fifo_credit_spent) { + if (ac_fifo_credit_spent) { ctx->stats.sendq_pkts[ac]++; WLFC_HOST_FIFO_CREDIT_INC_SENTCTRS(ctx, ac); + /* + 1 FIFO credit has been spent by sending this packet + to the device. + */ + credit++; } } else { + /* bus commit has failed, rollback. */ + rc = _dhd_wlfc_rollback_packet_toq(ctx, + p, /* - bus commit has failed, rollback. - remove wl-header for a delayed packet - save wl-header header for suppressed packets */ - rc = _dhd_wlfc_rollback_packet_toq(ctx, commit_info->p, - (commit_info->pkt_type), hslot); + (needs_hdr ? eWLFC_PKTTYPE_DELAYED : + eWLFC_PKTTYPE_SUPPRESSED), + hslot); if (rc != BCME_OK) ctx->stats.rollback_failed++; - - rc = BCME_ERROR; - } - - return rc; } - -int -dhd_wlfc_commit_packets(void* state, f_commitpkt_t fcommit, void* commit_ctx) -{ - int ac; - int credit; - int rc; - dhd_wlfc_commit_info_t commit_info; - athost_wl_status_info_t* ctx = (athost_wl_status_info_t*)state; - int credit_count = 0; - int bus_retry_count = 0; - uint8 ac_available = 0; /* Bitmask for 4 ACs + BC/MC */ - - if ((state == NULL) || - (fcommit == NULL)) { - WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); - return BCME_BADARG; } - - memset(&commit_info, 0, sizeof(commit_info)); - - /* - Commit packets for regular AC traffic. Higher priority first. - First, use up FIFO credits available to each AC. Based on distribution - and credits left, borrow from other ACs as applicable - - -NOTE: - If the bus between the host and firmware is overwhelmed by the - traffic from host, it is possible that higher priority traffic - starves the lower priority queue. If that occurs often, we may - have to employ weighted round-robin or ucode scheme to avoid - low priority packet starvation. - */ - - for (ac = AC_COUNT; ac >= 0; ac--) { - - int initial_credit_count = ctx->FIFO_credit[ac]; - - for (credit = 0; credit < ctx->FIFO_credit[ac];) { - commit_info.p = _dhd_wlfc_deque_delayedq(ctx, ac, - &(commit_info.ac_fifo_credit_spent), - &(commit_info.needs_hdr), - &(commit_info.mac_entry)); - - if (commit_info.p == NULL) - break; - - commit_info.pkt_type = (commit_info.needs_hdr) ? eWLFC_PKTTYPE_DELAYED : - eWLFC_PKTTYPE_SUPPRESSED; - - rc = _dhd_wlfc_handle_packet_commit(ctx, ac, &commit_info, - fcommit, commit_ctx); - - /* Bus commits may fail (e.g. flow control); abort after retries */ - if (rc == BCME_OK) { - if (commit_info.ac_fifo_credit_spent) { - credit++; - } - } - else { - bus_retry_count++; - if (bus_retry_count >= BUS_RETRIES) { - DHD_ERROR(("dhd_wlfc_commit_packets(): bus error\n")); - ctx->FIFO_credit[ac] -= credit; - return rc; - } - } - } - ctx->FIFO_credit[ac] -= credit; - - /* packets from SENDQ are fresh and they'd need header and have no MAC entry */ - commit_info.needs_hdr = 1; - commit_info.mac_entry = NULL; - commit_info.pkt_type = eWLFC_PKTTYPE_NEW; - + /* packets from SENDQ are fresh and they'd need header */ + needs_hdr = 1; for (credit = 0; credit < ctx->FIFO_credit[ac];) { - commit_info.p = _dhd_wlfc_deque_sendq(ctx, ac, - &(commit_info.ac_fifo_credit_spent)); - if (commit_info.p == NULL) + p = _dhd_wlfc_deque_sendq(ctx, ac, &ac_fifo_credit_spent); + if (p == NULL) break; - rc = _dhd_wlfc_handle_packet_commit(ctx, ac, &commit_info, - fcommit, commit_ctx); + DHD_PKTTAG_SETCREDITCHECK(PKTTAG(p), ac_fifo_credit_spent); + rc = _dhd_wlfc_pretx_pktprocess(ctx, NULL, p, needs_hdr, &hslot); + if (rc == BCME_OK) + rc = fcommit(commit_ctx, p); + else + ctx->stats.generic_error++; - /* Bus commits may fail (e.g. flow control); abort after retries */ if (rc == BCME_OK) { - if (commit_info.ac_fifo_credit_spent) { + ctx->stats.pkt2bus++; + if (ac_fifo_credit_spent) { + WLFC_HOST_FIFO_CREDIT_INC_SENTCTRS(ctx, ac); + ctx->stats.sendq_pkts[ac]++; credit++; } } else { - bus_retry_count++; - if (bus_retry_count >= BUS_RETRIES) { - DHD_ERROR(("dhd_wlfc_commit_packets(): bus error\n")); - ctx->FIFO_credit[ac] -= credit; - return rc; - } + /* bus commit has failed, rollback. */ + rc = _dhd_wlfc_rollback_packet_toq(ctx, + p, + /* remove wl-header while rolling back */ + eWLFC_PKTTYPE_NEW, + hslot); + if (rc != BCME_OK) + ctx->stats.rollback_failed++; } } - ctx->FIFO_credit[ac] -= credit; - - /* If no credits were used, the queue is idle and can be re-used - Note that resv credits cannot be borrowed - */ - if (initial_credit_count == ctx->FIFO_credit[ac]) { - ac_available |= (1 << ac); - credit_count += ctx->FIFO_credit[ac]; - } - } - - /* We borrow only for AC_BE and only if no other traffic seen for DEFER_PERIOD - - Note that (ac_available & WLFC_AC_BE_TRAFFIC_ONLY) is done to: - a) ignore BC/MC for deferring borrow - b) ignore AC_BE being available along with other ACs - (this should happen only for pure BC/MC traffic) - - i.e. AC_VI, AC_VO, AC_BK all MUST be available (i.e. no traffic) and - we do not care if AC_BE and BC/MC are available or not - */ - if ((ac_available & WLFC_AC_BE_TRAFFIC_ONLY) == WLFC_AC_BE_TRAFFIC_ONLY) { - - if (ctx->allow_credit_borrow) { - ac = 1; /* Set ac to AC_BE and borrow credits */ - } - else { - int delta; - int curr_t = OSL_SYSUPTIME(); - - if (curr_t > ctx->borrow_defer_timestamp) - delta = curr_t - ctx->borrow_defer_timestamp; - else - delta = 0xffffffff + curr_t - ctx->borrow_defer_timestamp; - - if (delta >= WLFC_BORROW_DEFER_PERIOD_MS) { - /* Reset borrow but defer to next iteration (defensive borrowing) */ - ctx->allow_credit_borrow = TRUE; - ctx->borrow_defer_timestamp = 0; - } - return BCME_OK; - } - } - else { - /* If we have multiple AC traffic, turn off borrowing, mark time and bail out */ - ctx->allow_credit_borrow = FALSE; - ctx->borrow_defer_timestamp = OSL_SYSUPTIME(); - return BCME_OK; - } - - /* At this point, borrow all credits only for "ac" (which should be set above to AC_BE) - Generically use "ac" only in case we extend to all ACs in future - */ - for (; (credit_count > 0);) { - - commit_info.p = _dhd_wlfc_deque_delayedq(ctx, ac, - &(commit_info.ac_fifo_credit_spent), - &(commit_info.needs_hdr), - &(commit_info.mac_entry)); - if (commit_info.p == NULL) - break; - - commit_info.pkt_type = (commit_info.needs_hdr) ? eWLFC_PKTTYPE_DELAYED : - eWLFC_PKTTYPE_SUPPRESSED; - - rc = _dhd_wlfc_handle_packet_commit(ctx, ac, &commit_info, - fcommit, commit_ctx); - - /* Bus commits may fail (e.g. flow control); abort after retries */ - if (rc == BCME_OK) { - if (commit_info.ac_fifo_credit_spent) { - (void) _dhd_wlfc_borrow_credit(ctx, ac_available, ac); - credit_count--; - } - } - else { - bus_retry_count++; - if (bus_retry_count >= BUS_RETRIES) { - DHD_ERROR(("dhd_wlfc_commit_packets(): bus error\n")); - return rc; - } - } - } - - /* packets from SENDQ are fresh and they'd need header and have no MAC entry */ - commit_info.needs_hdr = 1; - commit_info.mac_entry = NULL; - commit_info.pkt_type = eWLFC_PKTTYPE_NEW; - - for (; (credit_count > 0);) { - - commit_info.p = _dhd_wlfc_deque_sendq(ctx, ac, - &(commit_info.ac_fifo_credit_spent)); - if (commit_info.p == NULL) - break; - - rc = _dhd_wlfc_handle_packet_commit(ctx, ac, &commit_info, - fcommit, commit_ctx); - - /* Bus commits may fail (e.g. flow control); abort after retries */ - if (rc == BCME_OK) { - if (commit_info.ac_fifo_credit_spent) { - (void) _dhd_wlfc_borrow_credit(ctx, ac_available, ac); - credit_count--; - } - } - else { - bus_retry_count++; - if (bus_retry_count >= BUS_RETRIES) { - DHD_ERROR(("dhd_wlfc_commit_packets(): bus error\n")); - return rc; - } - } } - return BCME_OK; } @@ -1966,6 +1816,9 @@ dhd_wlfc_mac_table_update(dhd_pub_t *dhd, uint8* value, uint8 type) table[existing_index].state = WLFC_STATE_CLOSE; table[existing_index].requested_credit = 0; table[existing_index].interface_id = 0; + /* enable after packets are queued-deqeued properly. + pktq_flush(dhd->osh, &table[existing_index].psq, FALSE, NULL, 0); + */ } } } @@ -1981,6 +1834,7 @@ dhd_wlfc_mac_table_update(dhd_pub_t *dhd, uint8* value, uint8 type) wlfc->stats.mac_update_failed++; } } + BCM_REFERENCE(rc); return BCME_OK; } @@ -2101,8 +1955,22 @@ dhd_wlfc_packet_request(dhd_pub_t *dhd, uint8* value) return BCME_OK; } +static void +dhd_wlfc_reorderinfo_indicate(uint8 *val, uint8 len, uchar *info_buf, uint *info_len) +{ + if (info_len) { + if (info_buf) { + bcopy(val, info_buf, len); + *info_len = len; + } + else + *info_len = 0; + } +} + static int -dhd_wlfc_parse_header_info(dhd_pub_t *dhd, void* pktbuf, int tlv_hdr_len) +dhd_wlfc_parse_header_info(dhd_pub_t *dhd, void* pktbuf, int tlv_hdr_len, uchar *reorder_info_buf, + uint *reorder_info_len) { uint8 type, len; uint8* value; @@ -2132,6 +2000,9 @@ dhd_wlfc_parse_header_info(dhd_pub_t *dhd, void* pktbuf, int tlv_hdr_len) if (type == WLFC_CTL_TYPE_TXSTATUS) dhd_wlfc_txstatus_update(dhd, value); + else if (type == WLFC_CTL_TYPE_HOST_REORDER_RXPKTS) + dhd_wlfc_reorderinfo_indicate(value, len, reorder_info_buf, + reorder_info_len); else if (type == WLFC_CTL_TYPE_FIFO_CREDITBACK) dhd_wlfc_fifocreditback_indicate(dhd, value); @@ -2174,9 +2045,9 @@ dhd_wlfc_init(dhd_pub_t *dhd) WLFC_FLAGS_RSSI_SIGNALS | WLFC_FLAGS_XONXOFF_SIGNALS | WLFC_FLAGS_CREDIT_STATUS_SIGNALS | - WLFC_FLAGS_HOST_PROPTXSTATUS_ACTIVE : 0; + WLFC_FLAGS_HOST_RXRERODER_ACTIVE : 0; + /* WLFC_FLAGS_HOST_PROPTXSTATUS_ACTIVE | WLFC_FLAGS_HOST_RXRERODER_ACTIVE : 0; */ - dhd->wlfc_state = NULL; /* try to enable/disable signaling by sending "tlv" iovar. if that fails, @@ -2367,7 +2238,8 @@ dhd_prot_hdrpush(dhd_pub_t *dhd, int ifidx, void *pktbuf) } int -dhd_prot_hdrpull(dhd_pub_t *dhd, int *ifidx, void *pktbuf) +dhd_prot_hdrpull(dhd_pub_t *dhd, int *ifidx, void *pktbuf, uchar *reorder_buf_info, + uint *reorder_info_len) { #ifdef BDC struct bdc_header *h; @@ -2376,6 +2248,8 @@ dhd_prot_hdrpull(dhd_pub_t *dhd, int *ifidx, void *pktbuf) DHD_TRACE(("%s: Enter\n", __FUNCTION__)); #ifdef BDC + if (reorder_info_len) + *reorder_info_len = 0; /* Pop BDC header used to convey priority for buses that don't */ if (PKTLEN(dhd->osh, pktbuf) < BDC_HEADER_LEN) { @@ -2398,7 +2272,7 @@ dhd_prot_hdrpull(dhd_pub_t *dhd, int *ifidx, void *pktbuf) if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) == BDC_PROTO_VER_1) h->dataOffset = 0; else - return BCME_ERROR; + return BCME_ERROR; } if (h->flags & BDC_FLAG_SUM_GOOD) { @@ -2426,14 +2300,15 @@ dhd_prot_hdrpull(dhd_pub_t *dhd, int *ifidx, void *pktbuf) - parse txstatus only for packets that came from the firmware */ dhd_os_wlfc_block(dhd); - dhd_wlfc_parse_header_info(dhd, pktbuf, (h->dataOffset << 2)); + dhd_wlfc_parse_header_info(dhd, pktbuf, (h->dataOffset << 2), + reorder_buf_info, reorder_info_len); ((athost_wl_status_info_t*)dhd->wlfc_state)->stats.dhd_hdrpulls++; dhd_wlfc_commit_packets(dhd->wlfc_state, (f_commitpkt_t)dhd_bus_txdata, (void *)dhd->bus); dhd_os_wlfc_unblock(dhd); } #endif /* PROP_TXSTATUS */ - PKTPULL(dhd->osh, pktbuf, (h->dataOffset << 2)); + PKTPULL(dhd->osh, pktbuf, (h->dataOffset << 2)); return 0; } @@ -2444,9 +2319,9 @@ dhd_prot_attach(dhd_pub_t *dhd) if (!(cdc = (dhd_prot_t *)DHD_OS_PREALLOC(dhd->osh, DHD_PREALLOC_PROT, sizeof(dhd_prot_t)))) { - DHD_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); - goto fail; - } + DHD_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); + goto fail; + } memset(cdc, 0, sizeof(dhd_prot_t)); /* ensure that the msg buf directly follows the cdc msg struct */ @@ -2518,7 +2393,7 @@ dhd_prot_init(dhd_pub_t *dhd) #if defined(WL_CFG80211) if (dhd_download_fw_on_driverload) #endif /* defined(WL_CFG80211) */ - ret = dhd_preinit_ioctls(dhd); + ret = dhd_preinit_ioctls(dhd); /* Always assumes wl for now */ dhd->iswl = TRUE; @@ -2532,3 +2407,261 @@ dhd_prot_stop(dhd_pub_t *dhd) { /* Nothing to do for CDC */ } + + +static void +dhd_get_hostreorder_pkts(void *osh, struct reorder_info *ptr, void **pkt, + uint32 *pkt_count, void **pplast, uint8 start, uint8 end) +{ + uint i; + void *plast = NULL, *p; + uint32 pkt_cnt = 0; + + if (ptr->pend_pkts == 0) { + DHD_REORDER(("%s: no packets in reorder queue \n", __FUNCTION__)); + *pplast = NULL; + *pkt_count = 0; + *pkt = NULL; + return; + } + if (start == end) + i = ptr->max_idx + 1; + else { + if (start > end) + i = (ptr->max_idx - end) + start; + else + i = end - start; + } + while (i) { + p = (void *)(ptr->p[start]); + ptr->p[start] = NULL; + + if (p != NULL) { + if (plast == NULL) + *pkt = p; + else + PKTSETNEXT(dhd->osh, plast, p); + + plast = p; + pkt_cnt++; + } + i--; + if (start++ == ptr->max_idx) + start = 0; + } + *pplast = plast; + *pkt_count = (uint32)pkt_cnt; +} + +int +dhd_process_pkt_reorder_info(dhd_pub_t *dhd, uchar *reorder_info_buf, uint reorder_info_len, + void **pkt, uint32 *pkt_count) +{ + uint8 flow_id, max_idx, cur_idx, exp_idx; + struct reorder_info *ptr; + uint8 flags; + void *cur_pkt, *plast = NULL; + uint32 cnt = 0; + + if (pkt == NULL) { + if (pkt_count != NULL) + *pkt_count = 0; + return 0; + } + cur_pkt = *pkt; + *pkt = NULL; + + flow_id = reorder_info_buf[WLHOST_REORDERDATA_FLOWID_OFFSET]; + flags = reorder_info_buf[WLHOST_REORDERDATA_FLAGS_OFFSET]; + + DHD_REORDER(("flow_id %d, flags 0x%02x, idx(%d, %d, %d)\n", flow_id, flags, + reorder_info_buf[WLHOST_REORDERDATA_CURIDX_OFFSET], + reorder_info_buf[WLHOST_REORDERDATA_EXPIDX_OFFSET], + reorder_info_buf[WLHOST_REORDERDATA_MAXIDX_OFFSET])); + + /* validate flags and flow id */ + if (flags == 0xFF) { + DHD_ERROR(("%s: invalid flags...so ignore this packet\n", __FUNCTION__)); + *pkt_count = 1; + return 0; + } + + ptr = dhd->reorder_bufs[flow_id]; + if (flags & WLHOST_REORDERDATA_DEL_FLOW) { + uint32 buf_size = sizeof(struct reorder_info); + + DHD_REORDER(("%s: Flags indicating to delete a flow id %d\n", + __FUNCTION__, flow_id)); + + if (ptr == NULL) { + DHD_ERROR(("%s: received flags to cleanup, but no flow (%d) yet\n", + __FUNCTION__, flow_id)); + *pkt_count = 1; + return 0; + } + + dhd_get_hostreorder_pkts(dhd->osh, ptr, pkt, &cnt, &plast, + ptr->exp_idx, ptr->exp_idx); + /* set it to the last packet */ + if (plast) { + PKTSETNEXT(dhd->osh, plast, cur_pkt); + cnt++; + } + else { + if (cnt != 0) { + DHD_ERROR(("%s: del flow: something fishy, pending packets %d\n", + __FUNCTION__, cnt)); + } + *pkt = cur_pkt; + cnt = 1; + } + buf_size += ((ptr->max_idx + 1) * sizeof(void *)); + MFREE(dhd->osh, ptr, buf_size); + dhd->reorder_bufs[flow_id] = NULL; + *pkt_count = cnt; + return 0; + } + /* all the other cases depend on the existance of the reorder struct for that flow id */ + if (ptr == NULL) { + uint32 buf_size_alloc = sizeof(reorder_info_t); + max_idx = reorder_info_buf[WLHOST_REORDERDATA_MAXIDX_OFFSET]; + + buf_size_alloc += ((max_idx + 1) * sizeof(void*)); + /* allocate space to hold the buffers, index etc */ + + DHD_REORDER(("%s: alloc buffer of size %d size, reorder info id %d, maxidx %d\n", + __FUNCTION__, buf_size_alloc, flow_id, max_idx)); + ptr = (struct reorder_info *)MALLOC(dhd->osh, buf_size_alloc); + if (ptr == NULL) { + DHD_ERROR(("%s: Malloc failed to alloc buffer\n", __FUNCTION__)); + *pkt_count = 1; + return 0; + } + bzero(ptr, buf_size_alloc); + dhd->reorder_bufs[flow_id] = ptr; + ptr->p = (void *)(ptr+1); + ptr->max_idx = max_idx; + } + if (flags & WLHOST_REORDERDATA_NEW_HOLE) { + DHD_REORDER(("%s: new hole, so cleanup pending buffers\n", __FUNCTION__)); + if (ptr->pend_pkts) { + dhd_get_hostreorder_pkts(dhd->osh, ptr, pkt, &cnt, &plast, + ptr->exp_idx, ptr->exp_idx); + ptr->pend_pkts = 0; + } + ptr->cur_idx = reorder_info_buf[WLHOST_REORDERDATA_CURIDX_OFFSET]; + ptr->exp_idx = reorder_info_buf[WLHOST_REORDERDATA_EXPIDX_OFFSET]; + ptr->max_idx = reorder_info_buf[WLHOST_REORDERDATA_MAXIDX_OFFSET]; + ptr->p[ptr->cur_idx] = cur_pkt; + ptr->pend_pkts++; + *pkt_count = cnt; + } + else if (flags & WLHOST_REORDERDATA_CURIDX_VALID) { + cur_idx = reorder_info_buf[WLHOST_REORDERDATA_CURIDX_OFFSET]; + exp_idx = reorder_info_buf[WLHOST_REORDERDATA_EXPIDX_OFFSET]; + + + if ((exp_idx == ptr->exp_idx) && (cur_idx != ptr->exp_idx)) { + /* still in the current hole */ + /* enqueue the current on the buffer chain */ + if (ptr->p[cur_idx] != NULL) { + DHD_REORDER(("%s: HOLE: ERROR buffer pending..free it\n", + __FUNCTION__)); + PKTFREE(dhd->osh, ptr->p[cur_idx], TRUE); + ptr->p[cur_idx] = NULL; + } + ptr->p[cur_idx] = cur_pkt; + ptr->pend_pkts++; + ptr->cur_idx = cur_idx; + DHD_REORDER(("%s: fill up a hole..pending packets is %d\n", + __FUNCTION__, ptr->pend_pkts)); + *pkt_count = 0; + *pkt = NULL; + } + else if (ptr->exp_idx == cur_idx) { + /* got the right one ..flush from cur to exp and update exp */ + DHD_REORDER(("%s: got the right one now, cur_idx is %d\n", + __FUNCTION__, cur_idx)); + if (ptr->p[cur_idx] != NULL) { + DHD_REORDER(("%s: Error buffer pending..free it\n", + __FUNCTION__)); + PKTFREE(dhd->osh, ptr->p[cur_idx], TRUE); + ptr->p[cur_idx] = NULL; + } + ptr->p[cur_idx] = cur_pkt; + ptr->pend_pkts++; + + ptr->cur_idx = cur_idx; + ptr->exp_idx = exp_idx; + + dhd_get_hostreorder_pkts(dhd->osh, ptr, pkt, &cnt, &plast, + cur_idx, exp_idx); + ptr->pend_pkts -= (uint8)cnt; + *pkt_count = cnt; + DHD_REORDER(("%s: freeing up buffers %d, still pending %d\n", + __FUNCTION__, cnt, ptr->pend_pkts)); + } + else { + uint8 end_idx; + bool flush_current = FALSE; + /* both cur and exp are moved now .. */ + DHD_REORDER(("%s:, flow %d, both moved, cur %d(%d), exp %d(%d)\n", + __FUNCTION__, flow_id, ptr->cur_idx, cur_idx, + ptr->exp_idx, exp_idx)); + if (flags & WLHOST_REORDERDATA_FLUSH_ALL) + end_idx = ptr->exp_idx; + else + end_idx = exp_idx; + + /* flush pkts first */ + dhd_get_hostreorder_pkts(dhd->osh, ptr, pkt, &cnt, &plast, + ptr->exp_idx, end_idx); + + if (cur_idx == ptr->max_idx) { + if (exp_idx == 0) + flush_current = TRUE; + } else { + if (exp_idx == cur_idx + 1) + flush_current = TRUE; + } + if (flush_current) { + if (plast) + PKTSETNEXT(dhd->osh, plast, cur_pkt); + else + *pkt = cur_pkt; + cnt++; + } + else { + ptr->p[cur_idx] = cur_pkt; + ptr->pend_pkts++; + } + ptr->exp_idx = exp_idx; + ptr->cur_idx = cur_idx; + *pkt_count = cnt; + } + } + else { + uint8 end_idx; + /* no real packet but update to exp_seq...that means explicit window move */ + exp_idx = reorder_info_buf[WLHOST_REORDERDATA_EXPIDX_OFFSET]; + + DHD_REORDER(("%s: move the window, cur_idx is %d, exp is %d, new exp is %d\n", + __FUNCTION__, ptr->cur_idx, ptr->exp_idx, exp_idx)); + if (flags & WLHOST_REORDERDATA_FLUSH_ALL) + end_idx = ptr->exp_idx; + else + end_idx = exp_idx; + + dhd_get_hostreorder_pkts(dhd->osh, ptr, pkt, &cnt, &plast, ptr->exp_idx, end_idx); + ptr->pend_pkts -= (uint8)cnt; + if (plast) + PKTSETNEXT(dhd->osh, plast, cur_pkt); + else + *pkt = cur_pkt; + cnt++; + *pkt_count = cnt; + /* set the new expected idx */ + ptr->exp_idx = exp_idx; + } + return 0; +} diff --git a/drivers/net/wireless/bcmdhd/dhd_cfg80211.c b/drivers/net/wireless/bcmdhd/dhd_cfg80211.c index 800590cca65..f654d3113fb 100644 --- a/drivers/net/wireless/bcmdhd/dhd_cfg80211.c +++ b/drivers/net/wireless/bcmdhd/dhd_cfg80211.c @@ -1,9 +1,9 @@ /* * Linux cfg80211 driver - Dongle Host Driver (DHD) related * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -30,6 +30,7 @@ #include #include #include + extern struct wl_priv *wlcfg_drv_priv; static int dhd_dongle_up = FALSE; diff --git a/drivers/net/wireless/bcmdhd/dhd_cfg80211.h b/drivers/net/wireless/bcmdhd/dhd_cfg80211.h index 8dab652c1a2..18b213fa571 100644 --- a/drivers/net/wireless/bcmdhd/dhd_cfg80211.h +++ b/drivers/net/wireless/bcmdhd/dhd_cfg80211.h @@ -1,9 +1,9 @@ /* * Linux cfg80211 driver - Dongle Host Driver (DHD) related * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the diff --git a/drivers/net/wireless/bcmdhd/dhd_common.c b/drivers/net/wireless/bcmdhd/dhd_common.c index a54c39152e4..afe1e2818e8 100644 --- a/drivers/net/wireless/bcmdhd/dhd_common.c +++ b/drivers/net/wireless/bcmdhd/dhd_common.c @@ -1,9 +1,9 @@ /* * Broadcom Dongle Host Driver (DHD), common DHD core. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: dhd_common.c 307573 2012-01-12 00:04:39Z $ + * $Id: dhd_common.c 304622 2011-12-22 19:51:18Z $ */ #include #include @@ -44,8 +44,10 @@ #ifdef WL_CFG80211 #include #endif +#ifdef WLBTAMP #include #include +#endif #ifdef SET_RANDOM_MAC_SOFTAP #include #include @@ -115,8 +117,10 @@ enum { IOV_LOGSTAMP, IOV_GPIOOB, IOV_IOCTLTIMEOUT, +#ifdef WLBTAMP IOV_HCI_CMD, /* HCI command */ IOV_HCI_ACL_DATA, /* HCI data packet */ +#endif #if defined(DHD_DEBUG) IOV_CONS, IOV_DCONSOLE_POLL, @@ -130,6 +134,7 @@ enum { IOV_WLPKTDLYSTAT_SZ, #endif IOV_CHANGEMTU, + IOV_HOSTREORDER_FLOWS, IOV_LAST }; @@ -149,8 +154,10 @@ const bcm_iovar_t dhd_iovars[] = { {"clearcounts", IOV_CLEARCOUNTS, 0, IOVT_VOID, 0 }, {"gpioob", IOV_GPIOOB, 0, IOVT_UINT32, 0 }, {"ioctl_timeout", IOV_IOCTLTIMEOUT, 0, IOVT_UINT32, 0 }, +#ifdef WLBTAMP {"HCI_cmd", IOV_HCI_CMD, 0, IOVT_BUFFER, 0}, {"HCI_ACL_data", IOV_HCI_ACL_DATA, 0, IOVT_BUFFER, 0}, +#endif #ifdef PROP_TXSTATUS {"proptx", IOV_PROPTXSTATUS_ENABLE, 0, IOVT_UINT32, 0 }, /* @@ -166,6 +173,8 @@ const bcm_iovar_t dhd_iovars[] = { {"pktdlystatsz", IOV_WLPKTDLYSTAT_SZ, 0, IOVT_UINT8, 0 }, #endif {"changemtu", IOV_CHANGEMTU, 0, IOVT_UINT32, 0 }, + {"host_reorder_flows", IOV_HOSTREORDER_FLOWS, 0, IOVT_BUFFER, + (WLHOST_REORDERDATA_MAXFLOWS + 1) }, {NULL, 0, 0, 0, 0 } }; @@ -336,11 +345,6 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch case IOV_SVAL(IOV_MSGLEVEL): dhd_msg_level = int_val; -#ifdef WL_CFG80211 - /* Enable DHD and WL logs in oneshot */ - if (dhd_msg_level & DHD_WL_VAL) - wl_cfg80211_enable_trace(dhd_msg_level); -#endif break; case IOV_GVAL(IOV_BCMERRORSTR): bcm_strncpy_s((char *)arg, len, bcmerrorstr(dhd_pub->bcmerror), BCME_STRLEN); @@ -430,6 +434,7 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch break; } +#ifdef WLBTAMP case IOV_SVAL(IOV_HCI_CMD): { amp_hci_cmd_t *cmd = (amp_hci_cmd_t *)arg; @@ -459,6 +464,7 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch dhd_bta_tx_hcidata(dhd_pub, ACL_data, len); break; } +#endif /* WLBTAMP */ #ifdef PROP_TXSTATUS case IOV_GVAL(IOV_PROPTXSTATUS_ENABLE): @@ -513,6 +519,25 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch bcmerror = dhd_change_mtu(dhd_pub, int_val, 0); break; + case IOV_GVAL(IOV_HOSTREORDER_FLOWS): + { + uint i = 0; + uint8 *ptr = (uint8 *)arg; + uint8 count = 0; + + ptr++; + for (i = 0; i < WLHOST_REORDERDATA_MAXFLOWS; i++) { + if (dhd_pub->reorder_bufs[i] != NULL) { + *ptr = dhd_pub->reorder_bufs[i]->flow_id; + ptr++; + count++; + } + } + ptr = (uint8 *)arg; + *ptr = count; + break; + } + default: bcmerror = BCME_UNSUPPORTED; break; @@ -734,6 +759,7 @@ wl_show_host_event(wl_event_msg_t *event, void *event_data) flags = ntoh16(event->flags); status = ntoh32(event->status); reason = ntoh32(event->reason); + BCM_REFERENCE(reason); auth_type = ntoh32(event->auth_type); datalen = ntoh32(event->datalen); @@ -813,6 +839,7 @@ wl_show_host_event(wl_event_msg_t *event, void *event_data) DHD_EVENT(("MACEVENT: %s, MAC %s, %s, FAILURE, reason %d\n", event_name, eabuf, auth_str, (int)reason)); } + BCM_REFERENCE(auth_str); break; @@ -843,11 +870,14 @@ wl_show_host_event(wl_event_msg_t *event, void *event_data) case WLC_E_LINK: DHD_EVENT(("MACEVENT: %s %s\n", event_name, link?"UP":"DOWN")); + BCM_REFERENCE(link); break; case WLC_E_MIC_ERROR: DHD_EVENT(("MACEVENT: %s, MAC %s, Group %d, Flush %d\n", event_name, eabuf, group, flush_txq)); + BCM_REFERENCE(group); + BCM_REFERENCE(flush_txq); break; case WLC_E_ICV_ERROR: @@ -968,7 +998,7 @@ wl_host_event(dhd_pub_t *dhd_pub, int *ifidx, void *pktdata, /* check whether packet is a BRCM event pkt */ bcm_event_t *pvt_data = (bcm_event_t *)pktdata; uint8 *event_data; - uint32 type, status, reason, datalen; + uint32 type, status, datalen; uint16 flags; int evlen; @@ -992,7 +1022,6 @@ wl_host_event(dhd_pub_t *dhd_pub, int *ifidx, void *pktdata, type = ntoh32_ua((void *)&event->event_type); flags = ntoh16_ua((void *)&event->flags); status = ntoh32_ua((void *)&event->status); - reason = ntoh32_ua((void *)&event->reason); datalen = ntoh32_ua((void *)&event->datalen); evlen = datalen + sizeof(bcm_event_t); @@ -1010,26 +1039,26 @@ wl_host_event(dhd_pub_t *dhd_pub, int *ifidx, void *pktdata, case WLC_E_IF: { - dhd_if_event_t *ifevent = (dhd_if_event_t *)event_data; + dhd_if_event_t *ifevent = (dhd_if_event_t *)event_data; #ifdef PROP_TXSTATUS { - uint8* ea = pvt_data->eth.ether_dhost; - WLFC_DBGMESG(("WLC_E_IF: idx:%d, action:%s, iftype:%s, " - "[%02x:%02x:%02x:%02x:%02x:%02x]\n", - ifevent->ifidx, - ((ifevent->action == WLC_E_IF_ADD) ? "ADD":"DEL"), - ((ifevent->is_AP == 0) ? "STA":"AP "), - ea[0], ea[1], ea[2], ea[3], ea[4], ea[5])); - (void)ea; - - dhd_wlfc_interface_event(dhd_pub->info, - ((ifevent->action == WLC_E_IF_ADD) ? - eWLFC_MAC_ENTRY_ACTION_ADD : eWLFC_MAC_ENTRY_ACTION_DEL), - ifevent->ifidx, ifevent->is_AP, ea); - - /* dhd already has created an interface by default, for 0 */ - if (ifevent->ifidx == 0) - break; + uint8* ea = pvt_data->eth.ether_dhost; + WLFC_DBGMESG(("WLC_E_IF: idx:%d, action:%s, iftype:%s, " + "[%02x:%02x:%02x:%02x:%02x:%02x]\n", + ifevent->ifidx, + ((ifevent->action == WLC_E_IF_ADD) ? "ADD":"DEL"), + ((ifevent->is_AP == 0) ? "STA":"AP "), + ea[0], ea[1], ea[2], ea[3], ea[4], ea[5])); + (void)ea; + + dhd_wlfc_interface_event(dhd_pub->info, + ((ifevent->action == WLC_E_IF_ADD) ? + eWLFC_MAC_ENTRY_ACTION_ADD : eWLFC_MAC_ENTRY_ACTION_DEL), + ifevent->ifidx, ifevent->is_AP, ea); + + /* dhd already has created an interface by default, for 0 */ + if (ifevent->ifidx == 0) + break; } #endif /* PROP_TXSTATUS */ @@ -1043,7 +1072,7 @@ wl_host_event(dhd_pub_t *dhd_pub, int *ifidx, void *pktdata, return (BCME_OK); } #endif /* WL_CFG80211 */ - if (ifevent->ifidx > 0 && ifevent->ifidx < DHD_MAX_IFS) { + if (ifevent->ifidx > 0 && ifevent->ifidx < DHD_MAX_IFS) { if (ifevent->action == WLC_E_IF_ADD) { if (dhd_add_if(dhd_pub->info, ifevent->ifidx, NULL, event->ifname, @@ -1070,7 +1099,7 @@ wl_host_event(dhd_pub_t *dhd_pub, int *ifidx, void *pktdata, *ifidx = dhd_ifname2idx(dhd_pub->info, event->ifname); /* push up to external supp/auth */ dhd_event(dhd_pub->info, (char *)pvt_data, evlen, *ifidx); - break; + break; #ifdef WLMEDIA_HTSF @@ -1100,6 +1129,8 @@ wl_host_event(dhd_pub_t *dhd_pub, int *ifidx, void *pktdata, dhd_event(dhd_pub->info, (char *)pvt_data, evlen, *ifidx); DHD_TRACE(("%s: MAC event %d, flags %x, status %x\n", __FUNCTION__, type, flags, status)); + BCM_REFERENCE(flags); + BCM_REFERENCE(status); /* put it back to WLC_E_NDIS_LINK */ if (type == WLC_E_NDIS_LINK) { @@ -1488,7 +1519,7 @@ int dhd_arp_get_arp_hostip_table(dhd_pub_t *dhd, void *buf, int buflen) { int retcode, i; - int iov_len = 0; + int iov_len; uint32 *ptr32 = buf; bool clr_bottom = FALSE; @@ -1496,6 +1527,7 @@ dhd_arp_get_arp_hostip_table(dhd_pub_t *dhd, void *buf, int buflen) return -1; iov_len = bcm_mkiovar("arp_hostip", 0, 0, buf, buflen); + BCM_REFERENCE(iov_len); retcode = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, buflen, FALSE, 0); if (retcode) { @@ -1525,8 +1557,10 @@ void dhd_sendup_event_common(dhd_pub_t *dhdp, wl_event_msg_t *event, void *data) { switch (ntoh32(event->event_type)) { +#ifdef WLBTAMP case WLC_E_BTA_HCI_EVENT: break; +#endif /* WLBTAMP */ default: break; } @@ -2048,7 +2082,7 @@ int dhd_keep_alive_onoff(dhd_pub_t *dhd) mkeep_alive_pkt.keep_alive_id = 0; mkeep_alive_pkt.len_bytes = 0; buf_len += WL_MKEEP_ALIVE_FIXED_LEN; - /* Keep-alive attributes are set in local variable (mkeep_alive_pkt), and + /* Keep-alive attributes are set in local variable (mkeep_alive_pkt), and * then memcpy'ed into buffer (mkeep_alive_pktp) since there is no * guarantee that the buffer is properly aligned. */ diff --git a/drivers/net/wireless/bcmdhd/dhd_custom_gpio.c b/drivers/net/wireless/bcmdhd/dhd_custom_gpio.c index 9750eeb23bc..9a9d182e6b8 100644 --- a/drivers/net/wireless/bcmdhd/dhd_custom_gpio.c +++ b/drivers/net/wireless/bcmdhd/dhd_custom_gpio.c @@ -1,8 +1,8 @@ /* * Customer code to add GPIO control during WLAN start/stop -* Copyright (C) 1999-2011, Broadcom Corporation +* Copyright (C) 1999-2012, Broadcom Corporation * -* Unless you and Broadcom execute a separate written software license +* Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -20,7 +20,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * -* $Id: dhd_custom_gpio.c,v 1.2.42.1 2010-10-19 00:41:09 Exp $ +* $Id: dhd_custom_gpio.c 291086 2011-10-21 01:17:24Z $ */ #include @@ -98,7 +98,7 @@ int dhd_customer_oob_irq_map(unsigned long *irq_flags_ptr) if (dhd_oob_gpio_num < 0) { WL_ERROR(("%s: ERROR customer specific Host GPIO is NOT defined \n", - __FUNCTION__)); + __FUNCTION__)); return (dhd_oob_gpio_num); } @@ -289,5 +289,5 @@ void get_customized_country_code(char *country_iso_code, wl_country_t *cspec) cspec->rev = translate_custom_table[0].custom_locale_rev; #endif /* EXMAPLE_TABLE */ return; -#endif /* defined(CUSTOMER_HW2) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) */ +#endif /* defined(CUSTOMER_HW2) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) */ } diff --git a/drivers/net/wireless/bcmdhd/dhd_dbg.h b/drivers/net/wireless/bcmdhd/dhd_dbg.h index a195cbe88e5..2b40d2738c9 100644 --- a/drivers/net/wireless/bcmdhd/dhd_dbg.h +++ b/drivers/net/wireless/bcmdhd/dhd_dbg.h @@ -1,9 +1,9 @@ /* * Debug/trace/assert driver definitions for Dongle Host Driver. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: dhd_dbg.h 285933 2011-09-23 21:45:31Z $ + * $Id: dhd_dbg.h 308299 2012-01-14 01:36:58Z $ */ #ifndef _dhd_dbg_ @@ -44,6 +44,7 @@ #define DHD_BTA(args) do {if (dhd_msg_level & DHD_BTA_VAL) printf args;} while (0) #define DHD_ISCAN(args) do {if (dhd_msg_level & DHD_ISCAN_VAL) printf args;} while (0) #define DHD_ARPOE(args) do {if (dhd_msg_level & DHD_ARPOE_VAL) printf args;} while (0) +#define DHD_REORDER(args) do {if (dhd_msg_level & DHD_REORDER_VAL) printf args;} while (0) #define DHD_ERROR_ON() (dhd_msg_level & DHD_ERROR_VAL) #define DHD_TRACE_ON() (dhd_msg_level & DHD_TRACE_VAL) @@ -59,6 +60,7 @@ #define DHD_BTA_ON() (dhd_msg_level & DHD_BTA_VAL) #define DHD_ISCAN_ON() (dhd_msg_level & DHD_ISCAN_VAL) #define DHD_ARPOE_ON() (dhd_msg_level & DHD_ARPOE_VAL) +#define DHD_REORDER_ON() (dhd_msg_level & DHD_REORDER_VAL) #else /* defined(BCMDBG) || defined(DHD_DEBUG) */ @@ -76,6 +78,7 @@ #define DHD_BTA(args) #define DHD_ISCAN(args) #define DHD_ARPOE(args) +#define DHD_REORDER(args) #define DHD_ERROR_ON() 0 #define DHD_TRACE_ON() 0 @@ -91,11 +94,13 @@ #define DHD_BTA_ON() 0 #define DHD_ISCAN_ON() 0 #define DHD_ARPOE_ON() 0 +#define DHD_REORDER_ON() 0 #endif #define DHD_LOG(args) #define DHD_BLOG(cp, size) + #define DHD_NONE(args) extern int dhd_msg_level; diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.c b/drivers/net/wireless/bcmdhd/dhd_linux.c index b57af00a048..0ef8ae5c0a9 100644 --- a/drivers/net/wireless/bcmdhd/dhd_linux.c +++ b/drivers/net/wireless/bcmdhd/dhd_linux.c @@ -2,9 +2,9 @@ * Broadcom Dongle Host Driver (DHD), Linux-specific network interface * Basically selected code segments from usb-cdc.c and usb-rndis.c * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -22,7 +22,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: dhd_linux.c 308879 2012-01-17 22:03:47Z $ + * $Id: dhd_linux.c 309571 2012-01-20 01:45:10Z $ */ #include @@ -63,9 +63,11 @@ #include #endif +#ifdef WLBTAMP #include #include #include +#endif #ifdef WLMEDIA_HTSF #include @@ -101,6 +103,10 @@ extern bool ap_fw_loaded; /* enable HOSTIP cache update from the host side when an eth0:N is up */ #define AOE_IP_ALIAS_SUPPORT 1 +#ifdef BCM_FD_AGGR +#include +#include +#endif #ifdef PROP_TXSTATUS #include #include @@ -134,11 +140,15 @@ MODULE_LICENSE("GPL v2"); #include +#ifdef BCM_FD_AGGR +#define DBUS_RX_BUFFER_SIZE_DHD(net) (BCM_RPC_TP_DNGL_AGG_MAX_BYTE) +#else #ifndef PROP_TXSTATUS #define DBUS_RX_BUFFER_SIZE_DHD(net) (net->mtu + net->hard_header_len + dhd->pub.hdrlen) #else #define DBUS_RX_BUFFER_SIZE_DHD(net) (net->mtu + net->hard_header_len + dhd->pub.hdrlen + 128) #endif +#endif /* BCM_FD_AGGR */ #if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 15) const char * @@ -254,7 +264,7 @@ typedef struct dhd_info { struct wake_lock wl_rxwake; /* Wifi rx wakelock */ #endif -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 /* net_device interface lock, prevent race conditions among net_dev interface * calls and wifi_on or wifi_off */ @@ -278,6 +288,12 @@ typedef struct dhd_info { #ifdef ARP_OFFLOAD_SUPPORT u32 pend_ipaddr; #endif /* ARP_OFFLOAD_SUPPORT */ +#ifdef BCM_FD_AGGR + void *rpc_th; + void *rpc_osh; + struct timer_list rpcth_timer; + bool rpcth_timer_active; +#endif } dhd_info_t; /* Definitions to provide path to the firmware and nvram @@ -286,12 +302,12 @@ typedef struct dhd_info { char firmware_path[MOD_PARAM_PATHLEN]; char nvram_path[MOD_PARAM_PATHLEN]; -int op_mode = 0; -module_param(op_mode, int, 0644); extern int wl_control_wl_start(struct net_device *dev); extern int net_os_send_hang_message(struct net_device *dev); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) struct semaphore dhd_registration_sem; +struct semaphore dhd_chipup_sem; + #define DHD_REGISTRATION_TIMEOUT 12000 /* msec : allowed time to finished dhd registration */ #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ @@ -316,6 +332,7 @@ uint dhd_console_ms = 0; module_param(dhd_console_ms, uint, 0644); #endif /* defined(DHD_DEBUG) */ + /* ARP offload agent mode : Enable ARP Host Auto-Reply and ARP Peer Auto-Reply */ uint dhd_arp_mode = 0xb; module_param(dhd_arp_mode, uint, 0); @@ -334,7 +351,7 @@ module_param(dhd_pkt_filter_init, uint, 0); /* Pkt filter mode control */ uint dhd_master_mode = TRUE; -module_param(dhd_master_mode, uint, 0); +module_param(dhd_master_mode, uint, 1); #ifdef DHDTHREAD /* Watchdog thread priority, -1 to use kernel timer */ @@ -359,6 +376,19 @@ uint dhd_radio_up = 1; char iface_name[IFNAMSIZ] = {'\0'}; module_param_string(iface_name, iface_name, IFNAMSIZ, 0); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) +#define DAEMONIZE(a) daemonize(a); \ + allow_signal(SIGKILL); \ + allow_signal(SIGTERM); +#else /* Linux 2.4 (w/o preemption patch) */ +#define RAISE_RX_SOFTIRQ() \ + cpu_raise_softirq(smp_processor_id(), NET_RX_SOFTIRQ) +#define DAEMONIZE(a) daemonize(); \ + do { if (a) \ + strncpy(current->comm, a, MIN(sizeof(current->comm), (strlen(a) + 1))); \ + } while (0); +#endif /* LINUX_VERSION_CODE */ + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) #define BLOCKABLE() (!in_atomic()) #else @@ -430,9 +460,6 @@ static char dhd_version[] = "Dongle Host Driver, version " EPI_VERSION_STR ; static void dhd_net_if_lock_local(dhd_info_t *dhd); static void dhd_net_if_unlock_local(dhd_info_t *dhd); -#if !defined(AP) && defined(WLP2P) -static u32 dhd_concurrent_fw(dhd_pub_t *dhd); -#endif #ifdef WLMEDIA_HTSF void htsf_update(dhd_info_t *dhd, void *data); @@ -477,15 +504,15 @@ static int dhd_sleep_pm_callback(struct notifier_block *nfb, unsigned long actio #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)) switch (action) { - case PM_HIBERNATION_PREPARE: - case PM_SUSPEND_PREPARE: - dhd_mmc_suspend = TRUE; - ret = NOTIFY_OK; + case PM_HIBERNATION_PREPARE: + case PM_SUSPEND_PREPARE: + dhd_mmc_suspend = TRUE; + ret = NOTIFY_OK; break; - case PM_POST_HIBERNATION: - case PM_POST_SUSPEND: - dhd_mmc_suspend = FALSE; - ret = NOTIFY_OK; + case PM_POST_HIBERNATION: + case PM_POST_SUSPEND: + dhd_mmc_suspend = FALSE; + ret = NOTIFY_OK; break; } smp_mb(); @@ -495,7 +522,7 @@ static int dhd_sleep_pm_callback(struct notifier_block *nfb, unsigned long actio static struct notifier_block dhd_sleep_pm_notifier = { .notifier_call = dhd_sleep_pm_callback, - .priority = 10 + .priority = 0 }; extern int register_pm_notifier(struct notifier_block *nb); extern int unregister_pm_notifier(struct notifier_block *nb); @@ -934,7 +961,7 @@ extern tsk_ctl_t ap_eth_ctl; /* ap netdev heper thread ctl */ static void dhd_op_if(dhd_if_t *ifp) { - dhd_info_t *dhd; + dhd_info_t *dhd; int ret = 0, err = 0; #ifdef SOFTAP unsigned long flags; @@ -1135,7 +1162,7 @@ dhd_set_mac_address(struct net_device *dev, void *addr) if (ifidx == DHD_BAD_IF) return -1; - ASSERT(dhd->thr_sysioc_ctl.thr_pid >= 0); + ASSERT(&dhd->thr_sysioc_ctl.thr_pid >= 0); memcpy(&dhd->macvalue, sa->sa_data, ETHER_ADDR_LEN); dhd->set_macaddress = TRUE; up(&dhd->thr_sysioc_ctl.sema); @@ -1153,7 +1180,7 @@ dhd_set_multicast_list(struct net_device *dev) if (ifidx == DHD_BAD_IF) return; - ASSERT(dhd->thr_sysioc_ctl.thr_pid >= 0); + ASSERT(&dhd->thr_sysioc_ctl.thr_pid >= 0); dhd->iflist[ifidx]->set_multicast = TRUE; up(&dhd->thr_sysioc_ctl.sema); } @@ -1164,7 +1191,6 @@ dhd_os_wlfc_block(dhd_pub_t *pub) { dhd_info_t *di = (dhd_info_t *)(pub->info); ASSERT(di != NULL); - spin_lock_bh(&di->wlfc_spinlock); return 1; } @@ -1173,6 +1199,8 @@ int dhd_os_wlfc_unblock(dhd_pub_t *pub) { dhd_info_t *di = (dhd_info_t *)(pub->info); + + (void)di; ASSERT(di != NULL); spin_unlock_bh(&di->wlfc_spinlock); return 1; @@ -1207,8 +1235,8 @@ dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, void *pktbuf) if (ntoh16(eh->ether_type) == ETHER_TYPE_802_1X) atomic_inc(&dhd->pend_8021x_cnt); } else { - PKTFREE(dhd->pub.osh, pktbuf, TRUE); - return BCME_ERROR; + PKTFREE(dhd->pub.osh, pktbuf, TRUE); + return BCME_ERROR; } /* Look into the packet and update the packet priority */ @@ -1240,7 +1268,7 @@ dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, void *pktbuf) #endif #ifdef PROP_TXSTATUS if (dhdp->wlfc_state && ((athost_wl_status_info_t*)dhdp->wlfc_state)->proptxstatus_mode - != WLFC_FCMODE_NONE) { + != WLFC_FCMODE_NONE) { dhd_os_wlfc_block(dhdp); ret = dhd_wlfc_enque_sendq(dhdp->wlfc_state, DHD_PKTTAG_FIFO(PKTTAG(pktbuf)), pktbuf); @@ -1258,7 +1286,6 @@ dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, void *pktbuf) ret = dhd_bus_txdata(dhdp->bus, pktbuf); #endif /* PROP_TXSTATUS */ - return ret; } @@ -1398,19 +1425,21 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan) struct sk_buff *skb; uchar *eth; uint len; - void *data, *pnext = NULL, *save_pktbuf; + void *data, *pnext = NULL; int i; dhd_if_t *ifp; wl_event_msg_t event; int tout = DHD_PACKET_TIMEOUT_MS; - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - save_pktbuf = pktbuf; + BCM_REFERENCE(tout); + DHD_TRACE(("%s: Enter\n", __FUNCTION__)); for (i = 0; pktbuf && i < numpkt; i++, pktbuf = pnext) { +#ifdef WLBTAMP struct ether_header *eh; struct dot11_llc_snap_header *lsh; +#endif ifp = dhd->iflist[ifidx]; if (ifp == NULL) { @@ -1433,6 +1462,7 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan) pnext = PKTNEXT(dhdp->osh, pktbuf); PKTSETNEXT(wl->sh.osh, pktbuf, NULL); +#ifdef WLBTAMP eh = (struct ether_header *)PKTDATA(wl->sh.osh, pktbuf); lsh = (struct dot11_llc_snap_header *)&eh[1]; @@ -1444,6 +1474,7 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan) ((uint8 *)eh + RFC1042_HDR_LEN); ACL_data = NULL; } +#endif /* WLBTAMP */ #ifdef PROP_TXSTATUS if (dhdp->wlfc_state && PKTLEN(wl->sh.osh, pktbuf) == 0) { @@ -1487,7 +1518,7 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan) skb->len = len; #ifdef WLMEDIA_HTSF - dhd_htsf_addrxts(dhdp, pktbuf); + dhd_htsf_addrxts(dhdp, pktbuf); #endif /* Strip header, count, deliver upward */ skb_pull(skb, ETH_HLEN); @@ -1503,13 +1534,13 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan) &event, &data); +#ifdef WLBTAMP wl_event_to_host_order(&event); - tout = DHD_EVENT_TIMEOUT_MS; if (event.event_type == WLC_E_BTA_HCI_EVENT) { dhd_bta_doevt(dhdp, data, event.datalen); - } else if (event.event_type == WLC_E_PFN_NET_FOUND) { - tout *= 2; } + tout = DHD_EVENT_TIMEOUT_MS; +#endif /* WLBTAMP */ } ASSERT(ifidx < DHD_MAX_IFS && dhd->iflist[ifidx]); @@ -1559,9 +1590,11 @@ dhd_txcomplete(dhd_pub_t *dhdp, void *txp, bool success) dhd_info_t *dhd = (dhd_info_t *)(dhdp->info); struct ether_header *eh; uint16 type; +#ifdef WLBTAMP uint len; +#endif - dhd_prot_hdrpull(dhdp, &ifidx, txp); + dhd_prot_hdrpull(dhdp, &ifidx, txp, NULL, NULL); eh = (struct ether_header *)PKTDATA(dhdp->osh, txp); type = ntoh16(eh->ether_type); @@ -1569,6 +1602,7 @@ dhd_txcomplete(dhd_pub_t *dhdp, void *txp, bool success) if (type == ETHER_TYPE_802_1X) atomic_dec(&dhd->pend_8021x_cnt); +#ifdef WLBTAMP /* Crack open the packet and check to see if it is BT HCI ACL data packet. * If yes generate packet completion event. */ @@ -1584,6 +1618,7 @@ dhd_txcomplete(dhd_pub_t *dhdp, void *txp, bool success) dhd_bta_tx_hcidata_complete(dhdp, txp, success); } } +#endif /* WLBTAMP */ } static struct net_device_stats * @@ -1673,7 +1708,7 @@ dhd_watchdog_thread(void *data) DHD_OS_WAKE_UNLOCK(&dhd->pub); } else { break; - } + } complete_and_exit(&tsk->completed, 0); } @@ -2093,6 +2128,11 @@ dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd) /* Copy out any buffer passed */ if (ioc.buf) { + if (ioc.len == 0) { + DHD_TRACE(("%s: ioc.len=0, returns BCME_BADARG \n", __FUNCTION__)); + bcmerror = -BCME_BADARG; + goto done; + } buflen = MIN(ioc.len, DHD_IOCTL_MAXLEN); /* optimization for direct ioctl calls from kernel */ /* @@ -2208,6 +2248,13 @@ dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd) } #endif /* WLMEDIA_HTSF */ +#ifdef BCM_FD_AGGR + if ((ioc.cmd == WLC_SET_VAR || ioc.cmd == WLC_GET_VAR) && + ioc.buf != NULL && strncmp("rpc_", ioc.buf, 4) == 0) { + bcmerror = dhd_fdaggr_ioctl(&dhd->pub, ifidx, (wl_ioctl_t *)&ioc, buf, buflen); + goto done; + } +#endif bcmerror = dhd_wl_ioctl(&dhd->pub, ifidx, (wl_ioctl_t *)&ioc, buf, buflen); done: @@ -2246,17 +2293,17 @@ dhd_cleanup_virt_ifaces(dhd_info_t *dhd) #endif for (i = 1; i < DHD_MAX_IFS; i++) { - dhd_net_if_lock_local(dhd); if (dhd->iflist[i]) { DHD_TRACE(("Deleting IF: %d \n", i)); if ((dhd->iflist[i]->state != DHD_IF_DEL) && (dhd->iflist[i]->state != DHD_IF_DELETING)) { dhd->iflist[i]->state = DHD_IF_DEL; dhd->iflist[i]->idx = i; + dhd_net_if_lock_local(dhd); dhd_op_if(dhd->iflist[i]); + dhd_net_if_unlock_local(dhd); } } - dhd_net_if_unlock_local(dhd); } #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) @@ -2279,6 +2326,7 @@ dhd_stop(struct net_device *net) goto exit; } ifidx = dhd_net2idx(dhd, net); + BCM_REFERENCE(ifidx); #ifdef WL_CFG80211 if (ifidx == 0) { @@ -2308,7 +2356,8 @@ dhd_stop(struct net_device *net) #if defined(WL_CFG80211) if (ifidx == 0 && !dhd_download_fw_on_driverload) wl_android_wifi_off(net); -#endif +#endif + dhd->pub.hang_was_sent = 0; dhd->pub.rxcnt_timeout = 0; dhd->pub.txcnt_timeout = 0; OLD_MOD_DEC_USE_COUNT; @@ -2327,7 +2376,6 @@ dhd_open(struct net_device *net) #endif int ifidx; int32 ret = 0; - DHD_OS_WAKE_LOCK(&dhd->pub); /* Update FW path if it was changed */ if ((firmware_path != NULL) && (firmware_path[0] != '\0')) { @@ -2337,21 +2385,14 @@ dhd_open(struct net_device *net) firmware_path[0] = '\0'; } - dhd->pub.hang_was_sent = 0; - #if !defined(WL_CFG80211) /* * Force start if ifconfig_up gets called before START command - * We keep WEXT's wl_control_wl_start to provide backward compatibility - * This should be removed in the future + * We keep WEXT's wl_control_wl_start to provide backward compatibility + * This should be removed in the future */ - ret = wl_control_wl_start(net); - if (ret != 0) { - DHD_ERROR(("%s: failed with code %d\n", __FUNCTION__, ret)); - ret = -1; - goto exit; - } -#endif + wl_control_wl_start(net); +#endif ifidx = dhd_net2idx(dhd, net); DHD_TRACE(("%s: ifidx %d\n", __FUNCTION__, ifidx)); @@ -2375,12 +2416,11 @@ dhd_open(struct net_device *net) if (!dhd_download_fw_on_driverload) { ret = wl_android_wifi_on(net); if (ret != 0) { - DHD_ERROR(("%s: failed with code %d\n", __FUNCTION__, ret)); - ret = -1; + DHD_ERROR(("wl_android_wifi_on failed (%d)\n", ret)); goto exit; } } -#endif /* defined(WL_CFG80211) */ +#endif if (dhd->pub.busstate != DHD_BUS_DATA) { @@ -2427,32 +2467,6 @@ exit: return ret; } -int dhd_do_driver_init(struct net_device *net) -{ - dhd_info_t *dhd = NULL; - - if (!net) { - DHD_ERROR(("Primary Interface not initialized \n")); - return -EINVAL; - } - - dhd = *(dhd_info_t **)netdev_priv(net); - - /* If driver is already initialized, do nothing - */ - if (dhd->pub.busstate == DHD_BUS_DATA) { - DHD_TRACE(("Driver already Inititalized. Nothing to do")); - return 0; - } - - if (dhd_open(net) < 0) { - DHD_ERROR(("Driver Init Failed \n")); - return -1; - } - - return 0; -} - osl_t * dhd_osl_attach(void *pdev, uint bustype) { @@ -2466,9 +2480,10 @@ dhd_osl_detach(osl_t *osh) DHD_ERROR(("%s: MEMORY LEAK %d bytes\n", __FUNCTION__, MALLOCED(osh))); } osl_detach(osh); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) +#if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) up(&dhd_registration_sem); -#endif + up(&dhd_chipup_sem); +#endif } int @@ -2506,7 +2521,7 @@ dhd_add_if(dhd_info_t *dhd, int ifidx, void *handle, char *name, ifp->state = DHD_IF_ADD; ifp->idx = ifidx; ifp->bssidx = bssidx; - ASSERT(dhd->thr_sysioc_ctl.thr_pid >= 0); + ASSERT(&dhd->thr_sysioc_ctl.thr_pid >= 0); up(&dhd->thr_sysioc_ctl.sema); } else ifp->net = (struct net_device *)handle; @@ -2530,7 +2545,7 @@ dhd_del_if(dhd_info_t *dhd, int ifidx) ifp->state = DHD_IF_DEL; ifp->idx = ifidx; - ASSERT(dhd->thr_sysioc_ctl.thr_pid >= 0); + ASSERT(&dhd->thr_sysioc_ctl.thr_pid >= 0); up(&dhd->thr_sysioc_ctl.sema); } @@ -2542,7 +2557,11 @@ static struct net_device_ops dhd_ops_pri = { .ndo_do_ioctl = dhd_ioctl_entry, .ndo_start_xmit = dhd_start_xmit, .ndo_set_mac_address = dhd_set_mac_address, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) .ndo_set_rx_mode = dhd_set_multicast_list, +#else + .ndo_set_multicast_list = dhd_set_multicast_list, +#endif }; static struct net_device_ops dhd_ops_virt = { @@ -2550,7 +2569,11 @@ static struct net_device_ops dhd_ops_virt = { .ndo_do_ioctl = dhd_ioctl_entry, .ndo_start_xmit = dhd_start_xmit, .ndo_set_mac_address = dhd_set_mac_address, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) .ndo_set_rx_mode = dhd_set_multicast_list, +#else + .ndo_set_multicast_list = dhd_set_multicast_list, +#endif }; #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)) */ @@ -2650,7 +2673,7 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen) wake_lock_init(&dhd->wl_wifi, WAKE_LOCK_SUSPEND, "wlan_wake"); wake_lock_init(&dhd->wl_rxwake, WAKE_LOCK_SUSPEND, "wlan_rx_wake"); #endif -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 mutex_init(&dhd->dhd_net_if_mutex); #endif dhd_state |= DHD_ATTACH_STATE_WAKELOCKS_INIT; @@ -2676,9 +2699,9 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen) /* Attach and link in the iw */ if (!(dhd_state & DHD_ATTACH_STATE_CFG80211)) { if (wl_iw_attach(net, (void *)&dhd->pub) != 0) { - DHD_ERROR(("wl_iw_attach failed\n")); - goto fail; - } + DHD_ERROR(("wl_iw_attach failed\n")); + goto fail; + } dhd_state |= DHD_ATTACH_STATE_WL_ATTACH; } #endif /* defined(CONFIG_WIRELESS_EXT) */ @@ -2784,6 +2807,7 @@ dhd_bus_start(dhd_pub_t *dhdp) dhd_os_sdlock(dhdp); #endif /* DHDTHREAD */ + /* try to download image and nvram to the dongle */ if ((dhd->pub.busstate == DHD_BUS_DOWN) && (fw_path != NULL) && (fw_path[0] != '\0') && @@ -2887,37 +2911,6 @@ dhd_bus_start(dhd_pub_t *dhdp) return 0; } -#if !defined(AP) && defined(WLP2P) -/* For Android ICS MR2 release, the concurrent mode is enabled by default and the firmware - * name would be fw_bcmdhd.bin. So we need to determine whether P2P is enabled in the STA - * firmware and accordingly enable concurrent mode (Apply P2P settings). SoftAP firmware - * would still be named as fw_bcmdhd_apsta. - */ -static u32 -dhd_concurrent_fw(dhd_pub_t *dhd) -{ - int ret = 0; - char buf[WLC_IOCTL_SMLEN]; - - if ((!op_mode) && (strstr(fw_path, "_p2p") == NULL) && - (strstr(fw_path, "_apsta") == NULL)) { - /* Given path is for the STA firmware. Check whether P2P support is present in - * the firmware. If so, set mode as P2P (concurrent support). - */ - memset(buf, 0, sizeof(buf)); - bcm_mkiovar("p2p", 0, 0, buf, sizeof(buf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, sizeof(buf), - FALSE, 0)) < 0) { - DHD_TRACE(("%s: Get P2P failed (error=%d)\n", __FUNCTION__, ret)); - } else if (buf[0] == 1) { - DHD_TRACE(("%s: P2P is supported\n", __FUNCTION__)); - return 1; - } - } - return 0; -} -#endif - int dhd_preinit_ioctls(dhd_pub_t *dhd) { @@ -2978,12 +2971,13 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) } /* Update public MAC address after reading from Firmware */ memcpy(dhd->mac.octet, buf, ETHER_ADDR_LEN); + #ifdef GET_CUSTOM_MAC_ENABLE } #endif /* GET_CUSTOM_MAC_ENABLE */ #ifdef SET_RANDOM_MAC_SOFTAP - if ((!op_mode && strstr(fw_path, "_apsta") != NULL) || (op_mode == 0x02)) { + if (strstr(fw_path, "_apsta") != NULL) { uint rand_mac; srandom32((uint)jiffies); @@ -3007,8 +3001,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) DHD_TRACE(("Firmware = %s\n", fw_path)); #if !defined(AP) && defined(WLP2P) /* Check if firmware with WFD support used */ - if ((!op_mode && strstr(fw_path, "_p2p") != NULL) || (op_mode == 0x04) || - (dhd_concurrent_fw(dhd))) { + if (strstr(fw_path, "_p2p") != NULL) { bcm_mkiovar("apsta", (char *)&apsta, 4, iovbuf, sizeof(iovbuf)); if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) { @@ -3021,11 +3014,11 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) dhd_pkt_filter_enable = FALSE; } } -#endif +#endif #if !defined(AP) && defined(WL_CFG80211) /* Check if firmware with HostAPD support used */ - if ((!op_mode && strstr(fw_path, "_apsta") != NULL) || (op_mode == 0x02)) { + if (strstr(fw_path, "_apsta") != NULL) { /* Turn off MPC in AP mode */ bcm_mkiovar("mpc", (char *)&mpc, 4, iovbuf, sizeof(iovbuf)); if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, @@ -3039,7 +3032,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) dhd_pkt_filter_enable = FALSE; } } -#endif +#endif if ((dhd->op_mode != WFD_MASK) && (dhd->op_mode != HOSTAPD_MASK)) { /* STA only operation mode */ @@ -3095,7 +3088,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) if (ap_fw_loaded == TRUE) { dhd_wl_ioctl_cmd(dhd, WLC_SET_DTIMPRD, (char *)&dtim, sizeof(dtim), TRUE, 0); } -#endif +#endif #if defined(KEEP_ALIVE) { @@ -3104,7 +3097,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) #if defined(SOFTAP) if (ap_fw_loaded == FALSE) -#endif +#endif if ((res = dhd_keep_alive_onoff(dhd)) < 0) DHD_ERROR(("%s set keeplive failed %d\n", __FUNCTION__, res)); @@ -3224,8 +3217,6 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) bcmstrtok(&ptr, "\n", 0); /* Print fw version info */ DHD_ERROR(("Firmware version = %s\n", buf)); - DHD_BLOG(buf, strlen(buf) + 1); - DHD_BLOG(dhd_version, strlen(dhd_version) + 1); } done: @@ -3435,7 +3426,7 @@ dhd_net_attach(dhd_pub_t *dhdp, int ifidx) #else ASSERT(!net->netdev_ops); net->netdev_ops = &dhd_ops_virt; -#endif +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31) */ /* Ok, link into the network layer... */ if (ifidx == 0) { @@ -3447,7 +3438,7 @@ dhd_net_attach(dhd_pub_t *dhdp, int ifidx) net->stop = dhd_stop; #else net->netdev_ops = &dhd_ops_pri; -#endif +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31) */ } else { /* * We have to use the primary MAC for virtual interfaces @@ -3498,12 +3489,11 @@ dhd_net_attach(dhd_pub_t *dhdp, int ifidx) wl_iw_iscan_set_scan_broadcast_prep(net, 1); #endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) +#if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) if (ifidx == 0) { up(&dhd_registration_sem); } -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ +#endif return 0; fail: @@ -3528,7 +3518,7 @@ dhd_bus_detach(dhd_pub_t *dhdp) /* * In case of Android cfg80211 driver, the bus is down in dhd_stop, - * calling stop again will cuase SD read/write errors. + * calling stop again will cuase SD read/write errors. */ if (dhd->pub.busstate != DHD_BUS_DOWN) { /* Stop the protocol module */ @@ -3579,6 +3569,7 @@ void dhd_detach(dhd_pub_t *dhdp) } #endif /* defined(CONFIG_HAS_EARLYSUSPEND) */ + #if defined(CONFIG_WIRELESS_EXT) if (dhd->dhd_state & DHD_ATTACH_STATE_WL_ATTACH) { /* Detatch and unlink in the iw */ @@ -3586,7 +3577,7 @@ void dhd_detach(dhd_pub_t *dhdp) } #endif /* defined(CONFIG_WIRELESS_EXT) */ - if (dhd->thr_sysioc_ctl.thr_pid >= 0) { + if (&dhd->thr_sysioc_ctl.thr_pid >= 0) { PROC_STOP(&dhd->thr_sysioc_ctl); } @@ -3596,19 +3587,17 @@ void dhd_detach(dhd_pub_t *dhdp) dhd_if_t *ifp; /* Cleanup virtual interfaces */ - for (i = 1; i < DHD_MAX_IFS; i++) { - dhd_net_if_lock_local(dhd); + for (i = 1; i < DHD_MAX_IFS; i++) if (dhd->iflist[i]) { dhd->iflist[i]->state = DHD_IF_DEL; dhd->iflist[i]->idx = i; dhd_op_if(dhd->iflist[i]); } - dhd_net_if_unlock_local(dhd); - } + /* delete primary interface 0 */ ifp = dhd->iflist[0]; ASSERT(ifp); - + ASSERT(ifp->net); #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)) if (ifp->net->open) #else @@ -3622,6 +3611,7 @@ void dhd_detach(dhd_pub_t *dhdp) } MFREE(dhd->pub.osh, ifp, sizeof(*ifp)); dhd->iflist[0] = NULL; + } } @@ -3660,9 +3650,11 @@ void dhd_detach(dhd_pub_t *dhdp) } #endif + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) unregister_pm_notifier(&dhd_sleep_pm_notifier); #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */ + /* && defined(CONFIG_PM_SLEEP) */ if (dhd->dhd_state & DHD_ATTACH_STATE_WAKELOCKS_INIT) { #ifdef CONFIG_HAS_WAKELOCK @@ -3680,6 +3672,22 @@ dhd_free(dhd_pub_t *dhdp) DHD_TRACE(("%s: Enter\n", __FUNCTION__)); if (dhdp) { + int i; + for (i = 0; i < ARRAYSIZE(dhdp->reorder_bufs); i++) { + if (dhdp->reorder_bufs[i]) { + reorder_info_t *ptr; + uint32 buf_size = sizeof(struct reorder_info); + + ptr = dhdp->reorder_bufs[i]; + + buf_size += ((ptr->max_idx + 1) * sizeof(void*)); + DHD_REORDER(("free flow id buf %d, maxidx is %d, buf_size %d\n", + i, ptr->max_idx, buf_size)); + + MFREE(dhdp->osh, dhdp->reorder_bufs[i], buf_size); + dhdp->reorder_bufs[i] = NULL; + } + } dhd = (dhd_info_t *)dhdp->info; if (dhd) MFREE(dhd->pub.osh, dhd, sizeof(*dhd)); @@ -3702,16 +3710,22 @@ dhd_module_cleanup(void) dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF); } + static int __init dhd_module_init(void) { int error = 0; +#if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) + int retry = POWERUP_MAX_RETRY; + int chip_up = 0; +#endif + DHD_TRACE(("%s: Enter\n", __FUNCTION__)); wl_android_init(); -#ifdef DHDTHREAD +#if defined(DHDTHREAD) /* Sanity check on the module parameters */ do { /* Both watchdog and DPC as tasklets are ok */ @@ -3725,19 +3739,43 @@ dhd_module_init(void) DHD_ERROR(("Invalid module parameters.\n")); return -EINVAL; } while (0); -#endif /* DHDTHREAD */ - - /* Call customer gpio to turn on power with WL_REG_ON signal */ - dhd_customer_gpio_wlan_ctrl(WLAN_POWER_ON); +#endif +#if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) + do { + dhd_customer_gpio_wlan_ctrl(WLAN_POWER_ON); #if defined(CONFIG_WIFI_CONTROL_FUNC) - if (wl_android_wifictrl_func_add() < 0) - goto fail_1; -#endif + if (wl_android_wifictrl_func_add() < 0) + goto fail_1; +#endif /* defined(CONFIG_WIFI_CONTROL_FUNC) */ + sema_init(&dhd_chipup_sem, 0); + dhd_bus_reg_sdio_notify(&dhd_chipup_sem); + if (down_timeout(&dhd_chipup_sem, + msecs_to_jiffies(POWERUP_WAIT_MS)) == 0) { + dhd_bus_unreg_sdio_notify(); + chip_up = 1; + break; + } + DHD_ERROR(("\nfailed to power up wifi chip, retry again (%d left) **\n\n", + retry+1)); + dhd_bus_unreg_sdio_notify(); +#if defined(CONFIG_WIFI_CONTROL_FUNC) + wl_android_wifictrl_func_del(); +#endif /* defined(CONFIG_WIFI_CONTROL_FUNC) */ + dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF); + } while (retry-- > 0); + + if (!chip_up) { + DHD_ERROR(("\nfailed to power up wifi chip, max retry reached, exits **\n\n")); + return -ENODEV; + } +#endif + +#if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) + sema_init(&dhd_registration_sem, 0); +#endif + -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - sema_init(&dhd_registration_sem, 0); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ error = dhd_bus_register(); if (!error) @@ -3748,27 +3786,30 @@ dhd_module_init(void) } #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - /* - * Wait till MMC sdio_register_driver callback called and made driver attach. - * It's needed to make sync up exit from dhd insmod and - * Kernel MMC sdio device callback registration - */ + /* + * Wait till MMC sdio_register_driver callback called and made driver attach. + * It's needed to make sync up exit from dhd insmod and + * Kernel MMC sdio device callback registration + */ if (down_timeout(&dhd_registration_sem, msecs_to_jiffies(DHD_REGISTRATION_TIMEOUT)) != 0) { - error = -EINVAL; + error = -ENODEV; DHD_ERROR(("%s: sdio_register_driver timeout\n", __FUNCTION__)); goto fail_2; - } -#endif + } +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ #if defined(WL_CFG80211) wl_android_post_init(); -#endif +#endif /* defined(WL_CFG80211) */ return error; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && 1 + +#if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) fail_2: dhd_bus_unregister(); #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ + fail_1: + #if defined(CONFIG_WIFI_CONTROL_FUNC) wl_android_wifictrl_func_del(); #endif @@ -3784,6 +3825,7 @@ late_initcall(dhd_module_init); #else module_init(dhd_module_init); #endif + module_exit(dhd_module_cleanup); /* @@ -3926,10 +3968,10 @@ dhd_os_open_image(char *filename) * fp = open_namei(AT_FDCWD, filename, O_RD, 0); * ??? */ - if (IS_ERR(fp)) + if (IS_ERR(fp)) fp = NULL; - return fp; + return fp; } int @@ -4035,7 +4077,7 @@ uint8* dhd_os_prealloc(void *osh, int section, uint size) void dhd_os_prefree(void *osh, void *addr, uint size) { } -#endif /* defined(CONFIG_DHD_USE_STATIC_BUF) */ +#endif /* defined(CONFIG_WIFI_CONTROL_FUNC) */ #if defined(CONFIG_WIRELESS_EXT) struct iw_statistics * @@ -4074,23 +4116,17 @@ dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata, * Wireless ext is on primary interface only */ - ASSERT(dhd->iflist[*ifidx] != NULL); - ASSERT(dhd->iflist[*ifidx]->net != NULL); + ASSERT(dhd->iflist[*ifidx] != NULL); + ASSERT(dhd->iflist[*ifidx]->net != NULL); if (dhd->iflist[*ifidx]->net) { - wl_iw_event(dhd->iflist[*ifidx]->net, event, *data); + wl_iw_event(dhd->iflist[*ifidx]->net, event, *data); } } #endif /* defined(CONFIG_WIRELESS_EXT) */ #ifdef WL_CFG80211 - if ((ntoh32(event->event_type) == WLC_E_IF) && - (((dhd_if_event_t *)*data)->action == WLC_E_IF_ADD)) - /* If ADD_IF has been called directly by wl utility then we - * should not report this. In case if ADD_IF was called from - * CFG stack, then too this event need not be reported back - */ - return (BCME_OK); + if ((wl_cfg80211_is_progress_ifchange() || wl_cfg80211_is_progress_ifadd()) && (*ifidx != 0)) { /* @@ -4115,6 +4151,7 @@ void dhd_sendup_event(dhd_pub_t *dhdp, wl_event_msg_t *event, void *data) { switch (ntoh32(event->event_type)) { +#ifdef WLBTAMP /* Send up locally generated AMP HCI Events */ case WLC_E_BTA_HCI_EVENT: { struct sk_buff *p, *skb; @@ -4206,9 +4243,10 @@ dhd_sendup_event(dhd_pub_t *dhdp, wl_event_msg_t *event, void *data) else { /* Could not allocate a sk_buf */ DHD_ERROR(("%s: unable to alloc sk_buf", __FUNCTION__)); - } +} break; } /* case WLC_E_BTA_HCI_EVENT */ +#endif /* WLBTAMP */ default: break; @@ -4217,7 +4255,7 @@ dhd_sendup_event(dhd_pub_t *dhdp, wl_event_msg_t *event, void *data) void dhd_wait_for_event(dhd_pub_t *dhd, bool *lockvar) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) +#if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) struct dhd_info *dhdinfo = dhd->info; dhd_os_sdunlock(dhd); wait_event_interruptible_timeout(dhdinfo->ctrl_wait, (*lockvar == FALSE), HZ * 2); @@ -4228,7 +4266,7 @@ void dhd_wait_for_event(dhd_pub_t *dhd, bool *lockvar) void dhd_wait_event_wakeup(dhd_pub_t *dhd) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) +#if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) struct dhd_info *dhdinfo = dhd->info; if (waitqueue_active(&dhdinfo->ctrl_wait)) wake_up_interruptible(&dhdinfo->ctrl_wait); @@ -4399,8 +4437,6 @@ int net_os_send_hang_message(struct net_device *dev) #endif #if defined(WL_CFG80211) ret = wl_cfg80211_hang(dev, WLAN_REASON_UNSPECIFIED); - dev_close(dev); - dev_open(dev); #endif } } @@ -4415,7 +4451,6 @@ void dhd_bus_country_set(struct net_device *dev, wl_country_t *cspec) memcpy(&dhd->pub.dhd_cspec, cspec, sizeof(wl_country_t)); } - void dhd_net_if_lock(struct net_device *dev) { dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); @@ -4430,7 +4465,7 @@ void dhd_net_if_unlock(struct net_device *dev) static void dhd_net_if_lock_local(dhd_info_t *dhd) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 if (dhd) mutex_lock(&dhd->dhd_net_if_mutex); #endif @@ -4438,7 +4473,7 @@ static void dhd_net_if_lock_local(dhd_info_t *dhd) static void dhd_net_if_unlock_local(dhd_info_t *dhd) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 if (dhd) mutex_unlock(&dhd->dhd_net_if_mutex); #endif @@ -4648,7 +4683,6 @@ int dhd_os_check_wakelock(void *dhdp) #endif return 0; } - int net_os_wake_unlock(struct net_device *dev) { dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); @@ -4667,7 +4701,6 @@ int dhd_os_check_if_up(void *dhdp) return 0; return pub->up; } - int dhd_ioctl_entry_local(struct net_device *net, wl_ioctl_t *ioc, int cmd) { int ifidx; @@ -4708,7 +4741,8 @@ extern int dhd_wlfc_interface_entry_update(void* state, ewlfc_mac_entry_action_t extern int dhd_wlfc_FIFOcreditmap_update(void* state, uint8* credits); int dhd_wlfc_interface_event(struct dhd_info *dhd, - ewlfc_mac_entry_action_t action, uint8 ifid, uint8 iftype, uint8* ea) + ewlfc_mac_entry_action_t action, uint8 ifid, uint8 iftype, + uint8* ea) { if (dhd->pub.wlfc_state == NULL) return BCME_OK; diff --git a/drivers/net/wireless/bcmdhd/dhd_linux_sched.c b/drivers/net/wireless/bcmdhd/dhd_linux_sched.c index aadd122f5b0..290caf7e658 100644 --- a/drivers/net/wireless/bcmdhd/dhd_linux_sched.c +++ b/drivers/net/wireless/bcmdhd/dhd_linux_sched.c @@ -1,9 +1,9 @@ /* * Expose some of the kernel scheduler routines * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: dhd_linux_sched.c,v 1.3 2009-04-10 04:14:49 Exp $ + * $Id: dhd_linux_sched.c 291086 2011-10-21 01:17:24Z $ */ #include #include diff --git a/drivers/net/wireless/bcmdhd/dhd_proto.h b/drivers/net/wireless/bcmdhd/dhd_proto.h index e0a54ad0269..e420166a95a 100644 --- a/drivers/net/wireless/bcmdhd/dhd_proto.h +++ b/drivers/net/wireless/bcmdhd/dhd_proto.h @@ -4,9 +4,9 @@ * Provides type definitions and function prototypes used to link the * DHD OS, bus, and protocol modules. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -24,7 +24,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: dhd_proto.h,v 1.8.10.6 2010-12-22 23:47:24 Exp $ + * $Id: dhd_proto.h 303834 2011-12-20 06:17:39Z $ */ #ifndef _dhd_proto_h_ @@ -35,7 +35,7 @@ #ifndef IOCTL_RESP_TIMEOUT #define IOCTL_RESP_TIMEOUT 20000 /* In milli second */ -#endif +#endif /* IOCTL_RESP_TIMEOUT */ /* * Exported from the dhd protocol module (dhd_cdc, dhd_rndis) @@ -61,7 +61,7 @@ extern void dhd_prot_stop(dhd_pub_t *dhdp); extern void dhd_prot_hdrpush(dhd_pub_t *, int ifidx, void *txp); /* Remove any protocol-specific data header. */ -extern int dhd_prot_hdrpull(dhd_pub_t *, int *ifidx, void *rxp); +extern int dhd_prot_hdrpull(dhd_pub_t *, int *ifidx, void *rxp, uchar *buf, uint *len); /* Use protocol to issue ioctl to dongle */ extern int dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t * ioc, void * buf, int len); @@ -89,6 +89,10 @@ extern int dhd_wlfc_commit_packets(void* state, f_commitpkt_t fcommit, void* com extern void dhd_wlfc_cleanup(dhd_pub_t *dhd); #endif /* PROP_TXSTATUS */ +extern int dhd_process_pkt_reorder_info(dhd_pub_t *dhd, uchar *reorder_info_buf, + uint reorder_info_len, void **pkt, uint32 *free_buf_count); + + /******************************** * For version-string expansion * */ diff --git a/drivers/net/wireless/bcmdhd/dhd_sdio.c b/drivers/net/wireless/bcmdhd/dhd_sdio.c index d7823167cca..0b0377a8f47 100644 --- a/drivers/net/wireless/bcmdhd/dhd_sdio.c +++ b/drivers/net/wireless/bcmdhd/dhd_sdio.c @@ -1,9 +1,9 @@ /* * DHD Bus Module for SDIO * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: dhd_sdio.c 309234 2012-01-19 01:44:16Z $ + * $Id: dhd_sdio.c 309548 2012-01-20 01:13:08Z $ */ #include @@ -159,6 +159,18 @@ typedef struct dhd_console { } dhd_console_t; #endif /* DHD_DEBUG */ +#define REMAP_ENAB(bus) ((bus)->remap) +#define REMAP_ISADDR(bus, a) (((a) >= ((bus)->orig_ramsize)) && ((a) < ((bus)->ramsize))) +#define KSO_ENAB(bus) ((bus)->kso) +#define SLPAUTO_ENAB(bus) ((bus)->_slpauto) + +#define OOB_WAKEUP_ENAB(bus) ((bus)->_oobwakeup) +#define GPIO_DEV_SRSTATE 16 /* Host gpio17 mapped to device gpio0 SR state */ +#define GPIO_DEV_SRSTATE_TIMEOUT 320000 /* 320ms */ +#define GPIO_DEV_WAKEUP 17 /* Host gpio17 mapped to device gpio1 wakeup */ +#define CC_CHIPCTRL2_GPIO1_WAKEUP (1 << 0) + + /* Private data for SDIO bus interaction */ typedef struct dhd_bus { dhd_pub_t *dhd; @@ -183,8 +195,8 @@ typedef struct dhd_bus { bool fcstate; /* State of dongle flow-control */ uint16 cl_devid; /* cached devid for dhdsdio_probe_attach() */ - char *fw_path; /* module_param: path to firmware image */ - char *nv_path; /* module_param: path to nvram vars file */ + char *fw_path; /* module_param: path to firmware image */ + char *nv_path; /* module_param: path to nvram vars file */ const char *nvram_params; /* user specified nvram params. */ uint blocksize; /* Block size of SDIO transfers */ @@ -242,7 +254,7 @@ typedef struct dhd_bus { int32 sd_rxchain; /* If bcmsdh api accepts PKT chains */ bool use_rxchain; /* If dhd should use PKT chains */ bool sleeping; /* Is SDIO bus sleeping? */ - bool rxflow_mode; /* Rx flow control mode */ + uint rxflow_mode; /* Rx flow control mode */ bool rxflow; /* Is rx flow control on */ uint prev_rxlim_hit; /* Is prev rx limit exceeded (per dpc schedule) */ bool alp_only; /* Don't use HT clock (ALP only) */ @@ -301,6 +313,13 @@ typedef struct dhd_bus { uint32 ctrl_frame_len; bool ctrl_frame_stat; uint32 rxint_mode; /* rx interrupt mode */ + bool remap; /* Contiguous 1MB RAM: 512K socram + 512K devram + * Available with socram rev 16 + * Remap region not DMA-able + */ + bool kso; + bool _slpauto; + bool _oobwakeup; } dhd_bus_t; /* clkstate */ @@ -340,6 +359,7 @@ static bool retrydata; #define RETRYCHAN(chan) (((chan) == SDPCM_EVENT_CHANNEL) || retrydata) static const uint watermark = 8; +static const uint mesbusyctrl = 0; static const uint firstread = DHD_FIRSTREAD; #define HDATLEN (firstread - (SDPCM_HDRLEN)) @@ -380,6 +400,7 @@ static const uint max_roundup = 512; /* Try doing readahead */ static bool dhd_readahead; + /* To check if there's window offered */ #define DATAOK(bus) \ (((uint8)(bus->tx_max - bus->tx_seq) > 1) && \ @@ -461,7 +482,6 @@ do { \ #define GSPI_PR55150_BAILOUT - #ifdef SDTEST static void dhdsdio_testrcv(dhd_bus_t *bus, void *pkt, uint seq); static void dhdsdio_sdtest_set(dhd_bus_t *bus, uint8 count); @@ -472,6 +492,7 @@ static int dhdsdio_checkdied(dhd_bus_t *bus, char *data, uint size); static int dhd_serialconsole(dhd_bus_t *bus, bool get, bool enable, int *bcmerror); #endif /* DHD_DEBUG */ +static int dhdsdio_devcap_set(dhd_bus_t *bus, uint8 cap); static int dhdsdio_download_state(dhd_bus_t *bus, bool enter); static void dhdsdio_release(dhd_bus_t *bus, osl_t *osh); @@ -501,6 +522,9 @@ static int dhdsdio_download_nvram(dhd_bus_t *bus); #ifdef BCMEMBEDIMAGE static int dhdsdio_download_code_array(dhd_bus_t *bus); #endif +static int dhdsdio_bussleep(dhd_bus_t *bus, bool sleep); +static int dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok); +static uint8 dhdsdio_sleepcsr_get(dhd_bus_t *bus); #ifdef WLMEDIA_HTSF #include @@ -535,6 +559,281 @@ dhdsdio_set_siaddr_window(dhd_bus_t *bus, uint32 address) } +#ifdef USE_OOB_GPIO1 +static int +dhdsdio_oobwakeup_init(dhd_bus_t *bus) +{ + uint32 val, addr, data; + + bcmsdh_gpioouten(bus->sdh, GPIO_DEV_WAKEUP); + + addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, chipcontrol_addr); + data = SI_ENUM_BASE + OFFSETOF(chipcregs_t, chipcontrol_data); + + /* Set device for gpio1 wakeup */ + bcmsdh_reg_write(bus->sdh, addr, 4, 2); + val = bcmsdh_reg_read(bus->sdh, data, 4); + val |= CC_CHIPCTRL2_GPIO1_WAKEUP; + bcmsdh_reg_write(bus->sdh, data, 4, val); + + bus->_oobwakeup = TRUE; + + return 0; +} +#endif /* USE_OOB_GPIO1 */ + + +/* + * FIX: Be sure KSO bit is enabled + * Currently, it's defaulting to 0 which should be 1. + */ +static int +dhdsdio_clk_kso_init(dhd_bus_t *bus) +{ + uint8 val; + int err = 0; + + /* set flag */ + bus->kso = TRUE; + + /* + * Enable KeepSdioOn (KSO) bit for normal operation + * Default is 0 (4334A0) so set it. Fixed in B0. + */ + val = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SLEEPCSR, NULL); + if (!(val & SBSDIO_FUNC1_SLEEPCSR_KSO_MASK)) { + val |= (SBSDIO_FUNC1_SLEEPCSR_KSO_EN << SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT); + bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SLEEPCSR, val, &err); + if (err) + DHD_ERROR(("%s: SBSDIO_FUNC1_SLEEPCSR err: 0x%x\n", __FUNCTION__, err)); + } + + + return 0; +} + +static int +dhdsdio_clk_kso_enab(dhd_bus_t *bus, bool on) +{ + uint8 val = 0; + int err = 0; + + /* Don't read here since sdio could be off so just write only */ + val |= (on << SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT); + bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SLEEPCSR, val, &err); + + if (err) + DHD_TRACE(("%s: KSO toggle %d failed: %d\n", __FUNCTION__, on, err)); + return 0; +} + +static int +dhdsdio_clk_kso_iovar(dhd_bus_t *bus, bool on) +{ + int err = 0; + + if (on == FALSE) { + + BUS_WAKE(bus); + dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); + + DHD_ERROR(("%s: KSO disable clk: 0x%x\n", __FUNCTION__, + bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, &err))); + dhdsdio_clk_kso_enab(bus, FALSE); + } else { + DHD_ERROR(("%s: KSO enable\n", __FUNCTION__)); + + /* Make sure we have SD bus access */ + if (bus->clkstate == CLK_NONE) { + DHD_ERROR(("%s: Request SD clk\n", __FUNCTION__)); + dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); + } + + /* Double-write to be safe in case transition of AOS */ + dhdsdio_clk_kso_enab(bus, TRUE); + dhdsdio_clk_kso_enab(bus, TRUE); + OSL_DELAY(4000); + + /* Wait for device ready during transition to wake-up */ + SPINWAIT(((dhdsdio_sleepcsr_get(bus)) != + (SBSDIO_FUNC1_SLEEPCSR_KSO_MASK | + SBSDIO_FUNC1_SLEEPCSR_DEVON_MASK)), + (10000)); + + DHD_ERROR(("%s: sleepcsr: 0x%x\n", __FUNCTION__, + dhdsdio_sleepcsr_get(bus))); + } + + bus->kso = on; + BCM_REFERENCE(err); + + return 0; +} + +static uint8 +dhdsdio_sleepcsr_get(dhd_bus_t *bus) +{ + int err = 0; + uint8 val = 0; + + val = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SLEEPCSR, &err); + if (err) + DHD_TRACE(("Failed to read SLEEPCSR: %d\n", err)); + + return val; +} + +uint8 +dhdsdio_devcap_get(dhd_bus_t *bus) +{ + return bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_BRCM_CARDCAP, NULL); +} + +static int +dhdsdio_devcap_set(dhd_bus_t *bus, uint8 cap) +{ + int err = 0; + + bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_BRCM_CARDCAP, cap, &err); + if (err) + DHD_ERROR(("%s: devcap set err: 0x%x\n", __FUNCTION__, err)); + + return 0; +} + +static int +dhdsdio_clk_devsleep_iovar(dhd_bus_t *bus, bool on) +{ + int err = 0, retry; + uint8 val; + + retry = 0; + if (on == TRUE) { + /* Enter Sleep */ + + /* Be sure we request clk before going to sleep + * so we can wake-up with clk request already set + * else device can go back to sleep immediately + */ + if (!SLPAUTO_ENAB(bus)) + dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); + else { + val = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err); + if ((val & SBSDIO_CSR_MASK) == 0) { + DHD_ERROR(("%s: No clock before enter sleep:0x%x\n", + __FUNCTION__, val)); + + /* Reset clock request */ + bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, + SBSDIO_ALP_AVAIL_REQ, &err); + DHD_ERROR(("%s: clock before sleep:0x%x\n", __FUNCTION__, + bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, &err))); + } + } + + DHD_TRACE(("%s: clk before sleep: 0x%x\n", __FUNCTION__, + bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, &err))); +#ifdef USE_CMD14 + err = bcmsdh_sleep(bus->sdh, TRUE); +#else + err = dhdsdio_clk_kso_enab(bus, FALSE); + if (OOB_WAKEUP_ENAB(bus)) + err = bcmsdh_gpioout(bus->sdh, GPIO_DEV_WAKEUP, FALSE); /* GPIO_1 is off */ +#endif + } else { + /* Exit Sleep */ + /* Make sure we have SD bus access */ + if (bus->clkstate == CLK_NONE) { + DHD_TRACE(("%s: Request SD clk\n", __FUNCTION__)); + dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); + } + + if ((bus->sih->chip == BCM4334_CHIP_ID) && (bus->sih->chiprev == 2)) { + SPINWAIT((bcmsdh_gpioin(bus->sdh, GPIO_DEV_SRSTATE) != TRUE), + GPIO_DEV_SRSTATE_TIMEOUT); + + if (bcmsdh_gpioin(bus->sdh, GPIO_DEV_SRSTATE) == FALSE) { + DHD_ERROR(("ERROR: GPIO_DEV_SRSTATE still low!\n")); + } + } +#ifdef USE_CMD14 + err = bcmsdh_sleep(bus->sdh, FALSE); + if (SLPAUTO_ENAB(bus) && (err != 0)) { + OSL_DELAY(10000); + DHD_TRACE(("%s: Resync device sleep\n", __FUNCTION__)); + + /* Toggle sleep to resync with host and device */ + err = bcmsdh_sleep(bus->sdh, TRUE); + OSL_DELAY(10000); + err = bcmsdh_sleep(bus->sdh, FALSE); + + if (err) { + OSL_DELAY(10000); + DHD_ERROR(("%s: CMD14 exit failed again!\n", __FUNCTION__)); + + /* Toggle sleep to resync with host and device */ + err = bcmsdh_sleep(bus->sdh, TRUE); + OSL_DELAY(10000); + err = bcmsdh_sleep(bus->sdh, FALSE); + if (err) { + DHD_ERROR(("%s: CMD14 exit failed twice!\n", __FUNCTION__)); + DHD_ERROR(("%s: FATAL: Device non-response!\n", + __FUNCTION__)); + err = 0; + } + } + } +#else + if (OOB_WAKEUP_ENAB(bus)) + err = bcmsdh_gpioout(bus->sdh, GPIO_DEV_WAKEUP, TRUE); /* GPIO_1 is on */ + + do { + err = dhdsdio_clk_kso_enab(bus, TRUE); + OSL_DELAY(10000); + } while ((err != 0) && (++retry < 3)); + + if (err != 0) { + DHD_ERROR(("ERROR: kso set failed retry: %d\n", retry)); + err = 0; /* continue anyway */ + } +#endif /* !USE_CMD14 */ + + if (err == 0) { + uint8 csr; + + /* Wait for device ready during transition to wake-up */ + SPINWAIT((((csr = dhdsdio_sleepcsr_get(bus)) & + SBSDIO_FUNC1_SLEEPCSR_DEVON_MASK) != + (SBSDIO_FUNC1_SLEEPCSR_DEVON_MASK)), (10000)); + + DHD_TRACE(("%s: ExitSleep sleepcsr: 0x%x\n", __FUNCTION__, csr)); + + if (!(csr & SBSDIO_FUNC1_SLEEPCSR_DEVON_MASK)) { + DHD_ERROR(("%s:ERROR: ExitSleep device NOT Ready! 0x%x\n", + __FUNCTION__, csr)); + err = BCME_NODEVICE; + } + + SPINWAIT((((csr = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, &err)) & SBSDIO_HT_AVAIL) != + (SBSDIO_HT_AVAIL)), (10000)); + + } + } + + /* Update if successful */ + if (err == 0) + bus->kso = on ? FALSE : TRUE; + else { + DHD_ERROR(("%s: Sleep request failed: on:%d err:%d\n", __FUNCTION__, on, err)); + } + + return err; +} + /* Turn backplane clock on or off */ static int dhdsdio_htclk(dhd_bus_t *bus, bool on, bool pendok) @@ -546,19 +845,26 @@ dhdsdio_htclk(dhd_bus_t *bus, bool on, bool pendok) DHD_TRACE(("%s: Enter\n", __FUNCTION__)); #if defined(OOB_INTR_ONLY) - pendok = FALSE; + pendok = FALSE; #endif clkctl = 0; sdh = bus->sdh; + if (!KSO_ENAB(bus)) + return BCME_OK; + + if (SLPAUTO_ENAB(bus)) { + bus->clkstate = (on ? CLK_AVAIL : CLK_SDONLY); + return BCME_OK; + } + if (on) { /* Request HT Avail */ clkreq = bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ; - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err); if (err) { DHD_ERROR(("%s: HT Avail request error: %d\n", __FUNCTION__, err)); @@ -569,6 +875,7 @@ dhdsdio_htclk(dhd_bus_t *bus, bool on, bool pendok) ((bus->sih->buscoretype == PCMCIA_CORE_ID) && (bus->sih->buscorerev == 9))) { uint32 dummy, retries; R_SDREG(dummy, &bus->regs->clockctlstatus, retries); + BCM_REFERENCE(dummy); } /* Check current status */ @@ -617,7 +924,6 @@ dhdsdio_htclk(dhd_bus_t *bus, bool on, bool pendok) return BCME_ERROR; } - /* Mark clock available */ bus->clkstate = CLK_AVAIL; DHD_INFO(("CLKCTL: turned ON\n")); @@ -639,7 +945,6 @@ dhdsdio_htclk(dhd_bus_t *bus, bool on, bool pendok) bus->activity = TRUE; } else { clkreq = 0; - if (bus->clkstate == CLK_PENDING) { /* Cancel CA-only interrupt filter */ devctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); @@ -648,6 +953,7 @@ dhdsdio_htclk(dhd_bus_t *bus, bool on, bool pendok) } bus->clkstate = CLK_SDONLY; + bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err); DHD_INFO(("CLKCTL: turned OFF\n")); if (err) { @@ -655,6 +961,7 @@ dhdsdio_htclk(dhd_bus_t *bus, bool on, bool pendok) __FUNCTION__, err)); return BCME_ERROR; } + } return BCME_OK; } @@ -774,7 +1081,7 @@ dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok) ret = dhdsdio_htclk(bus, TRUE, pendok); if (ret == BCME_OK) { dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms); - bus->activity = TRUE; + bus->activity = TRUE; } break; @@ -801,7 +1108,7 @@ dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok) #ifdef DHD_DEBUG if (dhd_console_ms == 0) #endif /* DHD_DEBUG */ - dhd_os_wd_timer(bus->dhd, 0); + dhd_os_wd_timer(bus->dhd, 0); break; } #ifdef DHD_DEBUG @@ -814,6 +1121,7 @@ dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok) static int dhdsdio_bussleep(dhd_bus_t *bus, bool sleep) { + int err = 0; bcmsdh_info_t *sdh = bus->sdh; sdpcmd_regs_t *regs = bus->regs; uint retries = 0; @@ -833,27 +1141,35 @@ dhdsdio_bussleep(dhd_bus_t *bus, bool sleep) return BCME_BUSY; - /* Disable SDIO interrupts (no longer interested) */ - bcmsdh_intr_disable(bus->sdh); + if (!SLPAUTO_ENAB(bus)) { + /* Disable SDIO interrupts (no longer interested) */ + bcmsdh_intr_disable(bus->sdh); - /* Make sure the controller has the bus up */ - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); + /* Make sure the controller has the bus up */ + dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - /* Tell device to start using OOB wakeup */ - W_SDREG(SMB_USE_OOB, ®s->tosbmailbox, retries); - if (retries > retry_limit) - DHD_ERROR(("CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n")); + /* Tell device to start using OOB wakeup */ + W_SDREG(SMB_USE_OOB, ®s->tosbmailbox, retries); + if (retries > retry_limit) + DHD_ERROR(("CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n")); - /* Turn off our contribution to the HT clock request */ - dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); + /* Turn off our contribution to the HT clock request */ + dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - SBSDIO_FORCE_HW_CLKREQ_OFF, NULL); + bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, + SBSDIO_FORCE_HW_CLKREQ_OFF, NULL); - /* Isolate the bus */ - if (bus->sih->chip != BCM4329_CHIP_ID && bus->sih->chip != BCM4319_CHIP_ID) { - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, - SBSDIO_DEVCTL_PADS_ISO, NULL); + /* Isolate the bus */ + if (bus->sih->chip != BCM4329_CHIP_ID && + bus->sih->chip != BCM4319_CHIP_ID) { + bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, + SBSDIO_DEVCTL_PADS_ISO, NULL); + } + } else { + /* Leave interrupts enabled since device can exit sleep and + * interrupt host + */ + err = dhdsdio_clk_devsleep_iovar(bus, TRUE /* sleep */); } /* Change state */ @@ -862,38 +1178,43 @@ dhdsdio_bussleep(dhd_bus_t *bus, bool sleep) } else { /* Waking up: bus power up is ok, set local state */ - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - 0, NULL); + if (!SLPAUTO_ENAB(bus)) { + bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, 0, &err); - /* Force pad isolation off if possible (in case power never toggled) */ - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, 0, NULL); + /* Force pad isolation off if possible (in case power never toggled) */ + bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, 0, NULL); - /* Make sure the controller has the bus up */ - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); + /* Make sure the controller has the bus up */ + dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - /* Send misc interrupt to indicate OOB not needed */ - W_SDREG(0, ®s->tosbmailboxdata, retries); - if (retries <= retry_limit) - W_SDREG(SMB_DEV_INT, ®s->tosbmailbox, retries); + /* Send misc interrupt to indicate OOB not needed */ + W_SDREG(0, ®s->tosbmailboxdata, retries); + if (retries <= retry_limit) + W_SDREG(SMB_DEV_INT, ®s->tosbmailbox, retries); - if (retries > retry_limit) - DHD_ERROR(("CANNOT SIGNAL CHIP TO CLEAR OOB!!\n")); + if (retries > retry_limit) + DHD_ERROR(("CANNOT SIGNAL CHIP TO CLEAR OOB!!\n")); - /* Make sure we have SD bus access */ - dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); + /* Make sure we have SD bus access */ + dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); - /* Change state */ - bus->sleeping = FALSE; + /* Enable interrupts again */ + if (bus->intr && (bus->dhd->busstate == DHD_BUS_DATA)) { + bus->intdis = FALSE; + bcmsdh_intr_enable(bus->sdh); + } + } else { + err = dhdsdio_clk_devsleep_iovar(bus, FALSE /* wake */); + } - /* Enable interrupts again */ - if (bus->intr && (bus->dhd->busstate == DHD_BUS_DATA)) { - bus->intdis = FALSE; - bcmsdh_intr_enable(bus->sdh); + if (err == 0) { + /* Change state */ + bus->sleeping = FALSE; } } - return BCME_OK; + return err; } #if defined(OOB_INTR_ONLY) @@ -1058,7 +1379,9 @@ dhdsdio_txpkt(dhd_bus_t *bus, void *pkt, uint chan, bool free_pkt) bus->f2txdata++; ASSERT(ret != BCME_PENDING); - if (ret < 0) { + if (ret == BCME_NODEVICE) { + DHD_ERROR(("%s: Device asleep already\n", __FUNCTION__)); + } else if (ret < 0) { /* On failure, abort the command and terminate the frame */ DHD_INFO(("%s: sdio error %d, abort command and terminate frame.\n", __FUNCTION__, ret)); @@ -1079,7 +1402,6 @@ dhdsdio_txpkt(dhd_bus_t *bus, void *pkt, uint chan, bool free_pkt) if ((hi == 0) && (lo == 0)) break; } - } if (ret == 0) { bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; @@ -1087,7 +1409,7 @@ dhdsdio_txpkt(dhd_bus_t *bus, void *pkt, uint chan, bool free_pkt) } while ((ret < 0) && retrydata && retries++ < TXRETRIES); done: - /* restore pkt buffer pointer before calling tx complete routine */ + /* restore pkt buffer pointer before calling tx complete routine */ PKTPULL(osh, pkt, SDPCM_HDRLEN + pad1); #ifdef PROP_TXSTATUS if (bus->dhd->wlfc_state) { @@ -1175,7 +1497,7 @@ dhd_bus_txdata(struct dhd_bus *bus, void *pkt) #endif #ifdef PROP_TXSTATUS /* let the caller decide whether to free the packet */ - if (!bus->dhd->wlfc_state) + if (!bus->dhd->wlfc_state) #endif PKTFREE(osh, pkt, TRUE); ret = BCME_NORESOURCE; @@ -1250,6 +1572,11 @@ dhdsdio_sendfromq(dhd_bus_t *bus, uint maxframes) DHD_TRACE(("%s: Enter\n", __FUNCTION__)); + if (!KSO_ENAB(bus)) { + DHD_ERROR(("%s: Device asleep\n", __FUNCTION__)); + return BCME_NODEVICE; + } + tx_prec_map = ~bus->flowcontrol; /* Send frames until the limit or some other event */ @@ -1368,7 +1695,9 @@ dhd_bus_txctl(struct dhd_bus *bus, uchar *msg, uint msglen) /* Send from dpc */ bus->ctrl_frame_buf = frame; bus->ctrl_frame_len = len; + dhd_wait_for_event(bus->dhd, &bus->ctrl_frame_stat); + if (bus->ctrl_frame_stat == FALSE) { DHD_INFO(("%s: ctrl_frame_stat == FALSE\n", __FUNCTION__)); ret = 0; @@ -1399,7 +1728,9 @@ dhd_bus_txctl(struct dhd_bus *bus, uchar *msg, uint msglen) frame, len, NULL, NULL, NULL); ASSERT(ret != BCME_PENDING); - if (ret < 0) { + if (ret == BCME_NODEVICE) { + DHD_ERROR(("%s: Device asleep already\n", __FUNCTION__)); + } else if (ret < 0) { /* On failure, abort the command and terminate the frame */ DHD_INFO(("%s: sdio error %d, abort command and terminate frame.\n", __FUNCTION__, ret)); @@ -1421,7 +1752,6 @@ dhd_bus_txctl(struct dhd_bus *bus, uchar *msg, uint msglen) if ((hi == 0) && (lo == 0)) break; } - } if (ret == 0) { bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; @@ -1475,9 +1805,11 @@ dhd_bus_rxctl(struct dhd_bus *bus, uchar *msg, uint msglen) } else if (timeleft == 0) { DHD_ERROR(("%s: resumed on timeout\n", __FUNCTION__)); #ifdef DHD_DEBUG - dhd_os_sdlock(bus->dhd); - dhdsdio_checkdied(bus, NULL, 0); - dhd_os_sdunlock(bus->dhd); + if (!SLPAUTO_ENAB(bus)) { + dhd_os_sdlock(bus->dhd); + dhdsdio_checkdied(bus, NULL, 0); + dhd_os_sdunlock(bus->dhd); + } #endif /* DHD_DEBUG */ } else if (pending == TRUE) { DHD_CTL(("%s: canceled\n", __FUNCTION__)); @@ -1521,7 +1853,7 @@ enum { IOV_CHECKDIED, IOV_SERIALCONS, #endif /* DHD_DEBUG */ - IOV_DOWNLOAD, + IOV_SET_DOWNLOAD_STATE, IOV_SOCRAM_STATE, IOV_FORCEEVEN, IOV_SDIOD_DRIVE, @@ -1544,6 +1876,9 @@ enum { IOV_SD1IDLE, IOV_SLEEP, IOV_DONGLEISOLATION, + IOV_KSO, + IOV_DEVSLEEP, + IOV_DEVCAP, IOV_VARS, #ifdef SOFTAP IOV_FWPATH @@ -1559,7 +1894,7 @@ const bcm_iovar_t dhdsdio_iovars[] = { {"sd1idle", IOV_SD1IDLE, 0, IOVT_BOOL, 0 }, {"membytes", IOV_MEMBYTES, 0, IOVT_BUFFER, 2 * sizeof(int) }, {"memsize", IOV_MEMSIZE, 0, IOVT_UINT32, 0 }, - {"download", IOV_DOWNLOAD, 0, IOVT_BOOL, 0 }, + {"dwnldstate", IOV_SET_DOWNLOAD_STATE, 0, IOVT_BOOL, 0 }, {"socram_state", IOV_SOCRAM_STATE, 0, IOVT_BOOL, 0 }, {"vars", IOV_VARS, 0, IOVT_BUFFER, 0 }, {"sdiod_drive", IOV_SDIOD_DRIVE, 0, IOVT_UINT32, 0 }, @@ -1586,7 +1921,10 @@ const bcm_iovar_t dhdsdio_iovars[] = { {"extloop", IOV_EXTLOOP, 0, IOVT_BOOL, 0 }, {"pktgen", IOV_PKTGEN, 0, IOVT_BUFFER, sizeof(dhd_pktgen_t) }, #endif /* SDTEST */ + {"devcap", IOV_DEVCAP, 0, IOVT_UINT32, 0 }, {"dngl_isolation", IOV_DONGLEISOLATION, 0, IOVT_UINT32, 0 }, + {"kso", IOV_KSO, 0, IOVT_UINT32, 0 }, + {"devsleep", IOV_DEVSLEEP, 0, IOVT_UINT32, 0 }, #ifdef SOFTAP {"fwpath", IOV_FWPATH, 0, IOVT_BUFFER, 0 }, #endif @@ -1760,6 +2098,16 @@ dhdsdio_pktgen_set(dhd_bus_t *bus, uint8 *arg) } #endif /* SDTEST */ +static void +dhdsdio_devram_remap(dhd_bus_t *bus, bool val) +{ + uint8 enable, protect, remap; + + si_socdevram(bus->sih, FALSE, &enable, &protect, &remap); + remap = val ? TRUE : FALSE; + si_socdevram(bus->sih, TRUE, &enable, &protect, &remap); +} + static int dhdsdio_membytes(dhd_bus_t *bus, bool write, uint32 address, uint8 *data, uint size) { @@ -1767,6 +2115,15 @@ dhdsdio_membytes(dhd_bus_t *bus, bool write, uint32 address, uint8 *data, uint s uint32 sdaddr; uint dsize; + /* In remap mode, adjust address beyond socram and redirect + * to devram at SOCDEVRAM_BP_ADDR since remap address > orig_ramsize + * is not backplane accessible + */ + if (REMAP_ENAB(bus) && REMAP_ISADDR(bus, address)) { + address -= bus->orig_ramsize; + address += SOCDEVRAM_BP_ADDR; + } + /* Determine initial transfer parameters */ sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK; if ((sdaddr + size) & SBSDIO_SBWINDOW_MASK) @@ -1865,6 +2222,7 @@ dhdsdio_readshared(dhd_bus_t *bus, sdpcm_shared_t *sh) return BCME_OK; } +#define CONSOLE_LINE_MAX 192 static int dhdsdio_readconsole(dhd_bus_t *bus) @@ -1878,6 +2236,9 @@ dhdsdio_readconsole(dhd_bus_t *bus) if (bus->console_addr == 0) return 0; + if (!KSO_ENAB(bus)) + return 0; + /* Read console log struct */ addr = bus->console_addr + OFFSETOF(hndrte_cons_t, log); if ((rv = dhdsdio_membytes(bus, FALSE, addr, (uint8 *)&c->log, sizeof(c->log))) < 0) @@ -2034,7 +2395,7 @@ dhdsdio_checkdied(dhd_bus_t *bus, char *data, uint size) bcm_bprintf(&strbuf, "Dongle trap type 0x%x @ epc 0x%x, cpsr 0x%x, spsr 0x%x, sp 0x%x," - "lp 0x%x, rpc 0x%x Trap offset 0x%x, " + "lp 0x%x, rpc 0x%x Trap offset 0x%x, " "r0 0x%x, r1 0x%x, r2 0x%x, r3 0x%x, " "r4 0x%x, r5 0x%x, r6 0x%x, r7 0x%x\n\n", ltoh32(tr.type), ltoh32(tr.epc), ltoh32(tr.cpsr), ltoh32(tr.spsr), @@ -2088,10 +2449,8 @@ dhdsdio_checkdied(dhd_bus_t *bus, char *data, uint size) * will truncate a lot of the printfs */ - if (dhd_msg_level & DHD_ERROR_VAL) { + if (dhd_msg_level & DHD_ERROR_VAL) printf("CONSOLE: %s\n", line); - DHD_BLOG(line, strlen(line) + 1); - } } } } @@ -2152,13 +2511,18 @@ err: #ifdef DHD_DEBUG -#define CC_PLL_CHIPCTRL_SERIAL_ENAB (1 << 24) +#define CC_PLL_CHIPCTRL_SERIAL_ENAB (1 << 24) +#define CC_CHIPCTRL_JTAG_SEL (1 << 3) +#define CC_CHIPCTRL_GPIO_SEL (0x3) +#define CC_PLL_CHIPCTRL_SERIAL_ENAB_4334 (1 << 28) + static int dhd_serialconsole(dhd_bus_t *bus, bool set, bool enable, int *bcmerror) { int int_val; - uint32 addr, data; - + uint32 addr, data, uart_enab = 0; + uint32 jtag_sel = CC_CHIPCTRL_JTAG_SEL; + uint32 gpio_sel = CC_CHIPCTRL_GPIO_SEL; addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, chipcontrol_addr); data = SI_ENUM_BASE + OFFSETOF(chipcregs_t, chipcontrol_data); @@ -2174,12 +2538,27 @@ dhd_serialconsole(dhd_bus_t *bus, bool set, bool enable, int *bcmerror) *bcmerror = BCME_SDIO_ERROR; return -1; } + if (bus->sih->chip == BCM4330_CHIP_ID) { + uart_enab = CC_PLL_CHIPCTRL_SERIAL_ENAB; + } + else if (bus->sih->chip == BCM4334_CHIP_ID) { + if (enable) { + /* Moved to PMU chipcontrol 1 from 4330 */ + int_val &= ~gpio_sel; + int_val |= jtag_sel; + } else { + int_val |= gpio_sel; + int_val &= ~jtag_sel; + } + uart_enab = CC_PLL_CHIPCTRL_SERIAL_ENAB_4334; + } + if (!set) - return (int_val & CC_PLL_CHIPCTRL_SERIAL_ENAB); + return (int_val & uart_enab); if (enable) - int_val |= CC_PLL_CHIPCTRL_SERIAL_ENAB; + int_val |= uart_enab; else - int_val &= ~CC_PLL_CHIPCTRL_SERIAL_ENAB; + int_val &= ~uart_enab; bcmsdh_reg_write(bus->sdh, data, 4, int_val); if (bcmsdh_regfail(bus->sdh)) { *bcmerror = BCME_SDIO_ERROR; @@ -2189,15 +2568,15 @@ dhd_serialconsole(dhd_bus_t *bus, bool set, bool enable, int *bcmerror) uint32 chipcontrol; addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, chipcontrol); chipcontrol = bcmsdh_reg_read(bus->sdh, addr, 4); - chipcontrol &= ~0x8; + chipcontrol &= ~jtag_sel; if (enable) { - chipcontrol |= 0x8; - chipcontrol &= ~0x3; + chipcontrol |= jtag_sel; + chipcontrol &= ~gpio_sel; } bcmsdh_reg_write(bus->sdh, addr, 4, chipcontrol); } - return (int_val & CC_PLL_CHIPCTRL_SERIAL_ENAB); + return (int_val & uart_enab); } #endif @@ -2231,6 +2610,27 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch goto exit; } + /* + * Special handling for keepSdioOn: New SDIO Wake-up Mechanism + */ + if ((vi->varid == IOV_KSO) && (IOV_ISSET(actionid))) { + dhdsdio_clk_kso_iovar(bus, bool_val); + goto exit; + } else if ((vi->varid == IOV_DEVSLEEP) && (IOV_ISSET(actionid))) { + { + dhdsdio_clk_devsleep_iovar(bus, bool_val); + if (!SLPAUTO_ENAB(bus) && (bool_val == FALSE) && (bus->ipend)) { + DHD_ERROR(("INT pending in devsleep 1, dpc_sched: %d\n", + bus->dpc_sched)); + if (!bus->dpc_sched) { + bus->dpc_sched = TRUE; + dhd_sched_dpc(bus->dhd); + } + } + } + goto exit; + } + /* Handle sleep stuff before any clock mucking */ if (vi->varid == IOV_SLEEP) { if (IOV_ISSET(actionid)) { @@ -2341,8 +2741,8 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch if ((bus->orig_ramsize) && ((address > bus->orig_ramsize) || (address + size > bus->orig_ramsize))) { - uint8 enable, protect; - si_socdevram(bus->sih, FALSE, &enable, &protect); + uint8 enable, protect, remap; + si_socdevram(bus->sih, FALSE, &enable, &protect, &remap); if (!enable || protect) { DHD_ERROR(("%s: ramsize 0x%08x doesn't have %d bytes at 0x%08x\n", __FUNCTION__, bus->orig_ramsize, size, address)); @@ -2351,22 +2751,31 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch bcmerror = BCME_BADARG; break; } - if (enable && (bus->sih->chip == BCM4330_CHIP_ID)) { + + if (!REMAP_ENAB(bus) && (address >= SOCDEVRAM_ARM_ADDR)) { uint32 devramsize = si_socdevram_size(bus->sih); - if ((address < SOCDEVRAM_4330_ARM_ADDR) || - (address + size > (SOCDEVRAM_4330_ARM_ADDR + devramsize))) { + if ((address < SOCDEVRAM_ARM_ADDR) || + (address + size > (SOCDEVRAM_ARM_ADDR + devramsize))) { DHD_ERROR(("%s: bad address 0x%08x, size 0x%08x\n", __FUNCTION__, address, size)); DHD_ERROR(("%s: socram range 0x%08x,size 0x%08x\n", - __FUNCTION__, SOCDEVRAM_4330_ARM_ADDR, devramsize)); + __FUNCTION__, SOCDEVRAM_ARM_ADDR, devramsize)); bcmerror = BCME_BADARG; break; } /* move it such that address is real now */ - address -= SOCDEVRAM_4330_ARM_ADDR; - address += SOCDEVRAM_4330_BP_ADDR; + address -= SOCDEVRAM_ARM_ADDR; + address += SOCDEVRAM_BP_ADDR; DHD_INFO(("%s: Request to %s %d bytes @ Mapped address 0x%08x\n", __FUNCTION__, (set ? "write" : "read"), size, address)); + } else if (REMAP_ENAB(bus) && REMAP_ISADDR(bus, address) && remap) { + /* Can not access remap region while devram remap bit is set + * ROM content would be returned in this case + */ + DHD_ERROR(("%s: Need to disable remap for address 0x%08x\n", + __FUNCTION__, address)); + bcmerror = BCME_ERROR; + break; } } @@ -2394,7 +2803,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch si_sdiod_drive_strength_init(bus->sih, bus->dhd->osh, dhd_sdiod_drive_strength); break; - case IOV_SVAL(IOV_DOWNLOAD): + case IOV_SVAL(IOV_SET_DOWNLOAD_STATE): bcmerror = dhdsdio_download_state(bus, bool_val); break; @@ -2669,6 +3078,20 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch break; + case IOV_GVAL(IOV_KSO): + int_val = dhdsdio_sleepcsr_get(bus); + bcopy(&int_val, arg, val_size); + break; + + case IOV_GVAL(IOV_DEVCAP): + int_val = dhdsdio_devcap_get(bus); + bcopy(&int_val, arg, val_size); + break; + + case IOV_SVAL(IOV_DEVCAP): + dhdsdio_devcap_set(bus, (uint8) int_val); + break; + default: bcmerror = BCME_UNSUPPORTED; break; @@ -2682,9 +3105,6 @@ exit: dhd_os_sdunlock(bus->dhd); - if (actionid == IOV_SVAL(IOV_DEVRESET) && bool_val == FALSE) - dhd_preinit_ioctls((dhd_pub_t *) bus->dhd); - return bcmerror; } @@ -2692,7 +3112,7 @@ static int dhdsdio_write_vars(dhd_bus_t *bus) { int bcmerror = 0; - uint32 varsize; + uint32 varsize, phys_size; uint32 varaddr; uint8 *vbuffer; uint32 varsizew; @@ -2751,12 +3171,14 @@ dhdsdio_write_vars(dhd_bus_t *bus) MFREE(bus->dhd->osh, vbuffer, varsize); } + phys_size = REMAP_ENAB(bus) ? bus->ramsize : bus->orig_ramsize; + /* adjust to the user specified RAM */ DHD_INFO(("Physical memory size: %d, usable memory size: %d\n", - bus->orig_ramsize, bus->ramsize)); + phys_size, bus->ramsize)); DHD_INFO(("Vars are at %d, orig varsize is %d\n", varaddr, varsize)); - varsize = ((bus->orig_ramsize - 4) - varaddr); + varsize = ((phys_size - 4) - varaddr); /* * Determine the length token: @@ -2773,7 +3195,7 @@ dhdsdio_write_vars(dhd_bus_t *bus) DHD_INFO(("New varsize is %d, length token=0x%08x\n", varsize, varsizew)); /* Write the length token to the last word */ - bcmerror = dhdsdio_membytes(bus, TRUE, (bus->orig_ramsize - 4), + bcmerror = dhdsdio_membytes(bus, TRUE, (phys_size - 4), (uint8*)&varsizew, 4); return bcmerror; @@ -2785,9 +3207,6 @@ dhdsdio_download_state(dhd_bus_t *bus, bool enter) uint retries; int bcmerror = 0; - if (!bus->sih) - return BCME_ERROR; - /* To enter download state, disable ARM and reset SOCRAM. * To exit download state, simply reset ARM (default is RAM boot). */ @@ -2820,6 +3239,10 @@ dhdsdio_download_state(dhd_bus_t *bus, bool enter) goto fail; } + /* Disable remap for download */ + if (REMAP_ENAB(bus) && si_socdevram_remap_isenb(bus->sih)) + dhdsdio_devram_remap(bus, FALSE); + /* Clear the top bit of memory */ if (bus->ramsize) { uint32 zeros = 0; @@ -2846,6 +3269,12 @@ dhdsdio_download_state(dhd_bus_t *bus, bool enter) goto fail; } + /* Enable remap before ARM reset but after vars. + * No backplane access in remap mode + */ + if (REMAP_ENAB(bus) && !si_socdevram_remap_isenb(bus->sih)) + dhdsdio_devram_remap(bus, TRUE); + if (!si_setcore(bus->sih, PCMCIA_CORE_ID, 0) && !si_setcore(bus->sih, SDIOD_CORE_ID, 0)) { DHD_ERROR(("%s: Can't change back to SDIO core?\n", __FUNCTION__)); @@ -3012,6 +3441,8 @@ dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex) /* Change our idea of bus state */ bus->dhd->busstate = DHD_BUS_DOWN; + if (KSO_ENAB(bus)) { + /* Enable clock for device interrupts */ dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); @@ -3037,6 +3468,7 @@ dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex) /* Clear any pending interrupts now that F2 is disabled */ W_SDREG(local_hostintmask, &bus->regs->intstatus, retries); + } /* Turn off the backplane clock (only) */ dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); @@ -3118,7 +3550,6 @@ dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex) while (ready != enable && !dhd_timeout_expired(&tmo)) ready = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IORDY, NULL); - DHD_INFO(("%s: enable 0x%02x, ready 0x%02x (waited %uus)\n", __FUNCTION__, enable, ready, tmo.elapsed)); @@ -3166,8 +3597,12 @@ dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex) } /* Restore previous clock setting */ - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err); - + if (SLPAUTO_ENAB(bus)) + bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, SBSDIO_FORCE_HT, &err); + else + bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err); /* If we didn't come up, turn off backplane clock */ if (dhdp->busstate != DHD_BUS_DATA) @@ -3193,6 +3628,11 @@ dhdsdio_rxfail(dhd_bus_t *bus, bool abort, bool rtx) DHD_ERROR(("%s: %sterminate frame%s\n", __FUNCTION__, (abort ? "abort command, " : ""), (rtx ? ", send NAK" : ""))); + if (!KSO_ENAB(bus)) { + DHD_ERROR(("%s: Device asleep\n", __FUNCTION__)); + return; + } + if (abort) { bcmsdh_abort(sdh, SDIO_FUNC_2); } @@ -3352,6 +3792,8 @@ dhdsdio_rxglom(dhd_bus_t *bus, uint8 rxseq) int errcode; uint8 chan, seq, doff, sfdoff; uint8 txmax; + uchar reorder_info_buf[WLHOST_REORDERDATA_TOTLEN]; + uint reorder_info_len; int ifidx = 0; bool usechain = bus->use_rxchain; @@ -3670,6 +4112,8 @@ dhdsdio_rxglom(dhd_bus_t *bus, uint8 rxseq) PKTSETLEN(osh, pfirst, sublen); PKTPULL(osh, pfirst, doff); + reorder_info_len = sizeof(reorder_info_buf); + if (PKTLEN(osh, pfirst) == 0) { PKTFREE(bus->dhd->osh, pfirst, FALSE); if (plast) { @@ -3679,7 +4123,8 @@ dhdsdio_rxglom(dhd_bus_t *bus, uint8 rxseq) save_pfirst = pnext; } continue; - } else if (dhd_prot_hdrpull(bus->dhd, &ifidx, pfirst) != 0) { + } else if (dhd_prot_hdrpull(bus->dhd, &ifidx, pfirst, reorder_info_buf, + &reorder_info_len) != 0) { DHD_ERROR(("%s: rx protocol error\n", __FUNCTION__)); bus->dhd->rx_errors++; PKTFREE(osh, pfirst, FALSE); @@ -3691,12 +4136,53 @@ dhdsdio_rxglom(dhd_bus_t *bus, uint8 rxseq) } continue; } + if (reorder_info_len) { + uint32 free_buf_count; + void *ppfirst; + + ppfirst = pfirst; + /* Reordering info from the firmware */ + dhd_process_pkt_reorder_info(bus->dhd, reorder_info_buf, + reorder_info_len, &ppfirst, &free_buf_count); + + if (free_buf_count == 0) { + if (plast) { + PKTSETNEXT(osh, plast, pnext); + } else { + ASSERT(save_pfirst == pfirst); + save_pfirst = pnext; + } + continue; + } + else { + void *temp; - /* this packet will go up, link back into chain and count it */ - PKTSETNEXT(osh, pfirst, pnext); - plast = pfirst; - num++; + /* go to the end of the chain and attach the pnext there */ + temp = ppfirst; + while (PKTNEXT(osh, temp) != NULL) { + temp = PKTNEXT(osh, temp); + } + pfirst = temp; + if (plast) { + PKTSETNEXT(osh, plast, ppfirst); + } + else { + /* first one in the chain */ + save_pfirst = ppfirst; + } + + PKTSETNEXT(osh, pfirst, pnext); + plast = pfirst; + } + num += (uint8)free_buf_count; + } + else { + /* this packet will go up, link back into chain and count it */ + PKTSETNEXT(osh, pfirst, pnext); + plast = pfirst; + num++; + } #ifdef DHD_DEBUG if (DHD_GLOM_ON()) { DHD_GLOM(("%s subframe %d to stack, %p(%p/%d) nxt/lnk %p/%p\n", @@ -3721,6 +4207,7 @@ dhdsdio_rxglom(dhd_bus_t *bus, uint8 rxseq) return num; } + /* Return TRUE if there may be more frames to read */ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) @@ -3744,6 +4231,9 @@ dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) uint8 *rxbuf; int ifidx = 0; uint rxcount = 0; /* Total frames read */ + uchar reorder_info_buf[WLHOST_REORDERDATA_TOTLEN]; + uint reorder_info_len; + uint pkt_count; #if defined(DHD_DEBUG) || defined(SDTEST) bool sdtest = FALSE; /* To limit message spew from test mode */ @@ -3751,6 +4241,11 @@ dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) DHD_TRACE(("%s: Enter\n", __FUNCTION__)); + if (!KSO_ENAB(bus)) { + DHD_ERROR(("%s: KSO off\n", __FUNCTION__)); + return 0; + } + ASSERT(maxframes); #ifdef SDTEST @@ -4278,7 +4773,8 @@ deliver: PKTFREE(bus->dhd->osh, pkt, FALSE); dhd_os_sdunlock_rxq(bus->dhd); continue; - } else if (dhd_prot_hdrpull(bus->dhd, &ifidx, pkt) != 0) { + } else if (dhd_prot_hdrpull(bus->dhd, &ifidx, pkt, reorder_info_buf, + &reorder_info_len) != 0) { DHD_ERROR(("%s: rx protocol error\n", __FUNCTION__)); dhd_os_sdlock_rxq(bus->dhd); PKTFREE(bus->dhd->osh, pkt, FALSE); @@ -4286,11 +4782,20 @@ deliver: bus->dhd->rx_errors++; continue; } + if (reorder_info_len) { + /* Reordering info from the firmware */ + dhd_process_pkt_reorder_info(bus->dhd, reorder_info_buf, reorder_info_len, + &pkt, &pkt_count); + if (pkt_count == 0) + continue; + } + else + pkt_count = 1; /* Unlock during rx call */ dhd_os_sdunlock(bus->dhd); - dhd_rx_frame(bus->dhd, ifidx, pkt, 1, chan); + dhd_rx_frame(bus->dhd, ifidx, pkt, pkt_count, chan); dhd_os_sdlock(bus->dhd); } rxcount = maxframes - rxleft; @@ -4434,8 +4939,13 @@ dhdsdio_dpc(dhd_bus_t *bus) dhd_os_sdlock(bus->dhd); + if (!SLPAUTO_ENAB(bus) && !KSO_ENAB(bus)) { + DHD_ERROR(("%s: Device asleep\n", __FUNCTION__)); + goto exit; + } + /* If waiting for HTAVAIL, check status */ - if (bus->clkstate == CLK_PENDING) { + if (!SLPAUTO_ENAB(bus) && (bus->clkstate == CLK_PENDING)) { int err; uint8 clkctl, devctl = 0; @@ -4594,8 +5104,9 @@ clkwait: (uint8 *)bus->ctrl_frame_buf, (uint32)bus->ctrl_frame_len, NULL, NULL, NULL); ASSERT(ret != BCME_PENDING); - - if (ret < 0) { + if (ret == BCME_NODEVICE) { + DHD_ERROR(("%s: Device asleep already\n", __FUNCTION__)); + } else if (ret < 0) { /* On failure, abort the command and terminate the frame */ DHD_INFO(("%s: sdio error %d, abort command and terminate frame.\n", __FUNCTION__, ret)); @@ -4639,10 +5150,17 @@ clkwait: /* Resched if events or tx frames are pending, else await next interrupt */ /* On failed register access, all bets are off: no resched or interrupts */ if ((bus->dhd->busstate == DHD_BUS_DOWN) || bcmsdh_regfail(sdh)) { - DHD_ERROR(("%s: failed backplane access over SDIO, halting operation %d \n", - __FUNCTION__, bcmsdh_regfail(sdh))); - bus->dhd->busstate = DHD_BUS_DOWN; - bus->intstatus = 0; + if ((bus->sih->buscorerev >= 12) && !(dhdsdio_sleepcsr_get(bus) & + SBSDIO_FUNC1_SLEEPCSR_KSO_MASK)) { + /* Bus failed because of KSO */ + DHD_ERROR(("%s: Bus failed due to KSO\n", __FUNCTION__)); + bus->kso = FALSE; + } else { + DHD_ERROR(("%s: failed backplane access over SDIO, halting operation\n", + __FUNCTION__)); + bus->dhd->busstate = DHD_BUS_DOWN; + bus->intstatus = 0; + } } else if (bus->clkstate == CLK_PENDING) { /* Awaiting I_CHIPACTIVE; don't resched */ } else if (bus->intstatus || bus->ipend || @@ -4659,6 +5177,7 @@ clkwait: dhdsdio_clkctl(bus, CLK_NONE, FALSE); } +exit: dhd_os_sdunlock(bus->dhd); return resched; } @@ -4701,9 +5220,13 @@ dhdsdio_isr(void *arg) bus->ipend = TRUE; /* Shouldn't get this interrupt if we're sleeping? */ - if (bus->sleeping) { - DHD_ERROR(("INTERRUPT WHILE SLEEPING??\n")); - return; + if (!SLPAUTO_ENAB(bus)) { + if (bus->sleeping) { + DHD_ERROR(("INTERRUPT WHILE SLEEPING??\n")); + return; + } else if (!KSO_ENAB(bus)) { + DHD_ERROR(("ISR in devsleep 1\n")); + } } /* Disable additional interrupts (is this needed now)? */ @@ -4982,8 +5505,8 @@ dhdsdio_testrcv(dhd_bus_t *bus, void *pkt, uint seq) if (bus->pktgen_total && (bus->pktgen_rcvd_rcvsession >= bus->pktgen_total)) { bus->pktgen_count = 0; - DHD_ERROR(("Pktgen:rcv test complete!\n")); - bus->pktgen_rcv_state = PKTGEN_RCV_IDLE; + DHD_ERROR(("Pktgen:rcv test complete!\n")); + bus->pktgen_rcv_state = PKTGEN_RCV_IDLE; dhdsdio_sdtest_set(bus, FALSE); bus->pktgen_rcvd_rcvsession = 0; } @@ -5013,14 +5536,14 @@ dhd_bus_watchdog(dhd_pub_t *dhdp) return FALSE; /* Ignore the timer if simulating bus down */ - if (bus->sleeping) + if (!SLPAUTO_ENAB(bus) && bus->sleeping) return FALSE; if (dhdp->busstate == DHD_BUS_DOWN) return FALSE; /* Poll period: check device if appropriate. */ - if (bus->poll && (++bus->polltick >= bus->pollrate)) { + if (!SLPAUTO_ENAB(bus) && (bus->poll && (++bus->polltick >= bus->pollrate))) { uint32 intstatus = 0; /* Reset poll tick */ @@ -5060,6 +5583,9 @@ dhd_bus_watchdog(dhd_pub_t *dhdp) if (bus->console.count >= dhd_console_ms) { bus->console.count -= dhd_console_ms; /* Make sure backplane clock is on */ + if (SLPAUTO_ENAB(bus)) + dhdsdio_bussleep(bus, FALSE); + else dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); if (dhdsdio_readconsole(bus) < 0) dhd_console_ms = 0; /* On error, stop trying */ @@ -5083,7 +5609,10 @@ dhd_bus_watchdog(dhd_pub_t *dhdp) bus->idlecount = 0; if (bus->activity) { bus->activity = FALSE; - dhdsdio_clkctl(bus, CLK_NONE, FALSE); + if (SLPAUTO_ENAB(bus)) + dhdsdio_bussleep(bus, TRUE); + else + dhdsdio_clkctl(bus, CLK_NONE, FALSE); } } } @@ -5194,17 +5723,22 @@ dhdsdio_chipmatch(uint16 chipid) return TRUE; if (chipid == BCM4319_CHIP_ID) return TRUE; - if (chipid == BCM4330_CHIP_ID) - return TRUE; - if (chipid == BCM43239_CHIP_ID) - return TRUE; if (chipid == BCM4336_CHIP_ID) return TRUE; + if (chipid == BCM4330_CHIP_ID) + return TRUE; if (chipid == BCM43237_CHIP_ID) return TRUE; if (chipid == BCM43362_CHIP_ID) return TRUE; - + if (chipid == BCM4314_CHIP_ID) + return TRUE; + if (chipid == BCM4334_CHIP_ID) + return TRUE; + if (chipid == BCM43239_CHIP_ID) + return TRUE; + if (chipid == BCM4324_CHIP_ID) + return TRUE; return FALSE; } @@ -5240,7 +5774,6 @@ dhdsdio_probe(uint16 venid, uint16 devid, uint16 bus_no, uint16 slot, forcealign = TRUE; - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); DHD_INFO(("%s: venid 0x%04x devid 0x%04x\n", __FUNCTION__, venid, devid)); @@ -5380,8 +5913,7 @@ dhdsdio_probe(uint16 venid, uint16 devid, uint16 bus_no, uint16 slot, DHD_ERROR(("%s: dhd_bus_start failed\n", __FUNCTION__)); if (ret == BCME_NOTUP) goto fail; - } - + } /* Ok, have the per-port tell the stack we're open for business */ if (dhd_net_attach(bus->dhd, 0) != 0) { DHD_ERROR(("%s: Net attach failed!!\n", __FUNCTION__)); @@ -5434,7 +5966,6 @@ dhdsdio_probe_attach(struct dhd_bus *bus, osl_t *osh, void *sdh, void *regsva, goto fail; } - #ifdef DHD_DEBUG if (DHD_INFO_ON()) { uint fn, numfn; @@ -5496,6 +6027,13 @@ dhdsdio_probe_attach(struct dhd_bus *bus, osl_t *osh, void *sdh, void *regsva, goto fail; } + if (bus->sih->buscorerev >= 12) + dhdsdio_clk_kso_init(bus); + else + bus->kso = TRUE; + + if (CST4330_CHIPMODE_SDIOD(bus->sih->chipst)) { + } si_sdiod_drive_strength_init(bus->sih, osh, dhd_sdiod_drive_strength); @@ -5513,6 +6051,8 @@ dhdsdio_probe_attach(struct dhd_bus *bus, osl_t *osh, void *sdh, void *regsva, DHD_ERROR(("%s: failed to find SOCRAM memory!\n", __FUNCTION__)); goto fail; } + + bus->ramsize = bus->orig_ramsize; if (dhd_dongle_memsize) dhd_dongle_setmemsize(bus, dhd_dongle_memsize); @@ -5558,10 +6098,8 @@ dhdsdio_probe_attach(struct dhd_bus *bus, osl_t *osh, void *sdh, void *regsva, return TRUE; fail: - if (bus->sih != NULL) { + if (bus->sih != NULL) si_detach(bus->sih); - bus->sih = NULL; - } return FALSE; } @@ -5619,7 +6157,6 @@ dhdsdio_probe_init(dhd_bus_t *bus, osl_t *osh, void *sdh) bus->rxflow = FALSE; bus->prev_rxlim_hit = 0; - /* Done with backplane-dependent accesses, can drop clock... */ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); @@ -5692,13 +6229,25 @@ dhdsdio_download_firmware(struct dhd_bus *bus, osl_t *osh, void *sdh) { bool ret; - /* Download the firmware */ DHD_OS_WAKE_LOCK(bus->dhd); - dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); + + if (!SLPAUTO_ENAB(bus)) { + /* Download the firmware */ + dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); + } else { + int err = 0; + bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, SBSDIO_ALP_AVAIL_REQ, &err); + } ret = _dhdsdio_download_firmware(bus) == 0; - dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); + /* For SLPAUTO, keep ALP_REQ otherwise device can go into deep-sleep + * without host request + */ + if (!SLPAUTO_ENAB(bus)) + dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); + DHD_OS_WAKE_UNLOCK(bus->dhd); return ret; } @@ -5787,14 +6336,13 @@ dhdsdio_release_dongle(dhd_bus_t *bus, osl_t *osh, bool dongle_isolation, bool r dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); } #if !defined(BCMLXSDMMC) - if (dongle_isolation == FALSE) + if (KSO_ENAB(bus) && (dongle_isolation == FALSE)) si_watchdog(bus->sih, 4); #endif /* !defined(BCMLXSDMMC) */ if (bus->dhd) { dhdsdio_clkctl(bus, CLK_NONE, FALSE); } si_detach(bus->sih); - bus->sih = NULL; if (bus->vars && bus->varsz) MFREE(osh, bus->vars, bus->varsz); bus->vars = NULL; @@ -5845,6 +6393,17 @@ dhd_bus_unregister(void) bcmsdh_unregister(); } +/* Register a dummy SDIO client driver in order to be notified of new SDIO device */ +int dhd_bus_reg_sdio_notify(void* semaphore) +{ + return bcmsdh_reg_sdio_notify(semaphore); +} + +void dhd_bus_unreg_sdio_notify(void) +{ + bcmsdh_unreg_sdio_notify(); +} + #ifdef BCMEMBEDIMAGE static int dhdsdio_download_code_array(struct dhd_bus *bus) @@ -6108,6 +6667,8 @@ _dhdsdio_download_firmware(struct dhd_bus *bus) dlok = TRUE; } } +#else + BCM_REFERENCE(embed); #endif if (!dlok) { DHD_ERROR(("%s: dongle image download failed\n", __FUNCTION__)); @@ -6142,6 +6703,11 @@ dhd_bcmsdh_recv_buf(dhd_bus_t *bus, uint32 addr, uint fn, uint flags, uint8 *buf { int status; + if (!KSO_ENAB(bus)) { + DHD_ERROR(("%s: Device asleep\n", __FUNCTION__)); + return BCME_NODEVICE; + } + status = bcmsdh_recv_buf(bus->sdh, addr, fn, flags, buf, nbytes, pkt, complete, handle); return status; @@ -6151,6 +6717,11 @@ static int dhd_bcmsdh_send_buf(dhd_bus_t *bus, uint32 addr, uint fn, uint flags, uint8 *buf, uint nbytes, void *pkt, bcmsdh_cmplt_fn_t complete, void *handle) { + if (!KSO_ENAB(bus)) { + DHD_ERROR(("%s: Device asleep\n", __FUNCTION__)); + return BCME_NODEVICE; + } + return (bcmsdh_send_buf(bus->sdh, addr, fn, flags, buf, nbytes, pkt, complete, handle)); } @@ -6265,7 +6836,7 @@ dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag) bcmerror = BCME_SDIO_ERROR; #ifdef DHDTHREAD - dhd_os_sdunlock(dhdp); + dhd_os_sdunlock(dhdp); #endif /* DHDTHREAD */ } else { bcmerror = BCME_SDIO_ERROR; diff --git a/drivers/net/wireless/bcmdhd/dhd_wlfc.h b/drivers/net/wireless/bcmdhd/dhd_wlfc.h index c4d251806d7..42c3a6442e9 100644 --- a/drivers/net/wireless/bcmdhd/dhd_wlfc.h +++ b/drivers/net/wireless/bcmdhd/dhd_wlfc.h @@ -1,7 +1,7 @@ /* -* Copyright (C) 1999-2011, Broadcom Corporation +* Copyright (C) 1999-2012, Broadcom Corporation * -* Unless you and Broadcom execute a separate written software license +* Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -18,7 +18,7 @@ * Notwithstanding the above, under no circumstances may you combine this * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. -* $Id: dhd_wlfc.h 286994 2011-09-29 21:27:44Z $ +* $Id: dhd_wlfc.h 294267 2011-11-04 23:41:52Z $ * */ #ifndef __wlfc_host_driver_definitions_h__ @@ -222,7 +222,7 @@ typedef struct athost_wl_status_info { athost_wl_stat_counters_t stats; /* the additional ones are for bc/mc and ATIM FIFO */ - int FIFO_credit[AC_COUNT + 2]; + int FIFO_credit[AC_COUNT + 2]; /* Credit borrow counts for each FIFO from each of the other FIFOs */ int credits_borrowed[AC_COUNT + 2][AC_COUNT + 2]; diff --git a/drivers/net/wireless/bcmdhd/dngl_stats.h b/drivers/net/wireless/bcmdhd/dngl_stats.h index 9cdf718b399..5e5a2e2e531 100644 --- a/drivers/net/wireless/bcmdhd/dngl_stats.h +++ b/drivers/net/wireless/bcmdhd/dngl_stats.h @@ -2,9 +2,9 @@ * Common stats definitions for clients of dongle * ports * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -22,7 +22,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: dngl_stats.h,v 1.5 2008-06-02 16:56:20 Exp $ + * $Id: dngl_stats.h 241182 2011-02-17 21:50:03Z $ */ #ifndef _dngl_stats_h_ diff --git a/drivers/net/wireless/bcmdhd/dngl_wlhdr.h b/drivers/net/wireless/bcmdhd/dngl_wlhdr.h index 8b39b9ecb58..0e37df6e19e 100644 --- a/drivers/net/wireless/bcmdhd/dngl_wlhdr.h +++ b/drivers/net/wireless/bcmdhd/dngl_wlhdr.h @@ -1,9 +1,9 @@ /* * Dongle WL Header definitions * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: dngl_wlhdr.h,v 1.1 2009-01-08 01:21:12 Exp $ + * $Id: dngl_wlhdr.h 241182 2011-02-17 21:50:03Z $ */ #ifndef _dngl_wlhdr_h_ diff --git a/drivers/net/wireless/bcmdhd/hndpmu.c b/drivers/net/wireless/bcmdhd/hndpmu.c index 0e493343c80..d5c757d57e6 100644 --- a/drivers/net/wireless/bcmdhd/hndpmu.c +++ b/drivers/net/wireless/bcmdhd/hndpmu.c @@ -2,9 +2,9 @@ * Misc utility routines for accessing PMU corerev specific features * of the SiliconBackplane-based Broadcom chips. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -22,9 +22,10 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: hndpmu.c,v 1.228.2.56 2011-02-11 22:49:07 $ + * $Id: hndpmu.c 309997 2012-01-21 06:26:00Z $ */ +#include #include #include #include diff --git a/drivers/net/wireless/bcmdhd/include/Makefile b/drivers/net/wireless/bcmdhd/include/Makefile index 67c4906f588..42b3b689b56 100644 --- a/drivers/net/wireless/bcmdhd/include/Makefile +++ b/drivers/net/wireless/bcmdhd/include/Makefile @@ -10,7 +10,7 @@ # # Copyright 2005, Broadcom, Inc. # -# $Id: Makefile 241702 2011-02-19 00:41:03Z $ +# $Id: Makefile 241686 2011-02-19 00:22:45Z $ # SRCBASE := .. diff --git a/drivers/net/wireless/bcmdhd/include/aidmp.h b/drivers/net/wireless/bcmdhd/include/aidmp.h index b993a033abc..63513e6f6e2 100644 --- a/drivers/net/wireless/bcmdhd/include/aidmp.h +++ b/drivers/net/wireless/bcmdhd/include/aidmp.h @@ -1,9 +1,9 @@ /* * Broadcom AMBA Interconnect definitions. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,10 +21,9 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: aidmp.h 277737 2011-08-16 17:54:59Z $ + * $Id: aidmp.h 241182 2011-02-17 21:50:03Z $ */ - #ifndef _AIDMP_H #define _AIDMP_H @@ -191,7 +190,7 @@ typedef volatile struct _aidmp { uint32 errlogflags; uint32 PAD[56]; uint32 intstatus; - uint32 PAD[127]; + uint32 PAD[255]; uint32 config; uint32 PAD[63]; uint32 itcr; @@ -312,7 +311,6 @@ typedef volatile struct _aidmp { #define AI_RESETCTRL 0x800 #define AI_RESETSTATUS 0x804 - #define AI_IOCTRLWIDTH 0x700 #define AI_IOSTATUSWIDTH 0x704 diff --git a/drivers/net/wireless/bcmdhd/include/bcm_android_types.h b/drivers/net/wireless/bcmdhd/include/bcm_android_types.h new file mode 100644 index 00000000000..fd8aea72539 --- /dev/null +++ b/drivers/net/wireless/bcmdhd/include/bcm_android_types.h @@ -0,0 +1,44 @@ +/* + * Android related remote wl declarations + * + * Copyright (C) 2012, Broadcom Corporation + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of Broadcom Corporation. + * $Id: bcm_android_types.h 241182 2011-02-17 21:50:03Z $ + * + */ +#ifndef _wlu_android_h +#define _wlu_android_h +#define __fd_mask unsigned long +typedef struct + { + +#ifdef __USE_XOPEN + __fd_mask fds_bits[__FD_SETSIZE / __NFDBITS]; +# define __FDS_BITS(set) ((set)->fds_bits) +#else + __fd_mask __fds_bits[__FD_SETSIZE / __NFDBITS]; +# define __FDS_BITS(set) ((set)->__fds_bits) +#endif + } fd_set1; +#define fd_set fd_set1 + +#define htons(x) BCMSWAP16(x) +#define htonl(x) BCMSWAP32(x) +#define __FD_ZERO(s) \ + do { \ + unsigned int __i; \ + fd_set *__arr = (s); \ + for (__i = 0; __i < sizeof (fd_set) / sizeof (__fd_mask); ++__i) \ + __FDS_BITS(__arr)[__i] = 0; \ + } while (0) +#define __FD_SET(d, s) (__FDS_BITS (s)[__FDELT(d)] |= __FDMASK(d)) +#define __FD_CLR(d, s) (__FDS_BITS (s)[__FDELT(d)] &= ~__FDMASK(d)) +#define __FD_ISSET(d, s) ((__FDS_BITS (s)[__FDELT(d)] & __FDMASK(d)) != 0) +#define MCL_CURRENT 1 +#define MCL_FUTURE 2 +#endif diff --git a/drivers/net/wireless/bcmdhd/include/bcm_cfg.h b/drivers/net/wireless/bcmdhd/include/bcm_cfg.h new file mode 100644 index 00000000000..26da752186a --- /dev/null +++ b/drivers/net/wireless/bcmdhd/include/bcm_cfg.h @@ -0,0 +1,29 @@ +/* + * BCM common config options + * + * Copyright (C) 1999-2012, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: bcm_cfg.h 294399 2011-11-07 03:31:22Z $ + */ + +#ifndef _bcm_cfg_h_ +#define _bcm_cfg_h_ +#endif diff --git a/drivers/net/wireless/bcmdhd/include/bcm_mpool_pub.h b/drivers/net/wireless/bcmdhd/include/bcm_mpool_pub.h new file mode 100644 index 00000000000..8fe3de7afb7 --- /dev/null +++ b/drivers/net/wireless/bcmdhd/include/bcm_mpool_pub.h @@ -0,0 +1,361 @@ +/* + * Memory pools library, Public interface + * + * API Overview + * + * This package provides a memory allocation subsystem based on pools of + * homogenous objects. + * + * Instrumentation is available for reporting memory utilization both + * on a per-data-structure basis and system wide. + * + * There are two main types defined in this API. + * + * pool manager: A singleton object that acts as a factory for + * pool allocators. It also is used for global + * instrumentation, such as reporting all blocks + * in use across all data structures. The pool manager + * creates and provides individual memory pools + * upon request to application code. + * + * memory pool: An object for allocating homogenous memory blocks. + * + * Global identifiers in this module use the following prefixes: + * bcm_mpm_* Memory pool manager + * bcm_mp_* Memory pool + * + * There are two main types of memory pools: + * + * prealloc: The contiguous memory block of objects can either be supplied + * by the client or malloc'ed by the memory manager. The objects are + * allocated out of a block of memory and freed back to the block. + * + * heap: The memory pool allocator uses the heap (malloc/free) for memory. + * In this case, the pool allocator is just providing statistics + * and instrumentation on top of the heap, without modifying the heap + * allocation implementation. + * + * Copyright (C) 1999-2012, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id$ + */ + +#ifndef _BCM_MPOOL_PUB_H +#define _BCM_MPOOL_PUB_H 1 + +#include /* needed for uint16 */ + + +/* +************************************************************************** +* +* Type definitions, handles +* +************************************************************************** +*/ + +/* Forward declaration of OSL handle. */ +struct osl_info; + +/* Forward declaration of string buffer. */ +struct bcmstrbuf; + +/* + * Opaque type definition for the pool manager handle. This object is used for global + * memory pool operations such as obtaining a new pool, deleting a pool, iterating and + * instrumentation/debugging. + */ +struct bcm_mpm_mgr; +typedef struct bcm_mpm_mgr *bcm_mpm_mgr_h; + +/* + * Opaque type definition for an instance of a pool. This handle is used for allocating + * and freeing memory through the pool, as well as management/instrumentation on this + * specific pool. + */ +struct bcm_mp_pool; +typedef struct bcm_mp_pool *bcm_mp_pool_h; + + +/* + * To make instrumentation more readable, every memory + * pool must have a readable name. Pool names are up to + * 8 bytes including '\0' termination. (7 printable characters.) + */ +#define BCM_MP_NAMELEN 8 + + +/* + * Type definition for pool statistics. + */ +typedef struct bcm_mp_stats { + char name[BCM_MP_NAMELEN]; /* Name of this pool. */ + unsigned int objsz; /* Object size allocated in this pool */ + uint16 nobj; /* Total number of objects in this pool */ + uint16 num_alloc; /* Number of objects currently allocated */ + uint16 high_water; /* Max number of allocated objects. */ + uint16 failed_alloc; /* Failed allocations. */ +} bcm_mp_stats_t; + + +/* +************************************************************************** +* +* API Routines on the pool manager. +* +************************************************************************** +*/ + +/* + * bcm_mpm_init() - initialize the whole memory pool system. + * + * Parameters: + * osh: INPUT Operating system handle. Needed for heap memory allocation. + * max_pools: INPUT Maximum number of mempools supported. + * mgr: OUTPUT The handle is written with the new pools manager object/handle. + * + * Returns: + * BCME_OK Object initialized successfully. May be used. + * BCME_NOMEM Initialization failed due to no memory. Object must not be used. + */ +int bcm_mpm_init(struct osl_info *osh, int max_pools, bcm_mpm_mgr_h *mgrp); + + +/* + * bcm_mpm_deinit() - de-initialize the whole memory pool system. + * + * Parameters: + * mgr: INPUT Pointer to pool manager handle. + * + * Returns: + * BCME_OK Memory pool manager successfully de-initialized. + * other Indicated error occured during de-initialization. + */ +int bcm_mpm_deinit(bcm_mpm_mgr_h *mgrp); + +/* + * bcm_mpm_create_prealloc_pool() - Create a new pool for fixed size objects. The + * pool uses a contiguous block of pre-alloced + * memory. The memory block may either be provided + * by the client or dynamically allocated by the + * pool manager. + * + * Parameters: + * mgr: INPUT The handle to the pool manager + * obj_sz: INPUT Size of objects that will be allocated by the new pool + * Must be >= sizeof(void *). + * nobj: INPUT Maximum number of concurrently existing objects to support + * memstart INPUT Pointer to the memory to use, or NULL to malloc() + * memsize INPUT Number of bytes referenced from memstart (for error checking). + * Must be 0 if 'memstart' is NULL. + * poolname INPUT For instrumentation, the name of the pool + * newp: OUTPUT The handle for the new pool, if creation is successful + * + * Returns: + * BCME_OK Pool created ok. + * other Pool not created due to indicated error. newpoolp set to NULL. + * + * + */ +int bcm_mpm_create_prealloc_pool(bcm_mpm_mgr_h mgr, + unsigned int obj_sz, + int nobj, + void *memstart, + unsigned int memsize, + char poolname[BCM_MP_NAMELEN], + bcm_mp_pool_h *newp); + + +/* + * bcm_mpm_delete_prealloc_pool() - Delete a memory pool. This should only be called after + * all memory objects have been freed back to the pool. + * + * Parameters: + * mgr: INPUT The handle to the pools manager + * pool: INPUT The handle of the pool to delete + * + * Returns: + * BCME_OK Pool deleted ok. + * other Pool not deleted due to indicated error. + * + */ +int bcm_mpm_delete_prealloc_pool(bcm_mpm_mgr_h mgr, bcm_mp_pool_h *poolp); + +/* + * bcm_mpm_create_heap_pool() - Create a new pool for fixed size objects. The memory + * pool allocator uses the heap (malloc/free) for memory. + * In this case, the pool allocator is just providing + * statistics and instrumentation on top of the heap, + * without modifying the heap allocation implementation. + * + * Parameters: + * mgr: INPUT The handle to the pool manager + * obj_sz: INPUT Size of objects that will be allocated by the new pool + * poolname INPUT For instrumentation, the name of the pool + * newp: OUTPUT The handle for the new pool, if creation is successful + * + * Returns: + * BCME_OK Pool created ok. + * other Pool not created due to indicated error. newpoolp set to NULL. + * + * + */ +int bcm_mpm_create_heap_pool(bcm_mpm_mgr_h mgr, unsigned int obj_sz, + char poolname[BCM_MP_NAMELEN], + bcm_mp_pool_h *newp); + + +/* + * bcm_mpm_delete_heap_pool() - Delete a memory pool. This should only be called after + * all memory objects have been freed back to the pool. + * + * Parameters: + * mgr: INPUT The handle to the pools manager + * pool: INPUT The handle of the pool to delete + * + * Returns: + * BCME_OK Pool deleted ok. + * other Pool not deleted due to indicated error. + * + */ +int bcm_mpm_delete_heap_pool(bcm_mpm_mgr_h mgr, bcm_mp_pool_h *poolp); + + +/* + * bcm_mpm_stats() - Return stats for all pools + * + * Parameters: + * mgr: INPUT The handle to the pools manager + * stats: OUTPUT Array of pool statistics. + * nentries: MOD Max elements in 'stats' array on INPUT. Actual number + * of array elements copied to 'stats' on OUTPUT. + * + * Returns: + * BCME_OK Ok + * other Error getting stats. + * + */ +int bcm_mpm_stats(bcm_mpm_mgr_h mgr, bcm_mp_stats_t *stats, int *nentries); + + +/* + * bcm_mpm_dump() - Display statistics on all pools + * + * Parameters: + * mgr: INPUT The handle to the pools manager + * b: OUTPUT Output buffer. + * + * Returns: + * BCME_OK Ok + * other Error during dump. + * + */ +int bcm_mpm_dump(bcm_mpm_mgr_h mgr, struct bcmstrbuf *b); + + +/* + * bcm_mpm_get_obj_size() - The size of memory objects may need to be padded to + * compensate for alignment requirements of the objects. + * This function provides the padded object size. If clients + * pre-allocate a memory slab for a memory pool, the + * padded object size should be used by the client to allocate + * the memory slab (in order to provide sufficent space for + * the maximum number of objects). + * + * Parameters: + * mgr: INPUT The handle to the pools manager. + * obj_sz: INPUT Input object size. + * padded_obj_sz: OUTPUT Padded object size. + * + * Returns: + * BCME_OK Ok + * BCME_BADARG Bad arguments. + * + */ +int bcm_mpm_get_obj_size(bcm_mpm_mgr_h mgr, unsigned int obj_sz, unsigned int *padded_obj_sz); + + +/* +*************************************************************************** +* +* API Routines on a specific pool. +* +*************************************************************************** +*/ + + +/* + * bcm_mp_alloc() - Allocate a memory pool object. + * + * Parameters: + * pool: INPUT The handle to the pool. + * + * Returns: + * A pointer to the new object. NULL on error. + * + */ +void* bcm_mp_alloc(bcm_mp_pool_h pool); + +/* + * bcm_mp_free() - Free a memory pool object. + * + * Parameters: + * pool: INPUT The handle to the pool. + * objp: INPUT A pointer to the object to free. + * + * Returns: + * BCME_OK Ok + * other Error during free. + * + */ +int bcm_mp_free(bcm_mp_pool_h pool, void *objp); + +/* + * bcm_mp_stats() - Return stats for this pool + * + * Parameters: + * pool: INPUT The handle to the pool + * stats: OUTPUT Pool statistics + * + * Returns: + * BCME_OK Ok + * other Error getting statistics. + * + */ +int bcm_mp_stats(bcm_mp_pool_h pool, bcm_mp_stats_t *stats); + + +/* + * bcm_mp_dump() - Dump a pool + * + * Parameters: + * pool: INPUT The handle to the pool + * b OUTPUT Output buffer + * + * Returns: + * BCME_OK Ok + * other Error during dump. + * + */ +int bcm_mp_dump(bcm_mp_pool_h pool, struct bcmstrbuf *b); + + +#endif /* _BCM_MPOOL_PUB_H */ diff --git a/drivers/net/wireless/bcmdhd/include/bcmcdc.h b/drivers/net/wireless/bcmdhd/include/bcmcdc.h index 77a20f87b7e..a21eae3ac61 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmcdc.h +++ b/drivers/net/wireless/bcmdhd/include/bcmcdc.h @@ -4,9 +4,9 @@ * * Definitions subject to change without notice. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -24,9 +24,8 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: bcmcdc.h 277737 2011-08-16 17:54:59Z $ + * $Id: bcmcdc.h 309825 2012-01-20 20:16:13Z $ */ - #ifndef _bcmcdc_h_ #define _bcmcdc_h_ #include @@ -71,26 +70,43 @@ typedef struct cdc_ioctl { +struct bdc_header { + uint8 flags; + uint8 priority; + uint8 flags2; + uint8 dataOffset; +}; + #define BDC_HEADER_LEN 4 -#define BDC_PROTO_VER_1 1 -#define BDC_PROTO_VER 2 +#define BDC_FLAG_80211_PKT 0x01 +#define BDC_FLAG_SUM_GOOD 0x04 +#define BDC_FLAG_SUM_NEEDED 0x08 #define BDC_FLAG_VER_MASK 0xf0 #define BDC_FLAG_VER_SHIFT 4 -#define BDC_FLAG__UNUSED 0x03 -#define BDC_FLAG_SUM_GOOD 0x04 -#define BDC_FLAG_SUM_NEEDED 0x08 -#define BDC_PRIORITY_MASK 0x7 +#define BDC_PRIORITY_MASK 0x07 +#define BDC_PRIORITY_FC_MASK 0xf0 +#define BDC_PRIORITY_FC_SHIFT 4 -#define BDC_FLAG2_FC_FLAG 0x10 - -#define BDC_PRIORITY_FC_SHIFT 4 #define BDC_FLAG2_IF_MASK 0x0f #define BDC_FLAG2_IF_SHIFT 0 +#define BDC_FLAG2_FC_FLAG 0x10 + + + +#define BDC_PROTO_VER_1 1 +#define BDC_PROTO_VER 2 + + +#define BDC_GET_IF_IDX(hdr) \ + ((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT)) +#define BDC_SET_IF_IDX(hdr, idx) \ + ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | ((idx) << BDC_FLAG2_IF_SHIFT))) + #define BDC_FLAG2_PAD_MASK 0xf0 #define BDC_FLAG_PAD_MASK 0x03 #define BDC_FLAG2_PAD_SHIFT 2 @@ -106,16 +122,4 @@ typedef struct cdc_ioctl { ((hdr)->flags = (((hdr)->flags & ~BDC_FLAG_PAD_MASK) | \ (((idx) & BDC_FLAG_PAD_IDX) << BDC_FLAG_PAD_SHIFT))) -#define BDC_GET_IF_IDX(hdr) \ - ((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT)) -#define BDC_SET_IF_IDX(hdr, idx) \ - ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | ((idx) << BDC_FLAG2_IF_SHIFT))) - -struct bdc_header { - uint8 flags; - uint8 priority; - uint8 flags2; - uint8 dataOffset; -}; - #endif diff --git a/drivers/net/wireless/bcmdhd/include/bcmdefs.h b/drivers/net/wireless/bcmdhd/include/bcmdefs.h index 17cc0e955f6..c7f4cf4ecdd 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmdefs.h +++ b/drivers/net/wireless/bcmdhd/include/bcmdefs.h @@ -1,9 +1,9 @@ /* * Misc system wide definitions * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,10 +21,9 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: bcmdefs.h 279282 2011-08-23 22:44:02Z $ + * $Id: bcmdefs.h 309174 2012-01-18 23:10:14Z $ */ - #ifndef _bcmdefs_h_ #define _bcmdefs_h_ @@ -34,6 +33,14 @@ #define BCM_REFERENCE(data) ((void)(data)) +#define STATIC_ASSERT(expr) { \ + \ + typedef enum { _STATIC_ASSERT_NOT_CONSTANT = (expr) } _static_assert_e; \ + \ + typedef char STATIC_ASSERT_FAIL[(expr) ? 1 : -1]; \ +} + + #define bcmreclaimed 0 #define _data _data @@ -45,14 +52,10 @@ #define _fn _fn #define BCMNMIATTACHFN(_fn) _fn #define BCMNMIATTACHDATA(_data) _data -#define BCMOVERLAY0DATA(_sym) _sym -#define BCMOVERLAY0FN(_fn) _fn -#define BCMOVERLAY1DATA(_sym) _sym -#define BCMOVERLAY1FN(_fn) _fn -#define BCMOVERLAYERRFN(_fn) _fn #define CONST const +#ifndef BCMFASTPATH #define BCMFASTPATH - +#endif @@ -67,22 +70,6 @@ #define BCMROMDAT_SPATCH(data) - -#define OVERLAY_INLINE -#define OSTATIC static -#define BCMOVERLAYDATA(_ovly, _sym) _sym -#define BCMOVERLAYFN(_ovly, _fn) _fn -#define BCMOVERLAYERRFN(_fn) _fn -#define BCMROMOVERLAYDATA(_ovly, _data) _data -#define BCMROMOVERLAYFN(_ovly, _fn) _fn -#define BCMATTACHOVERLAYDATA(_ovly, _sym) _sym -#define BCMATTACHOVERLAYFN(_ovly, _fn) _fn -#define BCMINITOVERLAYDATA(_ovly, _sym) _sym -#define BCMINITOVERLAYFN(_ovly, _fn) _fn -#define BCMUNINITOVERLAYFN(_ovly, _fn) _fn - - - #define SI_BUS 0 #define PCI_BUS 1 #define PCMCIA_BUS 2 @@ -190,8 +177,13 @@ typedef struct { #if defined(BCM_RPC_NOCOPY) || defined(BCM_RCP_TXNOCOPY) #define BCMEXTRAHDROOM 220 -#else +#else #define BCMEXTRAHDROOM 172 +#endif + + +#ifndef SDALIGN +#define SDALIGN 32 #endif @@ -226,6 +218,16 @@ typedef struct { #define MAXSZ_NVRAM_VARS 4096 -#define LOCATOR_EXTERN static + + +#ifdef DL_NVRAM +#define NVRAM_ARRAY_MAXSIZE DL_NVRAM +#else +#define NVRAM_ARRAY_MAXSIZE MAXSZ_NVRAM_VARS +#endif + +#ifdef BCMUSBDEV_ENABLED +extern uint32 gFWID; +#endif #endif diff --git a/drivers/net/wireless/bcmdhd/include/bcmdevs.h b/drivers/net/wireless/bcmdhd/include/bcmdevs.h index ee01d8b4567..c49d68eecd6 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmdevs.h +++ b/drivers/net/wireless/bcmdhd/include/bcmdevs.h @@ -1,9 +1,9 @@ /* * Broadcom device-specific manifest constants. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,10 +21,9 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: bcmdevs.h 295140 2011-11-09 17:22:01Z $ + * $Id: bcmdevs.h 309997 2012-01-21 06:26:00Z $ */ - #ifndef _BCMDEVS_H #define _BCMDEVS_H @@ -60,7 +59,11 @@ #define BCM_DNGL_BL_PID_43236 0xbd17 #define BCM_DNGL_BL_PID_4332 0xbd18 #define BCM_DNGL_BL_PID_4330 0xbd19 +#define BCM_DNGL_BL_PID_4334 0xbd1a #define BCM_DNGL_BL_PID_43239 0xbd1b +#define BCM_DNGL_BL_PID_4324 0xbd1c +#define BCM_DNGL_BL_PID_4360 0xbd1d + #define BCM_DNGL_BDC_PID 0x0bdc #define BCM_DNGL_JTAG_PID 0x4a44 @@ -134,16 +137,31 @@ #define BCM43237_D11N_ID 0x4355 #define BCM43237_D11N5G_ID 0x4356 #define BCM43227_D11N2G_ID 0x4358 -#define BCM43228_D11N_ID 0x4359 +#define BCM43228_D11N_ID 0x4359 #define BCM43228_D11N5G_ID 0x435a #define BCM43362_D11N_ID 0x4363 #define BCM43239_D11N_ID 0x4370 #define BCM4324_D11N_ID 0x4374 #define BCM43217_D11N2G_ID 0x43a9 #define BCM43131_D11N2G_ID 0x43aa - #define BCM4314_D11N2G_ID 0x4364 #define BCM43142_D11N2G_ID 0x4365 +#define BCM4334_D11N_ID 0x4380 +#define BCM4334_D11N2G_ID 0x4381 +#define BCM4334_D11N5G_ID 0x4382 +#define BCM4360_D11AC_ID 0x43a0 +#define BCM4360_D11AC2G_ID 0x43a1 +#define BCM4360_D11AC5G_ID 0x43a2 + + +#define BCM943228HMB_SSID_VEN1 0x0607 +#define BCM94313HMGBL_SSID_VEN1 0x0608 +#define BCM94313HMG_SSID_VEN1 0x0609 + + +#define BCM4335_D11AC_ID 0x43a9 +#define BCM4335_D11AC2G_ID 0x43aa +#define BCM4335_D11AC5G_ID 0x43ab #define BCMGPRS_UART_ID 0x4333 #define BCMGPRS2_UART_ID 0x4344 @@ -225,6 +243,7 @@ #define BCM43421_CHIP_ID 43421 #define BCM43428_CHIP_ID 43428 #define BCM43431_CHIP_ID 43431 +#define BCM43460_CHIP_ID 43460 #define BCM4325_CHIP_ID 0x4325 #define BCM4328_CHIP_ID 0x4328 #define BCM4329_CHIP_ID 0x4329 @@ -235,11 +254,17 @@ #define BCM6362_CHIP_ID 0x6362 #define BCM4314_CHIP_ID 0x4314 #define BCM43142_CHIP_ID 43142 -#define BCM4324_CHIP_ID 0x4324 +#define BCM4324_CHIP_ID 0x4324 +#define BCM43242_CHIP_ID 43242 +#define BCM4334_CHIP_ID 0x4334 +#define BCM4360_CHIP_ID 0x4360 + +#define BCM4335_CHIP_ID 0x4335 #define BCM4342_CHIP_ID 4342 #define BCM4402_CHIP_ID 0x4402 #define BCM4704_CHIP_ID 0x4704 +#define BCM4706_CHIP_ID 0x5300 #define BCM4710_CHIP_ID 0x4710 #define BCM4712_CHIP_ID 0x4712 #define BCM4716_CHIP_ID 0x4716 @@ -278,11 +303,14 @@ #define BCM5357_PKG_ID 11 #define BCM5356U_PKG_ID 12 #define BCM53572_PKG_ID 8 +#define BCM5357C0_PKG_ID 8 #define BCM47188_PKG_ID 9 +#define BCM5358C0_PKG_ID 0xa +#define BCM5356C0_PKG_ID 0xb #define BCM4331TT_PKG_ID 8 #define BCM4331TN_PKG_ID 9 #define BCM4331TNA0_PKG_ID 0xb - +#define BCM4706L_PKG_ID 1 #define HDLSIM5350_PKG_ID 1 #define HDLSIM_PKG_ID 14 @@ -312,9 +340,7 @@ #define BFL_CCKHIPWR 0x00000040 #define BFL_ENETADM 0x00000080 #define BFL_ENETVLAN 0x00000100 -#ifdef WLAFTERBURNER -#define BFL_AFTERBURNER 0x00000200 -#endif +#define BFL_UNUSED 0x00000200 #define BFL_NOPCI 0x00000400 #define BFL_FEM 0x00000800 #define BFL_EXTLNA 0x00001000 @@ -362,6 +388,9 @@ #define BFL2_IPALVLSHIFT_3P3 0x00020000 #define BFL2_INTERNDET_TXIQCAL 0x00040000 #define BFL2_XTALBUFOUTEN 0x00080000 + + + #define BFL2_ANAPACTRL_2G 0x00100000 #define BFL2_ANAPACTRL_5G 0x00200000 #define BFL2_ELNACTRL_TRSW_2G 0x00400000 @@ -369,10 +398,11 @@ #define BFL2_TEMPSENSE_HIGHER 0x01000000 #define BFL2_BTC3WIREONLY 0x02000000 #define BFL2_PWR_NOMINAL 0x04000000 -#define BFL2_EXTLNA_TX 0x08000000 +#define BFL2_EXTLNA_PWRSAVE 0x08000000 #define BFL2_4313_RADIOREG 0x10000000 +#define BFL2_SDR_EN 0x20000000 #define BOARD_GPIO_BTC3W_IN 0x850 @@ -388,7 +418,8 @@ #define BOARD_GPIO_BTC4_BT 0x2000 #define BOARD_GPIO_BTC4_STAT 0x4000 #define BOARD_GPIO_BTC4_WLAN 0x8000 -#define BOARD_GPIO_1_WLAN_PWR 0x2 +#define BOARD_GPIO_1_WLAN_PWR 0x02 +#define BOARD_GPIO_3_WLAN_PWR 0x08 #define BOARD_GPIO_4_WLAN_PWR 0x10 #define GPIO_BTC4W_OUT_4312 0x010 @@ -397,6 +428,7 @@ #define GPIO_BTC4W_OUT_43225 0x0e0 #define GPIO_BTC4W_OUT_43421 0x020 #define GPIO_BTC4W_OUT_4313 0x060 +#define GPIO_BTC4W_OUT_4331_SHARED 0x010 #define PCI_CFG_GPIO_SCS 0x10 #define PCI_CFG_GPIO_HWRAD 0x20 @@ -410,316 +442,6 @@ #define XTAL_ON_DELAY 1000 -#define BU4710_BOARD 0x0400 -#define VSIM4710_BOARD 0x0401 -#define QT4710_BOARD 0x0402 - -#define BU4309_BOARD 0x040a -#define BCM94309CB_BOARD 0x040b -#define BCM94309MP_BOARD 0x040c -#define BCM4309AP_BOARD 0x040d - -#define BCM94302MP_BOARD 0x040e - -#define BU4306_BOARD 0x0416 -#define BCM94306CB_BOARD 0x0417 -#define BCM94306MP_BOARD 0x0418 - -#define BCM94710D_BOARD 0x041a -#define BCM94710R1_BOARD 0x041b -#define BCM94710R4_BOARD 0x041c -#define BCM94710AP_BOARD 0x041d - -#define BU2050_BOARD 0x041f - -#define BCM94306P50_BOARD 0x0420 - -#define BCM94309G_BOARD 0x0421 - -#define BU4704_BOARD 0x0423 -#define BU4702_BOARD 0x0424 - -#define BCM94306PC_BOARD 0x0425 - -#define MPSG4306_BOARD 0x0427 - -#define BCM94702MN_BOARD 0x0428 - - -#define BCM94702CPCI_BOARD 0x0429 - - -#define BCM95380RR_BOARD 0x042a - - -#define BCM94306CBSG_BOARD 0x042b - - -#define PCSG94306_BOARD 0x042d - - -#define BU4704SD_BOARD 0x042e - - -#define BCM94704AGR_BOARD 0x042f - - -#define BCM94308MP_BOARD 0x0430 - - -#define BCM94306GPRS_BOARD 0x0432 - - -#define BU5365_FPGA_BOARD 0x0433 - -#define BU4712_BOARD 0x0444 -#define BU4712SD_BOARD 0x045d -#define BU4712L_BOARD 0x045f - - -#define BCM94712AP_BOARD 0x0445 -#define BCM94712P_BOARD 0x0446 - - -#define BU4318_BOARD 0x0447 -#define CB4318_BOARD 0x0448 -#define MPG4318_BOARD 0x0449 -#define MP4318_BOARD 0x044a -#define SD4318_BOARD 0x044b - - -#define BCM94313BU_BOARD 0x050f -#define BCM94313HM_BOARD 0x0510 -#define BCM94313EPA_BOARD 0x0511 -#define BCM94313HMG_BOARD 0x051C - - -#define BCM96338_BOARD 0x6338 -#define BCM96348_BOARD 0x6348 -#define BCM96358_BOARD 0x6358 -#define BCM96368_BOARD 0x6368 - - -#define BCM94306P_BOARD 0x044c - - -#define BCM94303MP_BOARD 0x044e - - -#define BCM94306MPSGH_BOARD 0x044f - - -#define BCM94306MPM 0x0450 -#define BCM94306MPL 0x0453 - - -#define BCM94712AGR_BOARD 0x0451 - - -#define PC4303_BOARD 0x0454 - - -#define BCM95350K_BOARD 0x0455 - - -#define BCM95350R_BOARD 0x0456 - - -#define BCM94306MPLNA_BOARD 0x0457 - - -#define BU4320_BOARD 0x0458 -#define BU4320S_BOARD 0x0459 -#define BCM94320PH_BOARD 0x045a - - -#define BCM94306MPH_BOARD 0x045b - - -#define BCM94306PCIV_BOARD 0x045c - -#define BU4712SD_BOARD 0x045d - -#define BCM94320PFLSH_BOARD 0x045e - -#define BU4712L_BOARD 0x045f -#define BCM94712LGR_BOARD 0x0460 -#define BCM94320R_BOARD 0x0461 - -#define BU5352_BOARD 0x0462 - -#define BCM94318MPGH_BOARD 0x0463 - -#define BU4311_BOARD 0x0464 -#define BCM94311MC_BOARD 0x0465 -#define BCM94311MCAG_BOARD 0x0466 - -#define BCM95352GR_BOARD 0x0467 - - -#define BCM95351AGR_BOARD 0x0470 - - -#define BCM94704MPCB_BOARD 0x0472 - - -#define BU4785_BOARD 0x0478 - - -#define BU4321_BOARD 0x046b -#define BU4321E_BOARD 0x047c -#define MP4321_BOARD 0x046c -#define CB2_4321_BOARD 0x046d -#define CB2_4321_AG_BOARD 0x0066 -#define MC4321_BOARD 0x046e - - -#define BU4328_BOARD 0x0481 -#define BCM4328SDG_BOARD 0x0482 -#define BCM4328SDAG_BOARD 0x0483 -#define BCM4328UG_BOARD 0x0484 -#define BCM4328UAG_BOARD 0x0485 -#define BCM4328PC_BOARD 0x0486 -#define BCM4328CF_BOARD 0x0487 - - -#define BCM94325DEVBU_BOARD 0x0490 -#define BCM94325BGABU_BOARD 0x0491 - -#define BCM94325SDGWB_BOARD 0x0492 - -#define BCM94325SDGMDL_BOARD 0x04aa -#define BCM94325SDGMDL2_BOARD 0x04c6 -#define BCM94325SDGMDL3_BOARD 0x04c9 - -#define BCM94325SDABGWBA_BOARD 0x04e1 - - -#define BCM94322MC_SSID 0x04a4 -#define BCM94322USB_SSID 0x04a8 -#define BCM94322HM_SSID 0x04b0 -#define BCM94322USB2D_SSID 0x04bf - - -#define BCM4312MCGSG_BOARD 0x04b5 - - -#define BCM94315DEVBU_SSID 0x04c2 -#define BCM94315USBGP_SSID 0x04c7 -#define BCM94315BGABU_SSID 0x04ca -#define BCM94315USBGP41_SSID 0x04cb - - -#define BCM94319DEVBU_SSID 0X04e5 -#define BCM94319USB_SSID 0X04e6 -#define BCM94319SD_SSID 0X04e7 - - -#define BCM94716NR2_SSID 0x04cd - - -#define BCM94319DEVBU_SSID 0X04e5 -#define BCM94319USBNP4L_SSID 0X04e6 -#define BCM94319WLUSBN4L_SSID 0X04e7 -#define BCM94319SDG_SSID 0X04ea -#define BCM94319LCUSBSDN4L_SSID 0X04eb -#define BCM94319USBB_SSID 0x04ee -#define BCM94319LCSDN4L_SSID 0X0507 -#define BCM94319LSUSBN4L_SSID 0X0508 -#define BCM94319SDNA4L_SSID 0X0517 -#define BCM94319SDELNA4L_SSID 0X0518 -#define BCM94319SDELNA6L_SSID 0X0539 -#define BCM94319ARCADYAN_SSID 0X0546 -#define BCM94319WINDSOR_SSID 0x0561 -#define BCM94319MLAP_SSID 0x0562 -#define BCM94319SDNA_SSID 0x058b -#define BCM94319BHEMU3_SSID 0x0563 -#define BCM94319SDHMB_SSID 0x058c -#define BCM94319SDBREF_SSID 0x05a1 -#define BCM94319USBSDB_SSID 0x05a2 - - - -#define BCM94329AGB_SSID 0X04b9 -#define BCM94329TDKMDL1_SSID 0X04ba -#define BCM94329TDKMDL11_SSID 0X04fc -#define BCM94329OLYMPICN18_SSID 0X04fd -#define BCM94329OLYMPICN90_SSID 0X04fe -#define BCM94329OLYMPICN90U_SSID 0X050c -#define BCM94329OLYMPICN90M_SSID 0X050b -#define BCM94329AGBF_SSID 0X04ff -#define BCM94329OLYMPICX17_SSID 0X0504 -#define BCM94329OLYMPICX17M_SSID 0X050a -#define BCM94329OLYMPICX17U_SSID 0X0509 -#define BCM94329OLYMPICUNO_SSID 0X0564 -#define BCM94329MOTOROLA_SSID 0X0565 -#define BCM94329OLYMPICLOCO_SSID 0X0568 - -#define BCM94336SD_WLBGABU_SSID 0x0511 -#define BCM94336SD_WLBGAREF_SSID 0x0519 -#define BCM94336SDGP_SSID 0x0538 -#define BCM94336SDG_SSID 0x0519 -#define BCM94336SDGN_SSID 0x0538 -#define BCM94336SDGFC_SSID 0x056B - - -#define BCM94330SDG_SSID 0x0528 -#define BCM94330SD_FCBGABU_SSID 0x052e -#define BCM94330SD_WLBGABU_SSID 0x052f -#define BCM94330SD_FCBGA_SSID 0x0530 -#define BCM94330FCSDAGB_SSID 0x0532 -#define BCM94330OLYMPICAMG_SSID 0x0549 -#define BCM94330OLYMPICAMGEPA_SSID 0x054F -#define BCM94330OLYMPICUNO3_SSID 0x0551 -#define BCM94330WLSDAGB_SSID 0x0547 -#define BCM94330CSPSDAGBB_SSID 0x054A - - -#define BCM943224X21 0x056e -#define BCM943224X21_FCC 0x00d1 - - -#define BCM943228BU8_SSID 0x0540 -#define BCM943228BU9_SSID 0x0541 -#define BCM943228BU_SSID 0x0542 -#define BCM943227HM4L_SSID 0x0543 -#define BCM943227HMB_SSID 0x0544 -#define BCM943228HM4L_SSID 0x0545 -#define BCM943228SD_SSID 0x0573 - - -#define BCM943239MOD_SSID 0x05ac -#define BCM943239REF_SSID 0x05aa - - -#define BCM94331X19 0x00D6 -#define BCM94331PCIEBT3Ax_SSID 0x00E4 -#define BCM94331X12_2G_SSID 0x00EC -#define BCM94331X12_5G_SSID 0x00ED -#define BCM94331X29B 0x00EF -#define BCM94331BU_SSID 0x0523 -#define BCM94331S9BU_SSID 0x0524 -#define BCM94331MC_SSID 0x0525 -#define BCM94331MCI_SSID 0x0526 -#define BCM94331PCIEBT4_SSID 0x0527 -#define BCM94331HM_SSID 0x0574 -#define BCM94331PCIEDUAL_SSID 0x059B -#define BCM94331MCH5_SSID 0x05A9 -#define BCM94331PCIEDUALV2_SSID 0x05B7 -#define BCM94331CS_SSID 0x05C6 -#define BCM94331CSAX_SSID 0x00EF - - -#define BCM953572BU_SSID 0x058D -#define BCM953572NR2_SSID 0x058E -#define BCM947188NR2_SSID 0x058F -#define BCM953572SDRNR2_SSID 0x0590 - - -#define BCM943236OLYMPICSULLEY_SSID 0x594 -#define BCM943236PREPROTOBLU2O3_SSID 0x5b9 -#define BCM943236USBELNA_SSID 0x5f8 - #define GPIO_NUMPINS 32 @@ -738,8 +460,22 @@ #define MUXENAB_UART 0x00000001 #define MUXENAB_GPIO 0x00000002 -#define MUXENAB_ERCX 0x00000004 +#define MUXENAB_ERCX 0x00000004 #define MUXENAB_JTAG 0x00000008 -#define MUXENAB_HOST_WAKE 0x00000010 +#define MUXENAB_HOST_WAKE 0x00000010 +#define MUXENAB_I2S_EN 0x00000020 +#define MUXENAB_I2S_MASTER 0x00000040 +#define MUXENAB_I2S_FULL 0x00000080 +#define MUXENAB_SFLASH 0x00000100 +#define MUXENAB_RFSWCTRL0 0x00000200 +#define MUXENAB_RFSWCTRL1 0x00000400 +#define MUXENAB_RFSWCTRL2 0x00000800 +#define MUXENAB_SECI 0x00001000 +#define MUXENAB_BT_LEGACY 0x00002000 +#define MUXENAB_HOST_WAKE1 0x00004000 + + +#define FLASH_KERNEL_NFLASH 0x00000001 +#define FLASH_BOOT_NFLASH 0x00000002 #endif diff --git a/drivers/net/wireless/bcmdhd/include/bcmendian.h b/drivers/net/wireless/bcmdhd/include/bcmendian.h index f3356a724b4..22eb7dbcb95 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmendian.h +++ b/drivers/net/wireless/bcmdhd/include/bcmendian.h @@ -1,9 +1,9 @@ /* * Byte order utilities * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,13 +21,12 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: bcmendian.h 277737 2011-08-16 17:54:59Z $ + * $Id: bcmendian.h 241182 2011-02-17 21:50:03Z $ * * This file by default provides proper behavior on little-endian architectures. * On big-endian architectures, IL_BIGENDIAN should be defined. */ - #ifndef _BCMENDIAN_H_ #define _BCMENDIAN_H_ diff --git a/drivers/net/wireless/bcmdhd/include/bcmnvram.h b/drivers/net/wireless/bcmdhd/include/bcmnvram.h new file mode 100644 index 00000000000..ba6726be0fe --- /dev/null +++ b/drivers/net/wireless/bcmdhd/include/bcmnvram.h @@ -0,0 +1,136 @@ +/* + * NVRAM variable manipulation + * + * Copyright (C) 1999-2012, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: bcmnvram.h 288000 2011-10-05 19:05:16Z $ + */ + +#ifndef _bcmnvram_h_ +#define _bcmnvram_h_ + +#ifndef _LANGUAGE_ASSEMBLY + +#include +#include + +struct nvram_header { + uint32 magic; + uint32 len; + uint32 crc_ver_init; + uint32 config_refresh; + uint32 config_ncdl; +}; + +struct nvram_tuple { + char *name; + char *value; + struct nvram_tuple *next; +}; + + +extern char *nvram_default_get(const char *name); + + +extern int nvram_init(void *sih); + + +extern int nvram_append(void *si, char *vars, uint varsz); + +extern void nvram_get_global_vars(char **varlst, uint *varsz); + + + +extern int nvram_reset(void *sih); + + +extern void nvram_exit(void *sih); + + +extern char * nvram_get(const char *name); + + +extern int nvram_resetgpio_init(void *sih); + + +static INLINE char * +nvram_safe_get(const char *name) +{ + char *p = nvram_get(name); + return p ? p : ""; +} + + +static INLINE int +nvram_match(char *name, char *match) +{ + const char *value = nvram_get(name); + return (value && !strcmp(value, match)); +} + + +static INLINE int +nvram_invmatch(char *name, char *invmatch) +{ + const char *value = nvram_get(name); + return (value && strcmp(value, invmatch)); +} + + +extern int nvram_set(const char *name, const char *value); + + +extern int nvram_unset(const char *name); + + +extern int nvram_commit(void); + + +extern int nvram_getall(char *nvram_buf, int count); + + +uint8 nvram_calc_crc(struct nvram_header * nvh); + +#endif + + +#define NVRAM_SOFTWARE_VERSION "1" + +#define NVRAM_MAGIC 0x48534C46 +#define NVRAM_CLEAR_MAGIC 0x0 +#define NVRAM_INVALID_MAGIC 0xFFFFFFFF +#define NVRAM_VERSION 1 +#define NVRAM_HEADER_SIZE 20 +#define NVRAM_SPACE 0x8000 + +#define NVRAM_MAX_VALUE_LEN 255 +#define NVRAM_MAX_PARAM_LEN 64 + +#define NVRAM_CRC_START_POSITION 9 +#define NVRAM_CRC_VER_MASK 0xffffff00 + + +#define NVRAM_START_COMPRESSED 0x400 +#define NVRAM_START 0x1000 + +#define BCM_JUMBO_NVRAM_DELIMIT '\n' +#define BCM_JUMBO_START "Broadcom Jumbo Nvram file" +#endif diff --git a/drivers/net/wireless/bcmdhd/include/bcmpcispi.h b/drivers/net/wireless/bcmdhd/include/bcmpcispi.h index 51e0427e7f6..44b263cec6a 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmpcispi.h +++ b/drivers/net/wireless/bcmdhd/include/bcmpcispi.h @@ -1,9 +1,9 @@ /* * Broadcom PCI-SPI Host Controller Register Definitions * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: bcmpcispi.h 277737 2011-08-16 17:54:59Z $ + * $Id: bcmpcispi.h 241182 2011-02-17 21:50:03Z $ */ #ifndef _BCM_PCI_SPI_H #define _BCM_PCI_SPI_H diff --git a/drivers/net/wireless/bcmdhd/include/bcmperf.h b/drivers/net/wireless/bcmdhd/include/bcmperf.h index a503edbd622..74383076889 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmperf.h +++ b/drivers/net/wireless/bcmdhd/include/bcmperf.h @@ -1,9 +1,9 @@ /* * Performance counters software interface. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: bcmperf.h 277737 2011-08-16 17:54:59Z $ + * $Id: bcmperf.h 241182 2011-02-17 21:50:03Z $ */ /* essai */ #ifndef _BCMPERF_H_ diff --git a/drivers/net/wireless/bcmdhd/include/bcmsdbus.h b/drivers/net/wireless/bcmdhd/include/bcmsdbus.h index 21a58b473e9..b6fdd1f8a66 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmsdbus.h +++ b/drivers/net/wireless/bcmdhd/include/bcmsdbus.h @@ -2,9 +2,9 @@ * Definitions for API from sdio common code (bcmsdh) to individual * host controller drivers. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -22,7 +22,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: bcmsdbus.h 300017 2011-12-01 20:30:27Z $ + * $Id: bcmsdbus.h 299859 2011-12-01 03:53:27Z $ */ #ifndef _sdio_api_h_ @@ -117,6 +117,9 @@ void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh); +#if defined(BCMSDIOH_STD) + #define SDIOH_SLEEP_ENABLED +#endif extern SDIOH_API_RC sdioh_sleep(sdioh_info_t *si, bool enab); /* GPIO support */ diff --git a/drivers/net/wireless/bcmdhd/include/bcmsdh.h b/drivers/net/wireless/bcmdhd/include/bcmsdh.h index def3c026927..177498a1204 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmsdh.h +++ b/drivers/net/wireless/bcmdhd/include/bcmsdh.h @@ -3,9 +3,9 @@ * export functions to client drivers * abstract OS and BUS specific details of SDIO * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -23,7 +23,11 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: bcmsdh.h 300017 2011-12-01 20:30:27Z $ + * $Id: bcmsdh.h 309548 2012-01-20 01:13:08Z $ + */ + +/** + * @file bcmsdh.h */ #ifndef _bcmsdh_h_ @@ -36,6 +40,10 @@ extern const uint bcmsdh_msglevel; #define BCMSDH_ERROR(x) #define BCMSDH_INFO(x) +#if (defined(BCMSDIOH_STD) || defined(BCMSDIOH_BCM) || defined(BCMSDIOH_SPI)) +#define BCMSDH_ADAPTER +#endif /* BCMSDIO && (BCMSDIOH_STD || BCMSDIOH_BCM || BCMSDIOH_SPI) */ + /* forward declarations */ typedef struct bcmsdh_info bcmsdh_info_t; typedef void (*bcmsdh_cb_fn_t)(void *); @@ -68,11 +76,6 @@ extern int bcmsdh_intr_dereg(void *sdh); extern bool bcmsdh_intr_pending(void *sdh); #endif -#ifdef BCMLXSDMMC -extern int bcmsdh_claim_host_and_lock(void *sdh); -extern int bcmsdh_release_host_and_unlock(void *sdh); -#endif /* BCMLXSDMMC */ - /* Register a callback to be called if and when bcmsdh detects * device removal. No-op in the case of non-removable/hardwired devices. */ @@ -108,6 +111,9 @@ extern int bcmsdh_cis_read(void *sdh, uint func, uint8 *cis, uint length); extern uint32 bcmsdh_reg_read(void *sdh, uint32 addr, uint size); extern uint32 bcmsdh_reg_write(void *sdh, uint32 addr, uint size, uint32 data); +/* set sb address window */ +extern int bcmsdhsdio_set_sbaddr_window(void *sdh, uint32 address, bool force_set); + /* Indicate if last reg read/write failed */ extern bool bcmsdh_regfail(void *sdh); @@ -126,15 +132,16 @@ extern bool bcmsdh_regfail(void *sdh); typedef void (*bcmsdh_cmplt_fn_t)(void *handle, int status, bool sync_waiting); extern int bcmsdh_send_buf(void *sdh, uint32 addr, uint fn, uint flags, uint8 *buf, uint nbytes, void *pkt, - bcmsdh_cmplt_fn_t complete, void *handle); + bcmsdh_cmplt_fn_t complete_fn, void *handle); extern int bcmsdh_recv_buf(void *sdh, uint32 addr, uint fn, uint flags, uint8 *buf, uint nbytes, void *pkt, - bcmsdh_cmplt_fn_t complete, void *handle); + bcmsdh_cmplt_fn_t complete_fn, void *handle); /* Flags bits */ #define SDIO_REQ_4BYTE 0x1 /* Four-byte target (backplane) width (vs. two-byte) */ #define SDIO_REQ_FIXED 0x2 /* Fixed address (FIFO) (vs. incrementing address) */ #define SDIO_REQ_ASYNC 0x4 /* Async request (vs. sync request) */ +#define SDIO_BYTE_MODE 0x8 /* Byte mode request(non-block mode) */ /* Pending (non-error) return code */ #define BCME_PENDING 1 @@ -193,11 +200,15 @@ extern void bcmsdh_unregister(void); extern bool bcmsdh_chipmatch(uint16 vendor, uint16 device); extern void bcmsdh_device_remove(void * sdh); +extern int bcmsdh_reg_sdio_notify(void* semaphore); +extern void bcmsdh_unreg_sdio_notify(void); + #if defined(OOB_INTR_ONLY) extern int bcmsdh_register_oob_intr(void * dhdp); extern void bcmsdh_unregister_oob_intr(void); extern void bcmsdh_oob_intr_set(bool enable); #endif /* defined(OOB_INTR_ONLY) */ + /* Function to pass device-status bits to DHD. */ extern uint32 bcmsdh_get_dstatus(void *sdh); diff --git a/drivers/net/wireless/bcmdhd/include/bcmsdh_sdmmc.h b/drivers/net/wireless/bcmdhd/include/bcmsdh_sdmmc.h index bea97b610a8..69114208d01 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmsdh_sdmmc.h +++ b/drivers/net/wireless/bcmdhd/include/bcmsdh_sdmmc.h @@ -1,9 +1,9 @@ /* * BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: bcmsdh_sdmmc.h 277737 2011-08-16 17:54:59Z $ + * $Id: bcmsdh_sdmmc.h 294363 2011-11-06 23:02:20Z $ */ #ifndef __BCMSDH_SDMMC_H__ diff --git a/drivers/net/wireless/bcmdhd/include/bcmsdpcm.h b/drivers/net/wireless/bcmdhd/include/bcmsdpcm.h index 1b9d39fee8f..80c0a3d13ee 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmsdpcm.h +++ b/drivers/net/wireless/bcmdhd/include/bcmsdpcm.h @@ -2,9 +2,9 @@ * Broadcom SDIO/PCMCIA * Software-specific definitions shared between device and host side * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -22,7 +22,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: bcmsdpcm.h 277737 2011-08-16 17:54:59Z $ + * $Id: bcmsdpcm.h 291086 2011-10-21 01:17:24Z $ */ #ifndef _bcmsdpcm_h_ diff --git a/drivers/net/wireless/bcmdhd/include/bcmsdspi.h b/drivers/net/wireless/bcmdhd/include/bcmsdspi.h index a62bee42b2b..3d444f3ba26 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmsdspi.h +++ b/drivers/net/wireless/bcmdhd/include/bcmsdspi.h @@ -1,9 +1,9 @@ /* * SD-SPI Protocol Conversion - BCMSDH->SPI Translation Layer * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: bcmsdspi.h 277737 2011-08-16 17:54:59Z $ + * $Id: bcmsdspi.h 294363 2011-11-06 23:02:20Z $ */ #ifndef _BCM_SD_SPI_H #define _BCM_SD_SPI_H diff --git a/drivers/net/wireless/bcmdhd/include/bcmsdstd.h b/drivers/net/wireless/bcmdhd/include/bcmsdstd.h index c14444c57d3..16f084e6b6e 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmsdstd.h +++ b/drivers/net/wireless/bcmdhd/include/bcmsdstd.h @@ -1,9 +1,9 @@ /* * 'Standard' SDIO HOST CONTROLLER driver * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: bcmsdstd.h 281604 2011-09-02 18:58:49Z $ + * $Id: bcmsdstd.h 294369 2011-11-06 23:22:23Z $ */ #ifndef _BCM_SD_STD_H #define _BCM_SD_STD_H @@ -130,7 +130,7 @@ struct sdioh_info { int8 sd_dma_mode; /* DMA Mode (PIO, SDMA, ... ADMA2) on CMD53 */ uint8 num_funcs; /* Supported funcs on client */ uint32 com_cis_ptr; - uint32 func_cis_ptr[SDIOD_MAX_IOFUNCS]; + uint32 func_cis_ptr[SDIOD_MAX_FUNCS]; void *dma_buf; /* DMA Buffer virtual address */ ulong dma_phys; /* DMA Buffer physical address */ void *adma2_dscr_buf; /* ADMA2 Descriptor Buffer virtual address */ diff --git a/drivers/net/wireless/bcmdhd/include/bcmspi.h b/drivers/net/wireless/bcmdhd/include/bcmspi.h index 34a02d00c6b..e226cb10229 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmspi.h +++ b/drivers/net/wireless/bcmdhd/include/bcmspi.h @@ -1,9 +1,9 @@ /* * Broadcom SPI Low-Level Hardware Driver API * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: bcmspi.h 277737 2011-08-16 17:54:59Z $ + * $Id: bcmspi.h 241182 2011-02-17 21:50:03Z $ */ #ifndef _BCM_SPI_H #define _BCM_SPI_H diff --git a/drivers/net/wireless/bcmdhd/include/bcmspibrcm.h b/drivers/net/wireless/bcmdhd/include/bcmspibrcm.h new file mode 100644 index 00000000000..0975dc8acda --- /dev/null +++ b/drivers/net/wireless/bcmdhd/include/bcmspibrcm.h @@ -0,0 +1,139 @@ +/* + * SD-SPI Protocol Conversion - BCMSDH->gSPI Translation Layer + * + * Copyright (C) 2012, Broadcom Corporation + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of Broadcom Corporation. + * + * $Id: bcmspibrcm.h 241182 2011-02-17 21:50:03Z $ + */ +#ifndef _BCM_SPI_BRCM_H +#define _BCM_SPI_BRCM_H + +/* global msglevel for debug messages - bitvals come from sdiovar.h */ + +#define sd_err(x) +#define sd_trace(x) +#define sd_info(x) +#define sd_debug(x) +#define sd_data(x) +#define sd_ctrl(x) + +#define sd_log(x) + +#define SDIOH_ASSERT(exp) \ + do { if (!(exp)) \ + printf("!!!ASSERT fail: file %s lines %d", __FILE__, __LINE__); \ + } while (0) + +#define BLOCK_SIZE_F1 64 +#define BLOCK_SIZE_F2 2048 +#define BLOCK_SIZE_F3 2048 + +/* internal return code */ +#define SUCCESS 0 +#undef ERROR +#define ERROR 1 +#define ERROR_UF 2 +#define ERROR_OF 3 + +/* private bus modes */ +#define SDIOH_MODE_SPI 0 + +#define USE_BLOCKMODE 0x2 /* Block mode can be single block or multi */ +#define USE_MULTIBLOCK 0x4 + +struct sdioh_info { + uint cfg_bar; /* pci cfg address for bar */ + uint32 caps; /* cached value of capabilities reg */ + void *bar0; /* BAR0 for PCI Device */ + osl_t *osh; /* osh handler */ + void *controller; /* Pointer to SPI Controller's private data struct */ + + uint lockcount; /* nest count of spi_lock() calls */ + bool client_intr_enabled; /* interrupt connnected flag */ + bool intr_handler_valid; /* client driver interrupt handler valid */ + sdioh_cb_fn_t intr_handler; /* registered interrupt handler */ + void *intr_handler_arg; /* argument to call interrupt handler */ + bool initialized; /* card initialized */ + uint32 target_dev; /* Target device ID */ + uint32 intmask; /* Current active interrupts */ + void *sdos_info; /* Pointer to per-OS private data */ + + uint32 controller_type; /* Host controller type */ + uint8 version; /* Host Controller Spec Compliance Version */ + uint irq; /* Client irq */ + uint32 intrcount; /* Client interrupts */ + uint32 local_intrcount; /* Controller interrupts */ + bool host_init_done; /* Controller initted */ + bool card_init_done; /* Client SDIO interface initted */ + bool polled_mode; /* polling for command completion */ + + bool sd_use_dma; /* DMA on CMD53 */ + bool sd_blockmode; /* sd_blockmode == FALSE => 64 Byte Cmd 53s. */ + /* Must be on for sd_multiblock to be effective */ + bool use_client_ints; /* If this is false, make sure to restore */ + /* polling hack in wl_linux.c:wl_timer() */ + int adapter_slot; /* Maybe dealing with multiple slots/controllers */ + int sd_mode; /* SD1/SD4/SPI */ + int client_block_size[SPI_MAX_IOFUNCS]; /* Blocksize */ + uint32 data_xfer_count; /* Current transfer */ + uint16 card_rca; /* Current Address */ + uint8 num_funcs; /* Supported funcs on client */ + uint32 card_dstatus; /* 32bit device status */ + uint32 com_cis_ptr; + uint32 func_cis_ptr[SPI_MAX_IOFUNCS]; + void *dma_buf; + ulong dma_phys; + int r_cnt; /* rx count */ + int t_cnt; /* tx_count */ + uint32 wordlen; /* host processor 16/32bits */ + uint32 prev_fun; + uint32 chip; + uint32 chiprev; + bool resp_delay_all; + bool dwordmode; + bool resp_delay_new; + + struct spierrstats_t spierrstats; +}; + +/************************************************************ + * Internal interfaces: per-port references into bcmspibrcm.c + */ + +/* Global message bits */ +extern uint sd_msglevel; + +/************************************************************** + * Internal interfaces: bcmspibrcm.c references to per-port code + */ + +/* Interrupt (de)registration routines */ +extern int spi_register_irq(sdioh_info_t *sd, uint irq); +extern void spi_free_irq(uint irq, sdioh_info_t *sd); + +/* OS-specific interrupt wrappers (atomic interrupt enable/disable) */ +extern void spi_lock(sdioh_info_t *sd); +extern void spi_unlock(sdioh_info_t *sd); + +/* Allocate/init/free per-OS private data */ +extern int spi_osinit(sdioh_info_t *sd); +extern void spi_osfree(sdioh_info_t *sd); + +#define SPI_RW_FLAG_M BITFIELD_MASK(1) /* Bit [31] - R/W Command Bit */ +#define SPI_RW_FLAG_S 31 +#define SPI_ACCESS_M BITFIELD_MASK(1) /* Bit [30] - Fixed/Incr Access */ +#define SPI_ACCESS_S 30 +#define SPI_FUNCTION_M BITFIELD_MASK(2) /* Bit [29:28] - Function Number */ +#define SPI_FUNCTION_S 28 +#define SPI_REG_ADDR_M BITFIELD_MASK(17) /* Bit [27:11] - Address */ +#define SPI_REG_ADDR_S 11 +#define SPI_LEN_M BITFIELD_MASK(11) /* Bit [10:0] - Packet length */ +#define SPI_LEN_S 0 + +#endif /* _BCM_SPI_BRCM_H */ diff --git a/drivers/net/wireless/bcmdhd/include/bcmsrom_fmt.h b/drivers/net/wireless/bcmdhd/include/bcmsrom_fmt.h new file mode 100644 index 00000000000..8e38edc39d9 --- /dev/null +++ b/drivers/net/wireless/bcmdhd/include/bcmsrom_fmt.h @@ -0,0 +1,554 @@ +/* + * SROM format definition. + * + * Copyright (C) 1999-2012, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: bcmsrom_fmt.h 309193 2012-01-19 00:03:57Z $ + */ + +#ifndef _bcmsrom_fmt_h_ +#define _bcmsrom_fmt_h_ + +#define SROM_MAXREV 11 /* max revisiton supported by driver */ + +/* Maximum srom: 6 Kilobits == 768 bytes */ +#define SROM_MAX 768 +#define SROM_MAXW 384 +#define VARS_MAX 4096 + +/* PCI fields */ +#define PCI_F0DEVID 48 + + +#define SROM_WORDS 64 + +#define SROM3_SWRGN_OFF 28 /* s/w region offset in words */ + +#define SROM_SSID 2 + +#define SROM_WL1LHMAXP 29 + +#define SROM_WL1LPAB0 30 +#define SROM_WL1LPAB1 31 +#define SROM_WL1LPAB2 32 + +#define SROM_WL1HPAB0 33 +#define SROM_WL1HPAB1 34 +#define SROM_WL1HPAB2 35 + +#define SROM_MACHI_IL0 36 +#define SROM_MACMID_IL0 37 +#define SROM_MACLO_IL0 38 +#define SROM_MACHI_ET0 39 +#define SROM_MACMID_ET0 40 +#define SROM_MACLO_ET0 41 +#define SROM_MACHI_ET1 42 +#define SROM_MACMID_ET1 43 +#define SROM_MACLO_ET1 44 +#define SROM3_MACHI 37 +#define SROM3_MACMID 38 +#define SROM3_MACLO 39 + +#define SROM_BXARSSI2G 40 +#define SROM_BXARSSI5G 41 + +#define SROM_TRI52G 42 +#define SROM_TRI5GHL 43 + +#define SROM_RXPO52G 45 + +#define SROM2_ENETPHY 45 + +#define SROM_AABREV 46 +/* Fields in AABREV */ +#define SROM_BR_MASK 0x00ff +#define SROM_CC_MASK 0x0f00 +#define SROM_CC_SHIFT 8 +#define SROM_AA0_MASK 0x3000 +#define SROM_AA0_SHIFT 12 +#define SROM_AA1_MASK 0xc000 +#define SROM_AA1_SHIFT 14 + +#define SROM_WL0PAB0 47 +#define SROM_WL0PAB1 48 +#define SROM_WL0PAB2 49 + +#define SROM_LEDBH10 50 +#define SROM_LEDBH32 51 + +#define SROM_WL10MAXP 52 + +#define SROM_WL1PAB0 53 +#define SROM_WL1PAB1 54 +#define SROM_WL1PAB2 55 + +#define SROM_ITT 56 + +#define SROM_BFL 57 +#define SROM_BFL2 28 +#define SROM3_BFL2 61 + +#define SROM_AG10 58 + +#define SROM_CCODE 59 + +#define SROM_OPO 60 + +#define SROM3_LEDDC 62 + +#define SROM_CRCREV 63 + +/* SROM Rev 4: Reallocate the software part of the srom to accomodate + * MIMO features. It assumes up to two PCIE functions and 440 bytes + * of useable srom i.e. the useable storage in chips with OTP that + * implements hardware redundancy. + */ + +#define SROM4_WORDS 220 + +#define SROM4_SIGN 32 +#define SROM4_SIGNATURE 0x5372 + +#define SROM4_BREV 33 + +#define SROM4_BFL0 34 +#define SROM4_BFL1 35 +#define SROM4_BFL2 36 +#define SROM4_BFL3 37 +#define SROM5_BFL0 37 +#define SROM5_BFL1 38 +#define SROM5_BFL2 39 +#define SROM5_BFL3 40 + +#define SROM4_MACHI 38 +#define SROM4_MACMID 39 +#define SROM4_MACLO 40 +#define SROM5_MACHI 41 +#define SROM5_MACMID 42 +#define SROM5_MACLO 43 + +#define SROM4_CCODE 41 +#define SROM4_REGREV 42 +#define SROM5_CCODE 34 +#define SROM5_REGREV 35 + +#define SROM4_LEDBH10 43 +#define SROM4_LEDBH32 44 +#define SROM5_LEDBH10 59 +#define SROM5_LEDBH32 60 + +#define SROM4_LEDDC 45 +#define SROM5_LEDDC 45 + +#define SROM4_AA 46 +#define SROM4_AA2G_MASK 0x00ff +#define SROM4_AA2G_SHIFT 0 +#define SROM4_AA5G_MASK 0xff00 +#define SROM4_AA5G_SHIFT 8 + +#define SROM4_AG10 47 +#define SROM4_AG32 48 + +#define SROM4_TXPID2G 49 +#define SROM4_TXPID5G 51 +#define SROM4_TXPID5GL 53 +#define SROM4_TXPID5GH 55 + +#define SROM4_TXRXC 61 +#define SROM4_TXCHAIN_MASK 0x000f +#define SROM4_TXCHAIN_SHIFT 0 +#define SROM4_RXCHAIN_MASK 0x00f0 +#define SROM4_RXCHAIN_SHIFT 4 +#define SROM4_SWITCH_MASK 0xff00 +#define SROM4_SWITCH_SHIFT 8 + + +/* Per-path fields */ +#define MAX_PATH_SROM 4 +#define SROM4_PATH0 64 +#define SROM4_PATH1 87 +#define SROM4_PATH2 110 +#define SROM4_PATH3 133 + +#define SROM4_2G_ITT_MAXP 0 +#define SROM4_2G_PA 1 +#define SROM4_5G_ITT_MAXP 5 +#define SROM4_5GLH_MAXP 6 +#define SROM4_5G_PA 7 +#define SROM4_5GL_PA 11 +#define SROM4_5GH_PA 15 + +/* Fields in the ITT_MAXP and 5GLH_MAXP words */ +#define B2G_MAXP_MASK 0xff +#define B2G_ITT_SHIFT 8 +#define B5G_MAXP_MASK 0xff +#define B5G_ITT_SHIFT 8 +#define B5GH_MAXP_MASK 0xff +#define B5GL_MAXP_SHIFT 8 + +/* All the miriad power offsets */ +#define SROM4_2G_CCKPO 156 +#define SROM4_2G_OFDMPO 157 +#define SROM4_5G_OFDMPO 159 +#define SROM4_5GL_OFDMPO 161 +#define SROM4_5GH_OFDMPO 163 +#define SROM4_2G_MCSPO 165 +#define SROM4_5G_MCSPO 173 +#define SROM4_5GL_MCSPO 181 +#define SROM4_5GH_MCSPO 189 +#define SROM4_CDDPO 197 +#define SROM4_STBCPO 198 +#define SROM4_BW40PO 199 +#define SROM4_BWDUPPO 200 + +#define SROM4_CRCREV 219 + + +/* SROM Rev 8: Make space for a 48word hardware header for PCIe rev >= 6. + * This is acombined srom for both MIMO and SISO boards, usable in + * the .130 4Kilobit OTP with hardware redundancy. + */ + +#define SROM8_SIGN 64 + +#define SROM8_BREV 65 + +#define SROM8_BFL0 66 +#define SROM8_BFL1 67 +#define SROM8_BFL2 68 +#define SROM8_BFL3 69 + +#define SROM8_MACHI 70 +#define SROM8_MACMID 71 +#define SROM8_MACLO 72 + +#define SROM8_CCODE 73 +#define SROM8_REGREV 74 + +#define SROM8_LEDBH10 75 +#define SROM8_LEDBH32 76 + +#define SROM8_LEDDC 77 + +#define SROM8_AA 78 + +#define SROM8_AG10 79 +#define SROM8_AG32 80 + +#define SROM8_TXRXC 81 + +#define SROM8_BXARSSI2G 82 +#define SROM8_BXARSSI5G 83 +#define SROM8_TRI52G 84 +#define SROM8_TRI5GHL 85 +#define SROM8_RXPO52G 86 + +#define SROM8_FEM2G 87 +#define SROM8_FEM5G 88 +#define SROM8_FEM_ANTSWLUT_MASK 0xf800 +#define SROM8_FEM_ANTSWLUT_SHIFT 11 +#define SROM8_FEM_TR_ISO_MASK 0x0700 +#define SROM8_FEM_TR_ISO_SHIFT 8 +#define SROM8_FEM_PDET_RANGE_MASK 0x00f8 +#define SROM8_FEM_PDET_RANGE_SHIFT 3 +#define SROM8_FEM_EXTPA_GAIN_MASK 0x0006 +#define SROM8_FEM_EXTPA_GAIN_SHIFT 1 +#define SROM8_FEM_TSSIPOS_MASK 0x0001 +#define SROM8_FEM_TSSIPOS_SHIFT 0 + +#define SROM8_THERMAL 89 + +/* Temp sense related entries */ +#define SROM8_MPWR_RAWTS 90 +#define SROM8_TS_SLP_OPT_CORRX 91 +/* FOC: freiquency offset correction, HWIQ: H/W IOCAL enable, IQSWP: IQ CAL swap disable */ +#define SROM8_FOC_HWIQ_IQSWP 92 + +#define SROM8_EXTLNAGAIN 93 + +/* Temperature delta for PHY calibration */ +#define SROM8_PHYCAL_TEMPDELTA 94 + +/* Measured power 1 & 2, 0-13 bits at offset 95, MSB 2 bits are unused for now. */ +#define SROM8_MPWR_1_AND_2 95 + + +/* Per-path offsets & fields */ +#define SROM8_PATH0 96 +#define SROM8_PATH1 112 +#define SROM8_PATH2 128 +#define SROM8_PATH3 144 + +#define SROM8_2G_ITT_MAXP 0 +#define SROM8_2G_PA 1 +#define SROM8_5G_ITT_MAXP 4 +#define SROM8_5GLH_MAXP 5 +#define SROM8_5G_PA 6 +#define SROM8_5GL_PA 9 +#define SROM8_5GH_PA 12 + +/* All the miriad power offsets */ +#define SROM8_2G_CCKPO 160 + +#define SROM8_2G_OFDMPO 161 +#define SROM8_5G_OFDMPO 163 +#define SROM8_5GL_OFDMPO 165 +#define SROM8_5GH_OFDMPO 167 + +#define SROM8_2G_MCSPO 169 +#define SROM8_5G_MCSPO 177 +#define SROM8_5GL_MCSPO 185 +#define SROM8_5GH_MCSPO 193 + +#define SROM8_CDDPO 201 +#define SROM8_STBCPO 202 +#define SROM8_BW40PO 203 +#define SROM8_BWDUPPO 204 + +/* SISO PA parameters are in the path0 spaces */ +#define SROM8_SISO 96 + +/* Legacy names for SISO PA paramters */ +#define SROM8_W0_ITTMAXP (SROM8_SISO + SROM8_2G_ITT_MAXP) +#define SROM8_W0_PAB0 (SROM8_SISO + SROM8_2G_PA) +#define SROM8_W0_PAB1 (SROM8_SISO + SROM8_2G_PA + 1) +#define SROM8_W0_PAB2 (SROM8_SISO + SROM8_2G_PA + 2) +#define SROM8_W1_ITTMAXP (SROM8_SISO + SROM8_5G_ITT_MAXP) +#define SROM8_W1_MAXP_LCHC (SROM8_SISO + SROM8_5GLH_MAXP) +#define SROM8_W1_PAB0 (SROM8_SISO + SROM8_5G_PA) +#define SROM8_W1_PAB1 (SROM8_SISO + SROM8_5G_PA + 1) +#define SROM8_W1_PAB2 (SROM8_SISO + SROM8_5G_PA + 2) +#define SROM8_W1_PAB0_LC (SROM8_SISO + SROM8_5GL_PA) +#define SROM8_W1_PAB1_LC (SROM8_SISO + SROM8_5GL_PA + 1) +#define SROM8_W1_PAB2_LC (SROM8_SISO + SROM8_5GL_PA + 2) +#define SROM8_W1_PAB0_HC (SROM8_SISO + SROM8_5GH_PA) +#define SROM8_W1_PAB1_HC (SROM8_SISO + SROM8_5GH_PA + 1) +#define SROM8_W1_PAB2_HC (SROM8_SISO + SROM8_5GH_PA + 2) + +#define SROM8_CRCREV 219 + +/* SROM REV 9 */ +#define SROM9_2GPO_CCKBW20 160 +#define SROM9_2GPO_CCKBW20UL 161 +#define SROM9_2GPO_LOFDMBW20 162 +#define SROM9_2GPO_LOFDMBW20UL 164 + +#define SROM9_5GLPO_LOFDMBW20 166 +#define SROM9_5GLPO_LOFDMBW20UL 168 +#define SROM9_5GMPO_LOFDMBW20 170 +#define SROM9_5GMPO_LOFDMBW20UL 172 +#define SROM9_5GHPO_LOFDMBW20 174 +#define SROM9_5GHPO_LOFDMBW20UL 176 + +#define SROM9_2GPO_MCSBW20 178 +#define SROM9_2GPO_MCSBW20UL 180 +#define SROM9_2GPO_MCSBW40 182 + +#define SROM9_5GLPO_MCSBW20 184 +#define SROM9_5GLPO_MCSBW20UL 186 +#define SROM9_5GLPO_MCSBW40 188 +#define SROM9_5GMPO_MCSBW20 190 +#define SROM9_5GMPO_MCSBW20UL 192 +#define SROM9_5GMPO_MCSBW40 194 +#define SROM9_5GHPO_MCSBW20 196 +#define SROM9_5GHPO_MCSBW20UL 198 +#define SROM9_5GHPO_MCSBW40 200 + +#define SROM9_PO_MCS32 202 +#define SROM9_PO_LOFDM40DUP 203 +#define SROM8_RXGAINERR_2G 205 +#define SROM8_RXGAINERR_5GL 206 +#define SROM8_RXGAINERR_5GM 207 +#define SROM8_RXGAINERR_5GH 208 +#define SROM8_RXGAINERR_5GU 209 +#define SROM8_SUBBAND_PPR 210 +#define SROM8_PCIEINGRESS_WAR 211 +#define SROM9_SAR 212 + +#define SROM8_NOISELVL_2G 213 +#define SROM8_NOISELVL_5GL 214 +#define SROM8_NOISELVL_5GM 215 +#define SROM8_NOISELVL_5GH 216 +#define SROM8_NOISELVL_5GU 217 + +#define SROM9_REV_CRC 219 + +#define SROM10_CCKPWROFFSET 218 +#define SROM10_SIGN 219 +#define SROM10_SWCTRLMAP_2G 220 +#define SROM10_CRCREV 229 + +#define SROM10_WORDS 230 +#define SROM10_SIGNATURE SROM4_SIGNATURE + + +/* SROM REV 11 */ +#define SROM11_BREV 65 + +#define SROM11_BFL0 66 +#define SROM11_BFL1 67 +#define SROM11_BFL2 68 +#define SROM11_BFL3 69 +#define SROM11_BFL4 70 +#define SROM11_BFL5 71 + +#define SROM11_MACHI 72 +#define SROM11_MACMID 73 +#define SROM11_MACLO 74 + +#define SROM11_CCODE 75 +#define SROM11_REGREV 76 + +#define SROM11_LEDBH10 77 +#define SROM11_LEDBH32 78 + +#define SROM11_LEDDC 79 + +#define SROM11_AA 80 + +#define SROM11_AGBG10 81 +#define SROM11_AGBG2A0 82 +#define SROM11_AGA21 83 + +#define SROM11_TXRXC 84 + +#define SROM11_FEM_CFG1 85 +#define SROM11_FEM_CFG2 86 + +#define SROM11_THERMAL 87 +#define SROM11_MPWR_RAWTS 88 +#define SROM11_TS_SLP_OPT_CORRX 89 +#define SROM11_PHYCAL_TEMPDELTA 92 +#define SROM11_MPWR_1_AND_2 93 + +#define SROM11_PDOFF_40M_A0 101 +#define SROM11_PDOFF_40M_A1 102 +#define SROM11_PDOFF_40M_A2 103 +#define SROM11_PDOFF_80M_A0 104 +#define SROM11_PDOFF_80M_A1 105 +#define SROM11_PDOFF_80M_A2 106 + +#define SROM11_SUBBAND5GVER 107 + +/* Per-path fields and offset */ +#define MAX_PATH_SROM_11 3 +#define SROM11_PATH0 108 +#define SROM11_PATH1 128 +#define SROM11_PATH2 148 + +#define SROM11_2G_MAXP 0 +#define SROM11_2G_PA 1 +#define SROM11_RXGAINS 5 +#define SROM11_5GB1B0_MAXP 6 +#define SROM11_5GB3B2_MAXP 7 +#define SROM11_5GB0_PA 8 +#define SROM11_5GB1_PA 11 +#define SROM11_5GB2_PA 14 +#define SROM11_5GB3_PA 17 + +/* Power per rate */ +#define SROM11_CCKBW202GPO 168 +#define SROM11_CCKBW20UL2GPO 169 +#define SROM11_MCSBW202GPO 170 +#define SROM11_MCSBW202GPO_1 171 +#define SROM11_MCSBW402GPO 172 +#define SROM11_MCSBW402GPO_1 173 +#define SROM11_DOT11AGOFDMHRBW202GPO 174 +#define SROM11_OFDMLRBW202GPO 175 + +#define SROM11_MCSBW205GLPO 176 +#define SROM11_MCSBW205GLPO_1 177 +#define SROM11_MCSBW405GLPO 178 +#define SROM11_MCSBW405GLPO_1 179 +#define SROM11_MCSBW805GLPO 180 +#define SROM11_MCSBW805GLPO_1 181 +#define SROM11_MCSBW1605GLPO 182 +#define SROM11_MCSBW1605GLPO_1 183 +#define SROM11_MCSBW205GMPO 184 +#define SROM11_MCSBW205GMPO_1 185 +#define SROM11_MCSBW405GMPO 186 +#define SROM11_MCSBW405GMPO_1 187 +#define SROM11_MCSBW805GMPO 188 +#define SROM11_MCSBW805GMPO_1 189 +#define SROM11_MCSBW1605GMPO 190 +#define SROM11_MCSBW1605GMPO_1 191 +#define SROM11_MCSBW205GHPO 192 +#define SROM11_MCSBW205GHPO_1 193 +#define SROM11_MCSBW405GHPO 194 +#define SROM11_MCSBW405GHPO_1 195 +#define SROM11_MCSBW805GHPO 196 +#define SROM11_MCSBW805GHPO_1 197 +#define SROM11_MCSBW1605GHPO 198 +#define SROM11_MCSBW1605GHPO_1 199 + +#define SROM11_MCSLR5GLPO 200 +#define SROM11_MCSLR5GMPO 201 +#define SROM11_MCSLR5GHPO 202 + +#define SROM11_SB20IN40HRPO 203 +#define SROM11_SB20IN80AND160HR5GLPO 204 +#define SROM11_SB40AND80HR5GLPO 205 +#define SROM11_SB20IN80AND160HR5GMPO 206 +#define SROM11_SB40AND80HR5GMPO 207 +#define SROM11_SB20IN80AND160HR5GHPO 208 +#define SROM11_SB40AND80HR5GHPO 209 +#define SROM11_SB20IN40LRPO 210 +#define SROM11_SB20IN80AND160LR5GLPO 211 +#define SROM11_SB40AND80LR5GLPO 212 +#define SROM11_SB20IN80AND160LR5GMPO 213 +#define SROM11_SB40AND80LR5GMPO 214 +#define SROM11_SB20IN80AND160LR5GHPO 215 +#define SROM11_SB40AND80LR5GHPO 216 + +#define SROM11_DOT11AGDUPHRPO 217 +#define SROM11_DOT11AGDUPLRPO 218 + +/* MISC */ +#define SROM11_PCIEINGRESS_WAR 220 +#define SROM11_SAR 221 + +#define SROM11_NOISELVL_2G 222 +#define SROM11_NOISELVL_5GL 223 +#define SROM11_NOISELVL_5GM 224 +#define SROM11_NOISELVL_5GH 225 +#define SROM11_NOISELVL_5GU 226 + +#define SROM11_RXGAINERR_2G 227 +#define SROM11_RXGAINERR_5GL 228 +#define SROM11_RXGAINERR_5GM 229 +#define SROM11_RXGAINERR_5GH 230 +#define SROM11_RXGAINERR_5GU 231 + +#define SROM11_SIGN 64 +#define SROM11_CRCREV 233 + +#define SROM11_WORDS 234 +#define SROM11_SIGNATURE 0x0634 + +typedef struct { + uint8 tssipos; /* TSSI positive slope, 1: positive, 0: negative */ + uint8 extpagain; /* Ext PA gain-type: full-gain: 0, pa-lite: 1, no_pa: 2 */ + uint8 pdetrange; /* support 32 combinations of different Pdet dynamic ranges */ + uint8 triso; /* TR switch isolation */ + uint8 antswctrllut; /* antswctrl lookup table configuration: 32 possible choices */ +} srom_fem_t; + +#endif /* _bcmsrom_fmt_h_ */ diff --git a/drivers/net/wireless/bcmdhd/include/bcmsrom_tbl.h b/drivers/net/wireless/bcmdhd/include/bcmsrom_tbl.h new file mode 100644 index 00000000000..98ddb00cb78 --- /dev/null +++ b/drivers/net/wireless/bcmdhd/include/bcmsrom_tbl.h @@ -0,0 +1,837 @@ +/* + * Table that encodes the srom formats for PCI/PCIe NICs. + * + * Copyright (C) 1999-2012, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: bcmsrom_tbl.h 309193 2012-01-19 00:03:57Z $ + */ + +#ifndef _bcmsrom_tbl_h_ +#define _bcmsrom_tbl_h_ + +#include "sbpcmcia.h" +#include "wlioctl.h" + +typedef struct { + const char *name; + uint32 revmask; + uint32 flags; + uint16 off; + uint16 mask; +} sromvar_t; + +#define SRFL_MORE 1 /* value continues as described by the next entry */ +#define SRFL_NOFFS 2 /* value bits can't be all one's */ +#define SRFL_PRHEX 4 /* value is in hexdecimal format */ +#define SRFL_PRSIGN 8 /* value is in signed decimal format */ +#define SRFL_CCODE 0x10 /* value is in country code format */ +#define SRFL_ETHADDR 0x20 /* value is an Ethernet address */ +#define SRFL_LEDDC 0x40 /* value is an LED duty cycle */ +#define SRFL_NOVAR 0x80 /* do not generate a nvram param, entry is for mfgc */ +#define SRFL_ARRAY 0x100 /* value is in an array. All elements EXCEPT FOR THE LAST + * ONE in the array should have this flag set. + */ + + +/* Assumptions: + * - Ethernet address spans across 3 consective words + * + * Table rules: + * - Add multiple entries next to each other if a value spans across multiple words + * (even multiple fields in the same word) with each entry except the last having + * it's SRFL_MORE bit set. + * - Ethernet address entry does not follow above rule and must not have SRFL_MORE + * bit set. Its SRFL_ETHADDR bit implies it takes multiple words. + * - The last entry's name field must be NULL to indicate the end of the table. Other + * entries must have non-NULL name. + */ + +static const sromvar_t pci_sromvars[] = { + {"devid", 0xffffff00, SRFL_PRHEX|SRFL_NOVAR, PCI_F0DEVID, 0xffff}, + {"boardrev", 0x0000000e, SRFL_PRHEX, SROM_AABREV, SROM_BR_MASK}, + {"boardrev", 0x000000f0, SRFL_PRHEX, SROM4_BREV, 0xffff}, + {"boardrev", 0xffffff00, SRFL_PRHEX, SROM8_BREV, 0xffff}, + {"boardflags", 0x00000002, SRFL_PRHEX, SROM_BFL, 0xffff}, + {"boardflags", 0x00000004, SRFL_PRHEX|SRFL_MORE, SROM_BFL, 0xffff}, + {"", 0, 0, SROM_BFL2, 0xffff}, + {"boardflags", 0x00000008, SRFL_PRHEX|SRFL_MORE, SROM_BFL, 0xffff}, + {"", 0, 0, SROM3_BFL2, 0xffff}, + {"boardflags", 0x00000010, SRFL_PRHEX|SRFL_MORE, SROM4_BFL0, 0xffff}, + {"", 0, 0, SROM4_BFL1, 0xffff}, + {"boardflags", 0x000000e0, SRFL_PRHEX|SRFL_MORE, SROM5_BFL0, 0xffff}, + {"", 0, 0, SROM5_BFL1, 0xffff}, + {"boardflags", 0xffffff00, SRFL_PRHEX|SRFL_MORE, SROM8_BFL0, 0xffff}, + {"", 0, 0, SROM8_BFL1, 0xffff}, + {"boardflags2", 0x00000010, SRFL_PRHEX|SRFL_MORE, SROM4_BFL2, 0xffff}, + {"", 0, 0, SROM4_BFL3, 0xffff}, + {"boardflags2", 0x000000e0, SRFL_PRHEX|SRFL_MORE, SROM5_BFL2, 0xffff}, + {"", 0, 0, SROM5_BFL3, 0xffff}, + {"boardflags2", 0xffffff00, SRFL_PRHEX|SRFL_MORE, SROM8_BFL2, 0xffff}, + {"", 0, 0, SROM8_BFL3, 0xffff}, + {"boardtype", 0xfffffffc, SRFL_PRHEX, SROM_SSID, 0xffff}, + + {"boardnum", 0x00000006, 0, SROM_MACLO_IL0, 0xffff}, + {"boardnum", 0x00000008, 0, SROM3_MACLO, 0xffff}, + {"boardnum", 0x00000010, 0, SROM4_MACLO, 0xffff}, + {"boardnum", 0x000000e0, 0, SROM5_MACLO, 0xffff}, + {"boardnum", 0x00000700, 0, SROM8_MACLO, 0xffff}, + {"cc", 0x00000002, 0, SROM_AABREV, SROM_CC_MASK}, + {"regrev", 0x00000008, 0, SROM_OPO, 0xff00}, + {"regrev", 0x00000010, 0, SROM4_REGREV, 0x00ff}, + {"regrev", 0x000000e0, 0, SROM5_REGREV, 0x00ff}, + {"regrev", 0x00000700, 0, SROM8_REGREV, 0x00ff}, + {"ledbh0", 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0x00ff}, + {"ledbh1", 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0xff00}, + {"ledbh2", 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0x00ff}, + {"ledbh3", 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0xff00}, + {"ledbh0", 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0x00ff}, + {"ledbh1", 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0xff00}, + {"ledbh2", 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0x00ff}, + {"ledbh3", 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0xff00}, + {"ledbh0", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0x00ff}, + {"ledbh1", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0xff00}, + {"ledbh2", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0x00ff}, + {"ledbh3", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0xff00}, + {"ledbh0", 0x00000700, SRFL_NOFFS, SROM8_LEDBH10, 0x00ff}, + {"ledbh1", 0x00000700, SRFL_NOFFS, SROM8_LEDBH10, 0xff00}, + {"ledbh2", 0x00000700, SRFL_NOFFS, SROM8_LEDBH32, 0x00ff}, + {"ledbh3", 0x00000700, SRFL_NOFFS, SROM8_LEDBH32, 0xff00}, + {"pa0b0", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB0, 0xffff}, + {"pa0b1", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB1, 0xffff}, + {"pa0b2", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB2, 0xffff}, + {"pa0itssit", 0x0000000e, 0, SROM_ITT, 0x00ff}, + {"pa0maxpwr", 0x0000000e, 0, SROM_WL10MAXP, 0x00ff}, + {"pa0b0", 0x00000700, SRFL_PRHEX, SROM8_W0_PAB0, 0xffff}, + {"pa0b1", 0x00000700, SRFL_PRHEX, SROM8_W0_PAB1, 0xffff}, + {"pa0b2", 0x00000700, SRFL_PRHEX, SROM8_W0_PAB2, 0xffff}, + {"pa0itssit", 0x00000700, 0, SROM8_W0_ITTMAXP, 0xff00}, + {"pa0maxpwr", 0x00000700, 0, SROM8_W0_ITTMAXP, 0x00ff}, + {"opo", 0x0000000c, 0, SROM_OPO, 0x00ff}, + {"opo", 0x00000700, 0, SROM8_2G_OFDMPO, 0x00ff}, + {"aa2g", 0x0000000e, 0, SROM_AABREV, SROM_AA0_MASK}, + {"aa2g", 0x000000f0, 0, SROM4_AA, 0x00ff}, + {"aa2g", 0x00000700, 0, SROM8_AA, 0x00ff}, + {"aa5g", 0x0000000e, 0, SROM_AABREV, SROM_AA1_MASK}, + {"aa5g", 0x000000f0, 0, SROM4_AA, 0xff00}, + {"aa5g", 0x00000700, 0, SROM8_AA, 0xff00}, + {"ag0", 0x0000000e, 0, SROM_AG10, 0x00ff}, + {"ag1", 0x0000000e, 0, SROM_AG10, 0xff00}, + {"ag0", 0x000000f0, 0, SROM4_AG10, 0x00ff}, + {"ag1", 0x000000f0, 0, SROM4_AG10, 0xff00}, + {"ag2", 0x000000f0, 0, SROM4_AG32, 0x00ff}, + {"ag3", 0x000000f0, 0, SROM4_AG32, 0xff00}, + {"ag0", 0x00000700, 0, SROM8_AG10, 0x00ff}, + {"ag1", 0x00000700, 0, SROM8_AG10, 0xff00}, + {"ag2", 0x00000700, 0, SROM8_AG32, 0x00ff}, + {"ag3", 0x00000700, 0, SROM8_AG32, 0xff00}, + {"pa1b0", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB0, 0xffff}, + {"pa1b1", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB1, 0xffff}, + {"pa1b2", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB2, 0xffff}, + {"pa1lob0", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB0, 0xffff}, + {"pa1lob1", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB1, 0xffff}, + {"pa1lob2", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB2, 0xffff}, + {"pa1hib0", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB0, 0xffff}, + {"pa1hib1", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB1, 0xffff}, + {"pa1hib2", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB2, 0xffff}, + {"pa1itssit", 0x0000000e, 0, SROM_ITT, 0xff00}, + {"pa1maxpwr", 0x0000000e, 0, SROM_WL10MAXP, 0xff00}, + {"pa1lomaxpwr", 0x0000000c, 0, SROM_WL1LHMAXP, 0xff00}, + {"pa1himaxpwr", 0x0000000c, 0, SROM_WL1LHMAXP, 0x00ff}, + {"pa1b0", 0x00000700, SRFL_PRHEX, SROM8_W1_PAB0, 0xffff}, + {"pa1b1", 0x00000700, SRFL_PRHEX, SROM8_W1_PAB1, 0xffff}, + {"pa1b2", 0x00000700, SRFL_PRHEX, SROM8_W1_PAB2, 0xffff}, + {"pa1lob0", 0x00000700, SRFL_PRHEX, SROM8_W1_PAB0_LC, 0xffff}, + {"pa1lob1", 0x00000700, SRFL_PRHEX, SROM8_W1_PAB1_LC, 0xffff}, + {"pa1lob2", 0x00000700, SRFL_PRHEX, SROM8_W1_PAB2_LC, 0xffff}, + {"pa1hib0", 0x00000700, SRFL_PRHEX, SROM8_W1_PAB0_HC, 0xffff}, + {"pa1hib1", 0x00000700, SRFL_PRHEX, SROM8_W1_PAB1_HC, 0xffff}, + {"pa1hib2", 0x00000700, SRFL_PRHEX, SROM8_W1_PAB2_HC, 0xffff}, + {"pa1itssit", 0x00000700, 0, SROM8_W1_ITTMAXP, 0xff00}, + {"pa1maxpwr", 0x00000700, 0, SROM8_W1_ITTMAXP, 0x00ff}, + {"pa1lomaxpwr", 0x00000700, 0, SROM8_W1_MAXP_LCHC, 0xff00}, + {"pa1himaxpwr", 0x00000700, 0, SROM8_W1_MAXP_LCHC, 0x00ff}, + {"bxa2g", 0x00000008, 0, SROM_BXARSSI2G, 0x1800}, + {"rssisav2g", 0x00000008, 0, SROM_BXARSSI2G, 0x0700}, + {"rssismc2g", 0x00000008, 0, SROM_BXARSSI2G, 0x00f0}, + {"rssismf2g", 0x00000008, 0, SROM_BXARSSI2G, 0x000f}, + {"bxa2g", 0x00000700, 0, SROM8_BXARSSI2G, 0x1800}, + {"rssisav2g", 0x00000700, 0, SROM8_BXARSSI2G, 0x0700}, + {"rssismc2g", 0x00000700, 0, SROM8_BXARSSI2G, 0x00f0}, + {"rssismf2g", 0x00000700, 0, SROM8_BXARSSI2G, 0x000f}, + {"bxa5g", 0x00000008, 0, SROM_BXARSSI5G, 0x1800}, + {"rssisav5g", 0x00000008, 0, SROM_BXARSSI5G, 0x0700}, + {"rssismc5g", 0x00000008, 0, SROM_BXARSSI5G, 0x00f0}, + {"rssismf5g", 0x00000008, 0, SROM_BXARSSI5G, 0x000f}, + {"bxa5g", 0x00000700, 0, SROM8_BXARSSI5G, 0x1800}, + {"rssisav5g", 0x00000700, 0, SROM8_BXARSSI5G, 0x0700}, + {"rssismc5g", 0x00000700, 0, SROM8_BXARSSI5G, 0x00f0}, + {"rssismf5g", 0x00000700, 0, SROM8_BXARSSI5G, 0x000f}, + {"tri2g", 0x00000008, 0, SROM_TRI52G, 0x00ff}, + {"tri5g", 0x00000008, 0, SROM_TRI52G, 0xff00}, + {"tri5gl", 0x00000008, 0, SROM_TRI5GHL, 0x00ff}, + {"tri5gh", 0x00000008, 0, SROM_TRI5GHL, 0xff00}, + {"tri2g", 0x00000700, 0, SROM8_TRI52G, 0x00ff}, + {"tri5g", 0x00000700, 0, SROM8_TRI52G, 0xff00}, + {"tri5gl", 0x00000700, 0, SROM8_TRI5GHL, 0x00ff}, + {"tri5gh", 0x00000700, 0, SROM8_TRI5GHL, 0xff00}, + {"rxpo2g", 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0x00ff}, + {"rxpo5g", 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0xff00}, + {"rxpo2g", 0x00000700, SRFL_PRSIGN, SROM8_RXPO52G, 0x00ff}, + {"rxpo5g", 0x00000700, SRFL_PRSIGN, SROM8_RXPO52G, 0xff00}, + {"txchain", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_TXCHAIN_MASK}, + {"rxchain", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_RXCHAIN_MASK}, + {"antswitch", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_SWITCH_MASK}, + {"txchain", 0x00000700, SRFL_NOFFS, SROM8_TXRXC, SROM4_TXCHAIN_MASK}, + {"rxchain", 0x00000700, SRFL_NOFFS, SROM8_TXRXC, SROM4_RXCHAIN_MASK}, + {"antswitch", 0x00000700, SRFL_NOFFS, SROM8_TXRXC, SROM4_SWITCH_MASK}, + {"tssipos2g", 0x00000700, 0, SROM8_FEM2G, SROM8_FEM_TSSIPOS_MASK}, + {"extpagain2g", 0x00000700, 0, SROM8_FEM2G, SROM8_FEM_EXTPA_GAIN_MASK}, + {"pdetrange2g", 0x00000700, 0, SROM8_FEM2G, SROM8_FEM_PDET_RANGE_MASK}, + {"triso2g", 0x00000700, 0, SROM8_FEM2G, SROM8_FEM_TR_ISO_MASK}, + {"antswctl2g", 0x00000700, 0, SROM8_FEM2G, SROM8_FEM_ANTSWLUT_MASK}, + {"tssipos5g", 0x00000700, 0, SROM8_FEM5G, SROM8_FEM_TSSIPOS_MASK}, + {"extpagain5g", 0x00000700, 0, SROM8_FEM5G, SROM8_FEM_EXTPA_GAIN_MASK}, + {"pdetrange5g", 0x00000700, 0, SROM8_FEM5G, SROM8_FEM_PDET_RANGE_MASK}, + {"triso5g", 0x00000700, 0, SROM8_FEM5G, SROM8_FEM_TR_ISO_MASK}, + {"antswctl5g", 0x00000700, 0, SROM8_FEM5G, SROM8_FEM_ANTSWLUT_MASK}, + {"txpid2ga0", 0x000000f0, 0, SROM4_TXPID2G, 0x00ff}, + {"txpid2ga1", 0x000000f0, 0, SROM4_TXPID2G, 0xff00}, + {"txpid2ga2", 0x000000f0, 0, SROM4_TXPID2G + 1, 0x00ff}, + {"txpid2ga3", 0x000000f0, 0, SROM4_TXPID2G + 1, 0xff00}, + {"txpid5ga0", 0x000000f0, 0, SROM4_TXPID5G, 0x00ff}, + {"txpid5ga1", 0x000000f0, 0, SROM4_TXPID5G, 0xff00}, + {"txpid5ga2", 0x000000f0, 0, SROM4_TXPID5G + 1, 0x00ff}, + {"txpid5ga3", 0x000000f0, 0, SROM4_TXPID5G + 1, 0xff00}, + {"txpid5gla0", 0x000000f0, 0, SROM4_TXPID5GL, 0x00ff}, + {"txpid5gla1", 0x000000f0, 0, SROM4_TXPID5GL, 0xff00}, + {"txpid5gla2", 0x000000f0, 0, SROM4_TXPID5GL + 1, 0x00ff}, + {"txpid5gla3", 0x000000f0, 0, SROM4_TXPID5GL + 1, 0xff00}, + {"txpid5gha0", 0x000000f0, 0, SROM4_TXPID5GH, 0x00ff}, + {"txpid5gha1", 0x000000f0, 0, SROM4_TXPID5GH, 0xff00}, + {"txpid5gha2", 0x000000f0, 0, SROM4_TXPID5GH + 1, 0x00ff}, + {"txpid5gha3", 0x000000f0, 0, SROM4_TXPID5GH + 1, 0xff00}, + + {"ccode", 0x0000000f, SRFL_CCODE, SROM_CCODE, 0xffff}, + {"ccode", 0x00000010, SRFL_CCODE, SROM4_CCODE, 0xffff}, + {"ccode", 0x000000e0, SRFL_CCODE, SROM5_CCODE, 0xffff}, + {"ccode", 0x00000700, SRFL_CCODE, SROM8_CCODE, 0xffff}, + {"macaddr", 0x00000700, SRFL_ETHADDR, SROM8_MACHI, 0xffff}, + {"macaddr", 0x000000e0, SRFL_ETHADDR, SROM5_MACHI, 0xffff}, + {"macaddr", 0x00000010, SRFL_ETHADDR, SROM4_MACHI, 0xffff}, + {"macaddr", 0x00000008, SRFL_ETHADDR, SROM3_MACHI, 0xffff}, + {"il0macaddr", 0x00000007, SRFL_ETHADDR, SROM_MACHI_IL0, 0xffff}, + {"et1macaddr", 0x00000007, SRFL_ETHADDR, SROM_MACHI_ET1, 0xffff}, + {"leddc", 0x00000700, SRFL_NOFFS|SRFL_LEDDC, SROM8_LEDDC, 0xffff}, + {"leddc", 0x000000e0, SRFL_NOFFS|SRFL_LEDDC, SROM5_LEDDC, 0xffff}, + {"leddc", 0x00000010, SRFL_NOFFS|SRFL_LEDDC, SROM4_LEDDC, 0xffff}, + {"leddc", 0x00000008, SRFL_NOFFS|SRFL_LEDDC, SROM3_LEDDC, 0xffff}, + + {"tempthresh", 0x00000700, 0, SROM8_THERMAL, 0xff00}, + {"tempoffset", 0x00000700, 0, SROM8_THERMAL, 0x00ff}, + {"rawtempsense", 0x00000700, SRFL_PRHEX, SROM8_MPWR_RAWTS, 0x01ff}, + {"measpower", 0x00000700, SRFL_PRHEX, SROM8_MPWR_RAWTS, 0xfe00}, + {"tempsense_slope", 0x00000700, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX, 0x00ff}, + {"tempcorrx", 0x00000700, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX, 0xfc00}, + {"tempsense_option", 0x00000700, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX, 0x0300}, + {"freqoffset_corr", 0x00000700, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP, 0x000f}, + {"iqcal_swp_dis", 0x00000700, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP, 0x0010}, + {"hw_iqcal_en", 0x00000700, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP, 0x0020}, + {"elna2g", 0x00000700, 0, SROM8_EXTLNAGAIN, 0x00ff}, + {"elna5g", 0x00000700, 0, SROM8_EXTLNAGAIN, 0xff00}, + {"phycal_tempdelta", 0x00000700, 0, SROM8_PHYCAL_TEMPDELTA, 0x00ff}, + {"temps_period", 0x00000700, 0, SROM8_PHYCAL_TEMPDELTA, 0x0f00}, + {"temps_hysteresis", 0x00000700, 0, SROM8_PHYCAL_TEMPDELTA, 0xf000}, + {"measpower1", 0x00000700, SRFL_PRHEX, SROM8_MPWR_1_AND_2, 0x007f}, + {"measpower2", 0x00000700, SRFL_PRHEX, SROM8_MPWR_1_AND_2, 0x3f80}, + + {"cck2gpo", 0x000000f0, 0, SROM4_2G_CCKPO, 0xffff}, + {"cck2gpo", 0x00000100, 0, SROM8_2G_CCKPO, 0xffff}, + {"ofdm2gpo", 0x000000f0, SRFL_MORE, SROM4_2G_OFDMPO, 0xffff}, + {"", 0, 0, SROM4_2G_OFDMPO + 1, 0xffff}, + {"ofdm5gpo", 0x000000f0, SRFL_MORE, SROM4_5G_OFDMPO, 0xffff}, + {"", 0, 0, SROM4_5G_OFDMPO + 1, 0xffff}, + {"ofdm5glpo", 0x000000f0, SRFL_MORE, SROM4_5GL_OFDMPO, 0xffff}, + {"", 0, 0, SROM4_5GL_OFDMPO + 1, 0xffff}, + {"ofdm5ghpo", 0x000000f0, SRFL_MORE, SROM4_5GH_OFDMPO, 0xffff}, + {"", 0, 0, SROM4_5GH_OFDMPO + 1, 0xffff}, + {"ofdm2gpo", 0x00000100, SRFL_MORE, SROM8_2G_OFDMPO, 0xffff}, + {"", 0, 0, SROM8_2G_OFDMPO + 1, 0xffff}, + {"ofdm5gpo", 0x00000100, SRFL_MORE, SROM8_5G_OFDMPO, 0xffff}, + {"", 0, 0, SROM8_5G_OFDMPO + 1, 0xffff}, + {"ofdm5glpo", 0x00000100, SRFL_MORE, SROM8_5GL_OFDMPO, 0xffff}, + {"", 0, 0, SROM8_5GL_OFDMPO + 1, 0xffff}, + {"ofdm5ghpo", 0x00000100, SRFL_MORE, SROM8_5GH_OFDMPO, 0xffff}, + {"", 0, 0, SROM8_5GH_OFDMPO + 1, 0xffff}, + {"mcs2gpo0", 0x000000f0, 0, SROM4_2G_MCSPO, 0xffff}, + {"mcs2gpo1", 0x000000f0, 0, SROM4_2G_MCSPO + 1, 0xffff}, + {"mcs2gpo2", 0x000000f0, 0, SROM4_2G_MCSPO + 2, 0xffff}, + {"mcs2gpo3", 0x000000f0, 0, SROM4_2G_MCSPO + 3, 0xffff}, + {"mcs2gpo4", 0x000000f0, 0, SROM4_2G_MCSPO + 4, 0xffff}, + {"mcs2gpo5", 0x000000f0, 0, SROM4_2G_MCSPO + 5, 0xffff}, + {"mcs2gpo6", 0x000000f0, 0, SROM4_2G_MCSPO + 6, 0xffff}, + {"mcs2gpo7", 0x000000f0, 0, SROM4_2G_MCSPO + 7, 0xffff}, + {"mcs5gpo0", 0x000000f0, 0, SROM4_5G_MCSPO, 0xffff}, + {"mcs5gpo1", 0x000000f0, 0, SROM4_5G_MCSPO + 1, 0xffff}, + {"mcs5gpo2", 0x000000f0, 0, SROM4_5G_MCSPO + 2, 0xffff}, + {"mcs5gpo3", 0x000000f0, 0, SROM4_5G_MCSPO + 3, 0xffff}, + {"mcs5gpo4", 0x000000f0, 0, SROM4_5G_MCSPO + 4, 0xffff}, + {"mcs5gpo5", 0x000000f0, 0, SROM4_5G_MCSPO + 5, 0xffff}, + {"mcs5gpo6", 0x000000f0, 0, SROM4_5G_MCSPO + 6, 0xffff}, + {"mcs5gpo7", 0x000000f0, 0, SROM4_5G_MCSPO + 7, 0xffff}, + {"mcs5glpo0", 0x000000f0, 0, SROM4_5GL_MCSPO, 0xffff}, + {"mcs5glpo1", 0x000000f0, 0, SROM4_5GL_MCSPO + 1, 0xffff}, + {"mcs5glpo2", 0x000000f0, 0, SROM4_5GL_MCSPO + 2, 0xffff}, + {"mcs5glpo3", 0x000000f0, 0, SROM4_5GL_MCSPO + 3, 0xffff}, + {"mcs5glpo4", 0x000000f0, 0, SROM4_5GL_MCSPO + 4, 0xffff}, + {"mcs5glpo5", 0x000000f0, 0, SROM4_5GL_MCSPO + 5, 0xffff}, + {"mcs5glpo6", 0x000000f0, 0, SROM4_5GL_MCSPO + 6, 0xffff}, + {"mcs5glpo7", 0x000000f0, 0, SROM4_5GL_MCSPO + 7, 0xffff}, + {"mcs5ghpo0", 0x000000f0, 0, SROM4_5GH_MCSPO, 0xffff}, + {"mcs5ghpo1", 0x000000f0, 0, SROM4_5GH_MCSPO + 1, 0xffff}, + {"mcs5ghpo2", 0x000000f0, 0, SROM4_5GH_MCSPO + 2, 0xffff}, + {"mcs5ghpo3", 0x000000f0, 0, SROM4_5GH_MCSPO + 3, 0xffff}, + {"mcs5ghpo4", 0x000000f0, 0, SROM4_5GH_MCSPO + 4, 0xffff}, + {"mcs5ghpo5", 0x000000f0, 0, SROM4_5GH_MCSPO + 5, 0xffff}, + {"mcs5ghpo6", 0x000000f0, 0, SROM4_5GH_MCSPO + 6, 0xffff}, + {"mcs5ghpo7", 0x000000f0, 0, SROM4_5GH_MCSPO + 7, 0xffff}, + {"mcs2gpo0", 0x00000100, 0, SROM8_2G_MCSPO, 0xffff}, + {"mcs2gpo1", 0x00000100, 0, SROM8_2G_MCSPO + 1, 0xffff}, + {"mcs2gpo2", 0x00000100, 0, SROM8_2G_MCSPO + 2, 0xffff}, + {"mcs2gpo3", 0x00000100, 0, SROM8_2G_MCSPO + 3, 0xffff}, + {"mcs2gpo4", 0x00000100, 0, SROM8_2G_MCSPO + 4, 0xffff}, + {"mcs2gpo5", 0x00000100, 0, SROM8_2G_MCSPO + 5, 0xffff}, + {"mcs2gpo6", 0x00000100, 0, SROM8_2G_MCSPO + 6, 0xffff}, + {"mcs2gpo7", 0x00000100, 0, SROM8_2G_MCSPO + 7, 0xffff}, + {"mcs5gpo0", 0x00000100, 0, SROM8_5G_MCSPO, 0xffff}, + {"mcs5gpo1", 0x00000100, 0, SROM8_5G_MCSPO + 1, 0xffff}, + {"mcs5gpo2", 0x00000100, 0, SROM8_5G_MCSPO + 2, 0xffff}, + {"mcs5gpo3", 0x00000100, 0, SROM8_5G_MCSPO + 3, 0xffff}, + {"mcs5gpo4", 0x00000100, 0, SROM8_5G_MCSPO + 4, 0xffff}, + {"mcs5gpo5", 0x00000100, 0, SROM8_5G_MCSPO + 5, 0xffff}, + {"mcs5gpo6", 0x00000100, 0, SROM8_5G_MCSPO + 6, 0xffff}, + {"mcs5gpo7", 0x00000100, 0, SROM8_5G_MCSPO + 7, 0xffff}, + {"mcs5glpo0", 0x00000100, 0, SROM8_5GL_MCSPO, 0xffff}, + {"mcs5glpo1", 0x00000100, 0, SROM8_5GL_MCSPO + 1, 0xffff}, + {"mcs5glpo2", 0x00000100, 0, SROM8_5GL_MCSPO + 2, 0xffff}, + {"mcs5glpo3", 0x00000100, 0, SROM8_5GL_MCSPO + 3, 0xffff}, + {"mcs5glpo4", 0x00000100, 0, SROM8_5GL_MCSPO + 4, 0xffff}, + {"mcs5glpo5", 0x00000100, 0, SROM8_5GL_MCSPO + 5, 0xffff}, + {"mcs5glpo6", 0x00000100, 0, SROM8_5GL_MCSPO + 6, 0xffff}, + {"mcs5glpo7", 0x00000100, 0, SROM8_5GL_MCSPO + 7, 0xffff}, + {"mcs5ghpo0", 0x00000100, 0, SROM8_5GH_MCSPO, 0xffff}, + {"mcs5ghpo1", 0x00000100, 0, SROM8_5GH_MCSPO + 1, 0xffff}, + {"mcs5ghpo2", 0x00000100, 0, SROM8_5GH_MCSPO + 2, 0xffff}, + {"mcs5ghpo3", 0x00000100, 0, SROM8_5GH_MCSPO + 3, 0xffff}, + {"mcs5ghpo4", 0x00000100, 0, SROM8_5GH_MCSPO + 4, 0xffff}, + {"mcs5ghpo5", 0x00000100, 0, SROM8_5GH_MCSPO + 5, 0xffff}, + {"mcs5ghpo6", 0x00000100, 0, SROM8_5GH_MCSPO + 6, 0xffff}, + {"mcs5ghpo7", 0x00000100, 0, SROM8_5GH_MCSPO + 7, 0xffff}, + {"cddpo", 0x000000f0, 0, SROM4_CDDPO, 0xffff}, + {"stbcpo", 0x000000f0, 0, SROM4_STBCPO, 0xffff}, + {"bw40po", 0x000000f0, 0, SROM4_BW40PO, 0xffff}, + {"bwduppo", 0x000000f0, 0, SROM4_BWDUPPO, 0xffff}, + {"cddpo", 0x00000100, 0, SROM8_CDDPO, 0xffff}, + {"stbcpo", 0x00000100, 0, SROM8_STBCPO, 0xffff}, + {"bw40po", 0x00000100, 0, SROM8_BW40PO, 0xffff}, + {"bwduppo", 0x00000100, 0, SROM8_BWDUPPO, 0xffff}, + + /* power per rate from sromrev 9 */ + {"cckbw202gpo", 0x00000600, 0, SROM9_2GPO_CCKBW20, 0xffff}, + {"cckbw20ul2gpo", 0x00000600, 0, SROM9_2GPO_CCKBW20UL, 0xffff}, + {"legofdmbw202gpo", 0x00000600, SRFL_MORE, SROM9_2GPO_LOFDMBW20, 0xffff}, + {"", 0, 0, SROM9_2GPO_LOFDMBW20 + 1, 0xffff}, + {"legofdmbw20ul2gpo", 0x00000600, SRFL_MORE, SROM9_2GPO_LOFDMBW20UL, 0xffff}, + {"", 0, 0, SROM9_2GPO_LOFDMBW20UL + 1, 0xffff}, + {"legofdmbw205glpo", 0x00000600, SRFL_MORE, SROM9_5GLPO_LOFDMBW20, 0xffff}, + {"", 0, 0, SROM9_5GLPO_LOFDMBW20 + 1, 0xffff}, + {"legofdmbw20ul5glpo", 0x00000600, SRFL_MORE, SROM9_5GLPO_LOFDMBW20UL, 0xffff}, + {"", 0, 0, SROM9_5GLPO_LOFDMBW20UL + 1, 0xffff}, + {"legofdmbw205gmpo", 0x00000600, SRFL_MORE, SROM9_5GMPO_LOFDMBW20, 0xffff}, + {"", 0, 0, SROM9_5GMPO_LOFDMBW20 + 1, 0xffff}, + {"legofdmbw20ul5gmpo", 0x00000600, SRFL_MORE, SROM9_5GMPO_LOFDMBW20UL, 0xffff}, + {"", 0, 0, SROM9_5GMPO_LOFDMBW20UL + 1, 0xffff}, + {"legofdmbw205ghpo", 0x00000600, SRFL_MORE, SROM9_5GHPO_LOFDMBW20, 0xffff}, + {"", 0, 0, SROM9_5GHPO_LOFDMBW20 + 1, 0xffff}, + {"legofdmbw20ul5ghpo", 0x00000600, SRFL_MORE, SROM9_5GHPO_LOFDMBW20UL, 0xffff}, + {"", 0, 0, SROM9_5GHPO_LOFDMBW20UL + 1, 0xffff}, + {"mcsbw202gpo", 0x00000600, SRFL_MORE, SROM9_2GPO_MCSBW20, 0xffff}, + {"", 0, 0, SROM9_2GPO_MCSBW20 + 1, 0xffff}, + {"mcsbw20ul2gpo", 0x00000600, SRFL_MORE, SROM9_2GPO_MCSBW20UL, 0xffff}, + {"", 0, 0, SROM9_2GPO_MCSBW20UL + 1, 0xffff}, + {"mcsbw402gpo", 0x00000600, SRFL_MORE, SROM9_2GPO_MCSBW40, 0xffff}, + {"", 0, 0, SROM9_2GPO_MCSBW40 + 1, 0xffff}, + {"mcsbw205glpo", 0x00000600, SRFL_MORE, SROM9_5GLPO_MCSBW20, 0xffff}, + {"", 0, 0, SROM9_5GLPO_MCSBW20 + 1, 0xffff}, + {"mcsbw20ul5glpo", 0x00000600, SRFL_MORE, SROM9_5GLPO_MCSBW20UL, 0xffff}, + {"", 0, 0, SROM9_5GLPO_MCSBW20UL + 1, 0xffff}, + {"mcsbw405glpo", 0x00000600, SRFL_MORE, SROM9_5GLPO_MCSBW40, 0xffff}, + {"", 0, 0, SROM9_5GLPO_MCSBW40 + 1, 0xffff}, + {"mcsbw205gmpo", 0x00000600, SRFL_MORE, SROM9_5GMPO_MCSBW20, 0xffff}, + {"", 0, 0, SROM9_5GMPO_MCSBW20 + 1, 0xffff}, + {"mcsbw20ul5gmpo", 0x00000600, SRFL_MORE, SROM9_5GMPO_MCSBW20UL, 0xffff}, + {"", 0, 0, SROM9_5GMPO_MCSBW20UL + 1, 0xffff}, + {"mcsbw405gmpo", 0x00000600, SRFL_MORE, SROM9_5GMPO_MCSBW40, 0xffff}, + {"", 0, 0, SROM9_5GMPO_MCSBW40 + 1, 0xffff}, + {"mcsbw205ghpo", 0x00000600, SRFL_MORE, SROM9_5GHPO_MCSBW20, 0xffff}, + {"", 0, 0, SROM9_5GHPO_MCSBW20 + 1, 0xffff}, + {"mcsbw20ul5ghpo", 0x00000600, SRFL_MORE, SROM9_5GHPO_MCSBW20UL, 0xffff}, + {"", 0, 0, SROM9_5GHPO_MCSBW20UL + 1, 0xffff}, + {"mcsbw405ghpo", 0x00000600, SRFL_MORE, SROM9_5GHPO_MCSBW40, 0xffff}, + {"", 0, 0, SROM9_5GHPO_MCSBW40 + 1, 0xffff}, + {"mcs32po", 0x00000600, 0, SROM9_PO_MCS32, 0xffff}, + {"legofdm40duppo", 0x00000600, 0, SROM9_PO_LOFDM40DUP, 0xffff}, + {"pcieingress_war", 0x00000700, 0, SROM8_PCIEINGRESS_WAR, 0xf}, + {"rxgainerr2ga0", 0x00000700, 0, SROM8_RXGAINERR_2G, 0x003f}, + {"rxgainerr2ga1", 0x00000700, 0, SROM8_RXGAINERR_2G, 0x07c0}, + {"rxgainerr2ga2", 0x00000700, 0, SROM8_RXGAINERR_2G, 0xf800}, + {"rxgainerr5gla0", 0x00000700, 0, SROM8_RXGAINERR_5GL, 0x003f}, + {"rxgainerr5gla1", 0x00000700, 0, SROM8_RXGAINERR_5GL, 0x07c0}, + {"rxgainerr5gla2", 0x00000700, 0, SROM8_RXGAINERR_5GL, 0xf800}, + {"rxgainerr5gma0", 0x00000700, 0, SROM8_RXGAINERR_5GM, 0x003f}, + {"rxgainerr5gma1", 0x00000700, 0, SROM8_RXGAINERR_5GM, 0x07c0}, + {"rxgainerr5gma2", 0x00000700, 0, SROM8_RXGAINERR_5GM, 0xf800}, + {"rxgainerr5gha0", 0x00000700, 0, SROM8_RXGAINERR_5GH, 0x003f}, + {"rxgainerr5gha1", 0x00000700, 0, SROM8_RXGAINERR_5GH, 0x07c0}, + {"rxgainerr5gha2", 0x00000700, 0, SROM8_RXGAINERR_5GH, 0xf800}, + {"rxgainerr5gua0", 0x00000700, 0, SROM8_RXGAINERR_5GU, 0x003f}, + {"rxgainerr5gua1", 0x00000700, 0, SROM8_RXGAINERR_5GU, 0x07c0}, + {"rxgainerr5gua2", 0x00000700, 0, SROM8_RXGAINERR_5GU, 0xf800}, + {"sar2g", 0x00000600, 0, SROM9_SAR, 0x00ff}, + {"sar5g", 0x00000600, 0, SROM9_SAR, 0xff00}, + {"noiselvl2ga0", 0x00000700, 0, SROM8_NOISELVL_2G, 0x001f}, + {"noiselvl2ga1", 0x00000700, 0, SROM8_NOISELVL_2G, 0x03e0}, + {"noiselvl2ga2", 0x00000700, 0, SROM8_NOISELVL_2G, 0x7c00}, + {"noiselvl5gla0", 0x00000700, 0, SROM8_NOISELVL_5GL, 0x001f}, + {"noiselvl5gla1", 0x00000700, 0, SROM8_NOISELVL_5GL, 0x03e0}, + {"noiselvl5gla2", 0x00000700, 0, SROM8_NOISELVL_5GL, 0x7c00}, + {"noiselvl5gma0", 0x00000700, 0, SROM8_NOISELVL_5GM, 0x001f}, + {"noiselvl5gma1", 0x00000700, 0, SROM8_NOISELVL_5GM, 0x03e0}, + {"noiselvl5gma2", 0x00000700, 0, SROM8_NOISELVL_5GM, 0x7c00}, + {"noiselvl5gha0", 0x00000700, 0, SROM8_NOISELVL_5GH, 0x001f}, + {"noiselvl5gha1", 0x00000700, 0, SROM8_NOISELVL_5GH, 0x03e0}, + {"noiselvl5gha2", 0x00000700, 0, SROM8_NOISELVL_5GH, 0x7c00}, + {"noiselvl5gua0", 0x00000700, 0, SROM8_NOISELVL_5GU, 0x001f}, + {"noiselvl5gua1", 0x00000700, 0, SROM8_NOISELVL_5GU, 0x03e0}, + {"noiselvl5gua2", 0x00000700, 0, SROM8_NOISELVL_5GU, 0x7c00}, + {"subband5gver", 0x00000700, 0, SROM8_SUBBAND_PPR, 0x7}, + + {"cckPwrOffset", 0x00000400, 0, SROM10_CCKPWROFFSET, 0xffff}, + /* swctrlmap_2g array, note that the last element doesn't have SRFL_ARRAY flag set */ + {"swctrlmap_2g", 0x00000400, SRFL_MORE|SRFL_PRHEX|SRFL_ARRAY, SROM10_SWCTRLMAP_2G, 0xffff}, + {"", 0x00000400, SRFL_ARRAY, SROM10_SWCTRLMAP_2G + 1, 0xffff}, + {"", 0x00000400, SRFL_MORE|SRFL_PRHEX|SRFL_ARRAY, SROM10_SWCTRLMAP_2G + 2, 0xffff}, + {"", 0x00000400, SRFL_ARRAY, SROM10_SWCTRLMAP_2G + 3, 0xffff}, + {"", 0x00000400, SRFL_MORE|SRFL_PRHEX|SRFL_ARRAY, SROM10_SWCTRLMAP_2G + 4, 0xffff}, + {"", 0x00000400, SRFL_ARRAY, SROM10_SWCTRLMAP_2G + 5, 0xffff}, + {"", 0x00000400, SRFL_MORE|SRFL_PRHEX|SRFL_ARRAY, SROM10_SWCTRLMAP_2G + 6, 0xffff}, + {"", 0x00000400, SRFL_ARRAY, SROM10_SWCTRLMAP_2G + 7, 0xffff}, + {"", 0x00000400, SRFL_PRHEX, SROM10_SWCTRLMAP_2G + 8, 0xffff}, + + /* sromrev 11 */ + {"boardflags3", 0xfffff800, SRFL_PRHEX|SRFL_MORE, SROM11_BFL3, 0xffff}, + {"", 0, 0, SROM11_BFL3, 0xffff}, + {"boardnum", 0xfffff800, 0, SROM11_MACLO, 0xffff}, + {"macaddr", 0xfffff800, SRFL_ETHADDR, SROM11_MACHI, 0xffff}, + {"ccode", 0xfffff800, SRFL_CCODE, SROM11_CCODE, 0xffff}, + {"regrev", 0xfffff800, 0, SROM11_REGREV, 0x00ff}, + {"ledbh0", 0xfffff800, SRFL_NOFFS, SROM11_LEDBH10, 0x00ff}, + {"ledbh1", 0xfffff800, SRFL_NOFFS, SROM11_LEDBH10, 0xff00}, + {"ledbh2", 0xfffff800, SRFL_NOFFS, SROM11_LEDBH32, 0x00ff}, + {"ledbh3", 0xfffff800, SRFL_NOFFS, SROM11_LEDBH32, 0xff00}, + {"leddc", 0xfffff800, SRFL_NOFFS|SRFL_LEDDC, SROM11_LEDDC, 0xffff}, + {"aa2g", 0xfffff800, 0, SROM11_AA, 0x00ff}, + {"aa5g", 0xfffff800, 0, SROM11_AA, 0xff00}, + {"agbg0", 0xfffff800, 0, SROM11_AGBG10, 0x00ff}, + {"agbg1", 0xfffff800, 0, SROM11_AGBG10, 0xff00}, + {"agbg2", 0xfffff800, 0, SROM11_AGBG2A0, 0x00ff}, + {"aga0", 0xfffff800, 0, SROM11_AGBG2A0, 0xff00}, + {"aga1", 0xfffff800, 0, SROM11_AGA21, 0x00ff}, + {"aga2", 0xfffff800, 0, SROM11_AGA21, 0xff00}, + {"txchain", 0xfffff800, SRFL_NOFFS, SROM11_TXRXC, SROM4_TXCHAIN_MASK}, + {"rxchain", 0xfffff800, SRFL_NOFFS, SROM11_TXRXC, SROM4_RXCHAIN_MASK}, + {"antswitch", 0xfffff800, SRFL_NOFFS, SROM11_TXRXC, SROM4_SWITCH_MASK}, + + {"tssiposslope2g", 0xfffff800, 0, SROM11_FEM_CFG1, 0x0001}, + {"epagain2g", 0xfffff800, 0, SROM11_FEM_CFG1, 0x000e}, + {"pdgain2g", 0xfffff800, 0, SROM11_FEM_CFG1, 0x01f0}, + {"tworangetssi2g", 0xfffff800, 0, SROM11_FEM_CFG1, 0x0200}, + {"papdcap2g", 0xfffff800, 0, SROM11_FEM_CFG1, 0x0400}, + {"femctrl", 0xfffff800, 0, SROM11_FEM_CFG1, 0xf800}, + + {"tssiposslope5g", 0xfffff800, 0, SROM11_FEM_CFG2, 0x0001}, + {"epagain5g", 0xfffff800, 0, SROM11_FEM_CFG2, 0x000e}, + {"pdgain5g", 0xfffff800, 0, SROM11_FEM_CFG2, 0x01f0}, + {"tworangetssi5g", 0xfffff800, 0, SROM11_FEM_CFG2, 0x0200}, + {"papdcap5g", 0xfffff800, 0, SROM11_FEM_CFG2, 0x0400}, + {"gainctrlsph", 0xfffff800, 0, SROM11_FEM_CFG2, 0xf800}, + + {"tempthresh", 0xfffff800, 0, SROM11_THERMAL, 0xff00}, + {"tempoffset", 0xfffff800, 0, SROM11_THERMAL, 0x00ff}, + {"rawtempsense", 0xfffff800, SRFL_PRHEX, SROM11_MPWR_RAWTS, 0x01ff}, + {"measpower", 0xfffff800, SRFL_PRHEX, SROM11_MPWR_RAWTS, 0xfe00}, + {"tempsense_slope", 0xfffff800, SRFL_PRHEX, SROM11_TS_SLP_OPT_CORRX, 0x00ff}, + {"tempcorrx", 0xfffff800, SRFL_PRHEX, SROM11_TS_SLP_OPT_CORRX, 0xfc00}, + {"tempsense_option", 0xfffff800, SRFL_PRHEX, SROM11_TS_SLP_OPT_CORRX, 0x0300}, + {"phycal_tempdelta", 0xfffff800, 0, SROM11_PHYCAL_TEMPDELTA, 0x00ff}, + {"temps_period", 0xfffff800, 0, SROM11_PHYCAL_TEMPDELTA, 0x0f00}, + {"temps_hysteresis", 0xfffff800, 0, SROM11_PHYCAL_TEMPDELTA, 0xf000}, + {"measpower1", 0xfffff800, SRFL_PRHEX, SROM11_MPWR_1_AND_2, 0x007f}, + {"measpower2", 0xfffff800, SRFL_PRHEX, SROM11_MPWR_1_AND_2, 0x3f80}, + + {"subband5gver", 0xfffff800, SRFL_PRHEX, SROM11_SUBBAND5GVER, 0xffff}, + + /* power per rate */ + {"cckbw202gpo", 0xfffff800, 0, SROM11_CCKBW202GPO, 0xffff}, + {"cckbw20ul2gpo", 0xfffff800, 0, SROM11_CCKBW20UL2GPO, 0xffff}, + {"mcsbw202gpo", 0xfffff800, SRFL_MORE, SROM11_MCSBW202GPO, 0xffff}, + {"", 0xfffff800, 0, SROM11_MCSBW202GPO_1, 0xffff}, + {"mcsbw402gpo", 0xfffff800, SRFL_MORE, SROM11_MCSBW402GPO, 0xffff}, + {"", 0xfffff800, 0, SROM11_MCSBW402GPO_1, 0xffff}, + {"dot11agofdmhrbw202gpo", 0xfffff800, 0, SROM11_DOT11AGOFDMHRBW202GPO, 0xffff}, + {"ofdmlrbw202gpo", 0xfffff800, 0, SROM11_OFDMLRBW202GPO, 0xffff}, + {"mcsbw205glpo", 0xfffff800, SRFL_MORE, SROM11_MCSBW205GLPO, 0xffff}, + {"", 0xfffff800, 0, SROM11_MCSBW205GLPO_1, 0xffff}, + {"mcsbw405glpo", 0xfffff800, SRFL_MORE, SROM11_MCSBW405GLPO, 0xffff}, + {"", 0xfffff800, 0, SROM11_MCSBW405GLPO_1, 0xffff}, + {"mcsbw805glpo", 0xfffff800, SRFL_MORE, SROM11_MCSBW805GLPO, 0xffff}, + {"", 0xfffff800, 0, SROM11_MCSBW805GLPO_1, 0xffff}, + {"mcsbw1605glpo", 0xfffff800, SRFL_MORE, SROM11_MCSBW1605GLPO, 0xffff}, + {"", 0xfffff800, 0, SROM11_MCSBW1605GLPO_1, 0xffff}, + {"mcsbw205gmpo", 0xfffff800, SRFL_MORE, SROM11_MCSBW205GMPO, 0xffff}, + {"", 0xfffff800, 0, SROM11_MCSBW205GMPO_1, 0xffff}, + {"mcsbw405gmpo", 0xfffff800, SRFL_MORE, SROM11_MCSBW405GMPO, 0xffff}, + {"", 0xfffff800, 0, SROM11_MCSBW405GMPO_1, 0xffff}, + {"mcsbw805gmpo", 0xfffff800, SRFL_MORE, SROM11_MCSBW805GMPO, 0xffff}, + {"", 0xfffff800, 0, SROM11_MCSBW805GMPO_1, 0xffff}, + {"mcsbw1605gmpo", 0xfffff800, SRFL_MORE, SROM11_MCSBW1605GMPO, 0xffff}, + {"", 0xfffff800, 0, SROM11_MCSBW1605GMPO_1, 0xffff}, + {"mcsbw205ghpo", 0xfffff800, SRFL_MORE, SROM11_MCSBW205GHPO, 0xffff}, + {"", 0xfffff800, 0, SROM11_MCSBW205GHPO_1, 0xffff}, + {"mcsbw405ghpo", 0xfffff800, SRFL_MORE, SROM11_MCSBW405GHPO, 0xffff}, + {"", 0xfffff800, 0, SROM11_MCSBW405GHPO_1, 0xffff}, + {"mcsbw805ghpo", 0xfffff800, SRFL_MORE, SROM11_MCSBW805GHPO, 0xffff}, + {"", 0xfffff800, 0, SROM11_MCSBW805GHPO_1, 0xffff}, + {"mcsbw1605ghpo", 0xfffff800, SRFL_MORE, SROM11_MCSBW1605GHPO, 0xffff}, + {"", 0xfffff800, 0, SROM11_MCSBW1605GHPO_1, 0xffff}, + {"mcslr5glpo", 0xfffff800, 0, SROM11_MCSLR5GLPO, 0xffff}, + {"mcslr5gmpo", 0xfffff800, 0, SROM11_MCSLR5GMPO, 0xffff}, + {"mcslr5ghpo", 0xfffff800, 0, SROM11_MCSLR5GHPO, 0xffff}, + {"sb20in40hrrpo", 0xfffff800, 0, SROM11_SB20IN40HRPO, 0xffff}, + {"sb20in80and160hr5glpo", 0xfffff800, 0, SROM11_SB20IN80AND160HR5GLPO, 0xffff}, + {"sb40and80hr5glpo", 0xfffff800, 0, SROM11_SB40AND80HR5GLPO, 0xffff}, + {"sb20in80and160hr5gmpo", 0xfffff800, 0, SROM11_SB20IN80AND160HR5GMPO, 0xffff}, + {"sb40and80hr5gmpo", 0xfffff800, 0, SROM11_SB40AND80HR5GMPO, 0xffff}, + {"sb20in80and160hr5ghpo", 0xfffff800, 0, SROM11_SB20IN80AND160HR5GHPO, 0xffff}, + {"sb40and80hr5ghpo", 0xfffff800, 0, SROM11_SB40AND80HR5GHPO, 0xffff}, + {"sb20in40lrpo", 0xfffff800, 0, SROM11_SB20IN40LRPO, 0xffff}, + {"sb20in80and160lr5glpo", 0xfffff800, 0, SROM11_SB20IN80AND160LR5GLPO, 0xffff}, + {"sb40and80lr5glpo", 0xfffff800, 0, SROM11_SB40AND80LR5GLPO, 0xffff}, + {"sb20in80and160lr5gmpo", 0xfffff800, 0, SROM11_SB20IN80AND160LR5GMPO, 0xffff}, + {"sb40and80lr5gmpo", 0xfffff800, 0, SROM11_SB40AND80LR5GMPO, 0xffff}, + {"sb20in80and160lr5ghpo", 0xfffff800, 0, SROM11_SB20IN80AND160LR5GHPO, 0xffff}, + {"sb40and80lr5ghpo", 0xfffff800, 0, SROM11_SB40AND80LR5GHPO, 0xffff}, + {"dot11agduphrpo", 0xfffff800, 0, SROM11_DOT11AGDUPHRPO, 0xffff}, + {"dot11agduplrpo", 0xfffff800, 0, SROM11_DOT11AGDUPLRPO, 0xffff}, + + /* Misc */ + {"pcieingress_war", 0xfffff800, 0, SROM11_PCIEINGRESS_WAR, 0xf}, + {"sar2g", 0xfffff800, 0, SROM11_SAR, 0x00ff}, + {"sar5g", 0xfffff800, 0, SROM11_SAR, 0xff00}, + {"noiselvl2ga0", 0xfffff800, 0, SROM11_NOISELVL_2G, 0x001f}, + {"noiselvl2ga1", 0xfffff800, 0, SROM11_NOISELVL_2G, 0x03e0}, + {"noiselvl2ga2", 0xfffff800, 0, SROM11_NOISELVL_2G, 0x7c00}, + {"noiselvl5gla0", 0xfffff800, 0, SROM11_NOISELVL_5GL, 0x001f}, + {"noiselvl5gla1", 0xfffff800, 0, SROM11_NOISELVL_5GL, 0x03e0}, + {"noiselvl5gla2", 0xfffff800, 0, SROM11_NOISELVL_5GL, 0x7c00}, + {"noiselvl5gma0", 0xfffff800, 0, SROM11_NOISELVL_5GM, 0x001f}, + {"noiselvl5gma1", 0xfffff800, 0, SROM11_NOISELVL_5GM, 0x03e0}, + {"noiselvl5gma2", 0xfffff800, 0, SROM11_NOISELVL_5GM, 0x7c00}, + {"noiselvl5gha0", 0xfffff800, 0, SROM11_NOISELVL_5GH, 0x001f}, + {"noiselvl5gha1", 0xfffff800, 0, SROM11_NOISELVL_5GH, 0x03e0}, + {"noiselvl5gha2", 0xfffff800, 0, SROM11_NOISELVL_5GH, 0x7c00}, + {"noiselvl5gua0", 0xfffff800, 0, SROM11_NOISELVL_5GU, 0x001f}, + {"noiselvl5gua1", 0xfffff800, 0, SROM11_NOISELVL_5GU, 0x03e0}, + {"noiselvl5gua2", 0xfffff800, 0, SROM11_NOISELVL_5GU, 0x7c00}, + {"rxgainerr2g", 0xfffff800, SRFL_PRHEX, SROM11_RXGAINERR_2G, 0xffff}, + {"rxgainerr5g", 0xfffff800, SRFL_PRHEX|SRFL_ARRAY, SROM11_RXGAINERR_5GL, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX|SRFL_ARRAY, SROM11_RXGAINERR_5GM, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX|SRFL_ARRAY, SROM11_RXGAINERR_5GH, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX, SROM11_RXGAINERR_5GU, 0xffff}, + {NULL, 0, 0, 0, 0} +}; + +static const sromvar_t perpath_pci_sromvars[] = { + {"maxp2ga", 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0x00ff}, + {"itt2ga", 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0xff00}, + {"itt5ga", 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0xff00}, + {"pa2gw0a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA, 0xffff}, + {"pa2gw1a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 1, 0xffff}, + {"pa2gw2a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 2, 0xffff}, + {"pa2gw3a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 3, 0xffff}, + {"maxp5ga", 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0x00ff}, + {"maxp5gha", 0x000000f0, 0, SROM4_5GLH_MAXP, 0x00ff}, + {"maxp5gla", 0x000000f0, 0, SROM4_5GLH_MAXP, 0xff00}, + {"pa5gw0a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA, 0xffff}, + {"pa5gw1a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 1, 0xffff}, + {"pa5gw2a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 2, 0xffff}, + {"pa5gw3a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 3, 0xffff}, + {"pa5glw0a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA, 0xffff}, + {"pa5glw1a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 1, 0xffff}, + {"pa5glw2a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 2, 0xffff}, + {"pa5glw3a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 3, 0xffff}, + {"pa5ghw0a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA, 0xffff}, + {"pa5ghw1a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 1, 0xffff}, + {"pa5ghw2a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 2, 0xffff}, + {"pa5ghw3a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 3, 0xffff}, + {"maxp2ga", 0x00000700, 0, SROM8_2G_ITT_MAXP, 0x00ff}, + {"itt2ga", 0x00000700, 0, SROM8_2G_ITT_MAXP, 0xff00}, + {"itt5ga", 0x00000700, 0, SROM8_5G_ITT_MAXP, 0xff00}, + {"pa2gw0a", 0x00000700, SRFL_PRHEX, SROM8_2G_PA, 0xffff}, + {"pa2gw1a", 0x00000700, SRFL_PRHEX, SROM8_2G_PA + 1, 0xffff}, + {"pa2gw2a", 0x00000700, SRFL_PRHEX, SROM8_2G_PA + 2, 0xffff}, + {"maxp5ga", 0x00000700, 0, SROM8_5G_ITT_MAXP, 0x00ff}, + {"maxp5gha", 0x00000700, 0, SROM8_5GLH_MAXP, 0x00ff}, + {"maxp5gla", 0x00000700, 0, SROM8_5GLH_MAXP, 0xff00}, + {"pa5gw0a", 0x00000700, SRFL_PRHEX, SROM8_5G_PA, 0xffff}, + {"pa5gw1a", 0x00000700, SRFL_PRHEX, SROM8_5G_PA + 1, 0xffff}, + {"pa5gw2a", 0x00000700, SRFL_PRHEX, SROM8_5G_PA + 2, 0xffff}, + {"pa5glw0a", 0x00000700, SRFL_PRHEX, SROM8_5GL_PA, 0xffff}, + {"pa5glw1a", 0x00000700, SRFL_PRHEX, SROM8_5GL_PA + 1, 0xffff}, + {"pa5glw2a", 0x00000700, SRFL_PRHEX, SROM8_5GL_PA + 2, 0xffff}, + {"pa5ghw0a", 0x00000700, SRFL_PRHEX, SROM8_5GH_PA, 0xffff}, + {"pa5ghw1a", 0x00000700, SRFL_PRHEX, SROM8_5GH_PA + 1, 0xffff}, + {"pa5ghw2a", 0x00000700, SRFL_PRHEX, SROM8_5GH_PA + 2, 0xffff}, + + /* sromrev 11 */ + {"maxp2ga", 0xfffff800, 0, SROM11_2G_MAXP, 0x00ff}, + {"pa2ga", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_2G_PA, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_2G_PA + 1, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX, SROM11_2G_PA + 2, 0xffff}, + {"rxgains2gelnagaina", 0xfffff800, 0, SROM11_RXGAINS, 0x0007}, + {"rxgains2gtrisoa", 0xfffff800, 0, SROM11_RXGAINS, 0x0078}, + {"rxgains2gtrelnabypa", 0xfffff800, 0, SROM11_RXGAINS, 0x0080}, + {"rxgains5gelnagaina", 0xfffff800, 0, SROM11_RXGAINS, 0x0700}, + {"rxgains5gtrisoa", 0xfffff800, 0, SROM11_RXGAINS, 0x7800}, + {"rxgains5gtrelnabypa", 0xfffff800, 0, SROM11_RXGAINS, 0x8000}, + {"maxp5ga", 0xfffff800, SRFL_ARRAY, SROM11_5GB1B0_MAXP, 0x00ff}, + {"", 0xfffff800, SRFL_ARRAY, SROM11_5GB1B0_MAXP, 0xff00}, + {"", 0xfffff800, SRFL_ARRAY, SROM11_5GB3B2_MAXP, 0x00ff}, + {"", 0xfffff800, 0, SROM11_5GB3B2_MAXP, 0xff00}, + {"pa5ga", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_5GB0_PA, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_5GB0_PA + 1, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_5GB0_PA + 2, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_5GB1_PA, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_5GB1_PA + 1, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_5GB1_PA + 2, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_5GB2_PA, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_5GB2_PA + 1, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_5GB2_PA + 2, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_5GB3_PA, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX | SRFL_ARRAY, SROM11_5GB3_PA + 1, 0xffff}, + {"", 0xfffff800, SRFL_PRHEX, SROM11_5GB3_PA + 2, 0xffff}, + + {NULL, 0, 0, 0, 0} +}; + +#if !(defined(PHY_TYPE_HT) && defined(PHY_TYPE_N) && defined(PHY_TYPE_LP)) +#define PHY_TYPE_HT 7 /* HT-Phy value */ +#define PHY_TYPE_N 4 /* N-Phy value */ +#define PHY_TYPE_LP 5 /* LP-Phy value */ +#endif /* !(defined(PHY_TYPE_HT) && defined(PHY_TYPE_N) && defined(PHY_TYPE_LP)) */ +#if !defined(PHY_TYPE_AC) +#define PHY_TYPE_AC 11 /* AC-Phy value */ +#endif /* !defined(PHY_TYPE_AC) */ +#if !defined(PHY_TYPE_NULL) +#define PHY_TYPE_NULL 0xf /* Invalid Phy value */ +#endif /* !defined(PHY_TYPE_NULL) */ + +typedef struct { + uint16 phy_type; + uint16 bandrange; + uint16 chain; + const char *vars; +} pavars_t; + +static const pavars_t pavars[] = { + /* HTPHY */ + {PHY_TYPE_HT, WL_CHAN_FREQ_RANGE_2G, 0, "pa2gw0a0 pa2gw1a0 pa2gw2a0"}, + {PHY_TYPE_HT, WL_CHAN_FREQ_RANGE_2G, 1, "pa2gw0a1 pa2gw1a1 pa2gw2a1"}, + {PHY_TYPE_HT, WL_CHAN_FREQ_RANGE_2G, 2, "pa2gw0a2 pa2gw1a2 pa2gw2a2"}, + {PHY_TYPE_HT, WL_CHAN_FREQ_RANGE_5G_BAND0, 0, "pa5glw0a0 pa5glw1a0 pa5glw2a0"}, + {PHY_TYPE_HT, WL_CHAN_FREQ_RANGE_5G_BAND0, 1, "pa5glw0a1 pa5glw1a1 pa5glw2a1"}, + {PHY_TYPE_HT, WL_CHAN_FREQ_RANGE_5G_BAND0, 2, "pa5glw0a2 pa5glw1a2 pa5glw2a2"}, + {PHY_TYPE_HT, WL_CHAN_FREQ_RANGE_5G_BAND1, 0, "pa5gw0a0 pa5gw1a0 pa5gw2a0"}, + {PHY_TYPE_HT, WL_CHAN_FREQ_RANGE_5G_BAND1, 1, "pa5gw0a1 pa5gw1a1 pa5gw2a1"}, + {PHY_TYPE_HT, WL_CHAN_FREQ_RANGE_5G_BAND1, 2, "pa5gw0a2 pa5gw1a2 pa5gw2a2"}, + {PHY_TYPE_HT, WL_CHAN_FREQ_RANGE_5G_BAND2, 0, "pa5ghw0a0 pa5ghw1a0 pa5ghw2a0"}, + {PHY_TYPE_HT, WL_CHAN_FREQ_RANGE_5G_BAND2, 1, "pa5ghw0a1 pa5ghw1a1 pa5ghw2a1"}, + {PHY_TYPE_HT, WL_CHAN_FREQ_RANGE_5G_BAND2, 2, "pa5ghw0a2 pa5ghw1a2 pa5ghw2a2"}, + {PHY_TYPE_HT, WL_CHAN_FREQ_RANGE_5G_BAND3, 0, "pa5gw0a3 pa5gw1a3 pa5gw2a3"}, + {PHY_TYPE_HT, WL_CHAN_FREQ_RANGE_5G_BAND3, 1, "pa5glw0a3 pa5glw1a3 pa5glw2a3"}, + {PHY_TYPE_HT, WL_CHAN_FREQ_RANGE_5G_BAND3, 2, "pa5ghw0a3 pa5ghw1a3 pa5ghw2a3"}, + /* NPHY */ + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G, 0, "pa2gw0a0 pa2gw1a0 pa2gw2a0"}, + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G, 1, "pa2gw0a1 pa2gw1a1 pa2gw2a1"}, + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5G_BAND0, 0, "pa5glw0a0 pa5glw1a0 pa5glw2a0"}, + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5G_BAND0, 1, "pa5glw0a1 pa5glw1a1 pa5glw2a1"}, + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5G_BAND1, 0, "pa5gw0a0 pa5gw1a0 pa5gw2a0"}, + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5G_BAND1, 1, "pa5gw0a1 pa5gw1a1 pa5gw2a1"}, + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5G_BAND2, 0, "pa5ghw0a0 pa5ghw1a0 pa5ghw2a0"}, + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5G_BAND2, 1, "pa5ghw0a1 pa5ghw1a1 pa5ghw2a1"}, + /* LPPHY */ + {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_2G, 0, "pa0b0 pa0b1 pa0b2"}, + {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GL, 0, "pa1lob0 pa1lob1 pa1lob2"}, + {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GM, 0, "pa1b0 pa1b1 pa1b2"}, + {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GH, 0, "pa1hib0 pa1hib1 pa1hib2"}, + /* ACPHY */ + {PHY_TYPE_AC, WL_CHAN_FREQ_RANGE_2G, 0, "pa2ga0"}, + {PHY_TYPE_AC, WL_CHAN_FREQ_RANGE_2G, 1, "pa2ga1"}, + {PHY_TYPE_AC, WL_CHAN_FREQ_RANGE_2G, 2, "pa2ga2"}, + {PHY_TYPE_AC, WL_CHAN_FREQ_RANGE_5G_4BAND, 0, "pa5ga0"}, + {PHY_TYPE_AC, WL_CHAN_FREQ_RANGE_5G_4BAND, 1, "pa5ga1"}, + {PHY_TYPE_AC, WL_CHAN_FREQ_RANGE_5G_4BAND, 2, "pa5ga2"}, + {PHY_TYPE_NULL, 0, 0, ""} +}; + +typedef struct { + uint16 phy_type; + uint16 bandrange; + const char *vars; +} povars_t; + +static const povars_t povars[] = { + /* NPHY */ + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G, "mcs2gpo0 mcs2gpo1 mcs2gpo2 mcs2gpo3 " + "mcs2gpo4 mcs2gpo5 mcs2gpo6 mcs2gpo7"}, + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL, "mcs5glpo0 mcs5glpo1 mcs5glpo2 mcs5glpo3 " + "mcs5glpo4 mcs5glpo5 mcs5glpo6 mcs5glpo7"}, + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM, "mcs5gpo0 mcs5gpo1 mcs5gpo2 mcs5gpo3 " + "mcs5gpo4 mcs5gpo5 mcs5gpo6 mcs5gpo7"}, + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH, "mcs5ghpo0 mcs5ghpo1 mcs5ghpo2 mcs5ghpo3 " + "mcs5ghpo4 mcs5ghpo5 mcs5ghpo6 mcs5ghpo7"}, + {PHY_TYPE_NULL, 0, ""} +}; + +typedef struct { + uint8 tag; /* Broadcom subtag name */ + uint8 len; /* Length field of the tuple, note that it includes the + * subtag name (1 byte): 1 + tuple content length + */ + const char *params; +} cis_tuple_t; + +#define OTP_RAW (0xff - 1) /* Reserved tuple number for wrvar Raw input */ +#define OTP_VERS_1 (0xff - 2) /* CISTPL_VERS_1 */ +#define OTP_MANFID (0xff - 3) /* CISTPL_MANFID */ +#define OTP_RAW1 (0xff - 4) /* Like RAW, but comes first */ + +static const cis_tuple_t cis_hnbuvars[] = { + {OTP_RAW1, 0, ""}, /* special case */ + {OTP_VERS_1, 0, "smanf sproductname"}, /* special case (non BRCM tuple) */ + {OTP_MANFID, 4, "2manfid 2prodid"}, /* special case (non BRCM tuple) */ + /* Unified OTP: tupple to embed USB manfid inside SDIO CIS */ + {HNBU_UMANFID, 8, "8usbmanfid"}, + {HNBU_SROMREV, 2, "1sromrev"}, + /* NOTE: subdevid is also written to boardtype. + * Need to write HNBU_BOARDTYPE to change it if it is different. + */ + {HNBU_CHIPID, 11, "2vendid 2devid 2chiprev 2subvendid 2subdevid"}, + {HNBU_BOARDREV, 3, "2boardrev"}, + {HNBU_PAPARMS, 10, "2pa0b0 2pa0b1 2pa0b2 1pa0itssit 1pa0maxpwr 1opo"}, + {HNBU_AA, 3, "1aa2g 1aa5g"}, + {HNBU_AA, 3, "1aa0 1aa1"}, /* backward compatibility */ + {HNBU_AG, 5, "1ag0 1ag1 1ag2 1ag3"}, + {HNBU_BOARDFLAGS, 9, "4boardflags 4boardflags2"}, + {HNBU_LEDS, 5, "1ledbh0 1ledbh1 1ledbh2 1ledbh3"}, + {HNBU_CCODE, 4, "2ccode 1cctl"}, + {HNBU_CCKPO, 3, "2cckpo"}, + {HNBU_OFDMPO, 5, "4ofdmpo"}, + {HNBU_PAPARMS5G, 23, "2pa1b0 2pa1b1 2pa1b2 2pa1lob0 2pa1lob1 2pa1lob2 " + "2pa1hib0 2pa1hib1 2pa1hib2 1pa1itssit " + "1pa1maxpwr 1pa1lomaxpwr 1pa1himaxpwr"}, + {HNBU_RDLID, 3, "2rdlid"}, + {HNBU_RSSISMBXA2G, 3, "0rssismf2g 0rssismc2g 0rssisav2g 0bxa2g"}, /* special case */ + {HNBU_RSSISMBXA5G, 3, "0rssismf5g 0rssismc5g 0rssisav5g 0bxa5g"}, /* special case */ + {HNBU_XTALFREQ, 5, "4xtalfreq"}, + {HNBU_TRI2G, 2, "1tri2g"}, + {HNBU_TRI5G, 4, "1tri5gl 1tri5g 1tri5gh"}, + {HNBU_RXPO2G, 2, "1rxpo2g"}, + {HNBU_RXPO5G, 2, "1rxpo5g"}, + {HNBU_BOARDNUM, 3, "2boardnum"}, + {HNBU_MACADDR, 7, "6macaddr"}, /* special case */ + {HNBU_RDLSN, 3, "2rdlsn"}, + {HNBU_BOARDTYPE, 3, "2boardtype"}, + {HNBU_LEDDC, 3, "2leddc"}, + {HNBU_RDLRNDIS, 2, "1rdlndis"}, + {HNBU_CHAINSWITCH, 5, "1txchain 1rxchain 2antswitch"}, + {HNBU_REGREV, 2, "1regrev"}, + {HNBU_FEM, 5, "0antswctl2g 0triso2g 0pdetrange2g 0extpagain2g 0tssipos2g " + "0antswctl5g 0triso5g 0pdetrange5g 0extpagain5g 0tssipos5g" + }, /* special case */ + {HNBU_PAPARMS_C0, 31, "1maxp2ga0 1itt2ga0 2pa2gw0a0 2pa2gw1a0 " + "2pa2gw2a0 1maxp5ga0 1itt5ga0 1maxp5gha0 1maxp5gla0 2pa5gw0a0 " + "2pa5gw1a0 2pa5gw2a0 2pa5glw0a0 2pa5glw1a0 2pa5glw2a0 2pa5ghw0a0 " + "2pa5ghw1a0 2pa5ghw2a0"}, + {HNBU_PAPARMS_C1, 31, "1maxp2ga1 1itt2ga1 2pa2gw0a1 2pa2gw1a1 " + "2pa2gw2a1 1maxp5ga1 1itt5ga1 1maxp5gha1 1maxp5gla1 2pa5gw0a1 " + "2pa5gw1a1 2pa5gw2a1 2pa5glw0a1 2pa5glw1a1 2pa5glw2a1 2pa5ghw0a1 " + "2pa5ghw1a1 2pa5ghw2a1"}, + {HNBU_PO_CCKOFDM, 19, "2cck2gpo 4ofdm2gpo 4ofdm5gpo 4ofdm5glpo " + "4ofdm5ghpo"}, + {HNBU_PO_MCS2G, 17, "2mcs2gpo0 2mcs2gpo1 2mcs2gpo2 2mcs2gpo3 " + "2mcs2gpo4 2mcs2gpo5 2mcs2gpo6 2mcs2gpo7"}, + {HNBU_PO_MCS5GM, 17, "2mcs5gpo0 2mcs5gpo1 2mcs5gpo2 2mcs5gpo3 " + "2mcs5gpo4 2mcs5gpo5 2mcs5gpo6 2mcs5gpo7"}, + {HNBU_PO_MCS5GLH, 33, "2mcs5glpo0 2mcs5glpo1 2mcs5glpo2 2mcs5glpo3 " + "2mcs5glpo4 2mcs5glpo5 2mcs5glpo6 2mcs5glpo7 " + "2mcs5ghpo0 2mcs5ghpo1 2mcs5ghpo2 2mcs5ghpo3 " + "2mcs5ghpo4 2mcs5ghpo5 2mcs5ghpo6 2mcs5ghpo7"}, + {HNBU_CCKFILTTYPE, 2, "1cckdigfilttype"}, + {HNBU_PO_CDD, 3, "2cddpo"}, + {HNBU_PO_STBC, 3, "2stbcpo"}, + {HNBU_PO_40M, 3, "2bw40po"}, + {HNBU_PO_40MDUP, 3, "2bwduppo"}, + {HNBU_RDLRWU, 2, "1rdlrwu"}, + {HNBU_WPS, 3, "1wpsgpio 1wpsled"}, + {HNBU_USBFS, 2, "1usbfs"}, + {HNBU_ELNA2G, 2, "1elna2g"}, + {HNBU_ELNA5G, 2, "1elna5g"}, + {HNBU_CUSTOM1, 5, "4customvar1"}, + {OTP_RAW, 0, ""}, /* special case */ + {HNBU_OFDMPO5G, 13, "4ofdm5gpo 4ofdm5glpo 4ofdm5ghpo"}, + {HNBU_USBEPNUM, 3, "2usbepnum"}, + {HNBU_CCKBW202GPO, 5, "2cckbw202gpo 2cckbw20ul2gpo"}, + {HNBU_LEGOFDMBW202GPO, 9, "4legofdmbw202gpo 4legofdmbw20ul2gp"}, + {HNBU_LEGOFDMBW205GPO, 25, "4legofdmbw205glpo 4legofdmbw20ul5glpo 4legofdmbw205gmpo " + "4legofdmbw20ul5gmpo 4legofdmbw205ghpo 4legofdmbw20ul5ghpo"}, + {HNBU_MCS2GPO, 13, "4mcsbw202gpo 4mcsbw20ul2gpo 4mcsbw402gpo"}, + {HNBU_MCS5GLPO, 13, "4mcsbw205glpo 4mcsbw20ul5glpo 4mcsbw405glpo"}, + {HNBU_MCS5GMPO, 13, "4mcsbw205gmpo 4mcsbw20ul5gmpo 4mcsbw405gmpo"}, + {HNBU_MCS5GHPO, 13, "4mcsbw205ghpo 4mcsbw20ul5ghpo 4mcsbw405ghpo"}, + {HNBU_MCS32PO, 3, "2mcs32po"}, + {HNBU_LEG40DUPPO, 3, "2legofdm40duppo"}, + {HNBU_TEMPTHRESH, 3, "1tempthresh 1periodhyst"}, + {HNBU_UUID, 17, "16uuid"}, + {HNBU_WOWLGPIO, 2, "1wowl_gpio"}, + {0xFF, 0, ""} +}; + +#endif /* _bcmsrom_tbl_h_ */ diff --git a/drivers/net/wireless/bcmdhd/include/bcmutils.h b/drivers/net/wireless/bcmdhd/include/bcmutils.h index 6849c26da83..be3eba6230f 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmutils.h +++ b/drivers/net/wireless/bcmdhd/include/bcmutils.h @@ -1,9 +1,9 @@ /* * Misc useful os-independent macros and functions. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,10 +21,9 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: bcmutils.h 294991 2011-11-09 00:17:28Z $ + * $Id: bcmutils.h 309397 2012-01-19 15:36:59Z $ */ - #ifndef _bcmutils_h_ #define _bcmutils_h_ @@ -36,6 +35,10 @@ extern "C" { #endif +#ifdef PKTQ_LOG +#include +#endif + #define _BCM_U 0x01 #define _BCM_L 0x02 @@ -102,23 +105,45 @@ typedef struct pktq_prec { uint16 max; } pktq_prec_t; +#ifdef PKTQ_LOG +typedef struct { + uint32 requested; + uint32 stored; + uint32 saved; + uint32 selfsaved; + uint32 full_dropped; + uint32 dropped; + uint32 sacrificed; + uint32 busy; + uint32 retry; + uint32 ps_retry; + uint32 retry_drop; + uint32 max_avail; + uint32 max_used; + uint32 queue_capacity; +} pktq_counters_t; +#endif -struct pktq { - uint16 num_prec; - uint16 hi_prec; - uint16 max; +#define PKTQ_COMMON \ + uint16 num_prec; \ + uint16 hi_prec; \ + uint16 max; \ uint16 len; + + +struct pktq { + PKTQ_COMMON struct pktq_prec q[PKTQ_MAX_PREC]; +#ifdef PKTQ_LOG + pktq_counters_t _prec_cnt[PKTQ_MAX_PREC]; +#endif }; struct spktq { - uint16 num_prec; - uint16 hi_prec; - uint16 max; - uint16 len; + PKTQ_COMMON struct pktq_prec q[1]; }; @@ -142,7 +167,7 @@ typedef bool (*ifpkt_cb_t)(void*, int); #ifndef PKTPOOL_LEN_MAX #define PKTPOOL_LEN_MAX 40 -#endif +#endif #define PKTPOOL_CB_MAX 3 struct pktpool; @@ -193,6 +218,7 @@ typedef struct pktpool { uint8 cbcnt; uint8 ecbcnt; bool emptycb_disable; + pktpool_cbinfo_t *availcb_excl; pktpool_cbinfo_t cbs[PKTPOOL_CB_MAX]; pktpool_cbinfo_t ecbs[PKTPOOL_CB_MAX]; void *q[PKTPOOL_LEN_MAX + 1]; @@ -218,6 +244,8 @@ extern void* pktpool_get(pktpool_t *pktp); extern void pktpool_free(pktpool_t *pktp, void *p); extern int pktpool_add(pktpool_t *pktp, void *p); extern uint16 pktpool_avail(pktpool_t *pktp); +extern int pktpool_avail_notify_normal(osl_t *osh, pktpool_t *pktp); +extern int pktpool_avail_notify_exclusive(osl_t *osh, pktpool_t *pktp, pktpool_cb_t cb); extern int pktpool_avail_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg); extern int pktpool_empty_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg); extern int pktpool_setmaxlen(pktpool_t *pktp, uint16 maxlen); @@ -247,18 +275,20 @@ extern int ether_isnulladdr(const void *ea); -#define pktq_psetmax(pq, prec, _max) ((pq)->q[prec].max = (_max)) -#define pktq_plen(pq, prec) ((pq)->q[prec].len) -#define pktq_pavail(pq, prec) ((pq)->q[prec].max - (pq)->q[prec].len) -#define pktq_pfull(pq, prec) ((pq)->q[prec].len >= (pq)->q[prec].max) -#define pktq_pempty(pq, prec) ((pq)->q[prec].len == 0) +#define pktq_psetmax(pq, prec, _max) ((pq)->q[prec].max = (_max)) +#define pktq_pmax(pq, prec) ((pq)->q[prec].max) +#define pktq_plen(pq, prec) ((pq)->q[prec].len) +#define pktq_pavail(pq, prec) ((pq)->q[prec].max - (pq)->q[prec].len) +#define pktq_pfull(pq, prec) ((pq)->q[prec].len >= (pq)->q[prec].max) +#define pktq_pempty(pq, prec) ((pq)->q[prec].len == 0) -#define pktq_ppeek(pq, prec) ((pq)->q[prec].head) -#define pktq_ppeek_tail(pq, prec) ((pq)->q[prec].tail) +#define pktq_ppeek(pq, prec) ((pq)->q[prec].head) +#define pktq_ppeek_tail(pq, prec) ((pq)->q[prec].tail) extern void *pktq_penq(struct pktq *pq, int prec, void *p); extern void *pktq_penq_head(struct pktq *pq, int prec, void *p); extern void *pktq_pdeq(struct pktq *pq, int prec); +extern void *pktq_pdeq_prev(struct pktq *pq, int prec, void *prev_p); extern void *pktq_pdeq_tail(struct pktq *pq, int prec); extern void pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir, @@ -270,23 +300,26 @@ extern bool pktq_pdel(struct pktq *pq, void *p, int prec); extern int pktq_mlen(struct pktq *pq, uint prec_bmp); extern void *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); +extern void *pktq_mpeek(struct pktq *pq, uint prec_bmp, int *prec_out); -#define pktq_len(pq) ((int)(pq)->len) -#define pktq_max(pq) ((int)(pq)->max) -#define pktq_avail(pq) ((int)((pq)->max - (pq)->len)) -#define pktq_full(pq) ((pq)->len >= (pq)->max) -#define pktq_empty(pq) ((pq)->len == 0) +#define pktq_len(pq) ((int)(pq)->len) +#define pktq_max(pq) ((int)(pq)->max) +#define pktq_avail(pq) ((int)((pq)->max - (pq)->len)) +#define pktq_full(pq) ((pq)->len >= (pq)->max) +#define pktq_empty(pq) ((pq)->len == 0) -#define pktenq(pq, p) pktq_penq(((struct pktq *)pq), 0, (p)) -#define pktenq_head(pq, p) pktq_penq_head(((struct pktq *)pq), 0, (p)) -#define pktdeq(pq) pktq_pdeq(((struct pktq *)pq), 0) -#define pktdeq_tail(pq) pktq_pdeq_tail(((struct pktq *)pq), 0) -#define pktqinit(pq, len) pktq_init(((struct pktq *)pq), 1, len) +#define pktenq(pq, p) pktq_penq(((struct pktq *)(void *)pq), 0, (p)) +#define pktenq_head(pq, p) pktq_penq_head(((struct pktq *)(void *)pq), 0, (p)) +#define pktdeq(pq) pktq_pdeq(((struct pktq *)(void *)pq), 0) +#define pktdeq_tail(pq) pktq_pdeq_tail(((struct pktq *)(void *)pq), 0) +#define pktqinit(pq, len) pktq_init(((struct pktq *)(void *)pq), 1, len) extern void pktq_init(struct pktq *pq, int num_prec, int max_len); +extern void pktq_set_max_plen(struct pktq *pq, int prec, int max_len); + extern void *pktq_deq(struct pktq *pq, int *prec_out); extern void *pktq_deq_tail(struct pktq *pq, int *prec_out); @@ -301,18 +334,21 @@ extern uint pktfrombuf(osl_t *osh, void *p, uint offset, int len, uchar *buf); extern uint pkttotlen(osl_t *osh, void *p); extern void *pktlast(osl_t *osh, void *p); extern uint pktsegcnt(osl_t *osh, void *p); +extern uint pktsegcnt_war(osl_t *osh, void *p); +extern uint8 *pktoffset(osl_t *osh, void *p, uint offset); -extern uint pktsetprio(void *pkt, bool update_vtag); #define PKTPRIO_VDSCP 0x100 #define PKTPRIO_VLAN 0x200 #define PKTPRIO_UPD 0x400 #define PKTPRIO_DSCP 0x800 +extern uint pktsetprio(void *pkt, bool update_vtag); + -extern int bcm_atoi(char *s); -extern ulong bcm_strtoul(char *cp, char **endp, uint base); -extern char *bcmstrstr(char *haystack, char *needle); +extern int bcm_atoi(const char *s); +extern ulong bcm_strtoul(const char *cp, char **endp, uint base); +extern char *bcmstrstr(const char *haystack, const char *needle); extern char *bcmstrcat(char *dest, const char *src); extern char *bcmstrncat(char *dest, const char *src, uint size); extern ulong wchar2ascii(char *abuf, ushort *wbuf, ushort wbuflen, ulong abuflen); @@ -323,7 +359,7 @@ int bcmstrnicmp(const char* s1, const char* s2, int cnt); extern char *bcm_ether_ntoa(const struct ether_addr *ea, char *buf); -extern int bcm_ether_atoe(char *p, struct ether_addr *ea); +extern int bcm_ether_atoe(const char *p, struct ether_addr *ea); struct ipv4_addr; @@ -348,6 +384,7 @@ extern uint getgpiopin(char *vars, char *pin_name, uint def_pin); #define bcmtslog(tstamp, fmt, a1, a2) #define bcmprinttslogs() #define bcmprinttstamp(us) +#define bcmdumptslog(buf, size) extern char *bcm_nvram_vars(uint *length); extern int bcm_nvram_cache(void *sih); @@ -370,8 +407,8 @@ typedef struct bcm_iovar { #define IOV_SET 1 -#define IOV_GVAL(id) ((id)*2) -#define IOV_SVAL(id) (((id)*2)+IOV_SET) +#define IOV_GVAL(id) ((id) * 2) +#define IOV_SVAL(id) ((id) * 2 + IOV_SET) #define IOV_ISSET(actionid) ((actionid & IOV_SET) == IOV_SET) #define IOV_ID(actionid) (actionid >> 1) @@ -520,23 +557,25 @@ extern int bcm_format_ssid(char* buf, const uchar ssid[], uint ssid_len); } #ifndef ABS -#define ABS(a) (((a) < 0)?-(a):(a)) +#define ABS(a) (((a) < 0) ? -(a) : (a)) #endif #ifndef MIN -#define MIN(a, b) (((a) < (b))?(a):(b)) +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif #ifndef MAX -#define MAX(a, b) (((a) > (b))?(a):(b)) +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) #endif -#define CEIL(x, y) (((x) + ((y)-1)) / (y)) -#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y)) -#define ISALIGNED(a, x) (((uintptr)(a) & ((x)-1)) == 0) +#define CEIL(x, y) (((x) + ((y) - 1)) / (y)) +#define ROUNDUP(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) +#define ISALIGNED(a, x) (((uintptr)(a) & ((x) - 1)) == 0) #define ALIGN_ADDR(addr, boundary) (void *)(((uintptr)(addr) + (boundary) - 1) \ & ~((boundary) - 1)) -#define ISPOWEROF2(x) ((((x)-1)&(x)) == 0) +#define ALIGN_SIZE(size, boundary) (((size) + (boundary) - 1) \ + & ~((boundary) - 1)) +#define ISPOWEROF2(x) ((((x) - 1) & (x)) == 0) #define VALID_MASK(mask) !((mask) & ((mask) + 1)) #ifndef OFFSETOF @@ -550,7 +589,7 @@ extern int bcm_format_ssid(char* buf, const uchar ssid[], uint ssid_len); #endif #ifndef ARRAYSIZE -#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0])) +#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0])) #endif @@ -562,10 +601,10 @@ extern void *_bcmutils_dummy_fn; #ifndef NBBY #define NBBY 8 #endif -#define setbit(a, i) (((uint8 *)a)[(i)/NBBY] |= 1<<((i)%NBBY)) -#define clrbit(a, i) (((uint8 *)a)[(i)/NBBY] &= ~(1<<((i)%NBBY))) -#define isset(a, i) (((const uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) -#define isclr(a, i) ((((const uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0) +#define setbit(a, i) (((uint8 *)a)[(i) / NBBY] |= 1 << ((i) % NBBY)) +#define clrbit(a, i) (((uint8 *)a)[(i) / NBBY] &= ~(1 << ((i) % NBBY))) +#define isset(a, i) (((const uint8 *)a)[(i) / NBBY] & (1 << ((i) % NBBY))) +#define isclr(a, i) ((((const uint8 *)a)[(i) / NBBY] & (1 << ((i) % NBBY))) == 0) #endif #define NBITS(type) (sizeof(type) * 8) @@ -652,6 +691,7 @@ extern uint8 hndcrc8(uint8 *p, uint nbytes, uint8 crc); extern uint16 hndcrc16(uint8 *p, uint nbytes, uint16 crc); extern uint32 hndcrc32(uint8 *p, uint nbytes, uint32 crc); + #if defined(DHD_DEBUG) || defined(WLMSG_PRHDRS) || defined(WLMSG_PRPKT) || \ defined(WLMSG_ASSOC) extern int bcm_format_flags(const bcm_bit_desc_t *bd, uint32 flags, char* buf, int len); @@ -675,6 +715,7 @@ extern bcm_tlv_t *bcm_parse_ordered_tlvs(void *buf, int buflen, uint key); extern const char *bcmerrorstr(int bcmerror); +extern bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen, uint key); typedef uint32 mbool; @@ -684,10 +725,6 @@ typedef uint32 mbool; #define mboolmaskset(mb, mask, val) ((mb) = (((mb) & ~(mask)) | (val))) -extern uint16 bcm_qdbm_to_mw(uint8 qdbm); -extern uint8 bcm_mw_to_qdbm(uint16 mw); - - struct fielddesc { const char *nameandfmt; uint32 offset; @@ -695,21 +732,23 @@ struct fielddesc { }; extern void bcm_binit(struct bcmstrbuf *b, char *buf, uint size); -extern int bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...); +extern void bcm_bprhex(struct bcmstrbuf *b, const char *msg, bool newline, uint8 *buf, int len); + extern void bcm_inc_bytes(uchar *num, int num_bytes, uint8 amount); -extern int bcm_cmp_bytes(uchar *arg1, uchar *arg2, uint8 nbytes); -extern void bcm_print_bytes(char *name, const uchar *cdata, int len); +extern int bcm_cmp_bytes(const uchar *arg1, const uchar *arg2, uint8 nbytes); +extern void bcm_print_bytes(const char *name, const uchar *cdata, int len); typedef uint32 (*bcmutl_rdreg_rtn)(void *arg0, uint arg1, uint32 offset); extern uint bcmdumpfields(bcmutl_rdreg_rtn func_ptr, void *arg0, uint arg1, struct fielddesc *str, char *buf, uint32 bufsize); - -extern uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint len); extern uint bcm_bitcount(uint8 *bitmap, uint bytelength); +extern int bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...); -#define SSID_FMT_BUF_LEN ((4 * DOT11_MAX_SSID_LEN) + 1) +extern uint16 bcm_qdbm_to_mw(uint8 qdbm); +extern uint8 bcm_mw_to_qdbm(uint16 mw); +extern uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint len); unsigned int process_nvram_vars(char *varbuf, unsigned int len); diff --git a/drivers/net/wireless/bcmdhd/include/bcmwifi.h b/drivers/net/wireless/bcmdhd/include/bcmwifi.h index e5207e9c408..f3f593f49cc 100644 --- a/drivers/net/wireless/bcmdhd/include/bcmwifi.h +++ b/drivers/net/wireless/bcmdhd/include/bcmwifi.h @@ -3,9 +3,9 @@ * This header file housing the define and function prototype use by * both the wl driver, tools & Apps. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -23,10 +23,9 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: bcmwifi.h 277737 2011-08-16 17:54:59Z $ + * $Id: bcmwifi.h 309193 2012-01-19 00:03:57Z $ */ - #ifndef _bcmwifi_h_ #define _bcmwifi_h_ @@ -38,12 +37,20 @@ typedef uint16 chanspec_t; #define CH_UPPER_SB 0x01 #define CH_LOWER_SB 0x02 #define CH_EWA_VALID 0x04 +#define CH_80MHZ_APART 16 +#define CH_40MHZ_APART 8 #define CH_20MHZ_APART 4 #define CH_10MHZ_APART 2 #define CH_5MHZ_APART 1 #define CH_MAX_2G_CHANNEL 14 -#define WLC_MAX_2G_CHANNEL CH_MAX_2G_CHANNEL #define MAXCHANNEL 224 +#define CHSPEC_CTLOVLP(sp1, sp2, sep) ABS(wf_chspec_ctlchan(sp1) - wf_chspec_ctlchan(sp2)) < (sep) + + +#undef D11AC_IOTYPES +#define D11AC_IOTYPES + +#ifndef D11AC_IOTYPES #define WL_CHANSPEC_CHAN_MASK 0x00ff #define WL_CHANSPEC_CHAN_SHIFT 0 @@ -67,11 +74,6 @@ typedef uint16 chanspec_t; #define INVCHANSPEC 255 -#define WF_CHAN_FACTOR_2_4_G 4814 -#define WF_CHAN_FACTOR_5_G 10000 -#define WF_CHAN_FACTOR_4_G 8000 - - #define LOWER_20_SB(channel) (((channel) > CH_10MHZ_APART) ? ((channel) - CH_10MHZ_APART) : 0) #define UPPER_20_SB(channel) (((channel) < (MAXCHANNEL - CH_10MHZ_APART)) ? \ ((channel) + CH_10MHZ_APART) : 0) @@ -89,8 +91,8 @@ typedef uint16 chanspec_t; #define CHSPEC_BAND(chspec) ((chspec) & WL_CHANSPEC_BAND_MASK) -#define CHSPEC_CTL_SB(chspec) (chspec & WL_CHANSPEC_CTL_SB_MASK) -#define CHSPEC_BW(chspec) (chspec & WL_CHANSPEC_BW_MASK) +#define CHSPEC_CTL_SB(chspec) ((chspec) & WL_CHANSPEC_CTL_SB_MASK) +#define CHSPEC_BW(chspec) ((chspec) & WL_CHANSPEC_BW_MASK) #ifdef WL11N_20MHZONLY @@ -110,8 +112,6 @@ typedef uint16 chanspec_t; #endif -#define CHSPEC_IS20_UNCOND(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20) - #define CHSPEC_IS5G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G) #define CHSPEC_IS2G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_2G) #define CHSPEC_SB_NONE(chspec) (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_NONE) @@ -124,6 +124,180 @@ typedef uint16 chanspec_t; #define CHANSPEC_STR_LEN 8 +#else + +#define WL_CHANSPEC_CHAN_MASK 0x00ff +#define WL_CHANSPEC_CHAN_SHIFT 0 +#define WL_CHANSPEC_CHAN1_MASK 0x000f +#define WL_CHANSPEC_CHAN1_SHIFT 0 +#define WL_CHANSPEC_CHAN2_MASK 0x00f0 +#define WL_CHANSPEC_CHAN2_SHIFT 4 + +#define WL_CHANSPEC_CTL_SB_MASK 0x0700 +#define WL_CHANSPEC_CTL_SB_SHIFT 8 +#define WL_CHANSPEC_CTL_SB_LLL 0x0000 +#define WL_CHANSPEC_CTL_SB_LLU 0x0100 +#define WL_CHANSPEC_CTL_SB_LUL 0x0200 +#define WL_CHANSPEC_CTL_SB_LUU 0x0300 +#define WL_CHANSPEC_CTL_SB_ULL 0x0400 +#define WL_CHANSPEC_CTL_SB_ULU 0x0500 +#define WL_CHANSPEC_CTL_SB_UUL 0x0600 +#define WL_CHANSPEC_CTL_SB_UUU 0x0700 +#define WL_CHANSPEC_CTL_SB_LL WL_CHANSPEC_CTL_SB_LLL +#define WL_CHANSPEC_CTL_SB_LU WL_CHANSPEC_CTL_SB_LLU +#define WL_CHANSPEC_CTL_SB_UL WL_CHANSPEC_CTL_SB_LUL +#define WL_CHANSPEC_CTL_SB_UU WL_CHANSPEC_CTL_SB_LUU +#define WL_CHANSPEC_CTL_SB_L WL_CHANSPEC_CTL_SB_LLL +#define WL_CHANSPEC_CTL_SB_U WL_CHANSPEC_CTL_SB_LLU +#define WL_CHANSPEC_CTL_SB_LOWER WL_CHANSPEC_CTL_SB_LLL +#define WL_CHANSPEC_CTL_SB_UPPER WL_CHANSPEC_CTL_SB_LLU + +#define WL_CHANSPEC_BW_MASK 0x3800 +#define WL_CHANSPEC_BW_SHIFT 11 +#define WL_CHANSPEC_BW_5 0x0000 +#define WL_CHANSPEC_BW_10 0x0800 +#define WL_CHANSPEC_BW_20 0x1000 +#define WL_CHANSPEC_BW_40 0x1800 +#define WL_CHANSPEC_BW_80 0x2000 +#define WL_CHANSPEC_BW_160 0x2800 +#define WL_CHANSPEC_BW_8080 0x3000 + +#define WL_CHANSPEC_BAND_MASK 0xc000 +#define WL_CHANSPEC_BAND_SHIFT 14 +#define WL_CHANSPEC_BAND_2G 0x0000 +#define WL_CHANSPEC_BAND_3G 0x4000 +#define WL_CHANSPEC_BAND_4G 0x8000 +#define WL_CHANSPEC_BAND_5G 0xc000 +#define INVCHANSPEC 255 + + +#define LOWER_20_SB(channel) (((channel) > CH_10MHZ_APART) ? \ + ((channel) - CH_10MHZ_APART) : 0) +#define UPPER_20_SB(channel) (((channel) < (MAXCHANNEL - CH_10MHZ_APART)) ? \ + ((channel) + CH_10MHZ_APART) : 0) +#define LOWER_40_SB(channel) ((channel) - CH_20MHZ_APART) +#define UPPER_40_SB(channel) ((channel) + CH_20MHZ_APART) +#define CHSPEC_WLCBANDUNIT(chspec) (CHSPEC_IS5G(chspec) ? BAND_5G_INDEX : BAND_2G_INDEX) +#define CH20MHZ_CHSPEC(channel) (chanspec_t)((chanspec_t)(channel) | WL_CHANSPEC_BW_20 | \ + (((channel) <= CH_MAX_2G_CHANNEL) ? \ + WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G)) +#define NEXT_20MHZ_CHAN(channel) (((channel) < (MAXCHANNEL - CH_20MHZ_APART)) ? \ + ((channel) + CH_20MHZ_APART) : 0) +#define CH40MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \ + ((channel) | (ctlsb) | WL_CHANSPEC_BW_40 | \ + ((channel) <= CH_MAX_2G_CHANNEL ? WL_CHANSPEC_BAND_2G : \ + WL_CHANSPEC_BAND_5G)) +#define CH80MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \ + ((channel) | (ctlsb) | \ + WL_CHANSPEC_BW_80 | WL_CHANSPEC_BAND_5G) +#define CH160MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \ + ((channel) | (ctlsb) | \ + WL_CHANSPEC_BW_160 | WL_CHANSPEC_BAND_5G) + + +#define CHSPEC_CHANNEL(chspec) ((uint8)((chspec) & WL_CHANSPEC_CHAN_MASK)) +#define CHSPEC_CHAN1(chspec) ((chspec) & WL_CHANSPEC_CHAN1_MASK) +#define CHSPEC_CHAN2(chspec) ((chspec) & WL_CHANSPEC_CHAN2_MASK) +#define CHSPEC_BAND(chspec) ((chspec) & WL_CHANSPEC_BAND_MASK) +#define CHSPEC_CTL_SB(chspec) ((chspec) & WL_CHANSPEC_CTL_SB_MASK) +#define CHSPEC_BW(chspec) ((chspec) & WL_CHANSPEC_BW_MASK) + +#ifdef WL11N_20MHZONLY + +#define CHSPEC_IS10(chspec) 0 +#define CHSPEC_IS20(chspec) 1 +#ifndef CHSPEC_IS40 +#define CHSPEC_IS40(chspec) 0 +#endif +#ifndef CHSPEC_IS80 +#define CHSPEC_IS80(chspec) 0 +#endif +#ifndef CHSPEC_IS160 +#define CHSPEC_IS160(chspec) 0 +#endif +#ifndef CHSPEC_IS8080 +#define CHSPEC_IS8080(chspec) 0 +#endif + +#else + +#define CHSPEC_IS10(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_10) +#define CHSPEC_IS20(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20) +#ifndef CHSPEC_IS40 +#define CHSPEC_IS40(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40) +#endif +#ifndef CHSPEC_IS80 +#define CHSPEC_IS80(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_80) +#endif +#ifndef CHSPEC_IS160 +#define CHSPEC_IS160(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_160) +#endif +#ifndef CHSPEC_IS8080 +#define CHSPEC_IS8080(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_8080) +#endif + +#endif + +#define CHSPEC_IS5G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G) +#define CHSPEC_IS2G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_2G) +#define CHSPEC_SB_UPPER(chspec) \ + ((((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_UPPER) && \ + (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40)) +#define CHSPEC_SB_LOWER(chspec) \ + ((((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_LOWER) && \ + (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40)) +#define CHSPEC2WLC_BAND(chspec) (CHSPEC_IS5G(chspec) ? WLC_BAND_5G : WLC_BAND_2G) + + +#define CHANSPEC_STR_LEN 20 + + + +#define WL_LCHANSPEC_CHAN_MASK 0x00ff +#define WL_LCHANSPEC_CHAN_SHIFT 0 + +#define WL_LCHANSPEC_CTL_SB_MASK 0x0300 +#define WL_LCHANSPEC_CTL_SB_SHIFT 8 +#define WL_LCHANSPEC_CTL_SB_LOWER 0x0100 +#define WL_LCHANSPEC_CTL_SB_UPPER 0x0200 +#define WL_LCHANSPEC_CTL_SB_NONE 0x0300 + +#define WL_LCHANSPEC_BW_MASK 0x0C00 +#define WL_LCHANSPEC_BW_SHIFT 10 +#define WL_LCHANSPEC_BW_10 0x0400 +#define WL_LCHANSPEC_BW_20 0x0800 +#define WL_LCHANSPEC_BW_40 0x0C00 + +#define WL_LCHANSPEC_BAND_MASK 0xf000 +#define WL_LCHANSPEC_BAND_SHIFT 12 +#define WL_LCHANSPEC_BAND_5G 0x1000 +#define WL_LCHANSPEC_BAND_2G 0x2000 + +#define LCHSPEC_CHANNEL(chspec) ((uint8)((chspec) & WL_LCHANSPEC_CHAN_MASK)) +#define LCHSPEC_BAND(chspec) ((chspec) & WL_LCHANSPEC_BAND_MASK) +#define LCHSPEC_CTL_SB(chspec) ((chspec) & WL_LCHANSPEC_CTL_SB_MASK) +#define LCHSPEC_BW(chspec) ((chspec) & WL_LCHANSPEC_BW_MASK) +#define LCHSPEC_IS10(chspec) (((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_10) +#define LCHSPEC_IS20(chspec) (((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_20) +#define LCHSPEC_IS40(chspec) (((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_40) +#define LCHSPEC_IS5G(chspec) (((chspec) & WL_LCHANSPEC_BAND_MASK) == WL_LCHANSPEC_BAND_5G) +#define LCHSPEC_IS2G(chspec) (((chspec) & WL_LCHANSPEC_BAND_MASK) == WL_LCHANSPEC_BAND_2G) + +#define LCHSPEC_CREATE(chan, band, bw, sb) ((uint16)((chan) | (sb) | (bw) | (band))) + +#endif + + + + +#define WF_CHAN_FACTOR_2_4_G 4814 + + +#define WF_CHAN_FACTOR_5_G 10000 + + +#define WF_CHAN_FACTOR_4_G 8000 + #define WLC_MAXRATE 108 #define WLC_RATE_1M 2 @@ -145,18 +319,24 @@ typedef uint16 chanspec_t; extern char * wf_chspec_ntoa(chanspec_t chspec, char *buf); -extern chanspec_t wf_chspec_aton(char *a); +extern chanspec_t wf_chspec_aton(const char *a); extern bool wf_chspec_malformed(chanspec_t chanspec); +extern bool wf_chspec_valid(chanspec_t chanspec); + + extern uint8 wf_chspec_ctlchan(chanspec_t chspec); extern chanspec_t wf_chspec_ctlchspec(chanspec_t chspec); +extern chanspec_t wf_chspec_primary40_chspec(chanspec_t chspec); + + extern int wf_mhz2channel(uint freq, uint start_factor); diff --git a/drivers/net/wireless/bcmdhd/include/dbus.h b/drivers/net/wireless/bcmdhd/include/dbus.h new file mode 100644 index 00000000000..8c5a8cfea6b --- /dev/null +++ b/drivers/net/wireless/bcmdhd/include/dbus.h @@ -0,0 +1,568 @@ +/* + * Dongle BUS interface Abstraction layer + * target serial buses like USB, SDIO, SPI, etc. + * + * Copyright (C) 1999-2012, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id: dbus.h 309193 2012-01-19 00:03:57Z $ + */ + +#ifndef __DBUS_H__ +#define __DBUS_H__ + +#include "typedefs.h" + +#define DBUSTRACE(args) +#define DBUSERR(args) +#define DBUSINFO(args) +#define DBUSTRACE(args) +#define DBUSDBGLOCK(args) + +enum { + DBUS_OK = 0, + DBUS_ERR = -200, + DBUS_ERR_TIMEOUT, + DBUS_ERR_DISCONNECT, + DBUS_ERR_NODEVICE, + DBUS_ERR_UNSUPPORTED, + DBUS_ERR_PENDING, + DBUS_ERR_NOMEM, + DBUS_ERR_TXFAIL, + DBUS_ERR_TXTIMEOUT, + DBUS_ERR_TXDROP, + DBUS_ERR_RXFAIL, + DBUS_ERR_RXDROP, + DBUS_ERR_TXCTLFAIL, + DBUS_ERR_RXCTLFAIL, + DBUS_ERR_REG_PARAM, + DBUS_STATUS_CANCELLED, + DBUS_ERR_NVRAM, + DBUS_JUMBO_NOMATCH, + DBUS_JUMBO_BAD_FORMAT, + DBUS_NVRAM_NONTXT +}; + +#define BCM_OTP_SIZE_43236 84 /* number of 16 bit values */ +#define BCM_OTP_SW_RGN_43236 24 /* start offset of SW config region */ +#define BCM_OTP_ADDR_43236 0x18000800 /* address of otp base */ + +#define ERR_CBMASK_TXFAIL 0x00000001 +#define ERR_CBMASK_RXFAIL 0x00000002 +#define ERR_CBMASK_ALL 0xFFFFFFFF + +#define DBUS_CBCTL_WRITE 0 +#define DBUS_CBCTL_READ 1 + +#define DBUS_TX_RETRY_LIMIT 3 /* retries for failed txirb */ +#define DBUS_TX_TIMEOUT_INTERVAL 250 /* timeout for txirb complete, in ms */ + +#define DBUS_BUFFER_SIZE_TX 16000 +#define DBUS_BUFFER_SIZE_RX 5000 + +#define DBUS_BUFFER_SIZE_TX_NOAGG 2048 +#define DBUS_BUFFER_SIZE_RX_NOAGG 2048 + +/* DBUS types */ +enum { + DBUS_USB, + DBUS_SDIO, + DBUS_SPI, + DBUS_UNKNOWN +}; + +enum dbus_state { + DBUS_STATE_DL_PENDING, + DBUS_STATE_DL_DONE, + DBUS_STATE_UP, + DBUS_STATE_DOWN, + DBUS_STATE_PNP_FWDL, + DBUS_STATE_DISCONNECT, + DBUS_STATE_SLEEP +}; + +enum dbus_pnp_state { + DBUS_PNP_DISCONNECT, + DBUS_PNP_SLEEP, + DBUS_PNP_RESUME +}; + +enum dbus_file { + DBUS_FIRMWARE, + DBUS_NVFILE +}; + +typedef enum _DEVICE_SPEED { + INVALID_SPEED = -1, + LOW_SPEED = 1, /* USB 1.1: 1.5 Mbps */ + FULL_SPEED, /* USB 1.1: 12 Mbps */ + HIGH_SPEED, /* USB 2.0: 480 Mbps */ + SUPER_SPEED, /* USB 3.0: 4.8 Gbps */ +} DEVICE_SPEED; + +typedef struct { + int bustype; + int vid; + int pid; + int devid; + int chiprev; /* chip revsion number */ + int mtu; + int nchan; /* Data Channels */ + int has_2nd_bulk_in_ep; +} dbus_attrib_t; + +/* FIX: Account for errors related to DBUS; + * Let upper layer account for packets/bytes + */ +typedef struct { + uint32 rx_errors; + uint32 tx_errors; + uint32 rx_dropped; + uint32 tx_dropped; +} dbus_stats_t; + +/* + * Configurable BUS parameters + */ +typedef struct { + bool rxctl_deferrespok; +} dbus_config_t; + +/* + * External Download Info + */ +typedef struct dbus_extdl { + uint8 *fw; + int fwlen; + uint8 *vars; + int varslen; +} dbus_extdl_t; + +struct dbus_callbacks; +struct exec_parms; + +typedef void *(*probe_cb_t)(void *arg, const char *desc, uint32 bustype, uint32 hdrlen); +typedef void (*disconnect_cb_t)(void *arg); +typedef void *(*exec_cb_t)(struct exec_parms *args); + +/* Client callbacks registered during dbus_attach() */ +typedef struct dbus_callbacks { + void (*send_complete)(void *cbarg, void *info, int status); + void (*recv_buf)(void *cbarg, uint8 *buf, int len); + void (*recv_pkt)(void *cbarg, void *pkt); + void (*txflowcontrol)(void *cbarg, bool onoff); + void (*errhandler)(void *cbarg, int err); + void (*ctl_complete)(void *cbarg, int type, int status); + void (*state_change)(void *cbarg, int state); + void *(*pktget)(void *cbarg, uint len, bool send); + void (*pktfree)(void *cbarg, void *p, bool send); +} dbus_callbacks_t; + +struct dbus_pub; +struct bcmstrbuf; +struct dbus_irb; +struct dbus_irb_rx; +struct dbus_irb_tx; +struct dbus_intf_callbacks; + +typedef struct { + void* (*attach)(struct dbus_pub *pub, void *cbarg, struct dbus_intf_callbacks *cbs); + void (*detach)(struct dbus_pub *pub, void *bus); + + int (*up)(void *bus); + int (*down)(void *bus); + int (*send_irb)(void *bus, struct dbus_irb_tx *txirb); + int (*recv_irb)(void *bus, struct dbus_irb_rx *rxirb); + int (*cancel_irb)(void *bus, struct dbus_irb_tx *txirb); + int (*send_ctl)(void *bus, uint8 *buf, int len); + int (*recv_ctl)(void *bus, uint8 *buf, int len); + int (*get_stats)(void *bus, dbus_stats_t *stats); + int (*get_attrib)(void *bus, dbus_attrib_t *attrib); + + int (*pnp)(void *bus, int evnt); + int (*remove)(void *bus); + int (*resume)(void *bus); + int (*suspend)(void *bus); + int (*stop)(void *bus); + int (*reset)(void *bus); + + /* Access to bus buffers directly */ + void *(*pktget)(void *bus, int len); + void (*pktfree)(void *bus, void *pkt); + + int (*iovar_op)(void *bus, const char *name, void *params, int plen, void *arg, int len, + bool set); + void (*dump)(void *bus, struct bcmstrbuf *strbuf); + int (*set_config)(void *bus, dbus_config_t *config); + int (*get_config)(void *bus, dbus_config_t *config); + + bool (*device_exists)(void *bus); + bool (*dlneeded)(void *bus); + int (*dlstart)(void *bus, uint8 *fw, int len); + int (*dlrun)(void *bus); + bool (*recv_needed)(void *bus); + + void *(*exec_rxlock)(void *bus, exec_cb_t func, struct exec_parms *args); + void *(*exec_txlock)(void *bus, exec_cb_t func, struct exec_parms *args); + + int (*tx_timer_init)(void *bus); + int (*tx_timer_start)(void *bus, uint timeout); + int (*tx_timer_stop)(void *bus); + + int (*sched_dpc)(void *bus); + int (*lock)(void *bus); + int (*unlock)(void *bus); + int (*sched_probe_cb)(void *bus); + + int (*shutdown)(void *bus); + + int (*recv_stop)(void *bus); + int (*recv_resume)(void *bus); + + int (*recv_irb_from_ep)(void *bus, struct dbus_irb_rx *rxirb, uint ep_idx); + + int (*readreg)(void *bus, uint32 regaddr, int datalen, uint32 *value); + + /* Add from the bottom */ +} dbus_intf_t; + +typedef struct dbus_pub { + struct osl_info *osh; + dbus_stats_t stats; + dbus_attrib_t attrib; + enum dbus_state busstate; + DEVICE_SPEED device_speed; + int ntxq, nrxq, rxsize; + void *bus; + struct shared_info *sh; + void *dev_info; +} dbus_pub_t; + +#define BUS_INFO(bus, type) (((type *) bus)->pub->bus) + +#define ALIGNED_LOCAL_VARIABLE(var, align) \ + uint8 buffer[SDALIGN+64]; \ + uint8 *var = (uint8 *)(((uintptr)&buffer[0]) & ~(align-1)) + align; + +/* + * Public Bus Function Interface + */ + +/* + * FIX: Is there better way to pass OS/Host handles to DBUS but still + * maintain common interface for all OS?? + * Under NDIS, param1 needs to be MiniportHandle + * For NDIS60, param2 is WdfDevice + * Under Linux, param1 and param2 are NULL; + */ +extern int dbus_register(int vid, int pid, probe_cb_t prcb, disconnect_cb_t discb, void *prarg, + void *param1, void *param2); +extern int dbus_deregister(void); + +extern dbus_pub_t *dbus_attach(struct osl_info *osh, int rxsize, int nrxq, int ntxq, + void *cbarg, dbus_callbacks_t *cbs, dbus_extdl_t *extdl, struct shared_info *sh); +extern void dbus_detach(dbus_pub_t *pub); + +extern int dbus_up(dbus_pub_t *pub); +extern int dbus_down(dbus_pub_t *pub); +extern int dbus_stop(dbus_pub_t *pub); +extern int dbus_shutdown(dbus_pub_t *pub); +extern void dbus_flowctrl_rx(dbus_pub_t *pub, bool on); + +extern int dbus_send_txdata(dbus_pub_t *dbus, void *pktbuf); +extern int dbus_send_buf(dbus_pub_t *pub, uint8 *buf, int len, void *info); +extern int dbus_send_pkt(dbus_pub_t *pub, void *pkt, void *info); +extern int dbus_send_ctl(dbus_pub_t *pub, uint8 *buf, int len); +extern int dbus_recv_ctl(dbus_pub_t *pub, uint8 *buf, int len); +extern int dbus_recv_bulk(dbus_pub_t *pub, uint32 ep_idx); +extern int dbus_poll_intr(dbus_pub_t *pub); + +extern int dbus_get_stats(dbus_pub_t *pub, dbus_stats_t *stats); +extern int dbus_get_attrib(dbus_pub_t *pub, dbus_attrib_t *attrib); +extern int dbus_get_device_speed(dbus_pub_t *pub); +extern int dbus_set_config(dbus_pub_t *pub, dbus_config_t *config); +extern int dbus_get_config(dbus_pub_t *pub, dbus_config_t *config); +extern void * dbus_get_devinfo(dbus_pub_t *pub); + +extern void *dbus_pktget(dbus_pub_t *pub, int len); +extern void dbus_pktfree(dbus_pub_t *pub, void* pkt); + +extern int dbus_set_errmask(dbus_pub_t *pub, uint32 mask); +extern int dbus_pnp_sleep(dbus_pub_t *pub); +extern int dbus_pnp_resume(dbus_pub_t *pub, int *fw_reload); +extern int dbus_pnp_disconnect(dbus_pub_t *pub); + +extern int dbus_iovar_op(dbus_pub_t *pub, const char *name, + void *params, int plen, void *arg, int len, bool set); + +extern void *dhd_dbus_txq(const dbus_pub_t *pub); +extern uint dhd_dbus_hdrlen(const dbus_pub_t *pub); + +/* + * Private Common Bus Interface + */ + +/* IO Request Block (IRB) */ +typedef struct dbus_irb { + struct dbus_irb *next; /* it's casted from dbus_irb_tx or dbus_irb_rx struct */ +} dbus_irb_t; + +typedef struct dbus_irb_rx { + struct dbus_irb irb; /* Must be first */ + uint8 *buf; + int buf_len; + int actual_len; + void *pkt; + void *info; + void *arg; +} dbus_irb_rx_t; + +typedef struct dbus_irb_tx { + struct dbus_irb irb; /* Must be first */ + uint8 *buf; + int len; + void *pkt; + int retry_count; + void *info; + void *arg; + void *send_buf; /* linear bufffer for LINUX when aggreagtion is enabled */ +} dbus_irb_tx_t; + +/* DBUS interface callbacks are different from user callbacks + * so, internally, different info can be passed to upper layer + */ +typedef struct dbus_intf_callbacks { + void (*send_irb_timeout)(void *cbarg, dbus_irb_tx_t *txirb); + void (*send_irb_complete)(void *cbarg, dbus_irb_tx_t *txirb, int status); + void (*recv_irb_complete)(void *cbarg, dbus_irb_rx_t *rxirb, int status); + void (*errhandler)(void *cbarg, int err); + void (*ctl_complete)(void *cbarg, int type, int status); + void (*state_change)(void *cbarg, int state); + bool (*isr)(void *cbarg, bool *wantdpc); + bool (*dpc)(void *cbarg, bool bounded); + void (*watchdog)(void *cbarg); + void *(*pktget)(void *cbarg, uint len, bool send); + void (*pktfree)(void *cbarg, void *p, bool send); + struct dbus_irb* (*getirb)(void *cbarg, bool send); + void (*rxerr_indicate)(void *cbarg, bool on); +} dbus_intf_callbacks_t; + +/* + * Porting: To support new bus, port these functions below + */ + +/* + * Bus specific Interface + * Implemented by dbus_usb.c/dbus_sdio.c + */ +extern int dbus_bus_register(int vid, int pid, probe_cb_t prcb, disconnect_cb_t discb, void *prarg, + dbus_intf_t **intf, void *param1, void *param2); +extern int dbus_bus_deregister(void); +extern void dbus_bus_fw_get(void *bus, uint8 **fw, int *fwlen, int *decomp); + +/* + * Bus-specific and OS-specific Interface + * Implemented by dbus_usb_[linux/ndis].c/dbus_sdio_[linux/ndis].c + */ +extern int dbus_bus_osl_register(int vid, int pid, probe_cb_t prcb, disconnect_cb_t discb, + void *prarg, dbus_intf_t **intf, void *param1, void *param2); +extern int dbus_bus_osl_deregister(void); + +/* + * Bus-specific, OS-specific, HW-specific Interface + * Mainly for SDIO Host HW controller + */ +extern int dbus_bus_osl_hw_register(int vid, int pid, probe_cb_t prcb, disconnect_cb_t discb, + void *prarg, dbus_intf_t **intf); +extern int dbus_bus_osl_hw_deregister(void); + +extern uint usbdev_bulkin_eps(void); +#if defined(BCM_REQUEST_FW) +extern void *dbus_get_fw_nvfile(int devid, uint8 **fw, int *fwlen, int type, + uint16 boardtype, uint16 boardrev); +extern void dbus_release_fw_nvfile(void *firmware); +#endif /* #if defined(BCM_REQUEST_FW) */ + + +#if defined(EHCI_FASTPATH_TX) || defined(EHCI_FASTPATH_RX) + + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) + /* Backward compatibility */ + typedef unsigned int gfp_t; + + #define dma_pool pci_pool + #define dma_pool_create(name, dev, size, align, alloc) \ + pci_pool_create(name, dev, size, align, alloc, GFP_DMA | GFP_ATOMIC) + #define dma_pool_destroy(pool) pci_pool_destroy(pool) + #define dma_pool_alloc(pool, flags, handle) pci_pool_alloc(pool, flags, handle) + #define dma_pool_free(pool, vaddr, addr) pci_pool_free(pool, vaddr, addr) + + #define dma_map_single(dev, addr, size, dir) pci_map_single(dev, addr, size, dir) + #define dma_unmap_single(dev, hnd, size, dir) pci_unmap_single(dev, hnd, size, dir) + #define DMA_FROM_DEVICE PCI_DMA_FROMDEVICE + #define DMA_TO_DEVICE PCI_DMA_TODEVICE +#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) */ + +/* Availability of these functions varies (when present, they have two arguments) */ +#ifndef hc32_to_cpu + #define hc32_to_cpu(x) le32_to_cpu(x) + #define cpu_to_hc32(x) cpu_to_le32(x) + typedef unsigned int __hc32; +#else + #error Two-argument functions needed +#endif + +/* Private USB opcode base */ +#define EHCI_FASTPATH 0x31 +#define EHCI_SET_EP_BYPASS EHCI_FASTPATH +#define EHCI_SET_BYPASS_CB (EHCI_FASTPATH + 1) +#define EHCI_SET_BYPASS_DEV (EHCI_FASTPATH + 2) +#define EHCI_DUMP_STATE (EHCI_FASTPATH + 3) +#define EHCI_SET_BYPASS_POOL (EHCI_FASTPATH + 4) +#define EHCI_CLR_EP_BYPASS (EHCI_FASTPATH + 5) + +/* + * EHCI QTD structure (hardware and extension) + * NOTE that is does not need to (and does not) match its kernel counterpart + */ +#define EHCI_QTD_NBUFFERS 5 +#define EHCI_QTD_ALIGN 32 +#define EHCI_BULK_PACKET_SIZE 512 +#define EHCI_QTD_XACTERR_MAX 32 + +struct ehci_qtd { + /* Hardware map */ + volatile uint32_t qtd_next; + volatile uint32_t qtd_altnext; + volatile uint32_t qtd_status; +#define EHCI_QTD_GET_BYTES(x) (((x)>>16) & 0x7fff) +#define EHCI_QTD_IOC 0x00008000 +#define EHCI_QTD_GET_CERR(x) (((x)>>10) & 0x3) +#define EHCI_QTD_SET_CERR(x) ((x) << 10) +#define EHCI_QTD_GET_PID(x) (((x)>>8) & 0x3) +#define EHCI_QTD_SET_PID(x) ((x) << 8) +#define EHCI_QTD_ACTIVE 0x80 +#define EHCI_QTD_HALTED 0x40 +#define EHCI_QTD_BUFERR 0x20 +#define EHCI_QTD_BABBLE 0x10 +#define EHCI_QTD_XACTERR 0x08 +#define EHCI_QTD_MISSEDMICRO 0x04 + volatile uint32_t qtd_buffer[EHCI_QTD_NBUFFERS]; + volatile uint32_t qtd_buffer_hi[EHCI_QTD_NBUFFERS]; + + /* Implementation extension */ + dma_addr_t qtd_self; /* own hardware address */ + struct ehci_qtd *obj_next; /* software link to the next QTD */ + void *rpc; /* pointer to the rpc buffer */ + size_t length; /* length of the data in the buffer */ + void *buff; /* pointer to the reassembly buffer */ + int xacterrs; /* retry counter for qtd xact error */ +} __attribute__ ((aligned(EHCI_QTD_ALIGN))); + +#define EHCI_NULL __constant_cpu_to_le32(1) /* HW null pointer shall be odd */ + +#define SHORT_READ_Q(token) (EHCI_QTD_GET_BYTES(token) != 0 && EHCI_QTD_GET_PID(token) == 1) + +/* Queue Head */ +/* NOTE This structure is slightly different from the one in the kernel; but needs to stay + * compatible + */ +struct ehci_qh { + /* Hardware map */ + volatile uint32_t qh_link; + volatile uint32_t qh_endp; + volatile uint32_t qh_endphub; + volatile uint32_t qh_curqtd; + + /* QTD overlay */ + volatile uint32_t ow_next; + volatile uint32_t ow_altnext; + volatile uint32_t ow_status; + volatile uint32_t ow_buffer [EHCI_QTD_NBUFFERS]; + volatile uint32_t ow_buffer_hi [EHCI_QTD_NBUFFERS]; + + /* Extension (should match the kernel layout) */ + dma_addr_t unused0; + void *unused1; + struct list_head unused2; + struct ehci_qtd *dummy; + struct ehci_qh *unused3; + + struct ehci_hcd *unused4; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) + struct kref unused5; + unsigned unused6; + + uint8_t unused7; + + /* periodic schedule info */ + uint8_t unused8; + uint8_t unused9; + uint8_t unused10; + uint16_t unused11; + uint16_t unused12; + uint16_t unused13; + struct usb_device *unused14; +#else + unsigned unused5; + + u8 unused6; + + /* periodic schedule info */ + u8 unused7; + u8 unused8; + u8 unused9; + unsigned short unused10; + unsigned short unused11; +#define NO_FRAME ((unsigned short)~0) +#ifdef EHCI_QUIRK_FIX + struct usb_device *unused12; +#endif /* EHCI_QUIRK_FIX */ +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) */ + struct ehci_qtd *first_qtd; + /* Link to the first QTD; this is an optimized equivalent of the qtd_list field */ + /* NOTE that ehci_qh in ehci.h shall reserve this word */ +} __attribute__ ((aligned(EHCI_QTD_ALIGN))); + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) +/* The corresponding structure in the kernel is used to get the QH */ +struct hcd_dev { /* usb_device.hcpriv points to this */ + struct list_head unused0; + struct list_head unused1; + + /* array of QH pointers */ + void *ep[32]; +}; +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) */ + +int optimize_qtd_fill_with_rpc(const dbus_pub_t *pub, int epn, struct ehci_qtd *qtd, void *rpc, + int token, int len); +int optimize_qtd_fill_with_data(const dbus_pub_t *pub, int epn, struct ehci_qtd *qtd, void *data, + int token, int len); +int optimize_submit_async(struct ehci_qtd *qtd, int epn); +void inline optimize_ehci_qtd_init(struct ehci_qtd *qtd, dma_addr_t dma); +struct ehci_qtd *optimize_ehci_qtd_alloc(gfp_t flags); +void optimize_ehci_qtd_free(struct ehci_qtd *qtd); +void optimize_submit_rx_request(const dbus_pub_t *pub, int epn, struct ehci_qtd *qtd_in, void *buf); +#endif /* EHCI_FASTPATH_TX || EHCI_FASTPATH_RX */ + +void dbus_flowctrl_tx(void *dbi, bool on); +#endif /* __DBUS_H__ */ diff --git a/drivers/net/wireless/bcmdhd/include/dhdioctl.h b/drivers/net/wireless/bcmdhd/include/dhdioctl.h index 0312d220601..69f56c5d866 100644 --- a/drivers/net/wireless/bcmdhd/include/dhdioctl.h +++ b/drivers/net/wireless/bcmdhd/include/dhdioctl.h @@ -5,9 +5,9 @@ * * Definitions subject to change without notice. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -25,7 +25,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: dhdioctl.h 307573 2012-01-12 00:04:39Z $ + * $Id: dhdioctl.h 303826 2011-12-20 06:02:09Z $ */ #ifndef _dhdioctl_h_ @@ -87,7 +87,7 @@ enum { #define DHD_BTA_VAL 0x1000 #define DHD_ISCAN_VAL 0x2000 #define DHD_ARPOE_VAL 0x4000 -#define DHD_WL_VAL 0x8000 +#define DHD_REORDER_VAL 0x8000 #ifdef SDTEST /* For pktgen iovar */ diff --git a/drivers/net/wireless/bcmdhd/include/epivers.h b/drivers/net/wireless/bcmdhd/include/epivers.h index 53dd2f73673..fe10cfc00ed 100644 --- a/drivers/net/wireless/bcmdhd/include/epivers.h +++ b/drivers/net/wireless/bcmdhd/include/epivers.h @@ -1,7 +1,7 @@ /* - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -19,31 +19,30 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: epivers.h.in 277737 2011-08-16 17:54:59Z $ + * $Id: epivers.h.in,v 13.33 2010-09-08 22:08:53 $ * */ - #ifndef _epivers_h_ #define _epivers_h_ -#define EPI_MAJOR_VERSION 5 +#define EPI_MAJOR_VERSION 1 -#define EPI_MINOR_VERSION 90 +#define EPI_MINOR_VERSION 9 -#define EPI_RC_NUMBER 195 +#define EPI_RC_NUMBER 0 -#define EPI_INCREMENTAL_NUMBER 23 +#define EPI_INCREMENTAL_NUMBER 0 #define EPI_BUILD_NUMBER 0 -#define EPI_VERSION 5, 90, 195, 23 +#define EPI_VERSION 1, 9, 0, 0 -#define EPI_VERSION_NUM 0x055ac317 +#define EPI_VERSION_NUM 0x01090000 -#define EPI_VERSION_DEV 5.90.195 +#define EPI_VERSION_DEV 1.9.0 -#define EPI_VERSION_STR "5.90.195.23" +#define EPI_VERSION_STR "1.9 (r310571)" #endif diff --git a/drivers/net/wireless/bcmdhd/include/hndpmu.h b/drivers/net/wireless/bcmdhd/include/hndpmu.h index 69a834c6b7e..c41def6c7d8 100644 --- a/drivers/net/wireless/bcmdhd/include/hndpmu.h +++ b/drivers/net/wireless/bcmdhd/include/hndpmu.h @@ -1,9 +1,9 @@ /* * HND SiliconBackplane PMU support. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: hndpmu.h 277737 2011-08-16 17:54:59Z $ + * $Id: hndpmu.h 241182 2011-02-17 21:50:03Z $ */ #ifndef _hndpmu_h_ @@ -31,4 +31,6 @@ extern void si_pmu_otp_power(si_t *sih, osl_t *osh, bool on); extern void si_sdiod_drive_strength_init(si_t *sih, osl_t *osh, uint32 drivestrength); +extern void si_pmu_minresmask_htavail_set(si_t *sih, osl_t *osh, bool set_clear); + #endif /* _hndpmu_h_ */ diff --git a/drivers/net/wireless/bcmdhd/include/hndrte_armtrap.h b/drivers/net/wireless/bcmdhd/include/hndrte_armtrap.h index 7d862c4deb2..90d97992938 100644 --- a/drivers/net/wireless/bcmdhd/include/hndrte_armtrap.h +++ b/drivers/net/wireless/bcmdhd/include/hndrte_armtrap.h @@ -1,9 +1,9 @@ /* * HNDRTE arm trap handling. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: hndrte_armtrap.h 277737 2011-08-16 17:54:59Z $ + * $Id: hndrte_armtrap.h 261365 2011-05-24 20:42:23Z $ */ #ifndef _hndrte_armtrap_h @@ -65,22 +65,22 @@ typedef struct _trap_struct { uint32 epc; uint32 cpsr; uint32 spsr; - uint32 r0; - uint32 r1; - uint32 r2; - uint32 r3; - uint32 r4; - uint32 r5; - uint32 r6; - uint32 r7; - uint32 r8; - uint32 r9; - uint32 r10; - uint32 r11; - uint32 r12; - uint32 r13; - uint32 r14; - uint32 pc; + uint32 r0; /* a1 */ + uint32 r1; /* a2 */ + uint32 r2; /* a3 */ + uint32 r3; /* a4 */ + uint32 r4; /* v1 */ + uint32 r5; /* v2 */ + uint32 r6; /* v3 */ + uint32 r7; /* v4 */ + uint32 r8; /* v5 */ + uint32 r9; /* sb/v6 */ + uint32 r10; /* sl/v7 */ + uint32 r11; /* fp/v8 */ + uint32 r12; /* ip */ + uint32 r13; /* sp */ + uint32 r14; /* lr */ + uint32 pc; /* r15 */ } trap_t; #endif /* !_LANGUAGE_ASSEMBLY */ diff --git a/drivers/net/wireless/bcmdhd/include/hndrte_cons.h b/drivers/net/wireless/bcmdhd/include/hndrte_cons.h index 859ddc8953a..57abbbd5b67 100644 --- a/drivers/net/wireless/bcmdhd/include/hndrte_cons.h +++ b/drivers/net/wireless/bcmdhd/include/hndrte_cons.h @@ -1,9 +1,9 @@ /* * Console support for hndrte. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,9 +21,8 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: hndrte_cons.h 277737 2011-08-16 17:54:59Z $ + * $Id: hndrte_cons.h 300516 2011-12-04 17:39:44Z $ */ - #ifndef _HNDRTE_CONS_H #define _HNDRTE_CONS_H diff --git a/drivers/net/wireless/bcmdhd/include/hndsoc.h b/drivers/net/wireless/bcmdhd/include/hndsoc.h index 34f927c6af8..66640c3b0cb 100644 --- a/drivers/net/wireless/bcmdhd/include/hndsoc.h +++ b/drivers/net/wireless/bcmdhd/include/hndsoc.h @@ -1,9 +1,9 @@ /* * Broadcom HND chip & on-chip-interconnect-related definitions. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: hndsoc.h 277737 2011-08-16 17:54:59Z $ + * $Id: hndsoc.h 309193 2012-01-19 00:03:57Z $ */ #ifndef _HNDSOC_H @@ -60,6 +60,7 @@ #define SI_FLASH1 0x1fc00000 /* MIPS Flash Region 1 */ #define SI_FLASH1_SZ 0x00400000 /* MIPS Size of Flash Region 1 */ #define SI_ARM7S_ROM 0x20000000 /* ARM7TDMI-S ROM */ +#define SI_ARMCR4_ROM 0x000f0000 /* ARM Cortex-R4 ROM */ #define SI_ARMCM3_SRAM2 0x60000000 /* ARM Cortex-M3 SRAM Region 2 */ #define SI_ARM7S_SRAM2 0x80000000 /* ARM7TDMI-S SRAM Region 2 */ #define SI_ARM_FLASH1 0xffff0000 /* ARM Flash Region 1 */ @@ -132,11 +133,36 @@ #define I2S_CORE_ID 0x834 /* I2S core */ #define DMEMS_CORE_ID 0x835 /* SDR/DDR1 memory controller core */ #define DEF_SHIM_COMP 0x837 /* SHIM component in ubus/6362 */ + +#define ACPHY_CORE_ID 0x83b /* Dot11 ACPHY */ +#define PCIE2_CORE_ID 0x83c /* pci express Gen2 core */ +#define USB30D_CORE_ID 0x83d /* usb 3.0 device core */ +#define ARMCR4_CORE_ID 0x83e /* ARM CR4 CPU */ +#define APB_BRIDGE_CORE_ID 0x135 /* APB bridge core ID */ +#define AXI_CORE_ID 0x301 /* AXI/GPV core ID */ +#define EROM_CORE_ID 0x366 /* EROM core ID */ #define OOB_ROUTER_CORE_ID 0x367 /* OOB router core ID */ -#define DEF_AI_COMP 0xfff /* Default component, in ai chips it maps all +#define DEF_AI_COMP 0xfff /* Default component, in ai chips it maps all * unused address ranges */ +#define CC_4706_CORE_ID 0x500 /* chipcommon core */ +#define SOCRAM_4706_CORE_ID 0x50e /* internal memory core */ +#define GMAC_COMMON_4706_CORE_ID 0x5dc /* Gigabit MAC core */ +#define GMAC_4706_CORE_ID 0x52d /* Gigabit MAC core */ +#define AMEMC_CORE_ID 0x52e /* DDR1/2 memory controller core */ +#define ALTA_CORE_ID 0x534 /* I2S core */ +#define DDR23_PHY_CORE_ID 0x5dd + +#define SI_PCI1_MEM 0x40000000 /* Host Mode sb2pcitranslation0 (64 MB) */ +#define SI_PCI1_CFG 0x44000000 /* Host Mode sb2pcitranslation1 (64 MB) */ +#define SI_PCIE1_DMA_H32 0xc0000000 /* PCIE Client Mode sb2pcitranslation2 + * (2 ZettaBytes), high 32 bits + */ +#define CC_4706B0_CORE_REV 0x8000001f /* chipcommon core */ +#define SOCRAM_4706B0_CORE_REV 0x80000005 /* internal memory core */ +#define GMAC_4706B0_CORE_REV 0x80000000 /* Gigabit MAC core */ + /* There are TWO constants on all HND chips: SI_ENUM_BASE above, * and chipcommon being the first core: */ @@ -173,6 +199,8 @@ #define CCS_ALPAREQ 0x00000008 /* ALP Avail Request */ #define CCS_HTAREQ 0x00000010 /* HT Avail Request */ #define CCS_FORCEHWREQOFF 0x00000020 /* Force HW Clock Request Off */ +#define CCS_HQCLKREQ 0x00000040 /* HQ Clock Required */ +#define CCS_USBCLKREQ 0x00000100 /* USB Clock Req */ #define CCS_ERSRC_REQ_MASK 0x00000700 /* external resource requests */ #define CCS_ERSRC_REQ_SHIFT 8 #define CCS_ALPAVAIL 0x00010000 /* ALP is available */ diff --git a/drivers/net/wireless/bcmdhd/include/linux_osl.h b/drivers/net/wireless/bcmdhd/include/linux_osl.h index 830d351d882..e5133e07336 100644 --- a/drivers/net/wireless/bcmdhd/include/linux_osl.h +++ b/drivers/net/wireless/bcmdhd/include/linux_osl.h @@ -1,9 +1,9 @@ /* * Linux OS Independent Layer * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,10 +21,9 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: linux_osl.h 301794 2011-12-08 20:41:35Z $ + * $Id: linux_osl.h 309193 2012-01-19 00:03:57Z $ */ - #ifndef _linux_osl_h_ #define _linux_osl_h_ @@ -34,6 +33,7 @@ extern void * osl_os_open_image(char * filename); extern int osl_os_get_image_block(char * buf, int len, void * image); extern void osl_os_close_image(void * image); +extern int osl_os_image_size(void *image); #ifdef BCMDRIVER @@ -49,7 +49,7 @@ extern uint32 g_assert_type; #if defined(BCMASSERT_LOG) #define ASSERT(exp) \ do { if (!(exp)) osl_assert(#exp, __FILE__, __LINE__); } while (0) -extern void osl_assert(char *exp, char *file, int line); +extern void osl_assert(const char *exp, const char *file, int line); #else #ifdef __GNUC__ #define GCC_VERSION \ @@ -87,6 +87,7 @@ extern void osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val); #define OSL_PCI_SLOT(osh) osl_pci_slot(osh) extern uint osl_pci_bus(osl_t *osh); extern uint osl_pci_slot(osl_t *osh); +extern struct pci_dev *osl_pci_device(osl_t *osh); typedef struct { @@ -95,6 +96,7 @@ typedef struct { bool mmbus; pktfree_cb_fn_t tx_fn; void *tx_ctx; + void *unused[3]; } osl_pubinfo_t; #define PKTFREESETCB(osh, _tx_fn, _tx_ctx) \ @@ -135,8 +137,6 @@ extern void osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa); #define DMA_RX 2 -#define DMA_MAP(osh, va, size, direction, p, dmah) \ - osl_dma_map((osh), (va), (size), (direction)) #define DMA_UNMAP(osh, pa, size, direction, p, dmah) \ osl_dma_unmap((osh), (pa), (size), (direction)) extern uint osl_dma_map(osl_t *osh, void *va, uint size, int direction); @@ -162,6 +162,9 @@ extern int osl_error(int bcmerror); #define PKTBUFSZ 2048 +#include +#include +#include #define OSL_SYSUPTIME() ((uint32)jiffies * (1000 / HZ)) #define printf(fmt, args...) printk(fmt , ## args) @@ -174,18 +177,11 @@ extern int osl_error(int bcmerror); -#ifndef __mips__ -#define R_REG(osh, r) (\ - SELECT_BUS_READ(osh, sizeof(*(r)) == sizeof(uint8) ? readb((volatile uint8*)(r)) : \ - sizeof(*(r)) == sizeof(uint16) ? readw((volatile uint16*)(r)) : \ - readl((volatile uint32*)(r)), OSL_READ_REG(osh, r)) \ -) -#else #define R_REG(osh, r) (\ SELECT_BUS_READ(osh, \ ({ \ __typeof(*(r)) __osl_v; \ - __asm__ __volatile__("sync"); \ + BCM_REFERENCE(osh); \ switch (sizeof(*(r))) { \ case sizeof(uint8): __osl_v = \ readb((volatile uint8*)(r)); break; \ @@ -194,21 +190,14 @@ extern int osl_error(int bcmerror); case sizeof(uint32): __osl_v = \ readl((volatile uint32*)(r)); break; \ } \ - __asm__ __volatile__("sync"); \ __osl_v; \ }), \ - ({ \ - __typeof(*(r)) __osl_v; \ - __asm__ __volatile__("sync"); \ - __osl_v = OSL_READ_REG(osh, r); \ - __asm__ __volatile__("sync"); \ - __osl_v; \ - })) \ + OSL_READ_REG(osh, r)) \ ) -#endif #define W_REG(osh, r, v) do { \ - SELECT_BUS_WRITE(osh, \ + BCM_REFERENCE(osh); \ + SELECT_BUS_WRITE(osh, \ switch (sizeof(*(r))) { \ case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)(r)); break; \ case sizeof(uint16): writew((uint16)(v), (volatile uint16*)(r)); break; \ @@ -217,7 +206,6 @@ extern int osl_error(int bcmerror); (OSL_WRITE_REG(osh, r, v))); \ } while (0) - #define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v)) #define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v)) @@ -227,14 +215,11 @@ extern int osl_error(int bcmerror); #define bzero(b, len) memset((b), '\0', (len)) -#ifdef __mips__ -#include -#define OSL_UNCACHED(va) ((void *)KSEG1ADDR((va))) -#define OSL_CACHED(va) ((void *)KSEG0ADDR((va))) -#else #define OSL_UNCACHED(va) ((void *)va) #define OSL_CACHED(va) ((void *)va) -#endif + +#define OSL_PREF_RANGE_LD(va, sz) +#define OSL_PREF_RANGE_ST(va, sz) #if defined(__i386__) @@ -271,7 +256,7 @@ extern int osl_error(int bcmerror); #ifdef CONFIG_DHD_USE_STATIC_BUF #define PKTGET_STATIC(osh, len, send) osl_pktget_static((osh), (len)) #define PKTFREE_STATIC(osh, skb, send) osl_pktfree_static((osh), (skb), (send)) -#endif +#endif #define PKTDATA(osh, skb) (((struct sk_buff*)(skb))->data) #define PKTLEN(osh, skb) (((struct sk_buff*)(skb))->len) #define PKTHEADROOM(osh, skb) (PKTDATA(osh, skb)-(((struct sk_buff*)(skb))->head)) @@ -332,6 +317,7 @@ extern void osl_ctfpool_cleanup(osl_t *osh); extern void osl_ctfpool_stats(osl_t *osh, void *b); #endif + #ifdef HNDCTF #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) #define SKIPCT (1 << 6) @@ -354,44 +340,12 @@ extern void osl_pktfree(osl_t *osh, void *skb, bool send); extern void *osl_pktget_static(osl_t *osh, uint len); extern void osl_pktfree_static(osl_t *osh, void *skb, bool send); +extern void *osl_pkt_frmnative(osl_t *osh, void *skb); extern void *osl_pktget(osl_t *osh, uint len); extern void *osl_pktdup(osl_t *osh, void *skb); - - -static INLINE void * -osl_pkt_frmnative(osl_pubinfo_t *osh, void *pkt) -{ - struct sk_buff *nskb; - - if (osh->pkttag) - bzero((void*)((struct sk_buff*)pkt)->cb, OSL_PKTTAG_SZ); - - - for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) { - osh->pktalloced++; - } - - return (void *)pkt; -} -#define PKTFRMNATIVE(osh, skb) osl_pkt_frmnative(((osl_pubinfo_t *)osh), (struct sk_buff*)(skb)) - - -static INLINE struct sk_buff * -osl_pkt_tonative(osl_pubinfo_t *osh, void *pkt) -{ - struct sk_buff *nskb; - - if (osh->pkttag) - bzero(((struct sk_buff*)pkt)->cb, OSL_PKTTAG_SZ); - - - for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) { - osh->pktalloced--; - } - - return (struct sk_buff *)pkt; -} -#define PKTTONATIVE(osh, pkt) osl_pkt_tonative((osl_pubinfo_t *)(osh), (pkt)) +extern struct sk_buff *osl_pkt_tonative(osl_t *osh, void *pkt); +#define PKTFRMNATIVE(osh, skb) osl_pkt_frmnative(((osl_t *)osh), (struct sk_buff*)(skb)) +#define PKTTONATIVE(osh, pkt) osl_pkt_tonative((osl_t *)(osh), (pkt)) #define PKTLINK(skb) (((struct sk_buff*)(skb))->prev) #define PKTSETLINK(skb, x) (((struct sk_buff*)(skb))->prev = (struct sk_buff*)(x)) @@ -403,7 +357,8 @@ osl_pkt_tonative(osl_pubinfo_t *osh, void *pkt) #define PKTSHARED(skb) (((struct sk_buff*)(skb))->cloned) - +#define DMA_MAP(osh, va, size, direction, p, dmah) \ + osl_dma_map((osh), (va), (size), (direction)) #else diff --git a/drivers/net/wireless/bcmdhd/include/linuxver.h b/drivers/net/wireless/bcmdhd/include/linuxver.h index d269e66f7fb..058f2a79863 100644 --- a/drivers/net/wireless/bcmdhd/include/linuxver.h +++ b/drivers/net/wireless/bcmdhd/include/linuxver.h @@ -2,9 +2,9 @@ * Linux-specific abstractions to gain some independence from linux kernel versions. * Pave over some 2.2 versus 2.4 versus 2.6 kernel differences. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -22,10 +22,9 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: linuxver.h 280266 2011-08-28 04:18:20Z $ + * $Id: linuxver.h 309909 2012-01-21 00:15:02Z $ */ - #ifndef _linuxver_h_ #define _linuxver_h_ @@ -72,6 +71,8 @@ #include #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) #include +#else +#include #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)) #undef IP_TOS @@ -217,10 +218,10 @@ extern void pci_unregister_driver(struct pci_driver *drv); #undef WL_USE_NETDEV_OPS #endif -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)) && defined(CONFIG_RFKILL_INPUT) -#define WL_CONFIG_RFKILL_INPUT +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)) && defined(CONFIG_RFKILL) +#define WL_CONFIG_RFKILL #else -#undef WL_CONFIG_RFKILL_INPUT +#undef WL_CONFIG_RFKILL #endif #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 48)) @@ -469,7 +470,7 @@ typedef struct { long thr_pid; int prio; struct semaphore sema; - bool terminated; + int terminated; struct completion completed; } tsk_ctl_t; @@ -511,18 +512,6 @@ typedef struct { (tsk_ctl)->thr_pid = -1; \ } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -#define DAEMONIZE(a) daemonize(a); \ - allow_signal(SIGKILL); \ - allow_signal(SIGTERM); -#else /* Linux 2.4 (w/o preemption patch) */ -#define RAISE_RX_SOFTIRQ() \ - cpu_raise_softirq(smp_processor_id(), NET_RX_SOFTIRQ) -#define DAEMONIZE(a) daemonize(); \ - do { if (a) \ - strncpy(current->comm, a, MIN(sizeof(current->comm), (strlen(a) + 1))); \ - } while (0); -#endif /* LINUX_VERSION_CODE */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)) diff --git a/drivers/net/wireless/bcmdhd/include/miniopt.h b/drivers/net/wireless/bcmdhd/include/miniopt.h index 77eace6252d..c1eca68a602 100644 --- a/drivers/net/wireless/bcmdhd/include/miniopt.h +++ b/drivers/net/wireless/bcmdhd/include/miniopt.h @@ -1,9 +1,9 @@ /* * Command line options parser. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -20,7 +20,7 @@ * Notwithstanding the above, under no circumstances may you combine this * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. - * $Id: miniopt.h 277737 2011-08-16 17:54:59Z $ + * $Id: miniopt.h 241182 2011-02-17 21:50:03Z $ */ diff --git a/drivers/net/wireless/bcmdhd/include/msgtrace.h b/drivers/net/wireless/bcmdhd/include/msgtrace.h index 088f1e845a4..7c5fd8106f3 100644 --- a/drivers/net/wireless/bcmdhd/include/msgtrace.h +++ b/drivers/net/wireless/bcmdhd/include/msgtrace.h @@ -1,9 +1,9 @@ /* * Trace messages sent over HBUS * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: msgtrace.h 277737 2011-08-16 17:54:59Z $ + * $Id: msgtrace.h 281527 2011-09-02 17:12:53Z $ */ #ifndef _MSGTRACE_H @@ -51,7 +51,7 @@ typedef BWL_PRE_PACKED_STRUCT struct msgtrace_hdr { #define MSGTRACE_HDRLEN sizeof(msgtrace_hdr_t) -/* The hbus driver generates traces when sending a trace message. This causes endless traces. +/* The hbus driver generates traces when sending a trace message. This causes endless traces. * This flag must be set to TRUE in any hbus traces. The flag is reset in the function msgtrace_put. * This prevents endless traces but generates hasardous lost of traces only in bus device code. * It is recommendat to set this flag in macro SD_TRACE but not in SD_ERROR for avoiding missing diff --git a/drivers/net/wireless/bcmdhd/include/osl.h b/drivers/net/wireless/bcmdhd/include/osl.h index b8cc2569f50..0f529c74614 100644 --- a/drivers/net/wireless/bcmdhd/include/osl.h +++ b/drivers/net/wireless/bcmdhd/include/osl.h @@ -1,9 +1,9 @@ /* * OS Abstraction Layer * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,10 +21,9 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: osl.h 277737 2011-08-16 17:54:59Z $ + * $Id: osl.h 301926 2011-12-09 02:00:46Z $ */ - #ifndef _osl_h_ #define _osl_h_ @@ -38,12 +37,18 @@ typedef struct osl_dmainfo osldma_t; typedef void (*pktfree_cb_fn_t)(void *ctx, void *pkt, unsigned int status); +typedef unsigned int (*osl_rreg_fn_t)(void *ctx, volatile void *reg, unsigned int size); +typedef void (*osl_wreg_fn_t)(void *ctx, volatile void *reg, unsigned int val, unsigned int size); + + #include #ifndef PKTDBG_TRACE #define PKTDBG_TRACE(osh, pkt, bit) #endif +#define PKTCTFMAP(osh, p) + #define SET_REG(osh, r, mask, val) W_REG((osh), (r), ((R_REG((osh), r) & ~(mask)) | (val))) diff --git a/drivers/net/wireless/bcmdhd/include/packed_section_end.h b/drivers/net/wireless/bcmdhd/include/packed_section_end.h index 71f8b2e13b3..24ff4672734 100644 --- a/drivers/net/wireless/bcmdhd/include/packed_section_end.h +++ b/drivers/net/wireless/bcmdhd/include/packed_section_end.h @@ -15,9 +15,9 @@ * #include * * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -34,12 +34,11 @@ * Notwithstanding the above, under no circumstances may you combine this * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. - * $Id: packed_section_end.h 277737 2011-08-16 17:54:59Z $ + * $Id: packed_section_end.h 241182 2011-02-17 21:50:03Z $ */ - #ifdef BWL_PACKED_SECTION #undef BWL_PACKED_SECTION #else diff --git a/drivers/net/wireless/bcmdhd/include/packed_section_start.h b/drivers/net/wireless/bcmdhd/include/packed_section_start.h index afc2ba32fd9..7fce0ddfd56 100644 --- a/drivers/net/wireless/bcmdhd/include/packed_section_start.h +++ b/drivers/net/wireless/bcmdhd/include/packed_section_start.h @@ -15,9 +15,9 @@ * #include * * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -34,12 +34,11 @@ * Notwithstanding the above, under no circumstances may you combine this * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. - * $Id: packed_section_start.h 277737 2011-08-16 17:54:59Z $ + * $Id: packed_section_start.h 286783 2011-09-29 06:18:57Z $ */ - #ifdef BWL_PACKED_SECTION #error "BWL_PACKED_SECTION is already defined!" #else @@ -50,7 +49,7 @@ -#if defined(__GNUC__) +#if defined(__GNUC__) || defined(__lint) #define BWL_PRE_PACKED_STRUCT #define BWL_POST_PACKED_STRUCT __attribute__ ((packed)) #elif defined(__CC_ARM) diff --git a/drivers/net/wireless/bcmdhd/include/pcicfg.h b/drivers/net/wireless/bcmdhd/include/pcicfg.h index 66199431fb9..5f7df6a7a7e 100644 --- a/drivers/net/wireless/bcmdhd/include/pcicfg.h +++ b/drivers/net/wireless/bcmdhd/include/pcicfg.h @@ -1,9 +1,9 @@ /* * pcicfg.h: PCI configuration constants and structures. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,26 +21,46 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: pcicfg.h 277737 2011-08-16 17:54:59Z $ + * $Id: pcicfg.h 309193 2012-01-19 00:03:57Z $ */ - #ifndef _h_pcicfg_ #define _h_pcicfg_ #define PCI_CFG_VID 0 +#define PCI_CFG_DID 2 #define PCI_CFG_CMD 4 +#define PCI_CFG_STAT 6 #define PCI_CFG_REV 8 +#define PCI_CFG_PROGIF 9 +#define PCI_CFG_SUBCL 0xa +#define PCI_CFG_BASECL 0xb +#define PCI_CFG_CLSZ 0xc +#define PCI_CFG_LATTIM 0xd +#define PCI_CFG_HDR 0xe +#define PCI_CFG_BIST 0xf #define PCI_CFG_BAR0 0x10 #define PCI_CFG_BAR1 0x14 +#define PCI_CFG_BAR2 0x18 +#define PCI_CFG_BAR3 0x1c +#define PCI_CFG_BAR4 0x20 +#define PCI_CFG_BAR5 0x24 +#define PCI_CFG_CIS 0x28 +#define PCI_CFG_SVID 0x2c +#define PCI_CFG_SSID 0x2e +#define PCI_CFG_ROMBAR 0x30 +#define PCI_CFG_CAPPTR 0x34 +#define PCI_CFG_INT 0x3c +#define PCI_CFG_PIN 0x3d +#define PCI_CFG_MINGNT 0x3e +#define PCI_CFG_MAXLAT 0x3f #define PCI_BAR0_WIN 0x80 -#define PCI_INT_STATUS 0x90 -#define PCI_INT_MASK 0x94 - -#define PCIE_EXTCFG_OFFSET 0x100 +#define PCI_BAR1_WIN 0x84 #define PCI_SPROM_CONTROL 0x88 #define PCI_BAR1_CONTROL 0x8c +#define PCI_INT_STATUS 0x90 +#define PCI_INT_MASK 0x94 #define PCI_TO_SB_MB 0x98 #define PCI_BACKPLANE_ADDR 0xa0 #define PCI_BACKPLANE_DATA 0xa4 @@ -55,24 +75,16 @@ #define PCI_BAR0_PCIREGS_OFFSET (6 * 1024) #define PCI_BAR0_PCISBR_OFFSET (4 * 1024) -#define PCI_BAR0_WINSZ (16 * 1024) +#define PCIE2_BAR0_WIN2 0x70 +#define PCIE2_BAR0_CORE2_WIN 0x74 +#define PCIE2_BAR0_CORE2_WIN2 0x78 +#define PCI_BAR0_WINSZ (16 * 1024) #define PCI_16KB0_PCIREGS_OFFSET (8 * 1024) #define PCI_16KB0_CCREGS_OFFSET (12 * 1024) #define PCI_16KBB0_WINSZ (16 * 1024) -#define PCI_16KB0_WIN2_OFFSET (4 * 1024) - - - -#define SPROM_SZ_MSK 0x02 -#define SPROM_LOCKED 0x08 -#define SPROM_BLANK 0x04 -#define SPROM_WRITEEN 0x10 -#define SPROM_BOOTROM_WE 0x20 -#define SPROM_BACKPLANE_EN 0x40 -#define SPROM_OTPIN_USE 0x80 - +#define PCI_CONFIG_SPACE_SIZE 256 #endif diff --git a/drivers/net/wireless/bcmdhd/include/proto/802.11.h b/drivers/net/wireless/bcmdhd/include/proto/802.11.h index fd69aac4130..e367493e9c5 100644 --- a/drivers/net/wireless/bcmdhd/include/proto/802.11.h +++ b/drivers/net/wireless/bcmdhd/include/proto/802.11.h @@ -1,7 +1,7 @@ /* - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,10 +21,9 @@ * * Fundamental types and constants relating to 802.11 * - * $Id: 802.11.h 304058 2011-12-21 00:39:12Z $ + * $Id: 802.11.h 309193 2012-01-19 00:03:57Z $ */ - #ifndef _802_11_H_ #define _802_11_H_ @@ -42,255 +41,261 @@ #include -#define DOT11_TU_TO_US 1024 +#define DOT11_TU_TO_US 1024 -#define DOT11_A3_HDR_LEN 24 -#define DOT11_A4_HDR_LEN 30 -#define DOT11_MAC_HDR_LEN DOT11_A3_HDR_LEN -#define DOT11_FCS_LEN 4 -#define DOT11_ICV_LEN 4 -#define DOT11_ICV_AES_LEN 8 -#define DOT11_QOS_LEN 2 -#define DOT11_HTC_LEN 4 +#define DOT11_A3_HDR_LEN 24 +#define DOT11_A4_HDR_LEN 30 +#define DOT11_MAC_HDR_LEN DOT11_A3_HDR_LEN +#define DOT11_FCS_LEN 4 +#define DOT11_ICV_LEN 4 +#define DOT11_ICV_AES_LEN 8 +#define DOT11_QOS_LEN 2 +#define DOT11_HTC_LEN 4 -#define DOT11_KEY_INDEX_SHIFT 6 -#define DOT11_IV_LEN 4 -#define DOT11_IV_TKIP_LEN 8 -#define DOT11_IV_AES_OCB_LEN 4 -#define DOT11_IV_AES_CCM_LEN 8 -#define DOT11_IV_MAX_LEN 8 +#define DOT11_KEY_INDEX_SHIFT 6 +#define DOT11_IV_LEN 4 +#define DOT11_IV_TKIP_LEN 8 +#define DOT11_IV_AES_OCB_LEN 4 +#define DOT11_IV_AES_CCM_LEN 8 +#define DOT11_IV_MAX_LEN 8 -#define DOT11_MAX_MPDU_BODY_LEN 2304 +#define DOT11_MAX_MPDU_BODY_LEN 2304 -#define DOT11_MAX_MPDU_LEN (DOT11_A4_HDR_LEN + \ +#define DOT11_MAX_MPDU_LEN (DOT11_A4_HDR_LEN + \ DOT11_QOS_LEN + \ DOT11_IV_AES_CCM_LEN + \ DOT11_MAX_MPDU_BODY_LEN + \ DOT11_ICV_LEN + \ - DOT11_FCS_LEN) + DOT11_FCS_LEN) -#define DOT11_MAX_SSID_LEN 32 +#define DOT11_MAX_SSID_LEN 32 -#define DOT11_DEFAULT_RTS_LEN 2347 -#define DOT11_MAX_RTS_LEN 2347 +#define DOT11_DEFAULT_RTS_LEN 2347 +#define DOT11_MAX_RTS_LEN 2347 -#define DOT11_MIN_FRAG_LEN 256 -#define DOT11_MAX_FRAG_LEN 2346 -#define DOT11_DEFAULT_FRAG_LEN 2346 +#define DOT11_MIN_FRAG_LEN 256 +#define DOT11_MAX_FRAG_LEN 2346 +#define DOT11_DEFAULT_FRAG_LEN 2346 -#define DOT11_MIN_BEACON_PERIOD 1 -#define DOT11_MAX_BEACON_PERIOD 0xFFFF +#define DOT11_MIN_BEACON_PERIOD 1 +#define DOT11_MAX_BEACON_PERIOD 0xFFFF -#define DOT11_MIN_DTIM_PERIOD 1 -#define DOT11_MAX_DTIM_PERIOD 0xFF +#define DOT11_MIN_DTIM_PERIOD 1 +#define DOT11_MAX_DTIM_PERIOD 0xFF -#define DOT11_LLC_SNAP_HDR_LEN 8 -#define DOT11_OUI_LEN 3 +#define DOT11_LLC_SNAP_HDR_LEN 8 +#define DOT11_OUI_LEN 3 BWL_PRE_PACKED_STRUCT struct dot11_llc_snap_header { - uint8 dsap; - uint8 ssap; - uint8 ctl; - uint8 oui[DOT11_OUI_LEN]; - uint16 type; + uint8 dsap; + uint8 ssap; + uint8 ctl; + uint8 oui[DOT11_OUI_LEN]; + uint16 type; } BWL_POST_PACKED_STRUCT; -#define RFC1042_HDR_LEN (ETHER_HDR_LEN + DOT11_LLC_SNAP_HDR_LEN) +#define RFC1042_HDR_LEN (ETHER_HDR_LEN + DOT11_LLC_SNAP_HDR_LEN) BWL_PRE_PACKED_STRUCT struct dot11_header { - uint16 fc; - uint16 durid; - struct ether_addr a1; - struct ether_addr a2; - struct ether_addr a3; - uint16 seq; - struct ether_addr a4; + uint16 fc; + uint16 durid; + struct ether_addr a1; + struct ether_addr a2; + struct ether_addr a3; + uint16 seq; + struct ether_addr a4; } BWL_POST_PACKED_STRUCT; BWL_PRE_PACKED_STRUCT struct dot11_rts_frame { - uint16 fc; - uint16 durid; - struct ether_addr ra; - struct ether_addr ta; + uint16 fc; + uint16 durid; + struct ether_addr ra; + struct ether_addr ta; } BWL_POST_PACKED_STRUCT; -#define DOT11_RTS_LEN 16 +#define DOT11_RTS_LEN 16 BWL_PRE_PACKED_STRUCT struct dot11_cts_frame { - uint16 fc; - uint16 durid; - struct ether_addr ra; + uint16 fc; + uint16 durid; + struct ether_addr ra; } BWL_POST_PACKED_STRUCT; -#define DOT11_CTS_LEN 10 +#define DOT11_CTS_LEN 10 BWL_PRE_PACKED_STRUCT struct dot11_ack_frame { - uint16 fc; - uint16 durid; - struct ether_addr ra; + uint16 fc; + uint16 durid; + struct ether_addr ra; } BWL_POST_PACKED_STRUCT; -#define DOT11_ACK_LEN 10 +#define DOT11_ACK_LEN 10 BWL_PRE_PACKED_STRUCT struct dot11_ps_poll_frame { - uint16 fc; - uint16 durid; - struct ether_addr bssid; - struct ether_addr ta; + uint16 fc; + uint16 durid; + struct ether_addr bssid; + struct ether_addr ta; } BWL_POST_PACKED_STRUCT; -#define DOT11_PS_POLL_LEN 16 +#define DOT11_PS_POLL_LEN 16 BWL_PRE_PACKED_STRUCT struct dot11_cf_end_frame { - uint16 fc; - uint16 durid; - struct ether_addr ra; - struct ether_addr bssid; + uint16 fc; + uint16 durid; + struct ether_addr ra; + struct ether_addr bssid; } BWL_POST_PACKED_STRUCT; -#define DOT11_CS_END_LEN 16 +#define DOT11_CS_END_LEN 16 BWL_PRE_PACKED_STRUCT struct dot11_action_wifi_vendor_specific { - uint8 category; - uint8 OUI[3]; - uint8 type; - uint8 subtype; - uint8 data[1040]; + uint8 category; + uint8 OUI[3]; + uint8 type; + uint8 subtype; + uint8 data[1040]; } BWL_POST_PACKED_STRUCT; typedef struct dot11_action_wifi_vendor_specific dot11_action_wifi_vendor_specific_t; BWL_PRE_PACKED_STRUCT struct dot11_action_vs_frmhdr { - uint8 category; - uint8 OUI[3]; - uint8 type; - uint8 subtype; - uint8 data[1]; + uint8 category; + uint8 OUI[3]; + uint8 type; + uint8 subtype; + uint8 data[1]; } BWL_POST_PACKED_STRUCT; typedef struct dot11_action_vs_frmhdr dot11_action_vs_frmhdr_t; -#define DOT11_ACTION_VS_HDR_LEN 6 +#define DOT11_ACTION_VS_HDR_LEN 6 -#define BCM_ACTION_OUI_BYTE0 0x00 -#define BCM_ACTION_OUI_BYTE1 0x90 -#define BCM_ACTION_OUI_BYTE2 0x4c +#define BCM_ACTION_OUI_BYTE0 0x00 +#define BCM_ACTION_OUI_BYTE1 0x90 +#define BCM_ACTION_OUI_BYTE2 0x4c -#define DOT11_BA_CTL_POLICY_NORMAL 0x0000 -#define DOT11_BA_CTL_POLICY_NOACK 0x0001 -#define DOT11_BA_CTL_POLICY_MASK 0x0001 +#define DOT11_BA_CTL_POLICY_NORMAL 0x0000 +#define DOT11_BA_CTL_POLICY_NOACK 0x0001 +#define DOT11_BA_CTL_POLICY_MASK 0x0001 -#define DOT11_BA_CTL_MTID 0x0002 -#define DOT11_BA_CTL_COMPRESSED 0x0004 +#define DOT11_BA_CTL_MTID 0x0002 +#define DOT11_BA_CTL_COMPRESSED 0x0004 -#define DOT11_BA_CTL_NUMMSDU_MASK 0x0FC0 -#define DOT11_BA_CTL_NUMMSDU_SHIFT 6 +#define DOT11_BA_CTL_NUMMSDU_MASK 0x0FC0 +#define DOT11_BA_CTL_NUMMSDU_SHIFT 6 -#define DOT11_BA_CTL_TID_MASK 0xF000 -#define DOT11_BA_CTL_TID_SHIFT 12 +#define DOT11_BA_CTL_TID_MASK 0xF000 +#define DOT11_BA_CTL_TID_SHIFT 12 BWL_PRE_PACKED_STRUCT struct dot11_ctl_header { - uint16 fc; - uint16 durid; - struct ether_addr ra; - struct ether_addr ta; + uint16 fc; + uint16 durid; + struct ether_addr ra; + struct ether_addr ta; } BWL_POST_PACKED_STRUCT; -#define DOT11_CTL_HDR_LEN 16 +#define DOT11_CTL_HDR_LEN 16 BWL_PRE_PACKED_STRUCT struct dot11_bar { - uint16 bar_control; - uint16 seqnum; + uint16 bar_control; + uint16 seqnum; } BWL_POST_PACKED_STRUCT; -#define DOT11_BAR_LEN 4 +#define DOT11_BAR_LEN 4 -#define DOT11_BA_BITMAP_LEN 128 -#define DOT11_BA_CMP_BITMAP_LEN 8 +#define DOT11_BA_BITMAP_LEN 128 +#define DOT11_BA_CMP_BITMAP_LEN 8 BWL_PRE_PACKED_STRUCT struct dot11_ba { - uint16 ba_control; - uint16 seqnum; - uint8 bitmap[DOT11_BA_BITMAP_LEN]; + uint16 ba_control; + uint16 seqnum; + uint8 bitmap[DOT11_BA_BITMAP_LEN]; } BWL_POST_PACKED_STRUCT; -#define DOT11_BA_LEN 4 +#define DOT11_BA_LEN 4 BWL_PRE_PACKED_STRUCT struct dot11_management_header { - uint16 fc; - uint16 durid; - struct ether_addr da; - struct ether_addr sa; - struct ether_addr bssid; - uint16 seq; + uint16 fc; + uint16 durid; + struct ether_addr da; + struct ether_addr sa; + struct ether_addr bssid; + uint16 seq; } BWL_POST_PACKED_STRUCT; -#define DOT11_MGMT_HDR_LEN 24 +#define DOT11_MGMT_HDR_LEN 24 BWL_PRE_PACKED_STRUCT struct dot11_bcn_prb { - uint32 timestamp[2]; - uint16 beacon_interval; - uint16 capability; + uint32 timestamp[2]; + uint16 beacon_interval; + uint16 capability; } BWL_POST_PACKED_STRUCT; -#define DOT11_BCN_PRB_LEN 12 -#define DOT11_BCN_PRB_FIXED_LEN 12 +#define DOT11_BCN_PRB_LEN 12 +#define DOT11_BCN_PRB_FIXED_LEN 12 BWL_PRE_PACKED_STRUCT struct dot11_auth { - uint16 alg; - uint16 seq; - uint16 status; + uint16 alg; + uint16 seq; + uint16 status; } BWL_POST_PACKED_STRUCT; -#define DOT11_AUTH_FIXED_LEN 6 +#define DOT11_AUTH_FIXED_LEN 6 BWL_PRE_PACKED_STRUCT struct dot11_assoc_req { - uint16 capability; - uint16 listen; + uint16 capability; + uint16 listen; } BWL_POST_PACKED_STRUCT; -#define DOT11_ASSOC_REQ_FIXED_LEN 4 +#define DOT11_ASSOC_REQ_FIXED_LEN 4 BWL_PRE_PACKED_STRUCT struct dot11_reassoc_req { - uint16 capability; - uint16 listen; - struct ether_addr ap; + uint16 capability; + uint16 listen; + struct ether_addr ap; } BWL_POST_PACKED_STRUCT; -#define DOT11_REASSOC_REQ_FIXED_LEN 10 +#define DOT11_REASSOC_REQ_FIXED_LEN 10 BWL_PRE_PACKED_STRUCT struct dot11_assoc_resp { - uint16 capability; - uint16 status; - uint16 aid; + uint16 capability; + uint16 status; + uint16 aid; } BWL_POST_PACKED_STRUCT; -#define DOT11_ASSOC_RESP_FIXED_LEN 6 +#define DOT11_ASSOC_RESP_FIXED_LEN 6 BWL_PRE_PACKED_STRUCT struct dot11_action_measure { - uint8 category; - uint8 action; - uint8 token; - uint8 data[1]; + uint8 category; + uint8 action; + uint8 token; + uint8 data[1]; } BWL_POST_PACKED_STRUCT; -#define DOT11_ACTION_MEASURE_LEN 3 +#define DOT11_ACTION_MEASURE_LEN 3 BWL_PRE_PACKED_STRUCT struct dot11_action_ht_ch_width { - uint8 category; - uint8 action; - uint8 ch_width; + uint8 category; + uint8 action; + uint8 ch_width; } BWL_POST_PACKED_STRUCT; BWL_PRE_PACKED_STRUCT struct dot11_action_ht_mimops { - uint8 category; - uint8 action; - uint8 control; + uint8 category; + uint8 action; + uint8 control; +} BWL_POST_PACKED_STRUCT; + +BWL_PRE_PACKED_STRUCT struct dot11_action_sa_query { + uint8 category; + uint8 action; + uint16 id; } BWL_POST_PACKED_STRUCT; -#define SM_PWRSAVE_ENABLE 1 -#define SM_PWRSAVE_MODE 2 +#define SM_PWRSAVE_ENABLE 1 +#define SM_PWRSAVE_MODE 2 BWL_PRE_PACKED_STRUCT struct dot11_power_cnst { @@ -313,7 +318,7 @@ BWL_PRE_PACKED_STRUCT struct dot11_tpc_rep { uint8 margin; } BWL_POST_PACKED_STRUCT; typedef struct dot11_tpc_rep dot11_tpc_rep_t; -#define DOT11_MNG_IE_TPC_REPORT_LEN 2 +#define DOT11_MNG_IE_TPC_REPORT_LEN 2 BWL_PRE_PACKED_STRUCT struct dot11_supp_channels { uint8 id; @@ -325,106 +330,106 @@ typedef struct dot11_supp_channels dot11_supp_channels_t; BWL_PRE_PACKED_STRUCT struct dot11_extch { - uint8 id; - uint8 len; - uint8 extch; + uint8 id; + uint8 len; + uint8 extch; } BWL_POST_PACKED_STRUCT; typedef struct dot11_extch dot11_extch_ie_t; BWL_PRE_PACKED_STRUCT struct dot11_brcm_extch { - uint8 id; - uint8 len; - uint8 oui[3]; - uint8 type; - uint8 extch; + uint8 id; + uint8 len; + uint8 oui[3]; + uint8 type; + uint8 extch; } BWL_POST_PACKED_STRUCT; typedef struct dot11_brcm_extch dot11_brcm_extch_ie_t; -#define BRCM_EXTCH_IE_LEN 5 -#define BRCM_EXTCH_IE_TYPE 53 -#define DOT11_EXTCH_IE_LEN 1 -#define DOT11_EXT_CH_MASK 0x03 -#define DOT11_EXT_CH_UPPER 0x01 -#define DOT11_EXT_CH_LOWER 0x03 -#define DOT11_EXT_CH_NONE 0x00 +#define BRCM_EXTCH_IE_LEN 5 +#define BRCM_EXTCH_IE_TYPE 53 +#define DOT11_EXTCH_IE_LEN 1 +#define DOT11_EXT_CH_MASK 0x03 +#define DOT11_EXT_CH_UPPER 0x01 +#define DOT11_EXT_CH_LOWER 0x03 +#define DOT11_EXT_CH_NONE 0x00 BWL_PRE_PACKED_STRUCT struct dot11_action_frmhdr { - uint8 category; - uint8 action; - uint8 data[1]; + uint8 category; + uint8 action; + uint8 data[1]; } BWL_POST_PACKED_STRUCT; -#define DOT11_ACTION_FRMHDR_LEN 2 +#define DOT11_ACTION_FRMHDR_LEN 2 BWL_PRE_PACKED_STRUCT struct dot11_channel_switch { - uint8 id; - uint8 len; - uint8 mode; - uint8 channel; - uint8 count; + uint8 id; + uint8 len; + uint8 mode; + uint8 channel; + uint8 count; } BWL_POST_PACKED_STRUCT; typedef struct dot11_channel_switch dot11_chan_switch_ie_t; -#define DOT11_SWITCH_IE_LEN 3 +#define DOT11_SWITCH_IE_LEN 3 -#define DOT11_CSA_MODE_ADVISORY 0 -#define DOT11_CSA_MODE_NO_TX 1 +#define DOT11_CSA_MODE_ADVISORY 0 +#define DOT11_CSA_MODE_NO_TX 1 BWL_PRE_PACKED_STRUCT struct dot11_action_switch_channel { - uint8 category; - uint8 action; - dot11_chan_switch_ie_t chan_switch_ie; - dot11_brcm_extch_ie_t extch_ie; + uint8 category; + uint8 action; + dot11_chan_switch_ie_t chan_switch_ie; + dot11_brcm_extch_ie_t extch_ie; } BWL_POST_PACKED_STRUCT; BWL_PRE_PACKED_STRUCT struct dot11_csa_body { - uint8 mode; - uint8 reg; - uint8 channel; - uint8 count; + uint8 mode; + uint8 reg; + uint8 channel; + uint8 count; } BWL_POST_PACKED_STRUCT; BWL_PRE_PACKED_STRUCT struct dot11_ext_csa { - uint8 id; - uint8 len; - struct dot11_csa_body b; + uint8 id; + uint8 len; + struct dot11_csa_body b; } BWL_POST_PACKED_STRUCT; typedef struct dot11_ext_csa dot11_ext_csa_ie_t; -#define DOT11_EXT_CSA_IE_LEN 4 +#define DOT11_EXT_CSA_IE_LEN 4 BWL_PRE_PACKED_STRUCT struct dot11_action_ext_csa { - uint8 category; - uint8 action; - dot11_ext_csa_ie_t chan_switch_ie; + uint8 category; + uint8 action; + dot11_ext_csa_ie_t chan_switch_ie; } BWL_POST_PACKED_STRUCT; BWL_PRE_PACKED_STRUCT struct dot11y_action_ext_csa { - uint8 category; - uint8 action; - struct dot11_csa_body b; + uint8 category; + uint8 action; + struct dot11_csa_body b; } BWL_POST_PACKED_STRUCT; BWL_PRE_PACKED_STRUCT struct dot11_obss_coex { - uint8 id; - uint8 len; - uint8 info; + uint8 id; + uint8 len; + uint8 info; } BWL_POST_PACKED_STRUCT; typedef struct dot11_obss_coex dot11_obss_coex_t; -#define DOT11_OBSS_COEXINFO_LEN 1 +#define DOT11_OBSS_COEXINFO_LEN 1 -#define DOT11_OBSS_COEX_INFO_REQ 0x01 -#define DOT11_OBSS_COEX_40MHZ_INTOLERANT 0x02 -#define DOT11_OBSS_COEX_20MHZ_WIDTH_REQ 0x04 +#define DOT11_OBSS_COEX_INFO_REQ 0x01 +#define DOT11_OBSS_COEX_40MHZ_INTOLERANT 0x02 +#define DOT11_OBSS_COEX_20MHZ_WIDTH_REQ 0x04 BWL_PRE_PACKED_STRUCT struct dot11_obss_chanlist { - uint8 id; - uint8 len; - uint8 regclass; - uint8 chanlist[1]; + uint8 id; + uint8 len; + uint8 regclass; + uint8 chanlist[1]; } BWL_POST_PACKED_STRUCT; typedef struct dot11_obss_chanlist dot11_obss_chanlist_t; -#define DOT11_OBSS_CHANLIST_FIXED_LEN 1 +#define DOT11_OBSS_CHANLIST_FIXED_LEN 1 BWL_PRE_PACKED_STRUCT struct dot11_extcap_ie { uint8 id; @@ -432,9 +437,14 @@ BWL_PRE_PACKED_STRUCT struct dot11_extcap_ie { uint8 cap[1]; } BWL_POST_PACKED_STRUCT; typedef struct dot11_extcap_ie dot11_extcap_ie_t; -#define DOT11_EXTCAP_LEN 1 -#define DOT11_EXTCAP_LEN_TDLS 5 +#define DOT11_EXTCAP_LEN_MAX 7 +#define DOT11_EXTCAP_LEN_COEX 1 +#define DOT11_EXTCAP_LEN_BT 3 +#define DOT11_EXTCAP_LEN_IW 4 +#define DOT11_EXTCAP_LEN_SI 6 + +#define DOT11_EXTCAP_LEN_TDLS 5 BWL_PRE_PACKED_STRUCT struct dot11_extcap { uint8 extcap[DOT11_EXTCAP_LEN_TDLS]; } BWL_POST_PACKED_STRUCT; @@ -452,34 +462,34 @@ typedef struct dot11_extcap dot11_extcap_t; -#define DOT11_MEASURE_TYPE_BASIC 0 -#define DOT11_MEASURE_TYPE_CCA 1 -#define DOT11_MEASURE_TYPE_RPI 2 -#define DOT11_MEASURE_TYPE_CHLOAD 3 -#define DOT11_MEASURE_TYPE_NOISE 4 -#define DOT11_MEASURE_TYPE_BEACON 5 -#define DOT11_MEASURE_TYPE_FRAME 6 -#define DOT11_MEASURE_TYPE_STATS 7 -#define DOT11_MEASURE_TYPE_LCI 8 -#define DOT11_MEASURE_TYPE_TXSTREAM 9 -#define DOT11_MEASURE_TYPE_PAUSE 255 +#define DOT11_MEASURE_TYPE_BASIC 0 +#define DOT11_MEASURE_TYPE_CCA 1 +#define DOT11_MEASURE_TYPE_RPI 2 +#define DOT11_MEASURE_TYPE_CHLOAD 3 +#define DOT11_MEASURE_TYPE_NOISE 4 +#define DOT11_MEASURE_TYPE_BEACON 5 +#define DOT11_MEASURE_TYPE_FRAME 6 +#define DOT11_MEASURE_TYPE_STATS 7 +#define DOT11_MEASURE_TYPE_LCI 8 +#define DOT11_MEASURE_TYPE_TXSTREAM 9 +#define DOT11_MEASURE_TYPE_PAUSE 255 -#define DOT11_MEASURE_MODE_PARALLEL (1<<0) -#define DOT11_MEASURE_MODE_ENABLE (1<<1) -#define DOT11_MEASURE_MODE_REQUEST (1<<2) -#define DOT11_MEASURE_MODE_REPORT (1<<3) -#define DOT11_MEASURE_MODE_DUR (1<<4) +#define DOT11_MEASURE_MODE_PARALLEL (1<<0) +#define DOT11_MEASURE_MODE_ENABLE (1<<1) +#define DOT11_MEASURE_MODE_REQUEST (1<<2) +#define DOT11_MEASURE_MODE_REPORT (1<<3) +#define DOT11_MEASURE_MODE_DUR (1<<4) -#define DOT11_MEASURE_MODE_LATE (1<<0) -#define DOT11_MEASURE_MODE_INCAPABLE (1<<1) -#define DOT11_MEASURE_MODE_REFUSED (1<<2) +#define DOT11_MEASURE_MODE_LATE (1<<0) +#define DOT11_MEASURE_MODE_INCAPABLE (1<<1) +#define DOT11_MEASURE_MODE_REFUSED (1<<2) -#define DOT11_MEASURE_BASIC_MAP_BSS ((uint8)(1<<0)) -#define DOT11_MEASURE_BASIC_MAP_OFDM ((uint8)(1<<1)) -#define DOT11_MEASURE_BASIC_MAP_UKNOWN ((uint8)(1<<2)) -#define DOT11_MEASURE_BASIC_MAP_RADAR ((uint8)(1<<3)) -#define DOT11_MEASURE_BASIC_MAP_UNMEAS ((uint8)(1<<4)) +#define DOT11_MEASURE_BASIC_MAP_BSS ((uint8)(1<<0)) +#define DOT11_MEASURE_BASIC_MAP_OFDM ((uint8)(1<<1)) +#define DOT11_MEASURE_BASIC_MAP_UKNOWN ((uint8)(1<<2)) +#define DOT11_MEASURE_BASIC_MAP_RADAR ((uint8)(1<<3)) +#define DOT11_MEASURE_BASIC_MAP_UNMEAS ((uint8)(1<<4)) BWL_PRE_PACKED_STRUCT struct dot11_meas_req { uint8 id; @@ -492,9 +502,9 @@ BWL_PRE_PACKED_STRUCT struct dot11_meas_req { uint16 duration; } BWL_POST_PACKED_STRUCT; typedef struct dot11_meas_req dot11_meas_req_t; -#define DOT11_MNG_IE_MREQ_LEN 14 +#define DOT11_MNG_IE_MREQ_LEN 14 -#define DOT11_MNG_IE_MREQ_FIXED_LEN 3 +#define DOT11_MNG_IE_MREQ_FIXED_LEN 3 BWL_PRE_PACKED_STRUCT struct dot11_meas_rep { uint8 id; @@ -516,7 +526,7 @@ BWL_PRE_PACKED_STRUCT struct dot11_meas_rep { typedef struct dot11_meas_rep dot11_meas_rep_t; -#define DOT11_MNG_IE_MREP_FIXED_LEN 3 +#define DOT11_MNG_IE_MREP_FIXED_LEN 3 BWL_PRE_PACKED_STRUCT struct dot11_meas_rep_basic { uint8 channel; @@ -525,15 +535,15 @@ BWL_PRE_PACKED_STRUCT struct dot11_meas_rep_basic { uint8 map; } BWL_POST_PACKED_STRUCT; typedef struct dot11_meas_rep_basic dot11_meas_rep_basic_t; -#define DOT11_MEASURE_BASIC_REP_LEN 12 +#define DOT11_MEASURE_BASIC_REP_LEN 12 BWL_PRE_PACKED_STRUCT struct dot11_quiet { uint8 id; uint8 len; - uint8 count; - uint8 period; - uint16 duration; - uint16 offset; + uint8 count; + uint8 period; + uint16 duration; + uint16 offset; } BWL_POST_PACKED_STRUCT; typedef struct dot11_quiet dot11_quiet_t; @@ -553,31 +563,28 @@ BWL_PRE_PACKED_STRUCT struct dot11_ibss_dfs { typedef struct dot11_ibss_dfs dot11_ibss_dfs_t; -#define WME_OUI "\x00\x50\xf2" -#define WME_OUI_LEN 3 -#define WME_OUI_TYPE 2 -#define WME_VER 1 -#define WME_TYPE 2 -#define WME_SUBTYPE_IE 0 -#define WME_SUBTYPE_PARAM_IE 1 -#define WME_SUBTYPE_TSPEC 2 -#define WME_VERSION_LEN 1 -#define WME_PARAMETER_IE_LEN 24 +#define WME_OUI "\x00\x50\xf2" +#define WME_OUI_LEN 3 +#define WME_OUI_TYPE 2 +#define WME_TYPE 2 +#define WME_SUBTYPE_IE 0 +#define WME_SUBTYPE_PARAM_IE 1 +#define WME_SUBTYPE_TSPEC 2 +#define WME_VER 1 +#define AC_BE 0 +#define AC_BK 1 +#define AC_VI 2 +#define AC_VO 3 +#define AC_COUNT 4 -#define AC_BE 0 -#define AC_BK 1 -#define AC_VI 2 -#define AC_VO 3 -#define AC_COUNT 4 +typedef uint8 ac_bitmap_t; -typedef uint8 ac_bitmap_t; - -#define AC_BITMAP_NONE 0x0 -#define AC_BITMAP_ALL 0xf -#define AC_BITMAP_TST(ab, ac) (((ab) & (1 << (ac))) != 0) -#define AC_BITMAP_SET(ab, ac) (((ab) |= (1 << (ac)))) +#define AC_BITMAP_NONE 0x0 +#define AC_BITMAP_ALL 0xf +#define AC_BITMAP_TST(ab, ac) (((ab) & (1 << (ac))) != 0) +#define AC_BITMAP_SET(ab, ac) (((ab) |= (1 << (ac)))) #define AC_BITMAP_RESET(ab, ac) (((ab) &= ~(1 << (ac)))) @@ -589,12 +596,12 @@ BWL_PRE_PACKED_STRUCT struct wme_ie { uint8 qosinfo; } BWL_POST_PACKED_STRUCT; typedef struct wme_ie wme_ie_t; -#define WME_IE_LEN 7 +#define WME_IE_LEN 7 BWL_PRE_PACKED_STRUCT struct edcf_acparam { - uint8 ACI; - uint8 ECW; - uint16 TXOP; + uint8 ACI; + uint8 ECW; + uint16 TXOP; } BWL_POST_PACKED_STRUCT; typedef struct edcf_acparam edcf_acparam_t; @@ -657,32 +664,32 @@ typedef struct wme_param_ie wme_param_ie_t; #define NON_EDCF_AC_BE_ACI_STA 0x02 -#define EDCF_AC_BE_ACI_STA 0x03 -#define EDCF_AC_BE_ECW_STA 0xA4 -#define EDCF_AC_BE_TXOP_STA 0x0000 -#define EDCF_AC_BK_ACI_STA 0x27 -#define EDCF_AC_BK_ECW_STA 0xA4 -#define EDCF_AC_BK_TXOP_STA 0x0000 -#define EDCF_AC_VI_ACI_STA 0x42 -#define EDCF_AC_VI_ECW_STA 0x43 -#define EDCF_AC_VI_TXOP_STA 0x005e -#define EDCF_AC_VO_ACI_STA 0x62 -#define EDCF_AC_VO_ECW_STA 0x32 -#define EDCF_AC_VO_TXOP_STA 0x002f - - -#define EDCF_AC_BE_ACI_AP 0x03 -#define EDCF_AC_BE_ECW_AP 0x64 -#define EDCF_AC_BE_TXOP_AP 0x0000 -#define EDCF_AC_BK_ACI_AP 0x27 -#define EDCF_AC_BK_ECW_AP 0xA4 -#define EDCF_AC_BK_TXOP_AP 0x0000 -#define EDCF_AC_VI_ACI_AP 0x41 -#define EDCF_AC_VI_ECW_AP 0x43 -#define EDCF_AC_VI_TXOP_AP 0x005e -#define EDCF_AC_VO_ACI_AP 0x61 -#define EDCF_AC_VO_ECW_AP 0x32 -#define EDCF_AC_VO_TXOP_AP 0x002f +#define EDCF_AC_BE_ACI_STA 0x03 +#define EDCF_AC_BE_ECW_STA 0xA4 +#define EDCF_AC_BE_TXOP_STA 0x0000 +#define EDCF_AC_BK_ACI_STA 0x27 +#define EDCF_AC_BK_ECW_STA 0xA4 +#define EDCF_AC_BK_TXOP_STA 0x0000 +#define EDCF_AC_VI_ACI_STA 0x42 +#define EDCF_AC_VI_ECW_STA 0x43 +#define EDCF_AC_VI_TXOP_STA 0x005e +#define EDCF_AC_VO_ACI_STA 0x62 +#define EDCF_AC_VO_ECW_STA 0x32 +#define EDCF_AC_VO_TXOP_STA 0x002f + + +#define EDCF_AC_BE_ACI_AP 0x03 +#define EDCF_AC_BE_ECW_AP 0x64 +#define EDCF_AC_BE_TXOP_AP 0x0000 +#define EDCF_AC_BK_ACI_AP 0x27 +#define EDCF_AC_BK_ECW_AP 0xA4 +#define EDCF_AC_BK_TXOP_AP 0x0000 +#define EDCF_AC_VI_ACI_AP 0x41 +#define EDCF_AC_VI_ECW_AP 0x43 +#define EDCF_AC_VI_TXOP_AP 0x005e +#define EDCF_AC_VO_ACI_AP 0x61 +#define EDCF_AC_VO_ECW_AP 0x32 +#define EDCF_AC_VO_TXOP_AP 0x002f BWL_PRE_PACKED_STRUCT struct edca_param_ie { @@ -700,32 +707,33 @@ BWL_PRE_PACKED_STRUCT struct qos_cap_ie { typedef struct qos_cap_ie qos_cap_ie_t; BWL_PRE_PACKED_STRUCT struct dot11_qbss_load_ie { - uint8 id; + uint8 id; uint8 length; - uint16 station_count; - uint8 channel_utilization; - uint16 aac; + uint16 station_count; + uint8 channel_utilization; + uint16 aac; } BWL_POST_PACKED_STRUCT; typedef struct dot11_qbss_load_ie dot11_qbss_load_ie_t; +#define BSS_LOAD_IE_SIZE 7 -#define FIXED_MSDU_SIZE 0x8000 -#define MSDU_SIZE_MASK 0x7fff +#define FIXED_MSDU_SIZE 0x8000 +#define MSDU_SIZE_MASK 0x7fff -#define INTEGER_SHIFT 13 -#define FRACTION_MASK 0x1FFF +#define INTEGER_SHIFT 13 +#define FRACTION_MASK 0x1FFF BWL_PRE_PACKED_STRUCT struct dot11_management_notification { - uint8 category; + uint8 category; uint8 action; uint8 token; uint8 status; - uint8 data[1]; + uint8 data[1]; } BWL_POST_PACKED_STRUCT; -#define DOT11_MGMT_NOTIFICATION_LEN 4 +#define DOT11_MGMT_NOTIFICATION_LEN 4 BWL_PRE_PACKED_STRUCT struct ti_ie { @@ -737,252 +745,252 @@ typedef struct ti_ie ti_ie_t; #define TI_TYPE_KEY_LIFETIME 2 -#define WME_ADDTS_REQUEST 0 -#define WME_ADDTS_RESPONSE 1 -#define WME_DELTS_REQUEST 2 +#define WME_ADDTS_REQUEST 0 +#define WME_ADDTS_RESPONSE 1 +#define WME_DELTS_REQUEST 2 -#define WME_ADMISSION_ACCEPTED 0 -#define WME_INVALID_PARAMETERS 1 -#define WME_ADMISSION_REFUSED 3 +#define WME_ADMISSION_ACCEPTED 0 +#define WME_INVALID_PARAMETERS 1 +#define WME_ADMISSION_REFUSED 3 #define BCN_PRB_SSID(body) ((char*)(body) + DOT11_BCN_PRB_LEN) -#define DOT11_OPEN_SYSTEM 0 -#define DOT11_SHARED_KEY 1 +#define DOT11_OPEN_SYSTEM 0 +#define DOT11_SHARED_KEY 1 #define DOT11_FAST_BSS 2 -#define DOT11_CHALLENGE_LEN 128 - - -#define FC_PVER_MASK 0x3 -#define FC_PVER_SHIFT 0 -#define FC_TYPE_MASK 0xC -#define FC_TYPE_SHIFT 2 -#define FC_SUBTYPE_MASK 0xF0 -#define FC_SUBTYPE_SHIFT 4 -#define FC_TODS 0x100 -#define FC_TODS_SHIFT 8 -#define FC_FROMDS 0x200 -#define FC_FROMDS_SHIFT 9 -#define FC_MOREFRAG 0x400 -#define FC_MOREFRAG_SHIFT 10 -#define FC_RETRY 0x800 -#define FC_RETRY_SHIFT 11 -#define FC_PM 0x1000 -#define FC_PM_SHIFT 12 -#define FC_MOREDATA 0x2000 -#define FC_MOREDATA_SHIFT 13 -#define FC_WEP 0x4000 -#define FC_WEP_SHIFT 14 -#define FC_ORDER 0x8000 -#define FC_ORDER_SHIFT 15 - - -#define SEQNUM_SHIFT 4 -#define SEQNUM_MAX 0x1000 -#define FRAGNUM_MASK 0xF - - - - -#define FC_TYPE_MNG 0 -#define FC_TYPE_CTL 1 -#define FC_TYPE_DATA 2 - - -#define FC_SUBTYPE_ASSOC_REQ 0 -#define FC_SUBTYPE_ASSOC_RESP 1 -#define FC_SUBTYPE_REASSOC_REQ 2 -#define FC_SUBTYPE_REASSOC_RESP 3 -#define FC_SUBTYPE_PROBE_REQ 4 -#define FC_SUBTYPE_PROBE_RESP 5 -#define FC_SUBTYPE_BEACON 8 -#define FC_SUBTYPE_ATIM 9 -#define FC_SUBTYPE_DISASSOC 10 -#define FC_SUBTYPE_AUTH 11 -#define FC_SUBTYPE_DEAUTH 12 -#define FC_SUBTYPE_ACTION 13 -#define FC_SUBTYPE_ACTION_NOACK 14 - - -#define FC_SUBTYPE_CTL_WRAPPER 7 -#define FC_SUBTYPE_BLOCKACK_REQ 8 -#define FC_SUBTYPE_BLOCKACK 9 -#define FC_SUBTYPE_PS_POLL 10 -#define FC_SUBTYPE_RTS 11 -#define FC_SUBTYPE_CTS 12 -#define FC_SUBTYPE_ACK 13 -#define FC_SUBTYPE_CF_END 14 -#define FC_SUBTYPE_CF_END_ACK 15 +#define DOT11_CHALLENGE_LEN 128 + + +#define FC_PVER_MASK 0x3 +#define FC_PVER_SHIFT 0 +#define FC_TYPE_MASK 0xC +#define FC_TYPE_SHIFT 2 +#define FC_SUBTYPE_MASK 0xF0 +#define FC_SUBTYPE_SHIFT 4 +#define FC_TODS 0x100 +#define FC_TODS_SHIFT 8 +#define FC_FROMDS 0x200 +#define FC_FROMDS_SHIFT 9 +#define FC_MOREFRAG 0x400 +#define FC_MOREFRAG_SHIFT 10 +#define FC_RETRY 0x800 +#define FC_RETRY_SHIFT 11 +#define FC_PM 0x1000 +#define FC_PM_SHIFT 12 +#define FC_MOREDATA 0x2000 +#define FC_MOREDATA_SHIFT 13 +#define FC_WEP 0x4000 +#define FC_WEP_SHIFT 14 +#define FC_ORDER 0x8000 +#define FC_ORDER_SHIFT 15 + + +#define SEQNUM_SHIFT 4 +#define SEQNUM_MAX 0x1000 +#define FRAGNUM_MASK 0xF + + + + +#define FC_TYPE_MNG 0 +#define FC_TYPE_CTL 1 +#define FC_TYPE_DATA 2 + + +#define FC_SUBTYPE_ASSOC_REQ 0 +#define FC_SUBTYPE_ASSOC_RESP 1 +#define FC_SUBTYPE_REASSOC_REQ 2 +#define FC_SUBTYPE_REASSOC_RESP 3 +#define FC_SUBTYPE_PROBE_REQ 4 +#define FC_SUBTYPE_PROBE_RESP 5 +#define FC_SUBTYPE_BEACON 8 +#define FC_SUBTYPE_ATIM 9 +#define FC_SUBTYPE_DISASSOC 10 +#define FC_SUBTYPE_AUTH 11 +#define FC_SUBTYPE_DEAUTH 12 +#define FC_SUBTYPE_ACTION 13 +#define FC_SUBTYPE_ACTION_NOACK 14 + + +#define FC_SUBTYPE_CTL_WRAPPER 7 +#define FC_SUBTYPE_BLOCKACK_REQ 8 +#define FC_SUBTYPE_BLOCKACK 9 +#define FC_SUBTYPE_PS_POLL 10 +#define FC_SUBTYPE_RTS 11 +#define FC_SUBTYPE_CTS 12 +#define FC_SUBTYPE_ACK 13 +#define FC_SUBTYPE_CF_END 14 +#define FC_SUBTYPE_CF_END_ACK 15 -#define FC_SUBTYPE_DATA 0 -#define FC_SUBTYPE_DATA_CF_ACK 1 -#define FC_SUBTYPE_DATA_CF_POLL 2 -#define FC_SUBTYPE_DATA_CF_ACK_POLL 3 -#define FC_SUBTYPE_NULL 4 -#define FC_SUBTYPE_CF_ACK 5 -#define FC_SUBTYPE_CF_POLL 6 -#define FC_SUBTYPE_CF_ACK_POLL 7 -#define FC_SUBTYPE_QOS_DATA 8 -#define FC_SUBTYPE_QOS_DATA_CF_ACK 9 -#define FC_SUBTYPE_QOS_DATA_CF_POLL 10 -#define FC_SUBTYPE_QOS_DATA_CF_ACK_POLL 11 -#define FC_SUBTYPE_QOS_NULL 12 -#define FC_SUBTYPE_QOS_CF_POLL 14 -#define FC_SUBTYPE_QOS_CF_ACK_POLL 15 +#define FC_SUBTYPE_DATA 0 +#define FC_SUBTYPE_DATA_CF_ACK 1 +#define FC_SUBTYPE_DATA_CF_POLL 2 +#define FC_SUBTYPE_DATA_CF_ACK_POLL 3 +#define FC_SUBTYPE_NULL 4 +#define FC_SUBTYPE_CF_ACK 5 +#define FC_SUBTYPE_CF_POLL 6 +#define FC_SUBTYPE_CF_ACK_POLL 7 +#define FC_SUBTYPE_QOS_DATA 8 +#define FC_SUBTYPE_QOS_DATA_CF_ACK 9 +#define FC_SUBTYPE_QOS_DATA_CF_POLL 10 +#define FC_SUBTYPE_QOS_DATA_CF_ACK_POLL 11 +#define FC_SUBTYPE_QOS_NULL 12 +#define FC_SUBTYPE_QOS_CF_POLL 14 +#define FC_SUBTYPE_QOS_CF_ACK_POLL 15 -#define FC_SUBTYPE_ANY_QOS(s) (((s) & 8) != 0) -#define FC_SUBTYPE_ANY_NULL(s) (((s) & 4) != 0) -#define FC_SUBTYPE_ANY_CF_POLL(s) (((s) & 2) != 0) -#define FC_SUBTYPE_ANY_CF_ACK(s) (((s) & 1) != 0) +#define FC_SUBTYPE_ANY_QOS(s) (((s) & 8) != 0) +#define FC_SUBTYPE_ANY_NULL(s) (((s) & 4) != 0) +#define FC_SUBTYPE_ANY_CF_POLL(s) (((s) & 2) != 0) +#define FC_SUBTYPE_ANY_CF_ACK(s) (((s) & 1) != 0) -#define FC_KIND_MASK (FC_TYPE_MASK | FC_SUBTYPE_MASK) +#define FC_KIND_MASK (FC_TYPE_MASK | FC_SUBTYPE_MASK) -#define FC_KIND(t, s) (((t) << FC_TYPE_SHIFT) | ((s) << FC_SUBTYPE_SHIFT)) +#define FC_KIND(t, s) (((t) << FC_TYPE_SHIFT) | ((s) << FC_SUBTYPE_SHIFT)) -#define FC_SUBTYPE(fc) (((fc) & FC_SUBTYPE_MASK) >> FC_SUBTYPE_SHIFT) -#define FC_TYPE(fc) (((fc) & FC_TYPE_MASK) >> FC_TYPE_SHIFT) +#define FC_SUBTYPE(fc) (((fc) & FC_SUBTYPE_MASK) >> FC_SUBTYPE_SHIFT) +#define FC_TYPE(fc) (((fc) & FC_TYPE_MASK) >> FC_TYPE_SHIFT) -#define FC_ASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_REQ) -#define FC_ASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_RESP) -#define FC_REASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_REQ) -#define FC_REASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_RESP) -#define FC_PROBE_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_REQ) -#define FC_PROBE_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_RESP) -#define FC_BEACON FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_BEACON) -#define FC_DISASSOC FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DISASSOC) -#define FC_AUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_AUTH) -#define FC_DEAUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DEAUTH) -#define FC_ACTION FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ACTION) -#define FC_ACTION_NOACK FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ACTION_NOACK) +#define FC_ASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_REQ) +#define FC_ASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_RESP) +#define FC_REASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_REQ) +#define FC_REASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_RESP) +#define FC_PROBE_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_REQ) +#define FC_PROBE_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_RESP) +#define FC_BEACON FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_BEACON) +#define FC_DISASSOC FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DISASSOC) +#define FC_AUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_AUTH) +#define FC_DEAUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DEAUTH) +#define FC_ACTION FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ACTION) +#define FC_ACTION_NOACK FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ACTION_NOACK) -#define FC_CTL_WRAPPER FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CTL_WRAPPER) -#define FC_BLOCKACK_REQ FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_BLOCKACK_REQ) -#define FC_BLOCKACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_BLOCKACK) -#define FC_PS_POLL FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_PS_POLL) -#define FC_RTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_RTS) -#define FC_CTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CTS) -#define FC_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_ACK) -#define FC_CF_END FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END) -#define FC_CF_END_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END_ACK) +#define FC_CTL_WRAPPER FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CTL_WRAPPER) +#define FC_BLOCKACK_REQ FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_BLOCKACK_REQ) +#define FC_BLOCKACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_BLOCKACK) +#define FC_PS_POLL FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_PS_POLL) +#define FC_RTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_RTS) +#define FC_CTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CTS) +#define FC_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_ACK) +#define FC_CF_END FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END) +#define FC_CF_END_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END_ACK) -#define FC_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA) -#define FC_NULL_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_NULL) -#define FC_DATA_CF_ACK FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA_CF_ACK) -#define FC_QOS_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_DATA) -#define FC_QOS_NULL FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_NULL) +#define FC_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA) +#define FC_NULL_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_NULL) +#define FC_DATA_CF_ACK FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA_CF_ACK) +#define FC_QOS_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_DATA) +#define FC_QOS_NULL FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_NULL) -#define QOS_PRIO_SHIFT 0 -#define QOS_PRIO_MASK 0x0007 -#define QOS_PRIO(qos) (((qos) & QOS_PRIO_MASK) >> QOS_PRIO_SHIFT) +#define QOS_PRIO_SHIFT 0 +#define QOS_PRIO_MASK 0x0007 +#define QOS_PRIO(qos) (((qos) & QOS_PRIO_MASK) >> QOS_PRIO_SHIFT) -#define QOS_TID_SHIFT 0 -#define QOS_TID_MASK 0x000f -#define QOS_TID(qos) (((qos) & QOS_TID_MASK) >> QOS_TID_SHIFT) +#define QOS_TID_SHIFT 0 +#define QOS_TID_MASK 0x000f +#define QOS_TID(qos) (((qos) & QOS_TID_MASK) >> QOS_TID_SHIFT) -#define QOS_EOSP_SHIFT 4 -#define QOS_EOSP_MASK 0x0010 -#define QOS_EOSP(qos) (((qos) & QOS_EOSP_MASK) >> QOS_EOSP_SHIFT) +#define QOS_EOSP_SHIFT 4 +#define QOS_EOSP_MASK 0x0010 +#define QOS_EOSP(qos) (((qos) & QOS_EOSP_MASK) >> QOS_EOSP_SHIFT) -#define QOS_ACK_NORMAL_ACK 0 -#define QOS_ACK_NO_ACK 1 -#define QOS_ACK_NO_EXP_ACK 2 -#define QOS_ACK_BLOCK_ACK 3 -#define QOS_ACK_SHIFT 5 -#define QOS_ACK_MASK 0x0060 -#define QOS_ACK(qos) (((qos) & QOS_ACK_MASK) >> QOS_ACK_SHIFT) +#define QOS_ACK_NORMAL_ACK 0 +#define QOS_ACK_NO_ACK 1 +#define QOS_ACK_NO_EXP_ACK 2 +#define QOS_ACK_BLOCK_ACK 3 +#define QOS_ACK_SHIFT 5 +#define QOS_ACK_MASK 0x0060 +#define QOS_ACK(qos) (((qos) & QOS_ACK_MASK) >> QOS_ACK_SHIFT) -#define QOS_AMSDU_SHIFT 7 -#define QOS_AMSDU_MASK 0x0080 +#define QOS_AMSDU_SHIFT 7 +#define QOS_AMSDU_MASK 0x0080 -#define DOT11_MNG_AUTH_ALGO_LEN 2 -#define DOT11_MNG_AUTH_SEQ_LEN 2 -#define DOT11_MNG_BEACON_INT_LEN 2 -#define DOT11_MNG_CAP_LEN 2 -#define DOT11_MNG_AP_ADDR_LEN 6 -#define DOT11_MNG_LISTEN_INT_LEN 2 -#define DOT11_MNG_REASON_LEN 2 -#define DOT11_MNG_AID_LEN 2 -#define DOT11_MNG_STATUS_LEN 2 -#define DOT11_MNG_TIMESTAMP_LEN 8 +#define DOT11_MNG_AUTH_ALGO_LEN 2 +#define DOT11_MNG_AUTH_SEQ_LEN 2 +#define DOT11_MNG_BEACON_INT_LEN 2 +#define DOT11_MNG_CAP_LEN 2 +#define DOT11_MNG_AP_ADDR_LEN 6 +#define DOT11_MNG_LISTEN_INT_LEN 2 +#define DOT11_MNG_REASON_LEN 2 +#define DOT11_MNG_AID_LEN 2 +#define DOT11_MNG_STATUS_LEN 2 +#define DOT11_MNG_TIMESTAMP_LEN 8 -#define DOT11_AID_MASK 0x3fff +#define DOT11_AID_MASK 0x3fff -#define DOT11_RC_RESERVED 0 -#define DOT11_RC_UNSPECIFIED 1 -#define DOT11_RC_AUTH_INVAL 2 -#define DOT11_RC_DEAUTH_LEAVING 3 -#define DOT11_RC_INACTIVITY 4 -#define DOT11_RC_BUSY 5 -#define DOT11_RC_INVAL_CLASS_2 6 -#define DOT11_RC_INVAL_CLASS_3 7 -#define DOT11_RC_DISASSOC_LEAVING 8 -#define DOT11_RC_NOT_AUTH 9 -#define DOT11_RC_BAD_PC 10 -#define DOT11_RC_BAD_CHANNELS 11 +#define DOT11_RC_RESERVED 0 +#define DOT11_RC_UNSPECIFIED 1 +#define DOT11_RC_AUTH_INVAL 2 +#define DOT11_RC_DEAUTH_LEAVING 3 +#define DOT11_RC_INACTIVITY 4 +#define DOT11_RC_BUSY 5 +#define DOT11_RC_INVAL_CLASS_2 6 +#define DOT11_RC_INVAL_CLASS_3 7 +#define DOT11_RC_DISASSOC_LEAVING 8 +#define DOT11_RC_NOT_AUTH 9 +#define DOT11_RC_BAD_PC 10 +#define DOT11_RC_BAD_CHANNELS 11 -#define DOT11_RC_UNSPECIFIED_QOS 32 -#define DOT11_RC_INSUFFCIENT_BW 33 -#define DOT11_RC_EXCESSIVE_FRAMES 34 -#define DOT11_RC_TX_OUTSIDE_TXOP 35 -#define DOT11_RC_LEAVING_QBSS 36 -#define DOT11_RC_BAD_MECHANISM 37 -#define DOT11_RC_SETUP_NEEDED 38 -#define DOT11_RC_TIMEOUT 39 +#define DOT11_RC_UNSPECIFIED_QOS 32 +#define DOT11_RC_INSUFFCIENT_BW 33 +#define DOT11_RC_EXCESSIVE_FRAMES 34 +#define DOT11_RC_TX_OUTSIDE_TXOP 35 +#define DOT11_RC_LEAVING_QBSS 36 +#define DOT11_RC_BAD_MECHANISM 37 +#define DOT11_RC_SETUP_NEEDED 38 +#define DOT11_RC_TIMEOUT 39 -#define DOT11_RC_MAX 23 +#define DOT11_RC_MAX 23 #define DOT11_RC_TDLS_PEER_UNREACH 25 #define DOT11_RC_TDLS_DOWN_UNSPECIFIED 26 -#define DOT11_SC_SUCCESS 0 -#define DOT11_SC_FAILURE 1 +#define DOT11_SC_SUCCESS 0 +#define DOT11_SC_FAILURE 1 #define DOT11_SC_TDLS_WAKEUP_SCH_ALT 2 #define DOT11_SC_TDLS_WAKEUP_SCH_REJ 3 #define DOT11_SC_TDLS_SEC_DISABLED 5 #define DOT11_SC_LIFETIME_REJ 6 #define DOT11_SC_NOT_SAME_BSS 7 -#define DOT11_SC_CAP_MISMATCH 10 -#define DOT11_SC_REASSOC_FAIL 11 -#define DOT11_SC_ASSOC_FAIL 12 -#define DOT11_SC_AUTH_MISMATCH 13 -#define DOT11_SC_AUTH_SEQ 14 -#define DOT11_SC_AUTH_CHALLENGE_FAIL 15 -#define DOT11_SC_AUTH_TIMEOUT 16 -#define DOT11_SC_ASSOC_BUSY_FAIL 17 -#define DOT11_SC_ASSOC_RATE_MISMATCH 18 -#define DOT11_SC_ASSOC_SHORT_REQUIRED 19 -#define DOT11_SC_ASSOC_PBCC_REQUIRED 20 -#define DOT11_SC_ASSOC_AGILITY_REQUIRED 21 -#define DOT11_SC_ASSOC_SPECTRUM_REQUIRED 22 -#define DOT11_SC_ASSOC_BAD_POWER_CAP 23 -#define DOT11_SC_ASSOC_BAD_SUP_CHANNELS 24 -#define DOT11_SC_ASSOC_SHORTSLOT_REQUIRED 25 -#define DOT11_SC_ASSOC_ERPBCC_REQUIRED 26 -#define DOT11_SC_ASSOC_DSSOFDM_REQUIRED 27 +#define DOT11_SC_CAP_MISMATCH 10 +#define DOT11_SC_REASSOC_FAIL 11 +#define DOT11_SC_ASSOC_FAIL 12 +#define DOT11_SC_AUTH_MISMATCH 13 +#define DOT11_SC_AUTH_SEQ 14 +#define DOT11_SC_AUTH_CHALLENGE_FAIL 15 +#define DOT11_SC_AUTH_TIMEOUT 16 +#define DOT11_SC_ASSOC_BUSY_FAIL 17 +#define DOT11_SC_ASSOC_RATE_MISMATCH 18 +#define DOT11_SC_ASSOC_SHORT_REQUIRED 19 +#define DOT11_SC_ASSOC_PBCC_REQUIRED 20 +#define DOT11_SC_ASSOC_AGILITY_REQUIRED 21 +#define DOT11_SC_ASSOC_SPECTRUM_REQUIRED 22 +#define DOT11_SC_ASSOC_BAD_POWER_CAP 23 +#define DOT11_SC_ASSOC_BAD_SUP_CHANNELS 24 +#define DOT11_SC_ASSOC_SHORTSLOT_REQUIRED 25 +#define DOT11_SC_ASSOC_ERPBCC_REQUIRED 26 +#define DOT11_SC_ASSOC_DSSOFDM_REQUIRED 27 #define DOT11_SC_ASSOC_R0KH_UNREACHABLE 28 #define DOT11_SC_ASSOC_TRY_LATER 30 #define DOT11_SC_ASSOC_MFP_VIOLATION 31 @@ -992,6 +1000,7 @@ typedef struct ti_ie ti_ie_t; #define DOT11_SC_INVALID_PAIRWISE_CIPHER 42 #define DOT11_SC_INVALID_AKMP 43 #define DOT11_SC_INVALID_RSNIE_CAP 45 +#define DOT11_SC_DLS_NOT_ALLOWED 48 #define DOT11_SC_INVALID_PMKID 53 #define DOT11_SC_INVALID_MDID 54 #define DOT11_SC_INVALID_FTIE 55 @@ -1000,170 +1009,187 @@ typedef struct ti_ie ti_ie_t; #define DOT11_SC_INVALID_SNONCE 71 #define DOT11_SC_INVALID_RSNIE 72 -#define DOT11_MNG_DS_PARAM_LEN 1 -#define DOT11_MNG_IBSS_PARAM_LEN 2 - - -#define DOT11_MNG_TIM_FIXED_LEN 3 -#define DOT11_MNG_TIM_DTIM_COUNT 0 -#define DOT11_MNG_TIM_DTIM_PERIOD 1 -#define DOT11_MNG_TIM_BITMAP_CTL 2 -#define DOT11_MNG_TIM_PVB 3 - - -#define TLV_TAG_OFF 0 -#define TLV_LEN_OFF 1 -#define TLV_HDR_LEN 2 -#define TLV_BODY_OFF 2 - - -#define DOT11_MNG_SSID_ID 0 -#define DOT11_MNG_RATES_ID 1 -#define DOT11_MNG_FH_PARMS_ID 2 -#define DOT11_MNG_DS_PARMS_ID 3 -#define DOT11_MNG_CF_PARMS_ID 4 -#define DOT11_MNG_TIM_ID 5 -#define DOT11_MNG_IBSS_PARMS_ID 6 -#define DOT11_MNG_COUNTRY_ID 7 -#define DOT11_MNG_HOPPING_PARMS_ID 8 -#define DOT11_MNG_HOPPING_TABLE_ID 9 -#define DOT11_MNG_REQUEST_ID 10 -#define DOT11_MNG_QBSS_LOAD_ID 11 -#define DOT11_MNG_EDCA_PARAM_ID 12 -#define DOT11_MNG_CHALLENGE_ID 16 -#define DOT11_MNG_PWR_CONSTRAINT_ID 32 -#define DOT11_MNG_PWR_CAP_ID 33 -#define DOT11_MNG_TPC_REQUEST_ID 34 -#define DOT11_MNG_TPC_REPORT_ID 35 -#define DOT11_MNG_SUPP_CHANNELS_ID 36 -#define DOT11_MNG_CHANNEL_SWITCH_ID 37 -#define DOT11_MNG_MEASURE_REQUEST_ID 38 -#define DOT11_MNG_MEASURE_REPORT_ID 39 -#define DOT11_MNG_QUIET_ID 40 -#define DOT11_MNG_IBSS_DFS_ID 41 -#define DOT11_MNG_ERP_ID 42 -#define DOT11_MNG_TS_DELAY_ID 43 -#define DOT11_MNG_HT_CAP 45 -#define DOT11_MNG_QOS_CAP_ID 46 -#define DOT11_MNG_NONERP_ID 47 -#define DOT11_MNG_RSN_ID 48 -#define DOT11_MNG_EXT_RATES_ID 50 -#define DOT11_MNG_AP_CHREP_ID 51 -#define DOT11_MNG_NBR_REP_ID 52 -#define DOT11_MNG_MDIE_ID 54 -#define DOT11_MNG_FTIE_ID 55 -#define DOT11_MNG_FT_TI_ID 56 -#define DOT11_MNG_RDE_ID 57 -#define DOT11_MNG_REGCLASS_ID 59 -#define DOT11_MNG_EXT_CSA_ID 60 -#define DOT11_MNG_HT_ADD 61 -#define DOT11_MNG_EXT_CHANNEL_OFFSET 62 - - -#define DOT11_MNG_RRM_CAP_ID 70 -#define DOT11_MNG_HT_BSS_COEXINFO_ID 72 -#define DOT11_MNG_HT_BSS_CHANNEL_REPORT_ID 73 -#define DOT11_MNG_HT_OBSS_ID 74 + +#define DOT11_MNG_DS_PARAM_LEN 1 +#define DOT11_MNG_IBSS_PARAM_LEN 2 + + +#define DOT11_MNG_TIM_FIXED_LEN 3 +#define DOT11_MNG_TIM_DTIM_COUNT 0 +#define DOT11_MNG_TIM_DTIM_PERIOD 1 +#define DOT11_MNG_TIM_BITMAP_CTL 2 +#define DOT11_MNG_TIM_PVB 3 + + +#define TLV_TAG_OFF 0 +#define TLV_LEN_OFF 1 +#define TLV_HDR_LEN 2 +#define TLV_BODY_OFF 2 + + +#define DOT11_MNG_SSID_ID 0 +#define DOT11_MNG_RATES_ID 1 +#define DOT11_MNG_FH_PARMS_ID 2 +#define DOT11_MNG_DS_PARMS_ID 3 +#define DOT11_MNG_CF_PARMS_ID 4 +#define DOT11_MNG_TIM_ID 5 +#define DOT11_MNG_IBSS_PARMS_ID 6 +#define DOT11_MNG_COUNTRY_ID 7 +#define DOT11_MNG_HOPPING_PARMS_ID 8 +#define DOT11_MNG_HOPPING_TABLE_ID 9 +#define DOT11_MNG_REQUEST_ID 10 +#define DOT11_MNG_QBSS_LOAD_ID 11 +#define DOT11_MNG_EDCA_PARAM_ID 12 +#define DOT11_MNG_CHALLENGE_ID 16 +#define DOT11_MNG_PWR_CONSTRAINT_ID 32 +#define DOT11_MNG_PWR_CAP_ID 33 +#define DOT11_MNG_TPC_REQUEST_ID 34 +#define DOT11_MNG_TPC_REPORT_ID 35 +#define DOT11_MNG_SUPP_CHANNELS_ID 36 +#define DOT11_MNG_CHANNEL_SWITCH_ID 37 +#define DOT11_MNG_MEASURE_REQUEST_ID 38 +#define DOT11_MNG_MEASURE_REPORT_ID 39 +#define DOT11_MNG_QUIET_ID 40 +#define DOT11_MNG_IBSS_DFS_ID 41 +#define DOT11_MNG_ERP_ID 42 +#define DOT11_MNG_TS_DELAY_ID 43 +#define DOT11_MNG_HT_CAP 45 +#define DOT11_MNG_QOS_CAP_ID 46 +#define DOT11_MNG_NONERP_ID 47 +#define DOT11_MNG_RSN_ID 48 +#define DOT11_MNG_EXT_RATES_ID 50 +#define DOT11_MNG_AP_CHREP_ID 51 +#define DOT11_MNG_NBR_REP_ID 52 +#define DOT11_MNG_MDIE_ID 54 +#define DOT11_MNG_FTIE_ID 55 +#define DOT11_MNG_FT_TI_ID 56 +#define DOT11_MNG_REGCLASS_ID 59 +#define DOT11_MNG_EXT_CSA_ID 60 +#define DOT11_MNG_HT_ADD 61 +#define DOT11_MNG_EXT_CHANNEL_OFFSET 62 +#define DOT11_MNG_WAPI_ID 68 +#define DOT11_MNG_TIME_ADVERTISE_ID 69 +#define DOT11_MNG_RRM_CAP_ID 70 +#define DOT11_MNG_HT_BSS_COEXINFO_ID 72 +#define DOT11_MNG_HT_BSS_CHANNEL_REPORT_ID 73 +#define DOT11_MNG_HT_OBSS_ID 74 #define DOT11_MNG_CHANNEL_USAGE 97 +#define DOT11_MNG_TIME_ZONE_ID 98 #define DOT11_MNG_LINK_IDENTIFIER_ID 101 #define DOT11_MNG_WAKEUP_SCHEDULE_ID 102 #define DOT11_MNG_CHANNEL_SWITCH_TIMING_ID 104 #define DOT11_MNG_PTI_CONTROL_ID 105 #define DOT11_MNG_PU_BUFFER_STATUS_ID 106 -#define DOT11_MNG_EXT_CAP_ID 127 -#define DOT11_MNG_WPA_ID 221 -#define DOT11_MNG_PROPR_ID 221 +#define DOT11_MNG_INTERWORKING_ID 107 +#define DOT11_MNG_ADVERTISEMENT_ID 108 +#define DOT11_MNG_EXP_BW_REQ_ID 109 +#define DOT11_MNG_QOS_MAP_ID 110 +#define DOT11_MNG_ROAM_CONSORT_ID 111 +#define DOT11_MNG_EMERGCY_ALERT_ID 112 +#define DOT11_MNG_EXT_CAP_ID 127 +#define DOT11_MNG_VHT_CAP_ID 191 +#define DOT11_MNG_VHT_OPERATION_ID 192 + +#define DOT11_MNG_WPA_ID 221 +#define DOT11_MNG_PROPR_ID 221 -#define DOT11_MNG_VS_ID 221 +#define DOT11_MNG_VS_ID 221 -#define DOT11_RATE_BASIC 0x80 -#define DOT11_RATE_MASK 0x7F +#define DOT11_RATE_BASIC 0x80 +#define DOT11_RATE_MASK 0x7F -#define DOT11_MNG_ERP_LEN 1 -#define DOT11_MNG_NONERP_PRESENT 0x01 -#define DOT11_MNG_USE_PROTECTION 0x02 -#define DOT11_MNG_BARKER_PREAMBLE 0x04 +#define DOT11_MNG_ERP_LEN 1 +#define DOT11_MNG_NONERP_PRESENT 0x01 +#define DOT11_MNG_USE_PROTECTION 0x02 +#define DOT11_MNG_BARKER_PREAMBLE 0x04 -#define DOT11_MGN_TS_DELAY_LEN 4 -#define TS_DELAY_FIELD_SIZE 4 +#define DOT11_MGN_TS_DELAY_LEN 4 +#define TS_DELAY_FIELD_SIZE 4 -#define DOT11_CAP_ESS 0x0001 -#define DOT11_CAP_IBSS 0x0002 -#define DOT11_CAP_POLLABLE 0x0004 -#define DOT11_CAP_POLL_RQ 0x0008 -#define DOT11_CAP_PRIVACY 0x0010 -#define DOT11_CAP_SHORT 0x0020 -#define DOT11_CAP_PBCC 0x0040 -#define DOT11_CAP_AGILITY 0x0080 -#define DOT11_CAP_SPECTRUM 0x0100 -#define DOT11_CAP_SHORTSLOT 0x0400 -#define DOT11_CAP_RRM 0x1000 -#define DOT11_CAP_CCK_OFDM 0x2000 +#define DOT11_CAP_ESS 0x0001 +#define DOT11_CAP_IBSS 0x0002 +#define DOT11_CAP_POLLABLE 0x0004 +#define DOT11_CAP_POLL_RQ 0x0008 +#define DOT11_CAP_PRIVACY 0x0010 +#define DOT11_CAP_SHORT 0x0020 +#define DOT11_CAP_PBCC 0x0040 +#define DOT11_CAP_AGILITY 0x0080 +#define DOT11_CAP_SPECTRUM 0x0100 +#define DOT11_CAP_SHORTSLOT 0x0400 +#define DOT11_CAP_RRM 0x1000 +#define DOT11_CAP_CCK_OFDM 0x2000 -#define DOT11_OBSS_COEX_MNG_SUPPORT 0x01 +#define DOT11_EXT_CAP_OBSS_COEX_MGMT 0 + +#define DOT11_EXT_CAP_SPSMP 6 + +#define DOT11_EXT_CAP_BSS_TRANSITION_MGMT 19 + +#define DOT11_EXT_CAP_IW 31 -#define DOT11_ACTION_HDR_LEN 2 -#define DOT11_ACTION_CAT_OFF 0 -#define DOT11_ACTION_ACT_OFF 1 +#define DOT11_EXT_CAP_SI 41 +#define DOT11_EXT_CAP_SI_MASK 0x0E -#define DOT11_ACTION_CAT_ERR_MASK 0x80 -#define DOT11_ACTION_CAT_MASK 0x7F -#define DOT11_ACTION_CAT_SPECT_MNG 0 -#define DOT11_ACTION_CAT_QOS 1 -#define DOT11_ACTION_CAT_DLS 2 -#define DOT11_ACTION_CAT_BLOCKACK 3 -#define DOT11_ACTION_CAT_PUBLIC 4 -#define DOT11_ACTION_CAT_RRM 5 -#define DOT11_ACTION_CAT_FBT 6 -#define DOT11_ACTION_CAT_HT 7 -#if defined(MFP) || defined(WLFBT) || defined(WLWNM) +#define DOT11_ACTION_HDR_LEN 2 +#define DOT11_ACTION_CAT_OFF 0 +#define DOT11_ACTION_ACT_OFF 1 + + +#define DOT11_ACTION_CAT_ERR_MASK 0x80 +#define DOT11_ACTION_CAT_MASK 0x7F +#define DOT11_ACTION_CAT_SPECT_MNG 0 +#define DOT11_ACTION_CAT_QOS 1 +#define DOT11_ACTION_CAT_DLS 2 +#define DOT11_ACTION_CAT_BLOCKACK 3 +#define DOT11_ACTION_CAT_PUBLIC 4 +#define DOT11_ACTION_CAT_RRM 5 +#define DOT11_ACTION_CAT_FBT 6 +#define DOT11_ACTION_CAT_HT 7 #define DOT11_ACTION_CAT_SA_QUERY 8 #define DOT11_ACTION_CAT_PDPA 9 -#define DOT11_ACTION_CAT_BSSMGMT 10 -#define DOT11_ACTION_NOTIFICATION 17 -#define DOT11_ACTION_CAT_VSP 126 -#endif +#define DOT11_ACTION_CAT_BSSMGMT 10 #define DOT11_ACTION_NOTIFICATION 17 -#define DOT11_ACTION_CAT_VS 127 +#define DOT11_ACTION_CAT_VSP 126 +#define DOT11_ACTION_CAT_VS 127 -#define DOT11_SM_ACTION_M_REQ 0 -#define DOT11_SM_ACTION_M_REP 1 -#define DOT11_SM_ACTION_TPC_REQ 2 -#define DOT11_SM_ACTION_TPC_REP 3 -#define DOT11_SM_ACTION_CHANNEL_SWITCH 4 -#define DOT11_SM_ACTION_EXT_CSA 5 +#define DOT11_SM_ACTION_M_REQ 0 +#define DOT11_SM_ACTION_M_REP 1 +#define DOT11_SM_ACTION_TPC_REQ 2 +#define DOT11_SM_ACTION_TPC_REP 3 +#define DOT11_SM_ACTION_CHANNEL_SWITCH 4 +#define DOT11_SM_ACTION_EXT_CSA 5 -#define DOT11_ACTION_ID_HT_CH_WIDTH 0 -#define DOT11_ACTION_ID_HT_MIMO_PS 1 +#define DOT11_ACTION_ID_HT_CH_WIDTH 0 +#define DOT11_ACTION_ID_HT_MIMO_PS 1 -#define DOT11_PUB_ACTION_BSS_COEX_MNG 0 -#define DOT11_PUB_ACTION_CHANNEL_SWITCH 4 +#define DOT11_PUB_ACTION_BSS_COEX_MNG 0 +#define DOT11_PUB_ACTION_CHANNEL_SWITCH 4 -#define DOT11_BA_ACTION_ADDBA_REQ 0 -#define DOT11_BA_ACTION_ADDBA_RESP 1 -#define DOT11_BA_ACTION_DELBA 2 +#define DOT11_BA_ACTION_ADDBA_REQ 0 +#define DOT11_BA_ACTION_ADDBA_RESP 1 +#define DOT11_BA_ACTION_DELBA 2 -#define DOT11_ADDBA_PARAM_AMSDU_SUP 0x0001 -#define DOT11_ADDBA_PARAM_POLICY_MASK 0x0002 -#define DOT11_ADDBA_PARAM_POLICY_SHIFT 1 -#define DOT11_ADDBA_PARAM_TID_MASK 0x003c -#define DOT11_ADDBA_PARAM_TID_SHIFT 2 -#define DOT11_ADDBA_PARAM_BSIZE_MASK 0xffc0 -#define DOT11_ADDBA_PARAM_BSIZE_SHIFT 6 +#define DOT11_ADDBA_PARAM_AMSDU_SUP 0x0001 +#define DOT11_ADDBA_PARAM_POLICY_MASK 0x0002 +#define DOT11_ADDBA_PARAM_POLICY_SHIFT 1 +#define DOT11_ADDBA_PARAM_TID_MASK 0x003c +#define DOT11_ADDBA_PARAM_TID_SHIFT 2 +#define DOT11_ADDBA_PARAM_BSIZE_MASK 0xffc0 +#define DOT11_ADDBA_PARAM_BSIZE_SHIFT 6 -#define DOT11_ADDBA_POLICY_DELAYED 0 -#define DOT11_ADDBA_POLICY_IMMEDIATE 1 +#define DOT11_ADDBA_POLICY_DELAYED 0 +#define DOT11_ADDBA_POLICY_IMMEDIATE 1 #define DOT11_FT_ACTION_FT_RESERVED 0 @@ -1173,6 +1199,10 @@ typedef struct ti_ie ti_ie_t; #define DOT11_FT_ACTION_FT_ACK 4 +#define DOT11_DLS_ACTION_REQ 0 +#define DOT11_DLS_ACTION_RESP 1 +#define DOT11_DLS_ACTION_TD 2 + #define DOT11_WNM_ACTION_EVENT_REQ 0 #define DOT11_WNM_ACTION_EVENT_REP 1 @@ -1203,6 +1233,33 @@ typedef struct ti_ie ti_ie_t; #define DOT11_WNM_ACTION_NOTFCTN_REQ 26 #define DOT11_WNM_ACTION_NOTFCTN_RES 27 +#define DOT11_MNG_COUNTRY_ID_LEN 3 + + +BWL_PRE_PACKED_STRUCT struct dot11_dls_req { + uint8 category; + uint8 action; + struct ether_addr da; + struct ether_addr sa; + uint16 cap; + uint16 timeout; + uint8 data[1]; +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_dls_req dot11_dls_req_t; +#define DOT11_DLS_REQ_LEN 18 + + +BWL_PRE_PACKED_STRUCT struct dot11_dls_resp { + uint8 category; + uint8 action; + uint16 status; + struct ether_addr da; + struct ether_addr sa; + uint8 data[1]; +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_dls_resp dot11_dls_resp_t; +#define DOT11_DLS_RESP_LEN 16 + BWL_PRE_PACKED_STRUCT struct dot11_bss_trans_query { @@ -1280,42 +1337,44 @@ typedef struct dot11_bss_trans_res dot11_bss_trans_res_t; #define DOT11_NBR_RPRT_SUBELEM_BSS_CANDDT_PREF_ID 3 + + BWL_PRE_PACKED_STRUCT struct dot11_addba_req { - uint8 category; - uint8 action; - uint8 token; - uint16 addba_param_set; - uint16 timeout; - uint16 start_seqnum; + uint8 category; + uint8 action; + uint8 token; + uint16 addba_param_set; + uint16 timeout; + uint16 start_seqnum; } BWL_POST_PACKED_STRUCT; typedef struct dot11_addba_req dot11_addba_req_t; -#define DOT11_ADDBA_REQ_LEN 9 +#define DOT11_ADDBA_REQ_LEN 9 BWL_PRE_PACKED_STRUCT struct dot11_addba_resp { - uint8 category; - uint8 action; - uint8 token; - uint16 status; - uint16 addba_param_set; - uint16 timeout; + uint8 category; + uint8 action; + uint8 token; + uint16 status; + uint16 addba_param_set; + uint16 timeout; } BWL_POST_PACKED_STRUCT; typedef struct dot11_addba_resp dot11_addba_resp_t; -#define DOT11_ADDBA_RESP_LEN 9 +#define DOT11_ADDBA_RESP_LEN 9 -#define DOT11_DELBA_PARAM_INIT_MASK 0x0800 -#define DOT11_DELBA_PARAM_INIT_SHIFT 11 -#define DOT11_DELBA_PARAM_TID_MASK 0xf000 -#define DOT11_DELBA_PARAM_TID_SHIFT 12 +#define DOT11_DELBA_PARAM_INIT_MASK 0x0800 +#define DOT11_DELBA_PARAM_INIT_SHIFT 11 +#define DOT11_DELBA_PARAM_TID_MASK 0xf000 +#define DOT11_DELBA_PARAM_TID_SHIFT 12 BWL_PRE_PACKED_STRUCT struct dot11_delba { - uint8 category; - uint8 action; - uint16 delba_param_set; - uint16 reason; + uint8 category; + uint8 action; + uint16 delba_param_set; + uint16 reason; } BWL_POST_PACKED_STRUCT; typedef struct dot11_delba dot11_delba_t; -#define DOT11_DELBA_LEN 6 +#define DOT11_DELBA_LEN 6 #define SA_QUERY_REQUEST 0 @@ -1347,87 +1406,58 @@ typedef struct dot11_ft_res dot11_ft_res_t; #define DOT11_FT_RES_FIXED_LEN 16 -BWL_PRE_PACKED_STRUCT struct dot11_rde_ie { - uint8 id; - uint8 length; - uint8 rde_id; - uint8 rd_count; - uint16 status; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_rde_ie dot11_rde_ie_t; - - -#define DOT11_MNG_RDE_IE_LEN sizeof(dot11_rde_ie_t) - -#define DOT11_RRM_CAP_LEN 5 +#define DOT11_RRM_CAP_LEN 5 BWL_PRE_PACKED_STRUCT struct dot11_rrm_cap_ie { uint8 cap[DOT11_RRM_CAP_LEN]; } BWL_POST_PACKED_STRUCT; typedef struct dot11_rrm_cap_ie dot11_rrm_cap_ie_t; -#define DOT11_RRM_CAP_LINK 0 -#define DOT11_RRM_CAP_NEIGHBOR_REPORT 1 -#define DOT11_RRM_CAP_PARALLEL 2 -#define DOT11_RRM_CAP_REPEATED 3 -#define DOT11_RRM_CAP_BCN_PASSIVE 4 -#define DOT11_RRM_CAP_BCN_ACTIVE 5 -#define DOT11_RRM_CAP_BCN_TABLE 6 -#define DOT11_RRM_CAP_BCN_REP_COND 7 -#define DOT11_RRM_CAP_AP_CHANREP 16 - +#define DOT11_RRM_CAP_LINK 0 +#define DOT11_RRM_CAP_NEIGHBOR_REPORT 1 +#define DOT11_RRM_CAP_PARALLEL 2 +#define DOT11_RRM_CAP_REPEATED 3 +#define DOT11_RRM_CAP_BCN_PASSIVE 4 +#define DOT11_RRM_CAP_BCN_ACTIVE 5 +#define DOT11_RRM_CAP_BCN_TABLE 6 +#define DOT11_RRM_CAP_BCN_REP_COND 7 +#define DOT11_RRM_CAP_AP_CHANREP 16 -#define DOT11_EXT_CAP_LEN 4 -BWL_PRE_PACKED_STRUCT struct dot11_ext_cap_ie { - uint8 cap[DOT11_EXT_CAP_LEN]; -} BWL_POST_PACKED_STRUCT; -typedef struct dot11_ext_cap_ie dot11_ext_cap_ie_t; - - -#define DOT11_EXT_CAP_BSS_TRANSITION_MGMT 19 - #define DOT11_OP_CLASS_NONE 255 -BWL_PRE_PACKED_STRUCT struct do11_ap_chrep { - uint8 id; - uint8 len; - uint8 reg; - uint8 chanlist[1]; -} BWL_POST_PACKED_STRUCT; -typedef struct do11_ap_chrep dot11_ap_chrep_t; -#define DOT11_RM_ACTION_RM_REQ 0 -#define DOT11_RM_ACTION_RM_REP 1 -#define DOT11_RM_ACTION_LM_REQ 2 -#define DOT11_RM_ACTION_LM_REP 3 -#define DOT11_RM_ACTION_NR_REQ 4 -#define DOT11_RM_ACTION_NR_REP 5 +#define DOT11_RM_ACTION_RM_REQ 0 +#define DOT11_RM_ACTION_RM_REP 1 +#define DOT11_RM_ACTION_LM_REQ 2 +#define DOT11_RM_ACTION_LM_REP 3 +#define DOT11_RM_ACTION_NR_REQ 4 +#define DOT11_RM_ACTION_NR_REP 5 BWL_PRE_PACKED_STRUCT struct dot11_rm_action { - uint8 category; - uint8 action; - uint8 token; + uint8 category; + uint8 action; + uint8 token; uint8 data[1]; } BWL_POST_PACKED_STRUCT; typedef struct dot11_rm_action dot11_rm_action_t; #define DOT11_RM_ACTION_LEN 3 BWL_PRE_PACKED_STRUCT struct dot11_rmreq { - uint8 category; - uint8 action; - uint8 token; - uint16 reps; + uint8 category; + uint8 action; + uint8 token; + uint16 reps; } BWL_POST_PACKED_STRUCT; typedef struct dot11_rmreq dot11_rmreq_t; -#define DOT11_RMREQ_LEN 5 +#define DOT11_RMREQ_LEN 5 BWL_PRE_PACKED_STRUCT struct dot11_rm_ie { uint8 id; @@ -1437,19 +1467,19 @@ BWL_PRE_PACKED_STRUCT struct dot11_rm_ie { uint8 type; } BWL_POST_PACKED_STRUCT; typedef struct dot11_rm_ie dot11_rm_ie_t; -#define DOT11_RM_IE_LEN 5 +#define DOT11_RM_IE_LEN 5 -#define DOT11_RMREQ_MODE_PARALLEL 1 -#define DOT11_RMREQ_MODE_ENABLE 2 -#define DOT11_RMREQ_MODE_REQUEST 4 -#define DOT11_RMREQ_MODE_REPORT 8 -#define DOT11_RMREQ_MODE_DURMAND 0x10 +#define DOT11_RMREQ_MODE_PARALLEL 1 +#define DOT11_RMREQ_MODE_ENABLE 2 +#define DOT11_RMREQ_MODE_REQUEST 4 +#define DOT11_RMREQ_MODE_REPORT 8 +#define DOT11_RMREQ_MODE_DURMAND 0x10 -#define DOT11_RMREP_MODE_LATE 1 -#define DOT11_RMREP_MODE_INCAPABLE 2 -#define DOT11_RMREP_MODE_REFUSED 4 +#define DOT11_RMREP_MODE_LATE 1 +#define DOT11_RMREP_MODE_INCAPABLE 2 +#define DOT11_RMREP_MODE_REFUSED 4 BWL_PRE_PACKED_STRUCT struct dot11_rmreq_bcn { uint8 id; @@ -1462,10 +1492,10 @@ BWL_PRE_PACKED_STRUCT struct dot11_rmreq_bcn { uint16 interval; uint16 duration; uint8 bcn_mode; - struct ether_addr bssid; + struct ether_addr bssid; } BWL_POST_PACKED_STRUCT; typedef struct dot11_rmreq_bcn dot11_rmreq_bcn_t; -#define DOT11_RMREQ_BCN_LEN 18 +#define DOT11_RMREQ_BCN_LEN 18 BWL_PRE_PACKED_STRUCT struct dot11_rmrep_bcn { uint8 reg; @@ -1475,459 +1505,607 @@ BWL_PRE_PACKED_STRUCT struct dot11_rmrep_bcn { uint8 frame_info; uint8 rcpi; uint8 rsni; - struct ether_addr bssid; + struct ether_addr bssid; uint8 antenna_id; uint32 parent_tsf; } BWL_POST_PACKED_STRUCT; typedef struct dot11_rmrep_bcn dot11_rmrep_bcn_t; -#define DOT11_RMREP_BCN_LEN 26 +#define DOT11_RMREP_BCN_LEN 26 -#define DOT11_RMREQ_BCN_PASSIVE 0 -#define DOT11_RMREQ_BCN_ACTIVE 1 -#define DOT11_RMREQ_BCN_TABLE 2 +#define DOT11_RMREQ_BCN_PASSIVE 0 +#define DOT11_RMREQ_BCN_ACTIVE 1 +#define DOT11_RMREQ_BCN_TABLE 2 -#define DOT11_RMREQ_BCN_SSID_ID 0 -#define DOT11_RMREQ_BCN_REPINFO_ID 1 -#define DOT11_RMREQ_BCN_REPDET_ID 2 -#define DOT11_RMREQ_BCN_REQUEST_ID 10 -#define DOT11_RMREQ_BCN_APCHREP_ID DOT11_MNG_AP_CHREP_ID +#define DOT11_RMREQ_BCN_SSID_ID 0 +#define DOT11_RMREQ_BCN_REPINFO_ID 1 +#define DOT11_RMREQ_BCN_REPDET_ID 2 +#define DOT11_RMREQ_BCN_REQUEST_ID 10 +#define DOT11_RMREQ_BCN_APCHREP_ID 51 -#define DOT11_RMREQ_BCN_REPDET_FIXED 0 -#define DOT11_RMREQ_BCN_REPDET_REQUEST 1 -#define DOT11_RMREQ_BCN_REPDET_ALL 2 +#define DOT11_RMREQ_BCN_REPDET_FIXED 0 +#define DOT11_RMREQ_BCN_REPDET_REQUEST 1 +#define DOT11_RMREQ_BCN_REPDET_ALL 2 -#define DOT11_RMREP_BCN_FRM_BODY 1 +#define DOT11_RMREP_BCN_FRM_BODY 1 BWL_PRE_PACKED_STRUCT struct dot11_rmrep_nbr { - struct ether_addr bssid; - uint32 bssid_info; + struct ether_addr bssid; + uint32 bssid_info; uint8 reg; uint8 channel; uint8 phytype; uchar sub_elements[1]; } BWL_POST_PACKED_STRUCT; typedef struct dot11_rmrep_nbr dot11_rmrep_nbr_t; -#define DOT11_RMREP_NBR_LEN 13 +#define DOT11_RMREP_NBR_LEN 13 -#define DOT11_BSSTYPE_INFRASTRUCTURE 0 -#define DOT11_BSSTYPE_INDEPENDENT 1 -#define DOT11_BSSTYPE_ANY 2 -#define DOT11_SCANTYPE_ACTIVE 0 -#define DOT11_SCANTYPE_PASSIVE 1 +#define DOT11_BSSTYPE_INFRASTRUCTURE 0 +#define DOT11_BSSTYPE_INDEPENDENT 1 +#define DOT11_BSSTYPE_ANY 2 +#define DOT11_SCANTYPE_ACTIVE 0 +#define DOT11_SCANTYPE_PASSIVE 1 BWL_PRE_PACKED_STRUCT struct dot11_lmreq { - uint8 category; - uint8 action; - uint8 token; - uint8 txpwr; - uint8 maxtxpwr; + uint8 category; + uint8 action; + uint8 token; + uint8 txpwr; + uint8 maxtxpwr; } BWL_POST_PACKED_STRUCT; typedef struct dot11_lmreq dot11_lmreq_t; -#define DOT11_LMREQ_LEN 5 +#define DOT11_LMREQ_LEN 5 BWL_PRE_PACKED_STRUCT struct dot11_lmrep { - uint8 category; - uint8 action; - uint8 token; - dot11_tpc_rep_t tpc; - uint8 rxant; - uint8 txant; - uint8 rcpi; - uint8 rsni; + uint8 category; + uint8 action; + uint8 token; + dot11_tpc_rep_t tpc; + uint8 rxant; + uint8 txant; + uint8 rcpi; + uint8 rsni; } BWL_POST_PACKED_STRUCT; typedef struct dot11_lmrep dot11_lmrep_t; -#define DOT11_LMREP_LEN 11 +#define DOT11_LMREP_LEN 11 + + +#define PREN_PREAMBLE 24 +#define PREN_MM_EXT 12 +#define PREN_PREAMBLE_EXT 4 + + +#define RIFS_11N_TIME 2 + + + +#define HT_SIG1_MCS_MASK 0x00007F +#define HT_SIG1_CBW 0x000080 +#define HT_SIG1_HT_LENGTH 0xFFFF00 + + +#define HT_SIG2_SMOOTHING 0x000001 +#define HT_SIG2_NOT_SOUNDING 0x000002 +#define HT_SIG2_RESERVED 0x000004 +#define HT_SIG2_AGGREGATION 0x000008 +#define HT_SIG2_STBC_MASK 0x000030 +#define HT_SIG2_STBC_SHIFT 4 +#define HT_SIG2_FEC_CODING 0x000040 +#define HT_SIG2_SHORT_GI 0x000080 +#define HT_SIG2_ESS_MASK 0x000300 +#define HT_SIG2_ESS_SHIFT 8 +#define HT_SIG2_CRC 0x03FC00 +#define HT_SIG2_TAIL 0x1C0000 + + +#define APHY_SLOT_TIME 9 +#define APHY_SIFS_TIME 16 +#define APHY_DIFS_TIME (APHY_SIFS_TIME + (2 * APHY_SLOT_TIME)) +#define APHY_PREAMBLE_TIME 16 +#define APHY_SIGNAL_TIME 4 +#define APHY_SYMBOL_TIME 4 +#define APHY_SERVICE_NBITS 16 +#define APHY_TAIL_NBITS 6 +#define APHY_CWMIN 15 + + +#define BPHY_SLOT_TIME 20 +#define BPHY_SIFS_TIME 10 +#define BPHY_DIFS_TIME 50 +#define BPHY_PLCP_TIME 192 +#define BPHY_PLCP_SHORT_TIME 96 +#define BPHY_CWMIN 31 + + +#define DOT11_OFDM_SIGNAL_EXTENSION 6 + +#define PHY_CWMAX 1023 +#define DOT11_MAXNUMFRAGS 16 -#define PREN_PREAMBLE 24 -#define PREN_MM_EXT 12 -#define PREN_PREAMBLE_EXT 4 -#define RIFS_11N_TIME 2 +typedef int vht_group_id_t; -#define HT_SIG1_MCS_MASK 0x00007F -#define HT_SIG1_CBW 0x000080 -#define HT_SIG1_HT_LENGTH 0xFFFF00 +#define VHT_SIGA1_CONST_MASK 0x800004 +#define VHT_SIGA1_20MHZ_VAL 0x000000 +#define VHT_SIGA1_40MHZ_VAL 0x000001 +#define VHT_SIGA1_80MHZ_VAL 0x000002 +#define VHT_SIGA1_160MHZ_VAL 0x000003 -#define HT_SIG2_SMOOTHING 0x000001 -#define HT_SIG2_NOT_SOUNDING 0x000002 -#define HT_SIG2_RESERVED 0x000004 -#define HT_SIG2_AGGREGATION 0x000008 -#define HT_SIG2_STBC_MASK 0x000030 -#define HT_SIG2_STBC_SHIFT 4 -#define HT_SIG2_FEC_CODING 0x000040 -#define HT_SIG2_SHORT_GI 0x000080 -#define HT_SIG2_ESS_MASK 0x000300 -#define HT_SIG2_ESS_SHIFT 8 -#define HT_SIG2_CRC 0x03FC00 -#define HT_SIG2_TAIL 0x1C0000 +#define VHT_SIGA1_STBC 0x000008 +#define VHT_SIGA1_GID_MAX_GID 0x3f +#define VHT_SIGA1_GID_SHIFT 4 +#define VHT_SIGA1_GID_TO_AP 0x00 +#define VHT_SIGA1_GID_NOT_TO_AP 0x3f -#define APHY_SLOT_TIME 9 -#define APHY_SIFS_TIME 16 -#define APHY_DIFS_TIME (APHY_SIFS_TIME + (2 * APHY_SLOT_TIME)) -#define APHY_PREAMBLE_TIME 16 -#define APHY_SIGNAL_TIME 4 -#define APHY_SYMBOL_TIME 4 -#define APHY_SERVICE_NBITS 16 -#define APHY_TAIL_NBITS 6 -#define APHY_CWMIN 15 +#define VHT_SIGA1_NSTS_SHIFT 10 +#define VHT_SIGA1_NSTS_SHIFT_MASK_USER0 0x001C00 +#define VHT_SIGA1_PARTIAL_AID_SHIFT 13 -#define BPHY_SLOT_TIME 20 -#define BPHY_SIFS_TIME 10 -#define BPHY_DIFS_TIME 50 -#define BPHY_PLCP_TIME 192 -#define BPHY_PLCP_SHORT_TIME 96 -#define BPHY_CWMIN 31 +#define VHT_SIGA2_GI_NONE 0x000000 +#define VHT_SIGA2_GI_SHORT 0x000001 +#define VHT_SIGA2_GI_W_MOD10 0x000002 +#define VHT_SIGA2_CODING_LDPC 0x000004 +#define VHT_SIGA2_BEAMFORM_ENABLE 0x000100 +#define VHT_SIGA2_MCS_SHIFT 4 -#define DOT11_OFDM_SIGNAL_EXTENSION 6 +#define VHT_SIGA2_B9_RESERVED 0x000200 +#define VHT_SIGA2_TAIL_MASK 0xfc0000 +#define VHT_SIGA2_TAIL_VALUE 0x000000 -#define PHY_CWMAX 1023 +#define VHT_SIGA2_SVC_BITS 16 +#define VHT_SIGA2_TAIL_BITS 6 -#define DOT11_MAXNUMFRAGS 16 typedef struct d11cnt { - uint32 txfrag; - uint32 txmulti; - uint32 txfail; - uint32 txretry; - uint32 txretrie; - uint32 rxdup; - uint32 txrts; - uint32 txnocts; - uint32 txnoack; - uint32 rxfrag; - uint32 rxmulti; - uint32 rxcrc; - uint32 txfrmsnt; - uint32 rxundec; + uint32 txfrag; + uint32 txmulti; + uint32 txfail; + uint32 txretry; + uint32 txretrie; + uint32 rxdup; + uint32 txrts; + uint32 txnocts; + uint32 txnoack; + uint32 rxfrag; + uint32 rxmulti; + uint32 rxcrc; + uint32 txfrmsnt; + uint32 rxundec; } d11cnt_t; -#define BRCM_PROP_OUI "\x00\x90\x4C" +#define BRCM_PROP_OUI "\x00\x90\x4C" -#define BRCM_OUI "\x00\x10\x18" +#define BRCM_OUI "\x00\x10\x18" BWL_PRE_PACKED_STRUCT struct brcm_ie { - uint8 id; - uint8 len; - uint8 oui[3]; - uint8 ver; - uint8 assoc; - uint8 flags; - uint8 flags1; - uint16 amsdu_mtu_pref; -} BWL_POST_PACKED_STRUCT; -typedef struct brcm_ie brcm_ie_t; -#define BRCM_IE_LEN 11 -#define BRCM_IE_VER 2 -#define BRCM_IE_LEGACY_AES_VER 1 - - -#ifdef WLAFTERBURNER -#define BRF_ABCAP 0x1 -#define BRF_ABRQRD 0x2 -#define BRF_ABCOUNTER_MASK 0xf0 -#define BRF_ABCOUNTER_SHIFT 4 -#endif -#define BRF_LZWDS 0x4 -#define BRF_BLOCKACK 0x8 + uint8 id; + uint8 len; + uint8 oui[3]; + uint8 ver; + uint8 assoc; + uint8 flags; + uint8 flags1; + uint16 amsdu_mtu_pref; +} BWL_POST_PACKED_STRUCT; +typedef struct brcm_ie brcm_ie_t; +#define BRCM_IE_LEN 11 +#define BRCM_IE_VER 2 +#define BRCM_IE_LEGACY_AES_VER 1 -#define BRF1_AMSDU 0x1 -#define BRF1_WMEPS 0x4 -#define BRF1_PSOFIX 0x8 -#define BRF1_RX_LARGE_AGG 0x10 -#define BRF1_SOFTAP 0x40 +#define BRF_LZWDS 0x4 +#define BRF_BLOCKACK 0x8 -#ifdef WLAFTERBURNER -#define AB_WDS_TIMEOUT_MAX 15 -#define AB_WDS_TIMEOUT_MIN 1 -#endif -#define AB_GUARDCOUNT 10 +#define BRF1_AMSDU 0x1 +#define BRF1_WMEPS 0x4 +#define BRF1_PSOFIX 0x8 +#define BRF1_RX_LARGE_AGG 0x10 +#define BRF1_RFAWARE_DCS 0x20 +#define BRF1_SOFTAP 0x40 BWL_PRE_PACKED_STRUCT struct vndr_ie { uchar id; uchar len; uchar oui [3]; - uchar data [1]; + uchar data [1]; } BWL_POST_PACKED_STRUCT; typedef struct vndr_ie vndr_ie_t; -#define VNDR_IE_HDR_LEN 2 -#define VNDR_IE_MIN_LEN 3 -#define VNDR_IE_MAX_LEN 256 +#define VNDR_IE_HDR_LEN 2 +#define VNDR_IE_MIN_LEN 3 +#define VNDR_IE_MAX_LEN 256 -#define MCSSET_LEN 16 -#define MAX_MCS_NUM (128) +#define MCSSET_LEN 16 +#define MAX_MCS_NUM (128) BWL_PRE_PACKED_STRUCT struct ht_cap_ie { - uint16 cap; - uint8 params; - uint8 supp_mcs[MCSSET_LEN]; - uint16 ext_htcap; - uint32 txbf_cap; - uint8 as_cap; + uint16 cap; + uint8 params; + uint8 supp_mcs[MCSSET_LEN]; + uint16 ext_htcap; + uint32 txbf_cap; + uint8 as_cap; } BWL_POST_PACKED_STRUCT; typedef struct ht_cap_ie ht_cap_ie_t; BWL_PRE_PACKED_STRUCT struct ht_prop_cap_ie { - uint8 id; - uint8 len; - uint8 oui[3]; - uint8 type; + uint8 id; + uint8 len; + uint8 oui[3]; + uint8 type; ht_cap_ie_t cap_ie; } BWL_POST_PACKED_STRUCT; typedef struct ht_prop_cap_ie ht_prop_cap_ie_t; -#define HT_PROP_IE_OVERHEAD 4 -#define HT_CAP_IE_LEN 26 -#define HT_CAP_IE_TYPE 51 - -#define HT_CAP_LDPC_CODING 0x0001 -#define HT_CAP_40MHZ 0x0002 -#define HT_CAP_MIMO_PS_MASK 0x000C -#define HT_CAP_MIMO_PS_SHIFT 0x0002 -#define HT_CAP_MIMO_PS_OFF 0x0003 -#define HT_CAP_MIMO_PS_RTS 0x0001 -#define HT_CAP_MIMO_PS_ON 0x0000 -#define HT_CAP_GF 0x0010 -#define HT_CAP_SHORT_GI_20 0x0020 -#define HT_CAP_SHORT_GI_40 0x0040 -#define HT_CAP_TX_STBC 0x0080 -#define HT_CAP_RX_STBC_MASK 0x0300 -#define HT_CAP_RX_STBC_SHIFT 8 -#define HT_CAP_DELAYED_BA 0x0400 -#define HT_CAP_MAX_AMSDU 0x0800 -#define HT_CAP_DSSS_CCK 0x1000 -#define HT_CAP_PSMP 0x2000 -#define HT_CAP_40MHZ_INTOLERANT 0x4000 -#define HT_CAP_LSIG_TXOP 0x8000 - -#define HT_CAP_RX_STBC_NO 0x0 -#define HT_CAP_RX_STBC_ONE_STREAM 0x1 -#define HT_CAP_RX_STBC_TWO_STREAM 0x2 -#define HT_CAP_RX_STBC_THREE_STREAM 0x3 - -#define HT_MAX_AMSDU 7935 -#define HT_MIN_AMSDU 3835 - -#define HT_PARAMS_RX_FACTOR_MASK 0x03 -#define HT_PARAMS_DENSITY_MASK 0x1C -#define HT_PARAMS_DENSITY_SHIFT 2 - - -#define AMPDU_MAX_MPDU_DENSITY 7 -#define AMPDU_RX_FACTOR_8K 0 -#define AMPDU_RX_FACTOR_16K 1 -#define AMPDU_RX_FACTOR_32K 2 -#define AMPDU_RX_FACTOR_64K 3 -#define AMPDU_RX_FACTOR_BASE 8*1024 - -#define AMPDU_DELIMITER_LEN 4 -#define AMPDU_DELIMITER_LEN_MAX 63 +#define HT_PROP_IE_OVERHEAD 4 +#define HT_CAP_IE_LEN 26 +#define HT_CAP_IE_TYPE 51 + +#define HT_CAP_LDPC_CODING 0x0001 +#define HT_CAP_40MHZ 0x0002 +#define HT_CAP_MIMO_PS_MASK 0x000C +#define HT_CAP_MIMO_PS_SHIFT 0x0002 +#define HT_CAP_MIMO_PS_OFF 0x0003 +#define HT_CAP_MIMO_PS_RTS 0x0001 +#define HT_CAP_MIMO_PS_ON 0x0000 +#define HT_CAP_GF 0x0010 +#define HT_CAP_SHORT_GI_20 0x0020 +#define HT_CAP_SHORT_GI_40 0x0040 +#define HT_CAP_TX_STBC 0x0080 +#define HT_CAP_RX_STBC_MASK 0x0300 +#define HT_CAP_RX_STBC_SHIFT 8 +#define HT_CAP_DELAYED_BA 0x0400 +#define HT_CAP_MAX_AMSDU 0x0800 + +#define HT_CAP_DSSS_CCK 0x1000 +#define HT_CAP_PSMP 0x2000 +#define HT_CAP_40MHZ_INTOLERANT 0x4000 +#define HT_CAP_LSIG_TXOP 0x8000 + +#define HT_CAP_RX_STBC_NO 0x0 +#define HT_CAP_RX_STBC_ONE_STREAM 0x1 +#define HT_CAP_RX_STBC_TWO_STREAM 0x2 +#define HT_CAP_RX_STBC_THREE_STREAM 0x3 + +#define VHT_MAX_MPDU 11454 +#define VHT_MPDU_MSDU_DELTA 56 + +#define VHT_MAX_AMSDU (VHT_MAX_MPDU - VHT_MPDU_MSDU_DELTA) + +#define HT_MAX_AMSDU 7935 +#define HT_MIN_AMSDU 3835 + +#define HT_PARAMS_RX_FACTOR_MASK 0x03 +#define HT_PARAMS_DENSITY_MASK 0x1C +#define HT_PARAMS_DENSITY_SHIFT 2 + + +#define AMPDU_MAX_MPDU_DENSITY 7 +#define AMPDU_RX_FACTOR_8K 0 +#define AMPDU_RX_FACTOR_16K 1 +#define AMPDU_RX_FACTOR_32K 2 +#define AMPDU_RX_FACTOR_64K 3 +#define AMPDU_RX_FACTOR_BASE 8*1024 + +#define AMPDU_DELIMITER_LEN 4 +#define AMPDU_DELIMITER_LEN_MAX 63 + +#define HT_CAP_EXT_PCO 0x0001 +#define HT_CAP_EXT_PCO_TTIME_MASK 0x0006 +#define HT_CAP_EXT_PCO_TTIME_SHIFT 1 +#define HT_CAP_EXT_MCS_FEEDBACK_MASK 0x0300 +#define HT_CAP_EXT_MCS_FEEDBACK_SHIFT 8 +#define HT_CAP_EXT_HTC 0x0400 +#define HT_CAP_EXT_RD_RESP 0x0800 BWL_PRE_PACKED_STRUCT struct ht_add_ie { - uint8 ctl_ch; - uint8 byte1; - uint16 opmode; - uint16 misc_bits; - uint8 basic_mcs[MCSSET_LEN]; + uint8 ctl_ch; + uint8 byte1; + uint16 opmode; + uint16 misc_bits; + uint8 basic_mcs[MCSSET_LEN]; } BWL_POST_PACKED_STRUCT; typedef struct ht_add_ie ht_add_ie_t; BWL_PRE_PACKED_STRUCT struct ht_prop_add_ie { - uint8 id; - uint8 len; - uint8 oui[3]; - uint8 type; + uint8 id; + uint8 len; + uint8 oui[3]; + uint8 type; ht_add_ie_t add_ie; } BWL_POST_PACKED_STRUCT; typedef struct ht_prop_add_ie ht_prop_add_ie_t; -#define HT_ADD_IE_LEN 22 -#define HT_ADD_IE_TYPE 52 +#define HT_ADD_IE_LEN 22 +#define HT_ADD_IE_TYPE 52 -#define HT_BW_ANY 0x04 -#define HT_RIFS_PERMITTED 0x08 +#define HT_BW_ANY 0x04 +#define HT_RIFS_PERMITTED 0x08 -#define HT_OPMODE_MASK 0x0003 -#define HT_OPMODE_SHIFT 0 -#define HT_OPMODE_PURE 0x0000 -#define HT_OPMODE_OPTIONAL 0x0001 -#define HT_OPMODE_HT20IN40 0x0002 -#define HT_OPMODE_MIXED 0x0003 -#define HT_OPMODE_NONGF 0x0004 -#define DOT11N_TXBURST 0x0008 -#define DOT11N_OBSS_NONHT 0x0010 +#define HT_OPMODE_MASK 0x0003 +#define HT_OPMODE_SHIFT 0 +#define HT_OPMODE_PURE 0x0000 +#define HT_OPMODE_OPTIONAL 0x0001 +#define HT_OPMODE_HT20IN40 0x0002 +#define HT_OPMODE_MIXED 0x0003 +#define HT_OPMODE_NONGF 0x0004 +#define DOT11N_TXBURST 0x0008 +#define DOT11N_OBSS_NONHT 0x0010 -#define HT_BASIC_STBC_MCS 0x007f -#define HT_DUAL_STBC_PROT 0x0080 -#define HT_SECOND_BCN 0x0100 -#define HT_LSIG_TXOP 0x0200 -#define HT_PCO_ACTIVE 0x0400 -#define HT_PCO_PHASE 0x0800 +#define HT_BASIC_STBC_MCS 0x007f +#define HT_DUAL_STBC_PROT 0x0080 +#define HT_SECOND_BCN 0x0100 +#define HT_LSIG_TXOP 0x0200 +#define HT_PCO_ACTIVE 0x0400 +#define HT_PCO_PHASE 0x0800 +#define HT_DUALCTS_PROTECTION 0x0080 -#define DOT11N_2G_TXBURST_LIMIT 6160 -#define DOT11N_5G_TXBURST_LIMIT 3080 +#define DOT11N_2G_TXBURST_LIMIT 6160 +#define DOT11N_5G_TXBURST_LIMIT 3080 -#define GET_HT_OPMODE(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ +#define GET_HT_OPMODE(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ >> HT_OPMODE_SHIFT) -#define HT_MIXEDMODE_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ - == HT_OPMODE_MIXED) -#define HT_HT20_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ - == HT_OPMODE_HT20IN40) -#define HT_OPTIONAL_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ - == HT_OPMODE_OPTIONAL) -#define HT_USE_PROTECTION(add_ie) (HT_HT20_PRESENT((add_ie)) || \ +#define HT_MIXEDMODE_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ + == HT_OPMODE_MIXED) +#define HT_HT20_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ + == HT_OPMODE_HT20IN40) +#define HT_OPTIONAL_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ + == HT_OPMODE_OPTIONAL) +#define HT_USE_PROTECTION(add_ie) (HT_HT20_PRESENT((add_ie)) || \ HT_MIXEDMODE_PRESENT((add_ie))) -#define HT_NONGF_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_NONGF) \ - == HT_OPMODE_NONGF) -#define DOT11N_TXBURST_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & DOT11N_TXBURST) \ - == DOT11N_TXBURST) -#define DOT11N_OBSS_NONHT_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & DOT11N_OBSS_NONHT) \ - == DOT11N_OBSS_NONHT) +#define HT_NONGF_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_NONGF) \ + == HT_OPMODE_NONGF) +#define DOT11N_TXBURST_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & DOT11N_TXBURST) \ + == DOT11N_TXBURST) +#define DOT11N_OBSS_NONHT_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & DOT11N_OBSS_NONHT) \ + == DOT11N_OBSS_NONHT) BWL_PRE_PACKED_STRUCT struct obss_params { - uint16 passive_dwell; - uint16 active_dwell; - uint16 bss_widthscan_interval; - uint16 passive_total; - uint16 active_total; - uint16 chanwidth_transition_dly; - uint16 activity_threshold; + uint16 passive_dwell; + uint16 active_dwell; + uint16 bss_widthscan_interval; + uint16 passive_total; + uint16 active_total; + uint16 chanwidth_transition_dly; + uint16 activity_threshold; } BWL_POST_PACKED_STRUCT; typedef struct obss_params obss_params_t; BWL_PRE_PACKED_STRUCT struct dot11_obss_ie { - uint8 id; - uint8 len; + uint8 id; + uint8 len; obss_params_t obss_params; } BWL_POST_PACKED_STRUCT; typedef struct dot11_obss_ie dot11_obss_ie_t; -#define DOT11_OBSS_SCAN_IE_LEN sizeof(obss_params_t) - - -#define HT_CTRL_LA_TRQ 0x00000002 -#define HT_CTRL_LA_MAI 0x0000003C -#define HT_CTRL_LA_MAI_SHIFT 2 -#define HT_CTRL_LA_MAI_MRQ 0x00000004 -#define HT_CTRL_LA_MAI_MSI 0x00000038 -#define HT_CTRL_LA_MFSI 0x000001C0 -#define HT_CTRL_LA_MFSI_SHIFT 6 -#define HT_CTRL_LA_MFB_ASELC 0x0000FE00 -#define HT_CTRL_LA_MFB_ASELC_SH 9 -#define HT_CTRL_LA_ASELC_CMD 0x00000C00 -#define HT_CTRL_LA_ASELC_DATA 0x0000F000 -#define HT_CTRL_CAL_POS 0x00030000 -#define HT_CTRL_CAL_SEQ 0x000C0000 -#define HT_CTRL_CSI_STEERING 0x00C00000 -#define HT_CTRL_CSI_STEER_SHIFT 22 -#define HT_CTRL_CSI_STEER_NFB 0 -#define HT_CTRL_CSI_STEER_CSI 1 -#define HT_CTRL_CSI_STEER_NCOM 2 -#define HT_CTRL_CSI_STEER_COM 3 -#define HT_CTRL_NDP_ANNOUNCE 0x01000000 -#define HT_CTRL_AC_CONSTRAINT 0x40000000 -#define HT_CTRL_RDG_MOREPPDU 0x80000000 - -#define HT_OPMODE_OPTIONAL 0x0001 -#define HT_OPMODE_HT20IN40 0x0002 -#define HT_OPMODE_MIXED 0x0003 -#define HT_OPMODE_NONGF 0x0004 -#define DOT11N_TXBURST 0x0008 -#define DOT11N_OBSS_NONHT 0x0010 - - - -#define WPA_OUI "\x00\x50\xF2" -#define WPA_OUI_LEN 3 -#define WPA_OUI_TYPE 1 -#define WPA_VERSION 1 -#define WPA2_OUI "\x00\x0F\xAC" -#define WPA2_OUI_LEN 3 -#define WPA2_VERSION 1 -#define WPA2_VERSION_LEN 2 - - -#define WPS_OUI "\x00\x50\xF2" -#define WPS_OUI_LEN 3 -#define WPS_OUI_TYPE 4 - - -#define WFA_OUI "\x50\x6F\x9A" -#define WFA_OUI_LEN 3 - -#define WFA_OUI_TYPE_WPA 1 -#define WFA_OUI_TYPE_WPS 4 -#define WFA_OUI_TYPE_TPC 8 -#define WFA_OUI_TYPE_P2P 9 - - -#define RSN_AKM_NONE 0 -#define RSN_AKM_UNSPECIFIED 1 -#define RSN_AKM_PSK 2 -#define RSN_AKM_FBT_1X 3 -#define RSN_AKM_FBT_PSK 4 +#define DOT11_OBSS_SCAN_IE_LEN sizeof(obss_params_t) + + +#define HT_CTRL_LA_TRQ 0x00000002 +#define HT_CTRL_LA_MAI 0x0000003C +#define HT_CTRL_LA_MAI_SHIFT 2 +#define HT_CTRL_LA_MAI_MRQ 0x00000004 +#define HT_CTRL_LA_MAI_MSI 0x00000038 +#define HT_CTRL_LA_MFSI 0x000001C0 +#define HT_CTRL_LA_MFSI_SHIFT 6 +#define HT_CTRL_LA_MFB_ASELC 0x0000FE00 +#define HT_CTRL_LA_MFB_ASELC_SH 9 +#define HT_CTRL_LA_ASELC_CMD 0x00000C00 +#define HT_CTRL_LA_ASELC_DATA 0x0000F000 +#define HT_CTRL_CAL_POS 0x00030000 +#define HT_CTRL_CAL_SEQ 0x000C0000 +#define HT_CTRL_CSI_STEERING 0x00C00000 +#define HT_CTRL_CSI_STEER_SHIFT 22 +#define HT_CTRL_CSI_STEER_NFB 0 +#define HT_CTRL_CSI_STEER_CSI 1 +#define HT_CTRL_CSI_STEER_NCOM 2 +#define HT_CTRL_CSI_STEER_COM 3 +#define HT_CTRL_NDP_ANNOUNCE 0x01000000 +#define HT_CTRL_AC_CONSTRAINT 0x40000000 +#define HT_CTRL_RDG_MOREPPDU 0x80000000 + +#define HT_OPMODE_OPTIONAL 0x0001 +#define HT_OPMODE_HT20IN40 0x0002 +#define HT_OPMODE_MIXED 0x0003 +#define HT_OPMODE_NONGF 0x0004 +#define DOT11N_TXBURST 0x0008 +#define DOT11N_OBSS_NONHT 0x0010 + + + +BWL_PRE_PACKED_STRUCT struct vht_cap_ie { + uint32 vht_cap_info; + + uint16 rx_mcs_map; + uint16 rx_max_rate; + uint16 tx_mcs_map; + uint16 tx_max_rate; +} BWL_POST_PACKED_STRUCT; +typedef struct vht_cap_ie vht_cap_ie_t; + +#define VHT_CAP_IE_LEN 12 + +#define VHT_CAP_INFO_MAX_MPDU_LEN_MASK 0x00000003 +#define VHT_CAP_INFO_SUPP_CHAN_WIDTH_MASK 0x0000000c +#define VHT_CAP_INFO_LDPC 0x00000010 +#define VHT_CAP_INFO_SGI_80MHZ 0x00000020 +#define VHT_CAP_INFO_SGI_160MHZ 0x00000040 +#define VHT_CAP_INFO_TX_STBC 0x00000080 + +#define VHT_CAP_INFO_RX_STBC_MASK 0x00000700 +#define VHT_CAP_INFO_RX_STBC_SHIFT 8 +#define VHT_CAP_INFO_SU_BEAMFMR 0x00000800 +#define VHT_CAP_INFO_SU_BEAMFMEE 0x00001000 +#define VHT_CAP_INFO_NUM_BMFMR_ANT_MASK 0x0000e000 +#define VHT_CAP_INFO_NUM_BMFMR_ANT_SHIFT 13 + +#define VHT_CAP_INFO_NUM_SOUNDING_DIM_MASK 0x00070000 +#define VHT_CAP_INFO_NUM_SOUNDING_DIM_SHIFT 16 +#define VHT_CAP_INFO_MU_BEAMFMR 0x00080000 +#define VHT_CAP_INFO_MU_BEAMFMEE 0x00100000 +#define VHT_CAP_INFO_TXOPPS 0x00200000 +#define VHT_CAP_INFO_HTCVHT 0x00400000 +#define VHT_CAP_INFO_AMPDU_MAXLEN_EXP_MASK 0x03800000 +#define VHT_CAP_INFO_AMPDU_MAXLEN_EXP_SHIFT 23 + +#define VHT_CAP_INFO_LINK_ADAPT_CAP_MASK 0x0c000000 +#define VHT_CAP_INFO_LINK_ADAPT_CAP_SHIFT 26 + + +#define VHT_CAP_SUPP_MCS_RX_HIGHEST_RATE_MASK 0x1fff +#define VHT_CAP_SUPP_MCS_RX_HIGHEST_RATE_SHIFT 0 + +#define VHT_CAP_SUPP_MCS_TX_HIGHEST_RATE_MASK 0x1fff +#define VHT_CAP_SUPP_MCS_TX_HIGHEST_RATE_SHIFT 0 + +#define VHT_CAP_MCS_MAP_0_7 0 +#define VHT_CAP_MCS_MAP_0_8 1 +#define VHT_CAP_MCS_MAP_0_9 2 +#define VHT_CAP_MCS_MAP_NONE 3 + +#define VHT_CAP_MCS_MAP_NSS_MAX 8 + + +typedef enum vht_cap_chan_width { + VHT_CAP_CHAN_WIDTH_20_40 = 0x00, + VHT_CAP_CHAN_WIDTH_80 = 0x04, + VHT_CAP_CHAN_WIDTH_160 = 0x08 +} vht_cap_chan_width_t; + + +typedef enum vht_cap_max_mpdu_len { + VHT_CAP_MPDU_MAX_4K = 0x00, + VHT_CAP_MPDU_MAX_8K = 0x01, + VHT_CAP_MPDU_MAX_11K = 0x02 +} vht_cap_max_mpdu_len_t; + + +BWL_PRE_PACKED_STRUCT struct vht_op_ie { + uint8 chan_width; + uint8 chan1; + uint8 chan2; + uint16 supp_mcs; +} BWL_POST_PACKED_STRUCT; +typedef struct vht_op_ie vht_op_ie_t; + +#define VHT_OP_IE_LEN 5 + +typedef enum vht_op_chan_width { + VHT_OP_CHAN_WIDTH_20_40 = 0, + VHT_OP_CHAN_WIDTH_80 = 1, + VHT_OP_CHAN_WIDTH_160 = 2, + VHT_OP_CHAN_WIDTH_80_80 = 3 +} vht_op_chan_width_t; + + +#define VHT_MCS_MAP_GET_SS_IDX(numSpatialStreams) ((numSpatialStreams-1)*2) +#define VHT_MCS_MAP_GET_MCS_PER_SS(numSpatialStreams, mcsMap) \ + ((mcsMap >> VHT_MCS_MAP_GET_SS_IDX(numSpatialStreams)) & 0x3) +#define VHT_MCS_MAP_SET_MCS_PER_SS(numSpatialStreams, numMcs, mcsMap) \ + (mcsMap |= ((numMcs & 0x3) << VHT_MCS_MAP_GET_SS_IDX(numSpatialStreams))) + + +#define WPA_OUI "\x00\x50\xF2" +#define WPA_OUI_LEN 3 +#define WPA_OUI_TYPE 1 +#define WPA_VERSION 1 +#define WPA2_OUI "\x00\x0F\xAC" +#define WPA2_OUI_LEN 3 +#define WPA2_VERSION 1 +#define WPA2_VERSION_LEN 2 + + +#define WPS_OUI "\x00\x50\xF2" +#define WPS_OUI_LEN 3 +#define WPS_OUI_TYPE 4 + + + +#ifdef P2P_IE_OVRD +#define WFA_OUI MAC_OUI +#else +#define WFA_OUI "\x50\x6F\x9A" +#endif +#define WFA_OUI_LEN 3 +#ifdef P2P_IE_OVRD +#define WFA_OUI_TYPE_P2P MAC_OUI_TYPE_P2P +#else +#define WFA_OUI_TYPE_P2P 9 +#endif + +#define WFA_OUI_TYPE_TPC 8 + + +#define RSN_AKM_NONE 0 +#define RSN_AKM_UNSPECIFIED 1 +#define RSN_AKM_PSK 2 +#define RSN_AKM_FBT_1X 3 +#define RSN_AKM_FBT_PSK 4 #define RSN_AKM_MFP_1X 5 #define RSN_AKM_MFP_PSK 6 #define RSN_AKM_TPK 7 -#define DOT11_MAX_DEFAULT_KEYS 4 -#define DOT11_MAX_KEY_SIZE 32 -#define DOT11_MAX_IV_SIZE 16 -#define DOT11_EXT_IV_FLAG (1<<5) +#define DOT11_MAX_DEFAULT_KEYS 4 +#define DOT11_MAX_KEY_SIZE 32 +#define DOT11_MAX_IV_SIZE 16 +#define DOT11_EXT_IV_FLAG (1<<5) #define DOT11_WPA_KEY_RSC_LEN 8 -#define WEP1_KEY_SIZE 5 -#define WEP1_KEY_HEX_SIZE 10 -#define WEP128_KEY_SIZE 13 -#define WEP128_KEY_HEX_SIZE 26 -#define TKIP_MIC_SIZE 8 -#define TKIP_EOM_SIZE 7 -#define TKIP_EOM_FLAG 0x5a -#define TKIP_KEY_SIZE 32 -#define TKIP_MIC_AUTH_TX 16 -#define TKIP_MIC_AUTH_RX 24 -#define TKIP_MIC_SUP_RX TKIP_MIC_AUTH_TX -#define TKIP_MIC_SUP_TX TKIP_MIC_AUTH_RX -#define AES_KEY_SIZE 16 -#define AES_MIC_SIZE 8 - - -#define WCN_OUI "\x00\x50\xf2" -#define WCN_TYPE 4 - +#define WEP1_KEY_SIZE 5 +#define WEP1_KEY_HEX_SIZE 10 +#define WEP128_KEY_SIZE 13 +#define WEP128_KEY_HEX_SIZE 26 +#define TKIP_MIC_SIZE 8 +#define TKIP_EOM_SIZE 7 +#define TKIP_EOM_FLAG 0x5a +#define TKIP_KEY_SIZE 32 +#define TKIP_MIC_AUTH_TX 16 +#define TKIP_MIC_AUTH_RX 24 +#define TKIP_MIC_SUP_RX TKIP_MIC_AUTH_TX +#define TKIP_MIC_SUP_TX TKIP_MIC_AUTH_RX +#define AES_KEY_SIZE 16 +#define AES_MIC_SIZE 8 +#define BIP_KEY_SIZE 16 + + +#define WCN_OUI "\x00\x50\xf2" +#define WCN_TYPE 4 + +#ifdef BCMWAPI_WPI +#define SMS4_KEY_LEN 16 +#define SMS4_WPI_CBC_MAC_LEN 16 +#endif @@ -1935,25 +2113,37 @@ typedef struct dot11_obss_ie dot11_obss_ie_t; BWL_PRE_PACKED_STRUCT struct dot11_mdid_ie { uint8 id; uint8 len; - uint16 mdid; + uint16 mdid; uint8 cap; } BWL_POST_PACKED_STRUCT; typedef struct dot11_mdid_ie dot11_mdid_ie_t; -#define FBT_MDID_CAP_OVERDS 0x01 -#define FBT_MDID_CAP_RRP 0x02 +#define FBT_MDID_CAP_OVERDS 0x01 +#define FBT_MDID_CAP_RRP 0x02 BWL_PRE_PACKED_STRUCT struct dot11_ft_ie { uint8 id; uint8 len; - uint16 mic_control; + uint16 mic_control; uint8 mic[16]; uint8 anonce[32]; uint8 snonce[32]; } BWL_POST_PACKED_STRUCT; typedef struct dot11_ft_ie dot11_ft_ie_t; +#define TIE_TYPE_RESERVED 0 +#define TIE_TYPE_REASSOC_DEADLINE 1 +#define TIE_TYPE_KEY_LIEFTIME 2 +#define TIE_TYPE_ASSOC_COMEBACK 3 +BWL_PRE_PACKED_STRUCT struct dot11_timeout_ie { + uint8 id; + uint8 len; + uint8 type; + uint32 value; +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_timeout_ie dot11_timeout_ie_t; + BWL_PRE_PACKED_STRUCT struct dot11_gtk_ie { uint8 id; @@ -1968,6 +2158,24 @@ typedef struct dot11_gtk_ie dot11_gtk_ie_t; #define BSSID_INVALID "\x00\x00\x00\x00\x00\x00" #define BSSID_BROADCAST "\xFF\xFF\xFF\xFF\xFF\xFF" +#ifdef BCMWAPI_WAI +#define WAPI_IE_MIN_LEN 20 +#define WAPI_VERSION 1 +#define WAPI_VERSION_LEN 2 +#define WAPI_OUI "\x00\x14\x72" +#define WAPI_OUI_LEN DOT11_OUI_LEN +#endif + + +#define WMM_OUI "\x00\x50\xF2" +#define WMM_OUI_LEN 3 +#define WMM_OUI_TYPE 2 +#define WMM_VERSION 1 +#define WMM_VERSION_LEN 1 + + +#define WMM_OUI_SUBTYPE_PARAMETER 1 +#define WMM_PARAMETER_IE_LEN 24 BWL_PRE_PACKED_STRUCT struct link_id_ie { diff --git a/drivers/net/wireless/bcmdhd/include/proto/802.11_bta.h b/drivers/net/wireless/bcmdhd/include/proto/802.11_bta.h index cbdd05e624b..3ee5a748695 100644 --- a/drivers/net/wireless/bcmdhd/include/proto/802.11_bta.h +++ b/drivers/net/wireless/bcmdhd/include/proto/802.11_bta.h @@ -1,9 +1,9 @@ /* * BT-AMP (BlueTooth Alternate Mac and Phy) 802.11 PAL (Protocol Adaptation Layer) * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: 802.11_bta.h 277737 2011-08-16 17:54:59Z $ + * $Id: 802.11_bta.h 294267 2011-11-04 23:41:52Z $ */ #ifndef _802_11_BTA_H_ diff --git a/drivers/net/wireless/bcmdhd/include/proto/802.11e.h b/drivers/net/wireless/bcmdhd/include/proto/802.11e.h index 0e070a475b6..f391e68c110 100644 --- a/drivers/net/wireless/bcmdhd/include/proto/802.11e.h +++ b/drivers/net/wireless/bcmdhd/include/proto/802.11e.h @@ -1,9 +1,9 @@ /* * 802.11e protocol header file * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: 802.11e.h 277737 2011-08-16 17:54:59Z $ + * $Id: 802.11e.h 241182 2011-02-17 21:50:03Z $ */ #ifndef _802_11e_H_ diff --git a/drivers/net/wireless/bcmdhd/include/proto/802.1d.h b/drivers/net/wireless/bcmdhd/include/proto/802.1d.h index c7e07bd5e7c..116a226b1b4 100644 --- a/drivers/net/wireless/bcmdhd/include/proto/802.1d.h +++ b/drivers/net/wireless/bcmdhd/include/proto/802.1d.h @@ -1,7 +1,7 @@ /* - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,10 +21,9 @@ * * Fundamental types and constants relating to 802.1D * - * $Id: 802.1d.h 277737 2011-08-16 17:54:59Z $ + * $Id: 802.1d.h 241182 2011-02-17 21:50:03Z $ */ - #ifndef _802_1_D_ #define _802_1_D_ diff --git a/drivers/net/wireless/bcmdhd/include/proto/bcmeth.h b/drivers/net/wireless/bcmdhd/include/proto/bcmeth.h index 0f75d3c8f1d..e54b2e38187 100644 --- a/drivers/net/wireless/bcmdhd/include/proto/bcmeth.h +++ b/drivers/net/wireless/bcmdhd/include/proto/bcmeth.h @@ -1,9 +1,9 @@ /* * Broadcom Ethernettype protocol definitions * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,12 +21,11 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: bcmeth.h 277737 2011-08-16 17:54:59Z $ + * $Id: bcmeth.h 294352 2011-11-06 19:23:00Z $ */ - #ifndef _BCMETH_H_ #define _BCMETH_H_ diff --git a/drivers/net/wireless/bcmdhd/include/proto/bcmevent.h b/drivers/net/wireless/bcmdhd/include/proto/bcmevent.h index e8c2387dd10..0da2b76b9c2 100644 --- a/drivers/net/wireless/bcmdhd/include/proto/bcmevent.h +++ b/drivers/net/wireless/bcmdhd/include/proto/bcmevent.h @@ -1,9 +1,9 @@ /* * Broadcom Event protocol definitions * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -23,13 +23,12 @@ * * Dependencies: proto/bcmeth.h * - * $Id: bcmevent.h 288077 2011-10-06 00:08:47Z $ + * $Id: bcmevent.h 294352 2011-11-06 19:23:00Z $ * */ - #ifndef _BCMEVENT_H_ #define _BCMEVENT_H_ @@ -138,22 +137,22 @@ typedef BWL_PRE_PACKED_STRUCT struct bcm_event { #define WLC_E_PROBREQ_MSG 44 #define WLC_E_SCAN_CONFIRM_IND 45 #define WLC_E_PSK_SUP 46 -#define WLC_E_COUNTRY_CODE_CHANGED 47 -#define WLC_E_EXCEEDED_MEDIUM_TIME 48 +#define WLC_E_COUNTRY_CODE_CHANGED 47 +#define WLC_E_EXCEEDED_MEDIUM_TIME 48 #define WLC_E_ICV_ERROR 49 -#define WLC_E_UNICAST_DECODE_ERROR 50 -#define WLC_E_MULTICAST_DECODE_ERROR 51 +#define WLC_E_UNICAST_DECODE_ERROR 50 +#define WLC_E_MULTICAST_DECODE_ERROR 51 #define WLC_E_TRACE 52 +#ifdef WLBTAMP #define WLC_E_BTA_HCI_EVENT 53 -#define WLC_E_IF 54 -#ifdef WLP2P -#define WLC_E_P2P_DISC_LISTEN_COMPLETE 55 #endif +#define WLC_E_IF 54 +#define WLC_E_P2P_DISC_LISTEN_COMPLETE 55 #define WLC_E_RSSI 56 #define WLC_E_PFN_SCAN_COMPLETE 57 #define WLC_E_EXTLOG_MSG 58 #define WLC_E_ACTION_FRAME 59 -#define WLC_E_ACTION_FRAME_COMPLETE 60 +#define WLC_E_ACTION_FRAME_COMPLETE 60 #define WLC_E_PRE_ASSOC_IND 61 #define WLC_E_PRE_REASSOC_IND 62 #define WLC_E_CHANNEL_ADOPTED 63 @@ -164,28 +163,28 @@ typedef BWL_PRE_PACKED_STRUCT struct bcm_event { #define WLC_E_WAI_MSG 68 #define WLC_E_ESCAN_RESULT 69 #define WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE 70 -#if defined(WLP2P) #define WLC_E_PROBRESP_MSG 71 #define WLC_E_P2P_PROBREQ_MSG 72 -#endif -#define WLC_E_DCS_REQUEST 73 +#define WLC_E_DCS_REQUEST 73 -#define WLC_E_FIFO_CREDIT_MAP 74 +#define WLC_E_FIFO_CREDIT_MAP 74 #define WLC_E_ACTION_FRAME_RX 75 #define WLC_E_WAKE_EVENT 76 #define WLC_E_RM_COMPLETE 77 #define WLC_E_HTSFSYNC 78 #define WLC_E_OVERLAY_REQ 79 -#define WLC_E_CSA_COMPLETE_IND 80 +#define WLC_E_CSA_COMPLETE_IND 80 #define WLC_E_EXCESS_PM_WAKE_EVENT 81 #define WLC_E_PFN_SCAN_NONE 82 -#define WLC_E_PFN_SCAN_ALLGONE 83 -#define WLC_E_GTK_PLUMBED 84 -#define WLC_E_ASSOC_REQ_IE 85 -#define WLC_E_ASSOC_RESP_IE 86 -#define WLC_E_LAST 87 +#define WLC_E_PFN_SCAN_ALLGONE 83 +#define WLC_E_GTK_PLUMBED 84 +#define WLC_E_ASSOC_IND_NDIS 85 +#define WLC_E_REASSOC_IND_NDIS 86 +#define WLC_E_ASSOC_REQ_IE 87 +#define WLC_E_ASSOC_RESP_IE 88 +#define WLC_E_LAST 89 typedef struct { @@ -280,7 +279,7 @@ typedef BWL_PRE_PACKED_STRUCT struct wl_event_rx_frame_data { typedef struct wl_event_data_if { - uint8 ifidx; + uint8 ifidx; uint8 opcode; uint8 reserved; uint8 bssidx; @@ -298,8 +297,10 @@ typedef struct wl_event_data_if { #define WLC_E_IF_ROLE_WDS 2 #define WLC_E_IF_ROLE_P2P_GO 3 #define WLC_E_IF_ROLE_P2P_CLIENT 4 +#ifdef WLBTAMP #define WLC_E_IF_ROLE_BTA_CREATOR 5 #define WLC_E_IF_ROLE_BTA_ACCEPTOR 6 +#endif #define WLC_E_LINK_BCN_LOSS 1 @@ -308,7 +309,7 @@ typedef struct wl_event_data_if { #define WLC_E_LINK_BSSCFG_DIS 4 -#define WLC_E_OVL_DOWNLOAD 0 +#define WLC_E_OVL_DOWNLOAD 0 #define WLC_E_OVL_UPDATE_IND 1 diff --git a/drivers/net/wireless/bcmdhd/include/proto/bcmip.h b/drivers/net/wireless/bcmdhd/include/proto/bcmip.h index 55eff247c49..d5c3b76da5a 100644 --- a/drivers/net/wireless/bcmdhd/include/proto/bcmip.h +++ b/drivers/net/wireless/bcmdhd/include/proto/bcmip.h @@ -1,7 +1,7 @@ /* - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,10 +21,9 @@ * * Fundamental constants relating to IP Protocol * - * $Id: bcmip.h 277737 2011-08-16 17:54:59Z $ + * $Id: bcmip.h 290206 2011-10-17 19:13:51Z $ */ - #ifndef _bcmip_h_ #define _bcmip_h_ @@ -47,8 +46,10 @@ ((((uint8 *)(ip_body))[IP_VER_OFFSET] & IP_VER_MASK) >> IP_VER_SHIFT) #define IP_PROT_ICMP 0x1 +#define IP_PROT_IGMP 0x2 #define IP_PROT_TCP 0x6 #define IP_PROT_UDP 0x11 +#define IP_PROT_ICMP6 0x3a #define IPV4_VER_HL_OFFSET 0 @@ -149,6 +150,61 @@ BWL_PRE_PACKED_STRUCT struct ipv4_hdr { IP_VER(ip_body) == IP_VER_6 ? IPV6_TRAFFIC_CLASS(ip_body) : 0) +#define IPV6_EXTHDR_HOP 0 +#define IPV6_EXTHDR_ROUTING 43 +#define IPV6_EXTHDR_FRAGMENT 44 +#define IPV6_EXTHDR_AUTH 51 +#define IPV6_EXTHDR_NONE 59 +#define IPV6_EXTHDR_DEST 60 + +#define IPV6_EXTHDR(prot) (((prot) == IPV6_EXTHDR_HOP) || \ + ((prot) == IPV6_EXTHDR_ROUTING) || \ + ((prot) == IPV6_EXTHDR_FRAGMENT) || \ + ((prot) == IPV6_EXTHDR_AUTH) || \ + ((prot) == IPV6_EXTHDR_NONE) || \ + ((prot) == IPV6_EXTHDR_DEST)) + +#define IPV6_MIN_HLEN 40 + +#define IPV6_EXTHDR_LEN(eh) ((((struct ipv6_exthdr *)(eh))->hdrlen + 1) << 3) + +BWL_PRE_PACKED_STRUCT struct ipv6_exthdr { + uint8 nexthdr; + uint8 hdrlen; +} BWL_POST_PACKED_STRUCT; + +BWL_PRE_PACKED_STRUCT struct ipv6_exthdr_frag { + uint8 nexthdr; + uint8 rsvd; + uint16 frag_off; + uint32 ident; +} BWL_POST_PACKED_STRUCT; + +static INLINE int32 +ipv6_exthdr_len(uint8 *h, uint8 *proto) +{ + uint16 len = 0, hlen; + struct ipv6_exthdr *eh = (struct ipv6_exthdr *)h; + + while (IPV6_EXTHDR(eh->nexthdr)) { + if (eh->nexthdr == IPV6_EXTHDR_NONE) + return -1; + else if (eh->nexthdr == IPV6_EXTHDR_FRAGMENT) + hlen = 8; + else if (eh->nexthdr == IPV6_EXTHDR_AUTH) + hlen = (eh->hdrlen + 2) << 2; + else + hlen = IPV6_EXTHDR_LEN(eh); + + len += hlen; + eh = (struct ipv6_exthdr *)(h + len); + } + + *proto = eh->nexthdr; + return len; +} + + #include #endif diff --git a/drivers/net/wireless/bcmdhd/include/proto/bcmipv6.h b/drivers/net/wireless/bcmdhd/include/proto/bcmipv6.h new file mode 100644 index 00000000000..95333918274 --- /dev/null +++ b/drivers/net/wireless/bcmdhd/include/proto/bcmipv6.h @@ -0,0 +1,104 @@ +/* + * Copyright (C) 1999-2012, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * Fundamental constants relating to Neighbor Discovery Protocol + * + * $Id: bcmipv6.h 309193 2012-01-19 00:03:57Z $ + */ + +#ifndef _bcmipv6_h_ +#define _bcmipv6_h_ + +#ifndef _TYPEDEFS_H_ +#include +#endif + +/* This marks the start of a packed structure section. */ +#include + +#define ICMPV6_HEADER_TYPE 0x3A +#define ICMPV6_PKT_TYPE_NS 135 +#define ICMPV6_PKT_TYPE_NA 136 + +#define ICMPV6_ND_OPT_TYPE_TARGET_MAC 2 +#define ICMPV6_ND_OPT_TYPE_SRC_MAC 1 + +#define IPV6_VERSION 6 +#define IPV6_HOP_LIMIT 255 + +#define IPV6_ADDR_NULL(a) ((a[0] | a[1] | a[2] | a[3] | a[4] | \ + a[5] | a[6] | a[7] | a[8] | a[9] | \ + a[10] | a[11] | a[12] | a[13] | \ + a[14] | a[15]) == 0) + +/* IPV6 address */ +BWL_PRE_PACKED_STRUCT struct ipv6_addr { + uint8 addr[16]; +} BWL_POST_PACKED_STRUCT; + + +/* ICMPV6 Header */ +BWL_PRE_PACKED_STRUCT struct icmp6_hdr { + uint8 icmp6_type; + uint8 icmp6_code; + uint16 icmp6_cksum; + BWL_PRE_PACKED_STRUCT union { + uint32 reserved; + BWL_PRE_PACKED_STRUCT struct nd_advt { + uint32 reserved1:5, + override:1, + solicited:1, + router:1, + reserved2:24; + } BWL_POST_PACKED_STRUCT nd_advt; + } BWL_POST_PACKED_STRUCT opt; +} BWL_POST_PACKED_STRUCT; + +/* Ipv6 Header Format */ +BWL_PRE_PACKED_STRUCT struct ipv6_hdr { + uint8 priority:4, + version:4; + uint8 flow_lbl[3]; + uint16 payload_len; + uint8 nexthdr; + uint8 hop_limit; + struct ipv6_addr saddr; + struct ipv6_addr daddr; +} BWL_POST_PACKED_STRUCT; + +/* Neighbor Advertisement/Solicitation Packet Structure */ +BWL_PRE_PACKED_STRUCT struct nd_msg { + struct icmp6_hdr icmph; + struct ipv6_addr target; +} BWL_POST_PACKED_STRUCT; + + +/* Neighibor Solicitation/Advertisement Optional Structure */ +BWL_PRE_PACKED_STRUCT struct nd_msg_opt { + uint8 type; + uint8 len; + uint8 mac_addr[ETHER_ADDR_LEN]; +} BWL_POST_PACKED_STRUCT; + +/* This marks the end of a packed structure section. */ +#include + +#endif /* !defined(_bcmipv6_h_) */ diff --git a/drivers/net/wireless/bcmdhd/include/proto/bt_amp_hci.h b/drivers/net/wireless/bcmdhd/include/proto/bt_amp_hci.h index 91ab4fe538f..8617985dd36 100644 --- a/drivers/net/wireless/bcmdhd/include/proto/bt_amp_hci.h +++ b/drivers/net/wireless/bcmdhd/include/proto/bt_amp_hci.h @@ -1,9 +1,9 @@ /* * BT-AMP (BlueTooth Alternate Mac and Phy) HCI (Host/Controller Interface) * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: bt_amp_hci.h 277737 2011-08-16 17:54:59Z $ + * $Id: bt_amp_hci.h 294267 2011-11-04 23:41:52Z $ */ #ifndef _bt_amp_hci_h @@ -211,7 +211,6 @@ typedef BWL_PRE_PACKED_STRUCT struct amp_hci_event { #define HCI_Short_Range_Mode_Change_Complete_Event_Mask 0x1000 #define HCI_Status_Change_Event_Mask 0x2000 #define HCI_All_Event_Mask 0x31e7 - /* AMP HCI event parameters */ typedef BWL_PRE_PACKED_STRUCT struct cmd_status_parms { uint8 status; diff --git a/drivers/net/wireless/bcmdhd/include/proto/eapol.h b/drivers/net/wireless/bcmdhd/include/proto/eapol.h index 92634c1221a..8936d1641a3 100644 --- a/drivers/net/wireless/bcmdhd/include/proto/eapol.h +++ b/drivers/net/wireless/bcmdhd/include/proto/eapol.h @@ -7,7 +7,7 @@ * * Copyright (C) 2002 Broadcom Corporation * - * $Id: eapol.h 277737 2011-08-16 17:54:59Z $ + * $Id: eapol.h 241182 2011-02-17 21:50:03Z $ */ #ifndef _eapol_h_ @@ -23,16 +23,24 @@ #include /* EAPOL for 802.3/Ethernet */ -typedef struct { +typedef BWL_PRE_PACKED_STRUCT struct { struct ether_header eth; /* 802.3/Ethernet header */ unsigned char version; /* EAPOL protocol version */ unsigned char type; /* EAPOL type */ unsigned short length; /* Length of body */ unsigned char body[1]; /* Body (optional) */ -} eapol_header_t; +} BWL_POST_PACKED_STRUCT eapol_header_t; #define EAPOL_HEADER_LEN 18 +typedef struct { + unsigned char version; /* EAPOL protocol version */ + unsigned char type; /* EAPOL type */ + unsigned short length; /* Length of body */ +} eapol_hdr_t; + +#define EAPOL_HDR_LEN 4 + /* EAPOL version */ #define WPA2_EAPOL_VERSION 2 #define WPA_EAPOL_VERSION 1 @@ -116,6 +124,8 @@ typedef BWL_PRE_PACKED_STRUCT struct { #define WPA_KEY_ERROR 0x400 #define WPA_KEY_REQ 0x800 +#define WPA_KEY_DESC_V2_OR_V3 WPA_KEY_DESC_V2 + /* WPA-only KEY KEY_INFO bits */ #define WPA_KEY_INDEX_0 0x00 #define WPA_KEY_INDEX_1 0x10 @@ -142,6 +152,7 @@ typedef BWL_PRE_PACKED_STRUCT struct { #define WPA2_KEY_DATA_SUBTYPE_STAKEY 2 #define WPA2_KEY_DATA_SUBTYPE_MAC 3 #define WPA2_KEY_DATA_SUBTYPE_PMKID 4 +#define WPA2_KEY_DATA_SUBTYPE_IGTK 9 /* GTK encapsulation */ typedef BWL_PRE_PACKED_STRUCT struct { @@ -157,6 +168,15 @@ typedef BWL_PRE_PACKED_STRUCT struct { #define WPA2_GTK_TRANSMIT 0x04 +/* IGTK encapsulation */ +typedef BWL_PRE_PACKED_STRUCT struct { + uint16 key_id; + uint8 ipn[6]; + uint8 key[EAPOL_WPA_MAX_KEY_SIZE]; +} BWL_POST_PACKED_STRUCT eapol_wpa2_key_igtk_encap_t; + +#define EAPOL_WPA2_KEY_IGTK_ENCAP_HDR_LEN 8 + /* STAKey encapsulation */ typedef BWL_PRE_PACKED_STRUCT struct { uint8 reserved[2]; diff --git a/drivers/net/wireless/bcmdhd/include/proto/ethernet.h b/drivers/net/wireless/bcmdhd/include/proto/ethernet.h index 20865dc5a23..e45518564c1 100644 --- a/drivers/net/wireless/bcmdhd/include/proto/ethernet.h +++ b/drivers/net/wireless/bcmdhd/include/proto/ethernet.h @@ -1,9 +1,9 @@ /* * From FreeBSD 2.2.7: Fundamental constants relating to ethernet. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,10 +21,9 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: ethernet.h 285437 2011-09-21 22:16:56Z $ + * $Id: ethernet.h 309193 2012-01-19 00:03:57Z $ */ - #ifndef _NET_ETHERNET_H_ #define _NET_ETHERNET_H_ @@ -65,16 +64,17 @@ #define ETHER_TYPE_IP 0x0800 #define ETHER_TYPE_ARP 0x0806 #define ETHER_TYPE_8021Q 0x8100 +#define ETHER_TYPE_IPV6 0x86dd #define ETHER_TYPE_BRCM 0x886c #define ETHER_TYPE_802_1X 0x888e #define ETHER_TYPE_802_1X_PREAUTH 0x88c7 #define ETHER_TYPE_WAI 0x88b4 #define ETHER_TYPE_89_0D 0x890d +#define ETHER_TYPE_IPV6 0x86dd #define ETHER_BRCM_SUBTYPE_LEN 4 -#define ETHER_BRCM_CRAM 1 #define ETHER_DEST_OFFSET (0 * ETHER_ADDR_LEN) @@ -111,7 +111,7 @@ BWL_PRE_PACKED_STRUCT struct ether_addr { #define ETHER_SET_LOCALADDR(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] | 2)) #define ETHER_IS_LOCALADDR(ea) (((uint8 *)(ea))[0] & 2) -#define ETHER_CLR_LOCALADDR(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] & 0xd)) +#define ETHER_CLR_LOCALADDR(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] & 0xfd)) #define ETHER_TOGGLE_LOCALADDR(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] ^ 2)) @@ -122,15 +122,15 @@ BWL_PRE_PACKED_STRUCT struct ether_addr { -#define ether_cmp(a, b) (!(((short*)a)[0] == ((short*)b)[0]) | \ - !(((short*)a)[1] == ((short*)b)[1]) | \ - !(((short*)a)[2] == ((short*)b)[2])) +#define ether_cmp(a, b) (!(((short*)(a))[0] == ((short*)(b))[0]) | \ + !(((short*)(a))[1] == ((short*)(b))[1]) | \ + !(((short*)(a))[2] == ((short*)(b))[2])) #define ether_copy(s, d) { \ - ((short*)d)[0] = ((short*)s)[0]; \ - ((short*)d)[1] = ((short*)s)[1]; \ - ((short*)d)[2] = ((short*)s)[2]; } + ((short*)(d))[0] = ((const short*)(s))[0]; \ + ((short*)(d))[1] = ((const short*)(s))[1]; \ + ((short*)(d))[2] = ((const short*)(s))[2]; } static const struct ether_addr ether_bcast = {{255, 255, 255, 255, 255, 255}}; @@ -149,7 +149,6 @@ static const struct ether_addr ether_null = {{0, 0, 0, 0, 0, 0}}; ((uint8 *)(ea))[4] | \ ((uint8 *)(ea))[5]) == 0) - #define ETHER_MOVE_HDR(d, s) \ do { \ struct ether_header t; \ diff --git a/drivers/net/wireless/bcmdhd/include/proto/p2p.h b/drivers/net/wireless/bcmdhd/include/proto/p2p.h index d2bf3f20688..27996406f06 100644 --- a/drivers/net/wireless/bcmdhd/include/proto/p2p.h +++ b/drivers/net/wireless/bcmdhd/include/proto/p2p.h @@ -1,7 +1,7 @@ /* - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,7 +21,7 @@ * * Fundamental types and constants relating to WFA P2P (aka WiFi Direct) * - * $Id: p2p.h 277737 2011-08-16 17:54:59Z $ + * $Id: p2p.h 281528 2011-09-02 17:13:26Z $ */ #ifndef _P2P_H_ @@ -33,355 +33,349 @@ #include #include -/* This marks the start of a packed structure section. */ + #include -/* WiFi P2P OUI values */ -#define P2P_OUI WFA_OUI /* WiFi P2P OUI */ -#define P2P_VER WFA_OUI_TYPE_P2P /* P2P version: 9=WiFi P2P v1.0 */ -#define P2P_IE_ID 0xdd /* P2P IE element ID */ +#define P2P_OUI WFA_OUI +#define P2P_VER WFA_OUI_TYPE_P2P + +#define P2P_IE_ID 0xdd + -/* WiFi P2P IE */ BWL_PRE_PACKED_STRUCT struct wifi_p2p_ie { - uint8 id; /* IE ID: 0xDD */ - uint8 len; /* IE length */ - uint8 OUI[3]; /* WiFi P2P specific OUI: P2P_OUI */ - uint8 oui_type; /* Identifies P2P version: P2P_VER */ - uint8 subelts[1]; /* variable length subelements */ + uint8 id; + uint8 len; + uint8 OUI[3]; + uint8 oui_type; + uint8 subelts[1]; } BWL_POST_PACKED_STRUCT; typedef struct wifi_p2p_ie wifi_p2p_ie_t; -#define P2P_IE_FIXED_LEN 6 - -#define P2P_ATTR_ID_OFF 0 -#define P2P_ATTR_LEN_OFF 1 -#define P2P_ATTR_DATA_OFF 3 - -#define P2P_ATTR_HDR_LEN 3 /* ID + 2-byte length field spec 1.02 */ - -/* P2P IE Subelement IDs from WiFi P2P Technical Spec 1.00 */ -#define P2P_SEID_STATUS 0 /* Status */ -#define P2P_SEID_MINOR_RC 1 /* Minor Reason Code */ -#define P2P_SEID_P2P_INFO 2 /* P2P Capability (capabilities info) */ -#define P2P_SEID_DEV_ID 3 /* P2P Device ID */ -#define P2P_SEID_INTENT 4 /* Group Owner Intent */ -#define P2P_SEID_CFG_TIMEOUT 5 /* Configuration Timeout */ -#define P2P_SEID_CHANNEL 6 /* Channel */ -#define P2P_SEID_GRP_BSSID 7 /* P2P Group BSSID */ -#define P2P_SEID_XT_TIMING 8 /* Extended Listen Timing */ -#define P2P_SEID_INTINTADDR 9 /* Intended P2P Interface Address */ -#define P2P_SEID_P2P_MGBTY 10 /* P2P Manageability */ -#define P2P_SEID_CHAN_LIST 11 /* Channel List */ -#define P2P_SEID_ABSENCE 12 /* Notice of Absence */ -#define P2P_SEID_DEV_INFO 13 /* Device Info */ -#define P2P_SEID_GROUP_INFO 14 /* Group Info */ -#define P2P_SEID_GROUP_ID 15 /* Group ID */ -#define P2P_SEID_P2P_IF 16 /* P2P Interface */ -#define P2P_SEID_VNDR 221 /* Vendor-specific subelement */ - -#define P2P_SE_VS_ID_SERVICES 0x1b /* BRCM proprietary subel: L2 Services */ - - -/* WiFi P2P IE subelement: P2P Capability (capabilities info) */ +#define P2P_IE_FIXED_LEN 6 + +#define P2P_ATTR_ID_OFF 0 +#define P2P_ATTR_LEN_OFF 1 +#define P2P_ATTR_DATA_OFF 3 + +#define P2P_ATTR_HDR_LEN 3 + + +#define P2P_SEID_STATUS 0 +#define P2P_SEID_MINOR_RC 1 +#define P2P_SEID_P2P_INFO 2 +#define P2P_SEID_DEV_ID 3 +#define P2P_SEID_INTENT 4 +#define P2P_SEID_CFG_TIMEOUT 5 +#define P2P_SEID_CHANNEL 6 +#define P2P_SEID_GRP_BSSID 7 +#define P2P_SEID_XT_TIMING 8 +#define P2P_SEID_INTINTADDR 9 +#define P2P_SEID_P2P_MGBTY 10 +#define P2P_SEID_CHAN_LIST 11 +#define P2P_SEID_ABSENCE 12 +#define P2P_SEID_DEV_INFO 13 +#define P2P_SEID_GROUP_INFO 14 +#define P2P_SEID_GROUP_ID 15 +#define P2P_SEID_P2P_IF 16 +#define P2P_SEID_VNDR 221 + +#define P2P_SE_VS_ID_SERVICES 0x1b + + + BWL_PRE_PACKED_STRUCT struct wifi_p2p_info_se_s { - uint8 eltId; /* SE ID: P2P_SEID_P2P_INFO */ - uint8 len[2]; /* SE length not including eltId, len fields */ - uint8 dev; /* Device Capability Bitmap */ - uint8 group; /* Group Capability Bitmap */ + uint8 eltId; + uint8 len[2]; + uint8 dev; + uint8 group; } BWL_POST_PACKED_STRUCT; typedef struct wifi_p2p_info_se_s wifi_p2p_info_se_t; -/* P2P Capability subelement's Device Capability Bitmap bit values */ -#define P2P_CAPSE_DEV_SERVICE_DIS 0x1 /* Service Discovery */ -#define P2P_CAPSE_DEV_CLIENT_DIS 0x2 /* Client Discoverability */ -#define P2P_CAPSE_DEV_CONCURRENT 0x4 /* Concurrent Operation */ -#define P2P_CAPSE_DEV_INFRA_MAN 0x8 /* P2P Infrastructure Managed */ -#define P2P_CAPSE_DEV_LIMIT 0x10 /* P2P Device Limit */ -#define P2P_CAPSE_INVITE_PROC 0x20 /* P2P Invitation Procedure */ - -/* P2P Capability subelement's Group Capability Bitmap bit values */ -#define P2P_CAPSE_GRP_OWNER 0x1 /* P2P Group Owner */ -#define P2P_CAPSE_PERSIST_GRP 0x2 /* Persistent P2P Group */ -#define P2P_CAPSE_GRP_LIMIT 0x4 /* P2P Group Limit */ -#define P2P_CAPSE_GRP_INTRA_BSS 0x8 /* Intra-BSS Distribution */ -#define P2P_CAPSE_GRP_X_CONNECT 0x10 /* Cross Connection */ -#define P2P_CAPSE_GRP_PERSISTENT 0x20 /* Persistent Reconnect */ -#define P2P_CAPSE_GRP_FORMATION 0x40 /* Group Formation */ - - -/* WiFi P2P IE subelement: Group Owner Intent */ + +#define P2P_CAPSE_DEV_SERVICE_DIS 0x1 +#define P2P_CAPSE_DEV_CLIENT_DIS 0x2 +#define P2P_CAPSE_DEV_CONCURRENT 0x4 +#define P2P_CAPSE_DEV_INFRA_MAN 0x8 +#define P2P_CAPSE_DEV_LIMIT 0x10 +#define P2P_CAPSE_INVITE_PROC 0x20 + + +#define P2P_CAPSE_GRP_OWNER 0x1 +#define P2P_CAPSE_PERSIST_GRP 0x2 +#define P2P_CAPSE_GRP_LIMIT 0x4 +#define P2P_CAPSE_GRP_INTRA_BSS 0x8 +#define P2P_CAPSE_GRP_X_CONNECT 0x10 +#define P2P_CAPSE_GRP_PERSISTENT 0x20 +#define P2P_CAPSE_GRP_FORMATION 0x40 + + + BWL_PRE_PACKED_STRUCT struct wifi_p2p_intent_se_s { - uint8 eltId; /* SE ID: P2P_SEID_INTENT */ - uint8 len[2]; /* SE length not including eltId, len fields */ - uint8 intent; /* Intent Value 0...15 (0=legacy 15=master only) */ + uint8 eltId; + uint8 len[2]; + uint8 intent; } BWL_POST_PACKED_STRUCT; typedef struct wifi_p2p_intent_se_s wifi_p2p_intent_se_t; -/* WiFi P2P IE subelement: Configuration Timeout */ + BWL_PRE_PACKED_STRUCT struct wifi_p2p_cfg_tmo_se_s { - uint8 eltId; /* SE ID: P2P_SEID_CFG_TIMEOUT */ - uint8 len[2]; /* SE length not including eltId, len fields */ - uint8 go_tmo; /* GO config timeout in units of 10 ms */ - uint8 client_tmo; /* Client config timeout in units of 10 ms */ + uint8 eltId; + uint8 len[2]; + uint8 go_tmo; + uint8 client_tmo; } BWL_POST_PACKED_STRUCT; typedef struct wifi_p2p_cfg_tmo_se_s wifi_p2p_cfg_tmo_se_t; -/* WiFi P2P IE subelement: Status */ + BWL_PRE_PACKED_STRUCT struct wifi_p2p_status_se_s { - uint8 eltId; /* SE ID: P2P_SEID_STATUS */ - uint8 len[2]; /* SE length not including eltId, len fields */ - uint8 status; /* Status Code: P2P_STATSE_* */ + uint8 eltId; + uint8 len[2]; + uint8 status; } BWL_POST_PACKED_STRUCT; typedef struct wifi_p2p_status_se_s wifi_p2p_status_se_t; -/* Status subelement Status Code definitions */ -#define P2P_STATSE_SUCCESS 0 - /* Success */ -#define P2P_STATSE_FAIL_INFO_CURR_UNAVAIL 1 - /* Failed, information currently unavailable */ -#define P2P_STATSE_PASSED_UP P2P_STATSE_FAIL_INFO_CURR_UNAVAIL - /* Old name for above in P2P spec 1.08 and older */ -#define P2P_STATSE_FAIL_INCOMPAT_PARAMS 2 - /* Failed, incompatible parameters */ -#define P2P_STATSE_FAIL_LIMIT_REACHED 3 - /* Failed, limit reached */ -#define P2P_STATSE_FAIL_INVALID_PARAMS 4 - /* Failed, invalid parameters */ -#define P2P_STATSE_FAIL_UNABLE_TO_ACCOM 5 - /* Failed, unable to accomodate request */ -#define P2P_STATSE_FAIL_PROTO_ERROR 6 - /* Failed, previous protocol error or disruptive behaviour */ -#define P2P_STATSE_FAIL_NO_COMMON_CHAN 7 - /* Failed, no common channels */ -#define P2P_STATSE_FAIL_UNKNOWN_GROUP 8 - /* Failed, unknown P2P Group */ -#define P2P_STATSE_FAIL_INTENT 9 - /* Failed, both peers indicated Intent 15 in GO Negotiation */ -#define P2P_STATSE_FAIL_INCOMPAT_PROVIS 10 - /* Failed, incompatible provisioning method */ -#define P2P_STATSE_FAIL_USER_REJECT 11 - /* Failed, rejected by user */ - -/* WiFi P2P IE attribute: Extended Listen Timing */ + +#define P2P_STATSE_SUCCESS 0 + +#define P2P_STATSE_FAIL_INFO_CURR_UNAVAIL 1 + +#define P2P_STATSE_PASSED_UP P2P_STATSE_FAIL_INFO_CURR_UNAVAIL + +#define P2P_STATSE_FAIL_INCOMPAT_PARAMS 2 + +#define P2P_STATSE_FAIL_LIMIT_REACHED 3 + +#define P2P_STATSE_FAIL_INVALID_PARAMS 4 + +#define P2P_STATSE_FAIL_UNABLE_TO_ACCOM 5 + +#define P2P_STATSE_FAIL_PROTO_ERROR 6 + +#define P2P_STATSE_FAIL_NO_COMMON_CHAN 7 + +#define P2P_STATSE_FAIL_UNKNOWN_GROUP 8 + +#define P2P_STATSE_FAIL_INTENT 9 + +#define P2P_STATSE_FAIL_INCOMPAT_PROVIS 10 + +#define P2P_STATSE_FAIL_USER_REJECT 11 + + + BWL_PRE_PACKED_STRUCT struct wifi_p2p_ext_se_s { - uint8 eltId; /* ID: P2P_SEID_EXT_TIMING */ - uint8 len[2]; /* length not including eltId, len fields */ - uint8 avail[2]; /* availibility period */ - uint8 interval[2]; /* availibility interval */ + uint8 eltId; + uint8 len[2]; + uint8 avail[2]; + uint8 interval[2]; } BWL_POST_PACKED_STRUCT; typedef struct wifi_p2p_ext_se_s wifi_p2p_ext_se_t; -#define P2P_EXT_MIN 10 /* minimum 10ms */ +#define P2P_EXT_MIN 10 + -/* WiFi P2P IE subelement: Intended P2P Interface Address */ BWL_PRE_PACKED_STRUCT struct wifi_p2p_intintad_se_s { - uint8 eltId; /* SE ID: P2P_SEID_INTINTADDR */ - uint8 len[2]; /* SE length not including eltId, len fields */ - uint8 mac[6]; /* intended P2P interface MAC address */ + uint8 eltId; + uint8 len[2]; + uint8 mac[6]; } BWL_POST_PACKED_STRUCT; typedef struct wifi_p2p_intintad_se_s wifi_p2p_intintad_se_t; -/* WiFi P2P IE subelement: Channel */ + BWL_PRE_PACKED_STRUCT struct wifi_p2p_channel_se_s { - uint8 eltId; /* SE ID: P2P_SEID_STATUS */ - uint8 len[2]; /* SE length not including eltId, len fields */ - uint8 band; /* Regulatory Class (band) */ - uint8 channel; /* Channel */ + uint8 eltId; + uint8 len[2]; + uint8 band; + uint8 channel; } BWL_POST_PACKED_STRUCT; typedef struct wifi_p2p_channel_se_s wifi_p2p_channel_se_t; -/* Channel Entry structure within the Channel List SE */ + BWL_PRE_PACKED_STRUCT struct wifi_p2p_chanlist_entry_s { - uint8 band; /* Regulatory Class (band) */ - uint8 num_channels; /* # of channels in the channel list */ - uint8 channels[WL_NUMCHANNELS]; /* Channel List */ + uint8 band; + uint8 num_channels; + uint8 channels[WL_NUMCHANNELS]; } BWL_POST_PACKED_STRUCT; typedef struct wifi_p2p_chanlist_entry_s wifi_p2p_chanlist_entry_t; #define WIFI_P2P_CHANLIST_SE_MAX_ENTRIES 2 -/* WiFi P2P IE subelement: Channel List */ + BWL_PRE_PACKED_STRUCT struct wifi_p2p_chanlist_se_s { - uint8 eltId; /* SE ID: P2P_SEID_STATUS */ - uint8 len[2]; /* SE length not including eltId, len fields */ - uint8 country[3]; /* Country String */ - uint8 num_entries; /* # of channel entries */ - wifi_p2p_chanlist_entry_t entries[WIFI_P2P_CHANLIST_SE_MAX_ENTRIES]; - /* Channel Entry List */ + uint8 eltId; + uint8 len[2]; + uint8 country[3]; + uint8 num_entries; + wifi_p2p_chanlist_entry_t entries[WIFI_P2P_CHANLIST_SE_MAX_ENTRIES]; + } BWL_POST_PACKED_STRUCT; typedef struct wifi_p2p_chanlist_se_s wifi_p2p_chanlist_se_t; -/* WiFi P2P IE's Device Info subelement */ + BWL_PRE_PACKED_STRUCT struct wifi_p2p_devinfo_se_s { - uint8 eltId; /* SE ID: P2P_SEID_DEVINFO */ - uint8 len[2]; /* SE length not including eltId, len fields */ - uint8 mac[6]; /* P2P Device MAC address */ - uint16 wps_cfg_meths; /* Config Methods: reg_prototlv.h WPS_CONFMET_* */ - uint8 pri_devtype[8]; /* Primary Device Type */ + uint8 eltId; + uint8 len[2]; + uint8 mac[6]; + uint16 wps_cfg_meths; + uint8 pri_devtype[8]; } BWL_POST_PACKED_STRUCT; typedef struct wifi_p2p_devinfo_se_s wifi_p2p_devinfo_se_t; -#define P2P_DEV_TYPE_LEN 8 +#define P2P_DEV_TYPE_LEN 8 + -/* WiFi P2P IE's Group Info subelement Client Info Descriptor */ BWL_PRE_PACKED_STRUCT struct wifi_p2p_cid_fixed_s { - uint8 len; - uint8 devaddr[ETHER_ADDR_LEN]; /* P2P Device Address */ - uint8 ifaddr[ETHER_ADDR_LEN]; /* P2P Interface Address */ - uint8 devcap; /* Device Capability */ - uint8 cfg_meths[2]; /* Config Methods: reg_prototlv.h WPS_CONFMET_* */ - uint8 pridt[P2P_DEV_TYPE_LEN]; /* Primary Device Type */ - uint8 secdts; /* Number of Secondary Device Types */ + uint8 len; + uint8 devaddr[ETHER_ADDR_LEN]; + uint8 ifaddr[ETHER_ADDR_LEN]; + uint8 devcap; + uint8 cfg_meths[2]; + uint8 pridt[P2P_DEV_TYPE_LEN]; + uint8 secdts; } BWL_POST_PACKED_STRUCT; typedef struct wifi_p2p_cid_fixed_s wifi_p2p_cid_fixed_t; -/* WiFi P2P IE's Device ID subelement */ + BWL_PRE_PACKED_STRUCT struct wifi_p2p_devid_se_s { - uint8 eltId; - uint8 len[2]; - struct ether_addr addr; /* P2P Device MAC address */ + uint8 eltId; + uint8 len[2]; + struct ether_addr addr; } BWL_POST_PACKED_STRUCT; typedef struct wifi_p2p_devid_se_s wifi_p2p_devid_se_t; -/* WiFi P2P IE subelement: P2P Manageability */ + BWL_PRE_PACKED_STRUCT struct wifi_p2p_mgbt_se_s { - uint8 eltId; /* SE ID: P2P_SEID_P2P_MGBTY */ - uint8 len[2]; /* SE length not including eltId, len fields */ - uint8 mg_bitmap; /* manageability bitmap */ + uint8 eltId; + uint8 len[2]; + uint8 mg_bitmap; } BWL_POST_PACKED_STRUCT; typedef struct wifi_p2p_mgbt_se_s wifi_p2p_mgbt_se_t; -/* mg_bitmap field bit values */ -#define P2P_MGBTSE_P2PDEVMGMT_FLAG 0x1 /* AP supports Managed P2P Device */ -/* WiFi P2P IE subelement: Group Info */ +#define P2P_MGBTSE_P2PDEVMGMT_FLAG 0x1 + + BWL_PRE_PACKED_STRUCT struct wifi_p2p_grpinfo_se_s { - uint8 eltId; /* SE ID: P2P_SEID_GROUP_INFO */ - uint8 len[2]; /* SE length not including eltId, len fields */ + uint8 eltId; + uint8 len[2]; } BWL_POST_PACKED_STRUCT; typedef struct wifi_p2p_grpinfo_se_s wifi_p2p_grpinfo_se_t; -/* WiFi P2P Action Frame */ + BWL_PRE_PACKED_STRUCT struct wifi_p2p_action_frame { - uint8 category; /* P2P_AF_CATEGORY */ - uint8 OUI[3]; /* OUI - P2P_OUI */ - uint8 type; /* OUI Type - P2P_VER */ - uint8 subtype; /* OUI Subtype - P2P_AF_* */ - uint8 dialog_token; /* nonzero, identifies req/resp tranaction */ - uint8 elts[1]; /* Variable length information elements. Max size = - * ACTION_FRAME_SIZE - sizeof(this structure) - 1 - */ + uint8 category; + uint8 OUI[3]; + uint8 type; + uint8 subtype; + uint8 dialog_token; + uint8 elts[1]; } BWL_POST_PACKED_STRUCT; typedef struct wifi_p2p_action_frame wifi_p2p_action_frame_t; -#define P2P_AF_CATEGORY 0x7f +#define P2P_AF_CATEGORY 0x7f + +#define P2P_AF_FIXED_LEN 7 + -#define P2P_AF_FIXED_LEN 7 +#define P2P_AF_NOTICE_OF_ABSENCE 0 +#define P2P_AF_PRESENCE_REQ 1 +#define P2P_AF_PRESENCE_RSP 2 +#define P2P_AF_GO_DISC_REQ 3 -/* WiFi P2P Action Frame OUI Subtypes */ -#define P2P_AF_NOTICE_OF_ABSENCE 0 /* Notice of Absence */ -#define P2P_AF_PRESENCE_REQ 1 /* P2P Presence Request */ -#define P2P_AF_PRESENCE_RSP 2 /* P2P Presence Response */ -#define P2P_AF_GO_DISC_REQ 3 /* GO Discoverability Request */ -/* WiFi P2P Public Action Frame */ BWL_PRE_PACKED_STRUCT struct wifi_p2p_pub_act_frame { - uint8 category; /* P2P_PUB_AF_CATEGORY */ - uint8 action; /* P2P_PUB_AF_ACTION */ - uint8 oui[3]; /* P2P_OUI */ - uint8 oui_type; /* OUI type - P2P_VER */ - uint8 subtype; /* OUI subtype - P2P_TYPE_* */ - uint8 dialog_token; /* nonzero, identifies req/rsp transaction */ - uint8 elts[1]; /* Variable length information elements. Max size = - * ACTION_FRAME_SIZE - sizeof(this structure) - 1 - */ + uint8 category; + uint8 action; + uint8 oui[3]; + uint8 oui_type; + uint8 subtype; + uint8 dialog_token; + uint8 elts[1]; } BWL_POST_PACKED_STRUCT; typedef struct wifi_p2p_pub_act_frame wifi_p2p_pub_act_frame_t; -#define P2P_PUB_AF_FIXED_LEN 8 -#define P2P_PUB_AF_CATEGORY 0x04 -#define P2P_PUB_AF_ACTION 0x09 - -/* WiFi P2P Public Action Frame OUI Subtypes */ -#define P2P_PAF_GON_REQ 0 /* Group Owner Negotiation Req */ -#define P2P_PAF_GON_RSP 1 /* Group Owner Negotiation Rsp */ -#define P2P_PAF_GON_CONF 2 /* Group Owner Negotiation Confirm */ -#define P2P_PAF_INVITE_REQ 3 /* P2P Invitation Request */ -#define P2P_PAF_INVITE_RSP 4 /* P2P Invitation Response */ -#define P2P_PAF_DEVDIS_REQ 5 /* Device Discoverability Request */ -#define P2P_PAF_DEVDIS_RSP 6 /* Device Discoverability Response */ -#define P2P_PAF_PROVDIS_REQ 7 /* Provision Discovery Request */ -#define P2P_PAF_PROVDIS_RSP 8 /* Provision Discovery Request */ - -/* TODO: Stop using these obsolete aliases for P2P_PAF_GON_* */ -#define P2P_TYPE_MNREQ P2P_PAF_GON_REQ -#define P2P_TYPE_MNRSP P2P_PAF_GON_RSP -#define P2P_TYPE_MNCONF P2P_PAF_GON_CONF - -/* WiFi P2P IE subelement: Notice of Absence */ +#define P2P_PUB_AF_FIXED_LEN 8 +#define P2P_PUB_AF_CATEGORY 0x04 +#define P2P_PUB_AF_ACTION 0x09 + + +#define P2P_PAF_GON_REQ 0 +#define P2P_PAF_GON_RSP 1 +#define P2P_PAF_GON_CONF 2 +#define P2P_PAF_INVITE_REQ 3 +#define P2P_PAF_INVITE_RSP 4 +#define P2P_PAF_DEVDIS_REQ 5 +#define P2P_PAF_DEVDIS_RSP 6 +#define P2P_PAF_PROVDIS_REQ 7 +#define P2P_PAF_PROVDIS_RSP 8 + + +#define P2P_TYPE_MNREQ P2P_PAF_GON_REQ +#define P2P_TYPE_MNRSP P2P_PAF_GON_RSP +#define P2P_TYPE_MNCONF P2P_PAF_GON_CONF + + BWL_PRE_PACKED_STRUCT struct wifi_p2p_noa_desc { - uint8 cnt_type; /* Count/Type */ - uint32 duration; /* Duration */ - uint32 interval; /* Interval */ - uint32 start; /* Start Time */ + uint8 cnt_type; + uint32 duration; + uint32 interval; + uint32 start; } BWL_POST_PACKED_STRUCT; typedef struct wifi_p2p_noa_desc wifi_p2p_noa_desc_t; BWL_PRE_PACKED_STRUCT struct wifi_p2p_noa_se { - uint8 eltId; /* Subelement ID */ - uint8 len[2]; /* Length */ - uint8 index; /* Index */ - uint8 ops_ctw_parms; /* CTWindow and OppPS Parameters */ - wifi_p2p_noa_desc_t desc[1]; /* Notice of Absence Descriptor(s) */ + uint8 eltId; + uint8 len[2]; + uint8 index; + uint8 ops_ctw_parms; + wifi_p2p_noa_desc_t desc[1]; } BWL_POST_PACKED_STRUCT; typedef struct wifi_p2p_noa_se wifi_p2p_noa_se_t; -#define P2P_NOA_SE_FIXED_LEN 5 +#define P2P_NOA_SE_FIXED_LEN 5 -/* cnt_type field values */ -#define P2P_NOA_DESC_CNT_RESERVED 0 /* reserved and should not be used */ -#define P2P_NOA_DESC_CNT_REPEAT 255 /* continuous schedule */ -#define P2P_NOA_DESC_TYPE_PREFERRED 1 /* preferred values */ -#define P2P_NOA_DESC_TYPE_ACCEPTABLE 2 /* acceptable limits */ -/* ctw_ops_parms field values */ -#define P2P_NOA_CTW_MASK 0x7f -#define P2P_NOA_OPS_MASK 0x80 -#define P2P_NOA_OPS_SHIFT 7 +#define P2P_NOA_DESC_CNT_RESERVED 0 +#define P2P_NOA_DESC_CNT_REPEAT 255 +#define P2P_NOA_DESC_TYPE_PREFERRED 1 +#define P2P_NOA_DESC_TYPE_ACCEPTABLE 2 + + +#define P2P_NOA_CTW_MASK 0x7f +#define P2P_NOA_OPS_MASK 0x80 +#define P2P_NOA_OPS_SHIFT 7 + +#define P2P_CTW_MIN 10 + + +#define P2PSD_ACTION_CATEGORY 0x04 + +#define P2PSD_ACTION_ID_GAS_IREQ 0x0a + +#define P2PSD_ACTION_ID_GAS_IRESP 0x0b + +#define P2PSD_ACTION_ID_GAS_CREQ 0x0c + +#define P2PSD_ACTION_ID_GAS_CRESP 0x0d + +#define P2PSD_AD_EID 0x6c + +#define P2PSD_ADP_TUPLE_QLMT_PAMEBI 0x00 + +#define P2PSD_ADP_PROTO_ID 0x00 + +#define P2PSD_GAS_OUI P2P_OUI + +#define P2PSD_GAS_OUI_SUBTYPE P2P_VER + +#define P2PSD_GAS_NQP_INFOID 0xDDDD + +#define P2PSD_GAS_COMEBACKDEALY 0x00 + -#define P2P_CTW_MIN 10 /* minimum 10TU */ -/* - * P2P Service Discovery related - */ -#define P2PSD_ACTION_CATEGORY 0x04 - /* Public action frame */ -#define P2PSD_ACTION_ID_GAS_IREQ 0x0a - /* Action value for GAS Initial Request AF */ -#define P2PSD_ACTION_ID_GAS_IRESP 0x0b - /* Action value for GAS Initial Response AF */ -#define P2PSD_ACTION_ID_GAS_CREQ 0x0c - /* Action value for GAS Comback Request AF */ -#define P2PSD_ACTION_ID_GAS_CRESP 0x0d - /* Action value for GAS Comback Response AF */ -#define P2PSD_AD_EID 0x6c - /* Advertisement Protocol IE ID */ -#define P2PSD_ADP_TUPLE_QLMT_PAMEBI 0x00 - /* Query Response Length Limit 7 bits plus PAME-BI 1 bit */ -#define P2PSD_ADP_PROTO_ID 0x00 - /* Advertisement Protocol ID. Always 0 for P2P SD */ -#define P2PSD_GAS_OUI P2P_OUI - /* WFA OUI */ -#define P2PSD_GAS_OUI_SUBTYPE P2P_VER - /* OUI Subtype for GAS IE */ -#define P2PSD_GAS_NQP_INFOID 0xDDDD - /* NQP Query Info ID: 56797 */ -#define P2PSD_GAS_COMEBACKDEALY 0x00 - /* Not used in the Native GAS protocol */ - -/* Service Protocol Type */ typedef enum p2psd_svc_protype { SVC_RPOTYPE_ALL = 0, SVC_RPOTYPE_BONJOUR = 1, @@ -390,7 +384,7 @@ typedef enum p2psd_svc_protype { SVC_RPOTYPE_VENDOR = 255 } p2psd_svc_protype_t; -/* Service Discovery response status code */ + typedef enum { P2PSD_RESP_STATUS_SUCCESS = 0, P2PSD_RESP_STATUS_PROTYPE_NA = 1, @@ -398,115 +392,107 @@ typedef enum { P2PSD_RESP_STATUS_BAD_REQUEST = 3 } p2psd_resp_status_t; -/* Advertisement Protocol IE tuple field */ + BWL_PRE_PACKED_STRUCT struct wifi_p2psd_adp_tpl { - uint8 llm_pamebi; /* Query Response Length Limit bit 0-6, set to 0 plus - * Pre-Associated Message Exchange BSSID Independent bit 7, set to 0 - */ - uint8 adp_id; /* Advertisement Protocol ID: 0 for NQP Native Query Protocol */ + uint8 llm_pamebi; + uint8 adp_id; } BWL_POST_PACKED_STRUCT; typedef struct wifi_p2psd_adp_tpl wifi_p2psd_adp_tpl_t; -/* Advertisement Protocol IE */ + BWL_PRE_PACKED_STRUCT struct wifi_p2psd_adp_ie { - uint8 id; /* IE ID: 0x6c - 108 */ - uint8 len; /* IE length */ - wifi_p2psd_adp_tpl_t adp_tpl; /* Advertisement Protocol Tuple field. Only one - * tuple is defined for P2P Service Discovery - */ + uint8 id; + uint8 len; + wifi_p2psd_adp_tpl_t adp_tpl; } BWL_POST_PACKED_STRUCT; typedef struct wifi_p2psd_adp_ie wifi_p2psd_adp_ie_t; -/* NQP Vendor-specific Content */ + BWL_PRE_PACKED_STRUCT struct wifi_p2psd_nqp_query_vsc { - uint8 oui_subtype; /* OUI Subtype: 0x09 */ - uint16 svc_updi; /* Service Update Indicator */ - uint8 svc_tlvs[1]; /* wifi_p2psd_qreq_tlv_t type for service request, - * wifi_p2psd_qresp_tlv_t type for service response - */ + uint8 oui_subtype; + uint16 svc_updi; + uint8 svc_tlvs[1]; } BWL_POST_PACKED_STRUCT; typedef struct wifi_p2psd_nqp_query_vsc wifi_p2psd_nqp_query_vsc_t; -/* Service Request TLV */ + BWL_PRE_PACKED_STRUCT struct wifi_p2psd_qreq_tlv { - uint16 len; /* Length: 5 plus size of Query Data */ - uint8 svc_prot; /* Service Protocol Type */ - uint8 svc_tscid; /* Service Transaction ID */ - uint8 query_data[1]; /* Query Data, passed in from above Layer 2 */ + uint16 len; + uint8 svc_prot; + uint8 svc_tscid; + uint8 query_data[1]; } BWL_POST_PACKED_STRUCT; typedef struct wifi_p2psd_qreq_tlv wifi_p2psd_qreq_tlv_t; -/* Query Request Frame, defined in generic format, instead of NQP specific */ + BWL_PRE_PACKED_STRUCT struct wifi_p2psd_qreq_frame { - uint16 info_id; /* Info ID: 0xDDDD */ - uint16 len; /* Length of service request TLV, 5 plus the size of request data */ - uint8 oui[3]; /* WFA OUI: 0x0050F2 */ - uint8 qreq_vsc[1]; /* Vendor-specific Content: wifi_p2psd_nqp_query_vsc_t type for NQP */ + uint16 info_id; + uint16 len; + uint8 oui[3]; + uint8 qreq_vsc[1]; } BWL_POST_PACKED_STRUCT; typedef struct wifi_p2psd_qreq_frame wifi_p2psd_qreq_frame_t; -/* GAS Initial Request AF body, "elts" in wifi_p2p_pub_act_frame */ + BWL_PRE_PACKED_STRUCT struct wifi_p2psd_gas_ireq_frame { - wifi_p2psd_adp_ie_t adp_ie; /* Advertisement Protocol IE */ - uint16 qreq_len; /* Query Request Length */ - uint8 qreq_frm[1]; /* Query Request Frame wifi_p2psd_qreq_frame_t */ + wifi_p2psd_adp_ie_t adp_ie; + uint16 qreq_len; + uint8 qreq_frm[1]; } BWL_POST_PACKED_STRUCT; typedef struct wifi_p2psd_gas_ireq_frame wifi_p2psd_gas_ireq_frame_t; -/* Service Response TLV */ + BWL_PRE_PACKED_STRUCT struct wifi_p2psd_qresp_tlv { - uint16 len; /* Length: 5 plus size of Query Data */ - uint8 svc_prot; /* Service Protocol Type */ - uint8 svc_tscid; /* Service Transaction ID */ - uint8 status; /* Value defined in Table 57 of P2P spec. */ - uint8 query_data[1]; /* Response Data, passed in from above Layer 2 */ + uint16 len; + uint8 svc_prot; + uint8 svc_tscid; + uint8 status; + uint8 query_data[1]; } BWL_POST_PACKED_STRUCT; typedef struct wifi_p2psd_qresp_tlv wifi_p2psd_qresp_tlv_t; -/* Query Response Frame, defined in generic format, instead of NQP specific */ + BWL_PRE_PACKED_STRUCT struct wifi_p2psd_qresp_frame { - uint16 info_id; /* Info ID: 0xDDDD */ - uint16 len; /* Lenth of service response TLV, 6 plus the size of resp data */ - uint8 oui[3]; /* WFA OUI: 0x0050F2 */ - uint8 qresp_vsc[1]; /* Vendor-specific Content: wifi_p2psd_qresp_tlv_t type for NQP */ + uint16 info_id; + uint16 len; + uint8 oui[3]; + uint8 qresp_vsc[1]; } BWL_POST_PACKED_STRUCT; typedef struct wifi_p2psd_qresp_frame wifi_p2psd_qresp_frame_t; -/* GAS Initial Response AF body, "elts" in wifi_p2p_pub_act_frame */ + BWL_PRE_PACKED_STRUCT struct wifi_p2psd_gas_iresp_frame { - uint16 status; /* Value defined in Table 7-23 of IEEE P802.11u */ - uint16 cb_delay; /* GAS Comeback Delay */ - wifi_p2psd_adp_ie_t adp_ie; /* Advertisement Protocol IE */ - uint16 qresp_len; /* Query Response Length */ - uint8 qresp_frm[1]; /* Query Response Frame wifi_p2psd_qresp_frame_t */ + uint16 status; + uint16 cb_delay; + wifi_p2psd_adp_ie_t adp_ie; + uint16 qresp_len; + uint8 qresp_frm[1]; } BWL_POST_PACKED_STRUCT; typedef struct wifi_p2psd_gas_iresp_frame wifi_p2psd_gas_iresp_frame_t; -/* GAS Comeback Response AF body, "elts" in wifi_p2p_pub_act_frame */ + BWL_PRE_PACKED_STRUCT struct wifi_p2psd_gas_cresp_frame { - uint16 status; /* Value defined in Table 7-23 of IEEE P802.11u */ - uint8 fragment_id; /* Fragmentation ID */ - uint16 cb_delay; /* GAS Comeback Delay */ - wifi_p2psd_adp_ie_t adp_ie; /* Advertisement Protocol IE */ - uint16 qresp_len; /* Query Response Length */ - uint8 qresp_frm[1]; /* Query Response Frame wifi_p2psd_qresp_frame_t */ + uint16 status; + uint8 fragment_id; + uint16 cb_delay; + wifi_p2psd_adp_ie_t adp_ie; + uint16 qresp_len; + uint8 qresp_frm[1]; } BWL_POST_PACKED_STRUCT; typedef struct wifi_p2psd_gas_cresp_frame wifi_p2psd_gas_cresp_frame_t; -/* Wi-Fi GAS Public Action Frame */ + BWL_PRE_PACKED_STRUCT struct wifi_p2psd_gas_pub_act_frame { - uint8 category; /* 0x04 Public Action Frame */ - uint8 action; /* 0x6c Advertisement Protocol */ - uint8 dialog_token; /* nonzero, identifies req/rsp transaction */ - uint8 query_data[1]; /* Query Data. wifi_p2psd_gas_ireq_frame_t - * or wifi_p2psd_gas_iresp_frame_t format - */ + uint8 category; + uint8 action; + uint8 dialog_token; + uint8 query_data[1]; } BWL_POST_PACKED_STRUCT; typedef struct wifi_p2psd_gas_pub_act_frame wifi_p2psd_gas_pub_act_frame_t; -/* This marks the end of a packed structure section. */ + #include -#endif /* _P2P_H_ */ +#endif diff --git a/drivers/net/wireless/bcmdhd/include/proto/sdspi.h b/drivers/net/wireless/bcmdhd/include/proto/sdspi.h index 7353ff0d7c7..a4900edd4ac 100644 --- a/drivers/net/wireless/bcmdhd/include/proto/sdspi.h +++ b/drivers/net/wireless/bcmdhd/include/proto/sdspi.h @@ -1,9 +1,9 @@ /* * SD-SPI Protocol Standard * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,9 +21,8 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: sdspi.h 277737 2011-08-16 17:54:59Z $ + * $Id: sdspi.h 241182 2011-02-17 21:50:03Z $ */ - #ifndef _SD_SPI_H #define _SD_SPI_H diff --git a/drivers/net/wireless/bcmdhd/include/proto/vlan.h b/drivers/net/wireless/bcmdhd/include/proto/vlan.h index 27f00553760..9c94985cf95 100644 --- a/drivers/net/wireless/bcmdhd/include/proto/vlan.h +++ b/drivers/net/wireless/bcmdhd/include/proto/vlan.h @@ -1,9 +1,9 @@ /* * 802.1Q VLAN protocol definitions * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,10 +21,9 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: vlan.h 277737 2011-08-16 17:54:59Z $ + * $Id: vlan.h 241182 2011-02-17 21:50:03Z $ */ - #ifndef _vlan_h_ #define _vlan_h_ diff --git a/drivers/net/wireless/bcmdhd/include/proto/wpa.h b/drivers/net/wireless/bcmdhd/include/proto/wpa.h index 7361cbf20b0..cc2ff5b315d 100644 --- a/drivers/net/wireless/bcmdhd/include/proto/wpa.h +++ b/drivers/net/wireless/bcmdhd/include/proto/wpa.h @@ -1,9 +1,9 @@ /* * Fundamental types and constants relating to WPA * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,10 +21,9 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: wpa.h 285437 2011-09-21 22:16:56Z $ + * $Id: wpa.h 261155 2011-05-23 23:51:32Z $ */ - #ifndef _proto_wpa_h_ #define _proto_wpa_h_ @@ -117,6 +116,12 @@ typedef BWL_PRE_PACKED_STRUCT struct #define WPA_CIPHER_BIP 6 #define WPA_CIPHER_TPK 7 +#ifdef BCMWAPI_WAI +#define WAPI_CIPHER_NONE WPA_CIPHER_NONE +#define WAPI_CIPHER_SMS4 11 + +#define WAPI_CSE_WPI_SMS4 1 +#endif #define IS_WPA_CIPHER(cipher) ((cipher) == WPA_CIPHER_NONE || \ (cipher) == WPA_CIPHER_WEP_40 || \ @@ -126,6 +131,17 @@ typedef BWL_PRE_PACKED_STRUCT struct (cipher) == WPA_CIPHER_AES_CCM || \ (cipher) == WPA_CIPHER_TPK) +#ifdef BCMWAPI_WAI +#define IS_WAPI_CIPHER(cipher) ((cipher) == WAPI_CIPHER_NONE || \ + (cipher) == WAPI_CSE_WPI_SMS4) + + +#define WAPI_CSE_WPI_2_CIPHER(cse) ((cse) == WAPI_CSE_WPI_SMS4 ? \ + WAPI_CIPHER_SMS4 : WAPI_CIPHER_NONE) + +#define WAPI_CIPHER_2_CSE_WPI(cipher) ((cipher) == WAPI_CIPHER_SMS4 ? \ + WAPI_CSE_WPI_SMS4 : WAPI_CIPHER_NONE) +#endif #define WPA_TKIP_CM_DETECT 60 @@ -145,6 +161,10 @@ typedef BWL_PRE_PACKED_STRUCT struct #define RSN_CAP_2_REPLAY_CNTRS 1 #define RSN_CAP_4_REPLAY_CNTRS 2 #define RSN_CAP_16_REPLAY_CNTRS 3 +#ifdef MFP +#define RSN_CAP_MFPR 0x0040 +#define RSN_CAP_MFPC 0x0080 +#endif #define WPA_CAP_4_REPLAY_CNTRS RSN_CAP_4_REPLAY_CNTRS @@ -157,10 +177,25 @@ typedef BWL_PRE_PACKED_STRUCT struct #define WPA_CAP_LEN RSN_CAP_LEN -#define WPA_PMKID_CNT_LEN 2 +#define WPA_PMKID_CNT_LEN 2 #define WPA_CAP_WPA2_PREAUTH RSN_CAP_PREAUTH +#define WPA2_PMKID_COUNT_LEN 2 + +#ifdef BCMWAPI_WAI +#define WAPI_CAP_PREAUTH RSN_CAP_PREAUTH + + +#define WAPI_WAI_REQUEST 0x00F1 +#define WAPI_UNICAST_REKEY 0x00F2 +#define WAPI_STA_AGING 0x00F3 +#define WAPI_MUTIL_REKEY 0x00F4 +#define WAPI_STA_STATS 0x00F5 + +#define WAPI_USK_REKEY_COUNT 0x4000000 +#define WAPI_MSK_REKEY_COUNT 0x4000000 +#endif #include diff --git a/drivers/net/wireless/bcmdhd/include/proto/wps.h b/drivers/net/wireless/bcmdhd/include/proto/wps.h new file mode 100644 index 00000000000..cccbfff4cfb --- /dev/null +++ b/drivers/net/wireless/bcmdhd/include/proto/wps.h @@ -0,0 +1,379 @@ +/* + * WPS IE definitions + * + * Copyright (C) 1999-2012, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2 (the "GPL"), + * available at http://www.broadcom.com/licenses/GPLv2.php, with the + * following added to such license: + * + * As a special exception, the copyright holders of this software give you + * permission to link this software with independent modules, and to copy and + * distribute the resulting executable under terms of your choice, provided that + * you also meet, for each linked independent module, the terms and conditions of + * the license of that module. An independent module is a module which is not + * derived from this software. The special exception does not apply to any + * modifications of the software. + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a license + * other than the GPL, without Broadcom's express prior written consent. + * + * $Id$ + */ + +#ifndef _WPS_ +#define _WPS_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Data Element Definitions */ +#define WPS_ID_AP_CHANNEL 0x1001 +#define WPS_ID_ASSOC_STATE 0x1002 +#define WPS_ID_AUTH_TYPE 0x1003 +#define WPS_ID_AUTH_TYPE_FLAGS 0x1004 +#define WPS_ID_AUTHENTICATOR 0x1005 +#define WPS_ID_CONFIG_METHODS 0x1008 +#define WPS_ID_CONFIG_ERROR 0x1009 +#define WPS_ID_CONF_URL4 0x100A +#define WPS_ID_CONF_URL6 0x100B +#define WPS_ID_CONN_TYPE 0x100C +#define WPS_ID_CONN_TYPE_FLAGS 0x100D +#define WPS_ID_CREDENTIAL 0x100E +#define WPS_ID_DEVICE_NAME 0x1011 +#define WPS_ID_DEVICE_PWD_ID 0x1012 +#define WPS_ID_E_HASH1 0x1014 +#define WPS_ID_E_HASH2 0x1015 +#define WPS_ID_E_SNONCE1 0x1016 +#define WPS_ID_E_SNONCE2 0x1017 +#define WPS_ID_ENCR_SETTINGS 0x1018 +#define WPS_ID_ENCR_TYPE 0x100F +#define WPS_ID_ENCR_TYPE_FLAGS 0x1010 +#define WPS_ID_ENROLLEE_NONCE 0x101A +#define WPS_ID_FEATURE_ID 0x101B +#define WPS_ID_IDENTITY 0x101C +#define WPS_ID_IDENTITY_PROOF 0x101D +#define WPS_ID_KEY_WRAP_AUTH 0x101E +#define WPS_ID_KEY_IDENTIFIER 0x101F +#define WPS_ID_MAC_ADDR 0x1020 +#define WPS_ID_MANUFACTURER 0x1021 +#define WPS_ID_MSG_TYPE 0x1022 +#define WPS_ID_MODEL_NAME 0x1023 +#define WPS_ID_MODEL_NUMBER 0x1024 +#define WPS_ID_NW_INDEX 0x1026 +#define WPS_ID_NW_KEY 0x1027 +#define WPS_ID_NW_KEY_INDEX 0x1028 +#define WPS_ID_NEW_DEVICE_NAME 0x1029 +#define WPS_ID_NEW_PWD 0x102A +#define WPS_ID_OOB_DEV_PWD 0x102C +#define WPS_ID_OS_VERSION 0x102D +#define WPS_ID_POWER_LEVEL 0x102F +#define WPS_ID_PSK_CURRENT 0x1030 +#define WPS_ID_PSK_MAX 0x1031 +#define WPS_ID_PUBLIC_KEY 0x1032 +#define WPS_ID_RADIO_ENABLED 0x1033 +#define WPS_ID_REBOOT 0x1034 +#define WPS_ID_REGISTRAR_CURRENT 0x1035 +#define WPS_ID_REGISTRAR_ESTBLSHD 0x1036 +#define WPS_ID_REGISTRAR_LIST 0x1037 +#define WPS_ID_REGISTRAR_MAX 0x1038 +#define WPS_ID_REGISTRAR_NONCE 0x1039 +#define WPS_ID_REQ_TYPE 0x103A +#define WPS_ID_RESP_TYPE 0x103B +#define WPS_ID_RF_BAND 0x103C +#define WPS_ID_R_HASH1 0x103D +#define WPS_ID_R_HASH2 0x103E +#define WPS_ID_R_SNONCE1 0x103F +#define WPS_ID_R_SNONCE2 0x1040 +#define WPS_ID_SEL_REGISTRAR 0x1041 +#define WPS_ID_SERIAL_NUM 0x1042 +#define WPS_ID_SC_STATE 0x1044 +#define WPS_ID_SSID 0x1045 +#define WPS_ID_TOT_NETWORKS 0x1046 +#define WPS_ID_UUID_E 0x1047 +#define WPS_ID_UUID_R 0x1048 +#define WPS_ID_VENDOR_EXT 0x1049 +#define WPS_ID_VERSION 0x104A +#define WPS_ID_X509_CERT_REQ 0x104B +#define WPS_ID_X509_CERT 0x104C +#define WPS_ID_EAP_IDENTITY 0x104D +#define WPS_ID_MSG_COUNTER 0x104E +#define WPS_ID_PUBKEY_HASH 0x104F +#define WPS_ID_REKEY_KEY 0x1050 +#define WPS_ID_KEY_LIFETIME 0x1051 +#define WPS_ID_PERM_CFG_METHODS 0x1052 +#define WPS_ID_SEL_REG_CFG_METHODS 0x1053 +#define WPS_ID_PRIM_DEV_TYPE 0x1054 +#define WPS_ID_SEC_DEV_TYPE_LIST 0x1055 +#define WPS_ID_PORTABLE_DEVICE 0x1056 +#define WPS_ID_AP_SETUP_LOCKED 0x1057 +#define WPS_ID_APP_LIST 0x1058 +#define WPS_ID_EAP_TYPE 0x1059 +#define WPS_ID_INIT_VECTOR 0x1060 +#define WPS_ID_KEY_PROVIDED_AUTO 0x1061 +#define WPS_ID_8021X_ENABLED 0x1062 +#define WPS_ID_WEP_TRANSMIT_KEY 0x1064 +#define WPS_ID_REQ_DEV_TYPE 0x106A + +/* WSC 2.0, WFA Vendor Extension Subelements */ +#define WFA_VENDOR_EXT_ID "\x00\x37\x2A" +#define WPS_WFA_SUBID_VERSION2 0x00 +#define WPS_WFA_SUBID_AUTHORIZED_MACS 0x01 +#define WPS_WFA_SUBID_NW_KEY_SHAREABLE 0x02 +#define WPS_WFA_SUBID_REQ_TO_ENROLL 0x03 +#define WPS_WFA_SUBID_SETTINGS_DELAY_TIME 0x04 + + +/* WCN-NET Windows Rally Vertical Pairing Vendor Extensions */ +#define MS_VENDOR_EXT_ID "\x00\x01\x37" +#define WPS_MS_ID_VPI 0x1001 /* Vertical Pairing Identifier TLV */ +#define WPS_MS_ID_TRANSPORT_UUID 0x1002 /* Transport UUID TLV */ + +/* Vertical Pairing Identifier TLV Definitions */ +#define WPS_MS_VPI_TRANSPORT_NONE 0x00 /* None */ +#define WPS_MS_VPI_TRANSPORT_DPWS 0x01 /* Devices Profile for Web Services */ +#define WPS_MS_VPI_TRANSPORT_UPNP 0x02 /* uPnP */ +#define WPS_MS_VPI_TRANSPORT_SDNWS 0x03 /* Secure Devices Profile for Web Services */ +#define WPS_MS_VPI_NO_PROFILE_REQ 0x00 /* Wi-Fi profile not requested. + * Not supported in Windows 7 + */ +#define WPS_MS_VPI_PROFILE_REQ 0x01 /* Wi-Fi profile requested. */ + +/* sizes of the fixed size elements */ +#define WPS_ID_AP_CHANNEL_S 2 +#define WPS_ID_ASSOC_STATE_S 2 +#define WPS_ID_AUTH_TYPE_S 2 +#define WPS_ID_AUTH_TYPE_FLAGS_S 2 +#define WPS_ID_AUTHENTICATOR_S 8 +#define WPS_ID_CONFIG_METHODS_S 2 +#define WPS_ID_CONFIG_ERROR_S 2 +#define WPS_ID_CONN_TYPE_S 1 +#define WPS_ID_CONN_TYPE_FLAGS_S 1 +#define WPS_ID_DEVICE_PWD_ID_S 2 +#define WPS_ID_ENCR_TYPE_S 2 +#define WPS_ID_ENCR_TYPE_FLAGS_S 2 +#define WPS_ID_FEATURE_ID_S 4 +#define WPS_ID_MAC_ADDR_S 6 +#define WPS_ID_MSG_TYPE_S 1 +#define WPS_ID_SC_STATE_S 1 +#define WPS_ID_RF_BAND_S 1 +#define WPS_ID_OS_VERSION_S 4 +#define WPS_ID_VERSION_S 1 +#define WPS_ID_SEL_REGISTRAR_S 1 +#define WPS_ID_SEL_REG_CFG_METHODS_S 2 +#define WPS_ID_REQ_TYPE_S 1 +#define WPS_ID_RESP_TYPE_S 1 +#define WPS_ID_AP_SETUP_LOCKED_S 1 + +/* WSC 2.0, WFA Vendor Extension Subelements */ +#define WPS_WFA_SUBID_VERSION2_S 1 +#define WPS_WFA_SUBID_NW_KEY_SHAREABLE_S 1 +#define WPS_WFA_SUBID_REQ_TO_ENROLL_S 1 +#define WPS_WFA_SUBID_SETTINGS_DELAY_TIME_S 1 + +/* Association states */ +#define WPS_ASSOC_NOT_ASSOCIATED 0 +#define WPS_ASSOC_CONN_SUCCESS 1 +#define WPS_ASSOC_CONFIG_FAIL 2 +#define WPS_ASSOC_ASSOC_FAIL 3 +#define WPS_ASSOC_IP_FAIL 4 + +/* Authentication types */ +#define WPS_AUTHTYPE_OPEN 0x0001 +#define WPS_AUTHTYPE_WPAPSK 0x0002 /* Deprecated in WSC 2.0 */ +#define WPS_AUTHTYPE_SHARED 0x0004 /* Deprecated in WSC 2.0 */ +#define WPS_AUTHTYPE_WPA 0x0008 /* Deprecated in WSC 2.0 */ +#define WPS_AUTHTYPE_WPA2 0x0010 +#define WPS_AUTHTYPE_WPA2PSK 0x0020 + +/* Config methods */ +#define WPS_CONFMET_USBA 0x0001 /* Deprecated in WSC 2.0 */ +#define WPS_CONFMET_ETHERNET 0x0002 /* Deprecated in WSC 2.0 */ +#define WPS_CONFMET_LABEL 0x0004 +#define WPS_CONFMET_DISPLAY 0x0008 +#define WPS_CONFMET_EXT_NFC_TOK 0x0010 +#define WPS_CONFMET_INT_NFC_TOK 0x0020 +#define WPS_CONFMET_NFC_INTF 0x0040 +#define WPS_CONFMET_PBC 0x0080 +#define WPS_CONFMET_KEYPAD 0x0100 +/* WSC 2.0 */ +#define WPS_CONFMET_VIRT_PBC 0x0280 +#define WPS_CONFMET_PHY_PBC 0x0480 +#define WPS_CONFMET_VIRT_DISPLAY 0x2008 +#define WPS_CONFMET_PHY_DISPLAY 0x4008 + +/* WPS error messages */ +#define WPS_ERROR_NO_ERROR 0 +#define WPS_ERROR_OOB_INT_READ_ERR 1 +#define WPS_ERROR_DECRYPT_CRC_FAIL 2 +#define WPS_ERROR_CHAN24_NOT_SUPP 3 +#define WPS_ERROR_CHAN50_NOT_SUPP 4 +#define WPS_ERROR_SIGNAL_WEAK 5 /* Deprecated in WSC 2.0 */ +#define WPS_ERROR_NW_AUTH_FAIL 6 /* Deprecated in WSC 2.0 */ +#define WPS_ERROR_NW_ASSOC_FAIL 7 /* Deprecated in WSC 2.0 */ +#define WPS_ERROR_NO_DHCP_RESP 8 /* Deprecated in WSC 2.0 */ +#define WPS_ERROR_FAILED_DHCP_CONF 9 /* Deprecated in WSC 2.0 */ +#define WPS_ERROR_IP_ADDR_CONFLICT 10 /* Deprecated in WSC 2.0 */ +#define WPS_ERROR_FAIL_CONN_REGISTRAR 11 +#define WPS_ERROR_MULTI_PBC_DETECTED 12 +#define WPS_ERROR_ROGUE_SUSPECTED 13 +#define WPS_ERROR_DEVICE_BUSY 14 +#define WPS_ERROR_SETUP_LOCKED 15 +#define WPS_ERROR_MSG_TIMEOUT 16 /* Deprecated in WSC 2.0 */ +#define WPS_ERROR_REG_SESSION_TIMEOUT 17 /* Deprecated in WSC 2.0 */ +#define WPS_ERROR_DEV_PWD_AUTH_FAIL 18 + +/* Connection types */ +#define WPS_CONNTYPE_ESS 0x01 +#define WPS_CONNTYPE_IBSS 0x02 + +/* Device password ID */ +#define WPS_DEVICEPWDID_DEFAULT 0x0000 +#define WPS_DEVICEPWDID_USER_SPEC 0x0001 +#define WPS_DEVICEPWDID_MACHINE_SPEC 0x0002 +#define WPS_DEVICEPWDID_REKEY 0x0003 +#define WPS_DEVICEPWDID_PUSH_BTN 0x0004 +#define WPS_DEVICEPWDID_REG_SPEC 0x0005 + +/* Encryption type */ +#define WPS_ENCRTYPE_NONE 0x0001 +#define WPS_ENCRTYPE_WEP 0x0002 /* Deprecated in WSC 2.0 */ +#define WPS_ENCRTYPE_TKIP 0x0004 /* Deprecated in version 2.0. TKIP can only + * be advertised on the AP when Mixed Mode + * is enabled (Encryption Type is 0x000c). + */ +#define WPS_ENCRTYPE_AES 0x0008 + + +/* WPS Message Types */ +#define WPS_ID_BEACON 0x01 +#define WPS_ID_PROBE_REQ 0x02 +#define WPS_ID_PROBE_RESP 0x03 +#define WPS_ID_MESSAGE_M1 0x04 +#define WPS_ID_MESSAGE_M2 0x05 +#define WPS_ID_MESSAGE_M2D 0x06 +#define WPS_ID_MESSAGE_M3 0x07 +#define WPS_ID_MESSAGE_M4 0x08 +#define WPS_ID_MESSAGE_M5 0x09 +#define WPS_ID_MESSAGE_M6 0x0A +#define WPS_ID_MESSAGE_M7 0x0B +#define WPS_ID_MESSAGE_M8 0x0C +#define WPS_ID_MESSAGE_ACK 0x0D +#define WPS_ID_MESSAGE_NACK 0x0E +#define WPS_ID_MESSAGE_DONE 0x0F + +/* WSP private ID for local use */ +#define WPS_PRIVATE_ID_IDENTITY (WPS_ID_MESSAGE_DONE + 1) +#define WPS_PRIVATE_ID_WPS_START (WPS_ID_MESSAGE_DONE + 2) +#define WPS_PRIVATE_ID_FAILURE (WPS_ID_MESSAGE_DONE + 3) +#define WPS_PRIVATE_ID_FRAG (WPS_ID_MESSAGE_DONE + 4) +#define WPS_PRIVATE_ID_FRAG_ACK (WPS_ID_MESSAGE_DONE + 5) +#define WPS_PRIVATE_ID_EAPOL_START (WPS_ID_MESSAGE_DONE + 6) + + +/* Device Type categories for primary and secondary device types */ +#define WPS_DEVICE_TYPE_CAT_COMPUTER 1 +#define WPS_DEVICE_TYPE_CAT_INPUT_DEVICE 2 +#define WPS_DEVICE_TYPE_CAT_PRINTER 3 +#define WPS_DEVICE_TYPE_CAT_CAMERA 4 +#define WPS_DEVICE_TYPE_CAT_STORAGE 5 +#define WPS_DEVICE_TYPE_CAT_NW_INFRA 6 +#define WPS_DEVICE_TYPE_CAT_DISPLAYS 7 +#define WPS_DEVICE_TYPE_CAT_MM_DEVICES 8 +#define WPS_DEVICE_TYPE_CAT_GAME_DEVICES 9 +#define WPS_DEVICE_TYPE_CAT_TELEPHONE 10 +#define WPS_DEVICE_TYPE_CAT_AUDIO_DEVICES 11 /* WSC 2.0 */ + +/* Device Type sub categories for primary and secondary device types */ +#define WPS_DEVICE_TYPE_SUB_CAT_COMP_PC 1 +#define WPS_DEVICE_TYPE_SUB_CAT_COMP_SERVER 2 +#define WPS_DEVICE_TYPE_SUB_CAT_COMP_MEDIA_CTR 3 +#define WPS_DEVICE_TYPE_SUB_CAT_COMP_UM_PC 4 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_COMP_NOTEBOOK 5 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_COMP_DESKTOP 6 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_COMP_MID 7 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_COMP_NETBOOK 8 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_INP_Keyboard 1 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_INP_MOUSE 2 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_INP_JOYSTICK 3 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_INP_TRACKBALL 4 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_INP_GAM_CTRL 5 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_INP_REMOTE 6 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_INP_TOUCHSCREEN 7 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_INP_BIO_READER 8 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_INP_BAR_READER 9 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_PRTR_PRINTER 1 +#define WPS_DEVICE_TYPE_SUB_CAT_PRTR_SCANNER 2 +#define WPS_DEVICE_TYPE_SUB_CAT_PRTR_FAX 3 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_PRTR_COPIER 4 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_PRTR_ALLINONE 5 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_CAM_DGTL_STILL 1 +#define WPS_DEVICE_TYPE_SUB_CAT_CAM_VIDEO_CAM 2 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_CAM_WEB_CAM 3 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_CAM_SECU_CAM 4 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_STOR_NAS 1 +#define WPS_DEVICE_TYPE_SUB_CAT_NW_AP 1 +#define WPS_DEVICE_TYPE_SUB_CAT_NW_ROUTER 2 +#define WPS_DEVICE_TYPE_SUB_CAT_NW_SWITCH 3 +#define WPS_DEVICE_TYPE_SUB_CAT_NW_GATEWAY 4 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_NW_BRIDGE 5 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_DISP_TV 1 +#define WPS_DEVICE_TYPE_SUB_CAT_DISP_PIC_FRAME 2 +#define WPS_DEVICE_TYPE_SUB_CAT_DISP_PROJECTOR 3 +#define WPS_DEVICE_TYPE_SUB_CAT_DISP_MONITOR 4 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_MM_DAR 1 +#define WPS_DEVICE_TYPE_SUB_CAT_MM_PVR 2 +#define WPS_DEVICE_TYPE_SUB_CAT_MM_MCX 3 +#define WPS_DEVICE_TYPE_SUB_CAT_MM_STB 4 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_MM_MS_ME 5 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_MM_PVP 6 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_GAM_XBOX 1 +#define WPS_DEVICE_TYPE_SUB_CAT_GAM_XBOX_360 2 +#define WPS_DEVICE_TYPE_SUB_CAT_GAM_PS 3 +#define WPS_DEVICE_TYPE_SUB_CAT_GAM_GC 4 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_GAM_PGD 5 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_PHONE_WM 1 +#define WPS_DEVICE_TYPE_SUB_CAT_PHONE_PSM 2 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_PHONE_PDM 3 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_PHONE_SSM 4 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_PHONE_SDM 5 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_AUDIO_TUNER 1 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_AUDIO_SPEAKERS 2 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_AUDIO_PMP 3 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_AUDIO_HEADSET 4 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_AUDIO_HPHONE 5 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_AUDIO_MPHONE 6 /* WSC 2.0 */ +#define WPS_DEVICE_TYPE_SUB_CAT_AUDIO_HTS 7 /* WSC 2.0 */ + + +/* Device request/response type */ +#define WPS_MSGTYPE_ENROLLEE_INFO_ONLY 0x00 +#define WPS_MSGTYPE_ENROLLEE_OPEN_8021X 0x01 +#define WPS_MSGTYPE_REGISTRAR 0x02 +#define WPS_MSGTYPE_AP_WLAN_MGR 0x03 + +/* RF Band */ +#define WPS_RFBAND_24GHZ 0x01 +#define WPS_RFBAND_50GHZ 0x02 + +/* Simple Config state */ +#define WPS_SCSTATE_UNCONFIGURED 0x01 +#define WPS_SCSTATE_CONFIGURED 0x02 +#define WPS_SCSTATE_OFF 11 + +/* WPS Vendor extension key */ +#define WPS_OUI_HEADER_LEN 2 +#define WPS_OUI_HEADER_SIZE 4 +#define WPS_OUI_FIXED_HEADER_OFF 16 +#define WPS_WFA_SUBID_V2_OFF 3 +#define WPS_WFA_V2_OFF 5 + +#ifdef __cplusplus +} +#endif + +#endif /* _WPS_ */ diff --git a/drivers/net/wireless/bcmdhd/include/rwl_wifi.h b/drivers/net/wireless/bcmdhd/include/rwl_wifi.h new file mode 100644 index 00000000000..187c2bc6337 --- /dev/null +++ b/drivers/net/wireless/bcmdhd/include/rwl_wifi.h @@ -0,0 +1,96 @@ +/* + * RWL definitions of + * Broadcom 802.11bang Networking Device Driver + * + * Copyright (C) 2012, Broadcom Corporation + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of Broadcom Corporation. + * + * $Id: rwl_wifi.h 281527 2011-09-02 17:12:53Z $ + * + */ + +#ifndef _rwl_wifi_h_ +#define _rwl_wifi_h_ + +#if defined(RWL_WIFI) || defined(WIFI_REFLECTOR) || defined(RFAWARE) + +#define RWL_ACTION_WIFI_CATEGORY 127 /* Vendor-specific category value for WiFi */ +#define RWL_WIFI_OUI_BYTE0 0x00 /* BRCM-specific public OUI */ +#define RWL_WIFI_OUI_BYTE1 0x90 +#define RWL_WIFI_OUI_BYTE2 0x4c +#define RWL_WIFI_ACTION_FRAME_SIZE sizeof(struct dot11_action_wifi_vendor_specific) +#define RWL_WIFI_FIND_MY_PEER 0x09 /* Used while finding server */ +#define RWL_WIFI_FOUND_PEER 0x0A /* Server response to the client */ +#define RWL_WIFI_DEFAULT 0x00 +#define RWL_ACTION_WIFI_FRAG_TYPE 0x55 /* Fragment indicator for receiver */ + +/* + * Information about the action frame data fields in the dot11_action_wifi_vendor_specific + * cdc structure (1 to 16). This does not include the status flag. Since this + * is not directly visible to the driver code, we can't use sizeof(struct cdc_ioctl). + * Hence Ref MAC address offset starts from byte 17. + * REF MAC ADDR (6 bytes (MAC Address len) from byte 17 to 22) + * DUT MAC ADDR (6 bytes after the REF MAC Address byte 23 to 28) + * unused (byte 29 to 49) + * REF/Client Channel offset (50) + * DUT/Server channel offset (51) + * --------------------------------------------------------------------------------------- + * cdc struct|REF MAC ADDR|DUT_MAC_ADDR|un used|REF Channel|DUT channel|Action frame Data| + * 1---------17-----------23-------------------50----------51----------52----------------1040 + * REF MAC addr after CDC struct without status flag (status flag not used by wifi) + */ + +#define RWL_REF_MAC_ADDRESS_OFFSET 17 +#define RWL_DUT_MAC_ADDRESS_OFFSET 23 +#define RWL_WIFI_CLIENT_CHANNEL_OFFSET 50 +#define RWL_WIFI_SERVER_CHANNEL_OFFSET 51 + +#ifdef WIFI_REFLECTOR +#include +#define REMOTE_FINDSERVER_CMD 16 +#define RWL_WIFI_ACTION_CMD "wifiaction" +#define RWL_WIFI_ACTION_CMD_LEN 11 /* With the NULL terminator */ +#define REMOTE_SET_CMD 1 +#define REMOTE_GET_CMD 2 +#define REMOTE_REPLY 4 +#define RWL_WIFI_DEFAULT_TYPE 0x00 +#define RWL_WIFI_DEFAULT_SUBTYPE 0x00 +#define RWL_ACTION_FRAME_DATA_SIZE 1024 /* fixed size for the wifi frame data */ +#define RWL_WIFI_CDC_HEADER_OFFSET 0 +#define RWL_WIFI_FRAG_DATA_SIZE 960 /* max size of the frag data */ +#define RWL_DEFAULT_WIFI_FRAG_COUNT 127 /* maximum fragment count */ +#define RWL_WIFI_RETRY 5 /* CMD retry count for wifi */ +#define RWL_WIFI_SEND 5 /* WIFI frame sent count */ +#define RWL_WIFI_SEND_DELAY 100 /* delay between two frames */ +#define MICROSEC_CONVERTOR_VAL 1000 +#ifndef IFNAMSIZ +#define IFNAMSIZ 16 +#endif + +typedef struct rem_packet { + rem_ioctl_t rem_cdc; + uchar message [RWL_ACTION_FRAME_DATA_SIZE]; +} rem_packet_t; + +struct send_packet { + char command [RWL_WIFI_ACTION_CMD_LEN]; + dot11_action_wifi_vendor_specific_t response; +} PACKED; +typedef struct send_packet send_packet_t; + +#define REMOTE_SIZE sizeof(rem_ioctl_t) +#endif /* WIFI_REFLECTOR */ + +typedef struct rwl_request { + struct rwl_request* next_request; + struct dot11_action_wifi_vendor_specific action_frame; +} rwl_request_t; + + +#endif /* defined(RWL_WIFI) || defined(WIFI_REFLECTOR) */ +#endif /* _rwl_wifi_h_ */ diff --git a/drivers/net/wireless/bcmdhd/include/sbchipc.h b/drivers/net/wireless/bcmdhd/include/sbchipc.h index 3fe2a5a49d3..8216d1ee695 100644 --- a/drivers/net/wireless/bcmdhd/include/sbchipc.h +++ b/drivers/net/wireless/bcmdhd/include/sbchipc.h @@ -5,11 +5,11 @@ * JTAG, 0/1/2 UARTs, clock frequency control, a watchdog interrupt timer, * GPIO interface, extbus, and support for serial and parallel flashes. * - * $Id: sbchipc.h 277737 2011-08-16 17:54:59Z $ + * $Id: sbchipc.h 309193 2012-01-19 00:03:57Z $ * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -28,7 +28,6 @@ * other than the GPL, without Broadcom's express prior written consent. */ - #ifndef _SBCHIPC_H #define _SBCHIPC_H @@ -85,6 +84,12 @@ typedef struct eci_rev35 { uint32 eci_uartfifolevel; } eci_rev35_t; +typedef struct flash_config { + uint32 PAD[19]; + + uint32 flashstrconfig; +} flash_config_t; + typedef volatile struct { uint32 chipid; uint32 capabilities; @@ -115,7 +120,7 @@ typedef volatile struct { uint32 flashcontrol; uint32 flashaddress; uint32 flashdata; - uint32 PAD[1]; + uint32 otplayoutextension; uint32 broadcastaddress; @@ -179,7 +184,9 @@ typedef volatile struct { uint32 clkdiv2; - uint32 PAD[2]; + uint32 PAD; + + uint32 fabid; uint32 eromptr; @@ -208,7 +215,16 @@ typedef volatile struct { uint32 sromcontrol; uint32 sromaddress; uint32 sromdata; - uint32 PAD[9]; + uint32 PAD[1]; + + uint32 nflashctrl; + uint32 nflashconf; + uint32 nflashcoladdr; + uint32 nflashrowaddr; + uint32 nflashdata; + uint32 nflashwaitcnt0; + uint32 PAD[2]; + uint32 seci_uart_data; uint32 seci_uart_bauddiv; uint32 seci_uart_fcr; @@ -274,7 +290,69 @@ typedef volatile struct { uint32 pmustrapopt; uint32 pmu_xtalfreq; uint32 PAD[100]; - uint16 sromotp[768]; + uint16 sromotp[512]; + + uint32 nand_revision; + uint32 nand_cmd_start; + uint32 nand_cmd_addr_x; + uint32 nand_cmd_addr; + uint32 nand_cmd_end_addr; + uint32 nand_cs_nand_select; + uint32 nand_cs_nand_xor; + uint32 PAD; + uint32 nand_spare_rd0; + uint32 nand_spare_rd4; + uint32 nand_spare_rd8; + uint32 nand_spare_rd12; + uint32 nand_spare_wr0; + uint32 nand_spare_wr4; + uint32 nand_spare_wr8; + uint32 nand_spare_wr12; + uint32 nand_acc_control; + uint32 PAD; + uint32 nand_config; + uint32 PAD; + uint32 nand_timing_1; + uint32 nand_timing_2; + uint32 nand_semaphore; + uint32 PAD; + uint32 nand_devid; + uint32 nand_devid_x; + uint32 nand_block_lock_status; + uint32 nand_intfc_status; + uint32 nand_ecc_corr_addr_x; + uint32 nand_ecc_corr_addr; + uint32 nand_ecc_unc_addr_x; + uint32 nand_ecc_unc_addr; + uint32 nand_read_error_count; + uint32 nand_corr_stat_threshold; + uint32 PAD[2]; + uint32 nand_read_addr_x; + uint32 nand_read_addr; + uint32 nand_page_program_addr_x; + uint32 nand_page_program_addr; + uint32 nand_copy_back_addr_x; + uint32 nand_copy_back_addr; + uint32 nand_block_erase_addr_x; + uint32 nand_block_erase_addr; + uint32 nand_inv_read_addr_x; + uint32 nand_inv_read_addr; + uint32 PAD[2]; + uint32 nand_blk_wr_protect; + uint32 PAD[3]; + uint32 nand_acc_control_cs1; + uint32 nand_config_cs1; + uint32 nand_timing_1_cs1; + uint32 nand_timing_2_cs1; + uint32 PAD[20]; + uint32 nand_spare_rd16; + uint32 nand_spare_rd20; + uint32 nand_spare_rd24; + uint32 nand_spare_rd28; + uint32 nand_cache_addr; + uint32 nand_cache_data; + uint32 nand_ctrl_config; + uint32 nand_ctrl_status; } chipcregs_t; #endif @@ -285,7 +363,6 @@ typedef volatile struct { #define CC_CHIPST 0x2c #define CC_EROMPTR 0xfc - #define CC_OTPST 0x10 #define CC_JTAGCMD 0x30 #define CC_JTAGIR 0x34 @@ -323,6 +400,21 @@ typedef volatile struct { #define PMU_PLL_CONTROL_DATA 0x664 #define CC_SROM_OTP 0x800 +#ifdef NFLASH_SUPPORT + +#define CC_NAND_REVISION 0xC00 +#define CC_NAND_CMD_START 0xC04 +#define CC_NAND_CMD_ADDR 0xC0C +#define CC_NAND_SPARE_RD_0 0xC20 +#define CC_NAND_SPARE_RD_4 0xC24 +#define CC_NAND_SPARE_RD_8 0xC28 +#define CC_NAND_SPARE_RD_C 0xC2C +#define CC_NAND_CONFIG 0xC48 +#define CC_NAND_DEVID 0xC60 +#define CC_NAND_DEVID_EXT 0xC64 +#define CC_NAND_INTFC_STATUS 0xC6C +#endif + #define CID_ID_MASK 0x0000ffff #define CID_REV_MASK 0x000f0000 @@ -409,6 +501,7 @@ typedef volatile struct { #define OTPS_READY 0x00001000 #define OTPS_RV(x) (1 << (16 + (x))) #define OTPS_RV_MASK 0x0fff0000 +#define OTPS_PROGOK 0x40000000 #define OTPC_PROGSEL 0x00000001 @@ -435,6 +528,16 @@ typedef volatile struct { #define OTPP_READ 0x40000000 +#define OTPL_HWRGN_OFF_MASK 0x00000FFF +#define OTPL_HWRGN_OFF_SHIFT 0 +#define OTPL_WRAP_REVID_MASK 0x00F80000 +#define OTPL_WRAP_REVID_SHIFT 19 +#define OTPL_WRAP_TYPE_MASK 0x00070000 +#define OTPL_WRAP_TYPE_SHIFT 16 +#define OTPL_WRAP_TYPE_65NM 0 +#define OTPL_WRAP_TYPE_40NM 1 + + #define OTP_CISFORMAT_NEW 0x80000000 @@ -449,6 +552,27 @@ typedef volatile struct { #define OTPPOC_PRESCN_TEST 9 +#define OTPPOC_READ_40NM 0 +#define OTPPOC_PROG_ENABLE_40NM 1 +#define OTPPOC_PROG_DISABLE_40NM 2 +#define OTPPOC_VERIFY_40NM 3 +#define OTPPOC_WORD_VERIFY_1_40NM 4 +#define OTPPOC_ROW_LOCK_40NM 5 +#define OTPPOC_STBY_40NM 6 +#define OTPPOC_WAKEUP_40NM 7 +#define OTPPOC_WORD_VERIFY_0_40NM 8 +#define OTPPOC_PRESCN_TEST_40NM 9 +#define OTPPOC_BIT_PROG_40NM 10 +#define OTPPOC_WORDPROG_40NM 11 +#define OTPPOC_BURNIN_40NM 12 +#define OTPPOC_AUTORELOAD_40NM 13 +#define OTPPOC_OVST_READ_40NM 14 +#define OTPPOC_OVST_PROG_40NM 15 + + +#define OTPLAYOUTEXT_FUSE_MASK 0x3FF + + #define JTAGM_CREV_OLD 10 #define JTAGM_CREV_IRP 22 @@ -705,6 +829,7 @@ typedef volatile struct { #define FLASH_NONE 0x000 #define SFLASH_ST 0x100 #define SFLASH_AT 0x200 +#define NFLASH 0x300 #define PFLASH 0x700 @@ -762,6 +887,9 @@ typedef volatile struct { #define SFLASH_ST_CSA 0x1000 #define SFLASH_ST_SSE 0x0220 +#define SFLASH_MXIC_RDID 0x0390 +#define SFLASH_MXIC_MFID 0xc2 + #define SFLASH_ST_WIP 0x01 #define SFLASH_ST_WEL 0x02 @@ -884,6 +1012,7 @@ typedef volatile struct { #define PRRT_REQ_ACTIVE 0x0800 #define PRRT_ALP_REQ 0x1000 #define PRRT_HT_REQ 0x2000 +#define PRRT_HQ_REQ 0x4000 #define PMURES_BIT(bit) (1 << (bit)) @@ -917,6 +1046,16 @@ typedef volatile struct { #define PMU_CC1_SW_TYPE_RGMII 0x000000c0 +#define PMU_CHIPCTL2 2 + + +#define PMU_CHIPCTL3 3 + +#define PMU_CC3_ENABLE_SDIO_WAKEUP_SHIFT 19 +#define PMU_CC3_ENABLE_RF_SHIFT 22 +#define PMU_CC3_RF_DISABLE_IVALUE_SHIFT 23 + + @@ -1099,6 +1238,18 @@ typedef volatile struct { #define PMU5_MAINPLL_MEM 2 #define PMU5_MAINPLL_SI 3 + +#define PMU4706_MAINPLL_PLL0 0 +#define PMU6_4706_PROCPLL_OFF 4 +#define PMU6_4706_PROC_P2DIV_MASK 0x000f0000 +#define PMU6_4706_PROC_P2DIV_SHIFT 16 +#define PMU6_4706_PROC_P1DIV_MASK 0x0000f000 +#define PMU6_4706_PROC_P1DIV_SHIFT 12 +#define PMU6_4706_PROC_NDIV_INT_MASK 0x00000ff8 +#define PMU6_4706_PROC_NDIV_INT_SHIFT 3 +#define PMU6_4706_PROC_NDIV_MODE_MASK 0x00000007 +#define PMU6_4706_PROC_NDIV_MODE_SHIFT 0 + #define PMU7_PLL_PLLCTL7 7 #define PMU7_PLL_CTL7_M4DIV_MASK 0xff000000 #define PMU7_PLL_CTL7_M4DIV_SHIFT 24 @@ -1120,6 +1271,126 @@ typedef volatile struct { #define PMU7_PLL_PLLCTL11_VAL 0x22222200 +#define PMU15_PLL_PLLCTL0 0 +#define PMU15_PLL_PC0_CLKSEL_MASK 0x00000003 +#define PMU15_PLL_PC0_CLKSEL_SHIFT 0 +#define PMU15_PLL_PC0_FREQTGT_MASK 0x003FFFFC +#define PMU15_PLL_PC0_FREQTGT_SHIFT 2 +#define PMU15_PLL_PC0_PRESCALE_MASK 0x00C00000 +#define PMU15_PLL_PC0_PRESCALE_SHIFT 22 +#define PMU15_PLL_PC0_KPCTRL_MASK 0x07000000 +#define PMU15_PLL_PC0_KPCTRL_SHIFT 24 +#define PMU15_PLL_PC0_FCNTCTRL_MASK 0x38000000 +#define PMU15_PLL_PC0_FCNTCTRL_SHIFT 27 +#define PMU15_PLL_PC0_FDCMODE_MASK 0x40000000 +#define PMU15_PLL_PC0_FDCMODE_SHIFT 30 +#define PMU15_PLL_PC0_CTRLBIAS_MASK 0x80000000 +#define PMU15_PLL_PC0_CTRLBIAS_SHIFT 31 + +#define PMU15_PLL_PLLCTL1 1 +#define PMU15_PLL_PC1_BIAS_CTLM_MASK 0x00000060 +#define PMU15_PLL_PC1_BIAS_CTLM_SHIFT 5 +#define PMU15_PLL_PC1_BIAS_CTLM_RST_MASK 0x00000040 +#define PMU15_PLL_PC1_BIAS_CTLM_RST_SHIFT 6 +#define PMU15_PLL_PC1_BIAS_SS_DIVR_MASK 0x0001FF80 +#define PMU15_PLL_PC1_BIAS_SS_DIVR_SHIFT 7 +#define PMU15_PLL_PC1_BIAS_SS_RSTVAL_MASK 0x03FE0000 +#define PMU15_PLL_PC1_BIAS_SS_RSTVAL_SHIFT 17 +#define PMU15_PLL_PC1_BIAS_INTG_BW_MASK 0x0C000000 +#define PMU15_PLL_PC1_BIAS_INTG_BW_SHIFT 26 +#define PMU15_PLL_PC1_BIAS_INTG_BYP_MASK 0x10000000 +#define PMU15_PLL_PC1_BIAS_INTG_BYP_SHIFT 28 +#define PMU15_PLL_PC1_OPENLP_EN_MASK 0x40000000 +#define PMU15_PLL_PC1_OPENLP_EN_SHIFT 30 + +#define PMU15_PLL_PLLCTL2 2 +#define PMU15_PLL_PC2_CTEN_MASK 0x00000001 +#define PMU15_PLL_PC2_CTEN_SHIFT 0 + +#define PMU15_PLL_PLLCTL3 3 +#define PMU15_PLL_PC3_DITHER_EN_MASK 0x00000001 +#define PMU15_PLL_PC3_DITHER_EN_SHIFT 0 +#define PMU15_PLL_PC3_DCOCTLSP_MASK 0xFE000000 +#define PMU15_PLL_PC3_DCOCTLSP_SHIFT 25 +#define PMU15_PLL_PC3_DCOCTLSP_DIV2EN_MASK 0x01 +#define PMU15_PLL_PC3_DCOCTLSP_DIV2EN_SHIFT 0 +#define PMU15_PLL_PC3_DCOCTLSP_CH0EN_MASK 0x02 +#define PMU15_PLL_PC3_DCOCTLSP_CH0EN_SHIFT 1 +#define PMU15_PLL_PC3_DCOCTLSP_CH1EN_MASK 0x04 +#define PMU15_PLL_PC3_DCOCTLSP_CH1EN_SHIFT 2 +#define PMU15_PLL_PC3_DCOCTLSP_CH0SEL_MASK 0x18 +#define PMU15_PLL_PC3_DCOCTLSP_CH0SEL_SHIFT 3 +#define PMU15_PLL_PC3_DCOCTLSP_CH1SEL_MASK 0x60 +#define PMU15_PLL_PC3_DCOCTLSP_CH1SEL_SHIFT 5 +#define PMU15_PLL_PC3_DCOCTLSP_CHSEL_OUTP_DIV1 0 +#define PMU15_PLL_PC3_DCOCTLSP_CHSEL_OUTP_DIV2 1 +#define PMU15_PLL_PC3_DCOCTLSP_CHSEL_OUTP_DIV3 2 +#define PMU15_PLL_PC3_DCOCTLSP_CHSEL_OUTP_DIV5 3 + +#define PMU15_PLL_PLLCTL4 4 +#define PMU15_PLL_PC4_FLLCLK1_DIV_MASK 0x00000007 +#define PMU15_PLL_PC4_FLLCLK1_DIV_SHIFT 0 +#define PMU15_PLL_PC4_FLLCLK2_DIV_MASK 0x00000038 +#define PMU15_PLL_PC4_FLLCLK2_DIV_SHIFT 3 +#define PMU15_PLL_PC4_FLLCLK3_DIV_MASK 0x000001C0 +#define PMU15_PLL_PC4_FLLCLK3_DIV_SHIFT 6 +#define PMU15_PLL_PC4_DBGMODE_MASK 0x00000E00 +#define PMU15_PLL_PC4_DBGMODE_SHIFT 9 +#define PMU15_PLL_PC4_FLL480_CTLSP_LK_MASK 0x00001000 +#define PMU15_PLL_PC4_FLL480_CTLSP_LK_SHIFT 12 +#define PMU15_PLL_PC4_FLL480_CTLSP_MASK 0x000FE000 +#define PMU15_PLL_PC4_FLL480_CTLSP_SHIFT 13 +#define PMU15_PLL_PC4_DINPOL_MASK 0x00100000 +#define PMU15_PLL_PC4_DINPOL_SHIFT 20 +#define PMU15_PLL_PC4_CLKOUT_PD_MASK 0x00200000 +#define PMU15_PLL_PC4_CLKOUT_PD_SHIFT 21 +#define PMU15_PLL_PC4_CLKDIV2_PD_MASK 0x00400000 +#define PMU15_PLL_PC4_CLKDIV2_PD_SHIFT 22 +#define PMU15_PLL_PC4_CLKDIV4_PD_MASK 0x00800000 +#define PMU15_PLL_PC4_CLKDIV4_PD_SHIFT 23 +#define PMU15_PLL_PC4_CLKDIV8_PD_MASK 0x01000000 +#define PMU15_PLL_PC4_CLKDIV8_PD_SHIFT 24 +#define PMU15_PLL_PC4_CLKDIV16_PD_MASK 0x02000000 +#define PMU15_PLL_PC4_CLKDIV16_PD_SHIFT 25 +#define PMU15_PLL_PC4_TEST_EN_MASK 0x04000000 +#define PMU15_PLL_PC4_TEST_EN_SHIFT 26 + +#define PMU15_PLL_PLLCTL5 5 +#define PMU15_PLL_PC5_FREQTGT_MASK 0x000FFFFF +#define PMU15_PLL_PC5_FREQTGT_SHIFT 0 +#define PMU15_PLL_PC5_DCOCTLSP_MASK 0x07F00000 +#define PMU15_PLL_PC5_DCOCTLSP_SHIFT 20 +#define PMU15_PLL_PC5_PRESCALE_MASK 0x18000000 +#define PMU15_PLL_PC5_PRESCALE_SHIFT 27 + +#define PMU15_PLL_PLLCTL6 6 +#define PMU15_PLL_PC6_FREQTGT_MASK 0x000FFFFF +#define PMU15_PLL_PC6_FREQTGT_SHIFT 0 +#define PMU15_PLL_PC6_DCOCTLSP_MASK 0x07F00000 +#define PMU15_PLL_PC6_DCOCTLSP_SHIFT 20 +#define PMU15_PLL_PC6_PRESCALE_MASK 0x18000000 +#define PMU15_PLL_PC6_PRESCALE_SHIFT 27 + +#define PMU15_FREQTGT_480_DEFAULT 0x19AB1 +#define PMU15_FREQTGT_492_DEFAULT 0x1A4F5 +#define PMU15_ARM_96MHZ 96000000 +#define PMU15_ARM_98MHZ 98400000 +#define PMU15_ARM_97MHZ 97000000 + + +#define PMU17_PLLCTL2_NDIVTYPE_MASK 0x00000070 +#define PMU17_PLLCTL2_NDIVTYPE_SHIFT 4 + +#define PMU17_PLLCTL2_NDIV_MODE_INT 0 +#define PMU17_PLLCTL2_NDIV_MODE_INT1B8 1 +#define PMU17_PLLCTL2_NDIV_MODE_MASH111 2 +#define PMU17_PLLCTL2_NDIV_MODE_MASH111B8 3 + +#define PMU17_PLLCTL0_BBPLL_PWRDWN 0 +#define PMU17_PLLCTL0_BBPLL_DRST 3 +#define PMU17_PLLCTL0_BBPLL_DISBL_CLK 8 + + #define PMU4716_MAINPLL_PLL0 12 @@ -1161,8 +1432,9 @@ typedef volatile struct { #define RES5354_BB_PLL_PU 19 -#define CCTRL5357_EXTPA (1<<14) -#define CCTRL5357_ANT_MUX_2o3 (1<<15) +#define CCTRL5357_EXTPA (1<<14) +#define CCTRL5357_ANT_MUX_2o3 (1<<15) +#define CCTRL5357_NFLASH (1<<16) #define RES4328_EXT_SWITCHER_PWM 0 @@ -1392,27 +1664,9 @@ typedef volatile struct { #define CST43237_BOOT_FROM_INVALID 3 -#define RES43239_CBUCK_LPOM 0 -#define RES43239_CBUCK_BURST 1 -#define RES43239_CBUCK_LP_PWM 2 -#define RES43239_CBUCK_PWM 3 -#define RES43239_CLDO_PU 4 -#define RES43239_DIS_INT_RESET_PD 5 -#define RES43239_ILP_REQUEST 6 -#define RES43239_LNLDO_PU 7 -#define RES43239_LDO3P3_PU 8 #define RES43239_OTP_PU 9 -#define RES43239_XTAL_PU 10 -#define RES43239_ALP_AVAIL 11 -#define RES43239_RADIO_PU 12 #define RES43239_MACPHY_CLKAVAIL 23 #define RES43239_HT_AVAIL 24 -#define RES43239_XOLDO_PU 25 -#define RES43239_WL_XTAL_CTL_SEL 26 -#define RES43239_SR_CLK_STABLE 27 -#define RES43239_SR_SAVE_RESTORE 28 -#define RES43239_SR_PHY_PIC 29 -#define RES43239_SR_PHY_PWR_SW 30 #define CST43239_SPROM_MASK 0x00000002 @@ -1425,7 +1679,18 @@ typedef volatile struct { #define CST43239_CHIPMODE_GSPI(cs) (((cs) & (1 << 0)) == (1 << 0)) -#define CCTRL43239_XTAL_STRENGTH(ctl) ((ctl & 0x3F) << 12) +#define RES4324_OTP_PU 10 +#define RES4324_HT_AVAIL 29 +#define RES4324_MACPHY_CLKAVAIL 30 + + +#define CST4324_SPROM_MASK 0x00000080 +#define CST4324_SFLASH_MASK 0x00400000 +#define CST4324_RES_INIT_MODE_SHIFT 10 +#define CST4324_RES_INIT_MODE_MASK 0x00000c00 +#define CST4324_CHIPMODE_MASK 0x7 +#define CST4324_CHIPMODE_SDIOD(cs) ((~(cs)) & (1 << 2)) +#define CST4324_CHIPMODE_USB20D(cs) (((cs) & CST4324_CHIPMODE_MASK) == 0x6) #define RES4331_REGULATOR 0 @@ -1441,17 +1706,17 @@ typedef volatile struct { #define CCTRL4331_EXT_LNA_G (1<<2) #define CCTRL4331_SPROM_GPIO13_15 (1<<3) #define CCTRL4331_EXTPA_EN (1<<4) -#define CCTRL4331_GPIOCLK_ON_SPROMCS <1<<5) +#define CCTRL4331_GPIOCLK_ON_SPROMCS (1<<5) #define CCTRL4331_PCIE_MDIO_ON_SPROMCS (1<<6) #define CCTRL4331_EXTPA_ON_GPIO2_5 (1<<7) #define CCTRL4331_OVR_PIPEAUXCLKEN (1<<8) #define CCTRL4331_OVR_PIPEAUXPWRDOWN (1<<9) -#define CCTRL4331_PCIE_AUXCLKEN <1<<10) -#define CCTRL4331_PCIE_PIPE_PLLDOWN <1<<11) +#define CCTRL4331_PCIE_AUXCLKEN (1<<10) +#define CCTRL4331_PCIE_PIPE_PLLDOWN (1<<11) #define CCTRL4331_EXTPA_EN2 (1<<12) #define CCTRL4331_EXT_LNA_A (1<<13) -#define CCTRL4331_BT_SHD0_ON_GPIO4 <1<<16) -#define CCTRL4331_BT_SHD1_ON_GPIO5 <1<<17) +#define CCTRL4331_BT_SHD0_ON_GPIO4 (1<<16) +#define CCTRL4331_BT_SHD1_ON_GPIO5 (1<<17) #define CCTRL4331_EXTPA_ANA_EN (1<<24) @@ -1646,8 +1911,8 @@ typedef volatile struct { #define CST4330_CBUCK_MODE_MASK 0x00003000 #define CST4330_CBUCK_POWER_OK 0x00004000 #define CST4330_BB_PLL_LOCKED 0x00008000 -#define SOCDEVRAM_4330_BP_ADDR 0x1E000000 -#define SOCDEVRAM_4330_ARM_ADDR 0x00800000 +#define SOCDEVRAM_BP_ADDR 0x1E000000 +#define SOCDEVRAM_ARM_ADDR 0x00800000 #define PCTL_4330_SERIAL_ENAB (1 << 24) @@ -1659,6 +1924,64 @@ typedef volatile struct { #define CCTRL_4330_JTAG_DISABLE 0x00000008 +#define RES4334_LPLDO_PU 0 +#define RES4334_RESET_PULLDN_DIS 1 +#define RES4334_PMU_BG_PU 2 +#define RES4334_HSIC_LDO_PU 3 +#define RES4334_CBUCK_LPOM_PU 4 +#define RES4334_CBUCK_PFM_PU 5 +#define RES4334_CLDO_PU 6 +#define RES4334_LPLDO2_LVM 7 +#define RES4334_LNLDO_PU 8 +#define RES4334_LDO3P3_PU 9 +#define RES4334_OTP_PU 10 +#define RES4334_XTAL_PU 11 +#define RES4334_WL_PWRSW_PU 12 +#define RES4334_LQ_AVAIL 13 +#define RES4334_LOGIC_RET 14 +#define RES4334_MEM_SLEEP 15 +#define RES4334_MACPHY_RET 16 +#define RES4334_WL_CORE_READY 17 +#define RES4334_ILP_REQ 18 +#define RES4334_ALP_AVAIL 19 +#define RES4334_MISC_PWRSW_PU 20 +#define RES4334_SYNTH_PWRSW_PU 21 +#define RES4334_RX_PWRSW_PU 22 +#define RES4334_RADIO_PU 23 +#define RES4334_WL_PMU_PU 24 +#define RES4334_VCO_LDO_PU 25 +#define RES4334_AFE_LDO_PU 26 +#define RES4334_RX_LDO_PU 27 +#define RES4334_TX_LDO_PU 28 +#define RES4334_HT_AVAIL 29 +#define RES4334_MACPHY_CLK_AVAIL 30 + + +#define CST4334_CHIPMODE_MASK 7 +#define CST4334_SDIO_MODE 0x00000000 +#define CST4334_SPI_MODE 0x00000004 +#define CST4334_HSIC_MODE 0x00000006 +#define CST4334_BLUSB_MODE 0x00000007 +#define CST4334_CHIPMODE_HSIC(cs) (((cs) & CST4334_CHIPMODE_MASK) == CST4334_HSIC_MODE) +#define CST4334_OTP_PRESENT 0x00000010 +#define CST4334_LPO_AUTODET_EN 0x00000020 +#define CST4334_ARMREMAP_0 0x00000040 +#define CST4334_SPROM_PRESENT 0x00000080 +#define CST4334_ILPDIV_EN_MASK 0x00000100 +#define CST4334_ILPDIV_EN_SHIFT 8 +#define CST4334_LPO_SEL_MASK 0x00000200 +#define CST4334_LPO_SEL_SHIFT 9 +#define CST4334_RES_INIT_MODE_MASK 0x00000C00 +#define CST4334_RES_INIT_MODE_SHIFT 10 + + +#define PCTL_4334_GPIO3_ENAB (1 << 3) + + +#define CCTRL4334_HSIC_LDO_PU (1 << 23) + + + #define RES4313_BB_PU_RSRC 0 #define RES4313_ILP_REQ_RSRC 1 #define RES4313_XTAL_PU_RSRC 2 @@ -1686,6 +2009,41 @@ typedef volatile struct { #define CCTRL_4313_12MA_LED_DRIVE 0x00000007 +#define RES4314_LPLDO_PU 0 +#define RES4314_PMU_SLEEP_DIS 1 +#define RES4314_PMU_BG_PU 2 +#define RES4314_CBUCK_LPOM_PU 3 +#define RES4314_CBUCK_PFM_PU 4 +#define RES4314_CLDO_PU 5 +#define RES4314_LPLDO2_LVM 6 +#define RES4314_WL_PMU_PU 7 +#define RES4314_LNLDO_PU 8 +#define RES4314_LDO3P3_PU 9 +#define RES4314_OTP_PU 10 +#define RES4314_XTAL_PU 11 +#define RES4314_WL_PWRSW_PU 12 +#define RES4314_LQ_AVAIL 13 +#define RES4314_LOGIC_RET 14 +#define RES4314_MEM_SLEEP 15 +#define RES4314_MACPHY_RET 16 +#define RES4314_WL_CORE_READY 17 +#define RES4314_ILP_REQ 18 +#define RES4314_ALP_AVAIL 19 +#define RES4314_MISC_PWRSW_PU 20 +#define RES4314_SYNTH_PWRSW_PU 21 +#define RES4314_RX_PWRSW_PU 22 +#define RES4314_RADIO_PU 23 +#define RES4314_VCO_LDO_PU 24 +#define RES4314_AFE_LDO_PU 25 +#define RES4314_RX_LDO_PU 26 +#define RES4314_TX_LDO_PU 27 +#define RES4314_HT_AVAIL 28 +#define RES4314_MACPHY_CLK_AVAIL 29 + + +#define CST4314_OTP_ENABLED 0x00200000 + + #define RES43228_NOT_USED 0 #define RES43228_ILP_REQUEST 1 #define RES43228_XTAL_PU 2 @@ -1702,6 +2060,69 @@ typedef volatile struct { #define CST43228_SDIO_RESET 0x20 +#define CST4706_PKG_OPTION (1<<0) +#define CST4706_SFLASH_PRESENT (1<<1) +#define CST4706_SFLASH_TYPE (1<<2) +#define CST4706_MIPS_BENDIAN (1<<3) +#define CST4706_PCIE1_DISABLE (1<<5) + + +#define FLSTRCF4706_MASK 0x000000ff +#define FLSTRCF4706_SF1 0x00000001 +#define FLSTRCF4706_PF1 0x00000002 +#define FLSTRCF4706_SF1_TYPE 0x00000004 +#define FLSTRCF4706_NF1 0x00000008 +#define FLSTRCF4706_1ST_MADDR_SEG_MASK 0x000000f0 +#define FLSTRCF4706_1ST_MADDR_SEG_4MB 0x00000010 +#define FLSTRCF4706_1ST_MADDR_SEG_8MB 0x00000020 +#define FLSTRCF4706_1ST_MADDR_SEG_16MB 0x00000030 +#define FLSTRCF4706_1ST_MADDR_SEG_32MB 0x00000040 +#define FLSTRCF4706_1ST_MADDR_SEG_64MB 0x00000050 +#define FLSTRCF4706_1ST_MADDR_SEG_128MB 0x00000060 +#define FLSTRCF4706_1ST_MADDR_SEG_256MB 0x00000070 + + +#define CCTRL4360_SECI_MODE (1 << 2) +#define CCTRL4360_BTSWCTRL_MODE (1 << 3) +#define CCTRL4360_EXTRA_FEMCTRL_MODE (1 << 8) +#define CCTRL4360_BT_LGCY_MODE (1 << 9) +#define CCTRL4360_CORE2FEMCTRL4_ON (1 << 21) + + +#define RES4360_REGULATOR 0 +#define RES4360_ILP_AVAIL 1 +#define RES4360_ILP_REQ 2 +#define RES4360_XTAL_PU 3 +#define RES4360_ALP_AVAIL 4 +#define RES4360_BBPLLPWRSW_PU 5 +#define RES4360_HT_AVAIL 6 +#define RES4360_OTP_PU 7 +#define RES4360_USBLDO_PU 8 +#define RES4360_USBPLL_PWRSW_PU 9 +#define RES4360_LQ_AVAIL 10 + +#define CST4360_XTAL_40MZ 0x00000001 +#define CST4360_SFLASH 0x00000002 +#define CST4360_SPROM_PRESENT 0x00000004 +#define CST4360_SFLASH_TYPE 0x00000004 +#define CST4360_OTP_ENABLED 0x00000008 +#define CST4360_REMAP_ROM 0x00000010 +#define CST4360_RSRC_INIT_MODE_MASK 0x00000060 +#define CST4360_RSRC_INIT_MODE_SHIFT 5 +#define CST4360_ILP_DIVEN 0x00000080 +#define CST4360_MODE_USB 0x00000100 +#define CST4360_SPROM_SIZE_MASK 0x00000600 +#define CST4360_SPROM_SIZE_SHIFT 9 +#define CST4360_BBPLL_LOCK 0x00000800 +#define CST4360_AVBBPLL_LOCK 0x00001000 +#define CST4360_USBBBPLL_LOCK 0x00002000 + +#define CCTRL_4360_UART_SEL 0x2 + + +#define CHIP_HOSTIF_USB(sih) (si_chip_hostif(sih) & CST4360_MODE_USB) + + #define PMU_MAX_TRANSITION_DLY 15000 @@ -1723,6 +2144,9 @@ typedef volatile struct { #define SECI_MODE_SHIFT 4 #define SECI_UPD_SECI (1 << 7) +#define SECI_SIGNOFF_0 0xDB +#define SECI_SIGNOFF_1 0 + #define CLKCTL_STS_SECI_CLK_REQ (1 << 8) #define CLKCTL_STS_SECI_CLK_AVAIL (1 << 24) diff --git a/drivers/net/wireless/bcmdhd/include/sbconfig.h b/drivers/net/wireless/bcmdhd/include/sbconfig.h index f45351a586c..44d68329e66 100644 --- a/drivers/net/wireless/bcmdhd/include/sbconfig.h +++ b/drivers/net/wireless/bcmdhd/include/sbconfig.h @@ -1,9 +1,9 @@ /* * Broadcom SiliconBackplane hardware register definitions. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,10 +21,9 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: sbconfig.h 277737 2011-08-16 17:54:59Z $ + * $Id: sbconfig.h 241182 2011-02-17 21:50:03Z $ */ - #ifndef _SBCONFIG_H #define _SBCONFIG_H diff --git a/drivers/net/wireless/bcmdhd/include/sbhnddma.h b/drivers/net/wireless/bcmdhd/include/sbhnddma.h index 77c413f75f0..da1f1a10a65 100644 --- a/drivers/net/wireless/bcmdhd/include/sbhnddma.h +++ b/drivers/net/wireless/bcmdhd/include/sbhnddma.h @@ -2,9 +2,9 @@ * Generic Broadcom Home Networking Division (HND) DMA engine HW interface * This supports the following chips: BCM42xx, 44xx, 47xx . * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -22,10 +22,9 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: sbhnddma.h 278779 2011-08-19 22:07:18Z $ + * $Id: sbhnddma.h 309193 2012-01-19 00:03:57Z $ */ - #ifndef _sbhnddma_h_ #define _sbhnddma_h_ @@ -72,11 +71,44 @@ typedef volatile struct { #define XC_SE ((uint32)1 << 1) #define XC_LE ((uint32)1 << 2) #define XC_FL ((uint32)1 << 4) +#define XC_MR_MASK 0x000000C0 +#define XC_MR_SHIFT 6 #define XC_PD ((uint32)1 << 11) #define XC_AE ((uint32)3 << 16) #define XC_AE_SHIFT 16 -#define XC_BL_MASK 0x001C0000 +#define XC_BL_MASK 0x001C0000 #define XC_BL_SHIFT 18 +#define XC_PC_MASK 0x00E00000 +#define XC_PC_SHIFT 21 +#define XC_PT_MASK 0x03000000 +#define XC_PT_SHIFT 24 + + +#define DMA_MR_1 0 +#define DMA_MR_2 1 + + + +#define DMA_BL_16 0 +#define DMA_BL_32 1 +#define DMA_BL_64 2 +#define DMA_BL_128 3 +#define DMA_BL_256 4 +#define DMA_BL_512 5 +#define DMA_BL_1024 6 + + +#define DMA_PC_0 0 +#define DMA_PC_4 1 +#define DMA_PC_8 2 +#define DMA_PC_16 3 + + + +#define DMA_PT_1 0 +#define DMA_PT_2 1 +#define DMA_PT_4 2 +#define DMA_PT_8 3 #define XP_LD_MASK 0xfff @@ -110,8 +142,12 @@ typedef volatile struct { #define RC_PD ((uint32)1 << 11) #define RC_AE ((uint32)3 << 16) #define RC_AE_SHIFT 16 -#define RC_BL_MASK 0x001C0000 +#define RC_BL_MASK 0x001C0000 #define RC_BL_SHIFT 18 +#define RC_PC_MASK 0x00E00000 +#define RC_PC_SHIFT 21 +#define RC_PT_MASK 0x03000000 +#define RC_PT_SHIFT 24 #define RP_LD_MASK 0xfff @@ -202,19 +238,21 @@ typedef volatile struct { #define D64MAXDD (D64MAXRINGSZ / sizeof (dma64dd_t)) -#define D64_DEF_USBBURSTLEN 2 -#define D64_DEF_SDIOBURSTLEN 1 - - #define D64_XC_XE 0x00000001 #define D64_XC_SE 0x00000002 #define D64_XC_LE 0x00000004 #define D64_XC_FL 0x00000010 +#define D64_XC_MR_MASK 0x000000C0 +#define D64_XC_MR_SHIFT 6 #define D64_XC_PD 0x00000800 #define D64_XC_AE 0x00030000 #define D64_XC_AE_SHIFT 16 -#define D64_XC_BL_MASK 0x001C0000 +#define D64_XC_BL_MASK 0x001C0000 #define D64_XC_BL_SHIFT 18 +#define D64_XC_PC_MASK 0x00E00000 +#define D64_XC_PC_SHIFT 21 +#define D64_XC_PT_MASK 0x03000000 +#define D64_XC_PT_SHIFT 24 #define D64_XP_LD_MASK 0x00001fff @@ -249,8 +287,12 @@ typedef volatile struct { #define D64_RC_PD 0x00000800 #define D64_RC_AE 0x00030000 #define D64_RC_AE_SHIFT 16 -#define D64_RC_BL_MASK 0x001C0000 +#define D64_RC_BL_MASK 0x001C0000 #define D64_RC_BL_SHIFT 18 +#define D64_RC_PC_MASK 0x00E00000 +#define D64_RC_PC_SHIFT 21 +#define D64_RC_PT_MASK 0x03000000 +#define D64_RC_PT_SHIFT 24 #define DMA_CTRL_PEN (1 << 0) @@ -258,6 +300,7 @@ typedef volatile struct { #define DMA_CTRL_RXMULTI (1 << 2) #define DMA_CTRL_UNFRAMED (1 << 3) #define DMA_CTRL_USB_BOUNDRY4KB_WAR (1 << 4) +#define DMA_CTRL_DMA_AVOIDANCE_WAR (1 << 5) #define D64_RP_LD_MASK 0x00001fff diff --git a/drivers/net/wireless/bcmdhd/include/sbpcmcia.h b/drivers/net/wireless/bcmdhd/include/sbpcmcia.h index d84f69ab561..f94d82b2f62 100644 --- a/drivers/net/wireless/bcmdhd/include/sbpcmcia.h +++ b/drivers/net/wireless/bcmdhd/include/sbpcmcia.h @@ -1,9 +1,9 @@ /* * BCM43XX Sonics SiliconBackplane PCMCIA core hardware definitions. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,10 +21,9 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: sbpcmcia.h 277737 2011-08-16 17:54:59Z $ + * $Id: sbpcmcia.h 307736 2012-01-12 10:57:05Z $ */ - #ifndef _SBPCMCIA_H #define _SBPCMCIA_H diff --git a/drivers/net/wireless/bcmdhd/include/sbsdio.h b/drivers/net/wireless/bcmdhd/include/sbsdio.h index 7aaeb73f010..4b5a1cf465f 100644 --- a/drivers/net/wireless/bcmdhd/include/sbsdio.h +++ b/drivers/net/wireless/bcmdhd/include/sbsdio.h @@ -4,9 +4,9 @@ * * SDIO core support 1bit, 4 bit SDIO mode as well as SPI mode. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -24,7 +24,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: sbsdio.h 277737 2011-08-16 17:54:59Z $ + * $Id: sbsdio.h 308945 2012-01-18 02:15:27Z $ */ #ifndef _SBSDIO_H @@ -55,10 +55,24 @@ #define SBSDIO_FUNC1_WFRAMEBCHI 0x1001A /* Write Frame Byte Count High */ #define SBSDIO_FUNC1_RFRAMEBCLO 0x1001B /* Read Frame Byte Count Low */ #define SBSDIO_FUNC1_RFRAMEBCHI 0x1001C /* Read Frame Byte Count High */ +#define SBSDIO_FUNC1_MESBUSYCTRL 0x1001D /* MesBusyCtl at 0x1001D (rev 11) */ #define SBSDIO_FUNC1_MISC_REG_START 0x10000 /* f1 misc register start */ #define SBSDIO_FUNC1_MISC_REG_LIMIT 0x1001C /* f1 misc register end */ +/* Sdio Core Rev 12 */ +#define SBSDIO_FUNC1_WAKEUPCTRL 0x1001E +#define SBSDIO_FUNC1_WCTRL_ALPWAIT_MASK 0x1 +#define SBSDIO_FUNC1_WCTRL_ALPWAIT_SHIFT 0 +#define SBSDIO_FUNC1_WCTRL_HTWAIT_MASK 0x2 +#define SBSDIO_FUNC1_WCTRL_HTWAIT_SHIFT 1 +#define SBSDIO_FUNC1_SLEEPCSR 0x1001F +#define SBSDIO_FUNC1_SLEEPCSR_KSO_MASK 0x1 +#define SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT 0 +#define SBSDIO_FUNC1_SLEEPCSR_KSO_EN 1 +#define SBSDIO_FUNC1_SLEEPCSR_DEVON_MASK 0x2 +#define SBSDIO_FUNC1_SLEEPCSR_DEVON_SHIFT 1 + /* SBSDIO_SPROM_CS */ #define SBSDIO_SPROM_IDLE 0 #define SBSDIO_SPROM_WRITE 1 @@ -82,6 +96,12 @@ * to wait before sending data to host */ +/* SBSDIO_MESBUSYCTRL */ +/* When RX FIFO has less entries than this & MBE is set + * => busy signal is asserted between data blocks. +*/ +#define SBSDIO_MESBUSYCTRL_MASK 0x7f + /* SBSDIO_DEVICE_CTL */ #define SBSDIO_DEVCTL_SETBUSY 0x01 /* 1: device will assert busy signal when * receiving CMD53 @@ -114,6 +134,7 @@ /* In rev8, actual avail bits followed original docs */ #define SBSDIO_Rev8_HT_AVAIL 0x40 #define SBSDIO_Rev8_ALP_AVAIL 0x80 +#define SBSDIO_CSR_MASK 0x1F #define SBSDIO_AVBITS (SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL) #define SBSDIO_ALPAV(regval) ((regval) & SBSDIO_AVBITS) diff --git a/drivers/net/wireless/bcmdhd/include/sbsdpcmdev.h b/drivers/net/wireless/bcmdhd/include/sbsdpcmdev.h index e5176483e9a..2c595356805 100644 --- a/drivers/net/wireless/bcmdhd/include/sbsdpcmdev.h +++ b/drivers/net/wireless/bcmdhd/include/sbsdpcmdev.h @@ -2,9 +2,9 @@ * Broadcom SiliconBackplane SDIO/PCMCIA hardware-specific * device core support * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -22,7 +22,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: sbsdpcmdev.h 282638 2011-09-08 21:18:10Z $ + * $Id: sbsdpcmdev.h 241182 2011-02-17 21:50:03Z $ */ #ifndef _sbsdpcmdev_h_ diff --git a/drivers/net/wireless/bcmdhd/include/sbsocram.h b/drivers/net/wireless/bcmdhd/include/sbsocram.h index 45c4dc208bd..852d1151bc5 100644 --- a/drivers/net/wireless/bcmdhd/include/sbsocram.h +++ b/drivers/net/wireless/bcmdhd/include/sbsocram.h @@ -1,9 +1,9 @@ /* * BCM47XX Sonics SiliconBackplane embedded ram core * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,10 +21,9 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: sbsocram.h 277737 2011-08-16 17:54:59Z $ + * $Id: sbsocram.h 271781 2011-07-13 20:00:06Z $ */ - #ifndef _SBSOCRAM_H #define _SBSOCRAM_H @@ -67,7 +66,7 @@ typedef volatile struct sbsocramregs { uint32 PAD[84]; uint32 workaround; uint32 pwrctl; - uint32 PAD[133]; + uint32 PAD[133]; uint32 sr_control; uint32 sr_status; uint32 sr_address; @@ -154,7 +153,7 @@ typedef volatile struct sbsocramregs { #define SRCMD_DONE_DLY 1000 -#define SOCRAM_BANKINFO_SZMASK 0x3f +#define SOCRAM_BANKINFO_SZMASK 0x7f #define SOCRAM_BANKIDX_ROM_MASK 0x100 #define SOCRAM_BANKIDX_MEMTYPE_SHIFT 8 @@ -169,18 +168,26 @@ typedef volatile struct sbsocramregs { #define SOCRAM_BANKINFO_STDBY_TIMER 0x800 -#define SOCRAM_BANKINFO_DEVRAMSEL_SHIFT 13 -#define SOCRAM_BANKINFO_DEVRAMSEL_MASK 0x2000 -#define SOCRAM_BANKINFO_DEVRAMPRO_SHIFT 14 -#define SOCRAM_BANKINFO_DEVRAMPRO_MASK 0x4000 +#define SOCRAM_BANKINFO_DEVRAMSEL_SHIFT 13 +#define SOCRAM_BANKINFO_DEVRAMSEL_MASK 0x2000 +#define SOCRAM_BANKINFO_DEVRAMPRO_SHIFT 14 +#define SOCRAM_BANKINFO_DEVRAMPRO_MASK 0x4000 +#define SOCRAM_BANKINFO_SLPSUPP_SHIFT 15 +#define SOCRAM_BANKINFO_SLPSUPP_MASK 0x8000 +#define SOCRAM_BANKINFO_RETNTRAM_SHIFT 16 +#define SOCRAM_BANKINFO_RETNTRAM_MASK 0x00010000 +#define SOCRAM_BANKINFO_PDASZ_SHIFT 17 +#define SOCRAM_BANKINFO_PDASZ_MASK 0x003E0000 +#define SOCRAM_BANKINFO_DEVRAMREMAP_SHIFT 24 +#define SOCRAM_BANKINFO_DEVRAMREMAP_MASK 0x01000000 #define SOCRAM_DEVRAMBANK_MASK 0xF000 #define SOCRAM_DEVRAMBANK_SHIFT 12 -#define SOCRAM_BANKINFO_SZBASE 8192 -#define SOCRAM_BANKSIZE_SHIFT 13 +#define SOCRAM_BANKINFO_SZBASE 8192 +#define SOCRAM_BANKSIZE_SHIFT 13 #endif diff --git a/drivers/net/wireless/bcmdhd/include/sdio.h b/drivers/net/wireless/bcmdhd/include/sdio.h index c8ac7b773fb..b8eee1ffb40 100644 --- a/drivers/net/wireless/bcmdhd/include/sdio.h +++ b/drivers/net/wireless/bcmdhd/include/sdio.h @@ -2,9 +2,9 @@ * SDIO spec header file * Protocol and standard (common) device definitions * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -22,7 +22,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: sdio.h 277737 2011-08-16 17:54:59Z $ + * $Id: sdio.h 308973 2012-01-18 04:19:34Z $ */ #ifndef _SDIO_H @@ -84,7 +84,12 @@ typedef volatile struct { #define SDIOD_CCCR_INTR_EXTN 0x16 /* Broadcom extensions (corerev >= 1) */ -#define SDIOD_CCCR_BRCM_SEPINT 0xf2 +#define SDIOD_CCCR_BRCM_CARDCAP 0xf0 +#define SDIOD_CCCR_BRCM_CARDCAP_CMD14_SUPPORT 0x02 +#define SDIOD_CCCR_BRCM_CARDCAP_CMD14_EXT 0x04 +#define SDIOD_CCCR_BRCM_CARDCAP_CMD_NODEC 0x08 +#define SDIOD_CCCR_BRCM_CARDCTL 0xf1 +#define SDIOD_CCCR_BRCM_SEPINT 0xf2 /* cccr_sdio_rev */ #define SDIO_REV_SDIOID_MASK 0xf0 /* SDIO spec revision number */ @@ -188,6 +193,7 @@ typedef volatile struct { } sdio_fbr_t; /* Maximum number of I/O funcs */ +#define SDIOD_MAX_FUNCS 8 #define SDIOD_MAX_IOFUNCS 7 /* SDIO Device FBR Start Address */ @@ -608,5 +614,4 @@ typedef volatile struct { /* command issue options */ #define CMD_OPTION_DEFAULT 0 #define CMD_OPTION_TUNING 1 - #endif /* _SDIO_H */ diff --git a/drivers/net/wireless/bcmdhd/include/sdioh.h b/drivers/net/wireless/bcmdhd/include/sdioh.h index 5f47d6f88ce..e847a52babe 100644 --- a/drivers/net/wireless/bcmdhd/include/sdioh.h +++ b/drivers/net/wireless/bcmdhd/include/sdioh.h @@ -2,9 +2,9 @@ * SDIO Host Controller Spec header file * Register map and definitions for the Standard Host Controller * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -22,7 +22,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: sdioh.h 300017 2011-12-01 20:30:27Z $ + * $Id: sdioh.h 299859 2011-12-01 03:53:27Z $ */ #ifndef _SDIOH_H @@ -72,7 +72,6 @@ #define SD_GPIO_OE 0x104 #define SD_GPIO_Enable 0x108 - /* SD specific registers in PCI config space */ #define SD_SlotInfo 0x40 diff --git a/drivers/net/wireless/bcmdhd/include/sdiovar.h b/drivers/net/wireless/bcmdhd/include/sdiovar.h index 55a3d3490c3..83f82de2649 100644 --- a/drivers/net/wireless/bcmdhd/include/sdiovar.h +++ b/drivers/net/wireless/bcmdhd/include/sdiovar.h @@ -2,9 +2,9 @@ * Structure used by apps whose drivers access SDIO drivers. * Pulled out separately so dhdu and wlu can both use it. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -22,7 +22,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: sdiovar.h 277737 2011-08-16 17:54:59Z $ + * $Id: sdiovar.h 241182 2011-02-17 21:50:03Z $ */ #ifndef _sdiovar_h_ diff --git a/drivers/net/wireless/bcmdhd/include/siutils.h b/drivers/net/wireless/bcmdhd/include/siutils.h index 6a7b93c7b97..c052eb040ee 100644 --- a/drivers/net/wireless/bcmdhd/include/siutils.h +++ b/drivers/net/wireless/bcmdhd/include/siutils.h @@ -2,9 +2,9 @@ * Misc utility routines for accessing the SOC Interconnects * of Broadcom HNBU chips. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -22,10 +22,9 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: siutils.h 285387 2011-09-21 18:38:37Z $ + * $Id: siutils.h 309193 2012-01-19 00:03:57Z $ */ - #ifndef _siutils_h_ #define _siutils_h_ @@ -43,6 +42,7 @@ struct si_pub { int pmurev; uint32 pmucaps; uint boardtype; + uint boardrev; uint boardvendor; uint boardflags; uint boardflags2; @@ -115,6 +115,14 @@ typedef const struct si_pub si_t; typedef void (*gpio_handler_t)(uint32 stat, void *arg); +#define CC_BTCOEX_EN_MASK 0x01 + +#define GPIO_CTRL_EPA_EN_MASK 0x40 + +#define GPIO_CTRL_5_6_EN_MASK 0x60 +#define GPIO_CTRL_7_6_EN_MASK 0xC0 +#define GPIO_OUT_7_EN_MASK 0x80 + extern si_t *si_attach(uint pcidev, osl_t *osh, void *regs, uint bustype, @@ -148,6 +156,7 @@ extern void si_restore_core(si_t *sih, uint coreid, uint intr_val); extern int si_numaddrspaces(si_t *sih); extern uint32 si_addrspace(si_t *sih, uint asidx); extern uint32 si_addrspacesize(si_t *sih, uint asidx); +extern void si_coreaddrspaceX(si_t *sih, uint asidx, uint32 *addr, uint32 *size); extern int si_corebist(si_t *sih); extern void si_core_reset(si_t *sih, uint32 bits, uint32 resetbits); extern void si_core_disable(si_t *sih, uint32 bits); @@ -172,8 +181,11 @@ extern void si_btcgpiowar(si_t *sih); extern bool si_deviceremoved(si_t *sih); extern uint32 si_socram_size(si_t *sih); extern uint32 si_socdevram_size(si_t *sih); -extern void si_socdevram(si_t *sih, bool set, uint8 *ennable, uint8 *protect); +extern uint32 si_socram_srmem_size(si_t *sih); +extern void si_socdevram(si_t *sih, bool set, uint8 *ennable, uint8 *protect, uint8 *remap); extern bool si_socdevram_pkg(si_t *sih); +extern bool si_socdevram_remap_isenb(si_t *sih); +extern uint32 si_socdevram_remap_size(si_t *sih); extern void si_watchdog(si_t *sih, uint ticks); extern void si_watchdog_ms(si_t *sih, uint32 ms); @@ -203,6 +215,7 @@ extern bool si_pci_fastpmecap(struct osl_info *osh); extern bool si_pci_pmestat(si_t *sih); extern void si_pci_pmeclr(si_t *sih); extern void si_pci_pmeen(si_t *sih); +extern void si_pci_pmestatclr(si_t *sih); extern uint si_pcie_readreg(void *sih, uint addrtype, uint offset); extern void si_sdio_init(si_t *sih); @@ -212,11 +225,12 @@ extern int si_corepciid(si_t *sih, uint func, uint16 *pcivendor, uint16 *pcidevi uint8 *pciclass, uint8 *pcisubclass, uint8 *pciprogif, uint8 *pciheader); #define si_eci(sih) 0 -#define si_eci_init(sih) (0) +static INLINE void * si_eci_init(si_t *sih) {return NULL;} #define si_eci_notify_bt(sih, type, val) (0) #define si_seci(sih) 0 +#define si_seci_upd(sih, a) do {} while (0) static INLINE void * si_seci_init(si_t *sih, uint8 use_seci) {return NULL;} -#define si_seci_down(sih) do { } while (0) +#define si_seci_down(sih) do {} while (0) extern bool si_is_otp_disabled(si_t *sih); @@ -247,19 +261,35 @@ extern int si_devpath(si_t *sih, char *path, int size); extern char *si_getdevpathvar(si_t *sih, const char *name); extern int si_getdevpathintvar(si_t *sih, const char *name); +extern char *si_coded_devpathvar(si_t *sih, char *varname, int var_len, const char *name); extern uint8 si_pcieclkreq(si_t *sih, uint32 mask, uint32 val); extern uint32 si_pcielcreg(si_t *sih, uint32 mask, uint32 val); extern void si_war42780_clkreq(si_t *sih, bool clkreq); -extern void si_pci_sleep(si_t *sih); extern void si_pci_down(si_t *sih); extern void si_pci_up(si_t *sih); +extern void si_pci_sleep(si_t *sih); extern void si_pcie_war_ovr_update(si_t *sih, uint8 aspm); +extern void si_pcie_power_save_enable(si_t *sih, bool enable); extern void si_pcie_extendL1timer(si_t *sih, bool extend); extern int si_pci_fixcfg(si_t *sih); -extern uint si_pll_reset(si_t *sih); +extern void si_chippkg_set(si_t *sih, uint); + +extern void si_chipcontrl_btshd0_4331(si_t *sih, bool on); +extern void si_chipcontrl_restore(si_t *sih, uint32 val); +extern uint32 si_chipcontrl_read(si_t *sih); +extern void si_chipcontrl_epa4331(si_t *sih, bool on); +extern void si_chipcontrl_epa4331_wowl(si_t *sih, bool enter_wowl); +extern void si_chipcontrl_srom4360(si_t *sih, bool on); +extern void si_epa_4313war(si_t *sih); +extern void si_btc_enable_chipcontrol(si_t *sih); + +extern void si_btcombo_p250_4313_war(si_t *sih); +extern void si_btcombo_43228_war(si_t *sih); +extern void si_clk_pmu_htavail_set(si_t *sih, bool set_clear); +extern uint si_pll_reset(si_t *sih); extern bool si_taclear(si_t *sih, bool details); @@ -268,6 +298,13 @@ extern bool si_taclear(si_t *sih, bool details); extern uint32 si_pciereg(si_t *sih, uint32 offset, uint32 mask, uint32 val, uint type); extern uint32 si_pcieserdesreg(si_t *sih, uint32 mdioslave, uint32 offset, uint32 mask, uint32 val); +extern void si_pcie_set_request_size(si_t *sih, uint16 size); +extern uint16 si_pcie_get_request_size(si_t *sih); +extern uint16 si_pcie_get_ssid(si_t *sih); +extern uint32 si_pcie_get_bar0(si_t *sih); +extern int si_pcie_configspace_cache(si_t *sih); +extern int si_pcie_configspace_restore(si_t *sih); +extern int si_pcie_configspace_get(si_t *sih, uint8 *buf, uint size); char *si_getnvramflvar(si_t *sih, const char *name); diff --git a/drivers/net/wireless/bcmdhd/include/spid.h b/drivers/net/wireless/bcmdhd/include/spid.h new file mode 100644 index 00000000000..ccae9779cda --- /dev/null +++ b/drivers/net/wireless/bcmdhd/include/spid.h @@ -0,0 +1,153 @@ +/* + * SPI device spec header file + * + * Copyright (C) 2012, Broadcom Corporation + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of Broadcom Corporation. + * + * $Id: spid.h 241182 2011-02-17 21:50:03Z $ + */ + +#ifndef _SPI_H +#define _SPI_H + +/* + * Brcm SPI Device Register Map. + * + */ + +typedef volatile struct { + uint8 config; /* 0x00, len, endian, clock, speed, polarity, wakeup */ + uint8 response_delay; /* 0x01, read response delay in bytes (corerev < 3) */ + uint8 status_enable; /* 0x02, status-enable, intr with status, response_delay + * function selection, command/data error check + */ + uint8 reset_bp; /* 0x03, reset on wlan/bt backplane reset (corerev >= 1) */ + uint16 intr_reg; /* 0x04, Intr status register */ + uint16 intr_en_reg; /* 0x06, Intr mask register */ + uint32 status_reg; /* 0x08, RO, Status bits of last spi transfer */ + uint16 f1_info_reg; /* 0x0c, RO, enabled, ready for data transfer, blocksize */ + uint16 f2_info_reg; /* 0x0e, RO, enabled, ready for data transfer, blocksize */ + uint16 f3_info_reg; /* 0x10, RO, enabled, ready for data transfer, blocksize */ + uint32 test_read; /* 0x14, RO 0xfeedbead signature */ + uint32 test_rw; /* 0x18, RW */ + uint8 resp_delay_f0; /* 0x1c, read resp delay bytes for F0 (corerev >= 3) */ + uint8 resp_delay_f1; /* 0x1d, read resp delay bytes for F1 (corerev >= 3) */ + uint8 resp_delay_f2; /* 0x1e, read resp delay bytes for F2 (corerev >= 3) */ + uint8 resp_delay_f3; /* 0x1f, read resp delay bytes for F3 (corerev >= 3) */ +} spi_regs_t; + +/* SPI device register offsets */ +#define SPID_CONFIG 0x00 +#define SPID_RESPONSE_DELAY 0x01 +#define SPID_STATUS_ENABLE 0x02 +#define SPID_RESET_BP 0x03 /* (corerev >= 1) */ +#define SPID_INTR_REG 0x04 /* 16 bits - Interrupt status */ +#define SPID_INTR_EN_REG 0x06 /* 16 bits - Interrupt mask */ +#define SPID_STATUS_REG 0x08 /* 32 bits */ +#define SPID_F1_INFO_REG 0x0C /* 16 bits */ +#define SPID_F2_INFO_REG 0x0E /* 16 bits */ +#define SPID_F3_INFO_REG 0x10 /* 16 bits */ +#define SPID_TEST_READ 0x14 /* 32 bits */ +#define SPID_TEST_RW 0x18 /* 32 bits */ +#define SPID_RESP_DELAY_F0 0x1c /* 8 bits (corerev >= 3) */ +#define SPID_RESP_DELAY_F1 0x1d /* 8 bits (corerev >= 3) */ +#define SPID_RESP_DELAY_F2 0x1e /* 8 bits (corerev >= 3) */ +#define SPID_RESP_DELAY_F3 0x1f /* 8 bits (corerev >= 3) */ + +/* Bit masks for SPID_CONFIG device register */ +#define WORD_LENGTH_32 0x1 /* 0/1 16/32 bit word length */ +#define ENDIAN_BIG 0x2 /* 0/1 Little/Big Endian */ +#define CLOCK_PHASE 0x4 /* 0/1 clock phase delay */ +#define CLOCK_POLARITY 0x8 /* 0/1 Idle state clock polarity is low/high */ +#define HIGH_SPEED_MODE 0x10 /* 1/0 High Speed mode / Normal mode */ +#define INTR_POLARITY 0x20 /* 1/0 Interrupt active polarity is high/low */ +#define WAKE_UP 0x80 /* 0/1 Wake-up command from Host to WLAN */ + +/* Bit mask for SPID_RESPONSE_DELAY device register */ +#define RESPONSE_DELAY_MASK 0xFF /* Configurable rd response delay in multiples of 8 bits */ + +/* Bit mask for SPID_STATUS_ENABLE device register */ +#define STATUS_ENABLE 0x1 /* 1/0 Status sent/not sent to host after read/write */ +#define INTR_WITH_STATUS 0x2 /* 0/1 Do-not / do-interrupt if status is sent */ +#define RESP_DELAY_ALL 0x4 /* Applicability of resp delay to F1 or all func's read */ +#define DWORD_PKT_LEN_EN 0x8 /* Packet len denoted in dwords instead of bytes */ +#define CMD_ERR_CHK_EN 0x20 /* Command error check enable */ +#define DATA_ERR_CHK_EN 0x40 /* Data error check enable */ + +/* Bit mask for SPID_RESET_BP device register */ +#define RESET_ON_WLAN_BP_RESET 0x4 /* enable reset for WLAN backplane */ +#define RESET_ON_BT_BP_RESET 0x8 /* enable reset for BT backplane */ +#define RESET_SPI 0x80 /* reset the above enabled logic */ + +/* Bit mask for SPID_INTR_REG device register */ +#define DATA_UNAVAILABLE 0x0001 /* Requested data not available; Clear by writing a "1" */ +#define F2_F3_FIFO_RD_UNDERFLOW 0x0002 +#define F2_F3_FIFO_WR_OVERFLOW 0x0004 +#define COMMAND_ERROR 0x0008 /* Cleared by writing 1 */ +#define DATA_ERROR 0x0010 /* Cleared by writing 1 */ +#define F2_PACKET_AVAILABLE 0x0020 +#define F3_PACKET_AVAILABLE 0x0040 +#define F1_OVERFLOW 0x0080 /* Due to last write. Bkplane has pending write requests */ +#define MISC_INTR0 0x0100 +#define MISC_INTR1 0x0200 +#define MISC_INTR2 0x0400 +#define MISC_INTR3 0x0800 +#define MISC_INTR4 0x1000 +#define F1_INTR 0x2000 +#define F2_INTR 0x4000 +#define F3_INTR 0x8000 + +/* Bit mask for 32bit SPID_STATUS_REG device register */ +#define STATUS_DATA_NOT_AVAILABLE 0x00000001 +#define STATUS_UNDERFLOW 0x00000002 +#define STATUS_OVERFLOW 0x00000004 +#define STATUS_F2_INTR 0x00000008 +#define STATUS_F3_INTR 0x00000010 +#define STATUS_F2_RX_READY 0x00000020 +#define STATUS_F3_RX_READY 0x00000040 +#define STATUS_HOST_CMD_DATA_ERR 0x00000080 +#define STATUS_F2_PKT_AVAILABLE 0x00000100 +#define STATUS_F2_PKT_LEN_MASK 0x000FFE00 +#define STATUS_F2_PKT_LEN_SHIFT 9 +#define STATUS_F3_PKT_AVAILABLE 0x00100000 +#define STATUS_F3_PKT_LEN_MASK 0xFFE00000 +#define STATUS_F3_PKT_LEN_SHIFT 21 + +/* Bit mask for 16 bits SPID_F1_INFO_REG device register */ +#define F1_ENABLED 0x0001 +#define F1_RDY_FOR_DATA_TRANSFER 0x0002 +#define F1_MAX_PKT_SIZE 0x01FC + +/* Bit mask for 16 bits SPID_F2_INFO_REG device register */ +#define F2_ENABLED 0x0001 +#define F2_RDY_FOR_DATA_TRANSFER 0x0002 +#define F2_MAX_PKT_SIZE 0x3FFC + +/* Bit mask for 16 bits SPID_F3_INFO_REG device register */ +#define F3_ENABLED 0x0001 +#define F3_RDY_FOR_DATA_TRANSFER 0x0002 +#define F3_MAX_PKT_SIZE 0x3FFC + +/* Bit mask for 32 bits SPID_TEST_READ device register read in 16bit LE mode */ +#define TEST_RO_DATA_32BIT_LE 0xFEEDBEAD + +/* Maximum number of I/O funcs */ +#define SPI_MAX_IOFUNCS 4 + +#define SPI_MAX_PKT_LEN (2048*4) + +/* Misc defines */ +#define SPI_FUNC_0 0 +#define SPI_FUNC_1 1 +#define SPI_FUNC_2 2 +#define SPI_FUNC_3 3 + +#define WAIT_F2RXFIFORDY 100 +#define WAIT_F2RXFIFORDY_DELAY 20 + +#endif /* _SPI_H */ diff --git a/drivers/net/wireless/bcmdhd/include/trxhdr.h b/drivers/net/wireless/bcmdhd/include/trxhdr.h index b52fb15ba5c..bf92a5651af 100644 --- a/drivers/net/wireless/bcmdhd/include/trxhdr.h +++ b/drivers/net/wireless/bcmdhd/include/trxhdr.h @@ -1,9 +1,9 @@ /* * TRX image file header format. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,11 +21,11 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: trxhdr.h 286295 2011-09-27 06:39:43Z $ + * $Id: trxhdr.h 260898 2011-05-20 23:11:12Z $ */ -#ifndef _TRX_HDR_H_ -#define _TRX_HDR_H_ +#ifndef _TRX_HDR_H +#define _TRX_HDR_H #include @@ -34,10 +34,10 @@ #define TRX_MAX_LEN 0x3B0000 /* Max length */ #define TRX_NO_HEADER 1 /* Do not write TRX header */ #define TRX_GZ_FILES 0x2 /* Contains up to TRX_MAX_OFFSET individual gzip files */ -#define TRX_OVERLAYS 0x4 /* Contains an overlay header after the trx header */ -#define TRX_MAX_OFFSET 3 /* Max number of individual files */ -#define TRX_UNCOMP_IMAGE 0x20 /* Trx contains uncompressed rtecdc.bin image */ +#define TRX_EMBED_UCODE 0x8 /* Trx contains embedded ucode image */ #define TRX_ROMSIM_IMAGE 0x10 /* Trx contains ROM simulation image */ +#define TRX_UNCOMP_IMAGE 0x20 /* Trx contains uncompressed rtecdc.bin image */ +#define TRX_MAX_OFFSET 3 /* Max number of individual files */ struct trx_header { uint32 magic; /* "HDR0" */ @@ -50,4 +50,4 @@ struct trx_header { /* Compatibility */ typedef struct trx_header TRXHDR, *PTRXHDR; -#endif /* _TRX_HDR_H_ */ +#endif /* _TRX_HDR_H */ diff --git a/drivers/net/wireless/bcmdhd/include/typedefs.h b/drivers/net/wireless/bcmdhd/include/typedefs.h index d0902fe8089..4eee5bab8ce 100644 --- a/drivers/net/wireless/bcmdhd/include/typedefs.h +++ b/drivers/net/wireless/bcmdhd/include/typedefs.h @@ -1,7 +1,7 @@ /* - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -18,10 +18,9 @@ * Notwithstanding the above, under no circumstances may you combine this * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. - * $Id: typedefs.h 290055 2011-10-15 21:26:26Z $ + * $Id: typedefs.h 286783 2011-09-29 06:18:57Z $ */ - #ifndef _TYPEDEFS_H_ #define _TYPEDEFS_H_ @@ -66,7 +65,6 @@ typedef long unsigned int size_t; - #if defined(__sparc__) #define TYPEDEF_ULONG #endif @@ -260,7 +258,7 @@ typedef float64 float_t; -#if defined(__GNUC__) +#if defined(__GNUC__) || defined(__lint) #define BWL_COMPILER_GNU #elif defined(__CC_ARM) && __CC_ARM #define BWL_COMPILER_ARMCC diff --git a/drivers/net/wireless/bcmdhd/include/usbrdl.h b/drivers/net/wireless/bcmdhd/include/usbrdl.h new file mode 100644 index 00000000000..c90dccdcfad --- /dev/null +++ b/drivers/net/wireless/bcmdhd/include/usbrdl.h @@ -0,0 +1,203 @@ +/* + * Broadcom USB remote download definitions + * + * Copyright (C) 2012, Broadcom Corporation + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of Broadcom Corporation. + * + * $Id: usbrdl.h 296577 2011-11-16 03:09:51Z $ + */ + +#ifndef _USB_RDL_H +#define _USB_RDL_H + +/* Control messages: bRequest values */ +#define DL_GETSTATE 0 /* returns the rdl_state_t struct */ +#define DL_CHECK_CRC 1 /* currently unused */ +#define DL_GO 2 /* execute downloaded image */ +#define DL_START 3 /* initialize dl state */ +#define DL_REBOOT 4 /* reboot the device in 2 seconds */ +#define DL_GETVER 5 /* returns the bootrom_id_t struct */ +#define DL_GO_PROTECTED 6 /* execute the downloaded code and set reset event + * to occur in 2 seconds. It is the responsibility + * of the downloaded code to clear this event + */ +#define DL_EXEC 7 /* jump to a supplied address */ +#define DL_RESETCFG 8 /* To support single enum on dongle + * - Not used by bootloader + */ +#define DL_DEFER_RESP_OK 9 /* Potentially defer the response to setup + * if resp unavailable + */ + +#define DL_HWCMD_MASK 0xfc /* Mask for hardware read commands: */ +#define DL_RDHW 0x10 /* Read a hardware address (Ctl-in) */ +#define DL_RDHW32 0x10 /* Read a 32 bit word */ +#define DL_RDHW16 0x11 /* Read 16 bits */ +#define DL_RDHW8 0x12 /* Read an 8 bit byte */ +#define DL_WRHW 0x14 /* Write a hardware address (Ctl-out) */ +#define DL_WRHW_BLK 0x13 /* Block write to hardware access */ + +#define DL_CMD_RDHW 1 /* read data from a backplane address */ +#define DL_CMD_WRHW 2 /* write data to a backplane address */ + +#ifndef LINUX_POSTMOGRIFY_REMOVAL +#define DL_JTCONF 0x15 /* Get JTAG configuration (Ctl_in) + * Set JTAG configuration (Ctl-out) + */ +#define DL_JTON 0x16 /* Turn on jtag master (Ctl-in) */ +#define DL_JTOFF 0x17 /* Turn on jtag master (Ctl-in) */ +#define DL_RDRJT 0x18 /* Read a JTAG register (Ctl-in) */ +#define DL_WRJT 0x19 /* Write a hardware address over JTAG (Ctl/Bulk-out) */ +#define DL_WRRJT 0x1a /* Write a JTAG register (Ctl/Bulk-out) */ +#define DL_JTRST 0x1b /* Reset jtag fsm on jtag DUT (Ctl-in) */ + +#define DL_RDJT 0x1c /* Read a hardware address over JTAG (Ctl-in) */ +#define DL_RDJT32 0x1c /* Read 32 bits */ +#define DL_RDJT16 0x1e /* Read 16 bits (sz = 4 - low bits) */ +#define DL_RDJT8 0x1f /* Read 8 bits */ + +#define DL_MRDJT 0x20 /* Multiple read over JTAG (Ctl-out+Bulk-in) */ +#define DL_MRDJT32 0x20 /* M-read 32 bits */ +#define DL_MRDJT16 0x22 /* M-read 16 bits (sz = 4 - low bits) */ +#define DL_MRDJT6 0x23 /* M-read 8 bits */ +#define DL_MRDIJT 0x24 /* M-read over JTAG (Ctl-out+Bulk-in) with auto-increment */ +#define DL_MRDIJT32 0x24 /* M-read 32 bits w/ai */ +#define DL_MRDIJT16 0x26 /* M-read 16 bits w/ai (sz = 4 - low bits) */ +#define DL_MRDIJT8 0x27 /* M-read 8 bits w/ai */ +#define DL_MRDDJT 0x28 /* M-read over JTAG (Ctl-out+Bulk-in) with auto-decrement */ +#define DL_MRDDJT32 0x28 /* M-read 32 bits w/ad */ +#define DL_MRDDJT16 0x2a /* M-read 16 bits w/ad (sz = 4 - low bits) */ +#define DL_MRDDJT8 0x2b /* M-read 8 bits w/ad */ +#define DL_MWRJT 0x2c /* Multiple write over JTAG (Bulk-out) */ +#define DL_MWRIJT 0x2d /* With auto-increment */ +#define DL_MWRDJT 0x2e /* With auto-decrement */ +#define DL_VRDJT 0x2f /* Vector read over JTAG (Bulk-out+Bulk-in) */ +#define DL_VWRJT 0x30 /* Vector write over JTAG (Bulk-out+Bulk-in) */ +#define DL_SCJT 0x31 /* Jtag scan (Bulk-out+Bulk-in) */ + +#define DL_CFRD 0x33 /* Reserved for dmamem use */ +#define DL_CFWR 0x34 /* Reserved for dmamem use */ +#define DL_GET_NVRAM 0x35 /* Query nvram parameter */ + +#define DL_DBGTRIG 0xFF /* Trigger bRequest type to aid debug */ + +#define DL_JTERROR 0x80000000 +#endif /* LINUX_POSTMOGRIFY_REMOVAL */ + +/* states */ +#define DL_WAITING 0 /* waiting to rx first pkt that includes the hdr info */ +#define DL_READY 1 /* hdr was good, waiting for more of the compressed image */ +#define DL_BAD_HDR 2 /* hdr was corrupted */ +#define DL_BAD_CRC 3 /* compressed image was corrupted */ +#define DL_RUNNABLE 4 /* download was successful, waiting for go cmd */ +#define DL_START_FAIL 5 /* failed to initialize correctly */ +#define DL_NVRAM_TOOBIG 6 /* host specified nvram data exceeds DL_NVRAM value */ +#define DL_IMAGE_TOOBIG 7 /* download image too big (exceeds DATA_START for rdl) */ + +#define TIMEOUT 5000 /* Timeout for usb commands */ + +struct bcm_device_id { + char *name; + uint32 vend; + uint32 prod; +}; + +typedef struct { + uint32 state; + uint32 bytes; +} rdl_state_t; + +typedef struct { + uint32 chip; /* Chip id */ + uint32 chiprev; /* Chip rev */ + uint32 ramsize; /* Size of RAM */ + uint32 remapbase; /* Current remap base address */ + uint32 boardtype; /* Type of board */ + uint32 boardrev; /* Board revision */ +} bootrom_id_t; + +/* struct for backplane & jtag accesses */ +typedef struct { + uint32 cmd; /* tag to identify the cmd */ + uint32 addr; /* backplane address for write */ + uint32 len; /* length of data: 1, 2, 4 bytes */ + uint32 data; /* data to write */ +} hwacc_t; + +/* struct for backplane */ +typedef struct { + uint32 cmd; /* tag to identify the cmd */ + uint32 addr; /* backplane address for write */ + uint32 len; /* length of data: 1, 2, 4 bytes */ + uint8 data[1]; /* data to write */ +} hwacc_blk_t; + +#ifndef LINUX_POSTMOGRIFY_REMOVAL +typedef struct { + uint32 chip; /* Chip id */ + uint32 chiprev; /* Chip rev */ + uint32 ccrev; /* Chipcommon core rev */ + uint32 siclock; /* Backplane clock */ +} jtagd_id_t; + +/* Jtag configuration structure */ +typedef struct { + uint32 cmd; /* tag to identify the cmd */ + uint8 clkd; /* Jtag clock divisor */ + uint8 disgpio; /* Gpio to disable external driver */ + uint8 irsz; /* IR size for readreg/writereg */ + uint8 drsz; /* DR size for readreg/writereg */ + + uint8 bigend; /* Big endian */ + uint8 mode; /* Current mode */ + uint16 delay; /* Delay between jtagm "simple commands" */ + + uint32 retries; /* Number of retries for jtagm operations */ + uint32 ctrl; /* Jtag control reg copy */ + uint32 ir_lvbase; /* Bits to add to IR values in LV tap */ + uint32 dretries; /* Number of retries for dma operations */ +} jtagconf_t; + +/* struct for jtag scan */ +#define MAX_USB_IR_BITS 256 +#define MAX_USB_DR_BITS 3072 +#define USB_IR_WORDS (MAX_USB_IR_BITS / 32) +#define USB_DR_WORDS (MAX_USB_DR_BITS / 32) +typedef struct { + uint32 cmd; /* tag to identify the cmd */ + uint32 irsz; /* IR size in bits */ + uint32 drsz; /* DR size in bits */ + uint32 ts; /* Terminal state (def, pause, rti) */ + uint32 data[USB_IR_WORDS + USB_DR_WORDS]; /* IR & DR data */ +} scjt_t; +#endif /* LINUX_POSTMOGRIFY_REMOVAL */ + +/* struct for querying nvram params from bootloader */ +#define QUERY_STRING_MAX 32 +typedef struct { + uint32 cmd; /* tag to identify the cmd */ + char var[QUERY_STRING_MAX]; /* param name */ +} nvparam_t; + +typedef void (*exec_fn_t)(void *sih); + +#define USB_CTRL_IN (USB_TYPE_VENDOR | 0x80 | USB_RECIP_INTERFACE) +#define USB_CTRL_OUT (USB_TYPE_VENDOR | 0 | USB_RECIP_INTERFACE) + +#define USB_CTRL_EP_TIMEOUT 500 /* Timeout used in USB control_msg transactions. */ + +#define RDL_CHUNK 1500 /* size of each dl transfer */ + +/* bootloader makes special use of trx header "offsets" array */ +#define TRX_OFFSETS_DLFWLEN_IDX 0 /* Size of the fw; used in uncompressed case */ +#define TRX_OFFSETS_JUMPTO_IDX 1 /* RAM address for jumpto after download */ +#define TRX_OFFSETS_NVM_LEN_IDX 2 /* Length of appended NVRAM data */ + +#define TRX_OFFSETS_DLBASE_IDX 0 /* RAM start address for download */ + +#endif /* _USB_RDL_H */ diff --git a/drivers/net/wireless/bcmdhd/include/wlc_clm_rates.h b/drivers/net/wireless/bcmdhd/include/wlc_clm_rates.h new file mode 100644 index 00000000000..d9061bb8c5d --- /dev/null +++ b/drivers/net/wireless/bcmdhd/include/wlc_clm_rates.h @@ -0,0 +1,255 @@ +/* + * Indices for 802.11 a/b/g/n/ac 1-3 chain symmetric transmit rates + * Copyright (C) 2012, Broadcom Corporation + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of Broadcom Corporation. + * + * $Id: wlc_clm_rates.h 252708 2011-04-12 06:45:56Z $ + */ + +#ifndef _WLC_CLM_RATES_H_ +#define _WLC_CLM_RATES_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef enum clm_rates { + /************ + * 1 chain * + ************ + */ + + /* 1 Stream */ + CLM_RATE_1X1_DSSS_1 = 0, + CLM_RATE_1X1_DSSS_2 = 1, + CLM_RATE_1X1_DSSS_5_5 = 2, + CLM_RATE_1X1_DSSS_11 = 3, + + CLM_RATE_1X1_OFDM_6 = 4, + CLM_RATE_1X1_OFDM_9 = 5, + CLM_RATE_1X1_OFDM_12 = 6, + CLM_RATE_1X1_OFDM_18 = 7, + CLM_RATE_1X1_OFDM_24 = 8, + CLM_RATE_1X1_OFDM_36 = 9, + CLM_RATE_1X1_OFDM_48 = 10, + CLM_RATE_1X1_OFDM_54 = 11, + + CLM_RATE_1X1_MCS0 = 12, + CLM_RATE_1X1_MCS1 = 13, + CLM_RATE_1X1_MCS2 = 14, + CLM_RATE_1X1_MCS3 = 15, + CLM_RATE_1X1_MCS4 = 16, + CLM_RATE_1X1_MCS5 = 17, + CLM_RATE_1X1_MCS6 = 18, + CLM_RATE_1X1_MCS7 = 19, + + CLM_RATE_1X1_VHT0SS1 = 12, + CLM_RATE_1X1_VHT1SS1 = 13, + CLM_RATE_1X1_VHT2SS1 = 14, + CLM_RATE_1X1_VHT3SS1 = 15, + CLM_RATE_1X1_VHT4SS1 = 16, + CLM_RATE_1X1_VHT5SS1 = 17, + CLM_RATE_1X1_VHT6SS1 = 18, + CLM_RATE_1X1_VHT7SS1 = 19, + CLM_RATE_1X1_VHT8SS1 = 20, + CLM_RATE_1X1_VHT9SS1 = 21, + + + /************ + * 2 chains * + ************ + */ + + /* 1 Stream expanded + 1 */ + CLM_RATE_1X2_DSSS_1 = 22, + CLM_RATE_1X2_DSSS_2 = 23, + CLM_RATE_1X2_DSSS_5_5 = 24, + CLM_RATE_1X2_DSSS_11 = 25, + + CLM_RATE_1X2_CDD_OFDM_6 = 26, + CLM_RATE_1X2_CDD_OFDM_9 = 27, + CLM_RATE_1X2_CDD_OFDM_12 = 28, + CLM_RATE_1X2_CDD_OFDM_18 = 29, + CLM_RATE_1X2_CDD_OFDM_24 = 30, + CLM_RATE_1X2_CDD_OFDM_36 = 31, + CLM_RATE_1X2_CDD_OFDM_48 = 32, + CLM_RATE_1X2_CDD_OFDM_54 = 33, + + CLM_RATE_1X2_CDD_MCS0 = 34, + CLM_RATE_1X2_CDD_MCS1 = 35, + CLM_RATE_1X2_CDD_MCS2 = 36, + CLM_RATE_1X2_CDD_MCS3 = 37, + CLM_RATE_1X2_CDD_MCS4 = 38, + CLM_RATE_1X2_CDD_MCS5 = 39, + CLM_RATE_1X2_CDD_MCS6 = 40, + CLM_RATE_1X2_CDD_MCS7 = 41, + + CLM_RATE_1X2_VHT0SS1 = 34, + CLM_RATE_1X2_VHT1SS1 = 35, + CLM_RATE_1X2_VHT2SS1 = 36, + CLM_RATE_1X2_VHT3SS1 = 37, + CLM_RATE_1X2_VHT4SS1 = 38, + CLM_RATE_1X2_VHT5SS1 = 39, + CLM_RATE_1X2_VHT6SS1 = 40, + CLM_RATE_1X2_VHT7SS1 = 41, + CLM_RATE_1X2_VHT8SS1 = 42, + CLM_RATE_1X2_VHT9SS1 = 43, + + /* 2 Streams */ + CLM_RATE_2X2_STBC_MCS0 = 44, + CLM_RATE_2X2_STBC_MCS1 = 45, + CLM_RATE_2X2_STBC_MCS2 = 46, + CLM_RATE_2X2_STBC_MCS3 = 47, + CLM_RATE_2X2_STBC_MCS4 = 48, + CLM_RATE_2X2_STBC_MCS5 = 49, + CLM_RATE_2X2_STBC_MCS6 = 50, + CLM_RATE_2X2_STBC_MCS7 = 51, + + CLM_RATE_2X2_STBC_VHT0SS1 = 44, + CLM_RATE_2X2_STBC_VHT1SS1 = 45, + CLM_RATE_2X2_STBC_VHT2SS1 = 46, + CLM_RATE_2X2_STBC_VHT3SS1 = 47, + CLM_RATE_2X2_STBC_VHT4SS1 = 48, + CLM_RATE_2X2_STBC_VHT5SS1 = 49, + CLM_RATE_2X2_STBC_VHT6SS1 = 50, + CLM_RATE_2X2_STBC_VHT7SS1 = 51, + CLM_RATE_2X2_STBC_VHT8SS1 = 52, + CLM_RATE_2X2_STBC_VHT9SS1 = 53, + + CLM_RATE_2X2_SDM_MCS8 = 54, + CLM_RATE_2X2_SDM_MCS9 = 55, + CLM_RATE_2X2_SDM_MCS10 = 56, + CLM_RATE_2X2_SDM_MCS11 = 57, + CLM_RATE_2X2_SDM_MCS12 = 58, + CLM_RATE_2X2_SDM_MCS13 = 59, + CLM_RATE_2X2_SDM_MCS14 = 60, + CLM_RATE_2X2_SDM_MCS15 = 61, + + CLM_RATE_2X2_VHT0SS2 = 54, + CLM_RATE_2X2_VHT1SS2 = 55, + CLM_RATE_2X2_VHT2SS2 = 56, + CLM_RATE_2X2_VHT3SS2 = 57, + CLM_RATE_2X2_VHT4SS2 = 58, + CLM_RATE_2X2_VHT5SS2 = 59, + CLM_RATE_2X2_VHT6SS2 = 60, + CLM_RATE_2X2_VHT7SS2 = 61, + CLM_RATE_2X2_VHT8SS2 = 62, + CLM_RATE_2X2_VHT9SS2 = 63, + + + /************ + * 3 chains * + ************ + */ + + /* 1 Stream expanded + 2 */ + CLM_RATE_1X3_DSSS_1 = 64, + CLM_RATE_1X3_DSSS_2 = 65, + CLM_RATE_1X3_DSSS_5_5 = 66, + CLM_RATE_1X3_DSSS_11 = 67, + + CLM_RATE_1X3_CDD_OFDM_6 = 68, + CLM_RATE_1X3_CDD_OFDM_9 = 69, + CLM_RATE_1X3_CDD_OFDM_12 = 70, + CLM_RATE_1X3_CDD_OFDM_18 = 71, + CLM_RATE_1X3_CDD_OFDM_24 = 72, + CLM_RATE_1X3_CDD_OFDM_36 = 73, + CLM_RATE_1X3_CDD_OFDM_48 = 74, + CLM_RATE_1X3_CDD_OFDM_54 = 75, + + CLM_RATE_1X3_CDD_MCS0 = 76, + CLM_RATE_1X3_CDD_MCS1 = 77, + CLM_RATE_1X3_CDD_MCS2 = 78, + CLM_RATE_1X3_CDD_MCS3 = 79, + CLM_RATE_1X3_CDD_MCS4 = 80, + CLM_RATE_1X3_CDD_MCS5 = 81, + CLM_RATE_1X3_CDD_MCS6 = 82, + CLM_RATE_1X3_CDD_MCS7 = 83, + + CLM_RATE_1X3_VHT0SS1 = 76, + CLM_RATE_1X3_VHT1SS1 = 77, + CLM_RATE_1X3_VHT2SS1 = 78, + CLM_RATE_1X3_VHT3SS1 = 79, + CLM_RATE_1X3_VHT4SS1 = 80, + CLM_RATE_1X3_VHT5SS1 = 81, + CLM_RATE_1X3_VHT6SS1 = 82, + CLM_RATE_1X3_VHT7SS1 = 83, + CLM_RATE_1X3_VHT8SS1 = 84, + CLM_RATE_1X3_VHT9SS1 = 85, + + /* 2 Streams expanded + 1 */ + CLM_RATE_2X3_STBC_MCS0 = 86, + CLM_RATE_2X3_STBC_MCS1 = 87, + CLM_RATE_2X3_STBC_MCS2 = 88, + CLM_RATE_2X3_STBC_MCS3 = 89, + CLM_RATE_2X3_STBC_MCS4 = 90, + CLM_RATE_2X3_STBC_MCS5 = 91, + CLM_RATE_2X3_STBC_MCS6 = 92, + CLM_RATE_2X3_STBC_MCS7 = 93, + + CLM_RATE_2X3_STBC_VHT0SS1 = 86, + CLM_RATE_2X3_STBC_VHT1SS1 = 87, + CLM_RATE_2X3_STBC_VHT2SS1 = 88, + CLM_RATE_2X3_STBC_VHT3SS1 = 89, + CLM_RATE_2X3_STBC_VHT4SS1 = 90, + CLM_RATE_2X3_STBC_VHT5SS1 = 91, + CLM_RATE_2X3_STBC_VHT6SS1 = 92, + CLM_RATE_2X3_STBC_VHT7SS1 = 93, + CLM_RATE_2X3_STBC_VHT8SS1 = 94, + CLM_RATE_2X3_STBC_VHT9SS1 = 95, + + CLM_RATE_2X3_SDM_MCS8 = 96, + CLM_RATE_2X3_SDM_MCS9 = 97, + CLM_RATE_2X3_SDM_MCS10 = 98, + CLM_RATE_2X3_SDM_MCS11 = 99, + CLM_RATE_2X3_SDM_MCS12 = 100, + CLM_RATE_2X3_SDM_MCS13 = 101, + CLM_RATE_2X3_SDM_MCS14 = 102, + CLM_RATE_2X3_SDM_MCS15 = 103, + + CLM_RATE_2X3_VHT0SS2 = 96, + CLM_RATE_2X3_VHT1SS2 = 97, + CLM_RATE_2X3_VHT2SS2 = 98, + CLM_RATE_2X3_VHT3SS2 = 99, + CLM_RATE_2X3_VHT4SS2 = 100, + CLM_RATE_2X3_VHT5SS2 = 101, + CLM_RATE_2X3_VHT6SS2 = 102, + CLM_RATE_2X3_VHT7SS2 = 103, + CLM_RATE_2X3_VHT8SS2 = 104, + CLM_RATE_2X3_VHT9SS2 = 105, + + /* 3 Streams */ + CLM_RATE_3X3_SDM_MCS16 = 106, + CLM_RATE_3X3_SDM_MCS17 = 107, + CLM_RATE_3X3_SDM_MCS18 = 108, + CLM_RATE_3X3_SDM_MCS19 = 109, + CLM_RATE_3X3_SDM_MCS20 = 110, + CLM_RATE_3X3_SDM_MCS21 = 111, + CLM_RATE_3X3_SDM_MCS22 = 112, + CLM_RATE_3X3_SDM_MCS23 = 113, + + CLM_RATE_3X3_VHT0SS3 = 106, + CLM_RATE_3X3_VHT1SS3 = 107, + CLM_RATE_3X3_VHT2SS3 = 108, + CLM_RATE_3X3_VHT3SS3 = 109, + CLM_RATE_3X3_VHT4SS3 = 110, + CLM_RATE_3X3_VHT5SS3 = 111, + CLM_RATE_3X3_VHT6SS3 = 112, + CLM_RATE_3X3_VHT7SS3 = 113, + CLM_RATE_3X3_VHT8SS3 = 114, + CLM_RATE_3X3_VHT9SS3 = 115, + + /* Number of rate codes */ + CLM_NUMRATES = 116, + } clm_rates_t; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _WLC_CLM_RATES_H_ */ diff --git a/drivers/net/wireless/bcmdhd/include/wlc_extlog_idstr.h b/drivers/net/wireless/bcmdhd/include/wlc_extlog_idstr.h new file mode 100644 index 00000000000..95f616a5fc7 --- /dev/null +++ b/drivers/net/wireless/bcmdhd/include/wlc_extlog_idstr.h @@ -0,0 +1,117 @@ +/* + * EXTLOG Module log ID to log Format String mapping table + * + * Copyright (C) 2012, Broadcom Corporation + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of Broadcom Corporation. + * + * $Id: wlc_extlog_idstr.h 241182 2011-02-17 21:50:03Z $ + */ +#ifndef _WLC_EXTLOG_IDSTR_H_ +#define _WLC_EXTLOG_IDSTR_H_ + +#include "wlioctl.h" + +/* Strings corresponding to the IDs defined in wlioctl.h + * This file is only included by the apps and not included by the external driver + * Formats of pre-existing ids should NOT be changed + */ +log_idstr_t extlog_fmt_str[ ] = { + {FMTSTR_DRIVER_UP_ID, 0, LOG_ARGTYPE_NULL, + "Driver is Up\n"}, + + {FMTSTR_DRIVER_DOWN_ID, 0, LOG_ARGTYPE_NULL, + "Driver is Down\n"}, + + {FMTSTR_SUSPEND_MAC_FAIL_ID, 0, LOG_ARGTYPE_INT, + "wlc_suspend_mac_and_wait() failed with psmdebug 0x%08x\n"}, + + {FMTSTR_NO_PROGRESS_ID, 0, LOG_ARGTYPE_INT, + "No Progress on TX for %d seconds\n"}, + + {FMTSTR_RFDISABLE_ID, 0, LOG_ARGTYPE_INT, + "Detected a change in RF Disable Input 0x%x\n"}, + + {FMTSTR_REG_PRINT_ID, 0, LOG_ARGTYPE_STR_INT, + "Register %s = 0x%x\n"}, + + {FMTSTR_EXPTIME_ID, FMTSTRF_USER, LOG_ARGTYPE_NULL, + "Strong RF interference detected\n"}, + + {FMTSTR_JOIN_START_ID, FMTSTRF_USER, LOG_ARGTYPE_STR, + "Searching for networks with ssid %s\n"}, + + {FMTSTR_JOIN_COMPLETE_ID, FMTSTRF_USER, LOG_ARGTYPE_STR, + "Successfully joined network with BSSID %s\n"}, + + {FMTSTR_NO_NETWORKS_ID, FMTSTRF_USER, LOG_ARGTYPE_NULL, + "No networks found. Please check if the network exists and is in range\n"}, + + {FMTSTR_SECURITY_MISMATCH_ID, FMTSTRF_USER, LOG_ARGTYPE_NULL, + "AP rejected due to security mismatch. Change the security settings and try again...\n"}, + + {FMTSTR_RATE_MISMATCH_ID, FMTSTRF_USER, LOG_ARGTYPE_NULL, + "AP rejected due to rate mismatch\n"}, + + {FMTSTR_AP_PRUNED_ID, 0, LOG_ARGTYPE_INT, + "AP rejected due to reason %d\n"}, + + {FMTSTR_KEY_INSERTED_ID, 0, LOG_ARGTYPE_INT, + "Inserting keys for algorithm %d\n"}, + + {FMTSTR_DEAUTH_ID, FMTSTRF_USER, LOG_ARGTYPE_STR_INT, + "Received Deauth from %s with Reason %d\n"}, + + {FMTSTR_DISASSOC_ID, FMTSTRF_USER, LOG_ARGTYPE_STR_INT, + "Received Disassoc from %s with Reason %d\n"}, + + {FMTSTR_LINK_UP_ID, FMTSTRF_USER, LOG_ARGTYPE_NULL, + "Link Up\n"}, + + {FMTSTR_LINK_DOWN_ID, FMTSTRF_USER, LOG_ARGTYPE_NULL, + "Link Down\n"}, + + {FMTSTR_RADIO_HW_OFF_ID, FMTSTRF_USER, LOG_ARGTYPE_NULL, + "Radio button is turned OFF. Please turn it on...\n"}, + + {FMTSTR_RADIO_HW_ON_ID, FMTSTRF_USER, LOG_ARGTYPE_NULL, + "Hardware Radio button is turned ON\n"}, + + {FMTSTR_EVENT_DESC_ID, 0, LOG_ARGTYPE_INT_STR, + "Generated event id %d: (result status) is (%s)\n"}, + + {FMTSTR_PNP_SET_POWER_ID, 0, LOG_ARGTYPE_INT, + "Device going into power state %d\n"}, + + {FMTSTR_RADIO_SW_OFF_ID, FMTSTRF_USER, LOG_ARGTYPE_NULL, + "Software Radio is disabled. Please enable it through the UI...\n"}, + + {FMTSTR_RADIO_SW_ON_ID, FMTSTRF_USER, LOG_ARGTYPE_NULL, + "Software Radio is enabled\n"}, + + {FMTSTR_PWD_MISMATCH_ID, FMTSTRF_USER, LOG_ARGTYPE_NULL, + "Potential passphrase mismatch. Please try a different one...\n"}, + + {FMTSTR_FATAL_ERROR_ID, 0, LOG_ARGTYPE_INT, + "Fatal Error: intstatus 0x%x\n"}, + + {FMTSTR_AUTH_FAIL_ID, 0, LOG_ARGTYPE_STR_INT, + "Authentication to %s Failed with status %d\n"}, + + {FMTSTR_ASSOC_FAIL_ID, 0, LOG_ARGTYPE_STR_INT, + "Association to %s Failed with status %d\n"}, + + {FMTSTR_IBSS_FAIL_ID, FMTSTRF_USER, LOG_ARGTYPE_NULL, + "Unable to start IBSS since PeerNet is already active\n"}, + + {FMTSTR_EXTAP_FAIL_ID, FMTSTRF_USER, LOG_ARGTYPE_NULL, + "Unable to start Ext-AP since PeerNet is already active\n"}, + + {FMTSTR_MAX_ID, 0, 0, "\0"} +}; + +#endif /* _WLC_EXTLOG_IDSTR_H_ */ diff --git a/drivers/net/wireless/bcmdhd/include/wlfc_proto.h b/drivers/net/wireless/bcmdhd/include/wlfc_proto.h index d37105165ba..f656a638825 100644 --- a/drivers/net/wireless/bcmdhd/include/wlfc_proto.h +++ b/drivers/net/wireless/bcmdhd/include/wlfc_proto.h @@ -1,7 +1,7 @@ /* -* Copyright (C) 1999-2011, Broadcom Corporation +* Copyright (C) 1999-2012, Broadcom Corporation * -* Unless you and Broadcom execute a separate written software license +* Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -18,7 +18,7 @@ * Notwithstanding the above, under no circumstances may you combine this * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. -* $Id: wlfc_proto.h 277737 2011-08-16 17:54:59Z $ +* $Id: wlfc_proto.h 309193 2012-01-19 00:03:57Z $ * */ #ifndef __wlfc_proto_definitions_h__ @@ -68,15 +68,15 @@ --------------------------------------------------------------------------- */ -#define WLFC_CTL_TYPE_MAC_OPEN 1 -#define WLFC_CTL_TYPE_MAC_CLOSE 2 -#define WLFC_CTL_TYPE_MAC_REQUEST_CREDIT 3 -#define WLFC_CTL_TYPE_TXSTATUS 4 -#define WLFC_CTL_TYPE_PKTTAG 5 +#define WLFC_CTL_TYPE_MAC_OPEN 1 +#define WLFC_CTL_TYPE_MAC_CLOSE 2 +#define WLFC_CTL_TYPE_MAC_REQUEST_CREDIT 3 +#define WLFC_CTL_TYPE_TXSTATUS 4 +#define WLFC_CTL_TYPE_PKTTAG 5 -#define WLFC_CTL_TYPE_MACDESC_ADD 6 -#define WLFC_CTL_TYPE_MACDESC_DEL 7 -#define WLFC_CTL_TYPE_RSSI 8 +#define WLFC_CTL_TYPE_MACDESC_ADD 6 +#define WLFC_CTL_TYPE_MACDESC_DEL 7 +#define WLFC_CTL_TYPE_RSSI 8 #define WLFC_CTL_TYPE_INTERFACE_OPEN 9 #define WLFC_CTL_TYPE_INTERFACE_CLOSE 10 @@ -85,6 +85,7 @@ #define WLFC_CTL_TYPE_PENDING_TRAFFIC_BMP 12 #define WLFC_CTL_TYPE_MAC_REQUEST_PACKET 13 +#define WLFC_CTL_TYPE_HOST_REORDER_RXPKTS 14 #define WLFC_CTL_TYPE_FILLER 255 @@ -169,15 +170,15 @@ #define WLFC_CTL_PKTFLAG_DISCARD 0 /* D11 suppressed a packet */ #define WLFC_CTL_PKTFLAG_D11SUPPRESS 1 -/* WL firmware suppressed a packet because MAC is +/* WL firmware suppressed a packet because MAC is already in PSMode (short time window) */ #define WLFC_CTL_PKTFLAG_WLSUPPRESS 2 /* Firmware tossed this packet */ #define WLFC_CTL_PKTFLAG_TOSSED_BYWLC 3 -#define WLFC_D11_STATUS_INTERPRET(txs) ((((txs)->status & TX_STATUS_SUPR_MASK) >> \ - TX_STATUS_SUPR_SHIFT)) ? WLFC_CTL_PKTFLAG_D11SUPPRESS : WLFC_CTL_PKTFLAG_DISCARD +#define WLFC_D11_STATUS_INTERPRET(txs) \ + (((txs)->status.suppr_ind != 0) ? WLFC_CTL_PKTFLAG_D11SUPPRESS : WLFC_CTL_PKTFLAG_DISCARD) #ifdef PROP_TXSTATUS_DEBUG #define WLFC_DBGMESG(x) printf x @@ -195,4 +196,21 @@ #define WLFC_WHEREIS(s) #endif +/* AMPDU host reorder packet flags */ +#define WLHOST_REORDERDATA_MAXFLOWS 256 +#define WLHOST_REORDERDATA_LEN 10 +#define WLHOST_REORDERDATA_TOTLEN (WLHOST_REORDERDATA_LEN + 1 + 1) /* +tag +len */ + +#define WLHOST_REORDERDATA_FLOWID_OFFSET 0 +#define WLHOST_REORDERDATA_MAXIDX_OFFSET 2 +#define WLHOST_REORDERDATA_FLAGS_OFFSET 4 +#define WLHOST_REORDERDATA_CURIDX_OFFSET 6 +#define WLHOST_REORDERDATA_EXPIDX_OFFSET 8 + +#define WLHOST_REORDERDATA_DEL_FLOW 0x01 +#define WLHOST_REORDERDATA_FLUSH_ALL 0x02 +#define WLHOST_REORDERDATA_CURIDX_VALID 0x04 +#define WLHOST_REORDERDATA_EXPIDX_VALID 0x08 +#define WLHOST_REORDERDATA_NEW_HOLE 0x10 + #endif /* __wlfc_proto_definitions_h__ */ diff --git a/drivers/net/wireless/bcmdhd/include/wlioctl.h b/drivers/net/wireless/bcmdhd/include/wlioctl.h index e31bfa94c00..e2ba2442fdc 100644 --- a/drivers/net/wireless/bcmdhd/include/wlioctl.h +++ b/drivers/net/wireless/bcmdhd/include/wlioctl.h @@ -4,9 +4,9 @@ * * Definitions subject to change without notice. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -24,12 +24,11 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: wlioctl.h 307468 2012-01-11 18:29:27Z $ + * $Id: wlioctl.h 310294 2012-01-24 06:17:47Z $ */ - #ifndef _wlioctl_h_ -#define _wlioctl_h_ +#define _wlioctl_h_ #include #include @@ -38,177 +37,347 @@ #include #include +#include #include #ifndef INTF_NAME_SIZ -#define INTF_NAME_SIZ 16 +#define INTF_NAME_SIZ 16 #endif - +/* Used to send ioctls over the transport pipe */ typedef struct remote_ioctl { - cdc_ioctl_t msg; - uint data_len; + cdc_ioctl_t msg; + uint data_len; char intf_name[INTF_NAME_SIZ]; } rem_ioctl_t; -#define REMOTE_SIZE sizeof(rem_ioctl_t) +#define REMOTE_SIZE sizeof(rem_ioctl_t) -#define ACTION_FRAME_SIZE 1040 +#define ACTION_FRAME_SIZE 1800 typedef struct wl_action_frame { - struct ether_addr da; - uint16 len; - uint32 packetId; - uint8 data[ACTION_FRAME_SIZE]; + struct ether_addr da; + uint16 len; + uint32 packetId; + uint8 data[ACTION_FRAME_SIZE]; } wl_action_frame_t; #define WL_WIFI_ACTION_FRAME_SIZE sizeof(struct wl_action_frame) typedef struct ssid_info { - uint8 ssid_len; - uint8 ssid[32]; + uint8 ssid_len; /* the length of SSID */ + uint8 ssid[32]; /* SSID string */ } ssid_info_t; typedef struct wl_af_params { - uint32 channel; - int32 dwell_time; - struct ether_addr BSSID; - wl_action_frame_t action_frame; + uint32 channel; + int32 dwell_time; + struct ether_addr BSSID; + wl_action_frame_t action_frame; } wl_af_params_t; #define WL_WIFI_AF_PARAMS_SIZE sizeof(struct wl_af_params) +#define MFP_TEST_FLAG_NORMAL 0 +#define MFP_TEST_FLAG_ANY_KEY 1 +typedef struct wl_sa_query { + uint32 flag; + uint8 action; + uint16 id; + struct ether_addr da; +} wl_sa_query_t; + +/* require default structure packing */ #define BWL_DEFAULT_PACKING #include +#ifndef LINUX_POSTMOGRIFY_REMOVAL +/* Legacy structure to help keep backward compatible wl tool and tray app */ +#define LEGACY_WL_BSS_INFO_VERSION 107 /* older version of wl_bss_info struct */ +typedef struct wl_bss_info_107 { + uint32 version; /* version field */ + uint32 length; /* byte length of data in this record, + * starting at version and including IEs + */ + struct ether_addr BSSID; + uint16 beacon_period; /* units are Kusec */ + uint16 capability; /* Capability information */ + uint8 SSID_len; + uint8 SSID[32]; + struct { + uint count; /* # rates in this set */ + uint8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */ + } rateset; /* supported rates */ + uint8 channel; /* Channel no. */ + uint16 atim_window; /* units are Kusec */ + uint8 dtim_period; /* DTIM period */ + int16 RSSI; /* receive signal strength (in dBm) */ + int8 phy_noise; /* noise (in dBm) */ + uint32 ie_length; /* byte length of Information Elements */ + /* variable length Information Elements */ +} wl_bss_info_107_t; +#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -#define LEGACY2_WL_BSS_INFO_VERSION 108 +/* + * Per-BSS information structure. + */ +#define LEGACY2_WL_BSS_INFO_VERSION 108 /* old version of wl_bss_info struct */ +/* BSS info structure + * Applications MUST CHECK ie_offset field and length field to access IEs and + * next bss_info structure in a vector (in wl_scan_results_t) + */ typedef struct wl_bss_info_108 { - uint32 version; - uint32 length; + uint32 version; /* version field */ + uint32 length; /* byte length of data in this record, + * starting at version and including IEs + */ struct ether_addr BSSID; - uint16 beacon_period; - uint16 capability; - uint8 SSID_len; - uint8 SSID[32]; + uint16 beacon_period; /* units are Kusec */ + uint16 capability; /* Capability information */ + uint8 SSID_len; + uint8 SSID[32]; struct { - uint count; - uint8 rates[16]; - } rateset; - chanspec_t chanspec; - uint16 atim_window; - uint8 dtim_period; - int16 RSSI; - int8 phy_noise; - - uint8 n_cap; - uint32 nbss_cap; - uint8 ctl_ch; - uint32 reserved32[1]; - uint8 flags; - uint8 reserved[3]; - uint8 basic_mcs[MCSSET_LEN]; - - uint16 ie_offset; - uint32 ie_length; - - + uint count; /* # rates in this set */ + uint8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */ + } rateset; /* supported rates */ + chanspec_t chanspec; /* chanspec for bss */ + uint16 atim_window; /* units are Kusec */ + uint8 dtim_period; /* DTIM period */ + int16 RSSI; /* receive signal strength (in dBm) */ + int8 phy_noise; /* noise (in dBm) */ + + uint8 n_cap; /* BSS is 802.11N Capable */ + uint32 nbss_cap; /* 802.11N BSS Capabilities (based on HT_CAP_*) */ + uint8 ctl_ch; /* 802.11N BSS control channel number */ + uint32 reserved32[1]; /* Reserved for expansion of BSS properties */ + uint8 flags; /* flags */ + uint8 reserved[3]; /* Reserved for expansion of BSS properties */ + uint8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */ + + uint16 ie_offset; /* offset at which IEs start, from beginning */ + uint32 ie_length; /* byte length of Information Elements */ + /* Add new fields here */ + /* variable length Information Elements */ } wl_bss_info_108_t; -#define WL_BSS_INFO_VERSION 109 - +#define WL_BSS_INFO_VERSION 109 /* current version of wl_bss_info struct */ +/* BSS info structure + * Applications MUST CHECK ie_offset field and length field to access IEs and + * next bss_info structure in a vector (in wl_scan_results_t) + */ typedef struct wl_bss_info { - uint32 version; - uint32 length; + uint32 version; /* version field */ + uint32 length; /* byte length of data in this record, + * starting at version and including IEs + */ struct ether_addr BSSID; - uint16 beacon_period; - uint16 capability; - uint8 SSID_len; - uint8 SSID[32]; + uint16 beacon_period; /* units are Kusec */ + uint16 capability; /* Capability information */ + uint8 SSID_len; + uint8 SSID[32]; struct { - uint count; - uint8 rates[16]; - } rateset; - chanspec_t chanspec; - uint16 atim_window; - uint8 dtim_period; - int16 RSSI; - int8 phy_noise; - - uint8 n_cap; - uint32 nbss_cap; - uint8 ctl_ch; - uint32 reserved32[1]; - uint8 flags; - uint8 reserved[3]; - uint8 basic_mcs[MCSSET_LEN]; - - uint16 ie_offset; - uint32 ie_length; - int16 SNR; - - + uint count; /* # rates in this set */ + uint8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */ + } rateset; /* supported rates */ + chanspec_t chanspec; /* chanspec for bss */ + uint16 atim_window; /* units are Kusec */ + uint8 dtim_period; /* DTIM period */ + int16 RSSI; /* receive signal strength (in dBm) */ + int8 phy_noise; /* noise (in dBm) */ + + uint8 n_cap; /* BSS is 802.11N Capable */ + uint32 nbss_cap; /* 802.11N BSS Capabilities (based on HT_CAP_*) */ + uint8 ctl_ch; /* 802.11N BSS control channel number */ + uint8 padding1[3]; /* explicit struct alignment padding */ + uint16 vht_rxmcsmap; /* VHT rx mcs map */ + uint16 vht_txmcsmap; /* VHT tx mcs map */ + uint8 flags; /* flags */ + uint8 vht_cap; /* BSS is vht capable */ + uint8 reserved[2]; /* Reserved for expansion of BSS properties */ + uint8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */ + + uint16 ie_offset; /* offset at which IEs start, from beginning */ + uint32 ie_length; /* byte length of Information Elements */ + int16 SNR; /* average SNR of during frame reception */ + /* Add new fields here */ + /* variable length Information Elements */ } wl_bss_info_t; typedef struct wl_bsscfg { - uint32 wsec; - uint32 WPA_auth; - uint32 wsec_index; - uint32 associated; - uint32 BSS; - uint32 phytest_on; - struct ether_addr prev_BSSID; - struct ether_addr BSSID; + uint32 wsec; + uint32 WPA_auth; + uint32 wsec_index; + uint32 associated; + uint32 BSS; + uint32 phytest_on; + struct ether_addr prev_BSSID; + struct ether_addr BSSID; + uint32 targetbss_wpa2_flags; + uint32 assoc_type; + uint32 assoc_state; } wl_bsscfg_t; typedef struct wl_bss_config { - uint32 atim_window; - uint32 beacon_period; - uint32 chanspec; + uint32 atim_window; + uint32 beacon_period; + uint32 chanspec; } wl_bss_config_t; +#define DLOAD_HANDLER_VER 1 /* Downloader version */ +#define DLOAD_FLAG_VER_MASK 0xf000 /* Downloader version mask */ +#define DLOAD_FLAG_VER_SHIFT 12 /* Downloader version shift */ + +#define DL_CRC_NOT_INUSE 0x0001 + +/* generic download types & flags */ +enum { + DL_TYPE_UCODE = 1, + DL_TYPE_CLM = 2 +}; + +/* ucode type values */ +enum { + UCODE_FW, + INIT_VALS, + BS_INIT_VALS +}; + +struct wl_dload_data { + uint16 flag; + uint16 dload_type; + uint32 len; + uint32 crc; + uint8 data[1]; +}; +typedef struct wl_dload_data wl_dload_data_t; + +struct wl_ucode_info { + uint32 ucode_type; + uint32 num_chunks; + uint32 chunk_len; + uint32 chunk_num; + uint8 data_chunk[1]; +}; +typedef struct wl_ucode_info wl_ucode_info_t; + +struct wl_clm_dload_info { + uint32 ds_id; + uint32 clm_total_len; + uint32 num_chunks; + uint32 chunk_len; + uint32 chunk_offset; + uint8 data_chunk[1]; +}; +typedef struct wl_clm_dload_info wl_clm_dload_info_t; typedef struct wlc_ssid { - uint32 SSID_len; - uchar SSID[32]; + uint32 SSID_len; + uchar SSID[32]; } wlc_ssid_t; +#define MAX_PREFERRED_AP_NUM 5 +typedef struct wlc_fastssidinfo { + uint32 SSID_channel[MAX_PREFERRED_AP_NUM]; + wlc_ssid_t SSID_info[MAX_PREFERRED_AP_NUM]; +} wlc_fastssidinfo_t; + +typedef BWL_PRE_PACKED_STRUCT struct wnm_url { + uint8 len; + uint8 data[1]; +} BWL_POST_PACKED_STRUCT wnm_url_t; + +#ifndef LINUX_POSTMOGRIFY_REMOVAL +typedef struct chan_scandata { + uint8 txpower; + uint8 pad; + chanspec_t channel; /* Channel num, bw, ctrl_sb and band */ + uint32 channel_mintime; + uint32 channel_maxtime; +} chan_scandata_t; + +typedef enum wl_scan_type { + EXTDSCAN_FOREGROUND_SCAN, + EXTDSCAN_BACKGROUND_SCAN, + EXTDSCAN_FORCEDBACKGROUND_SCAN +} wl_scan_type_t; + +#define WLC_EXTDSCAN_MAX_SSID 5 + +#define WL_BSS_FLAGS_FROM_BEACON 0x01 /* bss_info derived from beacon */ +#define WL_BSS_FLAGS_FROM_CACHE 0x02 /* bss_info collected from cache */ +#define WL_BSS_FLAGS_RSSI_ONCHANNEL 0x04 /* rssi info was received on channel (vs offchannel) */ + +typedef struct wl_extdscan_params { + int8 nprobes; /* 0, passive, otherwise active */ + int8 split_scan; /* split scan */ + int8 band; /* band */ + int8 pad; + wlc_ssid_t ssid[WLC_EXTDSCAN_MAX_SSID]; /* ssid list */ + uint32 tx_rate; /* in 500ksec units */ + wl_scan_type_t scan_type; /* enum */ + int32 channel_num; + chan_scandata_t channel_list[1]; /* list of chandata structs */ +} wl_extdscan_params_t; + +#define WL_EXTDSCAN_PARAMS_FIXED_SIZE (sizeof(wl_extdscan_params_t) - sizeof(chan_scandata_t)) +#endif /* LINUX_POSTMOGRIFY_REMOVAL */ #define WL_BSSTYPE_INFRA 1 #define WL_BSSTYPE_INDEP 0 #define WL_BSSTYPE_ANY 2 - -#define WL_SCANFLAGS_PASSIVE 0x01 -#define WL_SCANFLAGS_RESERVED 0x02 -#define WL_SCANFLAGS_PROHIBITED 0x04 +/* Bitmask for scan_type */ +#define WL_SCANFLAGS_PASSIVE 0x01 /* force passive scan */ +#define WL_SCANFLAGS_RESERVED 0x02 /* Reserved */ +#define WL_SCANFLAGS_PROHIBITED 0x04 /* allow scanning prohibited channels */ #define WL_SCAN_PARAMS_SSID_MAX 10 typedef struct wl_scan_params { - wlc_ssid_t ssid; - struct ether_addr bssid; - int8 bss_type; - uint8 scan_type; - int32 nprobes; - int32 active_time; - int32 passive_time; - int32 home_time; - int32 channel_num; - uint16 channel_list[1]; + wlc_ssid_t ssid; /* default: {0, ""} */ + struct ether_addr bssid; /* default: bcast */ + int8 bss_type; /* default: any, + * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT + */ + uint8 scan_type; /* flags, 0 use default */ + int32 nprobes; /* -1 use default, number of probes per channel */ + int32 active_time; /* -1 use default, dwell time per channel for + * active scanning + */ + int32 passive_time; /* -1 use default, dwell time per channel + * for passive scanning + */ + int32 home_time; /* -1 use default, dwell time for the home channel + * between channel scans + */ + int32 channel_num; /* count of channels and ssids that follow + * + * low half is count of channels in channel_list, 0 + * means default (use all available channels) + * + * high half is entries in wlc_ssid_t array that + * follows channel_list, aligned for int32 (4 bytes) + * meaning an odd channel count implies a 2-byte pad + * between end of channel_list and first ssid + * + * if ssid count is zero, single ssid in the fixed + * parameter portion is assumed, otherwise ssid in + * the fixed portion is ignored + */ + uint16 channel_list[1]; /* list of chanspecs */ } wl_scan_params_t; - +/* size of wl_scan_params not including variable length array */ #define WL_SCAN_PARAMS_FIXED_SIZE 64 - +/* masks for channel and ssid count */ #define WL_SCAN_PARAMS_COUNT_MASK 0x0000ffff #define WL_SCAN_PARAMS_NSSID_SHIFT 16 @@ -218,7 +387,7 @@ typedef struct wl_scan_params { #define ISCAN_REQ_VERSION 1 - +/* incremental scan struct */ typedef struct wl_iscan_params { uint32 version; uint16 action; @@ -226,7 +395,7 @@ typedef struct wl_iscan_params { wl_scan_params_t params; } wl_iscan_params_t; - +/* 3 fields + size of wl_scan_params, not including variable length array */ #define WL_ISCAN_PARAMS_FIXED_SIZE (OFFSETOF(wl_iscan_params_t, params) + sizeof(wlc_ssid_t)) typedef struct wl_scan_results { @@ -236,17 +405,17 @@ typedef struct wl_scan_results { wl_bss_info_t bss_info[1]; } wl_scan_results_t; - +/* size of wl_scan_results not including variable length array */ #define WL_SCAN_RESULTS_FIXED_SIZE (sizeof(wl_scan_results_t) - sizeof(wl_bss_info_t)) - -#define WL_SCAN_RESULTS_SUCCESS 0 -#define WL_SCAN_RESULTS_PARTIAL 1 -#define WL_SCAN_RESULTS_PENDING 2 -#define WL_SCAN_RESULTS_ABORTED 3 +/* wl_iscan_results status values */ +#define WL_SCAN_RESULTS_SUCCESS 0 +#define WL_SCAN_RESULTS_PARTIAL 1 +#define WL_SCAN_RESULTS_PENDING 2 +#define WL_SCAN_RESULTS_ABORTED 3 #define WL_SCAN_RESULTS_NO_MEM 4 - +/* Used in EXT_STA */ #define DNGL_RXCTXT_SIZE 45 #if defined(SIMPLE_ISCAN) @@ -255,13 +424,13 @@ typedef struct wl_scan_results { #define ISCAN_STATE_SCANING 1 #define ISCAN_STATE_PENDING 2 - +/* the buf lengh can be WLC_IOCTL_MAXLEN (8K) to reduce iteration */ #define WLC_IW_ISCAN_MAXLEN 2048 typedef struct iscan_buf { struct iscan_buf * next; char iscan_buf[WLC_IW_ISCAN_MAXLEN]; } iscan_buf_t; -#endif +#endif /* SIMPLE_ISCAN */ #define ESCAN_REQ_VERSION 1 @@ -284,13 +453,13 @@ typedef struct wl_escan_result { #define WL_ESCAN_RESULTS_FIXED_SIZE (sizeof(wl_escan_result_t) - sizeof(wl_bss_info_t)) - +/* incremental scan results struct */ typedef struct wl_iscan_results { uint32 status; wl_scan_results_t results; } wl_iscan_results_t; - +/* size of wl_iscan_results not including variable length array */ #define WL_ISCAN_RESULTS_FIXED_SIZE \ (WL_SCAN_RESULTS_FIXED_SIZE + OFFSETOF(wl_iscan_results_t, results)) @@ -300,156 +469,255 @@ typedef struct wl_probe_params { struct ether_addr mac; } wl_probe_params_t; -#define WL_NUMRATES 16 +#define WL_NUMRATES 16 /* max # of rates in a rateset */ typedef struct wl_rateset { - uint32 count; - uint8 rates[WL_NUMRATES]; + uint32 count; /* # rates in this set */ + uint8 rates[WL_NUMRATES]; /* rates in 500kbps units w/hi bit set if basic */ } wl_rateset_t; typedef struct wl_rateset_args { - uint32 count; - uint8 rates[WL_NUMRATES]; - uint8 mcs[MCSSET_LEN]; + uint32 count; /* # rates in this set */ + uint8 rates[WL_NUMRATES]; /* rates in 500kbps units w/hi bit set if basic */ + uint8 mcs[MCSSET_LEN]; /* supported mcs index bit map */ } wl_rateset_args_t; - +/* uint32 list */ typedef struct wl_uint32_list { - + /* in - # of elements, out - # of entries */ uint32 count; - + /* variable length uint32 list */ uint32 element[1]; } wl_uint32_list_t; - +/* used for association with a specific BSSID and chanspec list */ typedef struct wl_assoc_params { - struct ether_addr bssid; - uint16 bssid_cnt; - int32 chanspec_num; - chanspec_t chanspec_list[1]; + struct ether_addr bssid; /* 00:00:00:00:00:00: broadcast scan */ + int32 chanspec_num; /* 0: all available channels, + * otherwise count of chanspecs in chanspec_list + */ + chanspec_t chanspec_list[1]; /* list of chanspecs */ } wl_assoc_params_t; -#define WL_ASSOC_PARAMS_FIXED_SIZE (sizeof(wl_assoc_params_t) - sizeof(chanspec_t)) - +#define WL_ASSOC_PARAMS_FIXED_SIZE OFFSETOF(wl_assoc_params_t, chanspec_list) +/* used for reassociation/roam to a specific BSSID and channel */ typedef wl_assoc_params_t wl_reassoc_params_t; -#define WL_REASSOC_PARAMS_FIXED_SIZE WL_ASSOC_PARAMS_FIXED_SIZE - +#define WL_REASSOC_PARAMS_FIXED_SIZE WL_ASSOC_PARAMS_FIXED_SIZE +/* used for association to a specific BSSID and channel */ typedef wl_assoc_params_t wl_join_assoc_params_t; -#define WL_JOIN_ASSOC_PARAMS_FIXED_SIZE WL_ASSOC_PARAMS_FIXED_SIZE - +#define WL_JOIN_ASSOC_PARAMS_FIXED_SIZE WL_ASSOC_PARAMS_FIXED_SIZE +/* used for join with or without a specific bssid and channel list */ typedef struct wl_join_params { wlc_ssid_t ssid; - wl_assoc_params_t params; + wl_assoc_params_t params; /* optional field, but it must include the fixed portion + * of the wl_assoc_params_t struct when it does present. + */ } wl_join_params_t; -#define WL_JOIN_PARAMS_FIXED_SIZE (sizeof(wl_join_params_t) - sizeof(chanspec_t)) - - +#define WL_JOIN_PARAMS_FIXED_SIZE (OFFSETOF(wl_join_params_t, params) + \ + WL_ASSOC_PARAMS_FIXED_SIZE) +/* scan params for extended join */ typedef struct wl_join_scan_params { - uint8 scan_type; - int32 nprobes; - int32 active_time; - int32 passive_time; - int32 home_time; + uint8 scan_type; /* 0 use default, active or passive scan */ + int32 nprobes; /* -1 use default, number of probes per channel */ + int32 active_time; /* -1 use default, dwell time per channel for + * active scanning + */ + int32 passive_time; /* -1 use default, dwell time per channel + * for passive scanning + */ + int32 home_time; /* -1 use default, dwell time for the home channel + * between channel scans + */ } wl_join_scan_params_t; - +/* extended join params */ typedef struct wl_extjoin_params { - wlc_ssid_t ssid; + wlc_ssid_t ssid; /* {0, ""}: wildcard scan */ wl_join_scan_params_t scan; - wl_join_assoc_params_t assoc; + wl_join_assoc_params_t assoc; /* optional field, but it must include the fixed portion + * of the wl_join_assoc_params_t struct when it does + * present. + */ } wl_extjoin_params_t; -#define WL_EXTJOIN_PARAMS_FIXED_SIZE (sizeof(wl_extjoin_params_t) - sizeof(chanspec_t)) +#define WL_EXTJOIN_PARAMS_FIXED_SIZE (OFFSETOF(wl_extjoin_params_t, assoc) + \ + WL_JOIN_ASSOC_PARAMS_FIXED_SIZE) + +/* All builds use the new 11ac ratespec/chanspec */ +#undef D11AC_IOTYPES +#define D11AC_IOTYPES + +#ifndef D11AC_IOTYPES + +/* defines used by the nrate iovar */ +#define NRATE_MCS_INUSE 0x00000080 /* MSC in use,indicates b0-6 holds an mcs */ +#define NRATE_RATE_MASK 0x0000007f /* rate/mcs value */ +#define NRATE_STF_MASK 0x0000ff00 /* stf mode mask: siso, cdd, stbc, sdm */ +#define NRATE_STF_SHIFT 8 /* stf mode shift */ +#define NRATE_OVERRIDE 0x80000000 /* bit indicates override both rate & mode */ +#define NRATE_OVERRIDE_MCS_ONLY 0x40000000 /* bit indicate to override mcs only */ +#define NRATE_SGI_MASK 0x00800000 /* sgi mode */ +#define NRATE_SGI_SHIFT 23 /* sgi mode */ +#define NRATE_LDPC_CODING 0x00400000 /* bit indicates adv coding in use */ +#define NRATE_LDPC_SHIFT 22 /* ldpc shift */ + +#define NRATE_STF_SISO 0 /* stf mode SISO */ +#define NRATE_STF_CDD 1 /* stf mode CDD */ +#define NRATE_STF_STBC 2 /* stf mode STBC */ +#define NRATE_STF_SDM 3 /* stf mode SDM */ + +#else /* D11AC_IOTYPES */ + +/* WL_RSPEC defines for rate information */ +#define WL_RSPEC_RATE_MASK 0x000000FF /* rate or HT MCS value */ +#define WL_RSPEC_VHT_MCS_MASK 0x0000000F /* VHT MCS value */ +#define WL_RSPEC_VHT_NSS_MASK 0x000000F0 /* VHT Nss value */ +#define WL_RSPEC_VHT_NSS_SHIFT 4 /* VHT Nss value shift */ +#define WL_RSPEC_TXEXP_MASK 0x00000300 +#define WL_RSPEC_TXEXP_SHIFT 8 +#define WL_RSPEC_BW_MASK 0x00070000 /* bandwidth mask */ +#define WL_RSPEC_BW_SHIFT 16 /* bandwidth shift */ +#define WL_RSPEC_STBC 0x00100000 /* STBC encoding, Nsts = 2 x Nss */ +#define WL_RSPEC_LDPC 0x00400000 /* bit indicates adv coding in use */ +#define WL_RSPEC_SGI 0x00800000 /* Short GI mode */ +#define WL_RSPEC_ENCODING_MASK 0x03000000 /* Encoding of Rate/MCS field */ +#define WL_RSPEC_OVERRIDE_RATE 0x40000000 /* bit indicate to override mcs only */ +#define WL_RSPEC_OVERRIDE_MODE 0x80000000 /* bit indicates override both rate & mode */ + +/* WL_RSPEC_ENCODING field defs */ +#define WL_RSPEC_ENCODE_RATE 0x00000000 /* Legacy rate is stored in RSPEC_RATE_MASK */ +#define WL_RSPEC_ENCODE_HT 0x01000000 /* HT MCS is stored in RSPEC_RATE_MASK */ +#define WL_RSPEC_ENCODE_VHT 0x02000000 /* VHT MCS and Nss is stored in RSPEC_RATE_MASK */ + +/* WL_RSPEC_BW field defs */ +#define WL_RSPEC_BW_UNSPECIFIED 0 +#define WL_RSPEC_BW_20MHZ 0x00010000 +#define WL_RSPEC_BW_40MHZ 0x00020000 +#define WL_RSPEC_BW_80MHZ 0x00030000 +#define WL_RSPEC_BW_160MHZ 0x00040000 + +/* Legacy defines for the nrate iovar */ +#define OLD_NRATE_MCS_INUSE 0x00000080 /* MSC in use,indicates b0-6 holds an mcs */ +#define OLD_NRATE_RATE_MASK 0x0000007f /* rate/mcs value */ +#define OLD_NRATE_STF_MASK 0x0000ff00 /* stf mode mask: siso, cdd, stbc, sdm */ +#define OLD_NRATE_STF_SHIFT 8 /* stf mode shift */ +#define OLD_NRATE_OVERRIDE 0x80000000 /* bit indicates override both rate & mode */ +#define OLD_NRATE_OVERRIDE_MCS_ONLY 0x40000000 /* bit indicate to override mcs only */ +#define OLD_NRATE_SGI 0x00800000 /* sgi mode */ +#define OLD_NRATE_LDPC_CODING 0x00400000 /* bit indicates adv coding in use */ + +#define OLD_NRATE_STF_SISO 0 /* stf mode SISO */ +#define OLD_NRATE_STF_CDD 1 /* stf mode CDD */ +#define OLD_NRATE_STF_STBC 2 /* stf mode STBC */ +#define OLD_NRATE_STF_SDM 3 /* stf mode SDM */ + +#endif /* D11AC_IOTYPES */ + +#define ANTENNA_NUM_1 1 /* total number of antennas to be used */ +#define ANTENNA_NUM_2 2 +#define ANTENNA_NUM_3 3 +#define ANTENNA_NUM_4 4 + +#define ANT_SELCFG_AUTO 0x80 /* bit indicates antenna sel AUTO */ +#define ANT_SELCFG_MASK 0x33 /* antenna configuration mask */ +#define ANT_SELCFG_MAX 4 /* max number of antenna configurations */ +#define ANT_SELCFG_TX_UNICAST 0 /* unicast tx antenna configuration */ +#define ANT_SELCFG_RX_UNICAST 1 /* unicast rx antenna configuration */ +#define ANT_SELCFG_TX_DEF 2 /* default tx antenna configuration */ +#define ANT_SELCFG_RX_DEF 3 /* default rx antenna configuration */ + +#define MAX_STREAMS_SUPPORTED 4 /* max number of streams supported */ typedef struct { - uint32 num; - chanspec_t list[1]; -} chanspec_list_t; - - -#define NRATE_MCS_INUSE 0x00000080 -#define NRATE_RATE_MASK 0x0000007f -#define NRATE_STF_MASK 0x0000ff00 -#define NRATE_STF_SHIFT 8 -#define NRATE_OVERRIDE 0x80000000 -#define NRATE_OVERRIDE_MCS_ONLY 0x40000000 -#define NRATE_SGI_MASK 0x00800000 -#define NRATE_SGI_SHIFT 23 -#define NRATE_LDPC_CODING 0x00400000 -#define NRATE_LDPC_SHIFT 22 -#define NRATE_BCMC_OVERRIDE 0x00200000 -#define NRATE_BCMC_SHIFT 21 - -#define NRATE_STF_SISO 0 -#define NRATE_STF_CDD 1 -#define NRATE_STF_STBC 2 -#define NRATE_STF_SDM 3 - -#define ANTENNA_NUM_1 1 -#define ANTENNA_NUM_2 2 -#define ANTENNA_NUM_3 3 -#define ANTENNA_NUM_4 4 - -#define ANT_SELCFG_AUTO 0x80 -#define ANT_SELCFG_MASK 0x33 -#define ANT_SELCFG_MAX 4 -#define ANT_SELCFG_TX_UNICAST 0 -#define ANT_SELCFG_RX_UNICAST 1 -#define ANT_SELCFG_TX_DEF 2 -#define ANT_SELCFG_RX_DEF 3 - -#define MAX_STREAMS_SUPPORTED 4 - -typedef struct { - uint8 ant_config[ANT_SELCFG_MAX]; - uint8 num_antcfg; + uint8 ant_config[ANT_SELCFG_MAX]; /* antenna configuration */ + uint8 num_antcfg; /* number of available antenna configurations */ } wlc_antselcfg_t; -#define HIGHEST_SINGLE_STREAM_MCS 7 +#define HIGHEST_SINGLE_STREAM_MCS 7 /* MCS values greater than this enable multiple streams */ -#define MAX_CCA_CHANNELS 38 -#define MAX_CCA_SECS 60 +#define MAX_CCA_CHANNELS 38 /* Max number of 20 Mhz wide channels */ +#define MAX_CCA_SECS 60 /* CCA keeps this many seconds history */ -#define IBSS_MED 15 -#define IBSS_HI 25 +#define IBSS_MED 15 /* Mediom in-bss congestion percentage */ +#define IBSS_HI 25 /* Hi in-bss congestion percentage */ #define OBSS_MED 12 #define OBSS_HI 25 #define INTERFER_MED 5 #define INTERFER_HI 10 -#define CCA_FLAG_2G_ONLY 0x01 -#define CCA_FLAG_5G_ONLY 0x02 -#define CCA_FLAG_IGNORE_DURATION 0x04 -#define CCA_FLAGS_PREFER_1_6_11 0x10 -#define CCA_FLAG_IGNORE_INTERFER 0x20 +#define CCA_FLAG_2G_ONLY 0x01 /* Return a channel from 2.4 Ghz band */ +#define CCA_FLAG_5G_ONLY 0x02 /* Return a channel from 2.4 Ghz band */ +#define CCA_FLAG_IGNORE_DURATION 0x04 /* Ignore dwell time for each channel */ +#define CCA_FLAGS_PREFER_1_6_11 0x10 +#define CCA_FLAG_IGNORE_INTERFER 0x20 /* do not exlude channel based on interfer level */ -#define CCA_ERRNO_BAND 1 -#define CCA_ERRNO_DURATION 2 -#define CCA_ERRNO_PREF_CHAN 3 -#define CCA_ERRNO_INTERFER 4 -#define CCA_ERRNO_TOO_FEW 5 +#define CCA_ERRNO_BAND 1 /* After filtering for band pref, no choices left */ +#define CCA_ERRNO_DURATION 2 /* After filtering for duration, no choices left */ +#define CCA_ERRNO_PREF_CHAN 3 /* After filtering for chan pref, no choices left */ +#define CCA_ERRNO_INTERFER 4 /* After filtering for interference, no choices left */ +#define CCA_ERRNO_TOO_FEW 5 /* Only 1 channel was input */ typedef struct { - uint32 duration; - uint32 congest_ibss; - - uint32 congest_obss; - uint32 interference; - uint32 timestamp; + uint32 duration; /* millisecs spent sampling this channel */ + uint32 congest_ibss; /* millisecs in our bss (presumably this traffic will */ + /* move if cur bss moves channels) */ + uint32 congest_obss; /* traffic not in our bss */ + uint32 interference; /* millisecs detecting a non 802.11 interferer. */ + uint32 timestamp; /* second timestamp */ } cca_congest_t; typedef struct { - chanspec_t chanspec; - uint8 num_secs; - cca_congest_t secs[1]; + chanspec_t chanspec; /* Which channel? */ + uint8 num_secs; /* How many secs worth of data */ + cca_congest_t secs[1]; /* Data */ } cca_congest_channel_req_t; -#define WLC_CNTRY_BUF_SZ 4 +/* interference source detection and identification mode */ +#define ITFR_MODE_DISABLE 0 /* disable feature */ +#define ITFR_MODE_MANUAL_ENABLE 1 /* enable manual detection */ +#define ITFR_MODE_AUTO_ENABLE 2 /* enable auto detection */ + +/* interference sources */ +enum interference_source { + ITFR_NONE = 0, /* interference */ + ITFR_PHONE, /* wireless phone */ + ITFR_VIDEO_CAMERA, /* wireless video camera */ + ITFR_MICROWAVE_OVEN, /* microwave oven */ + ITFR_BABY_MONITOR, /* wireless baby monitor */ + ITFR_BLUETOOTH, /* bluetooth */ + ITFR_VIDEO_CAMERA_OR_BABY_MONITOR, /* wireless camera or baby monitor */ + ITFR_BLUETOOTH_OR_BABY_MONITOR, /* bluetooth or baby monitor */ + ITFR_VIDEO_CAMERA_OR_PHONE, /* video camera or phone */ + ITFR_UNIDENTIFIED /* interference from unidentified source */ +}; + +/* structure for interference source report */ +typedef struct { + uint32 flags; /* flags. bit definitions below */ + uint32 source; /* last detected interference source */ + uint32 timestamp; /* second timestamp on interferenced flag change */ +} interference_source_rep_t; + +/* bit definitions for flags in interference source report */ +#define ITFR_INTERFERENCED 1 /* interference detected */ +#define ITFR_HOME_CHANNEL 2 /* home channel has interference */ +#define ITFR_NOISY_ENVIRONMENT 4 /* noisy environemnt so feature stopped */ + +#define WLC_CNTRY_BUF_SZ 4 /* Country string is 3 bytes + NUL */ typedef struct wl_country { - char country_abbrev[WLC_CNTRY_BUF_SZ]; - int32 rev; - char ccode[WLC_CNTRY_BUF_SZ]; + char country_abbrev[WLC_CNTRY_BUF_SZ]; /* nul-terminated country code used in + * the Country IE + */ + int32 rev; /* revision specifier for ccode + * on set, -1 indicates unspecified. + * on get, rev >= 0 + */ + char ccode[WLC_CNTRY_BUF_SZ]; /* nul-terminated built-in country code. + * variable length, but fixed size in + * struct allows simple allocation for + * expected country strings <= 3 chars. + */ } wl_country_t; typedef struct wl_channels_in_country { @@ -468,65 +736,65 @@ typedef struct wl_country_list { char country_abbrev[1]; } wl_country_list_t; -#define WL_NUM_RPI_BINS 8 -#define WL_RM_TYPE_BASIC 1 -#define WL_RM_TYPE_CCA 2 -#define WL_RM_TYPE_RPI 3 +#define WL_NUM_RPI_BINS 8 +#define WL_RM_TYPE_BASIC 1 +#define WL_RM_TYPE_CCA 2 +#define WL_RM_TYPE_RPI 3 -#define WL_RM_FLAG_PARALLEL (1<<0) +#define WL_RM_FLAG_PARALLEL (1<<0) -#define WL_RM_FLAG_LATE (1<<1) -#define WL_RM_FLAG_INCAPABLE (1<<2) -#define WL_RM_FLAG_REFUSED (1<<3) +#define WL_RM_FLAG_LATE (1<<1) +#define WL_RM_FLAG_INCAPABLE (1<<2) +#define WL_RM_FLAG_REFUSED (1<<3) typedef struct wl_rm_req_elt { - int8 type; - int8 flags; - chanspec_t chanspec; - uint32 token; - uint32 tsf_h; - uint32 tsf_l; - uint32 dur; + int8 type; + int8 flags; + chanspec_t chanspec; + uint32 token; /* token for this measurement */ + uint32 tsf_h; /* TSF high 32-bits of Measurement start time */ + uint32 tsf_l; /* TSF low 32-bits */ + uint32 dur; /* TUs */ } wl_rm_req_elt_t; typedef struct wl_rm_req { - uint32 token; - uint32 count; - void *cb; - void *cb_arg; - wl_rm_req_elt_t req[1]; + uint32 token; /* overall measurement set token */ + uint32 count; /* number of measurement requests */ + void *cb; /* completion callback function: may be NULL */ + void *cb_arg; /* arg to completion callback function */ + wl_rm_req_elt_t req[1]; /* variable length block of requests */ } wl_rm_req_t; -#define WL_RM_REQ_FIXED_LEN OFFSETOF(wl_rm_req_t, req) +#define WL_RM_REQ_FIXED_LEN OFFSETOF(wl_rm_req_t, req) typedef struct wl_rm_rep_elt { - int8 type; - int8 flags; - chanspec_t chanspec; - uint32 token; - uint32 tsf_h; - uint32 tsf_l; - uint32 dur; - uint32 len; - uint8 data[1]; + int8 type; + int8 flags; + chanspec_t chanspec; + uint32 token; /* token for this measurement */ + uint32 tsf_h; /* TSF high 32-bits of Measurement start time */ + uint32 tsf_l; /* TSF low 32-bits */ + uint32 dur; /* TUs */ + uint32 len; /* byte length of data block */ + uint8 data[1]; /* variable length data block */ } wl_rm_rep_elt_t; -#define WL_RM_REP_ELT_FIXED_LEN 24 +#define WL_RM_REP_ELT_FIXED_LEN 24 /* length excluding data block */ #define WL_RPI_REP_BIN_NUM 8 typedef struct wl_rm_rpi_rep { - uint8 rpi[WL_RPI_REP_BIN_NUM]; - int8 rpi_max[WL_RPI_REP_BIN_NUM]; + uint8 rpi[WL_RPI_REP_BIN_NUM]; + int8 rpi_max[WL_RPI_REP_BIN_NUM]; } wl_rm_rpi_rep_t; typedef struct wl_rm_rep { - uint32 token; - uint32 len; - wl_rm_rep_elt_t rep[1]; + uint32 token; /* overall measurement set token */ + uint32 len; /* length of measurement report block */ + wl_rm_rep_elt_t rep[1]; /* variable length block of reports */ } wl_rm_rep_t; -#define WL_RM_REP_FIXED_LEN 8 +#define WL_RM_REP_FIXED_LEN 8 typedef enum sup_auth_status { - + /* Basic supplicant authentication states */ WLC_SUP_DISCONNECTED = 0, WLC_SUP_CONNECTING, WLC_SUP_IDREQUIRED, @@ -537,210 +805,383 @@ typedef enum sup_auth_status { WLC_SUP_TIMEOUT, WLC_SUP_LAST_BASIC_STATE, - - + /* Extended supplicant authentication states */ + /* Waiting to receive handshake msg M1 */ WLC_SUP_KEYXCHANGE_WAIT_M1 = WLC_SUP_AUTHENTICATED, - + /* Preparing to send handshake msg M2 */ WLC_SUP_KEYXCHANGE_PREP_M2 = WLC_SUP_KEYXCHANGE, - + /* Waiting to receive handshake msg M3 */ WLC_SUP_KEYXCHANGE_WAIT_M3 = WLC_SUP_LAST_BASIC_STATE, - WLC_SUP_KEYXCHANGE_PREP_M4, - WLC_SUP_KEYXCHANGE_WAIT_G1, - WLC_SUP_KEYXCHANGE_PREP_G2 + WLC_SUP_KEYXCHANGE_PREP_M4, /* Preparing to send handshake msg M4 */ + WLC_SUP_KEYXCHANGE_WAIT_G1, /* Waiting to receive handshake msg G1 */ + WLC_SUP_KEYXCHANGE_PREP_G2 /* Preparing to send handshake msg G2 */ } sup_auth_status_t; - -#define CRYPTO_ALGO_OFF 0 -#define CRYPTO_ALGO_WEP1 1 -#define CRYPTO_ALGO_TKIP 2 -#define CRYPTO_ALGO_WEP128 3 -#define CRYPTO_ALGO_AES_CCM 4 -#define CRYPTO_ALGO_AES_OCB_MSDU 5 -#define CRYPTO_ALGO_AES_OCB_MPDU 6 -#define CRYPTO_ALGO_NALG 7 -#define CRYPTO_ALGO_PMK 12 - -#define WSEC_GEN_MIC_ERROR 0x0001 -#define WSEC_GEN_REPLAY 0x0002 -#define WSEC_GEN_ICV_ERROR 0x0004 - -#define WL_SOFT_KEY (1 << 0) -#define WL_PRIMARY_KEY (1 << 1) -#define WL_KF_RES_4 (1 << 4) -#define WL_KF_RES_5 (1 << 5) -#define WL_IBSS_PEER_GROUP_KEY (1 << 6) +/* Enumerate crypto algorithms */ +#define CRYPTO_ALGO_OFF 0 +#define CRYPTO_ALGO_WEP1 1 +#define CRYPTO_ALGO_TKIP 2 +#define CRYPTO_ALGO_WEP128 3 +#define CRYPTO_ALGO_AES_CCM 4 +#define CRYPTO_ALGO_AES_OCB_MSDU 5 +#define CRYPTO_ALGO_AES_OCB_MPDU 6 +#define CRYPTO_ALGO_NALG 7 +#ifdef BCMWAPI_WPI +#define CRYPTO_ALGO_SMS4 11 +#endif /* BCMWAPI_WPI */ +#define CRYPTO_ALGO_PMK 12 /* for 802.1x supp to set PMK before 4-way */ + +#define WSEC_GEN_MIC_ERROR 0x0001 +#define WSEC_GEN_REPLAY 0x0002 +#define WSEC_GEN_ICV_ERROR 0x0004 +#define WSEC_GEN_MFP_ACT_ERROR 0x0008 +#define WSEC_GEN_MFP_DISASSOC_ERROR 0x0010 +#define WSEC_GEN_MFP_DEAUTH_ERROR 0x0020 + +#define WL_SOFT_KEY (1 << 0) /* Indicates this key is using soft encrypt */ +#define WL_PRIMARY_KEY (1 << 1) /* Indicates this key is the primary (ie tx) key */ +#define WL_KF_RES_4 (1 << 4) /* Reserved for backward compat */ +#define WL_KF_RES_5 (1 << 5) /* Reserved for backward compat */ +#define WL_IBSS_PEER_GROUP_KEY (1 << 6) /* Indicates a group key for a IBSS PEER */ typedef struct wl_wsec_key { - uint32 index; - uint32 len; - uint8 data[DOT11_MAX_KEY_SIZE]; - uint32 pad_1[18]; - uint32 algo; - uint32 flags; - uint32 pad_2[2]; - int pad_3; - int iv_initialized; - int pad_4; - + uint32 index; /* key index */ + uint32 len; /* key length */ + uint8 data[DOT11_MAX_KEY_SIZE]; /* key data */ + uint32 pad_1[18]; + uint32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ + uint32 flags; /* misc flags */ + uint32 pad_2[2]; + int pad_3; + int iv_initialized; /* has IV been initialized already? */ + int pad_4; + /* Rx IV */ struct { - uint32 hi; - uint16 lo; + uint32 hi; /* upper 32 bits of IV */ + uint16 lo; /* lower 16 bits of IV */ } rxiv; - uint32 pad_5[2]; - struct ether_addr ea; + uint32 pad_5[2]; + struct ether_addr ea; /* per station */ } wl_wsec_key_t; -#define WSEC_MIN_PSK_LEN 8 -#define WSEC_MAX_PSK_LEN 64 - - -#define WSEC_PASSPHRASE (1<<0) +#define WSEC_MIN_PSK_LEN 8 +#define WSEC_MAX_PSK_LEN 64 +/* Flag for key material needing passhash'ing */ +#define WSEC_PASSPHRASE (1<<0) +/* receptacle for WLC_SET_WSEC_PMK parameter */ typedef struct { - ushort key_len; - ushort flags; - uint8 key[WSEC_MAX_PSK_LEN]; + ushort key_len; /* octets in key material */ + ushort flags; /* key handling qualification */ + uint8 key[WSEC_MAX_PSK_LEN]; /* PMK material */ } wsec_pmk_t; - -#define WEP_ENABLED 0x0001 -#define TKIP_ENABLED 0x0002 -#define AES_ENABLED 0x0004 -#define WSEC_SWFLAG 0x0008 -#define SES_OW_ENABLED 0x0040 - - -#define WPA_AUTH_DISABLED 0x0000 -#define WPA_AUTH_NONE 0x0001 -#define WPA_AUTH_UNSPECIFIED 0x0002 -#define WPA_AUTH_PSK 0x0004 - -#define WPA2_AUTH_UNSPECIFIED 0x0040 -#define WPA2_AUTH_PSK 0x0080 -#define BRCM_AUTH_PSK 0x0100 -#define BRCM_AUTH_DPT 0x0200 -#define WPA2_AUTH_MFP 0x1000 -#define WPA2_AUTH_TPK 0x2000 -#define WPA2_AUTH_FT 0x4000 - - -#define MAXPMKID 16 +/* wireless security bitvec */ +#define WEP_ENABLED 0x0001 +#define TKIP_ENABLED 0x0002 +#define AES_ENABLED 0x0004 +#define WSEC_SWFLAG 0x0008 +#define SES_OW_ENABLED 0x0040 /* to go into transition mode without setting wep */ +#ifdef BCMWAPI_WPI +#define SMS4_ENABLED 0x0100 +#endif /* BCMWAPI_WPI */ + +/* wsec macros for operating on the above definitions */ +#define WSEC_WEP_ENABLED(wsec) ((wsec) & WEP_ENABLED) +#define WSEC_TKIP_ENABLED(wsec) ((wsec) & TKIP_ENABLED) +#define WSEC_AES_ENABLED(wsec) ((wsec) & AES_ENABLED) + +#ifdef BCMWAPI_WPI +#define WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED | SMS4_ENABLED)) +#else /* BCMWAPI_WPI */ +#define WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED)) +#endif /* BCMWAPI_WPI */ +#define WSEC_SES_OW_ENABLED(wsec) ((wsec) & SES_OW_ENABLED) +#ifdef BCMWAPI_WAI +#define WSEC_SMS4_ENABLED(wsec) ((wsec) & SMS4_ENABLED) +#endif /* BCMWAPI_WAI */ + +#ifdef MFP +#define MFP_CAPABLE 0x0200 +#define MFP_REQUIRED 0x0400 +#define MFP_SHA256 0x0800 /* a special configuration for STA for WIFI test tool */ +#endif /* MFP */ + +/* WPA authentication mode bitvec */ +#define WPA_AUTH_DISABLED 0x0000 /* Legacy (i.e., non-WPA) */ +#define WPA_AUTH_NONE 0x0001 /* none (IBSS) */ +#define WPA_AUTH_UNSPECIFIED 0x0002 /* over 802.1x */ +#define WPA_AUTH_PSK 0x0004 /* Pre-shared key */ +/* #define WPA_AUTH_8021X 0x0020 */ /* 802.1x, reserved */ +#define WPA2_AUTH_UNSPECIFIED 0x0040 /* over 802.1x */ +#define WPA2_AUTH_PSK 0x0080 /* Pre-shared key */ +#define BRCM_AUTH_PSK 0x0100 /* BRCM specific PSK */ +#define BRCM_AUTH_DPT 0x0200 /* DPT PSK without group keys */ +#if defined(BCMWAPI_WAI) || defined(BCMWAPI_WPI) +#define WPA_AUTH_WAPI 0x0400 +#define WAPI_AUTH_NONE WPA_AUTH_NONE /* none (IBSS) */ +#define WAPI_AUTH_UNSPECIFIED 0x0400 /* over AS */ +#define WAPI_AUTH_PSK 0x0800 /* Pre-shared key */ +#endif /* BCMWAPI_WAI || BCMWAPI_WPI */ +#define WPA2_AUTH_MFP 0x1000 /* MFP (11w) in contrast to CCX */ +#define WPA2_AUTH_TPK 0x2000 /* TDLS Peer Key */ +#define WPA2_AUTH_FT 0x4000 /* Fast Transition. */ +#define WPA_AUTH_PFN_ANY 0xffffffff /* for PFN, match only ssid */ + +/* pmkid */ +#define MAXPMKID 16 typedef struct _pmkid { - struct ether_addr BSSID; - uint8 PMKID[WPA2_PMKID_LEN]; + struct ether_addr BSSID; + uint8 PMKID[WPA2_PMKID_LEN]; } pmkid_t; typedef struct _pmkid_list { - uint32 npmkid; - pmkid_t pmkid[1]; + uint32 npmkid; + pmkid_t pmkid[1]; } pmkid_list_t; typedef struct _pmkid_cand { - struct ether_addr BSSID; - uint8 preauth; + struct ether_addr BSSID; + uint8 preauth; } pmkid_cand_t; typedef struct _pmkid_cand_list { - uint32 npmkid_cand; - pmkid_cand_t pmkid_cand[1]; + uint32 npmkid_cand; + pmkid_cand_t pmkid_cand[1]; } pmkid_cand_list_t; typedef struct wl_assoc_info { - uint32 req_len; - uint32 resp_len; - uint32 flags; + uint32 req_len; + uint32 resp_len; + uint32 flags; struct dot11_assoc_req req; - struct ether_addr reassoc_bssid; + struct ether_addr reassoc_bssid; /* used in reassoc's */ struct dot11_assoc_resp resp; } wl_assoc_info_t; +/* flags */ +#define WLC_ASSOC_REQ_IS_REASSOC 0x01 /* assoc req was actually a reassoc */ -#define WLC_ASSOC_REQ_IS_REASSOC 0x01 +#ifndef LINUX_POSTMOGRIFY_REMOVAL +typedef struct wl_led_info { + uint32 index; /* led index */ + uint32 behavior; + uint8 activehi; +} wl_led_info_t; +/* srom read/write struct passed through ioctl */ typedef struct { - uint16 ver; - uint16 len; - uint16 cap; - uint32 flags; - uint32 idle; - struct ether_addr ea; - wl_rateset_t rateset; - uint32 in; - uint32 listen_interval_inms; - uint32 tx_pkts; - uint32 tx_failures; - uint32 rx_ucast_pkts; - uint32 rx_mcast_pkts; - uint32 tx_rate; - uint32 rx_rate; - uint32 rx_decrypt_succeeds; - uint32 rx_decrypt_failures; -} sta_info_t; + uint byteoff; /* byte offset */ + uint nbytes; /* number of bytes */ + uint16 buf[1]; +} srom_rw_t; + +/* similar cis (srom or otp) struct [iovar: may not be aligned] */ +typedef struct { + uint32 source; /* cis source */ + uint32 byteoff; /* byte offset */ + uint32 nbytes; /* number of bytes */ + /* data follows here */ +} cis_rw_t; -#define WL_OLD_STAINFO_SIZE OFFSETOF(sta_info_t, tx_pkts) +#define WLC_CIS_DEFAULT 0 /* built-in default */ +#define WLC_CIS_SROM 1 /* source is sprom */ +#define WLC_CIS_OTP 2 /* source is otp */ -#define WL_STA_VER 3 +/* R_REG and W_REG struct passed through ioctl */ +typedef struct { + uint32 byteoff; /* byte offset of the field in d11regs_t */ + uint32 val; /* read/write value of the field */ + uint32 size; /* sizeof the field */ + uint band; /* band (optional) */ +} rw_reg_t; + +/* Structure used by GET/SET_ATTEN ioctls - it controls power in b/g-band */ +/* PCL - Power Control Loop */ +/* current gain setting is replaced by user input */ +#define WL_ATTEN_APP_INPUT_PCL_OFF 0 /* turn off PCL, apply supplied input */ +#define WL_ATTEN_PCL_ON 1 /* turn on PCL */ +/* current gain setting is maintained */ +#define WL_ATTEN_PCL_OFF 2 /* turn off PCL. */ +typedef struct { + uint16 auto_ctrl; /* WL_ATTEN_XX */ + uint16 bb; /* Baseband attenuation */ + uint16 radio; /* Radio attenuation */ + uint16 txctl1; /* Radio TX_CTL1 value */ +} atten_t; + +/* Per-AC retry parameters */ +struct wme_tx_params_s { + uint8 short_retry; + uint8 short_fallback; + uint8 long_retry; + uint8 long_fallback; + uint16 max_rate; /* In units of 512 Kbps */ +}; -#define WL_STA_BRCM 0x1 -#define WL_STA_WME 0x2 -#define WL_STA_ABCAP 0x4 -#define WL_STA_AUTHE 0x8 -#define WL_STA_ASSOC 0x10 -#define WL_STA_AUTHO 0x20 -#define WL_STA_WDS 0x40 -#define WL_STA_WDS_LINKUP 0x80 -#define WL_STA_PS 0x100 -#define WL_STA_APSD_BE 0x200 -#define WL_STA_APSD_BK 0x400 -#define WL_STA_APSD_VI 0x800 -#define WL_STA_APSD_VO 0x1000 -#define WL_STA_N_CAP 0x2000 -#define WL_STA_SCBSTATS 0x4000 +typedef struct wme_tx_params_s wme_tx_params_t; + +#define WL_WME_TX_PARAMS_IO_BYTES (sizeof(wme_tx_params_t) * AC_COUNT) + +/* defines used by poweridx iovar - it controls power in a-band */ +/* current gain setting is maintained */ +#define WL_PWRIDX_PCL_OFF -2 /* turn off PCL. */ +#define WL_PWRIDX_PCL_ON -1 /* turn on PCL */ +#define WL_PWRIDX_LOWER_LIMIT -2 /* lower limit */ +#define WL_PWRIDX_UPPER_LIMIT 63 /* upper limit */ +/* value >= 0 causes + * - input to be set to that value + * - PCL to be off + */ + +/* Used to get specific link/ac parameters */ +typedef struct { + int ac; + uint8 val; + struct ether_addr ea; +} link_val_t; -#define WL_WDS_LINKUP WL_STA_WDS_LINKUP +#define BCM_MAC_STATUS_INDICATION (0x40010200L) +#endif /* LINUX_POSTMOGRIFY_REMOVAL */ +typedef struct { + uint16 ver; /* version of this struct */ + uint16 len; /* length in bytes of this structure */ + uint16 cap; /* sta's advertised capabilities */ + uint32 flags; /* flags defined below */ + uint32 idle; /* time since data pkt rx'd from sta */ + struct ether_addr ea; /* Station address */ + wl_rateset_t rateset; /* rateset in use */ + uint32 in; /* seconds elapsed since associated */ + uint32 listen_interval_inms; /* Min Listen interval in ms for this STA */ + uint32 tx_pkts; /* # of packets transmitted */ + uint32 tx_failures; /* # of packets failed */ + uint32 rx_ucast_pkts; /* # of unicast packets received */ + uint32 rx_mcast_pkts; /* # of multicast packets received */ + uint32 tx_rate; /* Rate of last successful tx frame */ + uint32 rx_rate; /* Rate of last successful rx frame */ + uint32 rx_decrypt_succeeds; /* # of packet decrypted successfully */ + uint32 rx_decrypt_failures; /* # of packet decrypted unsuccessfully */ +} sta_info_t; +#define WL_OLD_STAINFO_SIZE OFFSETOF(sta_info_t, tx_pkts) + +#define WL_STA_VER 3 + +/* Flags for sta_info_t indicating properties of STA */ +#define WL_STA_BRCM 0x1 /* Running a Broadcom driver */ +#define WL_STA_WME 0x2 /* WMM association */ +#define WL_STA_UNUSED 0x4 +#define WL_STA_AUTHE 0x8 /* Authenticated */ +#define WL_STA_ASSOC 0x10 /* Associated */ +#define WL_STA_AUTHO 0x20 /* Authorized */ +#define WL_STA_WDS 0x40 /* Wireless Distribution System */ +#define WL_STA_WDS_LINKUP 0x80 /* WDS traffic/probes flowing properly */ +#define WL_STA_PS 0x100 /* STA is in power save mode from AP's viewpoint */ +#define WL_STA_APSD_BE 0x200 /* APSD delv/trigger for AC_BE is default enabled */ +#define WL_STA_APSD_BK 0x400 /* APSD delv/trigger for AC_BK is default enabled */ +#define WL_STA_APSD_VI 0x800 /* APSD delv/trigger for AC_VI is default enabled */ +#define WL_STA_APSD_VO 0x1000 /* APSD delv/trigger for AC_VO is default enabled */ +#define WL_STA_N_CAP 0x2000 /* STA 802.11n capable */ +#define WL_STA_SCBSTATS 0x4000 /* Per STA debug stats */ + +#define WL_WDS_LINKUP WL_STA_WDS_LINKUP /* deprecated */ + +/* Values for TX Filter override mode */ #define WLC_TXFILTER_OVERRIDE_DISABLED 0 #define WLC_TXFILTER_OVERRIDE_ENABLED 1 - +/* Used to get specific STA parameters */ typedef struct { - uint32 val; + uint32 val; struct ether_addr ea; } scb_val_t; - +/* Used by iovar versions of some ioctls, i.e. WLC_SCB_AUTHORIZE et al */ typedef struct { uint32 code; scb_val_t ioctl_args; } authops_t; - +/* channel encoding */ typedef struct channel_info { int hw_channel; int target_channel; int scan_channel; } channel_info_t; - +/* For ioctls that take a list of MAC addresses */ struct maclist { - uint count; - struct ether_addr ea[1]; + uint count; /* number of MAC addresses */ + struct ether_addr ea[1]; /* variable length array of MAC addresses */ }; - +/* get pkt count struct passed through ioctl */ typedef struct get_pktcnt { uint rx_good_pkt; uint rx_bad_pkt; uint tx_good_pkt; uint tx_bad_pkt; - uint rx_ocast_good_pkt; + uint rx_ocast_good_pkt; /* unicast packets destined for others */ } get_pktcnt_t; +/* NINTENDO2 */ +#define LQ_IDX_MIN 0 +#define LQ_IDX_MAX 1 +#define LQ_IDX_AVG 2 +#define LQ_IDX_SUM 2 +#define LQ_IDX_LAST 3 +#define LQ_STOP_MONITOR 0 +#define LQ_START_MONITOR 1 + +/* Get averages RSSI, Rx PHY rate and SNR values */ +typedef struct { + int rssi[LQ_IDX_LAST]; /* Array to keep min, max, avg rssi */ + int snr[LQ_IDX_LAST]; /* Array to keep min, max, avg snr */ + int isvalid; /* Flag indicating whether above data is valid */ +} wl_lq_t; /* Link Quality */ + +/* NINTENDO2 */ +#define MCS_INDEX_SIZE 33 + +typedef enum wl_wakeup_reason_type { + LCD_ON = 1, + LCD_OFF, + DRC1_WAKE, + DRC2_WAKE, + REASON_LAST +} wl_wr_type_t; + +typedef struct { +/* Unique filter id */ + uint32 id; + +/* stores the reason for the last wake up */ + uint8 reason; +} wl_wr_t; + +/* Get MAC specific rate histogram command */ +typedef struct { + struct ether_addr ea; /* MAC Address */ + uint8 ac_cat; /* Access Category */ + uint8 num_pkts; /* Number of packet entries to be averaged */ +} wl_mac_ratehisto_cmd_t; /* MAC Specific Rate Histogram command */ + +/* Get MAC rate histogram response */ +typedef struct { + uint32 rate[WLC_MAXRATE + 1]; /* Rates */ + uint32 mcs_index[MCS_INDEX_SIZE]; /* MCS index */ + uint32 tsf_timer[2][2]; /* Start and End time for 8bytes value */ +} wl_mac_ratehisto_res_t; /* MAC Specific Rate Histogram Response */ + +/* Values for TX Filter override mode */ +#define WLC_TXFILTER_OVERRIDE_DISABLED 0 +#define WLC_TXFILTER_OVERRIDE_ENABLED 1 + #define WL_IOCTL_ACTION_GET 0x0 #define WL_IOCTL_ACTION_SET 0x1 #define WL_IOCTL_ACTION_OVL_IDX_MASK 0x1e @@ -749,42 +1190,45 @@ typedef struct get_pktcnt { #define WL_IOCTL_ACTION_MASK 0x7e #define WL_IOCTL_ACTION_OVL_SHIFT 1 - +/* Linux network driver ioctl encoding */ typedef struct wl_ioctl { - uint cmd; - void *buf; - uint len; - uint8 set; - uint used; - uint needed; + uint cmd; /* common ioctl definition */ + void *buf; /* pointer to user buffer */ + uint len; /* length of user buffer */ + uint8 set; /* 1=set IOCTL; 0=query IOCTL */ + uint used; /* bytes read or written (optional) */ + uint needed; /* bytes needed (optional) */ } wl_ioctl_t; +/* reference to wl_ioctl_t struct used by usermode driver */ +#define ioctl_subtype set /* subtype param */ +#define ioctl_pid used /* pid param */ +#define ioctl_status needed /* status param */ -#define ioctl_subtype set -#define ioctl_pid used -#define ioctl_status needed - - +/* + * Structure for passing hardware and software + * revision info up from the driver. + */ typedef struct wlc_rev_info { - uint vendorid; - uint deviceid; - uint radiorev; - uint chiprev; - uint corerev; - uint boardid; - uint boardvendor; - uint boardrev; - uint driverrev; - uint ucoderev; - uint bus; - uint chipnum; - uint phytype; - uint phyrev; - uint anarev; - uint chippkg; + uint vendorid; /* PCI vendor id */ + uint deviceid; /* device id of chip */ + uint radiorev; /* radio revision */ + uint chiprev; /* chip revision */ + uint corerev; /* core revision */ + uint boardid; /* board identifier (usu. PCI sub-device id) */ + uint boardvendor; /* board vendor (usu. PCI sub-vendor id) */ + uint boardrev; /* board revision */ + uint driverrev; /* driver version */ + uint ucoderev; /* microcode version */ + uint bus; /* bus type */ + uint chipnum; /* chip number */ + uint phytype; /* phy type */ + uint phyrev; /* phy revision */ + uint anarev; /* anacore rev */ + uint chippkg; /* chip package info */ } wlc_rev_info_t; -#define WL_REV_INFO_LEGACY_LENGTH 48 +#define WL_REV_INFO_LEGACY_LENGTH 48 #define WL_BRAND_MAX 10 typedef struct wl_instance_info { @@ -792,17 +1236,17 @@ typedef struct wl_instance_info { char brand[WL_BRAND_MAX]; } wl_instance_info_t; - +/* structure to change size of tx fifo */ typedef struct wl_txfifo_sz { - uint16 magic; - uint16 fifo; - uint16 size; + uint16 magic; + uint16 fifo; + uint16 size; } wl_txfifo_sz_t; +/* magic pattern used for mismatch driver and wl */ +#define WL_TXFIFO_SZ_MAGIC 0xa5a5 -#define WL_TXFIFO_SZ_MAGIC 0xa5a5 - - - +/* Transfer info about an IOVar from the driver */ +/* Max supported IOV name size in bytes, + 1 for nul termination */ #define WLC_IOV_NAME_LEN 30 typedef struct wlc_iov_trx_s { uint8 module; @@ -810,399 +1254,409 @@ typedef struct wlc_iov_trx_s { char name[WLC_IOV_NAME_LEN]; } wlc_iov_trx_t; +/* check this magic number */ +#define WLC_IOCTL_MAGIC 0x14e46c77 -#define WLC_IOCTL_MAGIC 0x14e46c77 - - -#define WLC_IOCTL_VERSION 1 - -#define WLC_IOCTL_MAXLEN 8192 -#define WLC_IOCTL_SMLEN 256 -#define WLC_IOCTL_MEDLEN 1536 -#ifdef WLC_HIGH_ONLY -#define WLC_SAMPLECOLLECT_MAXLEN 1024 -#define WLC_SAMPLECOLLECT_MAXLEN_LCN40 1024 +/* bump this number if you change the ioctl interface */ +#ifdef D11AC_IOTYPES +#define WLC_IOCTL_VERSION 2 +#define WLC_IOCTL_VERSION_LEGACY_IOTYPES 1 #else +#define WLC_IOCTL_VERSION 1 +#endif /* D11AC_IOTYPES */ + +#define WLC_IOCTL_MAXLEN 8192 /* max length ioctl buffer required */ +#define WLC_IOCTL_SMLEN 256 /* "small" length ioctl buffer required */ +#define WLC_IOCTL_MEDLEN 1536 /* "med" length ioctl buffer required */ #if defined(LCNCONF) || defined(LCN40CONF) -#define WLC_SAMPLECOLLECT_MAXLEN 8192 +#define WLC_SAMPLECOLLECT_MAXLEN 8192 /* Max Sample Collect buffer */ #else -#define WLC_SAMPLECOLLECT_MAXLEN 10240 +#define WLC_SAMPLECOLLECT_MAXLEN 10240 /* Max Sample Collect buffer for two cores */ #endif -#define WLC_SAMPLECOLLECT_MAXLEN_LCN40 8192 -#endif - - -#define WLC_GET_MAGIC 0 -#define WLC_GET_VERSION 1 -#define WLC_UP 2 -#define WLC_DOWN 3 -#define WLC_GET_LOOP 4 -#define WLC_SET_LOOP 5 -#define WLC_DUMP 6 -#define WLC_GET_MSGLEVEL 7 -#define WLC_SET_MSGLEVEL 8 -#define WLC_GET_PROMISC 9 -#define WLC_SET_PROMISC 10 -#define WLC_OVERLAY_IOCTL 11 -#define WLC_GET_RATE 12 - -#define WLC_GET_INSTANCE 14 - - - - -#define WLC_GET_INFRA 19 -#define WLC_SET_INFRA 20 -#define WLC_GET_AUTH 21 -#define WLC_SET_AUTH 22 -#define WLC_GET_BSSID 23 -#define WLC_SET_BSSID 24 -#define WLC_GET_SSID 25 -#define WLC_SET_SSID 26 -#define WLC_RESTART 27 -#define WLC_TERMINATED 28 - -#define WLC_GET_CHANNEL 29 -#define WLC_SET_CHANNEL 30 -#define WLC_GET_SRL 31 -#define WLC_SET_SRL 32 -#define WLC_GET_LRL 33 -#define WLC_SET_LRL 34 -#define WLC_GET_PLCPHDR 35 -#define WLC_SET_PLCPHDR 36 -#define WLC_GET_RADIO 37 -#define WLC_SET_RADIO 38 -#define WLC_GET_PHYTYPE 39 -#define WLC_DUMP_RATE 40 -#define WLC_SET_RATE_PARAMS 41 -#define WLC_GET_FIXRATE 42 -#define WLC_SET_FIXRATE 43 - - -#define WLC_GET_KEY 44 -#define WLC_SET_KEY 45 -#define WLC_GET_REGULATORY 46 -#define WLC_SET_REGULATORY 47 -#define WLC_GET_PASSIVE_SCAN 48 -#define WLC_SET_PASSIVE_SCAN 49 -#define WLC_SCAN 50 -#define WLC_SCAN_RESULTS 51 -#define WLC_DISASSOC 52 -#define WLC_REASSOC 53 -#define WLC_GET_ROAM_TRIGGER 54 -#define WLC_SET_ROAM_TRIGGER 55 -#define WLC_GET_ROAM_DELTA 56 -#define WLC_SET_ROAM_DELTA 57 -#define WLC_GET_ROAM_SCAN_PERIOD 58 -#define WLC_SET_ROAM_SCAN_PERIOD 59 -#define WLC_EVM 60 -#define WLC_GET_TXANT 61 -#define WLC_SET_TXANT 62 -#define WLC_GET_ANTDIV 63 -#define WLC_SET_ANTDIV 64 - - -#define WLC_GET_CLOSED 67 -#define WLC_SET_CLOSED 68 -#define WLC_GET_MACLIST 69 -#define WLC_SET_MACLIST 70 -#define WLC_GET_RATESET 71 -#define WLC_SET_RATESET 72 - -#define WLC_LONGTRAIN 74 -#define WLC_GET_BCNPRD 75 -#define WLC_SET_BCNPRD 76 -#define WLC_GET_DTIMPRD 77 -#define WLC_SET_DTIMPRD 78 -#define WLC_GET_SROM 79 -#define WLC_SET_SROM 80 -#define WLC_GET_WEP_RESTRICT 81 -#define WLC_SET_WEP_RESTRICT 82 -#define WLC_GET_COUNTRY 83 -#define WLC_SET_COUNTRY 84 -#define WLC_GET_PM 85 -#define WLC_SET_PM 86 -#define WLC_GET_WAKE 87 -#define WLC_SET_WAKE 88 - -#define WLC_GET_FORCELINK 90 -#define WLC_SET_FORCELINK 91 -#define WLC_FREQ_ACCURACY 92 -#define WLC_CARRIER_SUPPRESS 93 -#define WLC_GET_PHYREG 94 -#define WLC_SET_PHYREG 95 -#define WLC_GET_RADIOREG 96 -#define WLC_SET_RADIOREG 97 -#define WLC_GET_REVINFO 98 -#define WLC_GET_UCANTDIV 99 -#define WLC_SET_UCANTDIV 100 -#define WLC_R_REG 101 -#define WLC_W_REG 102 - - -#define WLC_GET_MACMODE 105 -#define WLC_SET_MACMODE 106 -#define WLC_GET_MONITOR 107 -#define WLC_SET_MONITOR 108 -#define WLC_GET_GMODE 109 -#define WLC_SET_GMODE 110 -#define WLC_GET_LEGACY_ERP 111 -#define WLC_SET_LEGACY_ERP 112 -#define WLC_GET_RX_ANT 113 -#define WLC_GET_CURR_RATESET 114 -#define WLC_GET_SCANSUPPRESS 115 -#define WLC_SET_SCANSUPPRESS 116 -#define WLC_GET_AP 117 -#define WLC_SET_AP 118 -#define WLC_GET_EAP_RESTRICT 119 -#define WLC_SET_EAP_RESTRICT 120 -#define WLC_SCB_AUTHORIZE 121 -#define WLC_SCB_DEAUTHORIZE 122 -#define WLC_GET_WDSLIST 123 -#define WLC_SET_WDSLIST 124 -#define WLC_GET_ATIM 125 -#define WLC_SET_ATIM 126 -#define WLC_GET_RSSI 127 -#define WLC_GET_PHYANTDIV 128 -#define WLC_SET_PHYANTDIV 129 -#define WLC_AP_RX_ONLY 130 -#define WLC_GET_TX_PATH_PWR 131 -#define WLC_SET_TX_PATH_PWR 132 -#define WLC_GET_WSEC 133 -#define WLC_SET_WSEC 134 -#define WLC_GET_PHY_NOISE 135 -#define WLC_GET_BSS_INFO 136 -#define WLC_GET_PKTCNTS 137 -#define WLC_GET_LAZYWDS 138 -#define WLC_SET_LAZYWDS 139 -#define WLC_GET_BANDLIST 140 -#define WLC_GET_BAND 141 -#define WLC_SET_BAND 142 -#define WLC_SCB_DEAUTHENTICATE 143 -#define WLC_GET_SHORTSLOT 144 -#define WLC_GET_SHORTSLOT_OVERRIDE 145 -#define WLC_SET_SHORTSLOT_OVERRIDE 146 -#define WLC_GET_SHORTSLOT_RESTRICT 147 -#define WLC_SET_SHORTSLOT_RESTRICT 148 -#define WLC_GET_GMODE_PROTECTION 149 -#define WLC_GET_GMODE_PROTECTION_OVERRIDE 150 -#define WLC_SET_GMODE_PROTECTION_OVERRIDE 151 -#define WLC_UPGRADE 152 - - -#define WLC_GET_IGNORE_BCNS 155 -#define WLC_SET_IGNORE_BCNS 156 -#define WLC_GET_SCB_TIMEOUT 157 -#define WLC_SET_SCB_TIMEOUT 158 -#define WLC_GET_ASSOCLIST 159 -#define WLC_GET_CLK 160 -#define WLC_SET_CLK 161 -#define WLC_GET_UP 162 -#define WLC_OUT 163 -#define WLC_GET_WPA_AUTH 164 -#define WLC_SET_WPA_AUTH 165 -#define WLC_GET_UCFLAGS 166 -#define WLC_SET_UCFLAGS 167 -#define WLC_GET_PWRIDX 168 -#define WLC_SET_PWRIDX 169 -#define WLC_GET_TSSI 170 -#define WLC_GET_SUP_RATESET_OVERRIDE 171 -#define WLC_SET_SUP_RATESET_OVERRIDE 172 - - - - - -#define WLC_GET_PROTECTION_CONTROL 178 -#define WLC_SET_PROTECTION_CONTROL 179 -#define WLC_GET_PHYLIST 180 -#define WLC_ENCRYPT_STRENGTH 181 -#define WLC_DECRYPT_STATUS 182 -#define WLC_GET_KEY_SEQ 183 -#define WLC_GET_SCAN_CHANNEL_TIME 184 -#define WLC_SET_SCAN_CHANNEL_TIME 185 -#define WLC_GET_SCAN_UNASSOC_TIME 186 -#define WLC_SET_SCAN_UNASSOC_TIME 187 -#define WLC_GET_SCAN_HOME_TIME 188 -#define WLC_SET_SCAN_HOME_TIME 189 -#define WLC_GET_SCAN_NPROBES 190 -#define WLC_SET_SCAN_NPROBES 191 -#define WLC_GET_PRB_RESP_TIMEOUT 192 -#define WLC_SET_PRB_RESP_TIMEOUT 193 -#define WLC_GET_ATTEN 194 -#define WLC_SET_ATTEN 195 -#define WLC_GET_SHMEM 196 -#define WLC_SET_SHMEM 197 - - -#define WLC_SET_WSEC_TEST 200 -#define WLC_SCB_DEAUTHENTICATE_FOR_REASON 201 -#define WLC_TKIP_COUNTERMEASURES 202 -#define WLC_GET_PIOMODE 203 -#define WLC_SET_PIOMODE 204 -#define WLC_SET_ASSOC_PREFER 205 -#define WLC_GET_ASSOC_PREFER 206 -#define WLC_SET_ROAM_PREFER 207 -#define WLC_GET_ROAM_PREFER 208 -#define WLC_SET_LED 209 -#define WLC_GET_LED 210 -#define WLC_GET_INTERFERENCE_MODE 211 -#define WLC_SET_INTERFERENCE_MODE 212 -#define WLC_GET_CHANNEL_QA 213 -#define WLC_START_CHANNEL_QA 214 -#define WLC_GET_CHANNEL_SEL 215 -#define WLC_START_CHANNEL_SEL 216 -#define WLC_GET_VALID_CHANNELS 217 -#define WLC_GET_FAKEFRAG 218 -#define WLC_SET_FAKEFRAG 219 -#define WLC_GET_PWROUT_PERCENTAGE 220 -#define WLC_SET_PWROUT_PERCENTAGE 221 -#define WLC_SET_BAD_FRAME_PREEMPT 222 -#define WLC_GET_BAD_FRAME_PREEMPT 223 -#define WLC_SET_LEAP_LIST 224 -#define WLC_GET_LEAP_LIST 225 -#define WLC_GET_CWMIN 226 -#define WLC_SET_CWMIN 227 -#define WLC_GET_CWMAX 228 -#define WLC_SET_CWMAX 229 -#define WLC_GET_WET 230 -#define WLC_SET_WET 231 -#define WLC_GET_PUB 232 - - -#define WLC_GET_KEY_PRIMARY 235 -#define WLC_SET_KEY_PRIMARY 236 - -#define WLC_GET_ACI_ARGS 238 -#define WLC_SET_ACI_ARGS 239 -#define WLC_UNSET_CALLBACK 240 -#define WLC_SET_CALLBACK 241 -#define WLC_GET_RADAR 242 -#define WLC_SET_RADAR 243 -#define WLC_SET_SPECT_MANAGMENT 244 -#define WLC_GET_SPECT_MANAGMENT 245 -#define WLC_WDS_GET_REMOTE_HWADDR 246 -#define WLC_WDS_GET_WPA_SUP 247 -#define WLC_SET_CS_SCAN_TIMER 248 -#define WLC_GET_CS_SCAN_TIMER 249 -#define WLC_MEASURE_REQUEST 250 -#define WLC_INIT 251 -#define WLC_SEND_QUIET 252 -#define WLC_KEEPALIVE 253 -#define WLC_SEND_PWR_CONSTRAINT 254 -#define WLC_UPGRADE_STATUS 255 -#define WLC_CURRENT_PWR 256 -#define WLC_GET_SCAN_PASSIVE_TIME 257 -#define WLC_SET_SCAN_PASSIVE_TIME 258 -#define WLC_LEGACY_LINK_BEHAVIOR 259 -#define WLC_GET_CHANNELS_IN_COUNTRY 260 -#define WLC_GET_COUNTRY_LIST 261 -#define WLC_GET_VAR 262 -#define WLC_SET_VAR 263 -#define WLC_NVRAM_GET 264 -#define WLC_NVRAM_SET 265 -#define WLC_NVRAM_DUMP 266 -#define WLC_REBOOT 267 -#define WLC_SET_WSEC_PMK 268 -#define WLC_GET_AUTH_MODE 269 -#define WLC_SET_AUTH_MODE 270 -#define WLC_GET_WAKEENTRY 271 -#define WLC_SET_WAKEENTRY 272 -#define WLC_NDCONFIG_ITEM 273 -#define WLC_NVOTPW 274 -#define WLC_OTPW 275 -#define WLC_IOV_BLOCK_GET 276 -#define WLC_IOV_MODULES_GET 277 -#define WLC_SOFT_RESET 278 -#define WLC_GET_ALLOW_MODE 279 -#define WLC_SET_ALLOW_MODE 280 -#define WLC_GET_DESIRED_BSSID 281 -#define WLC_SET_DESIRED_BSSID 282 -#define WLC_DISASSOC_MYAP 283 -#define WLC_GET_NBANDS 284 -#define WLC_GET_BANDSTATES 285 -#define WLC_GET_WLC_BSS_INFO 286 -#define WLC_GET_ASSOC_INFO 287 -#define WLC_GET_OID_PHY 288 -#define WLC_SET_OID_PHY 289 -#define WLC_SET_ASSOC_TIME 290 -#define WLC_GET_DESIRED_SSID 291 -#define WLC_GET_CHANSPEC 292 -#define WLC_GET_ASSOC_STATE 293 -#define WLC_SET_PHY_STATE 294 -#define WLC_GET_SCAN_PENDING 295 -#define WLC_GET_SCANREQ_PENDING 296 -#define WLC_GET_PREV_ROAM_REASON 297 -#define WLC_SET_PREV_ROAM_REASON 298 -#define WLC_GET_BANDSTATES_PI 299 -#define WLC_GET_PHY_STATE 300 -#define WLC_GET_BSS_WPA_RSN 301 -#define WLC_GET_BSS_WPA2_RSN 302 -#define WLC_GET_BSS_BCN_TS 303 -#define WLC_GET_INT_DISASSOC 304 -#define WLC_SET_NUM_PEERS 305 -#define WLC_GET_NUM_BSS 306 -#define WLC_NPHY_SAMPLE_COLLECT 307 -#define WLC_UM_PRIV 308 -#define WLC_GET_CMD 309 - -#define WLC_SET_INTERFERENCE_OVERRIDE_MODE 311 -#define WLC_GET_INTERFERENCE_OVERRIDE_MODE 312 -#define WLC_GET_WAI_RESTRICT 313 -#define WLC_SET_WAI_RESTRICT 314 -#define WLC_SET_WAI_REKEY 315 -#define WLC_SET_PEAKRATE 316 -#define WLC_GET_PEAKRATE 317 -#define WLC_LAST 318 + +/* common ioctl definitions */ +#define WLC_GET_MAGIC 0 +#define WLC_GET_VERSION 1 +#define WLC_UP 2 +#define WLC_DOWN 3 +#define WLC_GET_LOOP 4 +#define WLC_SET_LOOP 5 +#define WLC_DUMP 6 +#define WLC_GET_MSGLEVEL 7 +#define WLC_SET_MSGLEVEL 8 +#define WLC_GET_PROMISC 9 +#define WLC_SET_PROMISC 10 +/* #define WLC_OVERLAY_IOCTL 11 */ /* not supported */ +#define WLC_GET_RATE 12 +#define WLC_GET_MAX_RATE 13 +#define WLC_GET_INSTANCE 14 +/* #define WLC_GET_FRAG 15 */ /* no longer supported */ +/* #define WLC_SET_FRAG 16 */ /* no longer supported */ +/* #define WLC_GET_RTS 17 */ /* no longer supported */ +/* #define WLC_SET_RTS 18 */ /* no longer supported */ +#define WLC_GET_INFRA 19 +#define WLC_SET_INFRA 20 +#define WLC_GET_AUTH 21 +#define WLC_SET_AUTH 22 +#define WLC_GET_BSSID 23 +#define WLC_SET_BSSID 24 +#define WLC_GET_SSID 25 +#define WLC_SET_SSID 26 +#define WLC_RESTART 27 +#define WLC_TERMINATED 28 +/* #define WLC_DUMP_SCB 28 */ /* no longer supported */ +#define WLC_GET_CHANNEL 29 +#define WLC_SET_CHANNEL 30 +#define WLC_GET_SRL 31 +#define WLC_SET_SRL 32 +#define WLC_GET_LRL 33 +#define WLC_SET_LRL 34 +#define WLC_GET_PLCPHDR 35 +#define WLC_SET_PLCPHDR 36 +#define WLC_GET_RADIO 37 +#define WLC_SET_RADIO 38 +#define WLC_GET_PHYTYPE 39 +#define WLC_DUMP_RATE 40 +#define WLC_SET_RATE_PARAMS 41 +#define WLC_GET_FIXRATE 42 +#define WLC_SET_FIXRATE 43 +/* #define WLC_GET_WEP 42 */ /* no longer supported */ +/* #define WLC_SET_WEP 43 */ /* no longer supported */ +#define WLC_GET_KEY 44 +#define WLC_SET_KEY 45 +#define WLC_GET_REGULATORY 46 +#define WLC_SET_REGULATORY 47 +#define WLC_GET_PASSIVE_SCAN 48 +#define WLC_SET_PASSIVE_SCAN 49 +#define WLC_SCAN 50 +#define WLC_SCAN_RESULTS 51 +#define WLC_DISASSOC 52 +#define WLC_REASSOC 53 +#define WLC_GET_ROAM_TRIGGER 54 +#define WLC_SET_ROAM_TRIGGER 55 +#define WLC_GET_ROAM_DELTA 56 +#define WLC_SET_ROAM_DELTA 57 +#define WLC_GET_ROAM_SCAN_PERIOD 58 +#define WLC_SET_ROAM_SCAN_PERIOD 59 +#define WLC_EVM 60 /* diag */ +#define WLC_GET_TXANT 61 +#define WLC_SET_TXANT 62 +#define WLC_GET_ANTDIV 63 +#define WLC_SET_ANTDIV 64 +/* #define WLC_GET_TXPWR 65 */ /* no longer supported */ +/* #define WLC_SET_TXPWR 66 */ /* no longer supported */ +#define WLC_GET_CLOSED 67 +#define WLC_SET_CLOSED 68 +#define WLC_GET_MACLIST 69 +#define WLC_SET_MACLIST 70 +#define WLC_GET_RATESET 71 +#define WLC_SET_RATESET 72 +/* #define WLC_GET_LOCALE 73 */ /* no longer supported */ +#define WLC_LONGTRAIN 74 +#define WLC_GET_BCNPRD 75 +#define WLC_SET_BCNPRD 76 +#define WLC_GET_DTIMPRD 77 +#define WLC_SET_DTIMPRD 78 +#define WLC_GET_SROM 79 +#define WLC_SET_SROM 80 +#define WLC_GET_WEP_RESTRICT 81 +#define WLC_SET_WEP_RESTRICT 82 +#define WLC_GET_COUNTRY 83 +#define WLC_SET_COUNTRY 84 +#define WLC_GET_PM 85 +#define WLC_SET_PM 86 +#define WLC_GET_WAKE 87 +#define WLC_SET_WAKE 88 +/* #define WLC_GET_D11CNTS 89 */ /* -> "counters" iovar */ +#define WLC_GET_FORCELINK 90 /* ndis only */ +#define WLC_SET_FORCELINK 91 /* ndis only */ +#define WLC_FREQ_ACCURACY 92 /* diag */ +#define WLC_CARRIER_SUPPRESS 93 /* diag */ +#define WLC_GET_PHYREG 94 +#define WLC_SET_PHYREG 95 +#define WLC_GET_RADIOREG 96 +#define WLC_SET_RADIOREG 97 +#define WLC_GET_REVINFO 98 +#define WLC_GET_UCANTDIV 99 +#define WLC_SET_UCANTDIV 100 +#define WLC_R_REG 101 +#define WLC_W_REG 102 +/* #define WLC_DIAG_LOOPBACK 103 old tray diag */ +/* #define WLC_RESET_D11CNTS 104 */ /* -> "reset_d11cnts" iovar */ +#define WLC_GET_MACMODE 105 +#define WLC_SET_MACMODE 106 +#define WLC_GET_MONITOR 107 +#define WLC_SET_MONITOR 108 +#define WLC_GET_GMODE 109 +#define WLC_SET_GMODE 110 +#define WLC_GET_LEGACY_ERP 111 +#define WLC_SET_LEGACY_ERP 112 +#define WLC_GET_RX_ANT 113 +#define WLC_GET_CURR_RATESET 114 /* current rateset */ +#define WLC_GET_SCANSUPPRESS 115 +#define WLC_SET_SCANSUPPRESS 116 +#define WLC_GET_AP 117 +#define WLC_SET_AP 118 +#define WLC_GET_EAP_RESTRICT 119 +#define WLC_SET_EAP_RESTRICT 120 +#define WLC_SCB_AUTHORIZE 121 +#define WLC_SCB_DEAUTHORIZE 122 +#define WLC_GET_WDSLIST 123 +#define WLC_SET_WDSLIST 124 +#define WLC_GET_ATIM 125 +#define WLC_SET_ATIM 126 +#define WLC_GET_RSSI 127 +#define WLC_GET_PHYANTDIV 128 +#define WLC_SET_PHYANTDIV 129 +#define WLC_AP_RX_ONLY 130 +#define WLC_GET_TX_PATH_PWR 131 +#define WLC_SET_TX_PATH_PWR 132 +#define WLC_GET_WSEC 133 +#define WLC_SET_WSEC 134 +#define WLC_GET_PHY_NOISE 135 +#define WLC_GET_BSS_INFO 136 +#define WLC_GET_PKTCNTS 137 +#define WLC_GET_LAZYWDS 138 +#define WLC_SET_LAZYWDS 139 +#define WLC_GET_BANDLIST 140 +#define WLC_GET_BAND 141 +#define WLC_SET_BAND 142 +#define WLC_SCB_DEAUTHENTICATE 143 +#define WLC_GET_SHORTSLOT 144 +#define WLC_GET_SHORTSLOT_OVERRIDE 145 +#define WLC_SET_SHORTSLOT_OVERRIDE 146 +#define WLC_GET_SHORTSLOT_RESTRICT 147 +#define WLC_SET_SHORTSLOT_RESTRICT 148 +#define WLC_GET_GMODE_PROTECTION 149 +#define WLC_GET_GMODE_PROTECTION_OVERRIDE 150 +#define WLC_SET_GMODE_PROTECTION_OVERRIDE 151 +#define WLC_UPGRADE 152 +/* #define WLC_GET_MRATE 153 */ /* no longer supported */ +/* #define WLC_SET_MRATE 154 */ /* no longer supported */ +#define WLC_GET_IGNORE_BCNS 155 +#define WLC_SET_IGNORE_BCNS 156 +#define WLC_GET_SCB_TIMEOUT 157 +#define WLC_SET_SCB_TIMEOUT 158 +#define WLC_GET_ASSOCLIST 159 +#define WLC_GET_CLK 160 +#define WLC_SET_CLK 161 +#define WLC_GET_UP 162 +#define WLC_OUT 163 +#define WLC_GET_WPA_AUTH 164 +#define WLC_SET_WPA_AUTH 165 +#define WLC_GET_UCFLAGS 166 +#define WLC_SET_UCFLAGS 167 +#define WLC_GET_PWRIDX 168 +#define WLC_SET_PWRIDX 169 +#define WLC_GET_TSSI 170 +#define WLC_GET_SUP_RATESET_OVERRIDE 171 +#define WLC_SET_SUP_RATESET_OVERRIDE 172 +/* #define WLC_SET_FAST_TIMER 173 */ /* no longer supported */ +/* #define WLC_GET_FAST_TIMER 174 */ /* no longer supported */ +/* #define WLC_SET_SLOW_TIMER 175 */ /* no longer supported */ +/* #define WLC_GET_SLOW_TIMER 176 */ /* no longer supported */ +/* #define WLC_DUMP_PHYREGS 177 */ /* no longer supported */ +#define WLC_GET_PROTECTION_CONTROL 178 +#define WLC_SET_PROTECTION_CONTROL 179 +#define WLC_GET_PHYLIST 180 +#define WLC_ENCRYPT_STRENGTH 181 /* ndis only */ +#define WLC_DECRYPT_STATUS 182 /* ndis only */ +#define WLC_GET_KEY_SEQ 183 +#define WLC_GET_SCAN_CHANNEL_TIME 184 +#define WLC_SET_SCAN_CHANNEL_TIME 185 +#define WLC_GET_SCAN_UNASSOC_TIME 186 +#define WLC_SET_SCAN_UNASSOC_TIME 187 +#define WLC_GET_SCAN_HOME_TIME 188 +#define WLC_SET_SCAN_HOME_TIME 189 +#define WLC_GET_SCAN_NPROBES 190 +#define WLC_SET_SCAN_NPROBES 191 +#define WLC_GET_PRB_RESP_TIMEOUT 192 +#define WLC_SET_PRB_RESP_TIMEOUT 193 +#define WLC_GET_ATTEN 194 +#define WLC_SET_ATTEN 195 +#define WLC_GET_SHMEM 196 /* diag */ +#define WLC_SET_SHMEM 197 /* diag */ +/* #define WLC_GET_GMODE_PROTECTION_CTS 198 */ /* no longer supported */ +/* #define WLC_SET_GMODE_PROTECTION_CTS 199 */ /* no longer supported */ +#define WLC_SET_WSEC_TEST 200 +#define WLC_SCB_DEAUTHENTICATE_FOR_REASON 201 +#define WLC_TKIP_COUNTERMEASURES 202 +#define WLC_GET_PIOMODE 203 +#define WLC_SET_PIOMODE 204 +#define WLC_SET_ASSOC_PREFER 205 +#define WLC_GET_ASSOC_PREFER 206 +#define WLC_SET_ROAM_PREFER 207 +#define WLC_GET_ROAM_PREFER 208 +#define WLC_SET_LED 209 +#define WLC_GET_LED 210 +#define WLC_GET_INTERFERENCE_MODE 211 +#define WLC_SET_INTERFERENCE_MODE 212 +#define WLC_GET_CHANNEL_QA 213 +#define WLC_START_CHANNEL_QA 214 +#define WLC_GET_CHANNEL_SEL 215 +#define WLC_START_CHANNEL_SEL 216 +#define WLC_GET_VALID_CHANNELS 217 +#define WLC_GET_FAKEFRAG 218 +#define WLC_SET_FAKEFRAG 219 +#define WLC_GET_PWROUT_PERCENTAGE 220 +#define WLC_SET_PWROUT_PERCENTAGE 221 +#define WLC_SET_BAD_FRAME_PREEMPT 222 +#define WLC_GET_BAD_FRAME_PREEMPT 223 +#define WLC_SET_LEAP_LIST 224 +#define WLC_GET_LEAP_LIST 225 +#define WLC_GET_CWMIN 226 +#define WLC_SET_CWMIN 227 +#define WLC_GET_CWMAX 228 +#define WLC_SET_CWMAX 229 +#define WLC_GET_WET 230 +#define WLC_SET_WET 231 +#define WLC_GET_PUB 232 +/* #define WLC_SET_GLACIAL_TIMER 233 */ /* no longer supported */ +/* #define WLC_GET_GLACIAL_TIMER 234 */ /* no longer supported */ +#define WLC_GET_KEY_PRIMARY 235 +#define WLC_SET_KEY_PRIMARY 236 +/* #define WLC_DUMP_RADIOREGS 237 */ /* no longer supported */ +#define WLC_GET_ACI_ARGS 238 +#define WLC_SET_ACI_ARGS 239 +#define WLC_UNSET_CALLBACK 240 +#define WLC_SET_CALLBACK 241 +#define WLC_GET_RADAR 242 +#define WLC_SET_RADAR 243 +#define WLC_SET_SPECT_MANAGMENT 244 +#define WLC_GET_SPECT_MANAGMENT 245 +#define WLC_WDS_GET_REMOTE_HWADDR 246 /* handled in wl_linux.c/wl_vx.c */ +#define WLC_WDS_GET_WPA_SUP 247 +#define WLC_SET_CS_SCAN_TIMER 248 +#define WLC_GET_CS_SCAN_TIMER 249 +#define WLC_MEASURE_REQUEST 250 +#define WLC_INIT 251 +#define WLC_SEND_QUIET 252 +#define WLC_KEEPALIVE 253 +#define WLC_SEND_PWR_CONSTRAINT 254 +#define WLC_UPGRADE_STATUS 255 +#define WLC_CURRENT_PWR 256 +#define WLC_GET_SCAN_PASSIVE_TIME 257 +#define WLC_SET_SCAN_PASSIVE_TIME 258 +#define WLC_LEGACY_LINK_BEHAVIOR 259 +#define WLC_GET_CHANNELS_IN_COUNTRY 260 +#define WLC_GET_COUNTRY_LIST 261 +#define WLC_GET_VAR 262 /* get value of named variable */ +#define WLC_SET_VAR 263 /* set named variable to value */ +#define WLC_NVRAM_GET 264 /* deprecated */ +#define WLC_NVRAM_SET 265 +#define WLC_NVRAM_DUMP 266 +#define WLC_REBOOT 267 +#define WLC_SET_WSEC_PMK 268 +#define WLC_GET_AUTH_MODE 269 +#define WLC_SET_AUTH_MODE 270 +#define WLC_GET_WAKEENTRY 271 +#define WLC_SET_WAKEENTRY 272 +#define WLC_NDCONFIG_ITEM 273 /* currently handled in wl_oid.c */ +#define WLC_NVOTPW 274 +#define WLC_OTPW 275 +#define WLC_IOV_BLOCK_GET 276 +#define WLC_IOV_MODULES_GET 277 +#define WLC_SOFT_RESET 278 +#define WLC_GET_ALLOW_MODE 279 +#define WLC_SET_ALLOW_MODE 280 +#define WLC_GET_DESIRED_BSSID 281 +#define WLC_SET_DESIRED_BSSID 282 +#define WLC_DISASSOC_MYAP 283 +#define WLC_GET_NBANDS 284 /* for Dongle EXT_STA support */ +#define WLC_GET_BANDSTATES 285 /* for Dongle EXT_STA support */ +#define WLC_GET_WLC_BSS_INFO 286 /* for Dongle EXT_STA support */ +#define WLC_GET_ASSOC_INFO 287 /* for Dongle EXT_STA support */ +#define WLC_GET_OID_PHY 288 /* for Dongle EXT_STA support */ +#define WLC_SET_OID_PHY 289 /* for Dongle EXT_STA support */ +#define WLC_SET_ASSOC_TIME 290 /* for Dongle EXT_STA support */ +#define WLC_GET_DESIRED_SSID 291 /* for Dongle EXT_STA support */ +#define WLC_GET_CHANSPEC 292 /* for Dongle EXT_STA support */ +#define WLC_GET_ASSOC_STATE 293 /* for Dongle EXT_STA support */ +#define WLC_SET_PHY_STATE 294 /* for Dongle EXT_STA support */ +#define WLC_GET_SCAN_PENDING 295 /* for Dongle EXT_STA support */ +#define WLC_GET_SCANREQ_PENDING 296 /* for Dongle EXT_STA support */ +#define WLC_GET_PREV_ROAM_REASON 297 /* for Dongle EXT_STA support */ +#define WLC_SET_PREV_ROAM_REASON 298 /* for Dongle EXT_STA support */ +#define WLC_GET_BANDSTATES_PI 299 /* for Dongle EXT_STA support */ +#define WLC_GET_PHY_STATE 300 /* for Dongle EXT_STA support */ +#define WLC_GET_BSS_WPA_RSN 301 /* for Dongle EXT_STA support */ +#define WLC_GET_BSS_WPA2_RSN 302 /* for Dongle EXT_STA support */ +#define WLC_GET_BSS_BCN_TS 303 /* for Dongle EXT_STA support */ +#define WLC_GET_INT_DISASSOC 304 /* for Dongle EXT_STA support */ +#define WLC_SET_NUM_PEERS 305 /* for Dongle EXT_STA support */ +#define WLC_GET_NUM_BSS 306 /* for Dongle EXT_STA support */ +#define WLC_PHY_SAMPLE_COLLECT 307 /* phy sample collect mode */ +/* #define WLC_UM_PRIV 308 */ /* Deprecated: usermode driver */ +#define WLC_GET_CMD 309 +/* #define WLC_LAST 310 */ /* Never used - can be reused */ +#define WLC_SET_INTERFERENCE_OVERRIDE_MODE 311 /* set inter mode override */ +#define WLC_GET_INTERFERENCE_OVERRIDE_MODE 312 /* get inter mode override */ +/* #define WLC_GET_WAI_RESTRICT 313 */ /* for WAPI, deprecated use iovar instead */ +/* #define WLC_SET_WAI_RESTRICT 314 */ /* for WAPI, deprecated use iovar instead */ +/* #define WLC_SET_WAI_REKEY 315 */ /* for WAPI, deprecated use iovar instead */ +#define WLC_SET_NAT_CONFIG 316 /* for configuring NAT filter driver */ +#define WLC_GET_NAT_STATE 317 +#define WLC_LAST 318 #ifndef EPICTRL_COOKIE -#define EPICTRL_COOKIE 0xABADCEDE +#define EPICTRL_COOKIE 0xABADCEDE #endif - +/* vx wlc ioctl's offset */ #define CMN_IOCTL_OFF 0x180 +/* + * custom OID support + * + * 0xFF - implementation specific OID + * 0xE4 - first byte of Broadcom PCI vendor ID + * 0x14 - second byte of Broadcom PCI vendor ID + * 0xXX - the custom OID number + */ +/* begin 0x1f values beyond the start of the ET driver range. */ +#define WL_OID_BASE 0xFFE41420 - -#define WL_OID_BASE 0xFFE41420 - - -#define OID_WL_GETINSTANCE (WL_OID_BASE + WLC_GET_INSTANCE) -#define OID_WL_GET_FORCELINK (WL_OID_BASE + WLC_GET_FORCELINK) -#define OID_WL_SET_FORCELINK (WL_OID_BASE + WLC_SET_FORCELINK) -#define OID_WL_ENCRYPT_STRENGTH (WL_OID_BASE + WLC_ENCRYPT_STRENGTH) -#define OID_WL_DECRYPT_STATUS (WL_OID_BASE + WLC_DECRYPT_STATUS) +/* NDIS overrides */ +#define OID_WL_GETINSTANCE (WL_OID_BASE + WLC_GET_INSTANCE) +#define OID_WL_GET_FORCELINK (WL_OID_BASE + WLC_GET_FORCELINK) +#define OID_WL_SET_FORCELINK (WL_OID_BASE + WLC_SET_FORCELINK) +#define OID_WL_ENCRYPT_STRENGTH (WL_OID_BASE + WLC_ENCRYPT_STRENGTH) +#define OID_WL_DECRYPT_STATUS (WL_OID_BASE + WLC_DECRYPT_STATUS) #define OID_LEGACY_LINK_BEHAVIOR (WL_OID_BASE + WLC_LEGACY_LINK_BEHAVIOR) -#define OID_WL_NDCONFIG_ITEM (WL_OID_BASE + WLC_NDCONFIG_ITEM) - - -#define OID_STA_CHANSPEC (WL_OID_BASE + WLC_GET_CHANSPEC) -#define OID_STA_NBANDS (WL_OID_BASE + WLC_GET_NBANDS) -#define OID_STA_GET_PHY (WL_OID_BASE + WLC_GET_OID_PHY) -#define OID_STA_SET_PHY (WL_OID_BASE + WLC_SET_OID_PHY) -#define OID_STA_ASSOC_TIME (WL_OID_BASE + WLC_SET_ASSOC_TIME) -#define OID_STA_DESIRED_SSID (WL_OID_BASE + WLC_GET_DESIRED_SSID) -#define OID_STA_SET_PHY_STATE (WL_OID_BASE + WLC_SET_PHY_STATE) -#define OID_STA_SCAN_PENDING (WL_OID_BASE + WLC_GET_SCAN_PENDING) +#define OID_WL_NDCONFIG_ITEM (WL_OID_BASE + WLC_NDCONFIG_ITEM) + +/* EXT_STA Dongle suuport */ +#define OID_STA_CHANSPEC (WL_OID_BASE + WLC_GET_CHANSPEC) +#define OID_STA_NBANDS (WL_OID_BASE + WLC_GET_NBANDS) +#define OID_STA_GET_PHY (WL_OID_BASE + WLC_GET_OID_PHY) +#define OID_STA_SET_PHY (WL_OID_BASE + WLC_SET_OID_PHY) +#define OID_STA_ASSOC_TIME (WL_OID_BASE + WLC_SET_ASSOC_TIME) +#define OID_STA_DESIRED_SSID (WL_OID_BASE + WLC_GET_DESIRED_SSID) +#define OID_STA_SET_PHY_STATE (WL_OID_BASE + WLC_SET_PHY_STATE) +#define OID_STA_SCAN_PENDING (WL_OID_BASE + WLC_GET_SCAN_PENDING) #define OID_STA_SCANREQ_PENDING (WL_OID_BASE + WLC_GET_SCANREQ_PENDING) #define OID_STA_GET_ROAM_REASON (WL_OID_BASE + WLC_GET_PREV_ROAM_REASON) #define OID_STA_SET_ROAM_REASON (WL_OID_BASE + WLC_SET_PREV_ROAM_REASON) -#define OID_STA_GET_PHY_STATE (WL_OID_BASE + WLC_GET_PHY_STATE) -#define OID_STA_INT_DISASSOC (WL_OID_BASE + WLC_GET_INT_DISASSOC) -#define OID_STA_SET_NUM_PEERS (WL_OID_BASE + WLC_SET_NUM_PEERS) -#define OID_STA_GET_NUM_BSS (WL_OID_BASE + WLC_GET_NUM_BSS) +#define OID_STA_GET_PHY_STATE (WL_OID_BASE + WLC_GET_PHY_STATE) +#define OID_STA_INT_DISASSOC (WL_OID_BASE + WLC_GET_INT_DISASSOC) +#define OID_STA_SET_NUM_PEERS (WL_OID_BASE + WLC_SET_NUM_PEERS) +#define OID_STA_GET_NUM_BSS (WL_OID_BASE + WLC_GET_NUM_BSS) -#define WL_DECRYPT_STATUS_SUCCESS 1 -#define WL_DECRYPT_STATUS_FAILURE 2 -#define WL_DECRYPT_STATUS_UNKNOWN 3 +/* NAT filter driver support */ +#define OID_NAT_SET_CONFIG (WL_OID_BASE + WLC_SET_NAT_CONFIG) +#define OID_NAT_GET_STATE (WL_OID_BASE + WLC_GET_NAT_STATE) +#define WL_DECRYPT_STATUS_SUCCESS 1 +#define WL_DECRYPT_STATUS_FAILURE 2 +#define WL_DECRYPT_STATUS_UNKNOWN 3 -#define WLC_UPGRADE_SUCCESS 0 -#define WLC_UPGRADE_PENDING 1 +/* allows user-mode app to poll the status of USB image upgrade */ +#define WLC_UPGRADE_SUCCESS 0 +#define WLC_UPGRADE_PENDING 1 #ifdef CONFIG_USBRNDIS_RETAIL - +/* struct passed in for WLC_NDCONFIG_ITEM */ typedef struct { char *name; void *param; @@ -1210,192 +1664,211 @@ typedef struct { #endif +/* WLC_GET_AUTH, WLC_SET_AUTH values */ +#define WL_AUTH_OPEN_SYSTEM 0 /* d11 open authentication */ +#define WL_AUTH_SHARED_KEY 1 /* d11 shared authentication */ +#define WL_AUTH_OPEN_SHARED 2 /* try open, then shared if open failed w/rc 13 */ -#define WL_AUTH_OPEN_SYSTEM 0 -#define WL_AUTH_SHARED_KEY 1 -#define WL_AUTH_OPEN_SHARED 3 +/* Bit masks for radio disabled status - returned by WL_GET_RADIO */ +#define WL_RADIO_SW_DISABLE (1<<0) +#define WL_RADIO_HW_DISABLE (1<<1) +#define WL_RADIO_MPC_DISABLE (1<<2) +#define WL_RADIO_COUNTRY_DISABLE (1<<3) /* some countries don't support any channel */ +#define WL_SPURAVOID_OFF 0 +#define WL_SPURAVOID_ON1 1 +#define WL_SPURAVOID_ON2 2 -#define WL_RADIO_SW_DISABLE (1<<0) -#define WL_RADIO_HW_DISABLE (1<<1) -#define WL_RADIO_MPC_DISABLE (1<<2) -#define WL_RADIO_COUNTRY_DISABLE (1<<3) - -#define WL_SPURAVOID_OFF 0 -#define WL_SPURAVOID_ON1 1 -#define WL_SPURAVOID_ON2 2 - - -#define WL_TXPWR_OVERRIDE (1U<<31) +/* Override bit for WLC_SET_TXPWR. if set, ignore other level limits */ +#define WL_TXPWR_OVERRIDE (1U<<31) #define WL_TXPWR_NEG (1U<<30) -#define WL_PHY_PAVARS_LEN 6 +#define WL_PHY_PAVARS_LEN 32 /* Phy type, Band range, chain, a1[0], b0[0], b1[0] ... */ -#define WL_PHY_PAVARS2_NUM 3 -#define WL_PHY_PAVAR_VER 1 -typedef struct wl_pavars2 { - uint16 ver; - uint16 len; - uint16 inuse; - uint16 phy_type; - uint16 bandrange; - uint16 chain; - uint16 inpa[WL_PHY_PAVARS2_NUM]; -} wl_pavars2_t; +#define WL_PHY_PAVAR_VER 1 /* pavars version */ typedef struct wl_po { - uint16 phy_type; - uint16 band; - uint16 cckpo; - uint32 ofdmpo; - uint16 mcspo[8]; + uint16 phy_type; /* Phy type */ + uint16 band; + uint16 cckpo; + uint32 ofdmpo; + uint16 mcspo[8]; } wl_po_t; - -#define WLC_TXPWR_MAX (127) - - -#define WL_DIAG_INTERRUPT 1 -#define WL_DIAG_LOOPBACK 2 -#define WL_DIAG_MEMORY 3 -#define WL_DIAG_LED 4 -#define WL_DIAG_REG 5 -#define WL_DIAG_SROM 6 -#define WL_DIAG_DMA 7 - -#define WL_DIAGERR_SUCCESS 0 -#define WL_DIAGERR_FAIL_TO_RUN 1 -#define WL_DIAGERR_NOT_SUPPORTED 2 -#define WL_DIAGERR_INTERRUPT_FAIL 3 -#define WL_DIAGERR_LOOPBACK_FAIL 4 -#define WL_DIAGERR_SROM_FAIL 5 -#define WL_DIAGERR_SROM_BADCRC 6 -#define WL_DIAGERR_REG_FAIL 7 -#define WL_DIAGERR_MEMORY_FAIL 8 -#define WL_DIAGERR_NOMEM 9 -#define WL_DIAGERR_DMA_FAIL 10 - -#define WL_DIAGERR_MEMORY_TIMEOUT 11 -#define WL_DIAGERR_MEMORY_BADPATTERN 12 - - -#define WLC_BAND_AUTO 0 -#define WLC_BAND_5G 1 -#define WLC_BAND_2G 2 -#define WLC_BAND_ALL 3 - - +/* a large TX Power as an init value to factor out of MIN() calculations, + * keep low enough to fit in an int8, units are .25 dBm + */ +#define WLC_TXPWR_MAX (127) /* ~32 dBm = 1,500 mW */ + +/* "diag" iovar argument and error code */ +#define WL_DIAG_INTERRUPT 1 /* d11 loopback interrupt test */ +#define WL_DIAG_LOOPBACK 2 /* d11 loopback data test */ +#define WL_DIAG_MEMORY 3 /* d11 memory test */ +#define WL_DIAG_LED 4 /* LED test */ +#define WL_DIAG_REG 5 /* d11/phy register test */ +#define WL_DIAG_SROM 6 /* srom read/crc test */ +#define WL_DIAG_DMA 7 /* DMA test */ +#define WL_DIAG_LOOPBACK_EXT 8 /* enhenced d11 loopback data test */ + +#define WL_DIAGERR_SUCCESS 0 +#define WL_DIAGERR_FAIL_TO_RUN 1 /* unable to run requested diag */ +#define WL_DIAGERR_NOT_SUPPORTED 2 /* diag requested is not supported */ +#define WL_DIAGERR_INTERRUPT_FAIL 3 /* loopback interrupt test failed */ +#define WL_DIAGERR_LOOPBACK_FAIL 4 /* loopback data test failed */ +#define WL_DIAGERR_SROM_FAIL 5 /* srom read failed */ +#define WL_DIAGERR_SROM_BADCRC 6 /* srom crc failed */ +#define WL_DIAGERR_REG_FAIL 7 /* d11/phy register test failed */ +#define WL_DIAGERR_MEMORY_FAIL 8 /* d11 memory test failed */ +#define WL_DIAGERR_NOMEM 9 /* diag test failed due to no memory */ +#define WL_DIAGERR_DMA_FAIL 10 /* DMA test failed */ + +#define WL_DIAGERR_MEMORY_TIMEOUT 11 /* d11 memory test didn't finish in time */ +#define WL_DIAGERR_MEMORY_BADPATTERN 12 /* d11 memory test result in bad pattern */ + +/* band types */ +#define WLC_BAND_AUTO 0 /* auto-select */ +#define WLC_BAND_5G 1 /* 5 Ghz */ +#define WLC_BAND_2G 2 /* 2.4 Ghz */ +#define WLC_BAND_ALL 3 /* all bands */ + +/* band range returned by band_range iovar */ #define WL_CHAN_FREQ_RANGE_2G 0 #define WL_CHAN_FREQ_RANGE_5GL 1 #define WL_CHAN_FREQ_RANGE_5GM 2 #define WL_CHAN_FREQ_RANGE_5GH 3 -#define WL_CHAN_FREQ_RANGE_5GLL_5BAND 4 -#define WL_CHAN_FREQ_RANGE_5GLH_5BAND 5 -#define WL_CHAN_FREQ_RANGE_5GML_5BAND 6 -#define WL_CHAN_FREQ_RANGE_5GMH_5BAND 7 -#define WL_CHAN_FREQ_RANGE_5GH_5BAND 8 - #define WL_CHAN_FREQ_RANGE_5G_BAND0 1 #define WL_CHAN_FREQ_RANGE_5G_BAND1 2 #define WL_CHAN_FREQ_RANGE_5G_BAND2 3 #define WL_CHAN_FREQ_RANGE_5G_BAND3 4 +#define WL_CHAN_FREQ_RANGE_5G_4BAND 5 + +/* phy types (returned by WLC_GET_PHYTPE) */ +#define WLC_PHY_TYPE_A 0 +#define WLC_PHY_TYPE_B 1 +#define WLC_PHY_TYPE_G 2 +#define WLC_PHY_TYPE_N 4 +#define WLC_PHY_TYPE_LP 5 +#define WLC_PHY_TYPE_SSN 6 +#define WLC_PHY_TYPE_HT 7 +#define WLC_PHY_TYPE_LCN 8 +#define WLC_PHY_TYPE_LCN40 10 +#define WLC_PHY_TYPE_NULL 0xf + +/* MAC list modes */ +#define WLC_MACMODE_DISABLED 0 /* MAC list disabled */ +#define WLC_MACMODE_DENY 1 /* Deny specified (i.e. allow unspecified) */ +#define WLC_MACMODE_ALLOW 2 /* Allow specified (i.e. deny unspecified) */ -#define WLC_PHY_TYPE_A 0 -#define WLC_PHY_TYPE_B 1 -#define WLC_PHY_TYPE_G 2 -#define WLC_PHY_TYPE_N 4 -#define WLC_PHY_TYPE_LP 5 -#define WLC_PHY_TYPE_SSN 6 -#define WLC_PHY_TYPE_HT 7 -#define WLC_PHY_TYPE_LCN 8 -#define WLC_PHY_TYPE_NULL 0xf - - -#define WLC_MACMODE_DISABLED 0 -#define WLC_MACMODE_DENY 1 -#define WLC_MACMODE_ALLOW 2 - - -#define GMODE_LEGACY_B 0 -#define GMODE_AUTO 1 -#define GMODE_ONLY 2 -#define GMODE_B_DEFERRED 3 -#define GMODE_PERFORMANCE 4 -#define GMODE_LRS 5 -#define GMODE_MAX 6 - - -#define WLC_PLCP_AUTO -1 -#define WLC_PLCP_SHORT 0 -#define WLC_PLCP_LONG 1 - - -#define WLC_PROTECTION_AUTO -1 -#define WLC_PROTECTION_OFF 0 -#define WLC_PROTECTION_ON 1 -#define WLC_PROTECTION_MMHDR_ONLY 2 -#define WLC_PROTECTION_CTS_ONLY 3 - - -#define WLC_PROTECTION_CTL_OFF 0 -#define WLC_PROTECTION_CTL_LOCAL 1 -#define WLC_PROTECTION_CTL_OVERLAP 2 - - -#define WLC_N_PROTECTION_OFF 0 -#define WLC_N_PROTECTION_OPTIONAL 1 -#define WLC_N_PROTECTION_20IN40 2 -#define WLC_N_PROTECTION_MIXEDMODE 3 - - -#define WLC_N_PREAMBLE_MIXEDMODE 0 -#define WLC_N_PREAMBLE_GF 1 +/* + * 54g modes (basic bits may still be overridden) + * + * GMODE_LEGACY_B Rateset: 1b, 2b, 5.5, 11 + * Preamble: Long + * Shortslot: Off + * GMODE_AUTO Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54 + * Extended Rateset: 6, 9, 12, 48 + * Preamble: Long + * Shortslot: Auto + * GMODE_ONLY Rateset: 1b, 2b, 5.5b, 11b, 18, 24b, 36, 54 + * Extended Rateset: 6b, 9, 12b, 48 + * Preamble: Short required + * Shortslot: Auto + * GMODE_B_DEFERRED Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54 + * Extended Rateset: 6, 9, 12, 48 + * Preamble: Long + * Shortslot: On + * GMODE_PERFORMANCE Rateset: 1b, 2b, 5.5b, 6b, 9, 11b, 12b, 18, 24b, 36, 48, 54 + * Preamble: Short required + * Shortslot: On and required + * GMODE_LRS Rateset: 1b, 2b, 5.5b, 11b + * Extended Rateset: 6, 9, 12, 18, 24, 36, 48, 54 + * Preamble: Long + * Shortslot: Auto + */ +#define GMODE_LEGACY_B 0 +#define GMODE_AUTO 1 +#define GMODE_ONLY 2 +#define GMODE_B_DEFERRED 3 +#define GMODE_PERFORMANCE 4 +#define GMODE_LRS 5 +#define GMODE_MAX 6 + +/* values for PLCPHdr_override */ +#define WLC_PLCP_AUTO -1 +#define WLC_PLCP_SHORT 0 +#define WLC_PLCP_LONG 1 + +/* values for g_protection_override and n_protection_override */ +#define WLC_PROTECTION_AUTO -1 +#define WLC_PROTECTION_OFF 0 +#define WLC_PROTECTION_ON 1 +#define WLC_PROTECTION_MMHDR_ONLY 2 +#define WLC_PROTECTION_CTS_ONLY 3 + +/* values for g_protection_control and n_protection_control */ +#define WLC_PROTECTION_CTL_OFF 0 +#define WLC_PROTECTION_CTL_LOCAL 1 +#define WLC_PROTECTION_CTL_OVERLAP 2 + +/* values for n_protection */ +#define WLC_N_PROTECTION_OFF 0 +#define WLC_N_PROTECTION_OPTIONAL 1 +#define WLC_N_PROTECTION_20IN40 2 +#define WLC_N_PROTECTION_MIXEDMODE 3 + +/* values for n_preamble_type */ +#define WLC_N_PREAMBLE_MIXEDMODE 0 +#define WLC_N_PREAMBLE_GF 1 #define WLC_N_PREAMBLE_GF_BRCM 2 +/* values for band specific 40MHz capabilities */ +#define WLC_N_BW_20ALL 0 +#define WLC_N_BW_40ALL 1 +#define WLC_N_BW_20IN2G_40IN5G 2 -#define WLC_N_BW_20ALL 0 -#define WLC_N_BW_40ALL 1 -#define WLC_N_BW_20IN2G_40IN5G 2 - +/* values to force tx/rx chain */ +#define WLC_N_TXRX_CHAIN0 0 +#define WLC_N_TXRX_CHAIN1 1 -#define WLC_N_TXRX_CHAIN0 0 -#define WLC_N_TXRX_CHAIN1 1 +/* bitflags for SGI support (sgi_rx iovar) */ +#define WLC_N_SGI_20 0x01 +#define WLC_N_SGI_40 0x02 +/* when sgi_tx==WLC_SGI_ALL, bypass rate selection, enable sgi for all mcs */ +#define WLC_SGI_ALL 0x02 -#define WLC_N_SGI_20 0x01 -#define WLC_N_SGI_40 0x02 - - -#define PM_OFF 0 -#define PM_MAX 1 +/* Values for PM */ +#define PM_OFF 0 +#define PM_MAX 1 #define PM_FAST 2 +#define PM_FORCE_OFF 3 /* use this bit to force PM off even bt is active */ #define LISTEN_INTERVAL 10 - -#define INTERFERE_OVRRIDE_OFF -1 -#define INTERFERE_NONE 0 -#define NON_WLAN 1 -#define WLAN_MANUAL 2 -#define WLAN_AUTO 3 -#define WLAN_AUTO_W_NOISE 4 -#define AUTO_ACTIVE (1 << 7) +/* interference mitigation options */ +#define INTERFERE_OVRRIDE_OFF -1 /* interference override off */ +#define INTERFERE_NONE 0 /* off */ +#define NON_WLAN 1 /* foreign/non 802.11 interference, no auto detect */ +#define WLAN_MANUAL 2 /* ACI: no auto detection */ +#define WLAN_AUTO 3 /* ACI: auto detect */ +#define WLAN_AUTO_W_NOISE 4 /* ACI: auto - detect and non 802.11 interference */ +#define AUTO_ACTIVE (1 << 7) /* Auto is currently active */ typedef struct wl_aci_args { - int enter_aci_thresh; - int exit_aci_thresh; - int usec_spin; - int glitch_delay; - uint16 nphy_adcpwr_enter_thresh; - uint16 nphy_adcpwr_exit_thresh; - uint16 nphy_repeat_ctr; - uint16 nphy_num_samples; - uint16 nphy_undetect_window_sz; - uint16 nphy_b_energy_lo_aci; - uint16 nphy_b_energy_md_aci; - uint16 nphy_b_energy_hi_aci; - uint16 nphy_noise_noassoc_glitch_th_up; + int enter_aci_thresh; /* Trigger level to start detecting ACI */ + int exit_aci_thresh; /* Trigger level to exit ACI mode */ + int usec_spin; /* microsecs to delay between rssi samples */ + int glitch_delay; /* interval between ACI scans when glitch count is consistently high */ + uint16 nphy_adcpwr_enter_thresh; /* ADC power to enter ACI mitigation mode */ + uint16 nphy_adcpwr_exit_thresh; /* ADC power to exit ACI mitigation mode */ + uint16 nphy_repeat_ctr; /* Number of tries per channel to compute power */ + uint16 nphy_num_samples; /* Number of samples to compute power on one channel */ + uint16 nphy_undetect_window_sz; /* num of undetects to exit ACI Mitigation mode */ + uint16 nphy_b_energy_lo_aci; /* low ACI power energy threshold for bphy */ + uint16 nphy_b_energy_md_aci; /* mid ACI power energy threshold for bphy */ + uint16 nphy_b_energy_hi_aci; /* high ACI power energy threshold for bphy */ + uint16 nphy_noise_noassoc_glitch_th_up; /* wl interference 4 */ uint16 nphy_noise_noassoc_glitch_th_dn; uint16 nphy_noise_assoc_glitch_th_up; uint16 nphy_noise_assoc_glitch_th_dn; @@ -1409,22 +1882,22 @@ typedef struct wl_aci_args { uint16 nphy_noise_crsidx_decr; } wl_aci_args_t; -#define TRIGGER_NOW 0 -#define TRIGGER_CRS 0x01 -#define TRIGGER_CRSDEASSERT 0x02 -#define TRIGGER_GOODFCS 0x04 -#define TRIGGER_BADFCS 0x08 -#define TRIGGER_BADPLCP 0x10 -#define TRIGGER_CRSGLITCH 0x20 -#define WL_ACI_ARGS_LEGACY_LENGTH 16 -#define WL_SAMPLECOLLECT_T_VERSION 2 +#define TRIGGER_NOW 0 +#define TRIGGER_CRS 0x01 +#define TRIGGER_CRSDEASSERT 0x02 +#define TRIGGER_GOODFCS 0x04 +#define TRIGGER_BADFCS 0x08 +#define TRIGGER_BADPLCP 0x10 +#define TRIGGER_CRSGLITCH 0x20 +#define WL_ACI_ARGS_LEGACY_LENGTH 16 /* bytes of pre NPHY aci args */ +#define WL_SAMPLECOLLECT_T_VERSION 2 /* version of wl_samplecollect_args_t struct */ typedef struct wl_samplecollect_args { - + /* version 0 fields */ uint8 coll_us; int cores; - - uint16 version; - uint16 length; + /* add'l version 1 fields */ + uint16 version; /* see definition of WL_SAMPLECOLLECT_T_VERSION */ + uint16 length; /* length of entire structure */ int8 trigger; uint16 timeout; uint16 mode; @@ -1433,358 +1906,1364 @@ typedef struct wl_samplecollect_args { uint8 gpio_sel; bool downsamp; bool be_deaf; - bool agc; - bool filter; - + bool agc; /* loop from init gain and going down */ + bool filter; /* override high pass corners to lowest */ + /* add'l version 2 fields */ uint8 trigger_state; uint8 module_sel1; uint8 module_sel2; uint16 nsamps; } wl_samplecollect_args_t; -#define WL_SAMPLEDATA_HEADER_TYPE 1 -#define WL_SAMPLEDATA_HEADER_SIZE 80 -#define WL_SAMPLEDATA_TYPE 2 -#define WL_SAMPLEDATA_SEQ 0xff -#define WL_SAMPLEDATA_MORE_DATA 0x100 -#define WL_SAMPLEDATA_T_VERSION 1 - -#define WL_SAMPLEDATA_T_VERSION_SPEC_AN 2 +#define WL_SAMPLEDATA_HEADER_TYPE 1 +#define WL_SAMPLEDATA_HEADER_SIZE 80 /* sample collect header size (bytes) */ +#define WL_SAMPLEDATA_TYPE 2 +#define WL_SAMPLEDATA_SEQ 0xff /* sequence # */ +#define WL_SAMPLEDATA_MORE_DATA 0x100 /* more data mask */ +#define WL_SAMPLEDATA_T_VERSION 1 /* version of wl_samplecollect_args_t struct */ +/* version for unpacked sample data, int16 {(I,Q),Core(0..N)} */ +#define WL_SAMPLEDATA_T_VERSION_SPEC_AN 2 typedef struct wl_sampledata { - uint16 version; - uint16 size; - uint16 tag; - uint16 length; - uint32 flag; + uint16 version; /* structure version */ + uint16 size; /* size of structure */ + uint16 tag; /* Header/Data */ + uint16 length; /* data length */ + uint32 flag; /* bit def */ } wl_sampledata_t; +#ifndef LINUX_POSTMOGRIFY_REMOVAL +/* wl_radar_args_t */ +typedef struct { + int npulses; /* required number of pulses at n * t_int */ + int ncontig; /* required number of pulses at t_int */ + int min_pw; /* minimum pulse width (20 MHz clocks) */ + int max_pw; /* maximum pulse width (20 MHz clocks) */ + uint16 thresh0; /* Radar detection, thresh 0 */ + uint16 thresh1; /* Radar detection, thresh 1 */ + uint16 blank; /* Radar detection, blank control */ + uint16 fmdemodcfg; /* Radar detection, fmdemod config */ + int npulses_lp; /* Radar detection, minimum long pulses */ + int min_pw_lp; /* Minimum pulsewidth for long pulses */ + int max_pw_lp; /* Maximum pulsewidth for long pulses */ + int min_fm_lp; /* Minimum fm for long pulses */ + int max_span_lp; /* Maximum deltat for long pulses */ + int min_deltat; /* Minimum spacing between pulses */ + int max_deltat; /* Maximum spacing between pulses */ + uint16 autocorr; /* Radar detection, autocorr on or off */ + uint16 st_level_time; /* Radar detection, start_timing level */ + uint16 t2_min; /* minimum clocks needed to remain in state 2 */ + uint32 version; /* version */ + uint32 fra_pulse_err; /* sample error margin for detecting French radar pulsed */ + int npulses_fra; /* Radar detection, minimum French pulses set */ + int npulses_stg2; /* Radar detection, minimum staggered-2 pulses set */ + int npulses_stg3; /* Radar detection, minimum staggered-3 pulses set */ + uint16 percal_mask; /* defines which period cal is masked from radar detection */ + int quant; /* quantization resolution to pulse positions */ + uint32 min_burst_intv_lp; /* minimum burst to burst interval for bin3 radar */ + uint32 max_burst_intv_lp; /* maximum burst to burst interval for bin3 radar */ + int nskip_rst_lp; /* number of skipped pulses before resetting lp buffer */ + int max_pw_tol; /* maximum tollerance allowed in detected pulse width for radar detection */ + uint16 feature_mask; /* 16-bit mask to specify enabled features */ +} wl_radar_args_t; + +#define WL_RADAR_ARGS_VERSION 2 +typedef struct { + uint32 version; /* version */ + uint16 thresh0_20_lo; /* Radar detection, thresh 0 (range 5250-5350MHz) for BW 20MHz */ + uint16 thresh1_20_lo; /* Radar detection, thresh 1 (range 5250-5350MHz) for BW 20MHz */ + uint16 thresh0_40_lo; /* Radar detection, thresh 0 (range 5250-5350MHz) for BW 40MHz */ + uint16 thresh1_40_lo; /* Radar detection, thresh 1 (range 5250-5350MHz) for BW 40MHz */ + uint16 thresh0_20_hi; /* Radar detection, thresh 0 (range 5470-5725MHz) for BW 20MHz */ + uint16 thresh1_20_hi; /* Radar detection, thresh 1 (range 5470-5725MHz) for BW 20MHz */ + uint16 thresh0_40_hi; /* Radar detection, thresh 0 (range 5470-5725MHz) for BW 40MHz */ + uint16 thresh1_40_hi; /* Radar detection, thresh 1 (range 5470-5725MHz) for BW 40MHz */ +} wl_radar_thr_t; + +#define WL_RADAR_THR_VERSION 1 +#define WL_THRESHOLD_LO_BAND 70 /* range from 5250MHz - 5350MHz */ + +/* radar iovar SET defines */ +#define WL_RADAR_DETECTOR_OFF 0 /* radar detector off */ +#define WL_RADAR_DETECTOR_ON 1 /* radar detector on */ +#define WL_RADAR_SIMULATED 2 /* force radar detector to declare + * detection once + */ +#define WL_RSSI_ANT_VERSION 1 /* current version of wl_rssi_ant_t */ +#define WL_ANT_RX_MAX 2 /* max 2 receive antennas */ +#define WL_ANT_HT_RX_MAX 3 /* max 3 receive antennas/cores */ +#define WL_ANT_IDX_1 0 /* antenna index 1 */ +#define WL_ANT_IDX_2 1 /* antenna index 2 */ + +#ifndef WL_RSSI_ANT_MAX +#define WL_RSSI_ANT_MAX 4 /* max possible rx antennas */ +#elif WL_RSSI_ANT_MAX != 4 +#error "WL_RSSI_ANT_MAX does not match" +#endif -#define WL_ERROR_VAL 0x00000001 -#define WL_TRACE_VAL 0x00000002 -#define WL_PRHDRS_VAL 0x00000004 -#define WL_PRPKT_VAL 0x00000008 -#define WL_INFORM_VAL 0x00000010 -#define WL_TMP_VAL 0x00000020 -#define WL_OID_VAL 0x00000040 -#define WL_RATE_VAL 0x00000080 -#define WL_ASSOC_VAL 0x00000100 -#define WL_PRUSR_VAL 0x00000200 -#define WL_PS_VAL 0x00000400 -#define WL_TXPWR_VAL 0x00000800 -#define WL_PORT_VAL 0x00001000 -#define WL_DUAL_VAL 0x00002000 -#define WL_WSEC_VAL 0x00004000 -#define WL_WSEC_DUMP_VAL 0x00008000 -#define WL_LOG_VAL 0x00010000 -#define WL_NRSSI_VAL 0x00020000 -#define WL_LOFT_VAL 0x00040000 -#define WL_REGULATORY_VAL 0x00080000 -#define WL_PHYCAL_VAL 0x00100000 -#define WL_RADAR_VAL 0x00200000 -#define WL_MPC_VAL 0x00400000 -#define WL_APSTA_VAL 0x00800000 -#define WL_DFS_VAL 0x01000000 -#define WL_BA_VAL 0x02000000 -#define WL_ACI_VAL 0x04000000 -#define WL_MBSS_VAL 0x04000000 -#define WL_CAC_VAL 0x08000000 -#define WL_AMSDU_VAL 0x10000000 -#define WL_AMPDU_VAL 0x20000000 -#define WL_FFPLD_VAL 0x40000000 - - -#define WL_DPT_VAL 0x00000001 -#define WL_SCAN_VAL 0x00000002 -#define WL_WOWL_VAL 0x00000004 -#define WL_COEX_VAL 0x00000008 -#define WL_RTDC_VAL 0x00000010 -#define WL_PROTO_VAL 0x00000020 -#define WL_BTA_VAL 0x00000040 -#define WL_CHANINT_VAL 0x00000080 -#define WL_THERMAL_VAL 0x00000100 -#define WL_P2P_VAL 0x00000200 -#define WL_TXRX_VAL 0x00000400 -#define WL_MCHAN_VAL 0x00000800 -#define WL_TDLS_VAL 0x00001000 - - -#define WL_LED_NUMGPIO 16 - - -#define WL_LED_OFF 0 -#define WL_LED_ON 1 -#define WL_LED_ACTIVITY 2 -#define WL_LED_RADIO 3 -#define WL_LED_ARADIO 4 -#define WL_LED_BRADIO 5 -#define WL_LED_BGMODE 6 -#define WL_LED_WI1 7 -#define WL_LED_WI2 8 -#define WL_LED_WI3 9 -#define WL_LED_ASSOC 10 -#define WL_LED_INACTIVE 11 -#define WL_LED_ASSOCACT 12 -#define WL_LED_WI4 13 -#define WL_LED_WI5 14 -#define WL_LED_BLINKSLOW 15 -#define WL_LED_BLINKMED 16 -#define WL_LED_BLINKFAST 17 -#define WL_LED_BLINKCUSTOM 18 -#define WL_LED_BLINKPERIODIC 19 -#define WL_LED_ASSOC_WITH_SEC 20 - -#define WL_LED_START_OFF 21 -#define WL_LED_NUMBEHAVIOR 22 - +/* RSSI per antenna */ +typedef struct { + uint32 version; /* version field */ + uint32 count; /* number of valid antenna rssi */ + int8 rssi_ant[WL_RSSI_ANT_MAX]; /* rssi per antenna */ +} wl_rssi_ant_t; -#define WL_LED_BEH_MASK 0x7f -#define WL_LED_AL_MASK 0x80 +/* dfs_status iovar-related defines */ +/* cac - channel availability check, + * ism - in-service monitoring + * csa - channel switching announcement + */ -#define WL_NUMCHANNELS 64 -#define WL_NUMCHANSPECS 100 +/* cac state values */ +#define WL_DFS_CACSTATE_IDLE 0 /* state for operating in non-radar channel */ +#define WL_DFS_CACSTATE_PREISM_CAC 1 /* CAC in progress */ +#define WL_DFS_CACSTATE_ISM 2 /* ISM in progress */ +#define WL_DFS_CACSTATE_CSA 3 /* csa */ +#define WL_DFS_CACSTATE_POSTISM_CAC 4 /* ISM CAC */ +#define WL_DFS_CACSTATE_PREISM_OOC 5 /* PREISM OOC */ +#define WL_DFS_CACSTATE_POSTISM_OOC 6 /* POSTISM OOC */ +#define WL_DFS_CACSTATES 7 /* this many states exist */ + +/* data structure used in 'dfs_status' wl interface, which is used to query dfs status */ +typedef struct { + uint state; /* noted by WL_DFS_CACSTATE_XX. */ + uint duration; /* time spent in ms in state. */ + /* as dfs enters ISM state, it removes the operational channel from quiet channel + * list and notes the channel in channel_cleared. set to 0 if no channel is cleared + */ + chanspec_t chanspec_cleared; + /* chanspec cleared used to be a uint, add another to uint16 to maintain size */ + uint16 pad; +} wl_dfs_status_t; + +#define NUM_PWRCTRL_RATES 12 +typedef struct { + uint8 txpwr_band_max[NUM_PWRCTRL_RATES]; /* User set target */ + uint8 txpwr_limit[NUM_PWRCTRL_RATES]; /* reg and local power limit */ + uint8 txpwr_local_max; /* local max according to the AP */ + uint8 txpwr_local_constraint; /* local constraint according to the AP */ + uint8 txpwr_chan_reg_max; /* Regulatory max for this channel */ + uint8 txpwr_target[2][NUM_PWRCTRL_RATES]; /* Latest target for 2.4 and 5 Ghz */ + uint8 txpwr_est_Pout[2]; /* Latest estimate for 2.4 and 5 Ghz */ + uint8 txpwr_opo[NUM_PWRCTRL_RATES]; /* On G phy, OFDM power offset */ + uint8 txpwr_bphy_cck_max[NUM_PWRCTRL_RATES]; /* Max CCK power for this band (SROM) */ + uint8 txpwr_bphy_ofdm_max; /* Max OFDM power for this band (SROM) */ + uint8 txpwr_aphy_max[NUM_PWRCTRL_RATES]; /* Max power for A band (SROM) */ + int8 txpwr_antgain[2]; /* Ant gain for each band - from SROM */ + uint8 txpwr_est_Pout_gofdm; /* Pwr estimate for 2.4 OFDM */ +} tx_power_legacy_t; + +#define WL_TX_POWER_RATES_LEGACY 45 +#define WL_TX_POWER_MCS20_FIRST 12 +#define WL_TX_POWER_MCS20_NUM 16 +#define WL_TX_POWER_MCS40_FIRST 28 +#define WL_TX_POWER_MCS40_NUM 17 -#define WL_WDS_WPA_ROLE_AUTH 0 -#define WL_WDS_WPA_ROLE_SUP 1 -#define WL_WDS_WPA_ROLE_AUTO 255 +typedef struct { + uint32 flags; + chanspec_t chanspec; /* txpwr report for this channel */ + chanspec_t local_chanspec; /* channel on which we are associated */ + uint8 local_max; /* local max according to the AP */ + uint8 local_constraint; /* local constraint according to the AP */ + int8 antgain[2]; /* Ant gain for each band - from SROM */ + uint8 rf_cores; /* count of RF Cores being reported */ + uint8 est_Pout[4]; /* Latest tx power out estimate per RF + * chain without adjustment + */ + uint8 est_Pout_cck; /* Latest CCK tx power out estimate */ + uint8 user_limit[WL_TX_POWER_RATES_LEGACY]; /* User limit */ + uint8 reg_limit[WL_TX_POWER_RATES_LEGACY]; /* Regulatory power limit */ + uint8 board_limit[WL_TX_POWER_RATES_LEGACY]; /* Max power board can support (SROM) */ + uint8 target[WL_TX_POWER_RATES_LEGACY]; /* Latest target power */ +} tx_power_legacy2_t; + +/* TX Power index defines */ +#define WL_NUM_RATES_CCK 4 /* 1, 2, 5.5, 11 Mbps */ +#define WL_NUM_RATES_OFDM 8 /* 6, 9, 12, 18, 24, 36, 48, 54 Mbps SISO/CDD */ +#define WL_NUM_RATES_MCS_1STREAM 8 /* MCS 0-7 1-stream rates - SISO/CDD/STBC/MCS */ +#define WL_NUM_RATES_EXTRA_VHT 2 /* Additional VHT 11AC rates */ +#define WL_NUM_RATES_MCS32 1 + +#define WLC_NUM_RATES_CCK WL_NUM_RATES_CCK +#define WLC_NUM_RATES_OFDM WL_NUM_RATES_OFDM +#define WLC_NUM_RATES_MCS_1_STREAM WL_NUM_RATES_MCS_1STREAM +#define WLC_NUM_RATES_MCS_2_STREAM WL_NUM_RATES_MCS_1STREAM +#define WLC_NUM_RATES_MCS32 WL_NUM_RATES_MCS32 +#define WL_TX_POWER_CCK_NUM WL_NUM_RATES_CCK +#define WL_TX_POWER_OFDM_NUM WL_NUM_RATES_OFDM +#define WL_TX_POWER_MCS_1_STREAM_NUM WL_NUM_RATES_MCS_1STREAM +#define WL_TX_POWER_MCS_2_STREAM_NUM WL_NUM_RATES_MCS_1STREAM +#define WL_TX_POWER_MCS_32_NUM WL_NUM_RATES_MCS32 + +#define WL_NUM_2x2_ELEMENTS 4 +#define WL_NUM_3x3_ELEMENTS 6 + +typedef struct txppr { + /* start of 20MHz tx power limits */ + uint8 b20_1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ + uint8 b20_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */ + uint8 b20_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */ + + uint8 b20_1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ + uint8 b20_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ + uint8 b20_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */ + uint8 b20_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ + uint8 b20_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */ + + uint8 b20_1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ + uint8 b20_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ + uint8 b20_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */ + uint8 b20_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ + uint8 b20_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */ + uint8 b20_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */ + + uint8 b20_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */ + uint8 b20_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */ + uint8 b20_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */ + uint8 b20_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */ + uint8 b20_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */ + uint8 b20_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */ + uint8 b20_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */ + uint8 b20_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */ + + /* start of 40MHz tx power limits */ + uint8 b40_dummy1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ + uint8 b40_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */ + uint8 b40_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */ + + uint8 b40_dummy1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ + uint8 b40_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ + uint8 b40_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */ + uint8 b40_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ + uint8 b40_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */ + + uint8 b40_dummy1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ + uint8 b40_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ + uint8 b40_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */ + uint8 b40_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ + uint8 b40_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */ + uint8 b40_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */ + + uint8 b40_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */ + uint8 b40_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */ + uint8 b40_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */ + uint8 b40_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */ + uint8 b40_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */ + uint8 b40_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */ + uint8 b40_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */ + uint8 b40_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */ + + /* start of 20in40MHz tx power limits */ + uint8 b20in40_1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ + uint8 b20in40_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */ + uint8 b20in40_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */ + + uint8 b20in40_1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ + uint8 b20in40_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ + uint8 b20in40_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */ + uint8 b20in40_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ + uint8 b20in40_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */ + + uint8 b20in40_1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ + uint8 b20in40_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* 20 in 40 MHz Legacy OFDM CDD */ + uint8 b20in40_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */ + uint8 b20in40_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ + uint8 b20in40_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */ + uint8 b20in40_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */ + + uint8 b20in40_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */ + uint8 b20in40_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */ + uint8 b20in40_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */ + uint8 b20in40_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */ + uint8 b20in40_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */ + uint8 b20in40_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */ + uint8 b20in40_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */ + uint8 b20in40_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */ + + /* start of 80MHz tx power limits */ + uint8 b80_dummy1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ + uint8 b80_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */ + uint8 b80_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */ + + uint8 b80_dummy1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ + uint8 b80_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ + uint8 b80_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */ + uint8 b80_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ + uint8 b80_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */ + + uint8 b80_dummy1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ + uint8 b80_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ + uint8 b80_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */ + uint8 b80_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ + uint8 b80_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */ + uint8 b80_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */ + + uint8 b80_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */ + uint8 b80_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */ + uint8 b80_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */ + uint8 b80_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */ + uint8 b80_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */ + uint8 b80_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */ + uint8 b80_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */ + uint8 b80_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */ + + /* start of 20in80MHz tx power limits */ + uint8 b20in80_1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ + uint8 b20in80_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */ + uint8 b20in80_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */ + + uint8 b20in80_1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ + uint8 b20in80_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ + uint8 b20in80_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */ + uint8 b20in80_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ + uint8 b20in80_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */ + + uint8 b20in80_1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ + uint8 b20in80_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ + uint8 b20in80_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */ + uint8 b20in80_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ + uint8 b20in80_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */ + uint8 b20in80_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */ + + uint8 b20in80_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */ + uint8 b20in80_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */ + uint8 b20in80_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */ + uint8 b20in80_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */ + uint8 b20in80_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */ + uint8 b20in80_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */ + uint8 b20in80_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */ + uint8 b20in80_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */ + + /* start of 40in80MHz tx power limits */ + uint8 b40in80_dummy1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ + uint8 b40in80_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */ + uint8 b40in80_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */ + + uint8 b40in80_dummy1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ + uint8 b40in80_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ + uint8 b40in80_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */ + uint8 b40in80_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ + uint8 b40in80_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */ + + uint8 b40in80_dummy1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ + uint8 b40in80_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* MHz Legacy OFDM CDD */ + uint8 b40in80_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */ + uint8 b40in80_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ + uint8 b40in80_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */ + uint8 b40in80_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */ + + uint8 b40in80_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */ + uint8 b40in80_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */ + uint8 b40in80_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */ + uint8 b40in80_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */ + uint8 b40in80_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */ + uint8 b40in80_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */ + uint8 b40in80_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */ + uint8 b40in80_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */ + + uint8 mcs32; /* C_CHECK - THIS NEEDS TO BE REMOVED THROUGHOUT THE CODE */ +} txppr_t; + +/* 20MHz */ +#define WL_TX_POWER_CCK_FIRST OFFSETOF(txppr_t, b20_1x1dsss) +#define WL_TX_POWER_OFDM20_FIRST OFFSETOF(txppr_t, b20_1x1ofdm) +#define WL_TX_POWER_MCS20_SISO_FIRST OFFSETOF(txppr_t, b20_1x1mcs0) +#define WL_TX_POWER_20_S1x1_FIRST OFFSETOF(txppr_t, b20_1x1mcs0) + +#define WL_TX_POWER_CCK_CDD_S1x2_FIRST OFFSETOF(txppr_t, b20_1x2dsss) +#define WL_TX_POWER_OFDM20_CDD_FIRST OFFSETOF(txppr_t, b20_1x2cdd_ofdm) +#define WL_TX_POWER_MCS20_CDD_FIRST OFFSETOF(txppr_t, b20_1x2cdd_mcs0) +#define WL_TX_POWER_20_S1x2_FIRST OFFSETOF(txppr_t, b20_1x2cdd_mcs0) +#define WL_TX_POWER_MCS20_STBC_FIRST OFFSETOF(txppr_t, b20_2x2stbc_mcs0) +#define WL_TX_POWER_MCS20_SDM_FIRST OFFSETOF(txppr_t, b20_2x2sdm_mcs8) +#define WL_TX_POWER_20_S2x2_FIRST OFFSETOF(txppr_t, b20_2x2sdm_mcs8) + +#define WL_TX_POWER_CCK_CDD_S1x3_FIRST OFFSETOF(txppr_t, b20_1x3dsss) +#define WL_TX_POWER_OFDM20_CDD_S1x3_FIRST OFFSETOF(txppr_t, b20_1x3cdd_ofdm) +#define WL_TX_POWER_20_S1x3_FIRST OFFSETOF(txppr_t, b20_1x3cdd_mcs0) +#define WL_TX_POWER_20_STBC_S2x3_FIRST OFFSETOF(txppr_t, b20_2x3stbc_mcs0) +#define WL_TX_POWER_20_S2x3_FIRST OFFSETOF(txppr_t, b20_2x3sdm_mcs8) +#define WL_TX_POWER_20_S3x3_FIRST OFFSETOF(txppr_t, b20_3x3sdm_mcs16) + +#define WL_TX_POWER_20_S1X1_VHT OFFSETOF(txppr_t, b20_1x1vht) +#define WL_TX_POWER_20_S1X2_CDD_VHT OFFSETOF(txppr_t, b20_1x2cdd_vht) +#define WL_TX_POWER_20_S2X2_STBC_VHT OFFSETOF(txppr_t, b20_2x2stbc_vht) +#define WL_TX_POWER_20_S2X2_VHT OFFSETOF(txppr_t, b20_2x2sdm_vht) +#define WL_TX_POWER_20_S1X3_CDD_VHT OFFSETOF(txppr_t, b20_1x3cdd_vht) +#define WL_TX_POWER_20_S2X3_STBC_VHT OFFSETOF(txppr_t, b20_2x3stbc_vht) +#define WL_TX_POWER_20_S2X3_VHT OFFSETOF(txppr_t, b20_2x3sdm_vht) +#define WL_TX_POWER_20_S3X3_VHT OFFSETOF(txppr_t, b20_3x3sdm_vht) + +/* 40MHz */ +#define WL_TX_POWER_40_DUMMY_CCK_FIRST OFFSETOF(txppr_t, b40_dummy1x1dsss) +#define WL_TX_POWER_OFDM40_FIRST OFFSETOF(txppr_t, b40_1x1ofdm) +#define WL_TX_POWER_MCS40_SISO_FIRST OFFSETOF(txppr_t, b40_1x1mcs0) +#define WL_TX_POWER_40_S1x1_FIRST OFFSETOF(txppr_t, b40_1x1mcs0) + +#define WL_TX_POWER_40_DUMMY_CCK_CDD_S1x2_FIRST OFFSETOF(txppr_t, b40_dummy1x2dsss) +#define WL_TX_POWER_OFDM40_CDD_FIRST OFFSETOF(txppr_t, b40_1x2cdd_ofdm) +#define WL_TX_POWER_MCS40_CDD_FIRST OFFSETOF(txppr_t, b40_1x2cdd_mcs0) +#define WL_TX_POWER_40_S1x2_FIRST OFFSETOF(txppr_t, b40_1x2cdd_mcs0) +#define WL_TX_POWER_MCS40_STBC_FIRST OFFSETOF(txppr_t, b40_2x2stbc_mcs0) +#define WL_TX_POWER_MCS40_SDM_FIRST OFFSETOF(txppr_t, b40_2x2sdm_mcs8) +#define WL_TX_POWER_40_S2x2_FIRST OFFSETOF(txppr_t, b40_2x2sdm_mcs8) + +#define WL_TX_POWER_40_DUMMY_CCK_CDD_S1x3_FIRST OFFSETOF(txppr_t, b40_dummy1x3dsss) +#define WL_TX_POWER_OFDM40_CDD_S1x3_FIRST OFFSETOF(txppr_t, b40_1x3cdd_ofdm) +#define WL_TX_POWER_40_S1x3_FIRST OFFSETOF(txppr_t, b40_1x3cdd_mcs0) +#define WL_TX_POWER_40_STBC_S2x3_FIRST OFFSETOF(txppr_t, b40_2x3stbc_mcs0) +#define WL_TX_POWER_40_S2x3_FIRST OFFSETOF(txppr_t, b40_2x3sdm_mcs8) +#define WL_TX_POWER_40_S3x3_FIRST OFFSETOF(txppr_t, b40_3x3sdm_mcs16) + +#define WL_TX_POWER_40_S1X1_VHT OFFSETOF(txppr_t, b40_1x1vht) +#define WL_TX_POWER_40_S1X2_CDD_VHT OFFSETOF(txppr_t, b40_1x2cdd_vht) +#define WL_TX_POWER_40_S2X2_STBC_VHT OFFSETOF(txppr_t, b40_2x2stbc_vht) +#define WL_TX_POWER_40_S2X2_VHT OFFSETOF(txppr_t, b40_2x2sdm_vht) +#define WL_TX_POWER_40_S1X3_CDD_VHT OFFSETOF(txppr_t, b40_1x3cdd_vht) +#define WL_TX_POWER_40_S2X3_STBC_VHT OFFSETOF(txppr_t, b40_2x3stbc_vht) +#define WL_TX_POWER_40_S2X3_VHT OFFSETOF(txppr_t, b40_2x3sdm_vht) +#define WL_TX_POWER_40_S3X3_VHT OFFSETOF(txppr_t, b40_3x3sdm_vht) + +/* 20 in 40MHz */ +#define WL_TX_POWER_20UL_CCK_FIRST OFFSETOF(txppr_t, b20in40_1x1dsss) +#define WL_TX_POWER_20UL_OFDM_FIRST OFFSETOF(txppr_t, b20in40_1x1ofdm) +#define WL_TX_POWER_20UL_S1x1_FIRST OFFSETOF(txppr_t, b20in40_1x1mcs0) + +#define WL_TX_POWER_CCK_20U_CDD_S1x2_FIRST OFFSETOF(txppr_t, b20in40_1x2dsss) +#define WL_TX_POWER_20UL_OFDM_CDD_FIRST OFFSETOF(txppr_t, b20in40_1x2cdd_ofdm) +#define WL_TX_POWER_20UL_S1x2_FIRST OFFSETOF(txppr_t, b20in40_1x2cdd_mcs0) +#define WL_TX_POWER_20UL_STBC_S2x2_FIRST OFFSETOF(txppr_t, b20in40_2x2stbc_mcs0) +#define WL_TX_POWER_20UL_S2x2_FIRST OFFSETOF(txppr_t, b20in40_2x2sdm_mcs8) + +#define WL_TX_POWER_CCK_20U_CDD_S1x3_FIRST OFFSETOF(txppr_t, b20in40_1x3dsss) +#define WL_TX_POWER_20UL_OFDM_CDD_S1x3_FIRST OFFSETOF(txppr_t, b20in40_1x3cdd_ofdm) +#define WL_TX_POWER_20UL_S1x3_FIRST OFFSETOF(txppr_t, b20in40_1x3cdd_mcs0) +#define WL_TX_POWER_20UL_STBC_S2x3_FIRST OFFSETOF(txppr_t, b20in40_2x3stbc_mcs0) +#define WL_TX_POWER_20UL_S2x3_FIRST OFFSETOF(txppr_t, b20in40_2x3sdm_mcs8) +#define WL_TX_POWER_20UL_S3x3_FIRST OFFSETOF(txppr_t, b20in40_3x3sdm_mcs16) + +#define WL_TX_POWER_20UL_S1X1_VHT OFFSETOF(txppr_t, b20in40_1x1vht) +#define WL_TX_POWER_20UL_S1X2_CDD_VHT OFFSETOF(txppr_t, b20in40_1x2cdd_vht) +#define WL_TX_POWER_20UL_S2X2_STBC_VHT OFFSETOF(txppr_t, b20in40_2x2stbc_vht) +#define WL_TX_POWER_20UL_S2X2_VHT OFFSETOF(txppr_t, b20in40_2x2sdm_vht) +#define WL_TX_POWER_20UL_S1X3_CDD_VHT OFFSETOF(txppr_t, b20in40_1x3cdd_vht) +#define WL_TX_POWER_20UL_S2X3_STBC_VHT OFFSETOF(txppr_t, b20in40_2x3stbc_vht) +#define WL_TX_POWER_20UL_S2X3_VHT OFFSETOF(txppr_t, b20in40_2x3sdm_vht) +#define WL_TX_POWER_20UL_S3X3_VHT OFFSETOF(txppr_t, b20in40_3x3sdm_vht) + +/* 80MHz */ +#define WL_TX_POWER_80_DUMMY_CCK_FIRST OFFSETOF(txppr_t, b80_dummy1x1dsss) +#define WL_TX_POWER_OFDM80_FIRST OFFSETOF(txppr_t, b80_1x1ofdm) +#define WL_TX_POWER_MCS80_SISO_FIRST OFFSETOF(txppr_t, b80_1x1mcs0) +#define WL_TX_POWER_80_S1x1_FIRST OFFSETOF(txppr_t, b80_1x1mcs0) + +#define WL_TX_POWER_80_DUMMY_CCK_CDD_S1x2_FIRST OFFSETOF(txppr_t, b80_dummy1x2dsss) +#define WL_TX_POWER_OFDM80_CDD_FIRST OFFSETOF(txppr_t, b80_1x2cdd_ofdm) +#define WL_TX_POWER_MCS80_CDD_FIRST OFFSETOF(txppr_t, b80_1x2cdd_mcs0) +#define WL_TX_POWER_80_S1x2_FIRST OFFSETOF(txppr_t, b80_1x2cdd_mcs0) +#define WL_TX_POWER_MCS80_STBC_FIRST OFFSETOF(txppr_t, b80_2x2stbc_mcs0) +#define WL_TX_POWER_MCS80_SDM_FIRST OFFSETOF(txppr_t, b80_2x2sdm_mcs8) +#define WL_TX_POWER_80_S2x2_FIRST OFFSETOF(txppr_t, b80_2x2sdm_mcs8) + +#define WL_TX_POWER_80_DUMMY_CCK_CDD_S1x3_FIRST OFFSETOF(txppr_t, b80_dummy1x3dsss) +#define WL_TX_POWER_OFDM80_CDD_S1x3_FIRST OFFSETOF(txppr_t, b80_1x3cdd_ofdm) +#define WL_TX_POWER_80_S1x3_FIRST OFFSETOF(txppr_t, b80_1x3cdd_mcs0) +#define WL_TX_POWER_80_STBC_S2x3_FIRST OFFSETOF(txppr_t, b80_2x3stbc_mcs0) +#define WL_TX_POWER_80_S2x3_FIRST OFFSETOF(txppr_t, b80_2x3sdm_mcs8) +#define WL_TX_POWER_80_S3x3_FIRST OFFSETOF(txppr_t, b80_3x3sdm_mcs16) + +#define WL_TX_POWER_80_S1X1_VHT OFFSETOF(txppr_t, b80_1x1vht) +#define WL_TX_POWER_80_S1X2_CDD_VHT OFFSETOF(txppr_t, b80_1x2cdd_vht) +#define WL_TX_POWER_80_S2X2_STBC_VHT OFFSETOF(txppr_t, b80_2x2stbc_vht) +#define WL_TX_POWER_80_S2X2_VHT OFFSETOF(txppr_t, b80_2x2sdm_vht) +#define WL_TX_POWER_80_S1X3_CDD_VHT OFFSETOF(txppr_t, b80_1x3cdd_vht) +#define WL_TX_POWER_80_S2X3_STBC_VHT OFFSETOF(txppr_t, b80_2x3stbc_vht) +#define WL_TX_POWER_80_S2X3_VHT OFFSETOF(txppr_t, b80_2x3sdm_vht) +#define WL_TX_POWER_80_S3X3_VHT OFFSETOF(txppr_t, b80_3x3sdm_vht) + +/* 20 in 80MHz */ +#define WL_TX_POWER_20UUL_CCK_FIRST OFFSETOF(txppr_t, b20in80_1x1dsss) +#define WL_TX_POWER_20UUL_OFDM_FIRST OFFSETOF(txppr_t, b20in80_1x1ofdm) +#define WL_TX_POWER_20UUL_S1x1_FIRST OFFSETOF(txppr_t, b20in80_1x1mcs0) + +#define WL_TX_POWER_CCK_20UU_CDD_S1x2_FIRST OFFSETOF(txppr_t, b20in80_1x2dsss) +#define WL_TX_POWER_20UUL_OFDM_CDD_FIRST OFFSETOF(txppr_t, b20in80_1x2cdd_ofdm) +#define WL_TX_POWER_20UUL_S1x2_FIRST OFFSETOF(txppr_t, b20in80_1x2cdd_mcs0) +#define WL_TX_POWER_20UUL_STBC_S2x2_FIRST OFFSETOF(txppr_t, b20in80_2x2stbc_mcs0) +#define WL_TX_POWER_20UUL_S2x2_FIRST OFFSETOF(txppr_t, b20in80_2x2sdm_mcs8) + +#define WL_TX_POWER_CCK_20UU_CDD_S1x3_FIRST OFFSETOF(txppr_t, b20in80_1x3dsss) +#define WL_TX_POWER_20UUL_OFDM_CDD_S1x3_FIRST OFFSETOF(txppr_t, b20in80_1x3cdd_ofdm) +#define WL_TX_POWER_20UUL_S1x3_FIRST OFFSETOF(txppr_t, b20in80_1x3cdd_mcs0) +#define WL_TX_POWER_20UUL_STBC_S2x3_FIRST OFFSETOF(txppr_t, b20in80_2x3stbc_mcs0) +#define WL_TX_POWER_20UUL_S2x3_FIRST OFFSETOF(txppr_t, b20in80_2x3sdm_mcs8) +#define WL_TX_POWER_20UUL_S3x3_FIRST OFFSETOF(txppr_t, b20in80_3x3sdm_mcs16) + +#define WL_TX_POWER_20UUL_S1X1_VHT OFFSETOF(txppr_t, b20in80_1x1vht) +#define WL_TX_POWER_20UUL_S1X2_CDD_VHT OFFSETOF(txppr_t, b20in80_1x2cdd_vht) +#define WL_TX_POWER_20UUL_S2X2_STBC_VHT OFFSETOF(txppr_t, b20in80_2x2stbc_vht) +#define WL_TX_POWER_20UUL_S2X2_VHT OFFSETOF(txppr_t, b20in80_2x2sdm_vht) +#define WL_TX_POWER_20UUL_S1X3_CDD_VHT OFFSETOF(txppr_t, b20in80_1x3cdd_vht) +#define WL_TX_POWER_20UUL_S2X3_STBC_VHT OFFSETOF(txppr_t, b20in80_2x3stbc_vht) +#define WL_TX_POWER_20UUL_S2X3_VHT OFFSETOF(txppr_t, b20in80_2x3sdm_vht) +#define WL_TX_POWER_20UUL_S3X3_VHT OFFSETOF(txppr_t, b20in80_3x3sdm_vht) + +/* 40 in 80MHz */ +#define WL_TX_POWER_40UUL_DUMMY_CCK_FIRST OFFSETOF(txppr_t, b40in80_dummy1x1dsss) +#define WL_TX_POWER_40UUL_OFDM_FIRST OFFSETOF(txppr_t, b40in80_1x1ofdm) +#define WL_TX_POWER_40UUL_S1x1_FIRST OFFSETOF(txppr_t, b40in80_1x1mcs0) + +#define WL_TX_POWER_CCK_40UU_DUMMY_CDD_S1x2_FIRST OFFSETOF(txppr_t, b40in80_dummy1x2dsss) +#define WL_TX_POWER_40UUL_OFDM_CDD_FIRST OFFSETOF(txppr_t, b40in80_1x2cdd_ofdm) +#define WL_TX_POWER_40UUL_S1x2_FIRST OFFSETOF(txppr_t, b40in80_1x2cdd_mcs0) +#define WL_TX_POWER_40UUL_STBC_S2x2_FIRST OFFSETOF(txppr_t, b40in80_2x2stbc_mcs0) +#define WL_TX_POWER_40UUL_S2x2_FIRST OFFSETOF(txppr_t, b40in80_2x2sdm_mcs8) + +#define WL_TX_POWER_CCK_40UU_DUMMY_CDD_S1x3_FIRST OFFSETOF(txppr_t, b40in80_dummy1x3dsss) +#define WL_TX_POWER_40UUL_OFDM_CDD_S1x3_FIRST OFFSETOF(txppr_t, b40in80_1x3cdd_ofdm) +#define WL_TX_POWER_40UUL_S1x3_FIRST OFFSETOF(txppr_t, b40in80_1x3cdd_mcs0) +#define WL_TX_POWER_40UUL_STBC_S2x3_FIRST OFFSETOF(txppr_t, b40in80_2x3stbc_mcs0) +#define WL_TX_POWER_40UUL_S2x3_FIRST OFFSETOF(txppr_t, b40in80_2x3sdm_mcs8) +#define WL_TX_POWER_40UUL_S3x3_FIRST OFFSETOF(txppr_t, b40in80_3x3sdm_mcs16) + +#define WL_TX_POWER_40UUL_S1X1_VHT OFFSETOF(txppr_t, b40in80_1x1vht) +#define WL_TX_POWER_40UUL_S1X2_CDD_VHT OFFSETOF(txppr_t, b40in80_1x2cdd_vht) +#define WL_TX_POWER_40UUL_S2X2_STBC_VHT OFFSETOF(txppr_t, b40in80_2x2stbc_vht) +#define WL_TX_POWER_40UUL_S2X2_VHT OFFSETOF(txppr_t, b40in80_2x2sdm_vht) +#define WL_TX_POWER_40UUL_S1X3_CDD_VHT OFFSETOF(txppr_t, b40in80_1x3cdd_vht) +#define WL_TX_POWER_40UUL_S2X3_STBC_VHT OFFSETOF(txppr_t, b40in80_2x3stbc_vht) +#define WL_TX_POWER_40UUL_S2X3_VHT OFFSETOF(txppr_t, b40in80_2x3sdm_vht) +#define WL_TX_POWER_40UUL_S3X3_VHT OFFSETOF(txppr_t, b40in80_3x3sdm_vht) + +#define WL_TX_POWER_MCS_32 OFFSETOF(txppr_t, mcs32) /* C_CHECK remove later */ + +#define WL_TX_POWER_RATES sizeof(struct txppr) + +/* sslpnphy specifics */ +#define WL_TX_POWER_MCS20_SISO_FIRST_SSN WL_TX_POWER_MCS20_SISO_FIRST +#define WL_TX_POWER_MCS40_SISO_FIRST_SSN WL_TX_POWER_MCS40_SISO_FIRST + +/* tx_power_t.flags bits */ +#define WL_TX_POWER_F_ENABLED 1 +#define WL_TX_POWER_F_HW 2 +#define WL_TX_POWER_F_MIMO 4 +#define WL_TX_POWER_F_SISO 8 +#define WL_TX_POWER_F_HT 0x10 +typedef struct { + uint16 ver; /* version of this struct */ + uint16 len; /* length in bytes of this structure */ + uint32 flags; + chanspec_t chanspec; /* txpwr report for this channel */ + chanspec_t local_chanspec; /* channel on which we are associated */ + uint8 ppr[WL_TX_POWER_RATES]; /* Latest target power */ +} wl_txppr_t; -#define WL_EVENTING_MASK_LEN 16 +#define WL_TXPPR_VERSION 0 +#define WL_TXPPR_LENGTH (sizeof(wl_txppr_t)) +#define WL_CLM_NUM_RATES 116 /* must be the same as CLM_NUMRATES */ +#define TX_POWER_T_VERSION 43 +/* Defines used with channel_bandwidth for curpower */ +#define WL_BW_20MHZ 0 +#define WL_BW_40MHZ 1 +#define WL_BW_80MHZ 2 +typedef struct { + uint32 flags; + chanspec_t chanspec; /* txpwr report for this channel */ + chanspec_t local_chanspec; /* channel on which we are associated */ + uint8 local_max; /* local max according to the AP */ + uint8 local_constraint; /* local constraint according to the AP */ + int8 antgain[2]; /* Ant gain for each band - from SROM */ + uint8 rf_cores; /* count of RF Cores being reported */ + uint8 est_Pout[4]; /* Latest tx power out estimate per RF chain */ + uint8 est_Pout_act[4]; /* Latest tx power out estimate per RF chain + * without adjustment + */ + uint8 est_Pout_cck; /* Latest CCK tx power out estimate */ + uint8 tx_power_max[4]; /* Maximum target power among all rates */ + uint tx_power_max_rate_ind[4]; /* Index of the rate with the max target power */ + uint8 user_limit[WL_TX_POWER_RATES]; /* User limit */ + int8 board_limit[WL_TX_POWER_RATES]; /* Max power board can support (SROM) */ + int8 target[WL_TX_POWER_RATES]; /* Latest target power */ + int8 clm_limits[WL_CLM_NUM_RATES]; /* regulatory limits - 20, 40 or 80MHz */ + int8 clm_limits_subchan1[WL_CLM_NUM_RATES]; /* regulatory limits - 20in40 or 40in80 */ + int8 clm_limits_subchan2[WL_CLM_NUM_RATES]; /* regulatory limits - 20in80MHz */ + int8 sar; /* SAR limit for display by wl executable */ + int8 channel_bandwidth; /* 20, 40 or 80 MHz bandwidth? */ + uint8 version; /* Version of the data format wlu <--> driver */ +} tx_power_t; + +typedef struct tx_inst_power { + uint8 txpwr_est_Pout[2]; /* Latest estimate for 2.4 and 5 Ghz */ + uint8 txpwr_est_Pout_gofdm; /* Pwr estimate for 2.4 OFDM */ +} tx_inst_power_t; -#define WL_JOIN_PREF_RSSI 1 -#define WL_JOIN_PREF_WPA 2 -#define WL_JOIN_PREF_BAND 3 -#define WL_JOIN_PREF_RSSI_DELTA 4 -#define WL_JOIN_PREF_TRANS_PREF 5 +typedef struct { + uint32 flags; + chanspec_t chanspec; /* txpwr report for this channel */ + chanspec_t local_chanspec; /* channel on which we are associated */ + uint8 local_max; /* local max according to the AP */ + uint8 local_constraint; /* local constraint according to the AP */ + int8 antgain[2]; /* Ant gain for each band - from SROM */ + uint8 rf_cores; /* count of RF Cores being reported */ + uint8 est_Pout[4]; /* Latest tx power out estimate per RF chain */ + uint8 est_Pout_act[4]; /* Latest tx power out estimate per RF chain + * without adjustment + */ + uint8 est_Pout_cck; /* Latest CCK tx power out estimate */ + uint8 tx_power_max[4]; /* Maximum target power among all rates */ + uint tx_power_max_rate_ind[4]; /* Index of the rate with the max target power */ + txppr_t user_limit; /* User limit */ + txppr_t reg_limit; /* Regulatory power limit */ + txppr_t board_limit; /* Max power board can support (SROM) */ + txppr_t target; /* Latest target power */ +} wl_txpwr_t; + +#define WL_NUM_TXCHAIN_MAX 4 +typedef struct wl_txchain_pwr_offsets { + int8 offset[WL_NUM_TXCHAIN_MAX]; /* quarter dBm signed offset for each chain */ +} wl_txchain_pwr_offsets_t; + +/* 802.11h measurement types */ +#define WLC_MEASURE_TPC 1 +#define WLC_MEASURE_CHANNEL_BASIC 2 +#define WLC_MEASURE_CHANNEL_CCA 3 +#define WLC_MEASURE_CHANNEL_RPI 4 + +/* regulatory enforcement levels */ +#define SPECT_MNGMT_OFF 0 /* both 11h and 11d disabled */ +#define SPECT_MNGMT_LOOSE_11H 1 /* allow non-11h APs in scan lists */ +#define SPECT_MNGMT_STRICT_11H 2 /* prune out non-11h APs from scan list */ +#define SPECT_MNGMT_STRICT_11D 3 /* switch to 802.11D mode */ +/* SPECT_MNGMT_LOOSE_11H_D - same as SPECT_MNGMT_LOOSE with the exception that Country IE + * adoption is done regardless of capability spectrum_management + */ +#define SPECT_MNGMT_LOOSE_11H_D 4 /* operation defined above */ + +#define WL_CHAN_VALID_HW (1 << 0) /* valid with current HW */ +#define WL_CHAN_VALID_SW (1 << 1) /* valid with current country setting */ +#define WL_CHAN_BAND_5G (1 << 2) /* 5GHz-band channel */ +#define WL_CHAN_RADAR (1 << 3) /* radar sensitive channel */ +#define WL_CHAN_INACTIVE (1 << 4) /* temporarily inactive due to radar */ +#define WL_CHAN_PASSIVE (1 << 5) /* channel is in passive mode */ +#define WL_CHAN_RESTRICTED (1 << 6) /* restricted use channel */ + +/* BTC mode used by "btc_mode" iovar */ +#define WL_BTC_DISABLE 0 /* disable BT coexistence */ +#define WL_BTC_FULLTDM 1 /* full TDM COEX */ +#define WL_BTC_ENABLE 1 /* full TDM COEX to maintain backward compatiblity */ +#define WL_BTC_PREMPT 2 /* full TDM COEX with preemption */ +#define WL_BTC_LITE 3 /* light weight coex for large isolation platform */ +#define WL_BTC_PARALLEL 4 /* BT and WLAN run in parallel with separate antenna */ +#define WL_BTC_HYBRID 5 /* hybrid coex, only ack is allowed to transmit in BT slot */ +#define WL_BTC_DEFAULT 8 /* set the default mode for the device */ +#define WL_INF_BTC_DISABLE 0 +#define WL_INF_BTC_ENABLE 1 +#define WL_INF_BTC_AUTO 3 + +/* BTC wire used by "btc_wire" iovar */ +#define WL_BTC_DEFWIRE 0 /* use default wire setting */ +#define WL_BTC_2WIRE 2 /* use 2-wire BTC */ +#define WL_BTC_3WIRE 3 /* use 3-wire BTC */ +#define WL_BTC_4WIRE 4 /* use 4-wire BTC */ + +/* BTC flags: BTC configuration that can be set by host */ +#define WL_BTC_FLAG_PREMPT (1 << 0) +#define WL_BTC_FLAG_BT_DEF (1 << 1) +#define WL_BTC_FLAG_ACTIVE_PROT (1 << 2) +#define WL_BTC_FLAG_SIM_RSP (1 << 3) +#define WL_BTC_FLAG_PS_PROTECT (1 << 4) +#define WL_BTC_FLAG_SIM_TX_LP (1 << 5) +#define WL_BTC_FLAG_ECI (1 << 6) +#define WL_BTC_FLAG_LIGHT (1 << 7) +#define WL_BTC_FLAG_PARALLEL (1 << 8) +#endif /* !defined(LINUX_POSTMOGRIFY_REMOVAL) */ + +/* Message levels */ +#define WL_ERROR_VAL 0x00000001 +#define WL_TRACE_VAL 0x00000002 +#define WL_PRHDRS_VAL 0x00000004 +#define WL_PRPKT_VAL 0x00000008 +#define WL_INFORM_VAL 0x00000010 +#define WL_TMP_VAL 0x00000020 +#define WL_OID_VAL 0x00000040 +#define WL_RATE_VAL 0x00000080 +#define WL_ASSOC_VAL 0x00000100 +#define WL_PRUSR_VAL 0x00000200 +#define WL_PS_VAL 0x00000400 +#define WL_TXPWR_VAL 0x00000800 /* retired in TOT on 6/10/2009 */ +#define WL_PORT_VAL 0x00001000 +#define WL_DUAL_VAL 0x00002000 +#define WL_WSEC_VAL 0x00004000 +#define WL_WSEC_DUMP_VAL 0x00008000 +#define WL_LOG_VAL 0x00010000 +#define WL_NRSSI_VAL 0x00020000 /* retired in TOT on 6/10/2009 */ +#define WL_LOFT_VAL 0x00040000 /* retired in TOT on 6/10/2009 */ +#define WL_REGULATORY_VAL 0x00080000 +#define WL_PHYCAL_VAL 0x00100000 /* retired in TOT on 6/10/2009 */ +#define WL_RADAR_VAL 0x00200000 /* retired in TOT on 6/10/2009 */ +#define WL_MPC_VAL 0x00400000 +#define WL_APSTA_VAL 0x00800000 +#define WL_DFS_VAL 0x01000000 +#define WL_BA_VAL 0x02000000 /* retired in TOT on 6/14/2010 */ +#define WL_ACI_VAL 0x04000000 +#define WL_MBSS_VAL 0x04000000 +#define WL_CAC_VAL 0x08000000 +#define WL_AMSDU_VAL 0x10000000 +#define WL_AMPDU_VAL 0x20000000 +#define WL_FFPLD_VAL 0x40000000 + +/* wl_msg_level is full. For new bits take the next one and AND with + * wl_msg_level2 in wl_dbg.h + */ +#define WL_DPT_VAL 0x00000001 +#define WL_SCAN_VAL 0x00000002 +#define WL_WOWL_VAL 0x00000004 +#define WL_COEX_VAL 0x00000008 +#define WL_RTDC_VAL 0x00000010 +#define WL_PROTO_VAL 0x00000020 +#define WL_BTA_VAL 0x00000040 +#define WL_CHANINT_VAL 0x00000080 +#define WL_THERMAL_VAL 0x00000100 /* retired in TOT on 6/10/2009 */ +#define WL_P2P_VAL 0x00000200 +#define WL_ITFR_VAL 0x00000400 +#define WL_MCHAN_VAL 0x00000800 +#define WL_TDLS_VAL 0x00001000 +#define WL_MCNX_VAL 0x00002000 +#define WL_PROT_VAL 0x00004000 +#define WL_PSTA_VAL 0x00008000 +/* use top-bit for WL_TIME_STAMP_VAL because this is a modifier + * rather than a message-type of its own + */ +#define WL_TIMESTAMP_VAL 0x80000000 + +/* max # of leds supported by GPIO (gpio pin# == led index#) */ +#define WL_LED_NUMGPIO 32 /* gpio 0-31 */ + +/* led per-pin behaviors */ +#define WL_LED_OFF 0 /* always off */ +#define WL_LED_ON 1 /* always on */ +#define WL_LED_ACTIVITY 2 /* activity */ +#define WL_LED_RADIO 3 /* radio enabled */ +#define WL_LED_ARADIO 4 /* 5 Ghz radio enabled */ +#define WL_LED_BRADIO 5 /* 2.4Ghz radio enabled */ +#define WL_LED_BGMODE 6 /* on if gmode, off if bmode */ +#define WL_LED_WI1 7 +#define WL_LED_WI2 8 +#define WL_LED_WI3 9 +#define WL_LED_ASSOC 10 /* associated state indicator */ +#define WL_LED_INACTIVE 11 /* null behavior (clears default behavior) */ +#define WL_LED_ASSOCACT 12 /* on when associated; blink fast for activity */ +#define WL_LED_WI4 13 +#define WL_LED_WI5 14 +#define WL_LED_BLINKSLOW 15 /* blink slow */ +#define WL_LED_BLINKMED 16 /* blink med */ +#define WL_LED_BLINKFAST 17 /* blink fast */ +#define WL_LED_BLINKCUSTOM 18 /* blink custom */ +#define WL_LED_BLINKPERIODIC 19 /* blink periodic (custom 1000ms / off 400ms) */ +#define WL_LED_ASSOC_WITH_SEC 20 /* when connected with security */ + /* keep on for 300 sec */ +#define WL_LED_START_OFF 21 /* off upon boot, could be turned on later */ +#define WL_LED_NUMBEHAVIOR 22 + +/* led behavior numeric value format */ +#define WL_LED_BEH_MASK 0x7f /* behavior mask */ +#define WL_LED_AL_MASK 0x80 /* activelow (polarity) bit */ + +/* maximum channels returned by the get valid channels iovar */ +#define WL_NUMCHANNELS 64 +#define WL_NUMCHANSPECS 100 + +/* WDS link local endpoint WPA role */ +#define WL_WDS_WPA_ROLE_AUTH 0 /* authenticator */ +#define WL_WDS_WPA_ROLE_SUP 1 /* supplicant */ +#define WL_WDS_WPA_ROLE_AUTO 255 /* auto, based on mac addr value */ + +/* number of bytes needed to define a 128-bit mask for MAC event reporting */ +#define WL_EVENTING_MASK_LEN 16 +/* + * Join preference iovar value is an array of tuples. Each tuple has a one-byte type, + * a one-byte length, and a variable length value. RSSI type tuple must be present + * in the array. + * + * Types are defined in "join preference types" section. + * + * Length is the value size in octets. It is reserved for WL_JOIN_PREF_WPA type tuple + * and must be set to zero. + * + * Values are defined below. + * + * 1. RSSI - 2 octets + * offset 0: reserved + * offset 1: reserved + * + * 2. WPA - 2 + 12 * n octets (n is # tuples defined below) + * offset 0: reserved + * offset 1: # of tuples + * offset 2: tuple 1 + * offset 14: tuple 2 + * ... + * offset 2 + 12 * (n - 1) octets: tuple n + * + * struct wpa_cfg_tuple { + * uint8 akm[DOT11_OUI_LEN+1]; akm suite + * uint8 ucipher[DOT11_OUI_LEN+1]; unicast cipher suite + * uint8 mcipher[DOT11_OUI_LEN+1]; multicast cipher suite + * }; + * + * multicast cipher suite can be specified as a specific cipher suite or WL_WPA_ACP_MCS_ANY. + * + * 3. BAND - 2 octets + * offset 0: reserved + * offset 1: see "band preference" and "band types" + * + * 4. BAND RSSI - 2 octets + * offset 0: band types + * offset 1: +ve RSSI boost balue in dB + */ -#define WLJP_BAND_ASSOC_PREF 255 +/* join preference types */ +#define WL_JOIN_PREF_RSSI 1 /* by RSSI */ +#define WL_JOIN_PREF_WPA 2 /* by akm and ciphers */ +#define WL_JOIN_PREF_BAND 3 /* by 802.11 band */ +#define WL_JOIN_PREF_RSSI_DELTA 4 /* by 802.11 band only if RSSI delta condition matches */ +#define WL_JOIN_PREF_TRANS_PREF 5 /* defined by requesting AP */ +/* band preference */ +#define WLJP_BAND_ASSOC_PREF 255 /* use what WLC_SET_ASSOC_PREFER ioctl specifies */ -#define WL_WPA_ACP_MCS_ANY "\x00\x00\x00\x00" +/* any multicast cipher suite */ +#define WL_WPA_ACP_MCS_ANY "\x00\x00\x00\x00" struct tsinfo_arg { uint8 octets[3]; }; -#define NFIFO 6 +#define NFIFO 6 /* # tx/rx fifopairs */ -#define WL_CNT_T_VERSION 6 +#define WL_CNT_T_VERSION 8 /* current version of wl_cnt_t struct */ typedef struct { - uint16 version; - uint16 length; - - - uint32 txframe; - uint32 txbyte; - uint32 txretrans; - uint32 txerror; - uint32 txctl; - uint32 txprshort; - uint32 txserr; - uint32 txnobuf; - uint32 txnoassoc; - uint32 txrunt; - uint32 txchit; - uint32 txcmiss; - - - uint32 txuflo; - uint32 txphyerr; + uint16 version; /* see definition of WL_CNT_T_VERSION */ + uint16 length; /* length of entire structure */ + + /* transmit stat counters */ + uint32 txframe; /* tx data frames */ + uint32 txbyte; /* tx data bytes */ + uint32 txretrans; /* tx mac retransmits */ + uint32 txerror; /* tx data errors (derived: sum of others) */ + uint32 txctl; /* tx management frames */ + uint32 txprshort; /* tx short preamble frames */ + uint32 txserr; /* tx status errors */ + uint32 txnobuf; /* tx out of buffers errors */ + uint32 txnoassoc; /* tx discard because we're not associated */ + uint32 txrunt; /* tx runt frames */ + uint32 txchit; /* tx header cache hit (fastpath) */ + uint32 txcmiss; /* tx header cache miss (slowpath) */ + + /* transmit chip error counters */ + uint32 txuflo; /* tx fifo underflows */ + uint32 txphyerr; /* tx phy errors (indicated in tx status) */ + uint32 txphycrs; + + /* receive stat counters */ + uint32 rxframe; /* rx data frames */ + uint32 rxbyte; /* rx data bytes */ + uint32 rxerror; /* rx data errors (derived: sum of others) */ + uint32 rxctl; /* rx management frames */ + uint32 rxnobuf; /* rx out of buffers errors */ + uint32 rxnondata; /* rx non data frames in the data channel errors */ + uint32 rxbadds; /* rx bad DS errors */ + uint32 rxbadcm; /* rx bad control or management frames */ + uint32 rxfragerr; /* rx fragmentation errors */ + uint32 rxrunt; /* rx runt frames */ + uint32 rxgiant; /* rx giant frames */ + uint32 rxnoscb; /* rx no scb error */ + uint32 rxbadproto; /* rx invalid frames */ + uint32 rxbadsrcmac; /* rx frames with Invalid Src Mac */ + uint32 rxbadda; /* rx frames tossed for invalid da */ + uint32 rxfilter; /* rx frames filtered out */ + + /* receive chip error counters */ + uint32 rxoflo; /* rx fifo overflow errors */ + uint32 rxuflo[NFIFO]; /* rx dma descriptor underflow errors */ + + uint32 d11cnt_txrts_off; /* d11cnt txrts value when reset d11cnt */ + uint32 d11cnt_rxcrc_off; /* d11cnt rxcrc value when reset d11cnt */ + uint32 d11cnt_txnocts_off; /* d11cnt txnocts value when reset d11cnt */ + + /* misc counters */ + uint32 dmade; /* tx/rx dma descriptor errors */ + uint32 dmada; /* tx/rx dma data errors */ + uint32 dmape; /* tx/rx dma descriptor protocol errors */ + uint32 reset; /* reset count */ + uint32 tbtt; /* cnts the TBTT int's */ + uint32 txdmawar; + uint32 pkt_callback_reg_fail; /* callbacks register failure */ + + /* MAC counters: 32-bit version of d11.h's macstat_t */ + uint32 txallfrm; /* total number of frames sent, incl. Data, ACK, RTS, CTS, + * Control Management (includes retransmissions) + */ + uint32 txrtsfrm; /* number of RTS sent out by the MAC */ + uint32 txctsfrm; /* number of CTS sent out by the MAC */ + uint32 txackfrm; /* number of ACK frames sent out */ + uint32 txdnlfrm; /* Not used */ + uint32 txbcnfrm; /* beacons transmitted */ + uint32 txfunfl[8]; /* per-fifo tx underflows */ + uint32 txtplunfl; /* Template underflows (mac was too slow to transmit ACK/CTS + * or BCN) + */ + uint32 txphyerror; /* Transmit phy error, type of error is reported in tx-status for + * driver enqueued frames + */ + uint32 rxfrmtoolong; /* Received frame longer than legal limit (2346 bytes) */ + uint32 rxfrmtooshrt; /* Received frame did not contain enough bytes for its frame type */ + uint32 rxinvmachdr; /* Either the protocol version != 0 or frame type not + * data/control/management + */ + uint32 rxbadfcs; /* number of frames for which the CRC check failed in the MAC */ + uint32 rxbadplcp; /* parity check of the PLCP header failed */ + uint32 rxcrsglitch; /* PHY was able to correlate the preamble but not the header */ + uint32 rxstrt; /* Number of received frames with a good PLCP + * (i.e. passing parity check) + */ + uint32 rxdfrmucastmbss; /* Number of received DATA frames with good FCS and matching RA */ + uint32 rxmfrmucastmbss; /* number of received mgmt frames with good FCS and matching RA */ + uint32 rxcfrmucast; /* number of received CNTRL frames with good FCS and matching RA */ + uint32 rxrtsucast; /* number of unicast RTS addressed to the MAC (good FCS) */ + uint32 rxctsucast; /* number of unicast CTS addressed to the MAC (good FCS) */ + uint32 rxackucast; /* number of ucast ACKS received (good FCS) */ + uint32 rxdfrmocast; /* number of received DATA frames (good FCS and not matching RA) */ + uint32 rxmfrmocast; /* number of received MGMT frames (good FCS and not matching RA) */ + uint32 rxcfrmocast; /* number of received CNTRL frame (good FCS and not matching RA) */ + uint32 rxrtsocast; /* number of received RTS not addressed to the MAC */ + uint32 rxctsocast; /* number of received CTS not addressed to the MAC */ + uint32 rxdfrmmcast; /* number of RX Data multicast frames received by the MAC */ + uint32 rxmfrmmcast; /* number of RX Management multicast frames received by the MAC */ + uint32 rxcfrmmcast; /* number of RX Control multicast frames received by the MAC + * (unlikely to see these) + */ + uint32 rxbeaconmbss; /* beacons received from member of BSS */ + uint32 rxdfrmucastobss; /* number of unicast frames addressed to the MAC from + * other BSS (WDS FRAME) + */ + uint32 rxbeaconobss; /* beacons received from other BSS */ + uint32 rxrsptmout; /* Number of response timeouts for transmitted frames + * expecting a response + */ + uint32 bcntxcancl; /* transmit beacons canceled due to receipt of beacon (IBSS) */ + uint32 rxf0ovfl; /* Number of receive fifo 0 overflows */ + uint32 rxf1ovfl; /* Number of receive fifo 1 overflows (obsolete) */ + uint32 rxf2ovfl; /* Number of receive fifo 2 overflows (obsolete) */ + uint32 txsfovfl; /* Number of transmit status fifo overflows (obsolete) */ + uint32 pmqovfl; /* Number of PMQ overflows */ + uint32 rxcgprqfrm; /* Number of received Probe requests that made it into + * the PRQ fifo + */ + uint32 rxcgprsqovfl; /* Rx Probe Request Que overflow in the AP */ + uint32 txcgprsfail; /* Tx Probe Response Fail. AP sent probe response but did + * not get ACK + */ + uint32 txcgprssuc; /* Tx Probe Response Success (ACK was received) */ + uint32 prs_timeout; /* Number of probe requests that were dropped from the PRQ + * fifo because a probe response could not be sent out within + * the time limit defined in M_PRS_MAXTIME + */ + uint32 rxnack; /* obsolete */ + uint32 frmscons; /* obsolete */ + uint32 txnack; /* obsolete */ + uint32 txglitch_nack; /* obsolete */ + uint32 txburst; /* obsolete */ + + /* 802.11 MIB counters, pp. 614 of 802.11 reaff doc. */ + uint32 txfrag; /* dot11TransmittedFragmentCount */ + uint32 txmulti; /* dot11MulticastTransmittedFrameCount */ + uint32 txfail; /* dot11FailedCount */ + uint32 txretry; /* dot11RetryCount */ + uint32 txretrie; /* dot11MultipleRetryCount */ + uint32 rxdup; /* dot11FrameduplicateCount */ + uint32 txrts; /* dot11RTSSuccessCount */ + uint32 txnocts; /* dot11RTSFailureCount */ + uint32 txnoack; /* dot11ACKFailureCount */ + uint32 rxfrag; /* dot11ReceivedFragmentCount */ + uint32 rxmulti; /* dot11MulticastReceivedFrameCount */ + uint32 rxcrc; /* dot11FCSErrorCount */ + uint32 txfrmsnt; /* dot11TransmittedFrameCount (bogus MIB?) */ + uint32 rxundec; /* dot11WEPUndecryptableCount */ + + /* WPA2 counters (see rxundec for DecryptFailureCount) */ + uint32 tkipmicfaill; /* TKIPLocalMICFailures */ + uint32 tkipcntrmsr; /* TKIPCounterMeasuresInvoked */ + uint32 tkipreplay; /* TKIPReplays */ + uint32 ccmpfmterr; /* CCMPFormatErrors */ + uint32 ccmpreplay; /* CCMPReplays */ + uint32 ccmpundec; /* CCMPDecryptErrors */ + uint32 fourwayfail; /* FourWayHandshakeFailures */ + uint32 wepundec; /* dot11WEPUndecryptableCount */ + uint32 wepicverr; /* dot11WEPICVErrorCount */ + uint32 decsuccess; /* DecryptSuccessCount */ + uint32 tkipicverr; /* TKIPICVErrorCount */ + uint32 wepexcluded; /* dot11WEPExcludedCount */ + + uint32 txchanrej; /* Tx frames suppressed due to channel rejection */ + uint32 psmwds; /* Count PSM watchdogs */ + uint32 phywatchdog; /* Count Phy watchdogs (triggered by ucode) */ + + /* MBSS counters, AP only */ + uint32 prq_entries_handled; /* PRQ entries read in */ + uint32 prq_undirected_entries; /* which were bcast bss & ssid */ + uint32 prq_bad_entries; /* which could not be translated to info */ + uint32 atim_suppress_count; /* TX suppressions on ATIM fifo */ + uint32 bcn_template_not_ready; /* Template marked in use on send bcn ... */ + uint32 bcn_template_not_ready_done; /* ...but "DMA done" interrupt rcvd */ + uint32 late_tbtt_dpc; /* TBTT DPC did not happen in time */ + + /* per-rate receive stat counters */ + uint32 rx1mbps; /* packets rx at 1Mbps */ + uint32 rx2mbps; /* packets rx at 2Mbps */ + uint32 rx5mbps5; /* packets rx at 5.5Mbps */ + uint32 rx6mbps; /* packets rx at 6Mbps */ + uint32 rx9mbps; /* packets rx at 9Mbps */ + uint32 rx11mbps; /* packets rx at 11Mbps */ + uint32 rx12mbps; /* packets rx at 12Mbps */ + uint32 rx18mbps; /* packets rx at 18Mbps */ + uint32 rx24mbps; /* packets rx at 24Mbps */ + uint32 rx36mbps; /* packets rx at 36Mbps */ + uint32 rx48mbps; /* packets rx at 48Mbps */ + uint32 rx54mbps; /* packets rx at 54Mbps */ + uint32 rx108mbps; /* packets rx at 108mbps */ + uint32 rx162mbps; /* packets rx at 162mbps */ + uint32 rx216mbps; /* packets rx at 216 mbps */ + uint32 rx270mbps; /* packets rx at 270 mbps */ + uint32 rx324mbps; /* packets rx at 324 mbps */ + uint32 rx378mbps; /* packets rx at 378 mbps */ + uint32 rx432mbps; /* packets rx at 432 mbps */ + uint32 rx486mbps; /* packets rx at 486 mbps */ + uint32 rx540mbps; /* packets rx at 540 mbps */ + + /* pkteng rx frame stats */ + uint32 pktengrxducast; /* unicast frames rxed by the pkteng code */ + uint32 pktengrxdmcast; /* multicast frames rxed by the pkteng code */ + + uint32 rfdisable; /* count of radio disables */ + uint32 bphy_rxcrsglitch; /* PHY count of bphy glitches */ + + uint32 txexptime; /* Tx frames suppressed due to timer expiration */ + + uint32 txmpdu_sgi; /* count for sgi transmit */ + uint32 rxmpdu_sgi; /* count for sgi received */ + uint32 txmpdu_stbc; /* count for stbc transmit */ + uint32 rxmpdu_stbc; /* count for stbc received */ + + uint32 rxundec_mcst; /* dot11WEPUndecryptableCount */ + + /* WPA2 counters (see rxundec for DecryptFailureCount) */ + uint32 tkipmicfaill_mcst; /* TKIPLocalMICFailures */ + uint32 tkipcntrmsr_mcst; /* TKIPCounterMeasuresInvoked */ + uint32 tkipreplay_mcst; /* TKIPReplays */ + uint32 ccmpfmterr_mcst; /* CCMPFormatErrors */ + uint32 ccmpreplay_mcst; /* CCMPReplays */ + uint32 ccmpundec_mcst; /* CCMPDecryptErrors */ + uint32 fourwayfail_mcst; /* FourWayHandshakeFailures */ + uint32 wepundec_mcst; /* dot11WEPUndecryptableCount */ + uint32 wepicverr_mcst; /* dot11WEPICVErrorCount */ + uint32 decsuccess_mcst; /* DecryptSuccessCount */ + uint32 tkipicverr_mcst; /* TKIPICVErrorCount */ + uint32 wepexcluded_mcst; /* dot11WEPExcludedCount */ + + uint32 dma_hang; /* count for dma hang */ + uint32 reinit; /* count for reinit */ + + uint32 pstatxucast; /* count of ucast frames xmitted on all psta assoc */ + uint32 pstatxnoassoc; /* count of txnoassoc frames xmitted on all psta assoc */ + uint32 pstarxucast; /* count of ucast frames received on all psta assoc */ + uint32 pstarxbcmc; /* count of bcmc frames received on all psta */ + uint32 pstatxbcmc; /* count of bcmc frames transmitted on all psta */ + + uint32 cso_passthrough; /* hw cso required but passthrough */ +} wl_cnt_t; + +typedef struct { + uint16 version; /* see definition of WL_CNT_T_VERSION */ + uint16 length; /* length of entire structure */ + + /* transmit stat counters */ + uint32 txframe; /* tx data frames */ + uint32 txbyte; /* tx data bytes */ + uint32 txretrans; /* tx mac retransmits */ + uint32 txerror; /* tx data errors (derived: sum of others) */ + uint32 txctl; /* tx management frames */ + uint32 txprshort; /* tx short preamble frames */ + uint32 txserr; /* tx status errors */ + uint32 txnobuf; /* tx out of buffers errors */ + uint32 txnoassoc; /* tx discard because we're not associated */ + uint32 txrunt; /* tx runt frames */ + uint32 txchit; /* tx header cache hit (fastpath) */ + uint32 txcmiss; /* tx header cache miss (slowpath) */ + + /* transmit chip error counters */ + uint32 txuflo; /* tx fifo underflows */ + uint32 txphyerr; /* tx phy errors (indicated in tx status) */ uint32 txphycrs; - - uint32 rxframe; - uint32 rxbyte; - uint32 rxerror; - uint32 rxctl; - uint32 rxnobuf; - uint32 rxnondata; - uint32 rxbadds; - uint32 rxbadcm; - uint32 rxfragerr; - uint32 rxrunt; - uint32 rxgiant; - uint32 rxnoscb; - uint32 rxbadproto; - uint32 rxbadsrcmac; - uint32 rxbadda; - uint32 rxfilter; - - - uint32 rxoflo; - uint32 rxuflo[NFIFO]; - - uint32 d11cnt_txrts_off; - uint32 d11cnt_rxcrc_off; - uint32 d11cnt_txnocts_off; - - - uint32 dmade; - uint32 dmada; - uint32 dmape; - uint32 reset; - uint32 tbtt; + /* receive stat counters */ + uint32 rxframe; /* rx data frames */ + uint32 rxbyte; /* rx data bytes */ + uint32 rxerror; /* rx data errors (derived: sum of others) */ + uint32 rxctl; /* rx management frames */ + uint32 rxnobuf; /* rx out of buffers errors */ + uint32 rxnondata; /* rx non data frames in the data channel errors */ + uint32 rxbadds; /* rx bad DS errors */ + uint32 rxbadcm; /* rx bad control or management frames */ + uint32 rxfragerr; /* rx fragmentation errors */ + uint32 rxrunt; /* rx runt frames */ + uint32 rxgiant; /* rx giant frames */ + uint32 rxnoscb; /* rx no scb error */ + uint32 rxbadproto; /* rx invalid frames */ + uint32 rxbadsrcmac; /* rx frames with Invalid Src Mac */ + uint32 rxbadda; /* rx frames tossed for invalid da */ + uint32 rxfilter; /* rx frames filtered out */ + + /* receive chip error counters */ + uint32 rxoflo; /* rx fifo overflow errors */ + uint32 rxuflo[NFIFO]; /* rx dma descriptor underflow errors */ + + uint32 d11cnt_txrts_off; /* d11cnt txrts value when reset d11cnt */ + uint32 d11cnt_rxcrc_off; /* d11cnt rxcrc value when reset d11cnt */ + uint32 d11cnt_txnocts_off; /* d11cnt txnocts value when reset d11cnt */ + + /* misc counters */ + uint32 dmade; /* tx/rx dma descriptor errors */ + uint32 dmada; /* tx/rx dma data errors */ + uint32 dmape; /* tx/rx dma descriptor protocol errors */ + uint32 reset; /* reset count */ + uint32 tbtt; /* cnts the TBTT int's */ uint32 txdmawar; - uint32 pkt_callback_reg_fail; - - - uint32 txallfrm; - uint32 txrtsfrm; - uint32 txctsfrm; - uint32 txackfrm; - uint32 txdnlfrm; - uint32 txbcnfrm; - uint32 txfunfl[8]; - uint32 txtplunfl; - uint32 txphyerror; - uint32 rxfrmtoolong; - uint32 rxfrmtooshrt; - uint32 rxinvmachdr; - uint32 rxbadfcs; - uint32 rxbadplcp; - uint32 rxcrsglitch; - uint32 rxstrt; - uint32 rxdfrmucastmbss; - uint32 rxmfrmucastmbss; - uint32 rxcfrmucast; - uint32 rxrtsucast; - uint32 rxctsucast; - uint32 rxackucast; - uint32 rxdfrmocast; - uint32 rxmfrmocast; - uint32 rxcfrmocast; - uint32 rxrtsocast; - uint32 rxctsocast; - uint32 rxdfrmmcast; - uint32 rxmfrmmcast; - uint32 rxcfrmmcast; - uint32 rxbeaconmbss; - uint32 rxdfrmucastobss; - uint32 rxbeaconobss; - uint32 rxrsptmout; - uint32 bcntxcancl; - uint32 rxf0ovfl; - uint32 rxf1ovfl; - uint32 rxf2ovfl; - uint32 txsfovfl; - uint32 pmqovfl; - uint32 rxcgprqfrm; - uint32 rxcgprsqovfl; - uint32 txcgprsfail; - uint32 txcgprssuc; - uint32 prs_timeout; + uint32 pkt_callback_reg_fail; /* callbacks register failure */ + + /* MAC counters: 32-bit version of d11.h's macstat_t */ + uint32 txallfrm; /* total number of frames sent, incl. Data, ACK, RTS, CTS, + * Control Management (includes retransmissions) + */ + uint32 txrtsfrm; /* number of RTS sent out by the MAC */ + uint32 txctsfrm; /* number of CTS sent out by the MAC */ + uint32 txackfrm; /* number of ACK frames sent out */ + uint32 txdnlfrm; /* Not used */ + uint32 txbcnfrm; /* beacons transmitted */ + uint32 txfunfl[8]; /* per-fifo tx underflows */ + uint32 txtplunfl; /* Template underflows (mac was too slow to transmit ACK/CTS + * or BCN) + */ + uint32 txphyerror; /* Transmit phy error, type of error is reported in tx-status for + * driver enqueued frames + */ + uint32 rxfrmtoolong; /* Received frame longer than legal limit (2346 bytes) */ + uint32 rxfrmtooshrt; /* Received frame did not contain enough bytes for its frame type */ + uint32 rxinvmachdr; /* Either the protocol version != 0 or frame type not + * data/control/management + */ + uint32 rxbadfcs; /* number of frames for which the CRC check failed in the MAC */ + uint32 rxbadplcp; /* parity check of the PLCP header failed */ + uint32 rxcrsglitch; /* PHY was able to correlate the preamble but not the header */ + uint32 rxstrt; /* Number of received frames with a good PLCP + * (i.e. passing parity check) + */ + uint32 rxdfrmucastmbss; /* Number of received DATA frames with good FCS and matching RA */ + uint32 rxmfrmucastmbss; /* number of received mgmt frames with good FCS and matching RA */ + uint32 rxcfrmucast; /* number of received CNTRL frames with good FCS and matching RA */ + uint32 rxrtsucast; /* number of unicast RTS addressed to the MAC (good FCS) */ + uint32 rxctsucast; /* number of unicast CTS addressed to the MAC (good FCS) */ + uint32 rxackucast; /* number of ucast ACKS received (good FCS) */ + uint32 rxdfrmocast; /* number of received DATA frames (good FCS and not matching RA) */ + uint32 rxmfrmocast; /* number of received MGMT frames (good FCS and not matching RA) */ + uint32 rxcfrmocast; /* number of received CNTRL frame (good FCS and not matching RA) */ + uint32 rxrtsocast; /* number of received RTS not addressed to the MAC */ + uint32 rxctsocast; /* number of received CTS not addressed to the MAC */ + uint32 rxdfrmmcast; /* number of RX Data multicast frames received by the MAC */ + uint32 rxmfrmmcast; /* number of RX Management multicast frames received by the MAC */ + uint32 rxcfrmmcast; /* number of RX Control multicast frames received by the MAC + * (unlikely to see these) + */ + uint32 rxbeaconmbss; /* beacons received from member of BSS */ + uint32 rxdfrmucastobss; /* number of unicast frames addressed to the MAC from + * other BSS (WDS FRAME) + */ + uint32 rxbeaconobss; /* beacons received from other BSS */ + uint32 rxrsptmout; /* Number of response timeouts for transmitted frames + * expecting a response + */ + uint32 bcntxcancl; /* transmit beacons canceled due to receipt of beacon (IBSS) */ + uint32 rxf0ovfl; /* Number of receive fifo 0 overflows */ + uint32 rxf1ovfl; /* Number of receive fifo 1 overflows (obsolete) */ + uint32 rxf2ovfl; /* Number of receive fifo 2 overflows (obsolete) */ + uint32 txsfovfl; /* Number of transmit status fifo overflows (obsolete) */ + uint32 pmqovfl; /* Number of PMQ overflows */ + uint32 rxcgprqfrm; /* Number of received Probe requests that made it into + * the PRQ fifo + */ + uint32 rxcgprsqovfl; /* Rx Probe Request Que overflow in the AP */ + uint32 txcgprsfail; /* Tx Probe Response Fail. AP sent probe response but did + * not get ACK + */ + uint32 txcgprssuc; /* Tx Probe Response Success (ACK was received) */ + uint32 prs_timeout; /* Number of probe requests that were dropped from the PRQ + * fifo because a probe response could not be sent out within + * the time limit defined in M_PRS_MAXTIME + */ uint32 rxnack; uint32 frmscons; uint32 txnack; - uint32 txglitch_nack; - uint32 txburst; - - - uint32 txfrag; - uint32 txmulti; - uint32 txfail; - uint32 txretry; - uint32 txretrie; - uint32 rxdup; - uint32 txrts; - uint32 txnocts; - uint32 txnoack; - uint32 rxfrag; - uint32 rxmulti; - uint32 rxcrc; - uint32 txfrmsnt; - uint32 rxundec; - - - uint32 tkipmicfaill; - uint32 tkipcntrmsr; - uint32 tkipreplay; - uint32 ccmpfmterr; - uint32 ccmpreplay; - uint32 ccmpundec; - uint32 fourwayfail; - uint32 wepundec; - uint32 wepicverr; - uint32 decsuccess; - uint32 tkipicverr; - uint32 wepexcluded; - - uint32 rxundec_mcst; - - - uint32 tkipmicfaill_mcst; - uint32 tkipcntrmsr_mcst; - uint32 tkipreplay_mcst; - uint32 ccmpfmterr_mcst; - uint32 ccmpreplay_mcst; - uint32 ccmpundec_mcst; - uint32 fourwayfail_mcst; - uint32 wepundec_mcst; - uint32 wepicverr_mcst; - uint32 decsuccess_mcst; - uint32 tkipicverr_mcst; - uint32 wepexcluded_mcst; - - uint32 txchanrej; - uint32 txexptime; - uint32 psmwds; - uint32 phywatchdog; - - - uint32 prq_entries_handled; - uint32 prq_undirected_entries; - uint32 prq_bad_entries; - uint32 atim_suppress_count; - uint32 bcn_template_not_ready; - uint32 bcn_template_not_ready_done; - uint32 late_tbtt_dpc; - - - uint32 rx1mbps; - uint32 rx2mbps; - uint32 rx5mbps5; - uint32 rx6mbps; - uint32 rx9mbps; - uint32 rx11mbps; - uint32 rx12mbps; - uint32 rx18mbps; - uint32 rx24mbps; - uint32 rx36mbps; - uint32 rx48mbps; - uint32 rx54mbps; - uint32 rx108mbps; - uint32 rx162mbps; - uint32 rx216mbps; - uint32 rx270mbps; - uint32 rx324mbps; - uint32 rx378mbps; - uint32 rx432mbps; - uint32 rx486mbps; - uint32 rx540mbps; - - - uint32 pktengrxducast; - uint32 pktengrxdmcast; - - uint32 rfdisable; - uint32 bphy_rxcrsglitch; - - uint32 txmpdu_sgi; - uint32 rxmpdu_sgi; - uint32 txmpdu_stbc; - uint32 rxmpdu_stbc; -} wl_cnt_t; - + uint32 txglitch_nack; /* obsolete */ + uint32 txburst; /* obsolete */ + + /* 802.11 MIB counters, pp. 614 of 802.11 reaff doc. */ + uint32 txfrag; /* dot11TransmittedFragmentCount */ + uint32 txmulti; /* dot11MulticastTransmittedFrameCount */ + uint32 txfail; /* dot11FailedCount */ + uint32 txretry; /* dot11RetryCount */ + uint32 txretrie; /* dot11MultipleRetryCount */ + uint32 rxdup; /* dot11FrameduplicateCount */ + uint32 txrts; /* dot11RTSSuccessCount */ + uint32 txnocts; /* dot11RTSFailureCount */ + uint32 txnoack; /* dot11ACKFailureCount */ + uint32 rxfrag; /* dot11ReceivedFragmentCount */ + uint32 rxmulti; /* dot11MulticastReceivedFrameCount */ + uint32 rxcrc; /* dot11FCSErrorCount */ + uint32 txfrmsnt; /* dot11TransmittedFrameCount (bogus MIB?) */ + uint32 rxundec; /* dot11WEPUndecryptableCount */ + + /* WPA2 counters (see rxundec for DecryptFailureCount) */ + uint32 tkipmicfaill; /* TKIPLocalMICFailures */ + uint32 tkipcntrmsr; /* TKIPCounterMeasuresInvoked */ + uint32 tkipreplay; /* TKIPReplays */ + uint32 ccmpfmterr; /* CCMPFormatErrors */ + uint32 ccmpreplay; /* CCMPReplays */ + uint32 ccmpundec; /* CCMPDecryptErrors */ + uint32 fourwayfail; /* FourWayHandshakeFailures */ + uint32 wepundec; /* dot11WEPUndecryptableCount */ + uint32 wepicverr; /* dot11WEPICVErrorCount */ + uint32 decsuccess; /* DecryptSuccessCount */ + uint32 tkipicverr; /* TKIPICVErrorCount */ + uint32 wepexcluded; /* dot11WEPExcludedCount */ + + uint32 rxundec_mcst; /* dot11WEPUndecryptableCount */ + + /* WPA2 counters (see rxundec for DecryptFailureCount) */ + uint32 tkipmicfaill_mcst; /* TKIPLocalMICFailures */ + uint32 tkipcntrmsr_mcst; /* TKIPCounterMeasuresInvoked */ + uint32 tkipreplay_mcst; /* TKIPReplays */ + uint32 ccmpfmterr_mcst; /* CCMPFormatErrors */ + uint32 ccmpreplay_mcst; /* CCMPReplays */ + uint32 ccmpundec_mcst; /* CCMPDecryptErrors */ + uint32 fourwayfail_mcst; /* FourWayHandshakeFailures */ + uint32 wepundec_mcst; /* dot11WEPUndecryptableCount */ + uint32 wepicverr_mcst; /* dot11WEPICVErrorCount */ + uint32 decsuccess_mcst; /* DecryptSuccessCount */ + uint32 tkipicverr_mcst; /* TKIPICVErrorCount */ + uint32 wepexcluded_mcst; /* dot11WEPExcludedCount */ + + uint32 txchanrej; /* Tx frames suppressed due to channel rejection */ + uint32 txexptime; /* Tx frames suppressed due to timer expiration */ + uint32 psmwds; /* Count PSM watchdogs */ + uint32 phywatchdog; /* Count Phy watchdogs (triggered by ucode) */ + + /* MBSS counters, AP only */ + uint32 prq_entries_handled; /* PRQ entries read in */ + uint32 prq_undirected_entries; /* which were bcast bss & ssid */ + uint32 prq_bad_entries; /* which could not be translated to info */ + uint32 atim_suppress_count; /* TX suppressions on ATIM fifo */ + uint32 bcn_template_not_ready; /* Template marked in use on send bcn ... */ + uint32 bcn_template_not_ready_done; /* ...but "DMA done" interrupt rcvd */ + uint32 late_tbtt_dpc; /* TBTT DPC did not happen in time */ + + /* per-rate receive stat counters */ + uint32 rx1mbps; /* packets rx at 1Mbps */ + uint32 rx2mbps; /* packets rx at 2Mbps */ + uint32 rx5mbps5; /* packets rx at 5.5Mbps */ + uint32 rx6mbps; /* packets rx at 6Mbps */ + uint32 rx9mbps; /* packets rx at 9Mbps */ + uint32 rx11mbps; /* packets rx at 11Mbps */ + uint32 rx12mbps; /* packets rx at 12Mbps */ + uint32 rx18mbps; /* packets rx at 18Mbps */ + uint32 rx24mbps; /* packets rx at 24Mbps */ + uint32 rx36mbps; /* packets rx at 36Mbps */ + uint32 rx48mbps; /* packets rx at 48Mbps */ + uint32 rx54mbps; /* packets rx at 54Mbps */ + uint32 rx108mbps; /* packets rx at 108mbps */ + uint32 rx162mbps; /* packets rx at 162mbps */ + uint32 rx216mbps; /* packets rx at 216 mbps */ + uint32 rx270mbps; /* packets rx at 270 mbps */ + uint32 rx324mbps; /* packets rx at 324 mbps */ + uint32 rx378mbps; /* packets rx at 378 mbps */ + uint32 rx432mbps; /* packets rx at 432 mbps */ + uint32 rx486mbps; /* packets rx at 486 mbps */ + uint32 rx540mbps; /* packets rx at 540 mbps */ + + /* pkteng rx frame stats */ + uint32 pktengrxducast; /* unicast frames rxed by the pkteng code */ + uint32 pktengrxdmcast; /* multicast frames rxed by the pkteng code */ + + uint32 rfdisable; /* count of radio disables */ + uint32 bphy_rxcrsglitch; /* PHY count of bphy glitches */ + + uint32 txmpdu_sgi; /* count for sgi transmit */ + uint32 rxmpdu_sgi; /* count for sgi received */ + uint32 txmpdu_stbc; /* count for stbc transmit */ + uint32 rxmpdu_stbc; /* count for stbc received */ +} wl_cnt_ver_six_t; + + +#ifndef LINUX_POSTMOGRIFY_REMOVAL +#define WL_DELTA_STATS_T_VERSION 1 /* current version of wl_delta_stats_t struct */ -#define WL_WME_CNT_VERSION 1 +typedef struct { + uint16 version; /* see definition of WL_DELTA_STATS_T_VERSION */ + uint16 length; /* length of entire structure */ + + /* transmit stat counters */ + uint32 txframe; /* tx data frames */ + uint32 txbyte; /* tx data bytes */ + uint32 txretrans; /* tx mac retransmits */ + uint32 txfail; /* tx failures */ + + /* receive stat counters */ + uint32 rxframe; /* rx data frames */ + uint32 rxbyte; /* rx data bytes */ + + /* per-rate receive stat counters */ + uint32 rx1mbps; /* packets rx at 1Mbps */ + uint32 rx2mbps; /* packets rx at 2Mbps */ + uint32 rx5mbps5; /* packets rx at 5.5Mbps */ + uint32 rx6mbps; /* packets rx at 6Mbps */ + uint32 rx9mbps; /* packets rx at 9Mbps */ + uint32 rx11mbps; /* packets rx at 11Mbps */ + uint32 rx12mbps; /* packets rx at 12Mbps */ + uint32 rx18mbps; /* packets rx at 18Mbps */ + uint32 rx24mbps; /* packets rx at 24Mbps */ + uint32 rx36mbps; /* packets rx at 36Mbps */ + uint32 rx48mbps; /* packets rx at 48Mbps */ + uint32 rx54mbps; /* packets rx at 54Mbps */ + uint32 rx108mbps; /* packets rx at 108mbps */ + uint32 rx162mbps; /* packets rx at 162mbps */ + uint32 rx216mbps; /* packets rx at 216 mbps */ + uint32 rx270mbps; /* packets rx at 270 mbps */ + uint32 rx324mbps; /* packets rx at 324 mbps */ + uint32 rx378mbps; /* packets rx at 378 mbps */ + uint32 rx432mbps; /* packets rx at 432 mbps */ + uint32 rx486mbps; /* packets rx at 486 mbps */ + uint32 rx540mbps; /* packets rx at 540 mbps */ +} wl_delta_stats_t; +#endif /* LINUX_POSTMOGRIFY_REMOVAL */ + +#define WL_WME_CNT_VERSION 1 /* current version of wl_wme_cnt_t */ typedef struct { uint32 packets; @@ -1792,17 +3271,17 @@ typedef struct { } wl_traffic_stats_t; typedef struct { - uint16 version; - uint16 length; + uint16 version; /* see definition of WL_WME_CNT_VERSION */ + uint16 length; /* length of entire structure */ - wl_traffic_stats_t tx[AC_COUNT]; - wl_traffic_stats_t tx_failed[AC_COUNT]; - wl_traffic_stats_t rx[AC_COUNT]; - wl_traffic_stats_t rx_failed[AC_COUNT]; + wl_traffic_stats_t tx[AC_COUNT]; /* Packets transmitted */ + wl_traffic_stats_t tx_failed[AC_COUNT]; /* Packets dropped or failed to transmit */ + wl_traffic_stats_t rx[AC_COUNT]; /* Packets received */ + wl_traffic_stats_t rx_failed[AC_COUNT]; /* Packets failed to receive */ - wl_traffic_stats_t forward[AC_COUNT]; + wl_traffic_stats_t forward[AC_COUNT]; /* Packets forwarded by AP */ - wl_traffic_stats_t tx_expired[AC_COUNT]; + wl_traffic_stats_t tx_expired[AC_COUNT]; /* packets dropped due to lifetime expiry */ } wl_wme_cnt_t; @@ -1812,11 +3291,11 @@ struct wl_msglevel2 { }; typedef struct wl_mkeep_alive_pkt { - uint16 version; - uint16 length; + uint16 version; /* Version for mkeep_alive */ + uint16 length; /* length of fixed parameters in the structure */ uint32 period_msec; uint16 len_bytes; - uint8 keep_alive_id; + uint8 keep_alive_id; /* 0 - 3 for N = 4 */ uint8 data[1]; } wl_mkeep_alive_pkt_t; @@ -1824,16 +3303,246 @@ typedef struct wl_mkeep_alive_pkt { #define WL_MKEEP_ALIVE_FIXED_LEN OFFSETOF(wl_mkeep_alive_pkt_t, data) #define WL_MKEEP_ALIVE_PRECISION 500 +#ifndef LINUX_POSTMOGRIFY_REMOVAL +#ifdef WLBA + +#define WLC_BA_CNT_VERSION 1 /* current version of wlc_ba_cnt_t */ + +/* block ack related stats */ +typedef struct wlc_ba_cnt { + uint16 version; /* WLC_BA_CNT_VERSION */ + uint16 length; /* length of entire structure */ + + /* transmit stat counters */ + uint32 txpdu; /* pdus sent */ + uint32 txsdu; /* sdus sent */ + uint32 txfc; /* tx side flow controlled packets */ + uint32 txfci; /* tx side flow control initiated */ + uint32 txretrans; /* retransmitted pdus */ + uint32 txbatimer; /* ba resend due to timer */ + uint32 txdrop; /* dropped packets */ + uint32 txaddbareq; /* addba req sent */ + uint32 txaddbaresp; /* addba resp sent */ + uint32 txdelba; /* delba sent */ + uint32 txba; /* ba sent */ + uint32 txbar; /* bar sent */ + uint32 txpad[4]; /* future */ + + /* receive side counters */ + uint32 rxpdu; /* pdus recd */ + uint32 rxqed; /* pdus buffered before sending up */ + uint32 rxdup; /* duplicate pdus */ + uint32 rxnobuf; /* pdus discarded due to no buf */ + uint32 rxaddbareq; /* addba req recd */ + uint32 rxaddbaresp; /* addba resp recd */ + uint32 rxdelba; /* delba recd */ + uint32 rxba; /* ba recd */ + uint32 rxbar; /* bar recd */ + uint32 rxinvba; /* invalid ba recd */ + uint32 rxbaholes; /* ba recd with holes */ + uint32 rxunexp; /* unexpected packets */ + uint32 rxpad[4]; /* future */ +} wlc_ba_cnt_t; +#endif /* WLBA */ + +/* structure for per-tid ampdu control */ +struct ampdu_tid_control { + uint8 tid; /* tid */ + uint8 enable; /* enable/disable */ +}; +/* structure for identifying ea/tid for sending addba/delba */ +struct ampdu_ea_tid { + struct ether_addr ea; /* Station address */ + uint8 tid; /* tid */ +}; +/* structure for identifying retry/tid for retry_limit_tid/rr_retry_limit_tid */ +struct ampdu_retry_tid { + uint8 tid; /* tid */ + uint8 retry; /* retry value */ +}; -#define WLC_ROAM_TRIGGER_DEFAULT 0 -#define WLC_ROAM_TRIGGER_BANDWIDTH 1 -#define WLC_ROAM_TRIGGER_DISTANCE 2 -#define WLC_ROAM_TRIGGER_AUTO 3 -#define WLC_ROAM_TRIGGER_MAX_VALUE 3 +/* Different discovery modes for dpt */ +#define DPT_DISCOVERY_MANUAL 0x01 /* manual discovery mode */ +#define DPT_DISCOVERY_AUTO 0x02 /* auto discovery mode */ +#define DPT_DISCOVERY_SCAN 0x04 /* scan-based discovery mode */ + +/* different path selection values */ +#define DPT_PATHSEL_AUTO 0 /* auto mode for path selection */ +#define DPT_PATHSEL_DIRECT 1 /* always use direct DPT path */ +#define DPT_PATHSEL_APPATH 2 /* always use AP path */ + +/* different ops for deny list */ +#define DPT_DENY_LIST_ADD 1 /* add to dpt deny list */ +#define DPT_DENY_LIST_REMOVE 2 /* remove from dpt deny list */ + +/* different ops for manual end point */ +#define DPT_MANUAL_EP_CREATE 1 /* create manual dpt endpoint */ +#define DPT_MANUAL_EP_MODIFY 2 /* modify manual dpt endpoint */ +#define DPT_MANUAL_EP_DELETE 3 /* delete manual dpt endpoint */ + +/* structure for dpt iovars */ +typedef struct dpt_iovar { + struct ether_addr ea; /* Station address */ + uint8 mode; /* mode: depends on iovar */ + uint32 pad; /* future */ +} dpt_iovar_t; + +/* flags to indicate DPT status */ +#define DPT_STATUS_ACTIVE 0x01 /* link active (though may be suspended) */ +#define DPT_STATUS_AES 0x02 /* link secured through AES encryption */ +#define DPT_STATUS_FAILED 0x04 /* DPT link failed */ + +#define DPT_FNAME_LEN 48 /* Max length of friendly name */ + +typedef struct dpt_status { + uint8 status; /* flags to indicate status */ + uint8 fnlen; /* length of friendly name */ + uchar name[DPT_FNAME_LEN]; /* friendly name */ + uint32 rssi; /* RSSI of the link */ + sta_info_t sta; /* sta info */ +} dpt_status_t; + +/* structure for dpt list */ +typedef struct dpt_list { + uint32 num; /* number of entries in struct */ + dpt_status_t status[1]; /* per station info */ +} dpt_list_t; + +/* structure for dpt friendly name */ +typedef struct dpt_fname { + uint8 len; /* length of friendly name */ + uchar name[DPT_FNAME_LEN]; /* friendly name */ +} dpt_fname_t; + +#define BDD_FNAME_LEN 32 /* Max length of friendly name */ +typedef struct bdd_fname { + uint8 len; /* length of friendly name */ + uchar name[BDD_FNAME_LEN]; /* friendly name */ +} bdd_fname_t; + +/* structure for addts arguments */ +/* For ioctls that take a list of TSPEC */ +struct tslist { + int count; /* number of tspecs */ + struct tsinfo_arg tsinfo[1]; /* variable length array of tsinfo */ +}; +#ifdef WLTDLS +/* different ops for manual end point */ +#define TDLS_MANUAL_EP_CREATE 1 /* create manual dpt endpoint */ +#define TDLS_MANUAL_EP_MODIFY 2 /* modify manual dpt endpoint */ +#define TDLS_MANUAL_EP_DELETE 3 /* delete manual dpt endpoint */ +#define TDLS_MANUAL_EP_PM 4 /* put dpt endpoint in PM mode */ +#define TDLS_MANUAL_EP_WAKE 5 /* wake up dpt endpoint from PM */ +#define TDLS_MANUAL_EP_DISCOVERY 6 /* discover if endpoint is TDLS capable */ +#define TDLS_MANUAL_EP_CHSW 7 /* channel switch */ + +/* structure for tdls iovars */ +typedef struct tdls_iovar { + struct ether_addr ea; /* Station address */ + uint8 mode; /* mode: depends on iovar */ + chanspec_t chanspec; + uint32 pad; /* future */ +} tdls_iovar_t; +#endif /* WLTDLS */ + +/* structure for addts/delts arguments */ +typedef struct tspec_arg { + uint16 version; /* see definition of TSPEC_ARG_VERSION */ + uint16 length; /* length of entire structure */ + uint flag; /* bit field */ + /* TSPEC Arguments */ + struct tsinfo_arg tsinfo; /* TS Info bit field */ + uint16 nom_msdu_size; /* (Nominal or fixed) MSDU Size (bytes) */ + uint16 max_msdu_size; /* Maximum MSDU Size (bytes) */ + uint min_srv_interval; /* Minimum Service Interval (us) */ + uint max_srv_interval; /* Maximum Service Interval (us) */ + uint inactivity_interval; /* Inactivity Interval (us) */ + uint suspension_interval; /* Suspension Interval (us) */ + uint srv_start_time; /* Service Start Time (us) */ + uint min_data_rate; /* Minimum Data Rate (bps) */ + uint mean_data_rate; /* Mean Data Rate (bps) */ + uint peak_data_rate; /* Peak Data Rate (bps) */ + uint max_burst_size; /* Maximum Burst Size (bytes) */ + uint delay_bound; /* Delay Bound (us) */ + uint min_phy_rate; /* Minimum PHY Rate (bps) */ + uint16 surplus_bw; /* Surplus Bandwidth Allowance (range 1.0 to 8.0) */ + uint16 medium_time; /* Medium Time (32 us/s periods) */ + uint8 dialog_token; /* dialog token */ +} tspec_arg_t; + +/* tspec arg for desired station */ +typedef struct tspec_per_sta_arg { + struct ether_addr ea; + struct tspec_arg ts; +} tspec_per_sta_arg_t; + +/* structure for max bandwidth for each access category */ +typedef struct wme_max_bandwidth { + uint32 ac[AC_COUNT]; /* max bandwidth for each access category */ +} wme_max_bandwidth_t; + +#define WL_WME_MBW_PARAMS_IO_BYTES (sizeof(wme_max_bandwidth_t)) + +/* current version of wl_tspec_arg_t struct */ +#define TSPEC_ARG_VERSION 2 /* current version of wl_tspec_arg_t struct */ +#define TSPEC_ARG_LENGTH 55 /* argument length from tsinfo to medium_time */ +#define TSPEC_DEFAULT_DIALOG_TOKEN 42 /* default dialog token */ +#define TSPEC_DEFAULT_SBW_FACTOR 0x3000 /* default surplus bw */ + + +/* define for flag */ +#define TSPEC_PENDING 0 /* TSPEC pending */ +#define TSPEC_ACCEPTED 1 /* TSPEC accepted */ +#define TSPEC_REJECTED 2 /* TSPEC rejected */ +#define TSPEC_UNKNOWN 3 /* TSPEC unknown */ +#define TSPEC_STATUS_MASK 7 /* TSPEC status mask */ + + +/* Software feature flag defines used by wlfeatureflag */ +#ifdef WLAFTERBURNER +#define WL_SWFL_ABBFL 0x0001 /* Allow Afterburner on systems w/o hardware BFL */ +#define WL_SWFL_ABENCORE 0x0002 /* Allow AB on non-4318E chips */ +#endif /* WLAFTERBURNER */ +#define WL_SWFL_NOHWRADIO 0x0004 +#define WL_SWFL_FLOWCONTROL 0x0008 /* Enable backpressure to OS stack */ +#define WL_SWFL_WLBSSSORT 0x0010 /* Per-port supports sorting of BSS */ + +#define WL_LIFETIME_MAX 0xFFFF /* Max value in ms */ + +/* Packet lifetime configuration per ac */ +typedef struct wl_lifetime { + uint32 ac; /* access class */ + uint32 lifetime; /* Packet lifetime value in ms */ +} wl_lifetime_t; + +/* Channel Switch Announcement param */ +typedef struct wl_chan_switch { + uint8 mode; /* value 0 or 1 */ + uint8 count; /* count # of beacons before switching */ + chanspec_t chspec; /* chanspec */ + uint8 reg; /* regulatory class */ +} wl_chan_switch_t; +#endif /* LINUX_POSTMOGRIFY_REMOVAL */ + +/* Roaming trigger definitions for WLC_SET_ROAM_TRIGGER. + * + * (-100 < value < 0) value is used directly as a roaming trigger in dBm + * (0 <= value) value specifies a logical roaming trigger level from + * the list below + * + * WLC_GET_ROAM_TRIGGER always returns roaming trigger value in dBm, never + * the logical roam trigger value. + */ +#define WLC_ROAM_TRIGGER_DEFAULT 0 /* default roaming trigger */ +#define WLC_ROAM_TRIGGER_BANDWIDTH 1 /* optimize for bandwidth roaming trigger */ +#define WLC_ROAM_TRIGGER_DISTANCE 2 /* optimize for distance roaming trigger */ +#define WLC_ROAM_TRIGGER_AUTO 3 /* auto-detect environment */ +#define WLC_ROAM_TRIGGER_MAX_VALUE 3 /* max. valid value */ -#define WPA_AUTH_PFN_ANY 0xffffffff +/* Preferred Network Offload (PNO, formerly PFN) defines */ +#define WPA_AUTH_PFN_ANY 0xffffffff /* for PFN, match only ssid */ enum { PFN_LIST_ORDER, @@ -1854,11 +3563,11 @@ enum { #define SORT_CRITERIA_BIT 0 #define AUTO_NET_SWITCH_BIT 1 -#define ENABLE_BKGRD_SCAN_BIT 2 +#define ENABLE_BKGRD_SCAN_BIT 2 #define IMMEDIATE_SCAN_BIT 3 #define AUTO_CONNECT_BIT 4 #define ENABLE_BD_SCAN_BIT 5 -#define ENABLE_ADAPTSCAN_BIT 6 +#define ENABLE_ADAPTSCAN_BIT 6 #define IMMEDIATE_EVENT_BIT 8 #define SORT_CRITERIA_MASK 0x0001 @@ -1866,6 +3575,7 @@ enum { #define ENABLE_BKGRD_SCAN_MASK 0x0004 #define IMMEDIATE_SCAN_MASK 0x0008 #define AUTO_CONNECT_MASK 0x0010 + #define ENABLE_BD_SCAN_MASK 0x0020 #define ENABLE_ADAPTSCAN_MASK 0x00c0 #define IMMEDIATE_EVENT_MASK 0x0100 @@ -1882,18 +3592,18 @@ enum { #define DEFAULT_REPEAT 10 #define DEFAULT_EXP 2 - +/* PFN network info structure */ typedef struct wl_pfn_subnet_info { struct ether_addr BSSID; - uint8 channel; + uint8 channel; /* channel number only */ uint8 SSID_len; uint8 SSID[32]; } wl_pfn_subnet_info_t; typedef struct wl_pfn_net_info { wl_pfn_subnet_info_t pfnsubnet; - int16 RSSI; - uint16 timestamp; + int16 RSSI; /* receive signal strength (in dBm) */ + uint16 timestamp; /* age in seconds */ } wl_pfn_net_info_t; typedef struct wl_pfn_scanresults { @@ -1903,23 +3613,32 @@ typedef struct wl_pfn_scanresults { wl_pfn_net_info_t netinfo[1]; } wl_pfn_scanresults_t; - +/* PFN data structure */ typedef struct wl_pfn_param { - int32 version; - int32 scan_freq; - int32 lost_network_timeout; - int16 flags; - int16 rssi_margin; - uint8 bestn; - uint8 mscan; - uint8 repeat; - uint8 exp; - int32 slow_freq; + int32 version; /* PNO parameters version */ + int32 scan_freq; /* Scan frequency */ + int32 lost_network_timeout; /* Timeout in sec. to declare + * discovered network as lost + */ + int16 flags; /* Bit field to control features + * of PFN such as sort criteria auto + * enable switch and background scan + */ + int16 rssi_margin; /* Margin to avoid jitter for choosing a + * PFN based on RSSI sort criteria + */ + uint8 bestn; /* number of best networks in each scan */ + uint8 mscan; /* number of scans recorded */ + uint8 repeat; /* Minimum number of scan intervals + *before scan frequency changes in adaptive scan + */ + uint8 exp; /* Exponent of 2 for maximum scan interval */ + int32 slow_freq; /* slow scan period */ } wl_pfn_param_t; typedef struct wl_pfn_bssid { struct ether_addr macaddr; - + /* Bit4: suppress_lost, Bit3: suppress_found */ uint16 flags; } wl_pfn_bssid_t; #define WL_PFN_SUPPRESSFOUND_MASK 0x08 @@ -1935,39 +3654,39 @@ typedef struct wl_pfn_cfg { #define WL_PFN_REPORT_BSSIDNET 2 typedef struct wl_pfn { - wlc_ssid_t ssid; - int32 flags; - int32 infra; - int32 auth; - int32 wpa_auth; - int32 wsec; + wlc_ssid_t ssid; /* ssid name and its length */ + int32 flags; /* bit2: hidden */ + int32 infra; /* BSS Vs IBSS */ + int32 auth; /* Open Vs Closed */ + int32 wpa_auth; /* WPA type */ + int32 wsec; /* wsec value */ } wl_pfn_t; #define WL_PFN_HIDDEN_BIT 2 -#define PNO_SCAN_MAX_FW 508*1000 -#define PNO_SCAN_MAX_FW_SEC PNO_SCAN_MAX_FW/1000 -#define PNO_SCAN_MIN_FW_SEC 10 +#define PNO_SCAN_MAX_FW 508*1000 /* max time scan time in msec */ +#define PNO_SCAN_MAX_FW_SEC PNO_SCAN_MAX_FW/1000 /* max time scan time in SEC */ +#define PNO_SCAN_MIN_FW_SEC 10 /* min time scan time in SEC */ #define WL_PFN_HIDDEN_MASK 0x4 +/* TCP Checksum Offload defines */ +#define TOE_TX_CSUM_OL 0x00000001 +#define TOE_RX_CSUM_OL 0x00000002 -#define TOE_TX_CSUM_OL 0x00000001 -#define TOE_RX_CSUM_OL 0x00000002 - - -#define TOE_ERRTEST_TX_CSUM 0x00000001 -#define TOE_ERRTEST_RX_CSUM 0x00000002 -#define TOE_ERRTEST_RX_CSUM2 0x00000004 +/* TCP Checksum Offload error injection for testing */ +#define TOE_ERRTEST_TX_CSUM 0x00000001 +#define TOE_ERRTEST_RX_CSUM 0x00000002 +#define TOE_ERRTEST_RX_CSUM2 0x00000004 struct toe_ol_stats_t { - + /* Num of tx packets that don't need to be checksummed */ uint32 tx_summed; - + /* Num of tx packets where checksum is filled by offload engine */ uint32 tx_iph_fill; uint32 tx_tcp_fill; uint32 tx_udp_fill; uint32 tx_icmp_fill; - + /* Num of rx packets where toe finds out if checksum is good or bad */ uint32 rx_iph_good; uint32 rx_iph_bad; uint32 rx_tcp_good; @@ -1977,274 +3696,289 @@ struct toe_ol_stats_t { uint32 rx_icmp_good; uint32 rx_icmp_bad; - + /* Num of tx packets in which csum error is injected */ uint32 tx_tcp_errinj; uint32 tx_udp_errinj; uint32 tx_icmp_errinj; - + /* Num of rx packets in which csum error is injected */ uint32 rx_tcp_errinj; uint32 rx_udp_errinj; uint32 rx_icmp_errinj; }; +/* ARP Offload feature flags for arp_ol iovar */ +#define ARP_OL_AGENT 0x00000001 +#define ARP_OL_SNOOP 0x00000002 +#define ARP_OL_HOST_AUTO_REPLY 0x00000004 +#define ARP_OL_PEER_AUTO_REPLY 0x00000008 -#define ARP_OL_AGENT 0x00000001 -#define ARP_OL_SNOOP 0x00000002 -#define ARP_OL_HOST_AUTO_REPLY 0x00000004 -#define ARP_OL_PEER_AUTO_REPLY 0x00000008 - - -#define ARP_ERRTEST_REPLY_PEER 0x1 -#define ARP_ERRTEST_REPLY_HOST 0x2 - -#define ARP_MULTIHOMING_MAX 8 +/* ARP Offload error injection */ +#define ARP_ERRTEST_REPLY_PEER 0x1 +#define ARP_ERRTEST_REPLY_HOST 0x2 +#define ARP_MULTIHOMING_MAX 8 /* Maximum local host IP addresses */ +#define ND_MULTIHOMING_MAX 8 /* Maximum local host IP addresses */ +/* Arp offload statistic counts */ struct arp_ol_stats_t { - uint32 host_ip_entries; - uint32 host_ip_overflow; + uint32 host_ip_entries; /* Host IP table addresses (more than one if multihomed) */ + uint32 host_ip_overflow; /* Host IP table additions skipped due to overflow */ - uint32 arp_table_entries; - uint32 arp_table_overflow; + uint32 arp_table_entries; /* ARP table entries */ + uint32 arp_table_overflow; /* ARP table additions skipped due to overflow */ - uint32 host_request; - uint32 host_reply; - uint32 host_service; + uint32 host_request; /* ARP requests from host */ + uint32 host_reply; /* ARP replies from host */ + uint32 host_service; /* ARP requests from host serviced by ARP Agent */ - uint32 peer_request; - uint32 peer_request_drop; - uint32 peer_reply; - uint32 peer_reply_drop; - uint32 peer_service; + uint32 peer_request; /* ARP requests received from network */ + uint32 peer_request_drop; /* ARP requests from network that were dropped */ + uint32 peer_reply; /* ARP replies received from network */ + uint32 peer_reply_drop; /* ARP replies from network that were dropped */ + uint32 peer_service; /* ARP request from host serviced by ARP Agent */ }; +/* NS offload statistic counts */ +struct nd_ol_stats_t { + uint32 host_ip_entries; /* Host IP table addresses (more than one if multihomed) */ + uint32 host_ip_overflow; /* Host IP table additions skipped due to overflow */ + uint32 peer_request; /* NS requests received from network */ + uint32 peer_request_drop; /* NS requests from network that were dropped */ + uint32 peer_reply_drop; /* NA replies from network that were dropped */ + uint32 peer_service; /* NS request from host serviced by firmware */ +}; +/* + * Keep-alive packet offloading. + */ - +/* NAT keep-alive packets format: specifies the re-transmission period, the packet + * length, and packet contents. + */ typedef struct wl_keep_alive_pkt { - uint32 period_msec; - uint16 len_bytes; - uint8 data[1]; + uint32 period_msec; /* Retransmission period (0 to disable packet re-transmits) */ + uint16 len_bytes; /* Size of packet to transmit (0 to disable packet re-transmits) */ + uint8 data[1]; /* Variable length packet to transmit. Contents should include + * entire ethernet packet (enet header, IP header, UDP header, + * and UDP payload) in network byte order. + */ } wl_keep_alive_pkt_t; -#define WL_KEEP_ALIVE_FIXED_LEN OFFSETOF(wl_keep_alive_pkt_t, data) - - - - -#define MAX_WAKE_PACKET_BYTES 128 - - -typedef struct pm_wake_packet { - uint32 status; - uint32 pattern_id; - uint32 original_packet_size; - uint32 saved_packet_size; - uchar packet[MAX_WAKE_PACKET_BYTES]; -} pm_wake_packet_t; - - - -#define PKT_FILTER_MODE_FORWARD_ON_MATCH 1 - -#define PKT_FILTER_MODE_DISABLE 2 - -#define PKT_FILTER_MODE_PKT_CACHE_ON_MATCH 4 - -#define PKT_FILTER_MODE_PKT_FORWARD_OFF_DEFAULT 8 +#define WL_KEEP_ALIVE_FIXED_LEN OFFSETOF(wl_keep_alive_pkt_t, data) +/* + * Dongle pattern matching filter. + */ +/* Packet filter types. Currently, only pattern matching is supported. */ typedef enum wl_pkt_filter_type { - WL_PKT_FILTER_TYPE_PATTERN_MATCH, - WL_PKT_FILTER_TYPE_MAGIC_PATTERN_MATCH + WL_PKT_FILTER_TYPE_PATTERN_MATCH /* Pattern matching filter */ } wl_pkt_filter_type_t; #define WL_PKT_FILTER_TYPE wl_pkt_filter_type_t - +/* Pattern matching filter. Specifies an offset within received packets to + * start matching, the pattern to match, the size of the pattern, and a bitmask + * that indicates which bits within the pattern should be matched. + */ typedef struct wl_pkt_filter_pattern { - uint32 offset; - uint32 size_bytes; - uint8 mask_and_pattern[1]; + uint32 offset; /* Offset within received packet to start pattern matching. + * Offset '0' is the first byte of the ethernet header. + */ + uint32 size_bytes; /* Size of the pattern. Bitmask must be the same size. */ + uint8 mask_and_pattern[1]; /* Variable length mask and pattern data. mask starts + * at offset 0. Pattern immediately follows mask. + */ } wl_pkt_filter_pattern_t; - +/* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */ typedef struct wl_pkt_filter { - uint32 id; - uint32 type; - uint32 negate_match; - union { - wl_pkt_filter_pattern_t pattern; + uint32 id; /* Unique filter id, specified by app. */ + uint32 type; /* Filter type (WL_PKT_FILTER_TYPE_xxx). */ + uint32 negate_match; /* Negate the result of filter matches */ + union { /* Filter definitions */ + wl_pkt_filter_pattern_t pattern; /* Pattern matching filter */ } u; } wl_pkt_filter_t; -#define WL_PKT_FILTER_FIXED_LEN OFFSETOF(wl_pkt_filter_t, u) -#define WL_PKT_FILTER_PATTERN_FIXED_LEN OFFSETOF(wl_pkt_filter_pattern_t, mask_and_pattern) - +#define WL_PKT_FILTER_FIXED_LEN OFFSETOF(wl_pkt_filter_t, u) +#define WL_PKT_FILTER_PATTERN_FIXED_LEN OFFSETOF(wl_pkt_filter_pattern_t, mask_and_pattern) +/* IOVAR "pkt_filter_enable" parameter. */ typedef struct wl_pkt_filter_enable { - uint32 id; - uint32 enable; + uint32 id; /* Unique filter id */ + uint32 enable; /* Enable/disable bool */ } wl_pkt_filter_enable_t; - +/* IOVAR "pkt_filter_list" parameter. Used to retrieve a list of installed filters. */ typedef struct wl_pkt_filter_list { - uint32 num; - wl_pkt_filter_t filter[1]; + uint32 num; /* Number of installed packet filters */ + wl_pkt_filter_t filter[1]; /* Variable array of packet filters. */ } wl_pkt_filter_list_t; -#define WL_PKT_FILTER_LIST_FIXED_LEN OFFSETOF(wl_pkt_filter_list_t, filter) - +#define WL_PKT_FILTER_LIST_FIXED_LEN OFFSETOF(wl_pkt_filter_list_t, filter) +/* IOVAR "pkt_filter_stats" parameter. Used to retrieve debug statistics. */ typedef struct wl_pkt_filter_stats { - uint32 num_pkts_matched; - uint32 num_pkts_forwarded; - uint32 num_pkts_discarded; + uint32 num_pkts_matched; /* # filter matches for specified filter id */ + uint32 num_pkts_forwarded; /* # packets fwded from dongle to host for all filters */ + uint32 num_pkts_discarded; /* # packets discarded by dongle for all filters */ } wl_pkt_filter_stats_t; - +/* Sequential Commands ioctl */ typedef struct wl_seq_cmd_ioctl { - uint32 cmd; - uint32 len; + uint32 cmd; /* common ioctl definition */ + uint32 len; /* length of user buffer */ } wl_seq_cmd_ioctl_t; -#define WL_SEQ_CMD_ALIGN_BYTES 4 - +#define WL_SEQ_CMD_ALIGN_BYTES 4 +/* These are the set of get IOCTLs that should be allowed when using + * IOCTL sequence commands. These are issued implicitly by wl.exe each time + * it is invoked. We never want to buffer these, or else wl.exe will stop working. + */ #define WL_SEQ_CMDS_GET_IOCTL_FILTER(cmd) \ - (((cmd) == WLC_GET_MAGIC) || \ - ((cmd) == WLC_GET_VERSION) || \ - ((cmd) == WLC_GET_AP) || \ + (((cmd) == WLC_GET_MAGIC) || \ + ((cmd) == WLC_GET_VERSION) || \ + ((cmd) == WLC_GET_AP) || \ ((cmd) == WLC_GET_INSTANCE)) +/* + * Packet engine interface + */ +#define WL_PKTENG_PER_TX_START 0x01 +#define WL_PKTENG_PER_TX_STOP 0x02 +#define WL_PKTENG_PER_RX_START 0x04 +#define WL_PKTENG_PER_RX_WITH_ACK_START 0x05 +#define WL_PKTENG_PER_TX_WITH_ACK_START 0x06 +#define WL_PKTENG_PER_RX_STOP 0x08 +#define WL_PKTENG_PER_MASK 0xff -#define WL_PKTENG_PER_TX_START 0x01 -#define WL_PKTENG_PER_TX_STOP 0x02 -#define WL_PKTENG_PER_RX_START 0x04 -#define WL_PKTENG_PER_RX_WITH_ACK_START 0x05 -#define WL_PKTENG_PER_TX_WITH_ACK_START 0x06 -#define WL_PKTENG_PER_RX_STOP 0x08 -#define WL_PKTENG_PER_MASK 0xff - -#define WL_PKTENG_SYNCHRONOUS 0x100 +#define WL_PKTENG_SYNCHRONOUS 0x100 /* synchronous flag */ typedef struct wl_pkteng { uint32 flags; - uint32 delay; - uint32 nframes; - uint32 length; - uint8 seqno; - struct ether_addr dest; - struct ether_addr src; + uint32 delay; /* Inter-packet delay */ + uint32 nframes; /* Number of frames */ + uint32 length; /* Packet length */ + uint8 seqno; /* Enable/disable sequence no. */ + struct ether_addr dest; /* Destination address */ + struct ether_addr src; /* Source address */ } wl_pkteng_t; -#define NUM_80211b_RATES 4 -#define NUM_80211ag_RATES 8 -#define NUM_80211n_RATES 32 -#define NUM_80211_RATES (NUM_80211b_RATES+NUM_80211ag_RATES+NUM_80211n_RATES) +#define NUM_80211b_RATES 4 +#define NUM_80211ag_RATES 8 +#define NUM_80211n_RATES 32 +#define NUM_80211_RATES (NUM_80211b_RATES+NUM_80211ag_RATES+NUM_80211n_RATES) typedef struct wl_pkteng_stats { - uint32 lostfrmcnt; - int32 rssi; - int32 snr; + uint32 lostfrmcnt; /* RX PER test: no of frames lost (skip seqno) */ + int32 rssi; /* RSSI */ + int32 snr; /* signal to noise ratio */ uint16 rxpktcnt[NUM_80211_RATES+1]; } wl_pkteng_stats_t; +#define WL_WOWL_MAGIC (1 << 0) /* Wakeup on Magic packet */ +#define WL_WOWL_NET (1 << 1) /* Wakeup on Netpattern */ +#define WL_WOWL_DIS (1 << 2) /* Wakeup on loss-of-link due to Disassoc/Deauth */ +#define WL_WOWL_RETR (1 << 3) /* Wakeup on retrograde TSF */ +#define WL_WOWL_BCN (1 << 4) /* Wakeup on loss of beacon */ +#define WL_WOWL_TST (1 << 5) /* Wakeup after test */ +#define WL_WOWL_M1 (1 << 6) /* Wakeup after PTK refresh */ +#define WL_WOWL_EAPID (1 << 7) /* Wakeup after receipt of EAP-Identity Req */ +#define WL_WOWL_PME_GPIO (1 << 8) /* Wakeind via PME(0) or GPIO(1) */ +#define WL_WOWL_KEYROT (1 << 14) /* If the bit is set, use key rotaton */ +#define WL_WOWL_BCAST (1 << 15) /* If the bit is set, frm received was bcast frame */ -#define WL_WOWL_MAGIC (1 << 0) -#define WL_WOWL_NET (1 << 1) -#define WL_WOWL_DIS (1 << 2) -#define WL_WOWL_RETR (1 << 3) -#define WL_WOWL_BCN (1 << 4) -#define WL_WOWL_TST (1 << 5) -#define WL_WOWL_M1 (1 << 6) -#define WL_WOWL_EAPID (1 << 7) -#define WL_WOWL_KEYROT (1 << 14) -#define WL_WOWL_BCAST (1 << 15) - -#define MAGIC_PKT_MINLEN 102 +#define MAGIC_PKT_MINLEN 102 /* Magic pkt min length is 6 * 0xFF + 16 * ETHER_ADDR_LEN */ typedef struct { - uint masksize; - uint offset; - uint patternoffset; - uint patternsize; - ulong id; - - + uint masksize; /* Size of the mask in #of bytes */ + uint offset; /* Offset to start looking for the packet in # of bytes */ + uint patternoffset; /* Offset of start of pattern in the structure */ + uint patternsize; /* Size of the pattern itself in #of bytes */ + ulong id; /* id */ + uint reasonsize; /* Size of the wakeup reason code */ + /* Mask follows the structure above */ + /* Pattern follows the mask is at 'patternoffset' from the start */ } wl_wowl_pattern_t; typedef struct { - uint count; - wl_wowl_pattern_t pattern[1]; + uint count; + wl_wowl_pattern_t pattern[1]; } wl_wowl_pattern_list_t; typedef struct { - uint8 pci_wakeind; - uint16 ucode_wakeind; + uint8 pci_wakeind; /* Whether PCI PMECSR PMEStatus bit was set */ + uint16 ucode_wakeind; /* What wakeup-event indication was set by ucode */ } wl_wowl_wakeind_t; - +/* per AC rate control related data structure */ typedef struct wl_txrate_class { - uint8 init_rate; - uint8 min_rate; - uint8 max_rate; + uint8 init_rate; + uint8 min_rate; + uint8 max_rate; } wl_txrate_class_t; - -#define WLC_OBSS_SCAN_PASSIVE_DWELL_DEFAULT 20 -#define WLC_OBSS_SCAN_PASSIVE_DWELL_MIN 5 -#define WLC_OBSS_SCAN_PASSIVE_DWELL_MAX 1000 -#define WLC_OBSS_SCAN_ACTIVE_DWELL_DEFAULT 10 -#define WLC_OBSS_SCAN_ACTIVE_DWELL_MIN 10 -#define WLC_OBSS_SCAN_ACTIVE_DWELL_MAX 1000 -#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_DEFAULT 300 -#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_MIN 10 -#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_MAX 900 -#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_DEFAULT 5 -#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_MIN 5 -#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_MAX 100 -#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_DEFAULT 200 -#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_MIN 200 -#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_MAX 10000 -#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_DEFAULT 20 -#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_MIN 20 -#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_MAX 10000 -#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_DEFAULT 25 -#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_MIN 0 -#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_MAX 100 - - +/* Overlap BSS Scan parameters default, minimum, maximum */ +#define WLC_OBSS_SCAN_PASSIVE_DWELL_DEFAULT 20 /* unit TU */ +#define WLC_OBSS_SCAN_PASSIVE_DWELL_MIN 5 /* unit TU */ +#define WLC_OBSS_SCAN_PASSIVE_DWELL_MAX 1000 /* unit TU */ +#define WLC_OBSS_SCAN_ACTIVE_DWELL_DEFAULT 10 /* unit TU */ +#define WLC_OBSS_SCAN_ACTIVE_DWELL_MIN 10 /* unit TU */ +#define WLC_OBSS_SCAN_ACTIVE_DWELL_MAX 1000 /* unit TU */ +#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_DEFAULT 300 /* unit Sec */ +#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_MIN 10 /* unit Sec */ +#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_MAX 900 /* unit Sec */ +#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_DEFAULT 5 +#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_MIN 5 +#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_MAX 100 +#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_DEFAULT 200 /* unit TU */ +#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_MIN 200 /* unit TU */ +#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_MAX 10000 /* unit TU */ +#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_DEFAULT 20 /* unit TU */ +#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_MIN 20 /* unit TU */ +#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_MAX 10000 /* unit TU */ +#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_DEFAULT 25 /* unit percent */ +#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_MIN 0 /* unit percent */ +#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_MAX 100 /* unit percent */ + +/* structure for Overlap BSS scan arguments */ typedef struct wl_obss_scan_arg { - int16 passive_dwell; - int16 active_dwell; - int16 bss_widthscan_interval; - int16 passive_total; - int16 active_total; - int16 chanwidth_transition_delay; - int16 activity_threshold; + int16 passive_dwell; + int16 active_dwell; + int16 bss_widthscan_interval; + int16 passive_total; + int16 active_total; + int16 chanwidth_transition_delay; + int16 activity_threshold; } wl_obss_scan_arg_t; -#define WL_OBSS_SCAN_PARAM_LEN sizeof(wl_obss_scan_arg_t) -#define WL_MIN_NUM_OBSS_SCAN_ARG 7 +#define WL_OBSS_SCAN_PARAM_LEN sizeof(wl_obss_scan_arg_t) +#define WL_MIN_NUM_OBSS_SCAN_ARG 7 /* minimum number of arguments required for OBSS Scan */ -#define WL_COEX_INFO_MASK 0x07 -#define WL_COEX_INFO_REQ 0x01 -#define WL_COEX_40MHZ_INTOLERANT 0x02 -#define WL_COEX_WIDTH20 0x04 +#define WL_COEX_INFO_MASK 0x07 +#define WL_COEX_INFO_REQ 0x01 +#define WL_COEX_40MHZ_INTOLERANT 0x02 +#define WL_COEX_WIDTH20 0x04 -#define WLC_RSSI_INVALID 0 +#define WLC_RSSI_INVALID 0 /* invalid RSSI value */ #define MAX_RSSI_LEVELS 8 - +/* RSSI event notification configuration. */ typedef struct wl_rssi_event { - uint32 rate_limit_msec; - uint8 num_rssi_levels; - int8 rssi_levels[MAX_RSSI_LEVELS]; + uint32 rate_limit_msec; /* # of events posted to application will be limited to + * one per specified period (0 to disable rate limit). + */ + uint8 num_rssi_levels; /* Number of entries in rssi_levels[] below */ + int8 rssi_levels[MAX_RSSI_LEVELS]; /* Variable number of RSSI levels. An event + * will be posted each time the RSSI of received + * beacons/packets crosses a level. + */ } wl_rssi_event_t; typedef struct wl_action_obss_coex_req { @@ -2254,36 +3988,97 @@ typedef struct wl_action_obss_coex_req { } wl_action_obss_coex_req_t; -#define EXTLOG_CUR_VER 0x0100 +/* IOVar parameter block for small MAC address array with type indicator */ +#define WL_IOV_MAC_PARAM_LEN 4 -#define MAX_ARGSTR_LEN 18 - - -#define LOG_MODULE_COMMON 0x0001 -#define LOG_MODULE_ASSOC 0x0002 -#define LOG_MODULE_EVENT 0x0004 -#define LOG_MODULE_MAX 3 +#define WL_IOV_PKTQ_LOG_PRECS 16 +typedef struct { + uint32 num_addrs; + char addr_type[WL_IOV_MAC_PARAM_LEN]; + struct ether_addr ea[WL_IOV_MAC_PARAM_LEN]; +} wl_iov_mac_params_t; -#define WL_LOG_LEVEL_DISABLE 0 -#define WL_LOG_LEVEL_ERR 1 -#define WL_LOG_LEVEL_WARN 2 -#define WL_LOG_LEVEL_INFO 3 -#define WL_LOG_LEVEL_MAX WL_LOG_LEVEL_INFO +/* Parameter block for PKTQ_LOG statistics */ +typedef struct { + uint32 requested; /* packets requested to be stored */ + uint32 stored; /* packets stored */ + uint32 saved; /* packets saved, + because a lowest priority queue has given away one packet + */ + uint32 selfsaved; /* packets saved, + because an older packet from the same queue has been dropped + */ + uint32 full_dropped; /* packets dropped, + because pktq is full with higher precedence packets + */ + uint32 dropped; /* packets dropped because pktq per that precedence is full */ + uint32 sacrificed; /* packets dropped, + in order to save one from a queue of a highest priority + */ + uint32 busy; /* packets droped because of hardware/transmission error */ + uint32 retry; /* packets re-sent because they were not received */ + uint32 ps_retry; /* packets retried again prior to moving power save mode */ + uint32 retry_drop; /* packets finally dropped after retry limit */ + uint32 max_avail; /* the high-water mark of the queue capacity for packets - + goes to zero as queue fills + */ + uint32 max_used; /* the high-water mark of the queue utilisation for packets - + increases with use ('inverse' of max_avail) + */ + uint32 queue_capacity; /* the maximum capacity of the queue */ +} pktq_log_counters_v01_t; + +#define sacrified sacrificed -#define LOG_FLAG_EVENT 1 +typedef struct { + uint8 num_prec[WL_IOV_MAC_PARAM_LEN]; + pktq_log_counters_v01_t counters[WL_IOV_MAC_PARAM_LEN][WL_IOV_PKTQ_LOG_PRECS]; + char headings[1]; +} pktq_log_format_v01_t; -#define LOG_ARGTYPE_NULL 0 -#define LOG_ARGTYPE_STR 1 -#define LOG_ARGTYPE_INT 2 -#define LOG_ARGTYPE_INT_STR 3 -#define LOG_ARGTYPE_STR_INT 4 +typedef struct { + uint32 version; + wl_iov_mac_params_t params; + union { + pktq_log_format_v01_t v01; + } pktq_log; +} wl_iov_pktq_log_t; + + +/* **** EXTLOG **** */ +#define EXTLOG_CUR_VER 0x0100 + +#define MAX_ARGSTR_LEN 18 /* At least big enough for storing ETHER_ADDR_STR_LEN */ + +/* log modules (bitmap) */ +#define LOG_MODULE_COMMON 0x0001 +#define LOG_MODULE_ASSOC 0x0002 +#define LOG_MODULE_EVENT 0x0004 +#define LOG_MODULE_MAX 3 /* Update when adding module */ + +/* log levels */ +#define WL_LOG_LEVEL_DISABLE 0 +#define WL_LOG_LEVEL_ERR 1 +#define WL_LOG_LEVEL_WARN 2 +#define WL_LOG_LEVEL_INFO 3 +#define WL_LOG_LEVEL_MAX WL_LOG_LEVEL_INFO /* Update when adding level */ + +/* flag */ +#define LOG_FLAG_EVENT 1 + +/* log arg_type */ +#define LOG_ARGTYPE_NULL 0 +#define LOG_ARGTYPE_STR 1 /* %s */ +#define LOG_ARGTYPE_INT 2 /* %d */ +#define LOG_ARGTYPE_INT_STR 3 /* %d...%s */ +#define LOG_ARGTYPE_STR_INT 4 /* %s...%d */ typedef struct wlc_extlog_cfg { int max_number; - uint16 module; + uint16 module; /* bitmap */ uint8 level; uint8 flag; uint16 version; @@ -2313,15 +4108,18 @@ typedef struct wlc_extlog_results { } wlc_extlog_results_t; typedef struct log_idstr { - uint16 id; - uint16 flag; - uint8 arg_type; - const char *fmt_str; + uint16 id; + uint16 flag; + uint8 arg_type; + const char *fmt_str; } log_idstr_t; -#define FMTSTRF_USER 1 - +#define FMTSTRF_USER 1 +/* flat ID definitions + * New definitions HAVE TO BE ADDED at the end of the table. Otherwise, it will + * affect backward compatibility with pre-existing apps + */ typedef enum { FMTSTR_DRIVER_UP_ID = 0, FMTSTR_DRIVER_DOWN_ID = 1, @@ -2358,62 +4156,92 @@ typedef enum { #ifdef DONGLEOVERLAYS typedef struct { - uint32 flags_idx; - uint32 offset; - uint32 len; - + uint32 flags_idx; /* lower 8 bits: overlay index; upper 24 bits: flags */ + uint32 offset; /* offset into overlay region to write code */ + uint32 len; /* overlay code len */ + /* overlay code follows this struct */ } wl_ioctl_overlay_t; #define OVERLAY_IDX_MASK 0x000000ff #define OVERLAY_IDX_SHIFT 0 #define OVERLAY_FLAGS_MASK 0xffffff00 #define OVERLAY_FLAGS_SHIFT 8 - +/* overlay written to device memory immediately after loading the base image */ #define OVERLAY_FLAG_POSTLOAD 0x100 - +/* defer overlay download until the device responds w/WLC_E_OVL_DOWNLOAD event */ #define OVERLAY_FLAG_DEFER_DL 0x200 - +/* overlay downloaded prior to the host going to sleep */ #define OVERLAY_FLAG_PRESLEEP 0x400 #define OVERLAY_DOWNLOAD_CHUNKSIZE 1024 -#endif - +#endif /* DONGLEOVERLAYS */ +/* no default structure packing */ #include - +/* require strict packing */ #include - -#define VNDR_IE_CMD_LEN 4 - - -#define VNDR_IE_BEACON_FLAG 0x1 -#define VNDR_IE_PRBRSP_FLAG 0x2 -#define VNDR_IE_ASSOCRSP_FLAG 0x4 -#define VNDR_IE_AUTHRSP_FLAG 0x8 -#define VNDR_IE_PRBREQ_FLAG 0x10 -#define VNDR_IE_ASSOCREQ_FLAG 0x20 -#define VNDR_IE_CUSTOM_FLAG 0x100 - -#define VNDR_IE_INFO_HDR_LEN (sizeof(uint32)) +/* Structures and constants used for "vndr_ie" IOVar interface */ +#define VNDR_IE_CMD_LEN 4 /* length of the set command string: + * "add", "del" (+ NUL) + */ + +/* 802.11 Mgmt Packet flags */ +#define VNDR_IE_BEACON_FLAG 0x1 +#define VNDR_IE_PRBRSP_FLAG 0x2 +#define VNDR_IE_ASSOCRSP_FLAG 0x4 +#define VNDR_IE_AUTHRSP_FLAG 0x8 +#define VNDR_IE_PRBREQ_FLAG 0x10 +#define VNDR_IE_ASSOCREQ_FLAG 0x20 +#define VNDR_IE_IWAPID_FLAG 0x40 /* vendor IE in IW advertisement protocol ID field */ +#define VNDR_IE_CUSTOM_FLAG 0x100 /* allow custom IE id */ + +#define VNDR_IE_INFO_HDR_LEN (sizeof(uint32)) typedef BWL_PRE_PACKED_STRUCT struct { - uint32 pktflag; - vndr_ie_t vndr_ie_data; + uint32 pktflag; /* bitmask indicating which packet(s) contain this IE */ + vndr_ie_t vndr_ie_data; /* vendor IE data */ } BWL_POST_PACKED_STRUCT vndr_ie_info_t; typedef BWL_PRE_PACKED_STRUCT struct { - int iecount; - vndr_ie_info_t vndr_ie_list[1]; + int iecount; /* number of entries in the vndr_ie_list[] array */ + vndr_ie_info_t vndr_ie_list[1]; /* variable size list of vndr_ie_info_t structs */ } BWL_POST_PACKED_STRUCT vndr_ie_buf_t; typedef BWL_PRE_PACKED_STRUCT struct { - char cmd[VNDR_IE_CMD_LEN]; - vndr_ie_buf_t vndr_ie_buffer; + char cmd[VNDR_IE_CMD_LEN]; /* vndr_ie IOVar set command : "add", "del" + NUL */ + vndr_ie_buf_t vndr_ie_buffer; /* buffer containing Vendor IE list information */ } BWL_POST_PACKED_STRUCT vndr_ie_setbuf_t; +/* tag_ID/length/value_buffer tuple */ +typedef BWL_PRE_PACKED_STRUCT struct { + uint8 id; + uint8 len; + uint8 data[1]; +} BWL_POST_PACKED_STRUCT tlv_t; +typedef BWL_PRE_PACKED_STRUCT struct { + uint32 pktflag; /* bitmask indicating which packet(s) contain this IE */ + tlv_t ie_data; /* IE data */ +} BWL_POST_PACKED_STRUCT ie_info_t; +typedef BWL_PRE_PACKED_STRUCT struct { + int iecount; /* number of entries in the ie_list[] array */ + ie_info_t ie_list[1]; /* variable size list of ie_info_t structs */ +} BWL_POST_PACKED_STRUCT ie_buf_t; + +typedef BWL_PRE_PACKED_STRUCT struct { + char cmd[VNDR_IE_CMD_LEN]; /* ie IOVar set command : "add" + NUL */ + ie_buf_t ie_buffer; /* buffer containing IE list information */ +} BWL_POST_PACKED_STRUCT ie_setbuf_t; + +typedef BWL_PRE_PACKED_STRUCT struct { + uint32 pktflag; /* bitmask indicating which packet(s) contain this IE */ + uint8 id; /* IE type */ +} BWL_POST_PACKED_STRUCT ie_getbuf_t; + +/* structures used to define format of wps ie data from probe requests */ +/* passed up to applications via iovar "prbreq_wpsie" */ typedef BWL_PRE_PACKED_STRUCT struct sta_prbreq_wps_ie_hdr { struct ether_addr staAddr; uint16 ieLen; @@ -2432,21 +4260,22 @@ typedef BWL_PRE_PACKED_STRUCT struct sta_prbreq_wps_ie_list { #ifdef WLMEDIA_TXFAILEVENT typedef BWL_PRE_PACKED_STRUCT struct { - char dest[ETHER_ADDR_LEN]; - uint8 prio; - uint8 flags; - uint32 tsf_l; - uint32 tsf_h; - uint16 rates; - uint16 txstatus; + char dest[ETHER_ADDR_LEN]; /* destination MAC */ + uint8 prio; /* Packet Priority */ + uint8 flags; /* Flags */ + uint32 tsf_l; /* TSF timer low */ + uint32 tsf_h; /* TSF timer high */ + uint16 rates; /* Main Rates */ + uint16 txstatus; /* TX Status */ } BWL_POST_PACKED_STRUCT txfailinfo_t; -#endif +#endif /* WLMEDIA_TXFAILEVENT */ +/* no strict structure packing */ #include - -#define ASSERTLOG_CUR_VER 0x0100 -#define MAX_ASSRTSTR_LEN 64 +/* Global ASSERT Logging */ +#define ASSERTLOG_CUR_VER 0x0100 +#define MAX_ASSRTSTR_LEN 64 typedef struct assert_record { uint32 time; @@ -2461,32 +4290,61 @@ typedef struct assertlog_results { assert_record_t logs[1]; } assertlog_results_t; -#define LOGRRC_FIX_LEN 8 +#define LOGRRC_FIX_LEN 8 #define IOBUF_ALLOWED_NUM_OF_LOGREC(type, len) ((len - LOGRRC_FIX_LEN)/sizeof(type)) - - - - -#define CHANIM_DISABLE 0 -#define CHANIM_DETECT 1 -#define CHANIM_ACT 2 -#define CHANIM_MODE_MAX 2 - - -#define APCS_IOCTL 1 -#define APCS_CHANIM 2 -#define APCS_CSTIMER 3 -#define APCS_BTA 4 - - -#define CHANIM_ACS_RECORD 10 - - +#ifdef BCMWAPI_WAI +#define IV_LEN 16 +struct wapi_sta_msg_t +{ + uint16 msg_type; + uint16 datalen; + uint8 vap_mac[6]; + uint8 reserve_data1[2]; + uint8 sta_mac[6]; + uint8 reserve_data2[2]; + uint8 gsn[IV_LEN]; + uint8 wie[256]; +}; +#endif /* BCMWAPI_WAI */ + +/* channel interference measurement (chanim) related defines */ + +/* chanim mode */ +#define CHANIM_DISABLE 0 /* disabled */ +#define CHANIM_DETECT 1 /* detection only */ +#define CHANIM_EXT 2 /* external state machine */ +#define CHANIM_ACT 3 /* full internal state machine, detect + act */ +#define CHANIM_MODE_MAX 4 + +/* define for apcs reason code */ +#define APCS_INIT 0 +#define APCS_IOCTL 1 +#define APCS_CHANIM 2 +#define APCS_CSTIMER 3 +#define APCS_BTA 4 + +/* number of ACS record entries */ +#define CHANIM_ACS_RECORD 10 + +/* CHANIM */ +#define CCASTATS_TXDUR 0 +#define CCASTATS_INBSS 1 +#define CCASTATS_OBSS 2 +#define CCASTATS_NOCTG 3 +#define CCASTATS_NOPKT 4 +#define CCASTATS_DOZE 5 +#define CCASTATS_TXOP 6 +#define CCASTATS_GDTXDUR 7 +#define CCASTATS_BDTXDUR 8 +#define CCASTATS_MAX 9 + +/* chanim acs record */ typedef struct { bool valid; uint8 trigger; chanspec_t selected_chspc; + int8 bgnoise; uint32 glitch_cnt; uint8 ccastats; uint timestamp; @@ -2498,23 +4356,62 @@ typedef struct { uint timestamp; } wl_acs_record_t; +typedef struct chanim_stats { + uint32 glitchcnt; /* normalized as per second count */ + uint32 badplcp; /* normalized as per second count */ + uint8 ccastats[CCASTATS_MAX]; /* normalized as 0-255 */ + int8 bgnoise; /* background noise level (in dBm) */ + chanspec_t chanspec; + uint32 timestamp; +} chanim_stats_t; +#define WL_CHANIM_STATS_VERSION 1 +#define WL_CHANIM_COUNT_ALL 0xff +#define WL_CHANIM_COUNT_ONE 0x1 -#define SMFS_VERSION 1 +typedef struct { + uint32 buflen; + uint32 version; + uint32 count; + chanim_stats_t stats[1]; +} wl_chanim_stats_t; + +#define WL_CHANIM_STATS_FIXED_LEN OFFSETOF(wl_chanim_stats_t, stats) + +/* Noise measurement metrics. */ +#define NOISE_MEASURE_KNOISE 0x1 +/* scb probe parameter */ +typedef struct { + uint32 scb_timeout; + uint32 scb_activity_time; + uint32 scb_max_probe; +} wl_scb_probe_t; + +/* ap tpc modes */ +#define AP_TPC_OFF 0 +#define AP_TPC_BSS_PWR 1 /* BSS power control */ +#define AP_TPC_AP_PWR 2 /* AP power control */ +#define AP_TPC_AP_BSS_PWR 3 /* Both AP and BSS power control */ +#define AP_TPC_MAX_LINK_MARGIN 127 + +/* structure/defines for selective mgmt frame (smf) stats support */ + +#define SMFS_VERSION 1 +/* selected mgmt frame (smf) stats element */ typedef struct wl_smfs_elem { uint32 count; - uint16 code; + uint16 code; /* SC or RC code */ } wl_smfs_elem_t; typedef struct wl_smf_stats { uint32 version; - uint16 length; + uint16 length; /* reserved for future usage */ uint8 type; uint8 codetype; uint32 ignored_cnt; uint32 malformed_cnt; - uint32 count_total; + uint32 count_total; /* count included the interested group */ wl_smfs_elem_t elem[1]; } wl_smf_stats_t; @@ -2525,9 +4422,9 @@ enum { SMFS_CODETYPE_RC }; - -#define SMFS_CODE_MALFORMED 0xFFFE -#define SMFS_CODE_IGNORED 0xFFFD +/* reuse two number in the sc/rc space */ +#define SMFS_CODE_MALFORMED 0xFFFE +#define SMFS_CODE_IGNORED 0xFFFD typedef enum smfs_type { SMFS_TYPE_AUTH, @@ -2545,7 +4442,7 @@ typedef enum smfs_type { #define PHYMON_VERSION 1 typedef struct wl_phycal_core_state { - + /* Tx IQ/LO calibration coeffs */ int16 tx_iqlocal_a; int16 tx_iqlocal_b; int8 tx_iqlocal_ci; @@ -2557,19 +4454,19 @@ typedef struct wl_phycal_core_state { int8 tx_iqlocal_fi; int8 tx_iqlocal_fq; - + /* Rx IQ calibration coeffs */ int16 rx_iqcal_a; int16 rx_iqcal_b; - uint8 tx_iqlocal_pwridx; - uint32 papd_epsilon_table[64]; - int16 papd_epsilon_offset; - uint8 curr_tx_pwrindex; - int8 idle_tssi; - int8 est_tx_pwr; - int8 est_rx_pwr; - uint16 rx_gaininfo; - uint16 init_gaincode; + uint8 tx_iqlocal_pwridx; /* Tx Power Index for Tx IQ/LO calibration */ + uint32 papd_epsilon_table[64]; /* PAPD epsilon table */ + int16 papd_epsilon_offset; /* PAPD epsilon offset */ + uint8 curr_tx_pwrindex; /* Tx power index */ + int8 idle_tssi; /* Idle TSSI */ + int8 est_tx_pwr; /* Estimated Tx Power (dB) */ + int8 est_rx_pwr; /* Estimated Rx Power (dB) from RSSI */ + uint16 rx_gaininfo; /* Rx gain applied on last Rx pkt */ + uint16 init_gaincode; /* initgain required for ACI */ int8 estirr_tx; int8 estirr_rx; @@ -2577,193 +4474,280 @@ typedef struct wl_phycal_core_state { typedef struct wl_phycal_state { int version; - int8 num_phy_cores; - int8 curr_temperature; - chanspec_t chspec; - bool aci_state; - uint16 crsminpower; - uint16 crsminpowerl; - uint16 crsminpoweru; + int8 num_phy_cores; /* number of cores */ + int8 curr_temperature; /* on-chip temperature sensor reading */ + chanspec_t chspec; /* channspec for this state */ + bool aci_state; /* ACI state: ON/OFF */ + uint16 crsminpower; /* crsminpower required for ACI */ + uint16 crsminpowerl; /* crsminpowerl required for ACI */ + uint16 crsminpoweru; /* crsminpoweru required for ACI */ wl_phycal_core_state_t phycal_core[1]; } wl_phycal_state_t; #define WL_PHYCAL_STAT_FIXED_LEN OFFSETOF(wl_phycal_state_t, phycal_core) -#endif - -#ifdef WLDSTA -typedef struct wl_dsta_if { - struct ether_addr addr; -} wl_dsta_if_t; -#endif - -#ifdef WLP2P +#endif /* PHYMON */ +/* discovery state */ typedef struct wl_p2p_disc_st { - uint8 state; - chanspec_t chspec; - uint16 dwell; + uint8 state; /* see state */ + chanspec_t chspec; /* valid in listen state */ + uint16 dwell; /* valid in listen state, in ms */ } wl_p2p_disc_st_t; +/* state */ +#define WL_P2P_DISC_ST_SCAN 0 +#define WL_P2P_DISC_ST_LISTEN 1 +#define WL_P2P_DISC_ST_SEARCH 2 -#define WL_P2P_DISC_ST_SCAN 0 -#define WL_P2P_DISC_ST_LISTEN 1 -#define WL_P2P_DISC_ST_SEARCH 2 - - +/* scan request */ typedef struct wl_p2p_scan { - uint8 type; + uint8 type; /* 'S' for WLC_SCAN, 'E' for "escan" */ uint8 reserved[3]; - + /* scan or escan parms... */ } wl_p2p_scan_t; - +/* i/f request */ typedef struct wl_p2p_if { struct ether_addr addr; - uint8 type; - chanspec_t chspec; + uint8 type; /* see i/f type */ + chanspec_t chspec; /* for p2p_ifadd GO */ } wl_p2p_if_t; +/* i/f type */ +#define WL_P2P_IF_CLIENT 0 +#define WL_P2P_IF_GO 1 +#define WL_P2P_IF_DYNBCN_GO 2 +#define WL_P2P_IF_DEV 3 -#define WL_P2P_IF_CLIENT 0 -#define WL_P2P_IF_GO 1 -#define WL_P2P_IF_DYNBCN_GO 2 -#define WL_P2P_IF_DEV 3 - - +/* i/f query */ typedef struct wl_p2p_ifq { uint bsscfgidx; char ifname[BCM_MSG_IFNAME_MAX]; } wl_p2p_ifq_t; - +/* OppPS & CTWindow */ typedef struct wl_p2p_ops { - uint8 ops; - uint8 ctw; + uint8 ops; /* 0: disable 1: enable */ + uint8 ctw; /* >= 10 */ } wl_p2p_ops_t; - +/* absence and presence request */ typedef struct wl_p2p_sched_desc { uint32 start; uint32 interval; uint32 duration; - uint32 count; + uint32 count; /* see count */ } wl_p2p_sched_desc_t; - -#define WL_P2P_SCHED_RSVD 0 -#define WL_P2P_SCHED_REPEAT 255 +/* count */ +#define WL_P2P_SCHED_RSVD 0 +#define WL_P2P_SCHED_REPEAT 255 /* anything > 255 will be treated as 255 */ typedef struct wl_p2p_sched { - uint8 type; - uint8 action; - uint8 option; + uint8 type; /* see schedule type */ + uint8 action; /* see schedule action */ + uint8 option; /* see schedule option */ wl_p2p_sched_desc_t desc[1]; } wl_p2p_sched_t; -#define WL_P2P_SCHED_FIXED_LEN 3 - - -#define WL_P2P_SCHED_TYPE_ABS 0 -#define WL_P2P_SCHED_TYPE_REQ_ABS 1 - - -#define WL_P2P_SCHED_ACTION_NONE 0 -#define WL_P2P_SCHED_ACTION_DOZE 1 - -#define WL_P2P_SCHED_ACTION_GOOFF 2 - -#define WL_P2P_SCHED_ACTION_RESET 255 - - -#define WL_P2P_SCHED_OPTION_NORMAL 0 -#define WL_P2P_SCHED_OPTION_BCNPCT 1 - -#define WL_P2P_SCHED_OPTION_TSFOFS 2 - +#define WL_P2P_SCHED_FIXED_LEN 3 + +/* schedule type */ +#define WL_P2P_SCHED_TYPE_ABS 0 /* Scheduled Absence */ +#define WL_P2P_SCHED_TYPE_REQ_ABS 1 /* Requested Absence */ + +/* schedule action during absence periods (for WL_P2P_SCHED_ABS type) */ +#define WL_P2P_SCHED_ACTION_NONE 0 /* no action */ +#define WL_P2P_SCHED_ACTION_DOZE 1 /* doze */ +/* schedule option - WL_P2P_SCHED_TYPE_REQ_ABS */ +#define WL_P2P_SCHED_ACTION_GOOFF 2 /* turn off GO beacon/prbrsp functions */ +/* schedule option - WL_P2P_SCHED_TYPE_XXX */ +#define WL_P2P_SCHED_ACTION_RESET 255 /* reset */ + +/* schedule option - WL_P2P_SCHED_TYPE_ABS */ +#define WL_P2P_SCHED_OPTION_NORMAL 0 /* normal start/interval/duration/count */ +#define WL_P2P_SCHED_OPTION_BCNPCT 1 /* percentage of beacon interval */ +/* schedule option - WL_P2P_SCHED_TYPE_REQ_ABS */ +#define WL_P2P_SCHED_OPTION_TSFOFS 2 /* normal start/internal/duration/count with + * start being an offset of the 'current' TSF + */ + +/* feature flags */ +#define WL_P2P_FEAT_GO_CSA (1 << 0) /* GO moves with the STA using CSA method */ +#define WL_P2P_FEAT_GO_NOLEGACY (1 << 1) /* GO does not probe respond to non-p2p probe + * requests + */ +#define WL_P2P_FEAT_RESTRICT_DEV_RESP (1 << 2) /* Restrict p2p dev interface from responding */ + +#ifdef WLNIC +/* nic_cnx iovar */ +typedef struct wl_nic_cnx { + uint8 opcode; + struct ether_addr addr; + /* the following are valid for WL_NIC_CNX_CONN */ + uint8 SSID_len; + uint8 SSID[32]; + struct ether_addr abssid; + uint8 join_period; +} wl_nic_cnx_t; + +/* opcode */ +#define WL_NIC_CNX_ADD 0 /* add NIC connection */ +#define WL_NIC_CNX_DEL 1 /* delete NIC connection */ +#define WL_NIC_CNX_IDX 2 /* query NIC connection index */ +#define WL_NIC_CNX_CONN 3 /* join/create network */ +#define WL_NIC_CNX_DIS 4 /* disconnect from network */ + +/* nic_cfg iovar */ +typedef struct wl_nic_cfg { + uint8 version; + uint8 beacon_mode; + uint16 beacon_interval; + uint8 diluted_beacon_period; + uint8 repeat_EQC; + uint8 scan_length; + uint8 scan_interval; + uint8 scan_probability; + uint8 awake_window_length; + int8 TSF_correction; + uint8 ASID; + uint8 channel_usage_mode; +} wl_nic_cfg_t; + +/* version */ +#define WL_NIC_CFG_VER 1 + +/* beacon_mode */ +#define WL_NIC_BCN_NORM 0 +#define WL_NIC_BCN_DILUTED 1 + +/* channel_usage_mode */ +#define WL_NIC_CHAN_STATIC 0 +#define WL_NIC_CHAN_CYCLE 1 + +/* nic_cfg iovar */ +typedef struct wl_nic_frm { + uint8 type; + struct ether_addr da; + uint8 body[1]; +} wl_nic_frm_t; -#define WL_P2P_FEAT_GO_CSA (1 << 0) -#define WL_P2P_FEAT_GO_NOLEGACY (1 << 1) -#define WL_P2P_FEAT_RESTRICT_DEV_RESP (1 << 2) -#endif +/* type */ +#define WL_NIC_FRM_MYNET 1 +#define WL_NIC_FRM_ACTION 2 +/* i/f query */ +typedef struct wl_nic_ifq { + uint bsscfgidx; + char ifname[BCM_MSG_IFNAME_MAX]; +} wl_nic_ifq_t; +#endif /* WLNIC */ -#define BCM_ACTION_RFAWARE 0x77 +/* RFAWARE def */ +#define BCM_ACTION_RFAWARE 0x77 #define BCM_ACTION_RFAWARE_DCS 0x01 +/* DCS reason code define */ +#define BCM_DCS_IOVAR 0x1 +#define BCM_DCS_UNKNOWN 0xFF +typedef struct wl_bcmdcs_data { + uint reason; + chanspec_t chspec; +} wl_bcmdcs_data_t; -#define WL_11N_2x2 1 -#define WL_11N_3x3 3 -#define WL_11N_4x4 4 - - -#define WLFEATURE_DISABLE_11N 0x00000001 -#define WLFEATURE_DISABLE_11N_STBC_TX 0x00000002 -#define WLFEATURE_DISABLE_11N_STBC_RX 0x00000004 -#define WLFEATURE_DISABLE_11N_SGI_TX 0x00000008 -#define WLFEATURE_DISABLE_11N_SGI_RX 0x00000010 -#define WLFEATURE_DISABLE_11N_AMPDU_TX 0x00000020 -#define WLFEATURE_DISABLE_11N_AMPDU_RX 0x00000040 -#define WLFEATURE_DISABLE_11N_GF 0x00000080 - - -#define LQ_IDX_LAST 3 -#define MCS_INDEX_SIZE 33 - -#define LQ_IDX_MIN 0 -#define LQ_IDX_MAX 1 -#define LQ_IDX_AVG 2 -#define LQ_IDX_SUM 2 -#define LQ_IDX_LAST 3 -#define LQ_STOP_MONITOR 0 -#define LQ_START_MONITOR 1 - -#define LINKQUAL_V1 0x01 - -struct wl_lq { - int32 enable; - int32 rssi[LQ_IDX_LAST]; - int32 rssicnt; - int32 snr[LQ_IDX_LAST]; - uint32 nsamples; - uint8 isvalid; - uint8 version; -}; - -typedef struct wl_lq wl_lq_t; -typedef struct wl_lq wl_lq_stats_t; - +/* n-mode support capability */ +/* 2x2 includes both 1x1 & 2x2 devices + * reserved #define 2 for future when we want to separate 1x1 & 2x2 and + * control it independently + */ +#define WL_11N_2x2 1 +#define WL_11N_3x3 3 +#define WL_11N_4x4 4 + +/* define 11n feature disable flags */ +#define WLFEATURE_DISABLE_11N 0x00000001 +#define WLFEATURE_DISABLE_11N_STBC_TX 0x00000002 +#define WLFEATURE_DISABLE_11N_STBC_RX 0x00000004 +#define WLFEATURE_DISABLE_11N_SGI_TX 0x00000008 +#define WLFEATURE_DISABLE_11N_SGI_RX 0x00000010 +#define WLFEATURE_DISABLE_11N_AMPDU_TX 0x00000020 +#define WLFEATURE_DISABLE_11N_AMPDU_RX 0x00000040 +#define WLFEATURE_DISABLE_11N_GF 0x00000080 + +/* Proxy STA modes */ +#define PSTA_MODE_DISABLED 0 +#define PSTA_MODE_PROXY 1 +#define PSTA_MODE_REPEATER 2 + + +/* NAT configuration */ typedef struct { - struct ether_addr ea; - uint8 ac_cat; - uint8 num_pkts; -} wl_mac_ratehisto_cmd_t; - + uint32 ipaddr; /* interface ip address */ + uint32 ipaddr_mask; /* interface ip address mask */ + uint32 ipaddr_gateway; /* gateway ip address */ + uint8 mac_gateway[6]; /* gateway mac address */ + uint32 ipaddr_dns; /* DNS server ip address, valid only for public if */ + uint8 mac_dns[6]; /* DNS server mac address, valid only for public if */ + uint8 GUID[38]; /* interface GUID */ +} nat_if_info_t; typedef struct { - uint32 rate[WLC_MAXRATE + 1]; - uint32 mcs_index[MCS_INDEX_SIZE]; - uint32 tsf_timer[2][2]; -} wl_mac_ratehisto_res_t; - -#ifdef PROP_TXSTATUS + uint op; /* operation code */ + bool pub_if; /* set for public if, clear for private if */ + nat_if_info_t if_info; /* interface info */ +} nat_cfg_t; +/* op code in nat_cfg */ +#define NAT_OP_ENABLE 1 /* enable NAT on given interface */ +#define NAT_OP_DISABLE 2 /* disable NAT on given interface */ +#define NAT_OP_DISABLE_ALL 3 /* disable NAT on all interfaces */ -#define WLFC_FLAGS_RSSI_SIGNALS 1 +/* NAT state */ +#define NAT_STATE_ENABLED 1 /* NAT is enabled */ +#define NAT_STATE_DISABLED 2 /* NAT is disabled */ +typedef struct { + int state; /* NAT state returned */ +} nat_state_t; -#define WLFC_FLAGS_XONXOFF_SIGNALS 2 - +#ifdef PROP_TXSTATUS +/* Bit definitions for tlv iovar */ +/* + * enable RSSI signals: + * WLFC_CTL_TYPE_RSSI + */ +#define WLFC_FLAGS_RSSI_SIGNALS 0x0001 -#define WLFC_FLAGS_CREDIT_STATUS_SIGNALS 4 +/* enable (if/mac_open, if/mac_close,, mac_add, mac_del) signals: + * + * WLFC_CTL_TYPE_MAC_OPEN + * WLFC_CTL_TYPE_MAC_CLOSE + * + * WLFC_CTL_TYPE_INTERFACE_OPEN + * WLFC_CTL_TYPE_INTERFACE_CLOSE + * + * WLFC_CTL_TYPE_MACDESC_ADD + * WLFC_CTL_TYPE_MACDESC_DEL + * + */ +#define WLFC_FLAGS_XONXOFF_SIGNALS 0x0002 -#define WLFC_FLAGS_HOST_PROPTXSTATUS_ACTIVE 8 -#define WLFC_FLAGS_PSQ_GENERATIONFSM_ENABLE 16 -#define WLFC_FLAGS_PSQ_ZERO_BUFFER_ENABLE 32 -#endif +/* enable (status, fifo_credit, mac_credit) signals + * WLFC_CTL_TYPE_MAC_REQUEST_CREDIT + * WLFC_CTL_TYPE_TXSTATUS + * WLFC_CTL_TYPE_FIFO_CREDITBACK + */ +#define WLFC_FLAGS_CREDIT_STATUS_SIGNALS 0x0004 -#define BTA_STATE_LOG_SZ 64 +#define WLFC_FLAGS_HOST_PROPTXSTATUS_ACTIVE 0x0008 +#define WLFC_FLAGS_PSQ_GENERATIONFSM_ENABLE 0x0010 +#define WLFC_FLAGS_PSQ_ZERO_BUFFER_ENABLE 0x0020 +#define WLFC_FLAGS_HOST_RXRERODER_ACTIVE 0x0040 +#endif /* PROP_TXSTATUS */ +#define BTA_STATE_LOG_SZ 64 +/* BTAMP Statemachine states */ enum { HCIReset = 1, HCIReadLocalAMPInfo, @@ -2786,10 +4770,10 @@ typedef struct flush_txfifo { struct ether_addr ea; } flush_txfifo_t; -#define CHANNEL_5G_LOW_START 36 -#define CHANNEL_5G_MID_START 52 -#define CHANNEL_5G_HIGH_START 100 -#define CHANNEL_5G_UPPER_START 149 +#define CHANNEL_5G_LOW_START 36 /* 5G low (36..48) CDD enable/disable bit mask */ +#define CHANNEL_5G_MID_START 52 /* 5G mid (52..64) CDD enable/disable bit mask */ +#define CHANNEL_5G_HIGH_START 100 /* 5G high (100..140) CDD enable/disable bit mask */ +#define CHANNEL_5G_UPPER_START 149 /* 5G upper (149..161) CDD enable/disable bit mask */ enum { SPATIAL_MODE_2G_IDX = 0, @@ -2800,4 +4784,11 @@ enum { SPATIAL_MODE_MAX_IDX }; -#endif +/* IOVAR "mempool" parameter. Used to retrieve a list of memory pool statistics. */ +typedef struct wl_mempool_stats { + int num; /* Number of memory pools */ + bcm_mp_stats_t s[1]; /* Variable array of memory pool stats. */ +} wl_mempool_stats_t; + + +#endif /* _wlioctl_h_ */ diff --git a/drivers/net/wireless/bcmdhd/linux_osl.c b/drivers/net/wireless/bcmdhd/linux_osl.c index 4ef7bf7b24d..5cc3a876779 100644 --- a/drivers/net/wireless/bcmdhd/linux_osl.c +++ b/drivers/net/wireless/bcmdhd/linux_osl.c @@ -1,9 +1,9 @@ /* * Linux OS Independent Layer * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,10 +21,9 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: linux_osl.c,v 1.168.2.7 2011-01-27 17:01:13 $ + * $Id: linux_osl.c 309193 2012-01-19 00:03:57Z $ */ - #define LINUX_PORT #include @@ -40,6 +39,7 @@ #include #endif + #include #define PCI_CFG_RETRY 10 @@ -49,7 +49,7 @@ #ifdef CONFIG_DHD_USE_STATIC_BUF #define STATIC_BUF_MAX_NUM 16 -#define STATIC_BUF_SIZE (PAGE_SIZE * 2) +#define STATIC_BUF_SIZE (PAGE_SIZE*2) #define STATIC_BUF_TOTAL_LEN (STATIC_BUF_MAX_NUM * STATIC_BUF_SIZE) typedef struct bcm_static_buf { @@ -70,13 +70,14 @@ typedef struct bcm_static_pkt { } bcm_static_pkt_t; static bcm_static_pkt_t *bcm_static_skb = 0; -#endif +#endif typedef struct bcm_mem_link { struct bcm_mem_link *prev; struct bcm_mem_link *next; uint size; int line; + void *osh; char file[BCM_MEM_FILENAME_LEN]; } bcm_mem_link_t; @@ -91,6 +92,8 @@ struct osl_info { uint failed; uint bustype; bcm_mem_link_t *dbgmem_list; + spinlock_t dbgmem_lock; + spinlock_t pktalloc_lock; }; @@ -170,14 +173,8 @@ osl_t * osl_attach(void *pdev, uint bustype, bool pkttag) { osl_t *osh; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) - gfp_t flags; - flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL; - osh = kmalloc(sizeof(osl_t), flags); -#else osh = kmalloc(sizeof(osl_t), GFP_ATOMIC); -#endif ASSERT(osh); bzero(osh, sizeof(osl_t)); @@ -189,6 +186,7 @@ osl_attach(void *pdev, uint bustype, bool pkttag) atomic_set(&osh->malloced, 0); osh->failed = 0; osh->dbgmem_list = NULL; + spin_lock_init(&(osh->dbgmem_lock)); osh->pdev = pdev; osh->pub.pkttag = pkttag; osh->bustype = bustype; @@ -220,6 +218,7 @@ osl_attach(void *pdev, uint bustype, bool pkttag) else printk("alloc static buf at %x!\n", (unsigned int)bcm_static_buf); + sema_init(&bcm_static_buf->static_sem, 1); bcm_static_buf->buf_ptr = (unsigned char *)bcm_static_buf + STATIC_BUF_SIZE; @@ -231,13 +230,15 @@ osl_attach(void *pdev, uint bustype, bool pkttag) bcm_static_skb = (bcm_static_pkt_t *)((char *)bcm_static_buf + 2048); skb_buff_ptr = dhd_os_prealloc(osh, 4, 0); - bcopy(skb_buff_ptr, bcm_static_skb, sizeof(struct sk_buff *) * 16); + bcopy(skb_buff_ptr, bcm_static_skb, sizeof(struct sk_buff *)*16); for (i = 0; i < STATIC_PKT_MAX_NUM * 2; i++) bcm_static_skb->pkt_use[i] = 0; sema_init(&bcm_static_skb->osl_pkt_sem, 1); } -#endif +#endif + + spin_lock_init(&(osh->pktalloc_lock)); return osh; } @@ -248,6 +249,15 @@ osl_detach(osl_t *osh) if (osh == NULL) return; +#ifdef CONFIG_DHD_USE_STATIC_BUF + if (bcm_static_buf) { + bcm_static_buf = 0; + } + if (bcm_static_skb) { + bcm_static_skb = 0; + } +#endif + ASSERT(osh->magic == OS_HANDLE_MAGIC); kfree(osh); } @@ -255,7 +265,7 @@ osl_detach(osl_t *osh) static struct sk_buff *osl_alloc_skb(unsigned int len) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25) - gfp_t flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL; + gfp_t flags = GFP_ATOMIC; return __dev_alloc_skb(len, flags); #else @@ -265,20 +275,31 @@ static struct sk_buff *osl_alloc_skb(unsigned int len) #ifdef CTFPOOL +#ifdef CTFPOOL_SPINLOCK +#define CTFPOOL_LOCK(ctfpool, flags) spin_lock_irqsave(&(ctfpool)->lock, flags) +#define CTFPOOL_UNLOCK(ctfpool, flags) spin_unlock_irqrestore(&(ctfpool)->lock, flags) +#else +#define CTFPOOL_LOCK(ctfpool, flags) spin_lock_bh(&(ctfpool)->lock) +#define CTFPOOL_UNLOCK(ctfpool, flags) spin_unlock_bh(&(ctfpool)->lock) +#endif + void * osl_ctfpool_add(osl_t *osh) { struct sk_buff *skb; +#ifdef CTFPOOL_SPINLOCK + unsigned long flags; +#endif if ((osh == NULL) || (osh->ctfpool == NULL)) return NULL; - spin_lock_bh(&osh->ctfpool->lock); + CTFPOOL_LOCK(osh->ctfpool, flags); ASSERT(osh->ctfpool->curr_obj <= osh->ctfpool->max_obj); if (osh->ctfpool->curr_obj == osh->ctfpool->max_obj) { - spin_unlock_bh(&osh->ctfpool->lock); + CTFPOOL_UNLOCK(osh->ctfpool, flags); return NULL; } @@ -287,7 +308,7 @@ osl_ctfpool_add(osl_t *osh) if (skb == NULL) { printf("%s: skb alloc of len %d failed\n", __FUNCTION__, osh->ctfpool->obj_size); - spin_unlock_bh(&osh->ctfpool->lock); + CTFPOOL_UNLOCK(osh->ctfpool, flags); return NULL; } @@ -303,7 +324,7 @@ osl_ctfpool_add(osl_t *osh) PKTFAST(osh, skb) = FASTBUF; - spin_unlock_bh(&osh->ctfpool->lock); + CTFPOOL_UNLOCK(osh->ctfpool, flags); return skb; } @@ -326,14 +347,7 @@ osl_ctfpool_replenish(osl_t *osh, uint thresh) int32 osl_ctfpool_init(osl_t *osh, uint numobj, uint size) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) - gfp_t flags; - - flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL; - osh->ctfpool = kmalloc(sizeof(ctfpool_t), flags); -#else osh->ctfpool = kmalloc(sizeof(ctfpool_t), GFP_ATOMIC); -#endif ASSERT(osh->ctfpool); bzero(osh->ctfpool, sizeof(ctfpool_t)); @@ -356,11 +370,14 @@ void osl_ctfpool_cleanup(osl_t *osh) { struct sk_buff *skb, *nskb; +#ifdef CTFPOOL_SPINLOCK + unsigned long flags; +#endif if ((osh == NULL) || (osh->ctfpool == NULL)) return; - spin_lock_bh(&osh->ctfpool->lock); + CTFPOOL_LOCK(osh->ctfpool, flags); skb = osh->ctfpool->head; @@ -373,7 +390,7 @@ osl_ctfpool_cleanup(osl_t *osh) ASSERT(osh->ctfpool->curr_obj == 0); osh->ctfpool->head = NULL; - spin_unlock_bh(&osh->ctfpool->lock); + CTFPOOL_UNLOCK(osh->ctfpool, flags); kfree(osh->ctfpool); osh->ctfpool = NULL; @@ -412,16 +429,19 @@ static inline struct sk_buff * osl_pktfastget(osl_t *osh, uint len) { struct sk_buff *skb; +#ifdef CTFPOOL_SPINLOCK + unsigned long flags; +#endif if (osh->ctfpool == NULL) return NULL; - spin_lock_bh(&osh->ctfpool->lock); + CTFPOOL_LOCK(osh->ctfpool, flags); if (osh->ctfpool->head == NULL) { ASSERT(osh->ctfpool->curr_obj == 0); osh->ctfpool->slow_allocs++; - spin_unlock_bh(&osh->ctfpool->lock); + CTFPOOL_UNLOCK(osh->ctfpool, flags); return NULL; } @@ -434,7 +454,7 @@ osl_pktfastget(osl_t *osh, uint len) osh->ctfpool->fast_allocs++; osh->ctfpool->curr_obj--; ASSERT(CTFPOOLHEAD(osh, skb) == (struct sock *)osh->ctfpool->head); - spin_unlock_bh(&osh->ctfpool->lock); + CTFPOOL_UNLOCK(osh->ctfpool, flags); skb->next = skb->prev = NULL; @@ -450,24 +470,74 @@ osl_pktfastget(osl_t *osh, uint len) return skb; } +#endif + +struct sk_buff * BCMFASTPATH +osl_pkt_tonative(osl_t *osh, void *pkt) +{ +#ifndef WL_UMK + struct sk_buff *nskb; + unsigned long flags; #endif + if (osh->pub.pkttag) + bzero((void*)((struct sk_buff *)pkt)->cb, OSL_PKTTAG_SZ); + +#ifndef WL_UMK + + for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) { + spin_lock_irqsave(&osh->pktalloc_lock, flags); + osh->pub.pktalloced--; + spin_unlock_irqrestore(&osh->pktalloc_lock, flags); + } +#endif + return (struct sk_buff *)pkt; +} + + +void * BCMFASTPATH +osl_pkt_frmnative(osl_t *osh, void *pkt) +{ +#ifndef WL_UMK + struct sk_buff *nskb; + unsigned long flags; +#endif + + if (osh->pub.pkttag) + bzero((void*)((struct sk_buff *)pkt)->cb, OSL_PKTTAG_SZ); + +#ifndef WL_UMK + + for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) { + spin_lock_irqsave(&osh->pktalloc_lock, flags); + osh->pub.pktalloced++; + spin_unlock_irqrestore(&osh->pktalloc_lock, flags); + } +#endif + return (void *)pkt; +} + void * BCMFASTPATH osl_pktget(osl_t *osh, uint len) { struct sk_buff *skb; + unsigned long flags; #ifdef CTFPOOL + skb = osl_pktfastget(osh, len); if ((skb != NULL) || ((skb = osl_alloc_skb(len)) != NULL)) { -#else +#else if ((skb = osl_alloc_skb(len))) { -#endif +#endif skb_put(skb, len); skb->priority = 0; + + spin_lock_irqsave(&osh->pktalloc_lock, flags); osh->pub.pktalloced++; + spin_unlock_irqrestore(&osh->pktalloc_lock, flags); } return ((void*) skb); @@ -478,20 +548,9 @@ static inline void osl_pktfastfree(osl_t *osh, struct sk_buff *skb) { ctfpool_t *ctfpool; - - ctfpool = (ctfpool_t *)CTFPOOLPTR(osh, skb); - ASSERT(ctfpool != NULL); - - - spin_lock_bh(&ctfpool->lock); - skb->next = (struct sk_buff *)ctfpool->head; - ctfpool->head = (void *)skb; - - ctfpool->fast_frees++; - ctfpool->curr_obj++; - - ASSERT(ctfpool->curr_obj <= ctfpool->max_obj); - spin_unlock_bh(&ctfpool->lock); +#ifdef CTFPOOL_SPINLOCK + unsigned long flags; +#endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14) skb->tstamp.tv.sec = 0; @@ -505,6 +564,20 @@ osl_pktfastfree(osl_t *osh, struct sk_buff *skb) memset(skb->cb, 0, sizeof(skb->cb)); skb->ip_summed = 0; skb->destructor = NULL; + + ctfpool = (ctfpool_t *)CTFPOOLPTR(osh, skb); + ASSERT(ctfpool != NULL); + + + CTFPOOL_LOCK(ctfpool, flags); + skb->next = (struct sk_buff *)ctfpool->head; + ctfpool->head = (void *)skb; + + ctfpool->fast_frees++; + ctfpool->curr_obj++; + + ASSERT(ctfpool->curr_obj <= ctfpool->max_obj); + CTFPOOL_UNLOCK(ctfpool, flags); } #endif @@ -513,20 +586,24 @@ void BCMFASTPATH osl_pktfree(osl_t *osh, void *p, bool send) { struct sk_buff *skb, *nskb; + unsigned long flags; skb = (struct sk_buff*) p; if (send && osh->pub.tx_fn) osh->pub.tx_fn(osh->pub.tx_ctx, p, 0); + PKTDBG_TRACE(osh, (void *) skb, PKTLIST_PKTFREE); + while (skb) { nskb = skb->next; skb->next = NULL; + #ifdef CTFPOOL - if (PKTISFAST(osh, skb)) + if ((PKTISFAST(osh, skb)) && (atomic_read(&skb->users) == 1)) osl_pktfastfree(osh, skb); else { #else @@ -540,21 +617,21 @@ osl_pktfree(osl_t *osh, void *p, bool send) dev_kfree_skb(skb); } - + spin_lock_irqsave(&osh->pktalloc_lock, flags); osh->pub.pktalloced--; - + spin_unlock_irqrestore(&osh->pktalloc_lock, flags); skb = nskb; } } #ifdef CONFIG_DHD_USE_STATIC_BUF -void * +void* osl_pktget_static(osl_t *osh, uint len) { - int i; + int i = 0; struct sk_buff *skb; - if (!bcm_static_skb || (len > (PAGE_SIZE * 2))) { + if (len > (PAGE_SIZE*2)) { printk("%s: attempt to allocate huge packet (0x%x)\n", __FUNCTION__, len); return osl_pktget(osh, len); } @@ -569,10 +646,10 @@ osl_pktget_static(osl_t *osh, uint len) if (i != STATIC_PKT_MAX_NUM) { bcm_static_skb->pkt_use[i] = 1; + up(&bcm_static_skb->osl_pkt_sem); skb = bcm_static_skb->skb_4k[i]; skb->tail = skb->data + len; skb->len = len; - up(&bcm_static_skb->osl_pkt_sem); return skb; } } @@ -585,10 +662,10 @@ osl_pktget_static(osl_t *osh, uint len) if (i != STATIC_PKT_MAX_NUM) { bcm_static_skb->pkt_use[i+STATIC_PKT_MAX_NUM] = 1; + up(&bcm_static_skb->osl_pkt_sem); skb = bcm_static_skb->skb_8k[i]; skb->tail = skb->data + len; skb->len = len; - up(&bcm_static_skb->osl_pkt_sem); return skb; } @@ -602,14 +679,9 @@ osl_pktfree_static(osl_t *osh, void *p, bool send) { int i; - if (!bcm_static_skb) { - osl_pktfree(osh, p, send); - return; - } - - down(&bcm_static_skb->osl_pkt_sem); for (i = 0; i < STATIC_PKT_MAX_NUM; i++) { if (p == bcm_static_skb->skb_4k[i]) { + down(&bcm_static_skb->osl_pkt_sem); bcm_static_skb->pkt_use[i] = 0; up(&bcm_static_skb->osl_pkt_sem); return; @@ -618,15 +690,14 @@ osl_pktfree_static(osl_t *osh, void *p, bool send) for (i = 0; i < STATIC_PKT_MAX_NUM; i++) { if (p == bcm_static_skb->skb_8k[i]) { + down(&bcm_static_skb->osl_pkt_sem); bcm_static_skb->pkt_use[i + STATIC_PKT_MAX_NUM] = 0; up(&bcm_static_skb->osl_pkt_sem); return; } } - up(&bcm_static_skb->osl_pkt_sem); - osl_pktfree(osh, p, send); - return; + return osl_pktfree(osh, p, send); } #endif @@ -689,6 +760,15 @@ osl_pci_slot(osl_t *osh) return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn); } + +struct pci_dev * +osl_pci_device(osl_t *osh) +{ + ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); + + return osh->pdev; +} + static void osl_pcmcia_attr(osl_t *osh, uint offset, char *buf, int size, bool write) { @@ -710,18 +790,46 @@ void * osl_malloc(osl_t *osh, uint size) { void *addr; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) - gfp_t flags; if (osh) ASSERT(osh->magic == OS_HANDLE_MAGIC); - flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL; - if ((addr = kmalloc(size, flags)) == NULL) { -#else - if ((addr = kmalloc(size, GFP_ATOMIC)) == NULL) { +#ifdef CONFIG_DHD_USE_STATIC_BUF + if (bcm_static_buf) + { + int i = 0; + if ((size >= PAGE_SIZE)&&(size <= STATIC_BUF_SIZE)) + { + down(&bcm_static_buf->static_sem); + + for (i = 0; i < STATIC_BUF_MAX_NUM; i++) + { + if (bcm_static_buf->buf_use[i] == 0) + break; + } + + if (i == STATIC_BUF_MAX_NUM) + { + up(&bcm_static_buf->static_sem); + printk("all static buff in use!\n"); + goto original; + } + + bcm_static_buf->buf_use[i] = 1; + up(&bcm_static_buf->static_sem); + + bzero(bcm_static_buf->buf_ptr+STATIC_BUF_SIZE*i, size); + if (osh) + atomic_add(size, &osh->malloced); + + return ((void *)(bcm_static_buf->buf_ptr+STATIC_BUF_SIZE*i)); + } + } +original: #endif + + if ((addr = kmalloc(size, GFP_ATOMIC)) == NULL) { if (osh) osh->failed++; return (NULL); @@ -735,6 +843,28 @@ osl_malloc(osl_t *osh, uint size) void osl_mfree(osl_t *osh, void *addr, uint size) { +#ifdef CONFIG_DHD_USE_STATIC_BUF + if (bcm_static_buf) + { + if ((addr > (void *)bcm_static_buf) && ((unsigned char *)addr + <= ((unsigned char *)bcm_static_buf + STATIC_BUF_TOTAL_LEN))) + { + int buf_idx = 0; + + buf_idx = ((unsigned char *)addr - bcm_static_buf->buf_ptr)/STATIC_BUF_SIZE; + + down(&bcm_static_buf->static_sem); + bcm_static_buf->buf_use[buf_idx] = 0; + up(&bcm_static_buf->static_sem); + + if (osh) { + ASSERT(osh->magic == OS_HANDLE_MAGIC); + atomic_sub(size, &osh->malloced); + } + return; + } + } +#endif if (osh) { ASSERT(osh->magic == OS_HANDLE_MAGIC); atomic_sub(size, &osh->malloced); @@ -757,7 +887,6 @@ osl_malloc_failed(osl_t *osh) } - uint osl_dma_consistent_align(void) { @@ -807,10 +936,10 @@ osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction) #if defined(BCMASSERT_LOG) void -osl_assert(char *exp, char *file, int line) +osl_assert(const char *exp, const char *file, int line) { char tempbuf[256]; - char *basename; + const char *basename; basename = strrchr(file, '/'); @@ -849,14 +978,12 @@ void * osl_pktdup(osl_t *osh, void *skb) { void * p; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) - gfp_t flags; + unsigned long irqflags; - flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL; - if ((p = skb_clone((struct sk_buff *)skb, flags)) == NULL) -#else - if ((p = skb_clone((struct sk_buff*)skb, GFP_ATOMIC)) == NULL) -#endif + + PKTCTFMAP(osh, skb); + + if ((p = skb_clone((struct sk_buff *)skb, GFP_ATOMIC)) == NULL) return NULL; #ifdef CTFPOOL @@ -877,7 +1004,9 @@ osl_pktdup(osl_t *osh, void *skb) bzero((void*)((struct sk_buff *)p)->cb, OSL_PKTTAG_SZ); + spin_lock_irqsave(&osh->pktalloc_lock, irqflags); osh->pub.pktalloced++; + spin_unlock_irqrestore(&osh->pktalloc_lock, irqflags); return (p); } diff --git a/drivers/net/wireless/bcmdhd/sbutils.c b/drivers/net/wireless/bcmdhd/sbutils.c index 02d1bc0a79d..bc42a2b99af 100644 --- a/drivers/net/wireless/bcmdhd/sbutils.c +++ b/drivers/net/wireless/bcmdhd/sbutils.c @@ -2,9 +2,9 @@ * Misc utility routines for accessing chip-specific features * of the SiliconBackplane-based Broadcom chips. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -22,9 +22,10 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: sbutils.c,v 1.687.2.1 2010-11-29 20:21:56 Exp $ + * $Id: sbutils.c 300516 2011-12-04 17:39:44Z $ */ +#include #include #include #include @@ -113,8 +114,10 @@ sb_write_sbreg(si_info_t *sii, volatile uint32 *sbr, uint32 v) if (BUSTYPE(sii->pub.bustype) == PCMCIA_BUS) { dummy = R_REG(sii->osh, sbr); + BCM_REFERENCE(dummy); W_REG(sii->osh, (volatile uint16 *)sbr, (uint16)(v & 0xffff)); dummy = R_REG(sii->osh, sbr); + BCM_REFERENCE(dummy); W_REG(sii->osh, ((volatile uint16 *)sbr + 1), (uint16)((v >> 16) & 0xffff)); } else W_REG(sii->osh, sbr, v); @@ -787,6 +790,7 @@ sb_core_disable(si_t *sih, uint32 bits) /* set target reject and spin until busy is clear (preserve core-specific bits) */ OR_SBREG(sii, &sb->sbtmstatelow, SBTML_REJ); dummy = R_SBREG(sii, &sb->sbtmstatelow); + BCM_REFERENCE(dummy); OSL_DELAY(1); SPINWAIT((R_SBREG(sii, &sb->sbtmstatehigh) & SBTMH_BUSY), 100000); if (R_SBREG(sii, &sb->sbtmstatehigh) & SBTMH_BUSY) @@ -795,6 +799,7 @@ sb_core_disable(si_t *sih, uint32 bits) if (R_SBREG(sii, &sb->sbidlow) & SBIDL_INIT) { OR_SBREG(sii, &sb->sbimstate, SBIM_RJ); dummy = R_SBREG(sii, &sb->sbimstate); + BCM_REFERENCE(dummy); OSL_DELAY(1); SPINWAIT((R_SBREG(sii, &sb->sbimstate) & SBIM_BY), 100000); } @@ -804,6 +809,7 @@ sb_core_disable(si_t *sih, uint32 bits) (((bits | SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) | SBTML_REJ | SBTML_RESET)); dummy = R_SBREG(sii, &sb->sbtmstatelow); + BCM_REFERENCE(dummy); OSL_DELAY(10); /* don't forget to clear the initiator reject bit */ @@ -846,6 +852,7 @@ sb_core_reset(si_t *sih, uint32 bits, uint32 resetbits) (((bits | resetbits | SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) | SBTML_RESET)); dummy = R_SBREG(sii, &sb->sbtmstatelow); + BCM_REFERENCE(dummy); OSL_DELAY(1); if (R_SBREG(sii, &sb->sbtmstatehigh) & SBTMH_SERR) { @@ -859,11 +866,13 @@ sb_core_reset(si_t *sih, uint32 bits, uint32 resetbits) W_SBREG(sii, &sb->sbtmstatelow, ((bits | resetbits | SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT)); dummy = R_SBREG(sii, &sb->sbtmstatelow); + BCM_REFERENCE(dummy); OSL_DELAY(1); /* leave clock enabled */ W_SBREG(sii, &sb->sbtmstatelow, ((bits | SICF_CLOCK_EN) << SBTML_SICF_SHIFT)); dummy = R_SBREG(sii, &sb->sbtmstatelow); + BCM_REFERENCE(dummy); OSL_DELAY(1); } diff --git a/drivers/net/wireless/bcmdhd/siutils.c b/drivers/net/wireless/bcmdhd/siutils.c index a655ac4ef14..5cfb54e0a0f 100644 --- a/drivers/net/wireless/bcmdhd/siutils.c +++ b/drivers/net/wireless/bcmdhd/siutils.c @@ -2,9 +2,9 @@ * Misc utility routines for accessing chip-specific features * of the SiliconBackplane-based Broadcom chips. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -22,9 +22,10 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: siutils.c,v 1.813.2.36 2011-02-10 23:43:55 $ + * $Id: siutils.c 309908 2012-01-21 00:14:29Z $ */ +#include #include #include #include @@ -54,11 +55,14 @@ static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint uint *origidx, void *regs); + /* global variable to indicate reservation/release of gpio's */ static uint32 si_gpioreservation = 0; /* global flag to prevent shared resources from being initialized multiple times in si_attach() */ +int do_4360_pcie2_war = 0; + /* * Allocate a si handle. * devid - pci device id (used to determine chip#) @@ -117,8 +121,8 @@ si_kattach(osl_t *osh) /* save ticks normalized to ms for si_watchdog_ms() */ if (PMUCTL_ENAB(&ksii.pub)) { - /* based on 32KHz ILP clock */ - wd_msticks = 32; + /* based on 32KHz ILP clock */ + wd_msticks = 32; } else { wd_msticks = ALP_CLOCK / 1000; } @@ -180,7 +184,7 @@ static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin, uint *origidx, void *regs) { - bool pci, pcie; + bool pci, pcie, pcie_gen2 = FALSE; uint i; uint pciidx, pcieidx, pcirev, pcierev; @@ -236,10 +240,12 @@ si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin, pciidx = i; pcirev = crev; pci = TRUE; - } else if (cid == PCIE_CORE_ID) { + } else if ((cid == PCIE_CORE_ID) || (cid == PCIE2_CORE_ID)) { pcieidx = i; pcierev = crev; pcie = TRUE; + if (cid == PCIE2_CORE_ID) + pcie_gen2 = TRUE; } } else if ((BUSTYPE(bustype) == PCMCIA_BUS) && (cid == PCMCIA_CORE_ID)) { @@ -267,7 +273,10 @@ si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin, sii->pub.buscorerev = pcirev; sii->pub.buscoreidx = pciidx; } else if (pcie) { - sii->pub.buscoretype = PCIE_CORE_ID; + if (pcie_gen2) + sii->pub.buscoretype = PCIE2_CORE_ID; + else + sii->pub.buscoretype = PCIE_CORE_ID; sii->pub.buscorerev = pcierev; sii->pub.buscoreidx = pcieidx; } @@ -297,6 +306,7 @@ si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin, + static si_info_t * si_doattach(si_info_t *sii, uint devid, osl_t *osh, void *regs, uint bustype, void *sdh, char **vars, uint *varsz) @@ -327,6 +337,8 @@ si_doattach(si_info_t *sii, uint devid, osl_t *osh, void *regs, if (!GOODCOREADDR(savewin, SI_ENUM_BASE)) savewin = SI_ENUM_BASE; OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, SI_ENUM_BASE); + if (!regs) + return NULL; cc = (chipcregs_t *)regs; } else if ((bustype == SDIO_BUS) || (bustype == SPI_BUS)) { cc = (chipcregs_t *)sii->curmap; @@ -352,37 +364,21 @@ si_doattach(si_info_t *sii, uint devid, osl_t *osh, void *regs, * If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon), * some way of recognizing them needs to be added here. */ + if (!cc) { + SI_ERROR(("%s: chipcommon register space is null \n", __FUNCTION__)); + return NULL; + } w = R_REG(osh, &cc->chipid); sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT; /* Might as wll fill in chip id rev & pkg */ sih->chip = w & CID_ID_MASK; sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT; sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT; - if (CHIPID(sih->chip) == BCM4322_CHIP_ID && (((sih->chipst & CST4322_SPROM_OTP_SEL_MASK) - >> CST4322_SPROM_OTP_SEL_SHIFT) == (CST4322_OTP_PRESENT | - CST4322_SPROM_PRESENT))) { - SI_ERROR(("%s: Invalid setting: both SPROM and OTP strapped.\n", __FUNCTION__)); - return NULL; - } - -#if defined(HW_OOB) - if (CHIPID(sih->chip) == BCM43362_CHIP_ID) { - uint32 gpiocontrol, addr; - addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, gpiocontrol); - gpiocontrol = bcmsdh_reg_read(sdh, addr, 4); - gpiocontrol |= 0x2; - bcmsdh_reg_write(sdh, addr, 4, gpiocontrol); - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10005, 0xf, NULL); - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10006, 0x0, NULL); - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10007, 0x2, NULL); - } -#endif if ((CHIPID(sih->chip) == BCM4329_CHIP_ID) && (sih->chiprev == 0) && (sih->chippkg != BCM4329_289PIN_PKG_ID)) { sih->chippkg = BCM4329_182PIN_PKG_ID; } - sih->issim = IS_SIM(sih->chippkg); /* scan for cores */ @@ -413,12 +409,19 @@ si_doattach(si_info_t *sii, uint devid, osl_t *osh, void *regs, goto exit; } + if (CHIPID(sih->chip) == BCM4322_CHIP_ID && (((sih->chipst & CST4322_SPROM_OTP_SEL_MASK) + >> CST4322_SPROM_OTP_SEL_SHIFT) == (CST4322_OTP_PRESENT | + CST4322_SPROM_PRESENT))) { + SI_ERROR(("%s: Invalid setting: both SPROM and OTP strapped.\n", __FUNCTION__)); + return NULL; + } + /* assume current core is CC */ - if ((sii->pub.ccrev == 0x25) && ((CHIPID(sih->chip) == BCM43234_CHIP_ID || + if ((sii->pub.ccrev == 0x25) && ((CHIPID(sih->chip) == BCM43236_CHIP_ID || CHIPID(sih->chip) == BCM43235_CHIP_ID || - CHIPID(sih->chip) == BCM43236_CHIP_ID || + CHIPID(sih->chip) == BCM43234_CHIP_ID || CHIPID(sih->chip) == BCM43238_CHIP_ID) && - (CHIPREV(sii->pub.chiprev) == 0))) { + (CHIPREV(sii->pub.chiprev) <= 2))) { if ((cc->chipstatus & CST43236_BP_CLK) != 0) { uint clkdiv; @@ -431,21 +434,35 @@ si_doattach(si_info_t *sii, uint devid, osl_t *osh, void *regs, OSL_DELAY(10); } + if (bustype == PCI_BUS) { + + } pvars = NULL; + BCM_REFERENCE(pvars); if (sii->pub.ccrev >= 20) { + uint32 gpiopullup = 0, gpiopulldown = 0; cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); ASSERT(cc != NULL); - W_REG(osh, &cc->gpiopullup, 0); - W_REG(osh, &cc->gpiopulldown, 0); + + /* 4314/43142 has pin muxing, don't clear gpio bits */ + if ((CHIPID(sih->chip) == BCM4314_CHIP_ID) || + (CHIPID(sih->chip) == BCM43142_CHIP_ID)) { + gpiopullup |= 0x402e0; + gpiopulldown |= 0x20500; + } + + W_REG(osh, &cc->gpiopullup, gpiopullup); + W_REG(osh, &cc->gpiopulldown, gpiopulldown); si_setcoreidx(sih, origidx); } - + /* clear any previous epidiag-induced target abort */ + ASSERT(!si_taclear(sih, FALSE)); return (sii); @@ -829,6 +846,16 @@ si_addrspacesize(si_t *sih, uint asidx) } } +void +si_coreaddrspaceX(si_t *sih, uint asidx, uint32 *addr, uint32 *size) +{ + /* Only supported for SOCI_AI */ + if (CHIPTYPE(sih->socitype) == SOCI_AI) + ai_coreaddrspaceX(sih, asidx, addr, size); + else + *size = 0; +} + uint32 si_core_cflags(si_t *sih, uint32 mask, uint32 val) { @@ -1073,7 +1100,7 @@ si_watchdog(si_t *sih, uint ticks) si_setcore(sih, CC_CORE_ID, 0); } - nb = (sih->ccrev < 26) ? 16 : ((sih->ccrev >= 37) ? 32 : 24); + nb = (sih->ccrev < 26) ? 16 : ((sih->ccrev >= 37) ? 32 : 24); /* The mips compiler uses the sllv instruction, * so we specially handle the 32-bit case. */ @@ -1104,6 +1131,11 @@ si_watchdog_ms(si_t *sih, uint32 ms) si_watchdog(sih, wd_msticks * ms); } +bool +si_taclear(si_t *sih, bool details) +{ + return FALSE; +} @@ -1227,6 +1259,7 @@ si_clkctl_init(si_t *sih) si_setcoreidx(sih, origidx); } + /* change logical "focus" to the gpio core for optimized access */ void * si_gpiosetcore(si_t *sih) @@ -1234,7 +1267,12 @@ si_gpiosetcore(si_t *sih) return (si_setcoreidx(sih, SI_CC_IDX)); } -/* mask&set gpiocontrol bits */ +/* + * mask & set gpiocontrol bits. + * If a gpiocontrol bit is set to 0, chipcommon controls the corresponding GPIO pin. + * If a gpiocontrol bit is set to 1, the GPIO pin is no longer a GPIO and becomes dedicated + * to some chip-specific purpose. + */ uint32 si_gpiocontrol(si_t *sih, uint32 mask, uint32 val, uint8 priority) { @@ -1304,10 +1342,6 @@ si_gpioout(si_t *sih, uint32 mask, uint32 val, uint8 priority) uint32 si_gpioreserve(si_t *sih, uint32 gpio_bitmask, uint8 priority) { - si_info_t *sii; - - sii = SI_INFO(sih); - /* only cores on SI_BUS share GPIO's and only applcation users need to * reserve/release GPIO */ @@ -1339,10 +1373,6 @@ si_gpioreserve(si_t *sih, uint32 gpio_bitmask, uint8 priority) uint32 si_gpiorelease(si_t *sih, uint32 gpio_bitmask, uint8 priority) { - si_info_t *sii; - - sii = SI_INFO(sih); - /* only cores on SI_BUS share GPIO's and only applcation users need to * reserve/release GPIO */ @@ -1370,12 +1400,8 @@ si_gpiorelease(si_t *sih, uint32 gpio_bitmask, uint8 priority) uint32 si_gpioin(si_t *sih) { - si_info_t *sii; uint regoff; - sii = SI_INFO(sih); - regoff = 0; - regoff = OFFSETOF(chipcregs_t, gpioin); return (si_corereg(sih, SI_CC_IDX, regoff, 0, 0)); } @@ -1384,12 +1410,8 @@ si_gpioin(si_t *sih) uint32 si_gpiointpolarity(si_t *sih, uint32 mask, uint32 val, uint8 priority) { - si_info_t *sii; uint regoff; - sii = SI_INFO(sih); - regoff = 0; - /* gpios could be shared on router platforms */ if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) { mask = priority ? (si_gpioreservation & mask) : @@ -1405,12 +1427,8 @@ si_gpiointpolarity(si_t *sih, uint32 mask, uint32 val, uint8 priority) uint32 si_gpiointmask(si_t *sih, uint32 mask, uint32 val, uint8 priority) { - si_info_t *sii; uint regoff; - sii = SI_INFO(sih); - regoff = 0; - /* gpios could be shared on router platforms */ if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) { mask = priority ? (si_gpioreservation & mask) : @@ -1426,9 +1444,6 @@ si_gpiointmask(si_t *sih, uint32 mask, uint32 val, uint8 priority) uint32 si_gpioled(si_t *sih, uint32 mask, uint32 val) { - si_info_t *sii; - - sii = SI_INFO(sih); if (sih->ccrev < 16) return 0xffffffff; @@ -1440,10 +1455,6 @@ si_gpioled(si_t *sih, uint32 mask, uint32 val) uint32 si_gpiotimerval(si_t *sih, uint32 mask, uint32 gpiotimerval) { - si_info_t *sii; - - sii = SI_INFO(sih); - if (sih->ccrev < 16) return 0xffffffff; @@ -1454,10 +1465,8 @@ si_gpiotimerval(si_t *sih, uint32 mask, uint32 gpiotimerval) uint32 si_gpiopull(si_t *sih, bool updown, uint32 mask, uint32 val) { - si_info_t *sii; uint offs; - sii = SI_INFO(sih); if (sih->ccrev < 20) return 0xffffffff; @@ -1468,10 +1477,8 @@ si_gpiopull(si_t *sih, bool updown, uint32 mask, uint32 val) uint32 si_gpioevent(si_t *sih, uint regtype, uint32 mask, uint32 val) { - si_info_t *sii; uint offs; - sii = SI_INFO(sih); if (sih->ccrev < 11) return 0xffffffff; @@ -1576,10 +1583,8 @@ si_gpio_handler_process(si_t *sih) uint32 si_gpio_int_enable(si_t *sih, bool enable) { - si_info_t *sii; uint offs; - sii = SI_INFO(sih); if (sih->ccrev < 11) return 0xffffffff; @@ -1590,10 +1595,10 @@ si_gpio_int_enable(si_t *sih, bool enable) /* Return the size of the specified SOCRAM bank */ static uint -socram_banksize(si_info_t *sii, sbsocramregs_t *regs, uint8 index, uint8 mem_type) +socram_banksize(si_info_t *sii, sbsocramregs_t *regs, uint8 idx, uint8 mem_type) { uint banksize, bankinfo; - uint bankidx = index | (mem_type << SOCRAM_BANKIDX_MEMTYPE_SHIFT); + uint bankidx = idx | (mem_type << SOCRAM_BANKIDX_MEMTYPE_SHIFT); ASSERT(mem_type <= SOCRAM_MEMTYPE_DEVRAM); @@ -1604,7 +1609,7 @@ socram_banksize(si_info_t *sii, sbsocramregs_t *regs, uint8 index, uint8 mem_typ } void -si_socdevram(si_t *sih, bool set, uint8 *enable, uint8 *protect) +si_socdevram(si_t *sih, bool set, uint8 *enable, uint8 *protect, uint8 *remap) { si_info_t *sii; uint origidx; @@ -1620,7 +1625,7 @@ si_socdevram(si_t *sih, bool set, uint8 *enable, uint8 *protect) origidx = si_coreidx(sih); if (!set) - *enable = *protect = 0; + *enable = *protect = *remap = 0; /* Switch to SOCRAM core */ if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0))) @@ -1646,10 +1651,14 @@ si_socdevram(si_t *sih, bool set, uint8 *enable, uint8 *protect) if (set) { bankinfo &= ~SOCRAM_BANKINFO_DEVRAMSEL_MASK; bankinfo &= ~SOCRAM_BANKINFO_DEVRAMPRO_MASK; + bankinfo &= ~SOCRAM_BANKINFO_DEVRAMREMAP_MASK; if (*enable) { bankinfo |= (1 << SOCRAM_BANKINFO_DEVRAMSEL_SHIFT); if (*protect) bankinfo |= (1 << SOCRAM_BANKINFO_DEVRAMPRO_SHIFT); + if ((corerev >= 16) && *remap) + bankinfo |= + (1 << SOCRAM_BANKINFO_DEVRAMREMAP_SHIFT); } W_REG(sii->osh, ®s->bankinfo, bankinfo); } @@ -1658,6 +1667,8 @@ si_socdevram(si_t *sih, bool set, uint8 *enable, uint8 *protect) *enable = 1; if (bankinfo & SOCRAM_BANKINFO_DEVRAMPRO_MASK) *protect = 1; + if (bankinfo & SOCRAM_BANKINFO_DEVRAMREMAP_MASK) + *remap = 1; } } } @@ -1672,6 +1683,59 @@ done: INTR_RESTORE(sii, intr_val); } +bool +si_socdevram_remap_isenb(si_t *sih) +{ + si_info_t *sii; + uint origidx; + uint intr_val = 0; + sbsocramregs_t *regs; + bool wasup, remap = FALSE; + uint corerev; + uint32 extcinfo; + uint8 nb; + uint8 i; + uint32 bankidx, bankinfo; + + sii = SI_INFO(sih); + + /* Block ints and save current core */ + INTR_OFF(sii, intr_val); + origidx = si_coreidx(sih); + + /* Switch to SOCRAM core */ + if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0))) + goto done; + + /* Get info for determining size */ + if (!(wasup = si_iscoreup(sih))) + si_core_reset(sih, 0, 0); + + corerev = si_corerev(sih); + if (corerev >= 16) { + extcinfo = R_REG(sii->osh, ®s->extracoreinfo); + nb = ((extcinfo & SOCRAM_DEVRAMBANK_MASK) >> SOCRAM_DEVRAMBANK_SHIFT); + for (i = 0; i < nb; i++) { + bankidx = i | (SOCRAM_MEMTYPE_DEVRAM << SOCRAM_BANKIDX_MEMTYPE_SHIFT); + W_REG(sii->osh, ®s->bankidx, bankidx); + bankinfo = R_REG(sii->osh, ®s->bankinfo); + if (bankinfo & SOCRAM_BANKINFO_DEVRAMREMAP_MASK) { + remap = TRUE; + break; + } + } + } + + /* Return to previous state and core */ + if (!wasup) + si_core_disable(sih, 0); + si_setcoreidx(sih, origidx); + +done: + INTR_RESTORE(sii, intr_val); + return remap; +} + bool si_socdevram_pkg(si_t *sih) { @@ -1729,6 +1793,72 @@ done: return memsize; } +uint32 +si_socdevram_remap_size(si_t *sih) +{ + si_info_t *sii; + uint origidx; + uint intr_val = 0; + uint32 memsize = 0, banksz; + sbsocramregs_t *regs; + bool wasup; + uint corerev; + uint32 extcinfo; + uint8 nb; + uint8 i; + uint32 bankidx, bankinfo; + + sii = SI_INFO(sih); + + /* Block ints and save current core */ + INTR_OFF(sii, intr_val); + origidx = si_coreidx(sih); + + /* Switch to SOCRAM core */ + if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0))) + goto done; + + /* Get info for determining size */ + if (!(wasup = si_iscoreup(sih))) + si_core_reset(sih, 0, 0); + + corerev = si_corerev(sih); + if (corerev >= 16) { + extcinfo = R_REG(sii->osh, ®s->extracoreinfo); + nb = (((extcinfo & SOCRAM_DEVRAMBANK_MASK) >> SOCRAM_DEVRAMBANK_SHIFT)); + + /* + * FIX: A0 Issue: Max addressable is 512KB, instead 640KB + * Only four banks are accessible to ARM + */ + if ((corerev == 16) && (nb == 5)) + nb = 4; + + for (i = 0; i < nb; i++) { + bankidx = i | (SOCRAM_MEMTYPE_DEVRAM << SOCRAM_BANKIDX_MEMTYPE_SHIFT); + W_REG(sii->osh, ®s->bankidx, bankidx); + bankinfo = R_REG(sii->osh, ®s->bankinfo); + if (bankinfo & SOCRAM_BANKINFO_DEVRAMREMAP_MASK) { + banksz = socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_DEVRAM); + memsize += banksz; + } else { + /* Account only consecutive banks for now */ + break; + } + } + } + + /* Return to previous state and core */ + if (!wasup) + si_core_disable(sih, 0); + si_setcoreidx(sih, origidx); + +done: + INTR_RESTORE(sii, intr_val); + + return memsize; +} + /* Return the RAM size of the SOCRAM core */ uint32 si_socram_size(si_t *sih) @@ -1792,6 +1922,57 @@ done: return memsize; } +uint32 +si_socram_srmem_size(si_t *sih) +{ + si_info_t *sii; + uint origidx; + uint intr_val = 0; + + sbsocramregs_t *regs; + bool wasup; + uint corerev; + uint32 coreinfo; + uint memsize = 0; + + sii = SI_INFO(sih); + + /* Block ints and save current core */ + INTR_OFF(sii, intr_val); + origidx = si_coreidx(sih); + + /* Switch to SOCRAM core */ + if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0))) + goto done; + + /* Get info for determining size */ + if (!(wasup = si_iscoreup(sih))) + si_core_reset(sih, 0, 0); + corerev = si_corerev(sih); + coreinfo = R_REG(sii->osh, ®s->coreinfo); + + /* Calculate size from coreinfo based on rev */ + if (corerev >= 16) { + uint8 i; + uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT; + for (i = 0; i < nb; i++) { + W_REG(sii->osh, ®s->bankidx, i); + if (R_REG(sii->osh, ®s->bankinfo) & SOCRAM_BANKINFO_RETNTRAM_MASK) + memsize += socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_RAM); + } + } + + /* Return to previous state and core */ + if (!wasup) + si_core_disable(sih, 0); + si_setcoreidx(sih, origidx); + +done: + INTR_RESTORE(sii, intr_val); + + return memsize; +} + void si_btcgpiowar(si_t *sih) @@ -1825,6 +2006,171 @@ si_btcgpiowar(si_t *sih) INTR_RESTORE(sii, intr_val); } +void +si_chipcontrl_btshd0_4331(si_t *sih, bool on) +{ + si_info_t *sii; + chipcregs_t *cc; + uint origidx; + uint32 val; + uint intr_val = 0; + + sii = SI_INFO(sih); + + INTR_OFF(sii, intr_val); + + origidx = si_coreidx(sih); + + cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); + + val = R_REG(sii->osh, &cc->chipcontrol); + + /* bt_shd0 controls are same for 4331 chiprevs 0 and 1, packages 12x9 and 12x12 */ + if (on) { + /* Enable bt_shd0 on gpio4: */ + val |= (CCTRL4331_BT_SHD0_ON_GPIO4); + W_REG(sii->osh, &cc->chipcontrol, val); + } else { + val &= ~(CCTRL4331_BT_SHD0_ON_GPIO4); + W_REG(sii->osh, &cc->chipcontrol, val); + } + + /* restore the original index */ + si_setcoreidx(sih, origidx); + + INTR_RESTORE(sii, intr_val); +} + +void +si_chipcontrl_restore(si_t *sih, uint32 val) +{ + si_info_t *sii; + chipcregs_t *cc; + uint origidx; + + sii = SI_INFO(sih); + origidx = si_coreidx(sih); + cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); + W_REG(sii->osh, &cc->chipcontrol, val); + si_setcoreidx(sih, origidx); +} + +uint32 +si_chipcontrl_read(si_t *sih) +{ + si_info_t *sii; + chipcregs_t *cc; + uint origidx; + uint32 val; + + sii = SI_INFO(sih); + origidx = si_coreidx(sih); + cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); + val = R_REG(sii->osh, &cc->chipcontrol); + si_setcoreidx(sih, origidx); + return val; +} + +void +si_chipcontrl_epa4331(si_t *sih, bool on) +{ + si_info_t *sii; + chipcregs_t *cc; + uint origidx; + uint32 val; + + sii = SI_INFO(sih); + origidx = si_coreidx(sih); + + cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); + + val = R_REG(sii->osh, &cc->chipcontrol); + + if (on) { + if (sih->chippkg == 9 || sih->chippkg == 0xb) { + val |= (CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5); + /* Ext PA Controls for 4331 12x9 Package */ + W_REG(sii->osh, &cc->chipcontrol, val); + } else { + /* Ext PA Controls for 4331 12x12 Package */ + if (sih->chiprev > 0) { + W_REG(sii->osh, &cc->chipcontrol, val | + (CCTRL4331_EXTPA_EN) | (CCTRL4331_EXTPA_EN2)); + } else { + W_REG(sii->osh, &cc->chipcontrol, val | (CCTRL4331_EXTPA_EN)); + } + } + } else { + val &= ~(CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_EN2 | CCTRL4331_EXTPA_ON_GPIO2_5); + W_REG(sii->osh, &cc->chipcontrol, val); + } + + si_setcoreidx(sih, origidx); +} + +/* switch muxed pins, on: SROM, off: FEMCTRL */ +void +si_chipcontrl_srom4360(si_t *sih, bool on) +{ + si_info_t *sii; + chipcregs_t *cc; + uint origidx; + uint32 val; + + sii = SI_INFO(sih); + origidx = si_coreidx(sih); + + cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); + + val = R_REG(sii->osh, &cc->chipcontrol); + + if (on) { + val &= ~(CCTRL4360_SECI_MODE | + CCTRL4360_BTSWCTRL_MODE | + CCTRL4360_EXTRA_FEMCTRL_MODE | + CCTRL4360_BT_LGCY_MODE | + CCTRL4360_CORE2FEMCTRL4_ON); + + W_REG(sii->osh, &cc->chipcontrol, val); + } else { + } + + si_setcoreidx(sih, origidx); +} + +void +si_chipcontrl_epa4331_wowl(si_t *sih, bool enter_wowl) +{ + si_info_t *sii; + chipcregs_t *cc; + uint origidx; + uint32 val; + bool sel_chip; + + sel_chip = (CHIPID(sih->chip) == BCM4331_CHIP_ID) || + (CHIPID(sih->chip) == BCM43431_CHIP_ID); + sel_chip &= ((sih->chippkg == 9 || sih->chippkg == 0xb)); + + if (!sel_chip) + return; + + sii = SI_INFO(sih); + origidx = si_coreidx(sih); + + cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); + + val = R_REG(sii->osh, &cc->chipcontrol); + + if (enter_wowl) { + val |= CCTRL4331_EXTPA_EN; + W_REG(sii->osh, &cc->chipcontrol, val); + } else { + val |= (CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5); + W_REG(sii->osh, &cc->chipcontrol, val); + } + si_setcoreidx(sih, origidx); +} + uint si_pll_reset(si_t *sih) { @@ -1833,6 +2179,87 @@ si_pll_reset(si_t *sih) return (err); } +/* Enable BT-COEX & Ex-PA for 4313 */ +void +si_epa_4313war(si_t *sih) +{ + si_info_t *sii; + chipcregs_t *cc; + uint origidx; + + sii = SI_INFO(sih); + origidx = si_coreidx(sih); + + cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); + + /* EPA Fix */ + W_REG(sii->osh, &cc->gpiocontrol, + R_REG(sii->osh, &cc->gpiocontrol) | GPIO_CTRL_EPA_EN_MASK); + + si_setcoreidx(sih, origidx); +} + +void +si_clk_pmu_htavail_set(si_t *sih, bool set_clear) +{ +} + +/* WL/BT control for 4313 btcombo boards >= P250 */ +void +si_btcombo_p250_4313_war(si_t *sih) +{ + si_info_t *sii; + chipcregs_t *cc; + uint origidx; + + sii = SI_INFO(sih); + origidx = si_coreidx(sih); + + cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); + W_REG(sii->osh, &cc->gpiocontrol, + R_REG(sii->osh, &cc->gpiocontrol) | GPIO_CTRL_5_6_EN_MASK); + + W_REG(sii->osh, &cc->gpioouten, + R_REG(sii->osh, &cc->gpioouten) | GPIO_CTRL_5_6_EN_MASK); + + si_setcoreidx(sih, origidx); +} +void +si_btc_enable_chipcontrol(si_t *sih) +{ + si_info_t *sii; + chipcregs_t *cc; + uint origidx; + + sii = SI_INFO(sih); + origidx = si_coreidx(sih); + + cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); + + /* BT fix */ + W_REG(sii->osh, &cc->chipcontrol, + R_REG(sii->osh, &cc->chipcontrol) | CC_BTCOEX_EN_MASK); + + si_setcoreidx(sih, origidx); +} +void +si_btcombo_43228_war(si_t *sih) +{ + si_info_t *sii; + chipcregs_t *cc; + uint origidx; + + sii = SI_INFO(sih); + origidx = si_coreidx(sih); + + cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); + + W_REG(sii->osh, &cc->gpioouten, GPIO_CTRL_7_6_EN_MASK); + W_REG(sii->osh, &cc->gpioout, GPIO_OUT_7_EN_MASK); + + si_setcoreidx(sih, origidx); +} + /* check if the device is removed */ bool si_deviceremoved(si_t *sih) @@ -1878,14 +2305,9 @@ si_is_sprom_available(si_t *sih) return ((sih->chipst & CST4312_SPROM_OTP_SEL_MASK) != CST4312_OTP_SEL); case BCM4325_CHIP_ID: return (sih->chipst & CST4325_SPROM_SEL) != 0; - case BCM4322_CHIP_ID: - case BCM43221_CHIP_ID: - case BCM43231_CHIP_ID: - case BCM43222_CHIP_ID: - case BCM43111_CHIP_ID: - case BCM43112_CHIP_ID: - case BCM4342_CHIP_ID: - { + case BCM4322_CHIP_ID: case BCM43221_CHIP_ID: case BCM43231_CHIP_ID: + case BCM43222_CHIP_ID: case BCM43111_CHIP_ID: case BCM43112_CHIP_ID: + case BCM4342_CHIP_ID: { uint32 spromotp; spromotp = (sih->chipst & CST4322_SPROM_OTP_SEL_MASK) >> CST4322_SPROM_OTP_SEL_SHIFT; @@ -1897,18 +2319,28 @@ si_is_sprom_available(si_t *sih) return (sih->chipst & CST4315_SPROM_SEL) != 0; case BCM4319_CHIP_ID: return (sih->chipst & CST4319_SPROM_SEL) != 0; - case BCM4336_CHIP_ID: case BCM43362_CHIP_ID: return (sih->chipst & CST4336_SPROM_PRESENT) != 0; - case BCM4330_CHIP_ID: return (sih->chipst & CST4330_SPROM_PRESENT) != 0; case BCM4313_CHIP_ID: return (sih->chipst & CST4313_SPROM_PRESENT) != 0; + case BCM4331_CHIP_ID: + case BCM43431_CHIP_ID: + return (sih->chipst & CST4331_SPROM_PRESENT) != 0; case BCM43239_CHIP_ID: return ((sih->chipst & CST43239_SPROM_MASK) && !(sih->chipst & CST43239_SFLASH_MASK)); + case BCM4324_CHIP_ID: + return ((sih->chipst & CST4324_SPROM_MASK) && + !(sih->chipst & CST4324_SFLASH_MASK)); + case BCM43131_CHIP_ID: + case BCM43217_CHIP_ID: + case BCM43227_CHIP_ID: + case BCM43228_CHIP_ID: + case BCM43428_CHIP_ID: + return (sih->chipst & CST43228_OTP_PRESENT) != CST43228_OTP_PRESENT; default: return TRUE; } diff --git a/drivers/net/wireless/bcmdhd/siutils_priv.h b/drivers/net/wireless/bcmdhd/siutils_priv.h index d80246e01d1..9a3270f7424 100644 --- a/drivers/net/wireless/bcmdhd/siutils_priv.h +++ b/drivers/net/wireless/bcmdhd/siutils_priv.h @@ -1,9 +1,9 @@ /* * Include file private to the SOC Interconnect support files. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: siutils_priv.h,v 1.17.4.3 2010-10-25 16:56:56 Exp $ + * $Id: siutils_priv.h 309193 2012-01-19 00:03:57Z $ */ #ifndef _siutils_priv_h_ @@ -31,8 +31,11 @@ #define SI_MSG(args) -/* Define SI_VMSG to printf for verbose debugging, but don't check it in */ +#ifdef BCMDBG_SI +#define SI_VMSG(args) printf args +#else #define SI_VMSG(args) +#endif #define IS_SIM(chippkg) ((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID)) @@ -102,15 +105,21 @@ typedef struct si_info { #define PCI(si) ((BUSTYPE((si)->pub.bustype) == PCI_BUS) && \ ((si)->pub.buscoretype == PCI_CORE_ID)) -#define PCIE(si) ((BUSTYPE((si)->pub.bustype) == PCI_BUS) && \ + +#define PCIE_GEN1(si) ((BUSTYPE((si)->pub.bustype) == PCI_BUS) && \ ((si)->pub.buscoretype == PCIE_CORE_ID)) + +#define PCIE_GEN2(si) ((BUSTYPE((si)->pub.bustype) == PCI_BUS) && \ + ((si)->pub.buscoretype == PCIE2_CORE_ID)) + +#define PCIE(si) (PCIE_GEN1(si) || PCIE_GEN2(si)) + #define PCMCIA(si) ((BUSTYPE((si)->pub.bustype) == PCMCIA_BUS) && ((si)->memseg == TRUE)) /* Newer chips can access PCI/PCIE and CC core without requiring to change * PCI BAR0 WIN */ -#define SI_FAST(si) (((si)->pub.buscoretype == PCIE_CORE_ID) || \ - (((si)->pub.buscoretype == PCI_CORE_ID) && (si)->pub.buscorerev >= 13)) +#define SI_FAST(si) (PCIE(si) || (PCI(si) && ((si)->pub.buscorerev >= 13))) #define PCIEREGS(si) (((char *)((si)->curmap) + PCI_16KB0_PCIREGS_OFFSET)) #define CCREGS_FAST(si) (((char *)((si)->curmap) + PCI_16KB0_CCREGS_OFFSET)) @@ -138,9 +147,10 @@ typedef struct si_info { #define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */ #define PCI_FORCEHT(si) \ - (((PCIE(si)) && (si->pub.chip == BCM4311_CHIP_ID) && ((si->pub.chiprev <= 1))) || \ - ((PCI(si) || PCIE(si)) && (si->pub.chip == BCM4321_CHIP_ID)) || \ - (PCIE(si) && (si->pub.chip == BCM4716_CHIP_ID))) + (((PCIE_GEN1(si)) && (si->pub.chip == BCM4311_CHIP_ID) && ((si->pub.chiprev <= 1))) || \ + ((PCI(si) || PCIE_GEN1(si)) && (si->pub.chip == BCM4321_CHIP_ID)) || \ + (PCIE_GEN1(si) && (si->pub.chip == BCM4716_CHIP_ID)) || \ + (PCIE_GEN1(si) && (si->pub.chip == BCM4748_CHIP_ID))) /* GPIO Based LED powersave defines */ #define DEFAULT_GPIO_ONTIME 10 /* Default: 10% on */ @@ -208,6 +218,7 @@ extern void ai_core_disable(si_t *sih, uint32 bits); extern int ai_numaddrspaces(si_t *sih); extern uint32 ai_addrspace(si_t *sih, uint asidx); extern uint32 ai_addrspacesize(si_t *sih, uint asidx); +extern void ai_coreaddrspaceX(si_t *sih, uint asidx, uint32 *addr, uint32 *size); extern uint ai_wrap_reg(si_t *sih, uint32 offset, uint32 mask, uint32 val); diff --git a/drivers/net/wireless/bcmdhd/wl_android.c b/drivers/net/wireless/bcmdhd/wl_android.c index 2cbe333b0dd..65f89122662 100644 --- a/drivers/net/wireless/bcmdhd/wl_android.c +++ b/drivers/net/wireless/bcmdhd/wl_android.c @@ -1,9 +1,9 @@ /* * Linux cfg80211 driver - Android related functions * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: wl_android.c,v 1.1.4.1.2.14 2011/02/09 01:40:07 Exp $ + * $Id: wl_android.c 309571 2012-01-20 01:45:10Z $ */ #include @@ -53,28 +53,29 @@ * so they can be updated easily in the future (if needed) */ -#define CMD_START "START" -#define CMD_STOP "STOP" -#define CMD_SCAN_ACTIVE "SCAN-ACTIVE" -#define CMD_SCAN_PASSIVE "SCAN-PASSIVE" -#define CMD_RSSI "RSSI" -#define CMD_LINKSPEED "LINKSPEED" -#define CMD_RXFILTER_START "RXFILTER-START" -#define CMD_RXFILTER_STOP "RXFILTER-STOP" -#define CMD_RXFILTER_ADD "RXFILTER-ADD" -#define CMD_RXFILTER_REMOVE "RXFILTER-REMOVE" +#define CMD_START "START" +#define CMD_STOP "STOP" +#define CMD_SCAN_ACTIVE "SCAN-ACTIVE" +#define CMD_SCAN_PASSIVE "SCAN-PASSIVE" +#define CMD_RSSI "RSSI" +#define CMD_LINKSPEED "LINKSPEED" +#define CMD_RXFILTER_START "RXFILTER-START" +#define CMD_RXFILTER_STOP "RXFILTER-STOP" +#define CMD_RXFILTER_ADD "RXFILTER-ADD" +#define CMD_RXFILTER_REMOVE "RXFILTER-REMOVE" #define CMD_BTCOEXSCAN_START "BTCOEXSCAN-START" -#define CMD_BTCOEXSCAN_STOP "BTCOEXSCAN-STOP" -#define CMD_BTCOEXMODE "BTCOEXMODE" -#define CMD_SETSUSPENDOPT "SETSUSPENDOPT" -#define CMD_P2P_DEV_ADDR "P2P_DEV_ADDR" -#define CMD_SETFWPATH "SETFWPATH" -#define CMD_SETBAND "SETBAND" -#define CMD_GETBAND "GETBAND" -#define CMD_COUNTRY "COUNTRY" -#define CMD_P2P_SET_NOA "P2P_SET_NOA" -#define CMD_P2P_SET_PS "P2P_SET_PS" -#define CMD_SET_AP_WPS_P2P_IE "SET_AP_WPS_P2P_IE" +#define CMD_BTCOEXSCAN_STOP "BTCOEXSCAN-STOP" +#define CMD_BTCOEXMODE "BTCOEXMODE" +#define CMD_SETSUSPENDOPT "SETSUSPENDOPT" +#define CMD_P2P_DEV_ADDR "P2P_DEV_ADDR" +#define CMD_SETFWPATH "SETFWPATH" +#define CMD_SETBAND "SETBAND" +#define CMD_GETBAND "GETBAND" +#define CMD_COUNTRY "COUNTRY" +#define CMD_P2P_SET_NOA "P2P_SET_NOA" +#define CMD_P2P_GET_NOA "P2P_GET_NOA" +#define CMD_P2P_SET_PS "P2P_SET_PS" +#define CMD_SET_AP_WPS_P2P_IE "SET_AP_WPS_P2P_IE" #ifdef PNO_SUPPORT @@ -264,6 +265,7 @@ static int wl_android_set_pno_setup(struct net_device *dev, char *command, int t goto exit_proc; } + #ifdef PNO_SET_DEBUG memcpy(command, pno_in_example, sizeof(pno_in_example)); for (i = 0; i < sizeof(pno_in_example); i++) @@ -350,6 +352,7 @@ static int wl_android_get_p2p_dev_addr(struct net_device *ndev, char *command, i int wl_android_wifi_on(struct net_device *dev) { int ret = 0; + int retry = POWERUP_MAX_RETRY; printk("%s in\n", __FUNCTION__); if (!dev) { @@ -359,14 +362,26 @@ int wl_android_wifi_on(struct net_device *dev) dhd_net_if_lock(dev); if (!g_wifi_on) { - dhd_customer_gpio_wlan_ctrl(WLAN_RESET_ON); - sdioh_start(NULL, 0); + do { + dhd_customer_gpio_wlan_ctrl(WLAN_RESET_ON); + ret = sdioh_start(NULL, 0); + if (ret == 0) + break; + DHD_ERROR(("\nfailed to power up wifi chip, retry again (%d left) **\n\n", + retry+1)); + dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF); + } while (retry-- >= 0); + if (ret != 0) { + DHD_ERROR(("\nfailed to power up wifi chip, max retry reached **\n\n")); + goto exit; + } ret = dhd_dev_reset(dev, FALSE); sdioh_start(NULL, 1); - if (!ret) - dhd_dev_init_ioctl(dev); - g_wifi_on = 1; + dhd_dev_init_ioctl(dev); + g_wifi_on = TRUE; } + +exit: dhd_net_if_unlock(dev); return ret; @@ -384,10 +399,10 @@ int wl_android_wifi_off(struct net_device *dev) dhd_net_if_lock(dev); if (g_wifi_on) { - ret = dhd_dev_reset(dev, TRUE); + dhd_dev_reset(dev, 1); sdioh_stop(NULL); dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF); - g_wifi_on = 0; + g_wifi_on = FALSE; } dhd_net_if_unlock(dev); @@ -536,6 +551,9 @@ int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) bytes_written = wl_cfg80211_set_p2p_noa(net, command + skip, priv_cmd.total_len - skip); } + else if (strnicmp(command, CMD_P2P_GET_NOA, strlen(CMD_P2P_GET_NOA)) == 0) { + bytes_written = wl_cfg80211_get_p2p_noa(net, command, priv_cmd.total_len); + } else if (strnicmp(command, CMD_P2P_SET_PS, strlen(CMD_P2P_SET_PS)) == 0) { int skip = strlen(CMD_P2P_SET_PS) + 1; bytes_written = wl_cfg80211_set_p2p_ps(net, command + skip, @@ -556,9 +574,9 @@ int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) } if (bytes_written >= 0) { - if ((bytes_written == 0) && (priv_cmd.total_len > 0)) + if (bytes_written == 0) command[0] = '\0'; - if (bytes_written >= priv_cmd.total_len) { + if (bytes_written > priv_cmd.total_len) { DHD_ERROR(("%s: bytes_written = %d\n", __FUNCTION__, bytes_written)); bytes_written = priv_cmd.total_len; } else { @@ -658,21 +676,20 @@ void wl_android_wifictrl_func_del(void) } } -void *wl_android_prealloc(int section, unsigned long size) +void* wl_android_prealloc(int section, unsigned long size) { void *alloc_ptr = NULL; if (wifi_control_data && wifi_control_data->mem_prealloc) { alloc_ptr = wifi_control_data->mem_prealloc(section, size); if (alloc_ptr) { DHD_INFO(("success alloc section %d\n", section)); - if (size != 0L) - bzero(alloc_ptr, size); + bzero(alloc_ptr, size); return alloc_ptr; } } DHD_ERROR(("can't alloc section %d\n", section)); - return NULL; + return 0; } int wifi_get_irq_number(unsigned long *irq_flags_ptr) @@ -695,7 +712,7 @@ int wifi_set_power(int on, unsigned long msec) wifi_control_data->set_power(on); } if (msec) - msleep(msec); + mdelay(msec); return 0; } @@ -739,7 +756,6 @@ static int wifi_probe(struct platform_device *pdev) struct wifi_platform_data *wifi_ctrl = (struct wifi_platform_data *)(pdev->dev.platform_data); - DHD_ERROR(("## %s\n", __FUNCTION__)); wifi_irqres = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "bcmdhd_wlan_irq"); if (wifi_irqres == NULL) wifi_irqres = platform_get_resource_byname(pdev, @@ -771,19 +787,19 @@ static int wifi_remove(struct platform_device *pdev) static int wifi_suspend(struct platform_device *pdev, pm_message_t state) { DHD_TRACE(("##> %s\n", __FUNCTION__)); -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)) && defined(OOB_INTR_ONLY) +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)) && defined(OOB_INTR_ONLY) && 1 bcmsdh_oob_intr_set(0); -#endif +#endif /* (OOB_INTR_ONLY) */ return 0; } static int wifi_resume(struct platform_device *pdev) { DHD_TRACE(("##> %s\n", __FUNCTION__)); -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)) && defined(OOB_INTR_ONLY) +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)) && defined(OOB_INTR_ONLY) && 1 if (dhd_os_check_if_up(bcmsdh_get_drvdata())) bcmsdh_oob_intr_set(1); -#endif +#endif /* (OOB_INTR_ONLY) */ return 0; } diff --git a/drivers/net/wireless/bcmdhd/wl_android.h b/drivers/net/wireless/bcmdhd/wl_android.h index 3983306cfe3..583a16735ec 100644 --- a/drivers/net/wireless/bcmdhd/wl_android.h +++ b/drivers/net/wireless/bcmdhd/wl_android.h @@ -1,14 +1,14 @@ /* * Linux cfg80211 driver - Android related functions * - * Copyright (C) 1999-2011, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license + * Copyright (C) 1999-2012, Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the * following added to such license: - * + * * As a special exception, the copyright holders of this software give you * permission to link this software with independent modules, and to copy and * distribute the resulting executable under terms of your choice, provided that @@ -16,12 +16,12 @@ * the license of that module. An independent module is a module which is not * derived from this software. The special exception does not apply to any * modifications of the software. - * + * * Notwithstanding the above, under no circumstances may you combine this * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: wl_android.c,v 1.1.4.1.2.14 2011/02/09 01:40:07 Exp $ + * $Id: wl_android.h 307885 2012-01-12 23:30:48Z $ */ #include diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/wl_cfg80211.c index 2242a7adc0c..f7786ab1185 100644 --- a/drivers/net/wireless/bcmdhd/wl_cfg80211.c +++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.c @@ -1,9 +1,9 @@ /* * Linux cfg80211 driver * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: wl_cfg80211.c,v 1.1.4.1.2.14 2011/02/09 01:40:07 Exp $ + * $Id: wl_cfg80211.c 310409 2012-01-24 18:47:09Z $ */ #include @@ -60,8 +60,41 @@ #include #include +#ifdef BCMWAPI_WPI +/* these items should evetually go into wireless.h of the linux system headfile dir */ +#ifndef IW_ENCODE_ALG_SM4 +#define IW_ENCODE_ALG_SM4 0x20 +#endif + +#ifndef IW_AUTH_WAPI_ENABLED +#define IW_AUTH_WAPI_ENABLED 0x20 +#endif + +#ifndef IW_AUTH_WAPI_VERSION_1 +#define IW_AUTH_WAPI_VERSION_1 0x00000008 +#endif + +#ifndef IW_AUTH_CIPHER_SMS4 +#define IW_AUTH_CIPHER_SMS4 0x00000020 +#endif + +#ifndef IW_AUTH_KEY_MGMT_WAPI_PSK +#define IW_AUTH_KEY_MGMT_WAPI_PSK 4 +#endif + +#ifndef IW_AUTH_KEY_MGMT_WAPI_CERT +#define IW_AUTH_KEY_MGMT_WAPI_CERT 8 +#endif +#endif /* BCMWAPI_WPI */ + +#ifdef BCMWAPI_WPI +#define IW_WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED | SMS4_ENABLED)) +#else /* BCMWAPI_WPI */ +#define IW_WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED)) +#endif /* BCMWAPI_WPI */ + + static struct device *cfg80211_parent_dev = NULL; -static int vsdb_supported = 0; struct wl_priv *wlcfg_drv_priv = NULL; u32 wl_dbg_level = WL_DBG_ERR; @@ -69,17 +102,19 @@ u32 wl_dbg_level = WL_DBG_ERR; #define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] #define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" #define MAX_WAIT_TIME 1500 -#define WL_SCAN_ACTIVE_TIME 40 -#define WL_SCAN_PASSIVE_TIME 130 +#define WL_SCAN_ACTIVE_TIME 40 /* ms : Embedded default Active setting from DHD Driver */ +#define WL_SCAN_PASSIVE_TIME 130 /* ms: Embedded default Passive setting from DHD Driver */ + +#define WL_CHANSPEC_CTL_SB_NONE WL_CHANSPEC_CTL_SB_LLL + #define DNGL_FUNC(func, parameters) func parameters; #define COEX_DHCP - /* Set this to 1 to use a seperate interface (p2p0) * for p2p operations. */ -#define ENABLE_P2P_INTERFACE 1 +#define ENABLE_P2P_INTERFACE 0 /* This is to override regulatory domains defined in cfg80211 module (reg.c) * By default world regulatory domain defined in reg.c puts the flags NL80211_RRF_PASSIVE_SCAN @@ -220,8 +255,6 @@ static s32 wl_enq_event(struct wl_priv *wl, struct net_device *ndev, u32 type, const wl_event_msg_t *msg, void *data); static void wl_put_event(struct wl_event_q *e); static void wl_wakeup_event(struct wl_priv *wl); -static s32 wl_notify_connect_status_ap(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data); static s32 wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev, const wl_event_msg_t *e, void *data); @@ -236,13 +269,15 @@ static s32 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev, const wl_event_msg_t *e, void *data); static s32 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev, const wl_event_msg_t *e, void *data); -static s32 wl_notify_pfn_status(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data); /* * register/deregister parent device */ static void wl_cfg80211_clear_parent_dev(void); +/* + * ioctl utilites + */ + /* * cfg80211 set_wiphy_params utilities */ @@ -271,6 +306,10 @@ static s32 wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme); static s32 wl_set_set_sharedkey(struct net_device *dev, struct cfg80211_connect_params *sme); +#ifdef BCMWAPI_WPI +static s32 wl_set_set_wapi_ie(struct net_device *dev, + struct cfg80211_connect_params *sme); +#endif static s32 wl_get_assoc_ies(struct wl_priv *wl, struct net_device *ndev); static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params, size_t *join_params_size); @@ -285,7 +324,7 @@ static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size); static u32 wl_get_ielen(struct wl_priv *wl); -static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *dev); +static struct wireless_dev *wl_alloc_wdev(struct device *dev); static void wl_free_wdev(struct wl_priv *wl); static s32 wl_inform_bss(struct wl_priv *wl); @@ -376,18 +415,19 @@ int dhd_monitor_init(void *dhd_pub); int dhd_monitor_uninit(void); int dhd_start_xmit(struct sk_buff *skb, struct net_device *net); -#define CHECK_SYS_UP(wlpriv) \ + +#define CHECK_SYS_UP(wlpriv) \ do { \ - struct net_device *ndev = wl_to_prmry_ndev(wlpriv); \ + struct net_device *ndev = wl_to_prmry_ndev(wlpriv); \ if (unlikely(!wl_get_drv_status(wlpriv, READY, ndev))) { \ - WL_INFO(("device is not ready\n")); \ - return -EIO; \ + WL_INFO(("device is not ready\n")); \ + return -EIO; \ } \ } while (0) -#define IS_WPA_AKM(akm) ((akm) == RSN_AKM_NONE || \ - (akm) == RSN_AKM_UNSPECIFIED || \ +#define IS_WPA_AKM(akm) ((akm) == RSN_AKM_NONE || \ + (akm) == RSN_AKM_UNSPECIFIED || \ (akm) == RSN_AKM_PSK) @@ -539,8 +579,134 @@ static const u32 __wl_cipher_suites[] = { WLAN_CIPHER_SUITE_TKIP, WLAN_CIPHER_SUITE_CCMP, WLAN_CIPHER_SUITE_AES_CMAC, +#ifdef BCMWAPI_WPI + WLAN_CIPHER_SUITE_SMS4 +#endif }; +/* IOCtl version read from targeted driver */ +static int ioctl_version; + +/* Return a new chanspec given a legacy chanspec + * Returns INVCHANSPEC on error + */ +static chanspec_t +wl_chspec_from_legacy(chanspec_t legacy_chspec) +{ + chanspec_t chspec; + + /* get the channel number */ + chspec = LCHSPEC_CHANNEL(legacy_chspec); + + /* convert the band */ + if (LCHSPEC_IS2G(legacy_chspec)) { + chspec |= WL_CHANSPEC_BAND_2G; + } else { + chspec |= WL_CHANSPEC_BAND_5G; + } + + /* convert the bw and sideband */ + if (LCHSPEC_IS20(legacy_chspec)) { + chspec |= WL_CHANSPEC_BW_20; + } else { + chspec |= WL_CHANSPEC_BW_40; + if (LCHSPEC_CTL_SB(legacy_chspec) == WL_LCHANSPEC_CTL_SB_LOWER) { + chspec |= WL_CHANSPEC_CTL_SB_L; + } else { + chspec |= WL_CHANSPEC_CTL_SB_U; + } + } + + if (wf_chspec_malformed(chspec)) { + WL_ERR(("wl_chspec_from_legacy: output chanspec (0x%04X) malformed\n", + chspec)); + return INVCHANSPEC; + } + + return chspec; +} + +/* Return a legacy chanspec given a new chanspec + * Returns INVCHANSPEC on error + */ +static chanspec_t +wl_chspec_to_legacy(chanspec_t chspec) +{ + chanspec_t lchspec; + + if (wf_chspec_malformed(chspec)) { + WL_ERR(("wl_chspec_to_legacy: input chanspec (0x%04X) malformed\n", + chspec)); + return INVCHANSPEC; + } + + /* get the channel number */ + lchspec = CHSPEC_CHANNEL(chspec); + + /* convert the band */ + if (CHSPEC_IS2G(chspec)) { + lchspec |= WL_LCHANSPEC_BAND_2G; + } else { + lchspec |= WL_LCHANSPEC_BAND_5G; + } + + /* convert the bw and sideband */ + if (CHSPEC_IS20(chspec)) { + lchspec |= WL_LCHANSPEC_BW_20; + lchspec |= WL_LCHANSPEC_CTL_SB_NONE; + } else if (CHSPEC_IS40(chspec)) { + lchspec |= WL_LCHANSPEC_BW_40; + if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_L) { + lchspec |= WL_LCHANSPEC_CTL_SB_LOWER; + } else { + lchspec |= WL_LCHANSPEC_CTL_SB_UPPER; + } + } else { + /* cannot express the bandwidth */ + char chanbuf[CHANSPEC_STR_LEN]; + WL_ERR(( + "wl_chspec_to_legacy: unable to convert chanspec %s (0x%04X) " + "to pre-11ac format\n", + wf_chspec_ntoa(chspec, chanbuf), chspec)); + return INVCHANSPEC; + } + + return lchspec; +} + +/* given a chanspec value, do the endian and chanspec version conversion to + * a chanspec_t value + * Returns INVCHANSPEC on error + */ +static chanspec_t +wl_chspec_host_to_driver(chanspec_t chanspec) +{ + if (ioctl_version == 1) { + chanspec = wl_chspec_to_legacy(chanspec); + if (chanspec == INVCHANSPEC) { + return chanspec; + } + } + chanspec = htodchanspec(chanspec); + + return chanspec; +} + +/* given a chanspec value from the driver, do the endian and chanspec version conversion to + * a chanspec_t value + * Returns INVCHANSPEC on error + */ +static chanspec_t +wl_chspec_driver_to_host(chanspec_t chanspec) +{ + chanspec = dtohchanspec(chanspec); + if (ioctl_version == 1) { + chanspec = wl_chspec_from_legacy(chanspec); + } + + return chanspec; +} + /* There isn't a lot of sense in it, but you can transmit anything you like */ static const struct ieee80211_txrx_stypes wl_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { @@ -691,47 +857,43 @@ wl_validate_wps_ie(char *wps_ie, bool *pbc) static chanspec_t wl_cfg80211_get_shared_freq(struct wiphy *wiphy) { - if (vsdb_supported) { + chanspec_t chspec; + int err = 0; + struct wl_priv *wl = wiphy_priv(wiphy); + struct net_device *dev = wl_to_prmry_ndev(wl); + struct ether_addr bssid; + struct wl_bss_info *bss = NULL; + + if ((err = wldev_ioctl(dev, WLC_GET_BSSID, &bssid, sizeof(bssid), false))) { + /* STA interface is not associated. So start the new interface on a temp + * channel . Later proper channel will be applied by the above framework + * via set_channel (cfg80211 API). + */ + WL_DBG(("Not associated. Return a temp channel. \n")); return wf_chspec_aton(WL_P2P_TEMP_CHAN); } - else { - chanspec_t chspec; - int err = 0; - struct wl_priv *wl = wiphy_priv(wiphy); - struct net_device *dev = wl_to_prmry_ndev(wl); - struct ether_addr bssid; - struct wl_bss_info *bss = NULL; - if ((err = wldev_ioctl(dev, WLC_GET_BSSID, &bssid, sizeof(bssid), false))) { - /* STA interface is not associated. So start the new interface on a temp - * channel . Later proper channel will be applied by the above framework - * via set_channel (cfg80211 API). - */ - WL_DBG(("Not associated. Return a temp channel. \n")); - return wf_chspec_aton(WL_P2P_TEMP_CHAN); - } - *(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX); - if ((err = wldev_ioctl(dev, WLC_GET_BSS_INFO, wl->extra_buf, - sizeof(WL_EXTRA_BUF_MAX), false))) { - WL_ERR(("Failed to get associated bss info, use temp channel \n")); - chspec = wf_chspec_aton(WL_P2P_TEMP_CHAN); - } - else { - bss = (struct wl_bss_info *) (wl->extra_buf + 4); - chspec = bss->chanspec; - WL_DBG(("Valid BSS Found. chanspec:%d \n", bss->chanspec)); - } - return chspec; + *(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX); + if ((err = wldev_ioctl(dev, WLC_GET_BSS_INFO, wl->extra_buf, + sizeof(WL_EXTRA_BUF_MAX), false))) { + WL_ERR(("Failed to get associated bss info, use temp channel \n")); + chspec = wf_chspec_aton(WL_P2P_TEMP_CHAN); + } + else { + bss = (struct wl_bss_info *) (wl->extra_buf + 4); + chspec = bss->chanspec; + WL_DBG(("Valid BSS Found. chanspec:%d \n", bss->chanspec)); } + + return chspec; } static struct net_device* wl_cfg80211_add_monitor_if(char *name) { - int ret = 0; struct net_device* ndev = NULL; - ret = dhd_add_monitor(name, &ndev); + dhd_add_monitor(name, &ndev); WL_INFO(("wl_cfg80211_add_monitor_if net device returned: 0x%p\n", ndev)); return ndev; } @@ -752,7 +914,7 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name, int (*net_attach)(void *dhdp, int ifidx); bool rollback_lock = false; - /* Use primary I/F for sending cmds down to firmware */ + /* Use primary I/F for to send commands down */ _ndev = wl_to_prmry_ndev(wl); WL_DBG(("if name: %s, type: %d\n", name, type)); @@ -859,7 +1021,7 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name, } vwdev->wiphy = wl->wdev->wiphy; WL_INFO((" virtual interface(%s) is created memalloc done \n", - wl->p2p->vir_ifname)); + wl->p2p->vir_ifname)); vwdev->iftype = type; _ndev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION); _ndev->ieee80211_ptr = vwdev; @@ -909,8 +1071,8 @@ wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, struct net_device *dev) WL_DBG(("Enter\n")); if (wl->p2p_net == dev) { - /* Since there is no ifidx corresponding to p2p0, cmds to - * firmware should be routed through primary I/F + /* Since there is no ifidx corresponding to p2p0, + * all commands should be routed through primary I/F */ dev = wl_to_prmry_ndev(wl); } @@ -924,6 +1086,7 @@ wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, struct net_device *dev) wldev_iovar_setint(dev, "mpc", 1); wl_set_p2p_status(wl, IF_DELETING); ret = wl_cfgp2p_ifdel(wl, &p2p_mac); +#if defined(DONGLEHOST) /* Firmware could not delete the interface so we will not get WLC_E_IF * event for cleaning the dhd virtual nw interace * So lets do it here. Failures from fw will ensure the application to do @@ -937,6 +1100,7 @@ wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, struct net_device *dev) "HANG Notification sent to %s\n", ret, ndev->name)); wl_cfg80211_hang(ndev, WLAN_REASON_UNSPECIFIED); } +#endif /* defined(DONGLEHOST) */ /* Wait for any pending scan req to get aborted from the sysioc context */ timeout = wait_event_interruptible_timeout(wl->netif_change_event, @@ -960,8 +1124,6 @@ wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev, { s32 ap = 0; s32 infra = 0; - s32 err = BCME_OK; - s32 timeout = -1; s32 wlif_type; s32 mode = 0; chanspec_t chspec; @@ -1011,8 +1173,8 @@ wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev, ndev->name, ap, infra, type)); wl_set_p2p_status(wl, IF_CHANGING); wl_clr_p2p_status(wl, IF_CHANGED); - err = wl_cfgp2p_ifchange(wl, &wl->p2p->int_addr, htod32(wlif_type), chspec); - timeout = wait_event_interruptible_timeout(wl->netif_change_event, + wl_cfgp2p_ifchange(wl, &wl->p2p->int_addr, htod32(wlif_type), chspec); + wait_event_interruptible_timeout(wl->netif_change_event, (wl_get_p2p_status(wl, IF_CHANGED) == true), msecs_to_jiffies(MAX_WAIT_TIME)); wl_set_mode_by_netdev(wl, ndev, mode); @@ -1037,18 +1199,16 @@ wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev, } s32 -wl_cfg80211_notify_ifadd(struct net_device *ndev, s32 idx, s32 bssidx, - void* _net_attach) +wl_cfg80211_notify_ifadd(struct net_device *ndev, s32 idx, s32 bssidx, void* _net_attach) { struct wl_priv *wl = wlcfg_drv_priv; s32 ret = BCME_OK; - WL_DBG(("Enter")); if (!ndev) { WL_ERR(("net is NULL\n")); return 0; } if (wl->p2p_supported && wl_get_p2p_status(wl, IF_ADD)) { - WL_DBG(("IF_ADD event called from dongle, old interface name: %s," + WL_DBG(("IF_ADD event received, old interface name: %s," "new name: %s\n", ndev->name, wl->p2p->vir_ifname)); /* Assign the net device to CONNECT BSSCFG */ strncpy(ndev->name, wl->p2p->vir_ifname, IFNAMSIZ - 1); @@ -1071,7 +1231,6 @@ wl_cfg80211_notify_ifdel(struct net_device *ndev) struct wl_priv *wl = wlcfg_drv_priv; bool rollback_lock = false; s32 index = 0; - if (!ndev || !ndev->name) { WL_ERR(("net is NULL\n")); return 0; @@ -1092,7 +1251,7 @@ wl_cfg80211_notify_ifdel(struct net_device *ndev) if (rollback_lock) rtnl_unlock(); } - WL_ERR(("IF_DEL event called from dongle, net %x, vif name: %s\n", + WL_ERR(("IF_DEL event received, net %x, vif name: %s\n", (unsigned int)ndev, wl->p2p->vir_ifname)); memset(wl->p2p->vir_ifname, '\0', IFNAMSIZ); @@ -1146,8 +1305,8 @@ wl_cfg80211_notify_ifchange(void) static void wl_scan_prep(struct wl_scan_params *params, struct cfg80211_scan_request *request) { - u32 n_ssids; - u32 n_channels; + u32 n_ssids = request->n_ssids; + u32 n_channels = request->n_channels; u16 channel; chanspec_t chanspec; s32 i, offset; @@ -1176,13 +1335,6 @@ static void wl_scan_prep(struct wl_scan_params *params, struct cfg80211_scan_req params->passive_time = htod32(params->passive_time); params->home_time = htod32(params->home_time); - /* if request is null just exit so it will be all channel broadcast scan */ - if (!request) - return; - - n_ssids = request->n_ssids; - n_channels = request->n_channels; - /* Copy channel array if applicable */ WL_SCAN(("### List of channelspecs to scan ###\n")); if (n_channels > 0) { @@ -1268,10 +1420,12 @@ wl_run_iscan(struct wl_iscan_ctrl *iscan, struct cfg80211_scan_request *request, } params = (struct wl_iscan_params *)kzalloc(params_size, GFP_KERNEL); if (!params) { - return -ENOMEM; + err = -ENOMEM; + goto done; } - wl_scan_prep(¶ms->params, request); + if (request != NULL) + wl_scan_prep(¶ms->params, request); params->version = htod32(ISCAN_REQ_VERSION); params->action = htod16(action); @@ -1291,8 +1445,8 @@ wl_run_iscan(struct wl_iscan_ctrl *iscan, struct cfg80211_scan_request *request, WL_ERR(("error (%d)\n", err)); } } -done: kfree(params); +done: return err; } @@ -1319,7 +1473,6 @@ static s32 wl_do_iscan(struct wl_priv *wl, struct cfg80211_scan_request *request return err; } - static s32 wl_get_valid_channels(struct net_device *ndev, u8 *valid_chan_list, s32 size) { @@ -1338,7 +1491,6 @@ wl_get_valid_channels(struct net_device *ndev, u8 *valid_chan_list, s32 size) return err; } - static s32 wl_run_escan(struct wl_priv *wl, struct net_device *ndev, struct cfg80211_scan_request *request, uint16 action) @@ -1385,13 +1537,13 @@ wl_run_escan(struct wl_priv *wl, struct net_device *ndev, goto exit; } - wl_scan_prep(¶ms->params, request); + if (request != NULL) + wl_scan_prep(¶ms->params, request); params->version = htod32(ESCAN_REQ_VERSION); params->action = htod16(action); params->sync_id = htod16(0x1234); if (params_size + sizeof("escan") >= WLC_IOCTL_MEDLEN) { WL_ERR(("ioctl buffer length not sufficient\n")); - kfree(params); err = -ENOMEM; goto exit; } @@ -1508,7 +1660,7 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, wpa_ie_fixed_t *wps_ie; s32 passive_scan; bool iscan_req; - bool escan_req; + bool escan_req = false; bool p2p_ssid; s32 err = 0; s32 i; @@ -1746,7 +1898,6 @@ static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) s32 err = 0; CHECK_SYS_UP(wl); - WL_DBG(("Enter\n")); if (changed & WIPHY_PARAM_RTS_THRESHOLD && (wl->conf->rts_threshold != wiphy->rts_threshold)) { wl->conf->rts_threshold = wiphy->rts_threshold; @@ -1776,6 +1927,7 @@ static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) return err; } } + return err; } @@ -1886,6 +2038,13 @@ wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme) if (is_wps_conn(sme)) val = WPA_AUTH_DISABLED; +#ifdef BCMWAPI_WPI + if (sme->crypto.wpa_versions & NL80211_WAPI_VERSION_1) { + WL_DBG((" * wl_set_wpa_version, set wpa_auth" + " to WPA_AUTH_WAPI 0x400")); + val = WAPI_AUTH_PSK | WAPI_AUTH_UNSPECIFIED; + } +#endif WL_DBG(("setting wpa_auth to 0x%0x\n", val)); err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", val, bssidx); if (unlikely(err)) { @@ -1897,6 +2056,30 @@ wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme) return err; } +#ifdef BCMWAPI_WPI +static s32 +wl_set_set_wapi_ie(struct net_device *dev, struct cfg80211_connect_params *sme) +{ + struct wl_priv *wl = wlcfg_drv_priv; + s32 err = 0; + s32 bssidx = wl_cfgp2p_find_idx(wl, dev); + + WL_DBG((" %s \n", __FUNCTION__)); + + if (sme->crypto.wpa_versions & NL80211_WAPI_VERSION_1) { + err = wldev_iovar_setbuf_bsscfg(dev, "wapiie", sme->ie, + sme->ie_len, wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync); + + if (unlikely(err)) { + WL_ERR(("===> set_wapi_ie Error (%d)\n", err)); + return err; + } + } else + WL_DBG((" * skip \n")); + return err; +} +#endif /* BCMWAPI_WPI */ + static s32 wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme) { @@ -1944,6 +2127,9 @@ wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme) s32 pval = 0; s32 gval = 0; s32 err = 0; +#ifdef BCMWAPI_WPI + s32 val = 0; +#endif s32 bssidx = wl_cfgp2p_find_idx(wl, dev); if (sme->crypto.n_ciphers_pairwise) { @@ -1961,6 +2147,12 @@ wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme) case WLAN_CIPHER_SUITE_AES_CMAC: pval = AES_ENABLED; break; +#ifdef BCMWAPI_WPI + case WLAN_CIPHER_SUITE_SMS4: + val = SMS4_ENABLED; + pval = SMS4_ENABLED; + break; +#endif default: WL_ERR(("invalid cipher pairwise (%d)\n", sme->crypto.ciphers_pairwise[0])); @@ -1982,6 +2174,12 @@ wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme) case WLAN_CIPHER_SUITE_AES_CMAC: gval = AES_ENABLED; break; +#ifdef BCMWAPI_WPI + case WLAN_CIPHER_SUITE_SMS4: + val = SMS4_ENABLED; + gval = SMS4_ENABLED; + break; +#endif default: WL_ERR(("invalid cipher group (%d)\n", sme->crypto.cipher_group)); @@ -1994,9 +2192,18 @@ wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme) if (is_wps_conn(sme)) { err = wldev_iovar_setint_bsscfg(dev, "wsec", 4, bssidx); } else { - WL_DBG((" NO, is_wps_conn, Set pval | gval to WSEC")); - err = wldev_iovar_setint_bsscfg(dev, "wsec", +#ifdef BCMWAPI_WPI + if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_SMS4) { + WL_DBG((" NO, is_wps_conn, WAPI set to SMS4_ENABLED")); + err = wldev_iovar_setint_bsscfg(dev, "wsec", val, bssidx); + } else { +#endif + WL_DBG((" NO, is_wps_conn, Set pval | gval to WSEC")); + err = wldev_iovar_setint_bsscfg(dev, "wsec", pval | gval, bssidx); +#ifdef BCMWAPI_WPI + } +#endif } if (unlikely(err)) { WL_ERR(("error (%d)\n", err)); @@ -2052,6 +2259,22 @@ wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme) return -EINVAL; } } +#ifdef BCMWAPI_WPI + else if (val & (WAPI_AUTH_PSK | WAPI_AUTH_UNSPECIFIED)) { + switch (sme->crypto.akm_suites[0]) { + case WLAN_AKM_SUITE_WAPI_CERT: + val = WAPI_AUTH_UNSPECIFIED; + break; + case WLAN_AKM_SUITE_WAPI_PSK: + val = WAPI_AUTH_PSK; + break; + default: + WL_ERR(("invalid cipher group (%d)\n", + sme->crypto.cipher_group)); + return -EINVAL; + } + } +#endif WL_DBG(("setting wpa_auth to %d\n", val)); err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", val, bssidx); @@ -2083,9 +2306,17 @@ wl_set_set_sharedkey(struct net_device *dev, WL_DBG(("wpa_versions 0x%x cipher_pairwise 0x%x\n", sec->wpa_versions, sec->cipher_pairwise)); if (!(sec->wpa_versions & (NL80211_WPA_VERSION_1 | +#ifdef BCMWAPI_WPI + NL80211_WPA_VERSION_2 | NL80211_WAPI_VERSION_1)) && +#else NL80211_WPA_VERSION_2)) && +#endif (sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 | +#ifdef BCMWAPI_WPI + WLAN_CIPHER_SUITE_WEP104 | WLAN_CIPHER_SUITE_SMS4))) +#else WLAN_CIPHER_SUITE_WEP104))) +#endif { memset(&key, 0, sizeof(key)); key.len = (u32) sme->key_len; @@ -2103,6 +2334,11 @@ wl_set_set_sharedkey(struct net_device *dev, case WLAN_CIPHER_SUITE_WEP104: key.algo = CRYPTO_ALGO_WEP128; break; +#ifdef BCMWAPI_WPI + case WLAN_CIPHER_SUITE_SMS4: + key.algo = CRYPTO_ALGO_SMS4; + break; +#endif default: WL_ERR(("Invalid algorithm (%d)\n", sme->crypto.ciphers_pairwise[0])); @@ -2152,7 +2388,6 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, u32 chan_cnt = 0; u8 wpsie[IE_MAX_LEN]; struct ether_addr bssid; - WL_DBG(("In\n")); CHECK_SYS_UP(wl); @@ -2240,18 +2475,37 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, chan->center_freq)); } else wl->channel = 0; +#ifdef BCMWAPI_WPI + WL_DBG(("1. enable wapi auth\n")); + if (sme->crypto.wpa_versions & NL80211_WAPI_VERSION_1) { + WL_DBG(("2. set wapi ie \n")); + err = wl_set_set_wapi_ie(dev, sme); + if (unlikely(err)) + return err; + } else + WL_DBG(("2. Not wapi ie \n")); +#endif WL_DBG(("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len)); + WL_DBG(("3. set wapi version \n")); err = wl_set_wpa_version(dev, sme); if (unlikely(err)) { WL_ERR(("Invalid wpa_version\n")); return err; } - - err = wl_set_auth_type(dev, sme); - if (unlikely(err)) { - WL_ERR(("Invalid auth type\n")); - return err; +#ifdef BCMWAPI_WPI + if (sme->crypto.wpa_versions & NL80211_WAPI_VERSION_1) + WL_DBG(("4. WAPI Dont Set wl_set_auth_type\n")); + else { + WL_DBG(("4. wl_set_auth_type\n")); +#endif + err = wl_set_auth_type(dev, sme); + if (unlikely(err)) { + WL_ERR(("Invalid auth type\n")); + return err; + } +#ifdef BCMWAPI_WPI } +#endif err = wl_set_set_cipher(dev, sme); if (unlikely(err)) { @@ -2313,7 +2567,7 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, ext_join_params->assoc.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK; ext_join_params->assoc.chanspec_list[0] |= chspec; ext_join_params->assoc.chanspec_list[0] = - htodchanspec(ext_join_params->assoc.chanspec_list[0]); + wl_chspec_host_to_driver(ext_join_params->assoc.chanspec_list[0]); } ext_join_params->assoc.chanspec_num = htod32(ext_join_params->assoc.chanspec_num); if (ext_join_params->ssid.SSID_len < IEEE80211_MAX_SSID_LEN) { @@ -2576,6 +2830,12 @@ wl_add_keyext(struct wiphy *wiphy, struct net_device *dev, key.algo = CRYPTO_ALGO_AES_CCM; WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n")); break; +#ifdef BCMWAPI_WPI + case WLAN_CIPHER_SUITE_SMS4: + key.algo = CRYPTO_ALGO_SMS4; + WL_DBG(("WLAN_CIPHER_SUITE_SMS4\n")); + break; +#endif default: WL_ERR(("Invalid cipher (0x%x)\n", params->cipher)); return -EINVAL; @@ -2660,6 +2920,13 @@ wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, val = AES_ENABLED; WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n")); break; +#ifdef BCMWAPI_WPI + case WLAN_CIPHER_SUITE_SMS4: + key.algo = CRYPTO_ALGO_SMS4; + WL_DBG(("WLAN_CIPHER_SUITE_SMS4\n")); + val = SMS4_ENABLED; + break; +#endif /* BCMWAPI_WPI */ default: WL_ERR(("Invalid cipher (0x%x)\n", params->cipher)); return -EINVAL; @@ -2773,6 +3040,12 @@ wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev, params.cipher = WLAN_CIPHER_SUITE_AES_CMAC; WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n")); break; +#ifdef BCMWAPI_WPI + case WLAN_CIPHER_SUITE_SMS4: + key.algo = CRYPTO_ALGO_SMS4; + WL_DBG(("WLAN_CIPHER_SUITE_SMS4\n")); + break; +#endif default: WL_ERR(("Invalid algo (0x%x)\n", wsec)); return -EINVAL; @@ -2804,7 +3077,6 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, s8 eabuf[ETHER_ADDR_STR_LEN]; #endif dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub); - CHECK_SYS_UP(wl); if (wl_get_mode_by_netdev(wl, dev) == WL_MODE_AP) { err = wldev_iovar_getbuf(dev, "sta_info", (struct ether_addr *)mac, @@ -2831,42 +3103,41 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, sta->idle * 1000)); #endif } else if (wl_get_mode_by_netdev(wl, dev) == WL_MODE_BSS) { - u8 *curmacp = wl_read_prof(wl, dev, WL_PROF_BSSID); - if (!wl_get_drv_status(wl, CONNECTED, dev) || - (dhd_is_associated(dhd, NULL) == FALSE)) { - WL_ERR(("NOT assoc\n")); - err = -ENODEV; - goto get_station_err; - } - if (memcmp(mac, curmacp, ETHER_ADDR_LEN)) { - WL_ERR(("Wrong Mac address: "MACSTR" != "MACSTR"\n", - MAC2STR(mac), MAC2STR(curmacp))); - } - - /* Report the current tx rate */ - err = wldev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate), false); - if (err) { - WL_ERR(("Could not get rate (%d)\n", err)); - } else { - rate = dtoh32(rate); - sinfo->filled |= STATION_INFO_TX_BITRATE; - sinfo->txrate.legacy = rate * 5; - WL_DBG(("Rate %d Mbps\n", (rate / 2))); - } + u8 *curmacp = wl_read_prof(wl, dev, WL_PROF_BSSID); + if (!wl_get_drv_status(wl, CONNECTED, dev) || + (dhd_is_associated(dhd, NULL) == FALSE)) { + WL_ERR(("NOT assoc\n")); + err = -ENODEV; + goto get_station_err; + } + if (memcmp(mac, curmacp, ETHER_ADDR_LEN)) { + WL_ERR(("Wrong Mac address: "MACSTR" != "MACSTR"\n", + MAC2STR(mac), MAC2STR(curmacp))); + } - memset(&scb_val, 0, sizeof(scb_val)); - scb_val.val = 0; - err = wldev_ioctl(dev, WLC_GET_RSSI, &scb_val, - sizeof(scb_val_t), false); - if (err) { - WL_ERR(("Could not get rssi (%d)\n", err)); - goto get_station_err; - } + /* Report the current tx rate */ + err = wldev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate), false); + if (err) { + WL_ERR(("Could not get rate (%d)\n", err)); + } else { + rate = dtoh32(rate); + sinfo->filled |= STATION_INFO_TX_BITRATE; + sinfo->txrate.legacy = rate * 5; + WL_DBG(("Rate %d Mbps\n", (rate / 2))); + } - rssi = dtoh32(scb_val.val); - sinfo->filled |= STATION_INFO_SIGNAL; - sinfo->signal = rssi; - WL_DBG(("RSSI %d dBm\n", rssi)); + memset(&scb_val, 0, sizeof(scb_val)); + scb_val.val = 0; + err = wldev_ioctl(dev, WLC_GET_RSSI, &scb_val, + sizeof(scb_val_t), false); + if (err) { + WL_ERR(("Could not get rssi (%d)\n", err)); + goto get_station_err; + } + rssi = dtoh32(scb_val.val); + sinfo->filled |= STATION_INFO_SIGNAL; + sinfo->signal = rssi; + WL_DBG(("RSSI %d dBm\n", rssi)); get_station_err: if (err) { @@ -2968,7 +3239,6 @@ static s32 wl_cfg80211_suspend(struct wiphy *wiphy) struct net_info *iter, *next; struct net_device *ndev = wl_to_prmry_ndev(wl); unsigned long flags; - if (unlikely(!wl_get_drv_status(wl, READY, ndev))) { WL_INFO(("device is not ready : status (%d)\n", (int)wl->status)); @@ -3009,8 +3279,8 @@ wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list, return -EINVAL; } /* pmk list is supported only for STA interface i.e. primary interface - * Refer code wlc_bsscfg.c->wlc_bsscfg_sta_init - */ + * Refer code wlc_bsscfg.c->wlc_bsscfg_sta_init + */ if (primary_dev != dev) { WL_INFO(("Not supporting Flushing pmklist on virtual" " interfaces than primary interface\n")); @@ -3156,7 +3426,7 @@ wl_cfg80211_scan_alloc_params(int channel, int nprobes, int *out_params_size) params->active_time = htod32(-1); params->passive_time = htod32(-1); params->home_time = htod32(10); - params->channel_list[0] = htodchanspec(channel); + params->channel_list[0] = wl_chspec_host_to_driver(channel); /* Our scan params have 1 channel and 0 ssids */ params->channel_num = htod32((0 << WL_SCAN_PARAMS_NSSID_SHIFT) | @@ -3165,7 +3435,6 @@ wl_cfg80211_scan_alloc_params(int channel, int nprobes, int *out_params_size) *out_params_size = params_size; /* rtn size to the caller */ return params; } - s32 wl_cfg80211_scan_abort(struct wl_priv *wl, struct net_device *ndev) { @@ -3200,7 +3469,6 @@ wl_cfg80211_scan_abort(struct wl_priv *wl, struct net_device *ndev) kfree(params); return err; } - static s32 wl_cfg80211_remain_on_channel(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_channel * channel, @@ -3266,7 +3534,6 @@ wl_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, struct net_device *dev WL_DBG((" enter ) netdev_ifidx: %d \n", dev->ifindex)); return err; } - static s32 wl_cfg80211_send_pending_tx_act_frm(struct wl_priv *wl) { @@ -3359,14 +3626,18 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev, struct ieee80211_channel *channel, bool offchan, enum nl80211_channel_type channel_type, bool channel_type_valid, unsigned int wait, - const u8* buf, size_t len, bool no_cck, - bool dont_wait_for_ack, u64 *cookie) + const u8* buf, size_t len, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0) + bool no_cck, bool dont_wait_for_ack, +#endif + u64 *cookie) { wl_action_frame_t *action_frame; wl_af_params_t *af_params; wifi_p2p_ie_t *p2p_ie; wpa_ie_fixed_t *wps_ie; scb_val_t scb_val; + wifi_wfd_ie_t *wfd_ie; const struct ieee80211_mgmt *mgmt; struct wl_priv *wl = wiphy_priv(wiphy); struct net_device *dev = NULL; @@ -3374,6 +3645,7 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev, s32 bssidx = 0; u32 p2pie_len = 0; u32 wpsie_len = 0; + u32 wfdie_len = 0; u32 id; u32 retry = 0; bool ack = false; @@ -3422,6 +3694,11 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev, /* Total length of P2P Information Element */ p2pie_len = p2p_ie->len + sizeof(p2p_ie->len) + sizeof(p2p_ie->id); } + if ((wfd_ie = wl_cfgp2p_find_wfdie((u8 *)(buf + ie_offset), ie_len)) + != NULL) { + /* Total length of WFD Information Element */ + wfdie_len = wfd_ie->len + sizeof(wfd_ie->len) + sizeof(wfd_ie->id); + } if ((wps_ie = wl_cfgp2p_find_wpsie((u8 *)(buf + ie_offset), ie_len)) != NULL) { /* Order of Vendor IE is 1) WPS IE + @@ -3433,7 +3710,7 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev, sizeof(wps_ie->tag); wl_cfgp2p_set_management_ie(wl, dev, bssidx, VNDR_IE_PRBRSP_FLAG, - (u8 *)wps_ie, wpsie_len + p2pie_len); + (u8 *)wps_ie, wpsie_len + p2pie_len + wfdie_len); } cfg80211_mgmt_tx_status(ndev, *cookie, buf, len, true, GFP_KERNEL); goto exit; @@ -3685,6 +3962,11 @@ wl_validate_wpa2ie(struct net_device *dev, bcm_tlv_t *wpa2ie, s32 bssidx) case WPA_CIPHER_AES_CCM: gval = AES_ENABLED; break; +#ifdef BCMWAPI_WPI + case WAPI_CIPHER_SMS4: + gval = SMS4_ENABLED; + break; +#endif default: WL_ERR(("No Security Info\n")); break; @@ -3708,6 +3990,11 @@ wl_validate_wpa2ie(struct net_device *dev, bcm_tlv_t *wpa2ie, s32 bssidx) case WPA_CIPHER_AES_CCM: pval = AES_ENABLED; break; +#ifdef BCMWAPI_WPI + case WAPI_CIPHER_SMS4: + pval = SMS4_ENABLED; + break; +#endif default: WL_ERR(("No Security Info\n")); } @@ -3911,11 +4198,13 @@ wl_cfg80211_add_set_beacon(struct wiphy *wiphy, struct net_device *dev, wpa_ie_fixed_t *wpa_ie; bcm_tlv_t *wpa2_ie; wifi_p2p_ie_t *p2p_ie; + wifi_wfd_ie_t *wfd_ie; bool is_bssup = false; bool update_bss = false; bool pbc = false; u16 wpsie_len = 0; u16 p2pie_len = 0; + u32 wfdie_len = 0; u8 beacon_ie[IE_MAX_LEN]; s32 ie_offset = 0; s32 bssidx = 0; @@ -3973,10 +4262,25 @@ wl_cfg80211_add_set_beacon(struct wiphy *wiphy, struct net_device *dev, } else { WL_ERR(("No P2PIE in beacon \n")); } + + /* find the WFD IEs */ + if ((wfd_ie = wl_cfgp2p_find_wfdie((u8 *)info->tail, info->tail_len)) != NULL) { + /* Total length of P2P Information Element */ + wfdie_len = wfd_ie->len + sizeof(wfd_ie->len) + sizeof(wfd_ie->id); + if ((wpsie_len + p2pie_len + wfdie_len) < IE_MAX_LEN) { + memcpy(&beacon_ie[wpsie_len + p2pie_len], wfd_ie, wfdie_len); + } else { + WL_ERR(("Found WFD IE but there is no space, (%d)(%d)(%d)\n", + wpsie_len, p2pie_len, wfdie_len)); + wfdie_len = 0; + } + } else { + WL_ERR(("No WFDIE in beacon \n")); + } /* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */ wl_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc); wl_cfgp2p_set_management_ie(wl, dev, bssidx, VNDR_IE_BEACON_FLAG, - beacon_ie, wpsie_len + p2pie_len); + beacon_ie, wpsie_len + p2pie_len + wfdie_len); /* find the RSN_IE */ if ((wpa2_ie = bcm_parse_tlvs((u8 *)info->tail, info->tail_len, @@ -4081,7 +4385,7 @@ wl_cfg80211_add_set_beacon(struct wiphy *wiphy, struct net_device *dev, memcpy(beacon_ie, wps_ie, wpsie_len); wl_cfgp2p_set_management_ie(wl, dev, bssidx, VNDR_IE_BEACON_FLAG, beacon_ie, wpsie_len); - wl->ap_info->wps_ie = kmemdup(wps_ie, wpsie_len, GFP_KERNEL); + wl->ap_info->wps_ie = kmemdup(wps_ie, wpsie_len, GFP_KERNEL); /* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */ wl_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc); } else { @@ -4134,12 +4438,12 @@ wl_cfg80211_add_set_beacon(struct wiphy *wiphy, struct net_device *dev, memcmp(wl->ap_info->wps_ie, wps_ie, wpsie_len)) { WL_DBG((" WPS IE is changed\n")); kfree(wl->ap_info->wps_ie); - wl->ap_info->wps_ie = kmemdup(wps_ie, wpsie_len, GFP_KERNEL); + wl->ap_info->wps_ie = kmemdup(wps_ie, wpsie_len, GFP_KERNEL); /* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */ wl_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc); } else if (wl->ap_info->wps_ie == NULL) { WL_DBG((" WPS IE is added\n")); - wl->ap_info->wps_ie = kmemdup(wps_ie, wpsie_len, GFP_KERNEL); + wl->ap_info->wps_ie = kmemdup(wps_ie, wpsie_len, GFP_KERNEL); /* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */ wl_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc); } @@ -4277,17 +4581,23 @@ s32 wl_mode_to_nl80211_iftype(s32 mode) return err; } -static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev) +static struct wireless_dev *wl_alloc_wdev(struct device *dev) { + struct wireless_dev *wdev; s32 err = 0; + wdev = kzalloc(sizeof(*wdev), GFP_KERNEL); + if (unlikely(!wdev)) { + WL_ERR(("Could not allocate wireless device\n")); + return ERR_PTR(-ENOMEM); + } wdev->wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_priv)); if (unlikely(!wdev->wiphy)) { WL_ERR(("Couldn not allocate wiphy device\n")); err = -ENOMEM; - return err; + goto wiphy_new_out; } - set_wiphy_dev(wdev->wiphy, sdiofunc_dev); + set_wiphy_dev(wdev->wiphy, dev); wdev->wiphy->max_scan_ie_len = WL_SCAN_IE_LEN_MAX; /* Report how many SSIDs Driver can support per Scan request */ wdev->wiphy->max_scan_ssids = WL_SCAN_PARAMS_SSID_MAX; @@ -4314,9 +4624,7 @@ static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS | #endif WIPHY_FLAG_4ADDR_STATION; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) - wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM; -#endif + WL_DBG(("Registering custom regulatory)\n")); wdev->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; wiphy_apply_custom_regulatory(wdev->wiphy, &brcm_regdom); @@ -4324,9 +4632,17 @@ static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev err = wiphy_register(wdev->wiphy); if (unlikely(err < 0)) { WL_ERR(("Couldn not register wiphy device (%d)\n", err)); - wiphy_free(wdev->wiphy); + goto wiphy_register_out; } - return err; + return wdev; + +wiphy_register_out: + wiphy_free(wdev->wiphy); + +wiphy_new_out: + kfree(wdev); + + return ERR_PTR(err); } static void wl_free_wdev(struct wl_priv *wl) @@ -4421,6 +4737,7 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi) u.beacon.variable) + wl_get_ielen(wl); #if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS) freq = ieee80211_channel_to_frequency(notif_bss_info->channel); + (void)band->band; #else freq = ieee80211_channel_to_frequency(notif_bss_info->channel, band->band); #endif @@ -4433,7 +4750,6 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi) notif_bss_info->frame_len)); signal = notif_bss_info->rssi * 100; - #if defined(WLP2P) && ENABLE_P2P_INTERFACE if (wl->p2p_net && wl->scan_request && wl->scan_request->dev == wl->p2p_net) { @@ -4516,136 +4832,91 @@ static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e) return false; } -/* The mainline kernel >= 3.2.0 has support for indicating new/del station - * to AP/P2P GO via events. If this change is backported to kernel for which - * this driver is being built, set CFG80211_STA_EVENT_AVAILABLE to 1. You - * should use this new/del sta event mechanism for BRCM supplicant from BRANCH - * HOSTAP_BRANCH_0_15 (ver >= 15_1). - */ -#define CFG80211_STA_EVENT_AVAILABLE 0 static s32 -wl_notify_connect_status_ap(struct wl_priv *wl, struct net_device *ndev, +wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev, const wl_event_msg_t *e, void *data) { + bool act; + bool isfree = false; s32 err = 0; + s32 freq; + s32 channel; + u8 body[200]; u32 event = ntoh32(e->event_type); u32 reason = ntoh32(e->reason); u32 len = ntoh32(e->datalen); -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) && !CFG80211_STA_EVENT_AVAILABLE - bool isfree = false; + u16 fc = 0; u8 *mgmt_frame; u8 bsscfgidx = e->bsscfgidx; - s32 freq; - s32 channel; - u8 body[200]; - u16 fc = 0; struct ieee80211_supported_band *band; struct ether_addr da; struct ether_addr bssid; struct wiphy *wiphy = wl_to_wiphy(wl); channel_info_t ci; -#else - struct station_info sinfo; -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) && !CFG80211_STA_EVENT_AVAILABLE */ - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) && !CFG80211_STA_EVENT_AVAILABLE memset(body, 0, sizeof(body)); memset(&bssid, 0, ETHER_ADDR_LEN); WL_DBG(("Enter \n")); if (wl_get_mode_by_netdev(wl, ndev) == WL_INVALID) return WL_INVALID; - memcpy(body, data, len); - wldev_iovar_getbuf_bsscfg(ndev, "cur_etheraddr", - NULL, 0, wl->ioctl_buf, WLC_IOCTL_MAXLEN, bsscfgidx, &wl->ioctl_buf_sync); - memcpy(da.octet, wl->ioctl_buf, ETHER_ADDR_LEN); - err = wldev_ioctl(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false); - switch (event) { - case WLC_E_ASSOC_IND: - fc = FC_ASSOC_REQ; - break; - case WLC_E_REASSOC_IND: - fc = FC_REASSOC_REQ; - break; - case WLC_E_DISASSOC_IND: - fc = FC_DISASSOC; - break; - case WLC_E_DEAUTH_IND: - fc = FC_DISASSOC; - break; - case WLC_E_DEAUTH: - fc = FC_DISASSOC; - break; - default: - fc = 0; - goto exit; - } - if ((err = wldev_ioctl(ndev, WLC_GET_CHANNEL, &ci, sizeof(ci), false))) - return err; + if (wl_get_mode_by_netdev(wl, ndev) == WL_MODE_AP) { + memcpy(body, data, len); + wldev_iovar_getbuf_bsscfg(ndev, "cur_etheraddr", + NULL, 0, wl->ioctl_buf, WLC_IOCTL_MAXLEN, bsscfgidx, &wl->ioctl_buf_sync); + memcpy(da.octet, wl->ioctl_buf, ETHER_ADDR_LEN); + err = wldev_ioctl(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false); + switch (event) { + case WLC_E_ASSOC_IND: + fc = FC_ASSOC_REQ; + break; + case WLC_E_REASSOC_IND: + fc = FC_REASSOC_REQ; + break; + case WLC_E_DISASSOC_IND: + fc = FC_DISASSOC; + break; + case WLC_E_DEAUTH_IND: + fc = FC_DISASSOC; + break; + case WLC_E_DEAUTH: + fc = FC_DISASSOC; + break; + default: + fc = 0; + goto exit; + } + if ((err = wldev_ioctl(ndev, WLC_GET_CHANNEL, &ci, sizeof(ci), false))) + return err; - channel = dtoh32(ci.hw_channel); - if (channel <= CH_MAX_2G_CHANNEL) - band = wiphy->bands[IEEE80211_BAND_2GHZ]; - else - band = wiphy->bands[IEEE80211_BAND_5GHZ]; + channel = dtoh32(ci.hw_channel); + if (channel <= CH_MAX_2G_CHANNEL) + band = wiphy->bands[IEEE80211_BAND_2GHZ]; + else + band = wiphy->bands[IEEE80211_BAND_5GHZ]; #if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS) - freq = ieee80211_channel_to_frequency(channel); + freq = ieee80211_channel_to_frequency(channel); + (void)band->band; #else - freq = ieee80211_channel_to_frequency(channel, band->band); + freq = ieee80211_channel_to_frequency(channel, band->band); #endif - err = wl_frame_get_mgmt(fc, &da, &e->addr, &bssid, + err = wl_frame_get_mgmt(fc, &da, &e->addr, &bssid, &mgmt_frame, &len, body); - if (err < 0) - goto exit; - isfree = true; - - if (event == WLC_E_ASSOC_IND && reason == DOT11_SC_SUCCESS) { - cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC); - } else if (event == WLC_E_DISASSOC_IND) { - cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC); - } else if ((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DEAUTH)) { - cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC); - } + if (err < 0) + goto exit; + isfree = true; -exit: - if (isfree) - kfree(mgmt_frame); - return err; -#else /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0) && !CFG80211_STA_EVENT_AVAILABLE */ - sinfo.filled = 0; - if (((event == WLC_E_ASSOC_IND) || (event == WLC_E_REASSOC_IND)) && - reason == DOT11_SC_SUCCESS) { - sinfo.filled = STATION_INFO_ASSOC_REQ_IES; - if (!data) { - WL_ERR(("No IEs present in ASSOC/REASSOC_IND")); - return -EINVAL; + if (event == WLC_E_ASSOC_IND && reason == DOT11_SC_SUCCESS) { + cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC); + } else if (event == WLC_E_DISASSOC_IND) { + cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC); + } else if ((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DEAUTH)) { + cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC); } - sinfo.assoc_req_ies = data; - sinfo.assoc_req_ies_len = len; - cfg80211_new_sta(ndev, e->addr.octet, &sinfo, GFP_ATOMIC); - } else if (event == WLC_E_DISASSOC_IND) { - cfg80211_del_sta(ndev, e->addr.octet, GFP_ATOMIC); - } else if ((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DEAUTH)) { - cfg80211_del_sta(ndev, e->addr.octet, GFP_ATOMIC); - } -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0) && !CFG80211_STA_EVENT_AVAILABLE */ - return err; -} -static s32 -wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data) -{ - bool act; - s32 err = 0; - u32 event = ntoh32(e->event_type); - - if (wl_get_mode_by_netdev(wl, ndev) == WL_MODE_AP) { - wl_notify_connect_status_ap(wl, ndev, e, data); } else { WL_DBG(("wl_notify_connect_status : event %d status : %d \n", ntoh32(e->event_type), ntoh32(e->status))); @@ -4717,6 +4988,9 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev, printk("%s nothing\n", __FUNCTION__); } } +exit: + if (isfree) + kfree(mgmt_frame); return err; } @@ -4834,7 +5108,7 @@ static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params, join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK; join_params->params.chanspec_list[0] |= chanspec; join_params->params.chanspec_list[0] = - htodchanspec(join_params->params.chanspec_list[0]); + wl_chspec_host_to_driver(join_params->params.chanspec_list[0]); join_params->params.chanspec_num = htod32(join_params->params.chanspec_num); @@ -4858,6 +5132,7 @@ static s32 wl_update_bss_info(struct wl_priv *wl, struct net_device *ndev) u8 *curbssid; s32 err = 0; struct wiphy *wiphy; + wiphy = wl_to_wiphy(wl); if (wl_is_ibssmode(wl, ndev)) @@ -5009,19 +5284,6 @@ wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev, return 0; } -static s32 -wl_notify_pfn_status(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data) -{ - WL_ERR((" PNO Event\n")); - - mutex_lock(&wl->usr_sync); - /* TODO: Use cfg80211_sched_scan_results(wiphy); */ - cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL); - mutex_unlock(&wl->usr_sync); - return 0; -} - static s32 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev, const wl_event_msg_t *e, void *data) @@ -5161,6 +5423,7 @@ wl_notify_rx_mgmt_frame(struct wl_priv *wl, struct net_device *ndev, #if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS) freq = ieee80211_channel_to_frequency(channel); + (void)band->band; #else freq = ieee80211_channel_to_frequency(channel, band->band); #endif @@ -5258,7 +5521,7 @@ static void wl_init_event_handler(struct wl_priv *wl) wl->evt_handler[WLC_E_P2P_DISC_LISTEN_COMPLETE] = wl_cfgp2p_listen_complete; wl->evt_handler[WLC_E_ACTION_FRAME_COMPLETE] = wl_cfgp2p_action_tx_complete; wl->evt_handler[WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE] = wl_cfgp2p_action_tx_complete; - wl->evt_handler[WLC_E_PFN_NET_FOUND] = wl_notify_pfn_status; + } static s32 wl_init_priv_mem(struct wl_priv *wl) @@ -5565,7 +5828,6 @@ static void wl_scan_timeout(unsigned long data) wl_notify_iscan_complete(wl_to_iscan(wl), true); } } - static void wl_iscan_timer(unsigned long data) { struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data; @@ -5629,7 +5891,6 @@ wl_cfg80211_netdev_notifier_call(struct notifier_block * nb, static struct notifier_block wl_cfg80211_netdev_notifier = { .notifier_call = wl_cfg80211_netdev_notifier_call, }; - static void wl_notify_escan_complete(struct wl_priv *wl, struct net_device *ndev, bool aborted) @@ -5713,7 +5974,8 @@ static s32 wl_escan_handler(struct wl_priv *wl, p2p_dev_addr = wl_cfgp2p_retreive_p2p_dev_addr(bi, bi_length); if (p2p_dev_addr && !memcmp(p2p_dev_addr, wl->afx_hdl->pending_tx_dst_addr.octet, ETHER_ADDR_LEN)) { - s32 channel = CHSPEC_CHANNEL(dtohchanspec(bi->chanspec)); + s32 channel = CHSPEC_CHANNEL( + wl_chspec_driver_to_host(bi->chanspec)); WL_DBG(("ACTION FRAME SCAN : Peer found, channel : %d\n", channel)); wl_clr_p2p_status(wl, SCANNING); wl->afx_hdl->peer_chan = channel; @@ -5951,11 +6213,9 @@ s32 wl_cfg80211_attach_post(struct net_device *ndev) if (wl && !wl_get_drv_status(wl, READY, ndev)) { if (wl->wdev && wl_cfgp2p_supported(wl, ndev)) { -#if !ENABLE_P2P_INTERFACE wl->wdev->wiphy->interface_modes |= (BIT(NL80211_IFTYPE_P2P_CLIENT)| BIT(NL80211_IFTYPE_P2P_GO)); -#endif if ((err = wl_cfgp2p_init_priv(wl)) != 0) goto fail; @@ -5996,17 +6256,10 @@ s32 wl_cfg80211_attach(struct net_device *ndev, void *data) } WL_DBG(("func %p\n", wl_cfg80211_get_parent_dev())); dev = wl_cfg80211_get_parent_dev(); - - wdev = kzalloc(sizeof(*wdev), GFP_KERNEL); - if (unlikely(!wdev)) { - WL_ERR(("Could not allocate wireless device\n")); - return -ENOMEM; - } - err = wl_setup_wiphy(wdev, dev); - if (unlikely(err)) { - kfree(wdev); + wdev = wl_alloc_wdev(dev); + if (IS_ERR(wdev)) return -ENOMEM; - } + wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS); wl = (struct wl_priv *)wiphy_priv(wdev->wiphy); wl->wdev = wdev; @@ -6061,6 +6314,7 @@ void wl_cfg80211_detach(void *para) { struct wl_priv *wl; + (void)para; wl = wlcfg_drv_priv; WL_TRACE(("In\n")); @@ -6136,9 +6390,6 @@ static s32 wl_event_handler(void *data) tsk_ctl_t *tsk = (tsk_ctl_t *)data; wl = (struct wl_priv *)tsk->parent; - - DAEMONIZE("wl_event_handler"); - complete(&tsk->completed); while (down_interruptible (&tsk->sema) == 0) { @@ -6184,6 +6435,11 @@ wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data) WL_DBG(("event_type (%d):" "WLC_E_" "%s\n", event_type, estr)); #endif /* (WL_DBG_LEVEL > 0) */ + if (event_type == WLC_E_PFN_NET_FOUND) + WL_ERR((" PNOEVENT: PNO_NET_FOUND\n")); + else if (event_type == WLC_E_PFN_NET_LOST) + WL_ERR((" PNOEVENT: PNO_NET_LOST\n")); + if (likely(!wl_enq_event(wl, ndev, event_type, e, data))) wl_wakeup_event(wl); } @@ -6443,15 +6699,33 @@ s32 wl_cfg80211_up(void *para) { struct wl_priv *wl; s32 err = 0; + int val = 0; + (void)para; WL_TRACE(("In\n")); wl = wlcfg_drv_priv; + + if ((err = wldev_ioctl(wl_to_prmry_ndev(wl), WLC_GET_VERSION, &val, + sizeof(int), false) < 0)) { + WL_ERR(("WLC_GET_VERSION failed, err=%d\n", err)); + return err; + } + val = dtoh32(val); + if (val != WLC_IOCTL_VERSION && val != 1) { + WL_ERR(("Version mismatch, please upgrade. Got %d, expected %d or 1\n", + val, WLC_IOCTL_VERSION)); + return BCME_VERSION; + } + ioctl_version = val; + WL_ERR(("WLC_GET_VERSION=%d\n", ioctl_version)); + mutex_lock(&wl->usr_sync); wl_cfg80211_attach_post(wl_to_prmry_ndev(wl)); err = __wl_cfg80211_up(wl); if (err) WL_ERR(("__wl_cfg80211_up failed\n")); mutex_unlock(&wl->usr_sync); + return err; } @@ -6474,6 +6748,7 @@ s32 wl_cfg80211_down(void *para) struct wl_priv *wl; s32 err = 0; + (void)para; WL_TRACE(("In\n")); wl = wlcfg_drv_priv; mutex_lock(&wl->usr_sync); @@ -6688,7 +6963,6 @@ s32 wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pd struct wl_priv *wl = wlcfg_drv_priv; struct ether_addr p2pif_addr; struct ether_addr primary_mac; - if (!wl->p2p) return -1; if (!p2p_is_on(wl)) { @@ -6699,6 +6973,7 @@ s32 wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pd wl->p2p->dev_addr.octet, ETHER_ADDR_LEN); } + return 0; } s32 wl_cfg80211_set_p2p_noa(struct net_device *net, char* buf, int len) @@ -6837,21 +7112,3 @@ static void get_primary_mac(struct wl_priv *wl, struct ether_addr *mac) 0, wl->ioctl_buf, WLC_IOCTL_MAXLEN, 0, &wl->ioctl_buf_sync); memcpy(mac->octet, wl->ioctl_buf, ETHER_ADDR_LEN); } - -int wl_cfg80211_do_driver_init(struct net_device *net) -{ - struct wl_priv *wl = *(struct wl_priv **)netdev_priv(net); - - if (!wl || !wl->wdev) - return -EINVAL; - - if (dhd_do_driver_init(wl->wdev->netdev) < 0) - return -1; - - return 0; -} - -void wl_cfg80211_enable_trace(int level) -{ - wl_dbg_level |= WL_DBG_DBG; -} diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.h b/drivers/net/wireless/bcmdhd/wl_cfg80211.h index 2b8e66413f2..6e43c3f3b31 100644 --- a/drivers/net/wireless/bcmdhd/wl_cfg80211.h +++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.h @@ -1,9 +1,9 @@ /* * Linux cfg80211 driver * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: wl_cfg80211.h,v 1.1.4.1.2.8 2011/02/09 01:37:52 Exp $ + * $Id: wl_cfg80211.h 307885 2012-01-12 23:30:48Z $ */ #ifndef _wl_cfg80211_h_ @@ -423,7 +423,7 @@ struct wl_priv { bool pwr_save; bool roam_on; /* on/off switch for self-roaming */ bool scan_tried; /* indicates if first scan attempted */ - u8 *ioctl_buf; /* ioctl buffer */ + u8 *ioctl_buf; /* ioctl buffer */ struct mutex ioctl_buf_sync; u8 *escan_ioctl_buf; u8 *extra_buf; /* maily to grab assoc information */ @@ -444,12 +444,12 @@ struct wl_priv { struct timer_list scan_timeout; /* Timer for catch scan event timeout */ }; + static inline struct wl_bss_info *next_bss(struct wl_scan_results *list, struct wl_bss_info *bss) { return bss = bss ? (struct wl_bss_info *)((uintptr) bss + dtoh32(bss->length)) : list->bss_info; } - static inline s32 wl_alloc_netinfo(struct wl_priv *wl, struct net_device *ndev, struct wireless_dev * wdev, s32 mode) @@ -470,7 +470,6 @@ wl_alloc_netinfo(struct wl_priv *wl, struct net_device *ndev, } return err; } - static inline void wl_dealloc_netinfo(struct wl_priv *wl, struct net_device *ndev) { @@ -487,8 +486,8 @@ wl_dealloc_netinfo(struct wl_priv *wl, struct net_device *ndev) kfree(_net_info); } } -} +} static inline void wl_delete_all_netinfo(struct wl_priv *wl) { @@ -502,7 +501,6 @@ wl_delete_all_netinfo(struct wl_priv *wl) } wl->iface_cnt = 0; } - static inline bool wl_get_status_all(struct wl_priv *wl, s32 status) @@ -516,7 +514,6 @@ wl_get_status_all(struct wl_priv *wl, s32 status) } return cnt? true: false; } - static inline void wl_set_status_by_netdev(struct wl_priv *wl, s32 status, struct net_device *ndev, u32 op) @@ -540,6 +537,7 @@ wl_set_status_by_netdev(struct wl_priv *wl, s32 status, } } + } static inline u32 @@ -567,6 +565,7 @@ wl_get_mode_by_netdev(struct wl_priv *wl, struct net_device *ndev) return -1; } + static inline void wl_set_mode_by_netdev(struct wl_priv *wl, struct net_device *ndev, s32 mode) @@ -578,7 +577,6 @@ wl_set_mode_by_netdev(struct wl_priv *wl, struct net_device *ndev, _net_info->mode = mode; } } - static inline struct wl_profile * wl_get_profile_by_netdev(struct wl_priv *wl, struct net_device *ndev) { @@ -635,8 +633,7 @@ struct device *wl_cfg80211_get_parent_dev(void); extern s32 wl_cfg80211_up(void *para); extern s32 wl_cfg80211_down(void *para); -extern s32 wl_cfg80211_notify_ifadd(struct net_device *ndev, s32 idx, s32 bssidx, - void* _net_attach); +extern s32 wl_cfg80211_notify_ifadd(struct net_device *net, s32 idx, s32 bssidx, void* _net_attach); extern s32 wl_cfg80211_ifdel_ops(struct net_device *net); extern s32 wl_cfg80211_notify_ifdel(struct net_device *ndev); extern s32 wl_cfg80211_is_progress_ifadd(void); @@ -652,8 +649,6 @@ extern s32 wl_cfg80211_set_wps_p2p_ie(struct net_device *net, char *buf, int len extern s32 wl_cfg80211_set_p2p_ps(struct net_device *net, char* buf, int len); extern int wl_cfg80211_hang(struct net_device *dev, u16 reason); extern s32 wl_mode_to_nl80211_iftype(s32 mode); -int wl_cfg80211_do_driver_init(struct net_device *net); -void wl_cfg80211_enable_trace(int level); /* do scan abort */ extern s32 wl_cfg80211_scan_abort(struct wl_priv *wl, struct net_device *ndev); diff --git a/drivers/net/wireless/bcmdhd/wl_cfgp2p.c b/drivers/net/wireless/bcmdhd/wl_cfgp2p.c index 880123e067d..96e9029bfb9 100644 --- a/drivers/net/wireless/bcmdhd/wl_cfgp2p.c +++ b/drivers/net/wireless/bcmdhd/wl_cfgp2p.c @@ -1,9 +1,9 @@ /* * Linux cfgp2p driver * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: wl_cfgp2p.c,v 1.1.4.1.2.14 2011-02-09 01:40:07 $ + * $Id: wl_cfgp2p.c 308397 2012-01-15 07:32:58Z $ * */ #include @@ -140,43 +140,43 @@ void wl_cfgp2p_print_actframe(bool tx, void *frame, u32 frame_len) pact_frm = (wifi_p2p_pub_act_frame_t *)frame; switch (pact_frm->subtype) { case P2P_PAF_GON_REQ: - CFGP2P_DBG(("%s P2P Group Owner Negotiation Req Frame\n", + CFGP2P_ERR(("%s P2P Group Owner Negotiation Req Frame\n", (tx)? "TX": "RX")); break; case P2P_PAF_GON_RSP: - CFGP2P_DBG(("%s P2P Group Owner Negotiation Rsp Frame\n", + CFGP2P_ERR(("%s P2P Group Owner Negotiation Rsp Frame\n", (tx)? "TX": "RX")); break; case P2P_PAF_GON_CONF: - CFGP2P_DBG(("%s P2P Group Owner Negotiation Confirm Frame\n", + CFGP2P_ERR(("%s P2P Group Owner Negotiation Confirm Frame\n", (tx)? "TX": "RX")); break; case P2P_PAF_INVITE_REQ: - CFGP2P_DBG(("%s P2P Invitation Request Frame\n", + CFGP2P_ERR(("%s P2P Invitation Request Frame\n", (tx)? "TX": "RX")); break; case P2P_PAF_INVITE_RSP: - CFGP2P_DBG(("%s P2P Invitation Response Frame\n", + CFGP2P_ERR(("%s P2P Invitation Response Frame\n", (tx)? "TX": "RX")); break; case P2P_PAF_DEVDIS_REQ: - CFGP2P_DBG(("%s P2P Device Discoverability Request Frame\n", + CFGP2P_ERR(("%s P2P Device Discoverability Request Frame\n", (tx)? "TX": "RX")); break; case P2P_PAF_DEVDIS_RSP: - CFGP2P_DBG(("%s P2P Device Discoverability Response Frame\n", + CFGP2P_ERR(("%s P2P Device Discoverability Response Frame\n", (tx)? "TX": "RX")); break; case P2P_PAF_PROVDIS_REQ: - CFGP2P_DBG(("%s P2P Provision Discovery Request Frame\n", + CFGP2P_ERR(("%s P2P Provision Discovery Request Frame\n", (tx)? "TX": "RX")); break; case P2P_PAF_PROVDIS_RSP: - CFGP2P_DBG(("%s P2P Provision Discovery Response Frame\n", + CFGP2P_ERR(("%s P2P Provision Discovery Response Frame\n", (tx)? "TX": "RX")); break; default: - CFGP2P_DBG(("%s Unknown P2P Public Action Frame\n", + CFGP2P_ERR(("%s Unknown P2P Public Action Frame\n", (tx)? "TX": "RX")); } @@ -185,23 +185,23 @@ void wl_cfgp2p_print_actframe(bool tx, void *frame, u32 frame_len) act_frm = (wifi_p2p_action_frame_t *)frame; switch (act_frm->subtype) { case P2P_AF_NOTICE_OF_ABSENCE: - CFGP2P_DBG(("%s P2P Notice of Absence Frame\n", + CFGP2P_ERR(("%s P2P Notice of Absence Frame\n", (tx)? "TX": "RX")); break; case P2P_AF_PRESENCE_REQ: - CFGP2P_DBG(("%s P2P Presence Request Frame\n", + CFGP2P_ERR(("%s P2P Presence Request Frame\n", (tx)? "TX": "RX")); break; case P2P_AF_PRESENCE_RSP: - CFGP2P_DBG(("%s P2P Presence Response Frame\n", + CFGP2P_ERR(("%s P2P Presence Response Frame\n", (tx)? "TX": "RX")); break; case P2P_AF_GO_DISC_REQ: - CFGP2P_DBG(("%s P2P Discoverability Request Frame\n", + CFGP2P_ERR(("%s P2P Discoverability Request Frame\n", (tx)? "TX": "RX")); break; default: - CFGP2P_DBG(("%s Unknown P2P Action Frame\n", + CFGP2P_ERR(("%s Unknown P2P Action Frame\n", (tx)? "TX": "RX")); } @@ -209,26 +209,29 @@ void wl_cfgp2p_print_actframe(bool tx, void *frame, u32 frame_len) sd_act_frm = (wifi_p2psd_gas_pub_act_frame_t *)frame; switch (sd_act_frm->action) { case P2PSD_ACTION_ID_GAS_IREQ: - CFGP2P_DBG(("%s P2P GAS Initial Request\n", + CFGP2P_ERR(("%s P2P GAS Initial Request\n", (tx)? "TX" : "RX")); break; case P2PSD_ACTION_ID_GAS_IRESP: - CFGP2P_DBG(("%s P2P GAS Initial Response\n", + CFGP2P_ERR(("%s P2P GAS Initial Response\n", (tx)? "TX" : "RX")); break; case P2PSD_ACTION_ID_GAS_CREQ: - CFGP2P_DBG(("%s P2P GAS Comback Request\n", + CFGP2P_ERR(("%s P2P GAS Comback Request\n", (tx)? "TX" : "RX")); break; case P2PSD_ACTION_ID_GAS_CRESP: - CFGP2P_DBG(("%s P2P GAS Comback Response\n", + CFGP2P_ERR(("%s P2P GAS Comback Response\n", (tx)? "TX" : "RX")); break; default: - CFGP2P_DBG(("%s Unknown P2P GAS Frame\n", + CFGP2P_ERR(("%s Unknown P2P GAS Frame\n", (tx)? "TX" : "RX")); } + + } + } /* @@ -283,10 +286,8 @@ void wl_cfgp2p_deinit_priv(struct wl_priv *wl) { CFGP2P_DBG(("In\n")); - if (wl->p2p) { kfree(wl->p2p); - wl->p2p = NULL; } wl->p2p_supported = 0; } @@ -342,7 +343,7 @@ wl_cfgp2p_ifadd(struct wl_priv *wl, struct ether_addr *mac, u8 if_type, ifreq.chspec = chspec; memcpy(ifreq.addr.octet, mac->octet, sizeof(ifreq.addr.octet)); - CFGP2P_DBG(("---wl p2p_ifadd %02x:%02x:%02x:%02x:%02x:%02x %s %u\n", + CFGP2P_INFO(("---wl p2p_ifadd %02x:%02x:%02x:%02x:%02x:%02x %s %u\n", ifreq.addr.octet[0], ifreq.addr.octet[1], ifreq.addr.octet[2], ifreq.addr.octet[3], ifreq.addr.octet[4], ifreq.addr.octet[5], (if_type == WL_P2P_IF_GO) ? "go" : "client", @@ -828,6 +829,10 @@ exit: /* Check whether the given IE looks like WFA P2P IE. */ #define wl_cfgp2p_is_p2p_ie(ie, tlvs, len) wl_cfgp2p_has_ie(ie, tlvs, len, \ (const uint8 *)WFA_OUI, WFA_OUI_LEN, WFA_OUI_TYPE_P2P) +/* Check whether the given IE looks like WFA WFDisplay IE. */ +#define WFA_OUI_TYPE_WFD 0x0a /* WiFi Display OUI TYPE */ +#define wl_cfgp2p_is_wfd_ie(ie, tlvs, len) wl_cfgp2p_has_ie(ie, tlvs, len, \ + (const uint8 *)WFA_OUI, WFA_OUI_LEN, WFA_OUI_TYPE_WFD) /* Delete and Set a management vndr ie to firmware * Parameters: * @wl : wl_private data @@ -952,7 +957,8 @@ wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bss ie_len = ie_buf[pos++]; if ((ie_id == DOT11_MNG_VS_ID) && (wl_cfgp2p_is_wps_ie(&ie_buf[pos-2], NULL, 0) || - wl_cfgp2p_is_p2p_ie(&ie_buf[pos-2], NULL, 0))) { + wl_cfgp2p_is_p2p_ie(&ie_buf[pos-2], NULL, 0) || + wl_cfgp2p_is_wfd_ie(&ie_buf[pos-2], NULL, 0))) { CFGP2P_INFO(("DELELED ID : %d, Len : %d , OUI :" "%02x:%02x:%02x\n", ie_id, ie_len, ie_buf[pos], ie_buf[pos+1], ie_buf[pos+2])); @@ -978,7 +984,8 @@ wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bss ie_len = ie_buf[pos++]; if ((ie_id == DOT11_MNG_VS_ID) && (wl_cfgp2p_is_wps_ie(&ie_buf[pos-2], NULL, 0) || - wl_cfgp2p_is_p2p_ie(&ie_buf[pos-2], NULL, 0))) { + wl_cfgp2p_is_p2p_ie(&ie_buf[pos-2], NULL, 0) || + wl_cfgp2p_is_wfd_ie(&ie_buf[pos-2], NULL, 0))) { CFGP2P_INFO(("ADDED ID : %d, Len : %d , OUI :" "%02x:%02x:%02x\n", ie_id, ie_len, ie_buf[pos], ie_buf[pos+1], ie_buf[pos+2])); @@ -1089,6 +1096,18 @@ wl_cfgp2p_find_p2pie(u8 *parse, u32 len) return NULL; } +wifi_wfd_ie_t * +wl_cfgp2p_find_wfdie(u8 *parse, u32 len) +{ + bcm_tlv_t *ie; + + while ((ie = bcm_parse_tlvs(parse, (int)len, DOT11_MNG_VS_ID))) { + if (wl_cfgp2p_is_wfd_ie((uint8*)ie, &parse, &len)) { + return (wifi_wfd_ie_t *)ie; + } + } + return NULL; +} static s32 wl_cfgp2p_vndr_ie(struct wl_priv *wl, struct net_device *ndev, s32 bssidx, s32 pktflag, s8 *oui, s32 ie_id, s8 *data, s32 data_len, s32 delete) @@ -1526,7 +1545,6 @@ wl_cfgp2p_supported(struct wl_priv *wl, struct net_device *ndev) } return p2p_supported; } - /* Cleanup P2P resources */ s32 wl_cfgp2p_down(struct wl_priv *wl) @@ -1536,7 +1554,6 @@ wl_cfgp2p_down(struct wl_priv *wl) wl_cfgp2p_deinit_priv(wl); return 0; } - s32 wl_cfgp2p_set_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf, int len) { @@ -1610,10 +1627,10 @@ wl_cfgp2p_set_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf, in } return ret; } - s32 wl_cfgp2p_get_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf, int buf_len) { + wifi_p2p_noa_desc_t *noa_desc; int len = 0, i; char _buf[200]; @@ -1653,7 +1670,6 @@ wl_cfgp2p_get_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf, in } return len * 2; } - s32 wl_cfgp2p_set_p2p_ps(struct wl_priv *wl, struct net_device *ndev, char* buf, int len) { @@ -1679,14 +1695,15 @@ wl_cfgp2p_set_p2p_ps(struct wl_priv *wl, struct net_device *ndev, char* buf, int } } - if (legacy_ps != -1) { - s32 pm = legacy_ps ? PM_MAX : PM_OFF; + if ((legacy_ps != -1) && ((legacy_ps == PM_MAX) || (legacy_ps == PM_OFF))) { ret = wldev_ioctl(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION), - WLC_SET_PM, &pm, sizeof(pm), true); + WLC_SET_PM, &legacy_ps, sizeof(legacy_ps), true); if (unlikely(ret)) { CFGP2P_ERR(("error (%d)\n", ret)); } } + else + CFGP2P_ERR(("ilegal setting\n")); } else { CFGP2P_ERR(("ERROR: set_p2p_ps in non-p2p mode\n")); @@ -1886,7 +1903,6 @@ wl_cfgp2p_unregister_ndev(struct wl_priv *wl) return 0; } - static int wl_cfgp2p_start_xmit(struct sk_buff *skb, struct net_device *ndev) { CFGP2P_DBG(("(%s) is not used for data operations. Droping the packet. \n", ndev->name)); @@ -1904,7 +1920,11 @@ static int wl_cfgp2p_do_ioctl(struct net_device *net, struct ifreq *ifr, int cmd * For Android PRIV CMD handling map it to primary I/F */ if (cmd == SIOCDEVPRIVATE+1) { +#if defined(OEM_ANROID) ret = wl_android_priv_cmd(ndev, ifr, cmd); +#else + (void)ndev; +#endif } else { CFGP2P_ERR(("%s: IOCTL req 0x%x on p2p0 I/F. Ignoring. \n", @@ -1917,34 +1937,12 @@ static int wl_cfgp2p_do_ioctl(struct net_device *net, struct ifreq *ifr, int cmd static int wl_cfgp2p_if_open(struct net_device *net) { - struct wireless_dev *wdev = net->ieee80211_ptr; - - if (!wdev) - return -EINVAL; - - /* If suppose F/W download (ifconfig wlan0 up) hasn't been done by now, - * do it here. This will make sure that in concurrent mode, supplicant - * is not dependent on a particular order of interface initialization. - * i.e you may give wpa_supp -iwlan0 -N -ip2p0 or wpa_supp -ip2p0 -N - * -iwlan0. - */ - wl_cfg80211_do_driver_init(net); - - wdev->wiphy->interface_modes |= (BIT(NL80211_IFTYPE_P2P_CLIENT) - | BIT(NL80211_IFTYPE_P2P_GO)); - + CFGP2P_DBG(("Do Nothing \n")); return 0; } static int wl_cfgp2p_if_stop(struct net_device *net) { - struct wireless_dev *wdev = net->ieee80211_ptr; - - if (!wdev) - return -EINVAL; - - wdev->wiphy->interface_modes = (wdev->wiphy->interface_modes) - & (~(BIT(NL80211_IFTYPE_P2P_CLIENT)| - BIT(NL80211_IFTYPE_P2P_GO))); + CFGP2P_DBG(("Do Nothing \n")); return 0; } diff --git a/drivers/net/wireless/bcmdhd/wl_cfgp2p.h b/drivers/net/wireless/bcmdhd/wl_cfgp2p.h index 1e5b1197e92..eb15d448ead 100644 --- a/drivers/net/wireless/bcmdhd/wl_cfgp2p.h +++ b/drivers/net/wireless/bcmdhd/wl_cfgp2p.h @@ -1,9 +1,9 @@ /* * Linux cfgp2p driver * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: wl_cfgp2p.h,v 1.1.4.1.2.8 2011/02/09 01:37:52 Exp $ + * $Id: wl_cfgp2p.h 308397 2012-01-15 07:32:58Z $ */ #ifndef _wl_cfgp2p_h_ #define _wl_cfgp2p_h_ @@ -31,6 +31,7 @@ struct wl_priv; extern u32 wl_dbg_level; +typedef struct wifi_p2p_ie wifi_wfd_ie_t; /* Enumeration of the usages of the BSSCFGs used by the P2P Library. Do not * confuse this with a bsscfg index. This value is an index into the * saved_ie[] array of structures which in turn contains a bsscfg index field. @@ -101,11 +102,11 @@ enum wl_cfgp2p_status { #define wl_to_p2p_bss_saved_ie(w, type) ((wl)->p2p->bss_idx[type].saved_ie) #define wl_to_p2p_bss_private(w, type) ((wl)->p2p->bss_idx[type].private_data) #define wl_to_p2p_bss(wl, type) ((wl)->p2p->bss_idx[type]) -#define wl_get_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? 0:test_bit(WLP2P_STATUS_ ## stat, \ +#define wl_get_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? 0 : test_bit(WLP2P_STATUS_ ## stat, \ &(wl)->p2p->status)) -#define wl_set_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? 0:set_bit(WLP2P_STATUS_ ## stat, \ +#define wl_set_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? 0 : set_bit(WLP2P_STATUS_ ## stat, \ &(wl)->p2p->status)) -#define wl_clr_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? 0:clear_bit(WLP2P_STATUS_ ## stat, \ +#define wl_clr_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? 0 : clear_bit(WLP2P_STATUS_ ## stat, \ &(wl)->p2p->status)) #define wl_chg_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? 0:change_bit(WLP2P_STATUS_ ## stat, \ &(wl)->p2p->status)) @@ -192,6 +193,8 @@ wl_cfgp2p_find_wpsie(u8 *parse, u32 len); extern wifi_p2p_ie_t * wl_cfgp2p_find_p2pie(u8 *parse, u32 len); +extern wifi_wfd_ie_t * +wl_cfgp2p_find_wfdie(u8 *parse, u32 len); extern s32 wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bssidx, s32 pktflag, const u8 *vndr_ie, u32 vndr_ie_len); diff --git a/drivers/net/wireless/bcmdhd/wl_dbg.h b/drivers/net/wireless/bcmdhd/wl_dbg.h index 0b99557cbe8..ce73a276484 100644 --- a/drivers/net/wireless/bcmdhd/wl_dbg.h +++ b/drivers/net/wireless/bcmdhd/wl_dbg.h @@ -2,9 +2,9 @@ * Minimal debug/trace/assert driver definitions for * Broadcom 802.11 Networking Adapter. * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -22,11 +22,10 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: wl_dbg.h,v 1.115.6.3 2010-12-15 21:42:23 Exp $ + * $Id: wl_dbg.h 308108 2012-01-13 12:26:08Z $ */ - #ifndef _wl_dbg_h_ #define _wl_dbg_h_ @@ -34,15 +33,30 @@ extern uint32 wl_msg_level; extern uint32 wl_msg_level2; -#define WL_PRINT(args) printf args +#define WL_TIMESTAMP() +#if 0 && (VERSION_MAJOR > 9) +#include +#define WL_PRINT(args) do { printf args; IO8Log args; } while (0) +#else +#define WL_PRINT(args) do { WL_TIMESTAMP(); printf args; } while (0) +#endif -#define WL_NONE(args) -#define WL_ERROR(args) -#define WL_TRACE(args) +#define WL_NONE(args) +#define WL_ERROR(args) +#define WL_TRACE(args) +#define WL_APSTA_UPDN(args) +#define WL_APSTA_RX(args) +#ifdef WLMSG_WSEC +#define WL_WSEC(args) WL_PRINT(args) +#define WL_WSEC_DUMP(args) WL_PRINT(args) +#else +#define WL_WSEC(args) +#define WL_WSEC_DUMP(args) +#endif extern uint32 wl_msg_level; extern uint32 wl_msg_level2; diff --git a/drivers/net/wireless/bcmdhd/wl_iw.c b/drivers/net/wireless/bcmdhd/wl_iw.c index d09448a7932..4f8a76fd027 100644 --- a/drivers/net/wireless/bcmdhd/wl_iw.c +++ b/drivers/net/wireless/bcmdhd/wl_iw.c @@ -1,9 +1,9 @@ /* * Linux Wireless Extensions support * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,10 +21,11 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: wl_iw.c,v 1.132.2.18 2011-02-05 01:44:47 $ + * $Id: wl_iw.c 302026 2011-12-09 11:51:50Z $ */ -#include +#if defined(USE_IW) +#define LINUX_PORT #include #include @@ -37,118 +38,51 @@ #include #include -#include -#include -#include -typedef void wlc_info_t; -typedef void wl_info_t; -typedef const struct si_pub si_t; +typedef const struct si_pub si_t; #include -#include -#include -#include -#define WL_ERROR(x) printf x -#define WL_TRACE(x) -#define WL_ASSOC(x) -#define WL_INFORM(x) -#define WL_WSEC(x) -#define WL_SCAN(x) - - -#ifdef PNO_SET_DEBUG -#define WL_PNO(x) printf x -#else -#define WL_PNO(x) -#endif +#include +#include -#define JF2MS ((((jiffies / HZ) * 1000) + ((jiffies % HZ) * 1000) / HZ)) +#ifdef BCMWAPI_WPI -#ifdef COEX_DBG -#define WL_TRACE_COEX(x) printf("TS:%lu ", JF2MS); \ - printf x -#else -#define WL_TRACE_COEX(x) +#ifndef IW_ENCODE_ALG_SM4 +#define IW_ENCODE_ALG_SM4 0x20 #endif -#ifdef SCAN_DBG -#define WL_TRACE_SCAN(x) printf("TS:%lu ", JF2MS); \ - printf x -#else -#define WL_TRACE_SCAN(x) +#ifndef IW_AUTH_WAPI_ENABLED +#define IW_AUTH_WAPI_ENABLED 0x20 #endif +#ifndef IW_AUTH_WAPI_VERSION_1 +#define IW_AUTH_WAPI_VERSION_1 0x00000008 +#endif -#include - - - - -#define IW_WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED)) - -#include - -#define WL_IW_USE_ISCAN 1 -#define ENABLE_ACTIVE_PASSIVE_SCAN_SUPPRESS 1 +#ifndef IW_AUTH_CIPHER_SMS4 +#define IW_AUTH_CIPHER_SMS4 0x00000020 +#endif -#ifdef OEM_CHROMIUMOS -bool g_set_essid_before_scan = TRUE; +#ifndef IW_AUTH_KEY_MGMT_WAPI_PSK +#define IW_AUTH_KEY_MGMT_WAPI_PSK 4 #endif -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 - struct mutex g_wl_ss_scan_lock; +#ifndef IW_AUTH_KEY_MGMT_WAPI_CERT +#define IW_AUTH_KEY_MGMT_WAPI_CERT 8 +#endif #endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) +#include +#endif #if defined(SOFTAP) -#define WL_SOFTAP(x) -static struct net_device *priv_dev; -extern bool ap_cfg_running; -extern bool ap_fw_loaded; struct net_device *ap_net_dev = NULL; -tsk_ctl_t ap_eth_ctl; -static int wl_iw_set_ap_security(struct net_device *dev, struct ap_profile *ap); -static int wl_iw_softap_deassoc_stations(struct net_device *dev, u8 *mac); -#endif - - -#define WL_IW_IOCTL_CALL(func_call) \ - do { \ - func_call; \ - } while (0) - -#define RETURN_IF_EXTRA_NULL(extra) \ - if (!extra) { \ - WL_ERROR(("%s: error : extra is null pointer\n", __FUNCTION__)); \ - return -EINVAL; \ - } - -static int g_onoff = G_WLAN_SET_ON; -wl_iw_extra_params_t g_wl_iw_params; - - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 - -static struct mutex wl_cache_lock; -static struct mutex wl_softap_lock; - -#define DHD_OS_MUTEX_INIT(a) mutex_init(a) -#define DHD_OS_MUTEX_LOCK(a) mutex_lock(a) -#define DHD_OS_MUTEX_UNLOCK(a) mutex_unlock(a) - -#else - -#define DHD_OS_MUTEX_INIT(a) -#define DHD_OS_MUTEX_LOCK(a) -#define DHD_OS_MUTEX_UNLOCK(a) - +tsk_ctl_t ap_eth_ctl; #endif -#include -extern void dhd_customer_gpio_wlan_ctrl(int onoff); -extern uint dhd_dev_reset(struct net_device *dev, uint8 flag); -extern void dhd_dev_init_ioctl(struct net_device *dev); +extern bool wl_iw_conn_status_str(uint32 event_type, uint32 status, + uint32 reason, char* stringBuf, uint buflen); uint wl_msg_level = WL_ERROR_VAL; @@ -162,35 +96,14 @@ uint wl_msg_level = WL_ERROR_VAL; #define htodchanspec(i) i #define dtohchanspec(i) i -#ifdef CONFIG_WIRELESS_EXT - extern struct iw_statistics *dhd_get_wireless_stats(struct net_device *dev); extern int dhd_wait_pend8021x(struct net_device *dev); -#endif #if WIRELESS_EXT < 19 #define IW_IOCTL_IDX(cmd) ((cmd) - SIOCIWFIRST) #define IW_EVENT_IDX(cmd) ((cmd) - IWEVFIRST) #endif -static void *g_scan = NULL; -static volatile uint g_scan_specified_ssid; -static wlc_ssid_t g_specific_ssid; - -static wlc_ssid_t g_ssid; - -#ifdef CONFIG_WPS2 -static char *g_wps_probe_req_ie; -static int g_wps_probe_req_ie_len; -#endif - -bool btcoex_is_sco_active(struct net_device *dev); -static wl_iw_ss_cache_ctrl_t g_ss_cache_ctrl; -#if defined(CONFIG_FIRST_SCAN) -static volatile uint g_first_broadcast_scan; -static volatile uint g_first_counter_scans; -#define MAX_ALLOWED_BLOCK_SCAN_FROM_FIRST_SCAN 3 -#endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) #define DAEMONIZE(a) daemonize(a); \ @@ -205,15 +118,6 @@ static volatile uint g_first_counter_scans; } while (0); #endif -#if defined(WL_IW_USE_ISCAN) -#if !defined(CSCAN) -static void wl_iw_free_ss_cache(void); -static int wl_iw_run_ss_cache_timer(int kick_off); -#endif -#if defined(CONFIG_FIRST_SCAN) -int wl_iw_iscan_set_scan_broadcast_prep(struct net_device *dev, uint flag); -#endif -static int dev_wlc_bufvar_set(struct net_device *dev, char *name, char *buf, int len); #define ISCAN_STATE_IDLE 0 #define ISCAN_STATE_SCANING 1 @@ -234,104 +138,26 @@ typedef struct iscan_info { iscan_buf_t * list_cur; - tsk_ctl_t tsk_ctl; + long sysioc_pid; + struct semaphore sysioc_sem; + struct completion sysioc_exited; + - uint32 scan_flag; -#if defined CSCAN - char ioctlbuf[WLC_IOCTL_MEDLEN]; -#else char ioctlbuf[WLC_IOCTL_SMLEN]; -#endif - - wl_iscan_params_t *iscan_ex_params_p; - int iscan_ex_param_size; } iscan_info_t; - - - -#define COEX_DHCP 1 -#ifdef COEX_DHCP - -#define BT_DHCP_eSCO_FIX -#define BT_DHCP_USE_FLAGS -#define BT_DHCP_OPPORTUNITY_WINDOW_TIME 2500 -#define BT_DHCP_FLAG_FORCE_TIME 5500 - - - -static int wl_iw_set_btcoex_dhcp( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -); - -static void wl_iw_bt_flag_set(struct net_device *dev, bool set); -static void wl_iw_bt_release(void); - -typedef enum bt_coex_status { - BT_DHCP_IDLE = 0, - BT_DHCP_START, - BT_DHCP_OPPORTUNITY_WINDOW, - BT_DHCP_FLAG_FORCE_TIMEOUT -} coex_status_t; - - -typedef struct bt_info { - struct net_device *dev; - struct timer_list timer; - uint32 timer_ms; - uint32 timer_on; - uint32 ts_dhcp_start; - uint32 ts_dhcp_ok; - bool dhcp_done; - int bt_state; - - - tsk_ctl_t tsk_ctl; - -} bt_info_t; - -bt_info_t *g_bt = NULL; -static void wl_iw_bt_timerfunc(ulong data); -#endif iscan_info_t *g_iscan = NULL; -void dhd_print_buf(void *pbuf, int len, int bytes_per_line); static void wl_iw_timerfunc(ulong data); static void wl_iw_set_event_mask(struct net_device *dev); -static int -wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, uint16 action); -#endif - -static int -wl_iw_set_scan( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -); - -#ifndef CSCAN -static int -wl_iw_get_scan( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -); +static int wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, uint16 action); -static uint -wl_iw_get_scan_prep( - wl_scan_results_t *list, - struct iw_request_info *info, - char *extra, - short max_size -); -#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) +#define IW_DEV_IF(dev) ((wl_iw_t *)netdev_priv(dev)) +#else +#define IW_DEV_IF(dev) ((wl_iw_t *)dev->priv) +#endif -static void -swap_key_from_BE( - wl_wsec_key_t *key +static void swap_key_from_BE( + wl_wsec_key_t *key ) { key->index = htod32(key->index); @@ -343,9 +169,8 @@ swap_key_from_BE( key->iv_initialized = htod32(key->iv_initialized); } -static void -swap_key_to_BE( - wl_wsec_key_t *key +static void swap_key_to_BE( + wl_wsec_key_t *key ) { key->index = dtoh32(key->index); @@ -368,95 +193,34 @@ dev_wlc_ioctl( struct ifreq ifr; wl_ioctl_t ioc; mm_segment_t fs; - int ret = -EINVAL; - - if (!dev) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - return ret; - } - - net_os_wake_lock(dev); - - WL_INFORM(("%s, PID:%x: send Local IOCTL -> dhd: cmd:0x%x, buf:%p, len:%d ,\n", - __FUNCTION__, current->pid, cmd, arg, len)); + int ret; - if (g_onoff == G_WLAN_SET_ON) { - memset(&ioc, 0, sizeof(ioc)); - ioc.cmd = cmd; - ioc.buf = arg; - ioc.len = len; + memset(&ioc, 0, sizeof(ioc)); + ioc.cmd = cmd; + ioc.buf = arg; + ioc.len = len; - strcpy(ifr.ifr_name, dev->name); - ifr.ifr_data = (caddr_t) &ioc; + strcpy(ifr.ifr_name, dev->name); + ifr.ifr_data = (caddr_t) &ioc; - - ret = dev_open(dev); - if (ret) { - WL_ERROR(("%s: Error dev_open: %d\n", __func__, ret)); - net_os_wake_unlock(dev); - return ret; - } +#ifndef LINUX_HYBRID + + dev_open(dev); +#endif - fs = get_fs(); - set_fs(get_ds()); -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31) - ret = dev->do_ioctl(dev, &ifr, SIOCDEVPRIVATE); + fs = get_fs(); + set_fs(get_ds()); +#if defined(WL_USE_NETDEV_OPS) + ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE); #else - ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE); -#endif - set_fs(fs); - } - else { - WL_TRACE(("%s: call after driver stop : ignored\n", __FUNCTION__)); - } - - net_os_wake_unlock(dev); + ret = dev->do_ioctl(dev, &ifr, SIOCDEVPRIVATE); +#endif + set_fs(fs); return ret; } -static int -dev_wlc_intvar_get_reg( - struct net_device *dev, - char *name, - uint reg, - int *retval) -{ - union { - char buf[WLC_IOCTL_SMLEN]; - int val; - } var; - int error; - - uint len; - len = bcm_mkiovar(name, (char *)(®), sizeof(reg), (char *)(&var), sizeof(var.buf)); - ASSERT(len); - error = dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)&var, len); - - *retval = dtoh32(var.val); - return (error); -} - - -static int -dev_wlc_intvar_set_reg( - struct net_device *dev, - char *name, - char *addr, - char * val) -{ - char reg_addr[8]; - - memset(reg_addr, 0, sizeof(reg_addr)); - memcpy((char *)®_addr[0], (char *)addr, 4); - memcpy((char *)®_addr[4], (char *)val, 4); - - return (dev_wlc_bufvar_set(dev, name, (char *)®_addr[0], sizeof(reg_addr))); -} - - - static int dev_wlc_intvar_set( @@ -474,7 +238,6 @@ dev_wlc_intvar_set( return (dev_wlc_ioctl(dev, WLC_SET_VAR, buf, len)); } -#if defined(WL_IW_USE_ISCAN) static int dev_iw_iovar_setbuf( struct net_device *dev, @@ -489,9 +252,6 @@ dev_iw_iovar_setbuf( iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen); ASSERT(iolen); - if (iolen == 0) - return 0; - return (dev_wlc_ioctl(dev, WLC_SET_VAR, bufptr, iolen)); } @@ -508,11 +268,10 @@ dev_iw_iovar_getbuf( iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen); ASSERT(iolen); + BCM_REFERENCE(iolen); return (dev_wlc_ioctl(dev, WLC_GET_VAR, bufptr, buflen)); } -#endif - #if WIRELESS_EXT > 17 static int @@ -521,41 +280,47 @@ dev_wlc_bufvar_set( char *name, char *buf, int len) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31) - char ioctlbuf[MAX_WLIW_IOCTL_LEN]; -#else - static char ioctlbuf[MAX_WLIW_IOCTL_LEN]; -#endif + char *ioctlbuf; uint buflen; + int error; + + ioctlbuf = kmalloc(MAX_WLIW_IOCTL_LEN, GFP_KERNEL); + if (!ioctlbuf) + return -ENOMEM; - buflen = bcm_mkiovar(name, buf, len, ioctlbuf, sizeof(ioctlbuf)); + buflen = bcm_mkiovar(name, buf, len, ioctlbuf, MAX_WLIW_IOCTL_LEN); ASSERT(buflen); + error = dev_wlc_ioctl(dev, WLC_SET_VAR, ioctlbuf, buflen); - return (dev_wlc_ioctl(dev, WLC_SET_VAR, ioctlbuf, buflen)); + kfree(ioctlbuf); + return error; } #endif + static int dev_wlc_bufvar_get( struct net_device *dev, char *name, char *buf, int buflen) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31) - char ioctlbuf[MAX_WLIW_IOCTL_LEN]; -#else - static char ioctlbuf[MAX_WLIW_IOCTL_LEN]; -#endif + char *ioctlbuf; int error; + uint len; - len = bcm_mkiovar(name, NULL, 0, ioctlbuf, sizeof(ioctlbuf)); + ioctlbuf = kmalloc(MAX_WLIW_IOCTL_LEN, GFP_KERNEL); + if (!ioctlbuf) + return -ENOMEM; + len = bcm_mkiovar(name, NULL, 0, ioctlbuf, MAX_WLIW_IOCTL_LEN); ASSERT(len); + BCM_REFERENCE(len); error = dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)ioctlbuf, MAX_WLIW_IOCTL_LEN); if (!error) bcopy(ioctlbuf, buf, buflen); + kfree(ioctlbuf); return (error); } @@ -586,7088 +351,2553 @@ dev_wlc_intvar_get( } +#if WIRELESS_EXT < 13 +struct iw_request_info +{ + __u16 cmd; + __u16 flags; +}; + +typedef int (*iw_handler)(struct net_device *dev, struct iw_request_info *info, + void *wrqu, char *extra); +#endif + #if WIRELESS_EXT > 12 static int -wl_iw_set_active_scan( +wl_iw_set_leddc( struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra ) { - int as = 0; - int error = 0; - char *p = extra; - -#if defined(WL_IW_USE_ISCAN) - if (g_iscan->iscan_state == ISCAN_STATE_IDLE) -#endif - error = dev_wlc_ioctl(dev, WLC_SET_PASSIVE_SCAN, &as, sizeof(as)); -#if defined(WL_IW_USE_ISCAN) - else - g_iscan->scan_flag = as; -#endif - p += snprintf(p, MAX_WX_STRING, "OK"); + int dc = *(int *)extra; + int error; - wrqu->data.length = p - extra + 1; + error = dev_wlc_intvar_set(dev, "leddc", dc); return error; } static int -wl_iw_set_passive_scan( +wl_iw_set_vlanmode( struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra ) { - int ps = 1; - int error = 0; - char *p = extra; - -#if defined(WL_IW_USE_ISCAN) - if (g_iscan->iscan_state == ISCAN_STATE_IDLE) { -#endif - - - if (g_scan_specified_ssid == 0) { - error = dev_wlc_ioctl(dev, WLC_SET_PASSIVE_SCAN, &ps, sizeof(ps)); - } -#if defined(WL_IW_USE_ISCAN) - } - else - g_iscan->scan_flag = ps; -#endif - - p += snprintf(p, MAX_WX_STRING, "OK"); + int mode = *(int *)extra; + int error; - wrqu->data.length = p - extra + 1; + mode = htod32(mode); + error = dev_wlc_intvar_set(dev, "vlan_mode", mode); return error; } - static int -wl_iw_set_txpower( +wl_iw_set_pm( struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra ) { - int error = 0; - char *p = extra; - int txpower = -1; - - txpower = bcm_atoi(extra + strlen(TXPOWER_SET_CMD) + 1); - if ((txpower >= 0) && (txpower <= 127)) - { - txpower |= WL_TXPWR_OVERRIDE; - txpower = htod32(txpower); - - error = dev_wlc_intvar_set(dev, "qtxpower", txpower); - p += snprintf(p, MAX_WX_STRING, "OK"); - WL_TRACE(("%s: set TXpower 0x%X is OK\n", __FUNCTION__, txpower)); - } else { - WL_ERROR(("%s: set tx power failed\n", __FUNCTION__)); - p += snprintf(p, MAX_WX_STRING, "FAIL"); - } + int pm = *(int *)extra; + int error; - wrqu->data.length = p - extra + 1; + pm = htod32(pm); + error = dev_wlc_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm)); return error; } +#endif -static int -wl_iw_get_macaddr( +int +wl_iw_send_priv_event( struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra + char *flag ) { - int error; - char buf[128]; - struct ether_addr *id; - char *p = extra; - - - strcpy(buf, "cur_etheraddr"); - error = dev_wlc_ioctl(dev, WLC_GET_VAR, buf, sizeof(buf)); - id = (struct ether_addr *) buf; - p += snprintf(p, MAX_WX_STRING, "Macaddr = %02X:%02X:%02X:%02X:%02X:%02X\n", - id->octet[0], id->octet[1], id->octet[2], - id->octet[3], id->octet[4], id->octet[5]); - wrqu->data.length = p - extra + 1; + union iwreq_data wrqu; + char extra[IW_CUSTOM_MAX + 1]; + int cmd; - return error; -} + cmd = IWEVCUSTOM; + memset(&wrqu, 0, sizeof(wrqu)); + if (strlen(flag) > sizeof(extra)) + return -1; + strcpy(extra, flag); + wrqu.data.length = strlen(extra); + wireless_send_event(dev, cmd, &wrqu, extra); + WL_TRACE(("Send IWEVCUSTOM Event as %s\n", extra)); + return 0; +} static int -wl_iw_set_country( +wl_iw_config_commit( struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, + void *zwrq, char *extra ) { - char country_code[WLC_CNTRY_BUF_SZ]; - int error = 0; - char *p = extra; - int country_offset; - int country_code_size; - wl_country_t cspec = {{0}, 0, {0}}; - char smbuf[WLC_IOCTL_SMLEN]; - scb_val_t scbval; - - cspec.rev = -1; - memset(country_code, 0, sizeof(country_code)); - memset(smbuf, 0, sizeof(smbuf)); - - - country_offset = strcspn(extra, " "); - country_code_size = strlen(extra) - country_offset; + wlc_ssid_t ssid; + int error; + struct sockaddr bssid; - - if (country_offset != 0) { - strncpy(country_code, extra + country_offset +1, - MIN(country_code_size, sizeof(country_code))); + WL_TRACE(("%s: SIOCSIWCOMMIT\n", dev->name)); - - bzero(&scbval, sizeof(scb_val_t)); - if ((error = dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t)))) { - WL_ERROR(("%s: set country failed due to Disassoc error\n", __FUNCTION__)); - goto exit_failed; - } + if ((error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid)))) + return error; - memcpy(cspec.country_abbrev, country_code, WLC_CNTRY_BUF_SZ); - memcpy(cspec.ccode, country_code, WLC_CNTRY_BUF_SZ); + ssid.SSID_len = dtoh32(ssid.SSID_len); - get_customized_country_code((char *)&cspec.country_abbrev, &cspec); + if (!ssid.SSID_len) + return 0; - - if ((error = dev_iw_iovar_setbuf(dev, "country", &cspec, - sizeof(cspec), smbuf, sizeof(smbuf))) >= 0) { - p += snprintf(p, MAX_WX_STRING, "OK"); - WL_ERROR(("%s: set country for %s as %s rev %d is OK\n", - __FUNCTION__, country_code, cspec.ccode, cspec.rev)); - dhd_bus_country_set(dev, &cspec); - goto exit; - } + bzero(&bssid, sizeof(struct sockaddr)); + if ((error = dev_wlc_ioctl(dev, WLC_REASSOC, &bssid, ETHER_ADDR_LEN))) { + WL_ERROR(("%s: WLC_REASSOC failed (%d)\n", __FUNCTION__, error)); + return error; } - WL_ERROR(("%s: set country for %s as %s rev %d failed\n", - __FUNCTION__, country_code, cspec.ccode, cspec.rev)); - -exit_failed: - p += snprintf(p, MAX_WX_STRING, "FAIL"); - -exit: - wrqu->data.length = p - extra + 1; - return error; + return 0; } static int -wl_iw_set_power_mode( +wl_iw_get_name( struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, + union iwreq_data *cwrq, char *extra ) { - int error = 0; - char *p = extra; - static int pm = PM_FAST; - int pm_local = PM_OFF; - char powermode_val = 0; + int phytype, err; + uint band[3]; + char cap[5]; - WL_TRACE_COEX(("%s: DHCP session cmd:%s\n", __FUNCTION__, extra)); - - strncpy((char *)&powermode_val, extra + strlen("POWERMODE") +1, 1); - - if (strnicmp((char *)&powermode_val, "1", strlen("1")) == 0) { - - WL_TRACE(("%s: DHCP session starts\n", __FUNCTION__)); - - dev_wlc_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm)); - dev_wlc_ioctl(dev, WLC_SET_PM, &pm_local, sizeof(pm_local)); + WL_TRACE(("%s: SIOCGIWNAME\n", dev->name)); - - net_os_set_packet_filter(dev, 0); + cap[0] = 0; + if ((err = dev_wlc_ioctl(dev, WLC_GET_PHYTYPE, &phytype, sizeof(phytype))) < 0) + goto done; + if ((err = dev_wlc_ioctl(dev, WLC_GET_BANDLIST, band, sizeof(band))) < 0) + goto done; -#ifdef COEX_DHCP - g_bt->ts_dhcp_start = JF2MS; - g_bt->dhcp_done = FALSE; - WL_TRACE_COEX(("%s: DHCP start, pm:%d changed to pm:%d\n", - __FUNCTION__, pm, pm_local)); - -#endif - } else if (strnicmp((char *)&powermode_val, "0", strlen("0")) == 0) { - - - dev_wlc_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm)); - - - net_os_set_packet_filter(dev, 1); - -#ifdef COEX_DHCP - g_bt->dhcp_done = TRUE; - g_bt->ts_dhcp_ok = JF2MS; - WL_TRACE_COEX(("%s: DHCP done for:%d ms, restored pm:%d\n", - __FUNCTION__, (g_bt->ts_dhcp_ok - g_bt->ts_dhcp_start), pm)); -#endif - - } else { - WL_ERROR(("%s Unkwown yet power setting, ignored\n", - __FUNCTION__)); - } - - p += snprintf(p, MAX_WX_STRING, "OK"); - - wrqu->data.length = p - extra + 1; - - return error; -} - - -bool btcoex_is_sco_active(struct net_device *dev) -{ - int ioc_res = 0; - bool res = FALSE; - int sco_id_cnt = 0; - int param27; - int i; - - for (i = 0; i < 12; i++) { - - ioc_res = dev_wlc_intvar_get_reg(dev, "btc_params", 27, ¶m27); - - WL_TRACE_COEX(("%s, sample[%d], btc params: 27:%x\n", - __FUNCTION__, i, param27)); - - if (ioc_res < 0) { - WL_ERROR(("%s ioc read btc params error\n", __FUNCTION__)); + band[0] = dtoh32(band[0]); + switch (phytype) { + case WLC_PHY_TYPE_A: + strcpy(cap, "a"); break; - } - - if ((param27 & 0x6) == 2) { - sco_id_cnt++; - } - - if (sco_id_cnt > 2) { - WL_TRACE_COEX(("%s, sco/esco detected, pkt id_cnt:%d samples:%d\n", - __FUNCTION__, sco_id_cnt, i)); - res = TRUE; + case WLC_PHY_TYPE_B: + strcpy(cap, "b"); + break; + case WLC_PHY_TYPE_LP: + case WLC_PHY_TYPE_G: + if (band[0] >= 2) + strcpy(cap, "abg"); + else + strcpy(cap, "bg"); + break; + case WLC_PHY_TYPE_N: + if (band[0] >= 2) + strcpy(cap, "abgn"); + else + strcpy(cap, "bgn"); break; - } - - msleep(5); - } - - return res; -} - -#if defined(BT_DHCP_eSCO_FIX) - -static int set_btc_esco_params(struct net_device *dev, bool trump_sco) -{ - static bool saved_status = FALSE; - - char buf_reg50va_dhcp_on[8] = { 50, 00, 00, 00, 0x22, 0x80, 0x00, 0x00 }; - char buf_reg51va_dhcp_on[8] = { 51, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 }; - char buf_reg64va_dhcp_on[8] = { 64, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 }; - char buf_reg65va_dhcp_on[8] = { 65, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 }; - char buf_reg71va_dhcp_on[8] = { 71, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 }; - - uint32 regaddr; - static uint32 saved_reg50; - static uint32 saved_reg51; - static uint32 saved_reg64; - static uint32 saved_reg65; - static uint32 saved_reg71; - - if (trump_sco) { - - - WL_TRACE_COEX(("Do new SCO/eSCO coex algo {save & override} \n")); - - - if ((!dev_wlc_intvar_get_reg(dev, "btc_params", 50, &saved_reg50)) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 51, &saved_reg51)) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 64, &saved_reg64)) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 65, &saved_reg65)) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 71, &saved_reg71))) { - - saved_status = TRUE; - WL_TRACE_COEX(("%s saved bt_params[50,51,64,65,71]:" - " 0x%x 0x%x 0x%x 0x%x 0x%x\n", - __FUNCTION__, saved_reg50, saved_reg51, - saved_reg64, saved_reg65, saved_reg71)); - - } else { - WL_ERROR((":%s: save btc_params failed\n", - __FUNCTION__)); - saved_status = FALSE; - return -1; - } - - WL_TRACE_COEX(("override with [50,51,64,65,71]:" - " 0x%x 0x%x 0x%x 0x%x 0x%x\n", - *(u32 *)(buf_reg50va_dhcp_on+4), - *(u32 *)(buf_reg51va_dhcp_on+4), - *(u32 *)(buf_reg64va_dhcp_on+4), - *(u32 *)(buf_reg65va_dhcp_on+4), - *(u32 *)(buf_reg71va_dhcp_on+4))); - - dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg50va_dhcp_on[0], 8); - dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg51va_dhcp_on[0], 8); - dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg64va_dhcp_on[0], 8); - dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg65va_dhcp_on[0], 8); - dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg71va_dhcp_on[0], 8); - - saved_status = TRUE; - - } else if (saved_status) { - - WL_TRACE_COEX(("Do new SCO/eSCO coex algo {save & override} \n")); - - regaddr = 50; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg50); - regaddr = 51; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg51); - regaddr = 64; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg64); - regaddr = 65; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg65); - regaddr = 71; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg71); - - WL_TRACE_COEX(("restore bt_params[50,51,64,65,71]: 0x%x 0x%x 0x%x 0x%x 0x%x\n", - saved_reg50, saved_reg51, saved_reg64, - saved_reg65, saved_reg71)); - - saved_status = FALSE; - } else { - WL_ERROR((":%s att to restore not saved BTCOEX params\n", - __FUNCTION__)); - return -1; } +done: + snprintf(cwrq->name, IFNAMSIZ, "IEEE 802.11%s", cap); return 0; } -#endif - static int -wl_iw_get_power_mode( +wl_iw_set_freq( struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, + struct iw_freq *fwrq, char *extra ) { - int error = 0; - int pm_local; - char *p = extra; - - error = dev_wlc_ioctl(dev, WLC_GET_PM, &pm_local, sizeof(pm_local)); - if (!error) { - WL_TRACE(("%s: Powermode = %d\n", __func__, pm_local)); - if (pm_local == PM_OFF) - pm_local = 1; - else - pm_local = 0; - p += snprintf(p, MAX_WX_STRING, "powermode = %d", pm_local); - } - else { - WL_TRACE(("%s: Error = %d\n", __func__, error)); - p += snprintf(p, MAX_WX_STRING, "FAIL"); - } - wrqu->data.length = p - extra + 1; - return error; -} + int error, chan; + uint sf = 0; -static int -wl_iw_set_btcoex_dhcp( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = 0; - char *p = extra; - char powermode_val = 0; - char buf_reg66va_dhcp_on[8] = { 66, 00, 00, 00, 0x10, 0x27, 0x00, 0x00 }; - char buf_reg41va_dhcp_on[8] = { 41, 00, 00, 00, 0x33, 0x00, 0x00, 0x00 }; - char buf_reg68va_dhcp_on[8] = { 68, 00, 00, 00, 0x90, 0x01, 0x00, 0x00 }; - - uint32 regaddr; - static uint32 saved_reg66; - static uint32 saved_reg41; - static uint32 saved_reg68; - static bool saved_status = FALSE; - -#ifdef COEX_DHCP - char buf_flag7_default[8] = { 7, 00, 00, 00, 0x0, 0x00, 0x00, 0x00}; -#endif + WL_TRACE(("%s: SIOCSIWFREQ\n", dev->name)); - strncpy((char *)&powermode_val, extra + strlen("BTCOEXMODE") +1, 1); - - if (strnicmp((char *)&powermode_val, "1", strlen("1")) == 0) { - - WL_TRACE(("%s: DHCP session starts\n", __FUNCTION__)); - - - if ((saved_status == FALSE) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 66, &saved_reg66)) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 41, &saved_reg41)) && - (!dev_wlc_intvar_get_reg(dev, "btc_params", 68, &saved_reg68))) { - saved_status = TRUE; - WL_TRACE(("Saved 0x%x 0x%x 0x%x\n", - saved_reg66, saved_reg41, saved_reg68)); - - - - -#ifdef COEX_DHCP - - if (btcoex_is_sco_active(dev)) { - - dev_wlc_bufvar_set(dev, "btc_params", - (char *)&buf_reg66va_dhcp_on[0], - sizeof(buf_reg66va_dhcp_on)); - - dev_wlc_bufvar_set(dev, "btc_params", - (char *)&buf_reg41va_dhcp_on[0], - sizeof(buf_reg41va_dhcp_on)); - - dev_wlc_bufvar_set(dev, "btc_params", - (char *)&buf_reg68va_dhcp_on[0], - sizeof(buf_reg68va_dhcp_on)); - saved_status = TRUE; - - g_bt->bt_state = BT_DHCP_START; - g_bt->timer_on = 1; - mod_timer(&g_bt->timer, g_bt->timer.expires); - WL_TRACE_COEX(("%s enable BT DHCP Timer\n", - __FUNCTION__)); - } -#endif - } - else if (saved_status == TRUE) { - WL_ERROR(("%s was called w/o DHCP OFF. Continue\n", __FUNCTION__)); - } + if (fwrq->e == 0 && fwrq->m < MAXCHANNEL) { + chan = fwrq->m; } - else if (strnicmp((char *)&powermode_val, "2", strlen("2")) == 0) { - - - - -#ifdef COEX_DHCP - - WL_TRACE(("%s disable BT DHCP Timer\n", __FUNCTION__)); - if (g_bt->timer_on) { - g_bt->timer_on = 0; - del_timer_sync(&g_bt->timer); - - if (g_bt->bt_state != BT_DHCP_IDLE) { - - WL_TRACE_COEX(("%s bt->bt_state:%d\n", - __FUNCTION__, g_bt->bt_state)); - - up(&g_bt->tsk_ctl.sema); - } - } - - - if (saved_status == TRUE) - dev_wlc_bufvar_set(dev, "btc_flags", - (char *)&buf_flag7_default[0], sizeof(buf_flag7_default)); -#endif + + else { - if (saved_status == TRUE) { - regaddr = 66; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg66); - regaddr = 41; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg41); - regaddr = 68; - dev_wlc_intvar_set_reg(dev, "btc_params", - (char *)®addr, (char *)&saved_reg68); - - WL_TRACE_COEX(("restore regs {66,41,68} <- 0x%x 0x%x 0x%x\n", - saved_reg66, saved_reg41, saved_reg68)); + if (fwrq->e >= 6) { + fwrq->e -= 6; + while (fwrq->e--) + fwrq->m *= 10; + } else if (fwrq->e < 6) { + while (fwrq->e++ < 6) + fwrq->m /= 10; } - saved_status = FALSE; - - } - else { - WL_ERROR(("%s Unkwown yet power setting, ignored\n", - __FUNCTION__)); - } - - p += snprintf(p, MAX_WX_STRING, "OK"); - - wrqu->data.length = p - extra + 1; - - return error; -} - -static int -wl_iw_set_suspend( -struct net_device *dev, -struct iw_request_info *info, -union iwreq_data *wrqu, -char *extra -) -{ - int suspend_flag; - int ret_now; - int ret = 0; - - suspend_flag = *(extra + strlen(SETSUSPEND_CMD) + 1) - '0'; - - if (suspend_flag != 0) - suspend_flag = 1; - - ret_now = net_os_set_suspend_disable(dev, suspend_flag); - - if (ret_now != suspend_flag) { - if (!(ret = net_os_set_suspend(dev, ret_now))) - WL_ERROR(("%s: Suspend Flag %d -> %d\n", - __FUNCTION__, ret_now, suspend_flag)); - else - WL_ERROR(("%s: failed %d\n", __FUNCTION__, ret)); - } - - return ret; -} + if (fwrq->m > 4000 && fwrq->m < 5000) + sf = WF_CHAN_FACTOR_4_G; -static int -wl_format_ssid(char* ssid_buf, uint8* ssid, int ssid_len) -{ - int i, c; - char *p = ssid_buf; - - if (ssid_len > 32) ssid_len = 32; - - for (i = 0; i < ssid_len; i++) { - c = (int)ssid[i]; - if (c == '\\') { - *p++ = '\\'; - *p++ = '\\'; - } else if (isprint((uchar)c)) { - *p++ = (char)c; - } else { - p += sprintf(p, "\\x%02X", c); - } + chan = wf_mhz2channel(fwrq->m, sf); } - *p = '\0'; + chan = htod32(chan); + if ((error = dev_wlc_ioctl(dev, WLC_SET_CHANNEL, &chan, sizeof(chan)))) + return error; - return p - ssid_buf; + + return -EINPROGRESS; } static int -wl_iw_get_link_speed( +wl_iw_get_freq( struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, + struct iw_freq *fwrq, char *extra ) { - int error = 0; - char *p = extra; - static int link_speed; - - - net_os_wake_lock(dev); - if (g_onoff == G_WLAN_SET_ON) { - error = dev_wlc_ioctl(dev, WLC_GET_RATE, &link_speed, sizeof(link_speed)); - link_speed *= 500000; - } + channel_info_t ci; + int error; - p += snprintf(p, MAX_WX_STRING, "LinkSpeed %d", link_speed/1000000); + WL_TRACE(("%s: SIOCGIWFREQ\n", dev->name)); - wrqu->data.length = p - extra + 1; + if ((error = dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci)))) + return error; - net_os_wake_unlock(dev); - return error; + + fwrq->m = dtoh32(ci.hw_channel); + fwrq->e = dtoh32(0); + return 0; } - static int -wl_iw_get_dtim_skip( +wl_iw_set_mode( struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, + __u32 *uwrq, char *extra ) { - int error = -1; - char *p = extra; - char iovbuf[32]; + int infra = 0, ap = 0, error = 0; - net_os_wake_lock(dev); - if (g_onoff == G_WLAN_SET_ON) { + WL_TRACE(("%s: SIOCSIWMODE\n", dev->name)); - memset(iovbuf, 0, sizeof(iovbuf)); - strcpy(iovbuf, "bcn_li_dtim"); + switch (*uwrq) { + case IW_MODE_MASTER: + infra = ap = 1; + break; + case IW_MODE_ADHOC: + case IW_MODE_AUTO: + break; + case IW_MODE_INFRA: + infra = 1; + break; + default: + return -EINVAL; + } + infra = htod32(infra); + ap = htod32(ap); - if ((error = dev_wlc_ioctl(dev, WLC_GET_VAR, - &iovbuf, sizeof(iovbuf))) >= 0) { + if ((error = dev_wlc_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(infra))) || + (error = dev_wlc_ioctl(dev, WLC_SET_AP, &ap, sizeof(ap)))) + return error; - p += snprintf(p, MAX_WX_STRING, "Dtim_skip %d", iovbuf[0]); - WL_TRACE(("%s: get dtim_skip = %d\n", __FUNCTION__, iovbuf[0])); - wrqu->data.length = p - extra + 1; - } - else - WL_ERROR(("%s: get dtim_skip failed code %d\n", - __FUNCTION__, error)); - } - net_os_wake_unlock(dev); - return error; + + return -EINPROGRESS; } - static int -wl_iw_set_dtim_skip( +wl_iw_get_mode( struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, + __u32 *uwrq, char *extra ) { - int error = -1; - char *p = extra; - int bcn_li_dtim; - char iovbuf[32]; - - net_os_wake_lock(dev); - if (g_onoff == G_WLAN_SET_ON) { - - bcn_li_dtim = htod32((uint)*(extra + strlen(DTIM_SKIP_SET_CMD) + 1) - '0'); - - if ((bcn_li_dtim >= 0) || ((bcn_li_dtim <= 5))) { - - memset(iovbuf, 0, sizeof(iovbuf)); - bcm_mkiovar("bcn_li_dtim", (char *)&bcn_li_dtim, - 4, iovbuf, sizeof(iovbuf)); - - if ((error = dev_wlc_ioctl(dev, WLC_SET_VAR, - &iovbuf, sizeof(iovbuf))) >= 0) { - p += snprintf(p, MAX_WX_STRING, "OK"); + int error, infra = 0, ap = 0; - - net_os_set_dtim_skip(dev, bcn_li_dtim); + WL_TRACE(("%s: SIOCGIWMODE\n", dev->name)); - WL_TRACE(("%s: set dtim_skip %d OK\n", __FUNCTION__, - bcn_li_dtim)); - goto exit; - } - else WL_ERROR(("%s: set dtim_skip %d failed code %d\n", - __FUNCTION__, bcn_li_dtim, error)); - } - else WL_ERROR(("%s Incorrect dtim_skip setting %d, ignored\n", - __FUNCTION__, bcn_li_dtim)); - } + if ((error = dev_wlc_ioctl(dev, WLC_GET_INFRA, &infra, sizeof(infra))) || + (error = dev_wlc_ioctl(dev, WLC_GET_AP, &ap, sizeof(ap)))) + return error; - p += snprintf(p, MAX_WX_STRING, "FAIL"); + infra = dtoh32(infra); + ap = dtoh32(ap); + *uwrq = infra ? ap ? IW_MODE_MASTER : IW_MODE_INFRA : IW_MODE_ADHOC; -exit: - wrqu->data.length = p - extra + 1; - net_os_wake_unlock(dev); - return error; + return 0; } - static int -wl_iw_get_band( +wl_iw_get_range( struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, + struct iw_point *dwrq, char *extra ) { - int error = -1; - char *p = extra; - static int band; + struct iw_range *range = (struct iw_range *) extra; + static int channels[MAXCHANNEL+1]; + wl_uint32_list_t *list = (wl_uint32_list_t *) channels; + wl_rateset_t rateset; + int error, i, k; + uint sf, ch; - net_os_wake_lock(dev); + int phytype; + int bw_cap = 0, sgi_tx = 0, nmode = 0; + channel_info_t ci; + uint8 nrate_list2copy = 0; + uint16 nrate_list[4][8] = { {13, 26, 39, 52, 78, 104, 117, 130}, + {14, 29, 43, 58, 87, 116, 130, 144}, + {27, 54, 81, 108, 162, 216, 243, 270}, + {30, 60, 90, 120, 180, 240, 270, 300}}; - if (g_onoff == G_WLAN_SET_ON) { - error = dev_wlc_ioctl(dev, WLC_GET_BAND, &band, sizeof(band)); + WL_TRACE(("%s: SIOCGIWRANGE\n", dev->name)); - p += snprintf(p, MAX_WX_STRING, "Band %d", band); + if (!extra) + return -EINVAL; - wrqu->data.length = p - extra + 1; - } + dwrq->length = sizeof(struct iw_range); + memset(range, 0, sizeof(*range)); - net_os_wake_unlock(dev); - return error; -} + + range->min_nwid = range->max_nwid = 0; + + list->count = htod32(MAXCHANNEL); + if ((error = dev_wlc_ioctl(dev, WLC_GET_VALID_CHANNELS, channels, sizeof(channels)))) + return error; + for (i = 0; i < dtoh32(list->count) && i < IW_MAX_FREQUENCIES; i++) { + range->freq[i].i = dtoh32(list->element[i]); -static int -wl_iw_set_band( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = -1; - char *p = extra; - uint band; + ch = dtoh32(list->element[i]); + if (ch <= CH_MAX_2G_CHANNEL) + sf = WF_CHAN_FACTOR_2_4_G; + else + sf = WF_CHAN_FACTOR_5_G; + + range->freq[i].m = wf_channel2mhz(ch, sf); + range->freq[i].e = 6; + } + range->num_frequency = range->num_channels = i; + + + range->max_qual.qual = 5; + + range->max_qual.level = 0x100 - 200; + + range->max_qual.noise = 0x100 - 200; + + range->sensitivity = 65535; - net_os_wake_lock(dev); +#if WIRELESS_EXT > 11 + + range->avg_qual.qual = 3; + + range->avg_qual.level = 0x100 + WL_IW_RSSI_GOOD; + + range->avg_qual.noise = 0x100 - 75; +#endif - if (g_onoff == G_WLAN_SET_ON) { + + if ((error = dev_wlc_ioctl(dev, WLC_GET_CURR_RATESET, &rateset, sizeof(rateset)))) + return error; + rateset.count = dtoh32(rateset.count); + range->num_bitrates = rateset.count; + for (i = 0; i < rateset.count && i < IW_MAX_BITRATES; i++) + range->bitrate[i] = (rateset.rates[i] & 0x7f) * 500000; + dev_wlc_intvar_get(dev, "nmode", &nmode); + if ((error = dev_wlc_ioctl(dev, WLC_GET_PHYTYPE, &phytype, sizeof(phytype)))) + return error; - band = htod32((uint)*(extra + strlen(BAND_SET_CMD) + 1) - '0'); + if (nmode == 1 && ((phytype == WLC_PHY_TYPE_SSN) || (phytype == WLC_PHY_TYPE_LCN) || + (phytype == WLC_PHY_TYPE_LCN40))) { + dev_wlc_intvar_get(dev, "mimo_bw_cap", &bw_cap); + dev_wlc_intvar_get(dev, "sgi_tx", &sgi_tx); + dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(channel_info_t)); + ci.hw_channel = dtoh32(ci.hw_channel); - if ((band == WLC_BAND_AUTO) || (band == WLC_BAND_5G) || (band == WLC_BAND_2G)) { + if (bw_cap == 0 || + (bw_cap == 2 && ci.hw_channel <= 14)) { + if (sgi_tx == 0) + nrate_list2copy = 0; + else + nrate_list2copy = 1; + } + if (bw_cap == 1 || + (bw_cap == 2 && ci.hw_channel >= 36)) { + if (sgi_tx == 0) + nrate_list2copy = 2; + else + nrate_list2copy = 3; + } + range->num_bitrates += 8; + for (k = 0; i < range->num_bitrates; k++, i++) { - if ((error = dev_wlc_ioctl(dev, WLC_SET_BAND, - &band, sizeof(band))) >= 0) { - p += snprintf(p, MAX_WX_STRING, "OK"); - WL_TRACE(("%s: set band %d OK\n", __FUNCTION__, band)); - goto exit; - } else { - WL_ERROR(("%s: set band %d failed code %d\n", __FUNCTION__, - band, error)); - } - } else { - WL_ERROR(("%s Incorrect band setting %d, ignored\n", __FUNCTION__, band)); + range->bitrate[i] = (nrate_list[nrate_list2copy][k]) * 500000; } } - p += snprintf(p, MAX_WX_STRING, "FAIL"); + + if ((error = dev_wlc_ioctl(dev, WLC_GET_PHYTYPE, &i, sizeof(i)))) + return error; + i = dtoh32(i); + if (i == WLC_PHY_TYPE_A) + range->throughput = 24000000; + else + range->throughput = 1500000; -exit: - wrqu->data.length = p - extra + 1; - net_os_wake_unlock(dev); - return error; -} + + range->min_rts = 0; + range->max_rts = 2347; + range->min_frag = 256; + range->max_frag = 2346; -#ifdef PNO_SUPPORT + range->max_encoding_tokens = DOT11_MAX_DEFAULT_KEYS; + range->num_encoding_sizes = 4; + range->encoding_size[0] = WEP1_KEY_SIZE; + range->encoding_size[1] = WEP128_KEY_SIZE; +#if WIRELESS_EXT > 17 + range->encoding_size[2] = TKIP_KEY_SIZE; +#else + range->encoding_size[2] = 0; +#endif + range->encoding_size[3] = AES_KEY_SIZE; -static int -wl_iw_set_pno_reset( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error = -1; - char *p = extra; + + range->min_pmp = 0; + range->max_pmp = 0; + range->min_pmt = 0; + range->max_pmt = 0; + range->pmp_flags = 0; + range->pm_capa = 0; - net_os_wake_lock(dev); - if ((g_onoff == G_WLAN_SET_ON) && (dev != NULL)) { + + range->num_txpower = 2; + range->txpower[0] = 1; + range->txpower[1] = 255; + range->txpower_capa = IW_TXPOW_MWATT; - if ((error = dhd_dev_pno_reset(dev)) >= 0) { - p += snprintf(p, MAX_WX_STRING, "OK"); - WL_TRACE(("%s: set OK\n", __FUNCTION__)); - goto exit; - } - else WL_ERROR(("%s: failed code %d\n", __FUNCTION__, error)); - } +#if WIRELESS_EXT > 10 + range->we_version_compiled = WIRELESS_EXT; + range->we_version_source = 19; - p += snprintf(p, MAX_WX_STRING, "FAIL"); + + range->retry_capa = IW_RETRY_LIMIT; + range->retry_flags = IW_RETRY_LIMIT; + range->r_time_flags = 0; + + range->min_retry = 1; + range->max_retry = 255; + + range->min_r_time = 0; + range->max_r_time = 0; +#endif -exit: - wrqu->data.length = p - extra + 1; - net_os_wake_unlock(dev); - return error; -} +#if WIRELESS_EXT > 17 + range->enc_capa = IW_ENC_CAPA_WPA; + range->enc_capa |= IW_ENC_CAPA_CIPHER_TKIP; + range->enc_capa |= IW_ENC_CAPA_CIPHER_CCMP; + range->enc_capa |= IW_ENC_CAPA_WPA2; +#if (defined(BCMSUP_PSK) && defined(WLFBT)) + + range->enc_capa |= IW_ENC_CAPA_4WAY_HANDSHAKE; +#endif + + + IW_EVENT_CAPA_SET_KERNEL(range->event_capa); + + IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP); + IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN); + IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP); + IW_EVENT_CAPA_SET(range->event_capa, IWEVMICHAELMICFAILURE); + IW_EVENT_CAPA_SET(range->event_capa, IWEVASSOCREQIE); + IW_EVENT_CAPA_SET(range->event_capa, IWEVASSOCRESPIE); + IW_EVENT_CAPA_SET(range->event_capa, IWEVPMKIDCAND); + +#if WIRELESS_EXT >= 22 && defined(IW_SCAN_CAPA_ESSID) + + range->scan_capa = IW_SCAN_CAPA_ESSID; +#endif +#endif + return 0; +} +static int +rssi_to_qual(int rssi) +{ + if (rssi <= WL_IW_RSSI_NO_SIGNAL) + return 0; + else if (rssi <= WL_IW_RSSI_VERY_LOW) + return 1; + else if (rssi <= WL_IW_RSSI_LOW) + return 2; + else if (rssi <= WL_IW_RSSI_GOOD) + return 3; + else if (rssi <= WL_IW_RSSI_VERY_GOOD) + return 4; + else + return 5; +} static int -wl_iw_set_pno_enable( +wl_iw_set_spy( struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, + struct iw_point *dwrq, char *extra ) { - int error = -1; - char *p = extra; - int pfn_enabled; - - net_os_wake_lock(dev); - pfn_enabled = htod32((uint)*(extra + strlen(PNOENABLE_SET_CMD) + 1) - '0'); + wl_iw_t *iw = IW_DEV_IF(dev); + struct sockaddr *addr = (struct sockaddr *) extra; + int i; - if ((g_onoff == G_WLAN_SET_ON) && (dev != NULL)) { + WL_TRACE(("%s: SIOCSIWSPY\n", dev->name)); - if ((error = dhd_dev_pno_enable(dev, pfn_enabled)) >= 0) { - p += snprintf(p, MAX_WX_STRING, "OK"); - WL_TRACE(("%s: set OK\n", __FUNCTION__)); - goto exit; - } - else WL_ERROR(("%s: failed code %d\n", __FUNCTION__, error)); - } + if (!extra) + return -EINVAL; - p += snprintf(p, MAX_WX_STRING, "FAIL"); + iw->spy_num = MIN(ARRAYSIZE(iw->spy_addr), dwrq->length); + for (i = 0; i < iw->spy_num; i++) + memcpy(&iw->spy_addr[i], addr[i].sa_data, ETHER_ADDR_LEN); + memset(iw->spy_qual, 0, sizeof(iw->spy_qual)); -exit: - wrqu->data.length = p - extra + 1; - net_os_wake_unlock(dev); - return error; + return 0; } - - static int -wl_iw_set_pno_set( +wl_iw_get_spy( struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, + struct iw_point *dwrq, char *extra ) { - int res = -1; - wlc_ssid_t ssids_local[MAX_PFN_LIST_COUNT]; - int nssid = 0; - cmd_tlv_t *cmd_tlv_temp; - char *str_ptr; - int tlv_size_left; - int pno_time; - int pno_repeat; - int pno_freq_expo_max; -#ifdef PNO_SET_DEBUG + wl_iw_t *iw = IW_DEV_IF(dev); + struct sockaddr *addr = (struct sockaddr *) extra; + struct iw_quality *qual = (struct iw_quality *) &addr[iw->spy_num]; int i; - char pno_in_example[] = { - 'P', 'N', 'O', 'S', 'E', 'T', 'U', 'P', ' ', - 'S', '1', '2', '0', - 'S', - 0x04, - 'B', 'R', 'C', 'M', - 'S', - 0x04, - 'G', 'O', 'O', 'G', - 'T', - '1', 'E', - 'R', - '2', - 'M', - '2', - 0x00 - }; -#endif - - net_os_wake_lock(dev); - WL_ERROR(("\n### %s: info->cmd:%x, info->flags:%x, u.data=0x%p, u.len=%d\n", - __FUNCTION__, info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length)); - - if (g_onoff == G_WLAN_SET_OFF) { - WL_TRACE(("%s: driver is not up yet after START\n", __FUNCTION__)); - goto exit_proc; - } - if (wrqu->data.length < (strlen(PNOSETUP_SET_CMD) + sizeof(cmd_tlv_t))) { - WL_ERROR(("%s argument=%d less %d\n", __FUNCTION__, - wrqu->data.length, (int)(strlen(PNOSETUP_SET_CMD) + sizeof(cmd_tlv_t)))); - goto exit_proc; - } - -#ifdef PNO_SET_DEBUG - if (!(extra = kmalloc(sizeof(pno_in_example) +100, GFP_KERNEL))) { - res = -ENOMEM; - goto exit_proc; - } - memcpy(extra, pno_in_example, sizeof(pno_in_example)); - wrqu->data.length = sizeof(pno_in_example); - for (i = 0; i < wrqu->data.length; i++) - printf("%02X ", extra[i]); - printf("\n"); -#endif - - str_ptr = extra; -#ifdef PNO_SET_DEBUG - str_ptr += strlen("PNOSETUP "); - tlv_size_left = wrqu->data.length - strlen("PNOSETUP "); -#else - str_ptr += strlen(PNOSETUP_SET_CMD); - tlv_size_left = wrqu->data.length - strlen(PNOSETUP_SET_CMD); -#endif - - cmd_tlv_temp = (cmd_tlv_t *)str_ptr; - memset(ssids_local, 0, sizeof(ssids_local)); - pno_repeat = pno_freq_expo_max = 0; - - if ((cmd_tlv_temp->prefix == PNO_TLV_PREFIX) && - (cmd_tlv_temp->version == PNO_TLV_VERSION) && - (cmd_tlv_temp->subver == PNO_TLV_SUBVERSION)) - { - str_ptr += sizeof(cmd_tlv_t); - tlv_size_left -= sizeof(cmd_tlv_t); + WL_TRACE(("%s: SIOCGIWSPY\n", dev->name)); - - if ((nssid = wl_iw_parse_ssid_list_tlv(&str_ptr, ssids_local, - MAX_PFN_LIST_COUNT, - &tlv_size_left)) <= 0) { - WL_ERROR(("SSID is not presented or corrupted ret=%d\n", nssid)); - goto exit_proc; - } - else { - if ((str_ptr[0] != PNO_TLV_TYPE_TIME) || (tlv_size_left <= 1)) { - WL_ERROR(("%s scan duration corrupted field size %d\n", - __FUNCTION__, tlv_size_left)); - goto exit_proc; - } - str_ptr++; - pno_time = simple_strtoul(str_ptr, &str_ptr, 16); - WL_PNO(("%s: pno_time=%d\n", __FUNCTION__, pno_time)); + if (!extra) + return -EINVAL; - - if (str_ptr[0] != 0) { - if ((str_ptr[0] != PNO_TLV_FREQ_REPEAT)) { - WL_ERROR(("%s pno repeat : corrupted field\n", - __FUNCTION__)); - goto exit_proc; - } - str_ptr++; - pno_repeat = simple_strtoul(str_ptr, &str_ptr, 16); - WL_PNO(("%s :got pno_repeat=%d\n", __FUNCTION__, pno_repeat)); - if (str_ptr[0] != PNO_TLV_FREQ_EXPO_MAX) { - WL_ERROR(("%s FREQ_EXPO_MAX corrupted field size\n", - __FUNCTION__)); - goto exit_proc; - } - str_ptr++; - pno_freq_expo_max = simple_strtoul(str_ptr, &str_ptr, 16); - WL_PNO(("%s: pno_freq_expo_max=%d\n", - __FUNCTION__, pno_freq_expo_max)); - } - } - } - else { - WL_ERROR(("%s get wrong TLV command\n", __FUNCTION__)); - goto exit_proc; + dwrq->length = iw->spy_num; + for (i = 0; i < iw->spy_num; i++) { + memcpy(addr[i].sa_data, &iw->spy_addr[i], ETHER_ADDR_LEN); + addr[i].sa_family = AF_UNIX; + memcpy(&qual[i], &iw->spy_qual[i], sizeof(struct iw_quality)); + iw->spy_qual[i].updated = 0; } - - res = dhd_dev_pno_set(dev, ssids_local, nssid, pno_time, pno_repeat, pno_freq_expo_max); - -exit_proc: - net_os_wake_unlock(dev); - return res; + return 0; } static int -wl_iw_set_pno_setadd( +wl_iw_set_wap( struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, + struct sockaddr *awrq, char *extra ) { - int ret = -1; - char *tmp_ptr; - int size, tmp_size; - - net_os_wake_lock(dev); - WL_ERROR(("\n### %s: info->cmd:%x, info->flags:%x, u.data=0x%p, u.len=%d\n", - __FUNCTION__, info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length)); - - if (g_onoff == G_WLAN_SET_OFF) { - WL_TRACE(("%s: driver is not up yet after START\n", __FUNCTION__)); - goto exit_proc; - } + int error = -EINVAL; - if (wrqu->data.length <= strlen(PNOSETADD_SET_CMD) + sizeof(cmd_tlv_t)) { - WL_ERROR(("%s argument=%d less than %d\n", __FUNCTION__, - wrqu->data.length, (int)(strlen(PNOSETADD_SET_CMD) + sizeof(cmd_tlv_t)))); - goto exit_proc; - } + WL_TRACE(("%s: SIOCSIWAP\n", dev->name)); - - bcopy(PNOSETUP_SET_CMD, extra, strlen(PNOSETUP_SET_CMD)); + if (awrq->sa_family != ARPHRD_ETHER) { + WL_ERROR(("%s: Invalid Header...sa_family\n", __FUNCTION__)); + return -EINVAL; + } - tmp_ptr = extra + strlen(PNOSETUP_SET_CMD); - size = wrqu->data.length - strlen(PNOSETUP_SET_CMD); - tmp_size = size; - while (*tmp_ptr && tmp_size > 0) { - if ((*tmp_ptr == 'S') && (size - tmp_size) >= sizeof(cmd_tlv_t)) { - *(tmp_ptr + 1) = ((*(tmp_ptr + 1) - '0') << 4) + (*(tmp_ptr + 2) - '0'); - memmove(tmp_ptr + 2, tmp_ptr + 3, tmp_size - 3); - tmp_size -= 2 + *(tmp_ptr + 1); - tmp_ptr += 2 + *(tmp_ptr + 1); - size--; - } else { - tmp_ptr++; - tmp_size--; + if (ETHER_ISBCAST(awrq->sa_data) || ETHER_ISNULLADDR(awrq->sa_data)) { + scb_val_t scbval; + bzero(&scbval, sizeof(scb_val_t)); + if ((error = dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t)))) { + WL_ERROR(("%s: WLC_DISASSOC failed (%d).\n", __FUNCTION__, error)); } + return 0; + } + + + if ((error = dev_wlc_ioctl(dev, WLC_REASSOC, awrq->sa_data, ETHER_ADDR_LEN))) { + WL_ERROR(("%s: WLC_REASSOC failed (%d).\n", __FUNCTION__, error)); + return error; } - wrqu->data.length = strlen(PNOSETUP_SET_CMD) + size; - ret = wl_iw_set_pno_set(dev, info, wrqu, extra); - -exit_proc: - net_os_wake_unlock(dev); - return ret; - + return 0; } -#endif static int -wl_iw_get_rssi( +wl_iw_get_wap( struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, + struct sockaddr *awrq, char *extra ) { - static int rssi = 0; - static wlc_ssid_t ssid = {0}; - int error = 0; - char *p = extra; - static char ssidbuf[SSID_FMT_BUF_LEN]; - scb_val_t scb_val; - - net_os_wake_lock(dev); - - bzero(&scb_val, sizeof(scb_val_t)); - - if (g_onoff == G_WLAN_SET_ON) { - error = dev_wlc_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t)); - if (error) { - WL_ERROR(("%s: Fails %d\n", __FUNCTION__, error)); - net_os_wake_unlock(dev); - return error; - } - rssi = dtoh32(scb_val.val); + WL_TRACE(("%s: SIOCGIWAP\n", dev->name)); - error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid)); - if (!error) { - ssid.SSID_len = dtoh32(ssid.SSID_len); - wl_format_ssid(ssidbuf, ssid.SSID, dtoh32(ssid.SSID_len)); - } - } + awrq->sa_family = ARPHRD_ETHER; + memset(awrq->sa_data, 0, ETHER_ADDR_LEN); - p += snprintf(p, MAX_WX_STRING, "%s rssi %d ", ssidbuf, rssi); - wrqu->data.length = p - extra + 1; + + (void) dev_wlc_ioctl(dev, WLC_GET_BSSID, awrq->sa_data, ETHER_ADDR_LEN); - net_os_wake_unlock(dev); - return error; + return 0; } -int -wl_iw_send_priv_event( +#if WIRELESS_EXT > 17 +static int +wl_iw_mlme( struct net_device *dev, - char *flag + struct iw_request_info *info, + struct sockaddr *awrq, + char *extra ) { - union iwreq_data wrqu; - char extra[IW_CUSTOM_MAX + 1]; - int cmd; - - cmd = IWEVCUSTOM; - memset(&wrqu, 0, sizeof(wrqu)); - if (strlen(flag) > sizeof(extra)) - return -1; - - strcpy(extra, flag); - wrqu.data.length = strlen(extra); - wireless_send_event(dev, cmd, &wrqu, extra); - net_os_wake_lock_timeout_enable(dev, DHD_EVENT_TIMEOUT_MS); - WL_TRACE(("Send IWEVCUSTOM Event as %s\n", extra)); - - return 0; -} - - -int -wl_control_wl_start(struct net_device *dev) -{ - wl_iw_t *iw; - int ret = 0; + struct iw_mlme *mlme; + scb_val_t scbval; + int error = -EINVAL; - WL_TRACE(("Enter %s \n", __FUNCTION__)); + WL_TRACE(("%s: SIOCSIWMLME\n", dev->name)); - if (!dev) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - return -1; + mlme = (struct iw_mlme *)extra; + if (mlme == NULL) { + WL_ERROR(("Invalid ioctl data.\n")); + return error; } - iw = *(wl_iw_t **)netdev_priv(dev); + scbval.val = mlme->reason_code; + bcopy(&mlme->addr.sa_data, &scbval.ea, ETHER_ADDR_LEN); - if (!iw) { - WL_ERROR(("%s: wl is null\n", __FUNCTION__)); - return -1; + if (mlme->cmd == IW_MLME_DISASSOC) { + scbval.val = htod32(scbval.val); + error = dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t)); } - - dhd_net_if_lock(dev); - - if (g_onoff == G_WLAN_SET_OFF) { - dhd_customer_gpio_wlan_ctrl(WLAN_RESET_ON); - -#if defined(BCMLXSDMMC) - sdioh_start(NULL, 0); -#endif - - ret = dhd_dev_reset(dev, 0); - -#if defined(BCMLXSDMMC) - sdioh_start(NULL, 1); -#endif - if (!ret) - dhd_dev_init_ioctl(dev); - - g_onoff = G_WLAN_SET_ON; + else if (mlme->cmd == IW_MLME_DEAUTH) { + scbval.val = htod32(scbval.val); + error = dev_wlc_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scbval, + sizeof(scb_val_t)); + } + else { + WL_ERROR(("%s: Invalid ioctl data.\n", __FUNCTION__)); + return error; } - WL_TRACE(("Exited %s\n", __FUNCTION__)); - dhd_net_if_unlock(dev); - return ret; + return error; } - +#endif static int -wl_iw_control_wl_off( +wl_iw_get_aplist( struct net_device *dev, - struct iw_request_info *info + struct iw_request_info *info, + struct iw_point *dwrq, + char *extra ) { - wl_iw_t *iw; - int ret = 0; - - WL_TRACE(("Enter %s\n", __FUNCTION__)); + wl_scan_results_t *list; + struct sockaddr *addr = (struct sockaddr *) extra; + struct iw_quality qual[IW_MAX_AP]; + wl_bss_info_t *bi = NULL; + int error, i; + uint buflen = dwrq->length; - if (!dev) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - return -1; - } + WL_TRACE(("%s: SIOCGIWAPLIST\n", dev->name)); - iw = *(wl_iw_t **)netdev_priv(dev); + if (!extra) + return -EINVAL; - if (!iw) { - WL_ERROR(("%s: wl is null\n", __FUNCTION__)); - return -1; + + list = kmalloc(buflen, GFP_KERNEL); + if (!list) + return -ENOMEM; + memset(list, 0, buflen); + list->buflen = htod32(buflen); + if ((error = dev_wlc_ioctl(dev, WLC_SCAN_RESULTS, list, buflen))) { + WL_ERROR(("%d: Scan results error %d\n", __LINE__, error)); + kfree(list); + return error; } + list->buflen = dtoh32(list->buflen); + list->version = dtoh32(list->version); + list->count = dtoh32(list->count); + ASSERT(list->version == WL_BSS_INFO_VERSION); - dhd_net_if_lock(dev); - -#ifdef SOFTAP - ap_cfg_running = FALSE; -#endif - - if (g_onoff == G_WLAN_SET_ON) { - g_onoff = G_WLAN_SET_OFF; - -#if defined(WL_IW_USE_ISCAN) - g_iscan->iscan_state = ISCAN_STATE_IDLE; -#endif - - ret = dhd_dev_reset(dev, 1); + for (i = 0, dwrq->length = 0; i < list->count && dwrq->length < IW_MAX_AP; i++) { + bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : list->bss_info; + ASSERT(((uintptr)bi + dtoh32(bi->length)) <= ((uintptr)list + + buflen)); -#if defined(WL_IW_USE_ISCAN) -#if !defined(CSCAN) - wl_iw_free_ss_cache(); - wl_iw_run_ss_cache_timer(0); + if (!(dtoh16(bi->capability) & DOT11_CAP_ESS)) + continue; + - g_ss_cache_ctrl.m_link_down = 1; -#endif - memset(g_scan, 0, G_SCAN_RESULTS); - g_scan_specified_ssid = 0; -#if defined(CONFIG_FIRST_SCAN) + memcpy(addr[dwrq->length].sa_data, &bi->BSSID, ETHER_ADDR_LEN); + addr[dwrq->length].sa_family = ARPHRD_ETHER; + qual[dwrq->length].qual = rssi_to_qual(dtoh16(bi->RSSI)); + qual[dwrq->length].level = 0x100 + dtoh16(bi->RSSI); + qual[dwrq->length].noise = 0x100 + bi->phy_noise; + - g_first_broadcast_scan = BROADCAST_SCAN_FIRST_IDLE; - g_first_counter_scans = 0; -#endif +#if WIRELESS_EXT > 18 + qual[dwrq->length].updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; +#else + qual[dwrq->length].updated = 7; #endif -#if defined(BCMLXSDMMC) - sdioh_stop(NULL); -#endif - - dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF); - - wl_iw_send_priv_event(dev, "STOP"); + dwrq->length++; } - dhd_net_if_unlock(dev); + kfree(list); - WL_TRACE(("Exited %s\n", __FUNCTION__)); + if (dwrq->length) { + memcpy(&addr[dwrq->length], qual, sizeof(struct iw_quality) * dwrq->length); + + dwrq->flags = 1; + } - return ret; + return 0; } static int -wl_iw_control_wl_on( +wl_iw_iscan_get_aplist( struct net_device *dev, - struct iw_request_info *info + struct iw_request_info *info, + struct iw_point *dwrq, + char *extra ) { - int ret = 0; + wl_scan_results_t *list; + iscan_buf_t * buf; + iscan_info_t *iscan = g_iscan; - WL_TRACE(("Enter %s \n", __FUNCTION__)); + struct sockaddr *addr = (struct sockaddr *) extra; + struct iw_quality qual[IW_MAX_AP]; + wl_bss_info_t *bi = NULL; + int i; - ret = wl_control_wl_start(dev); + WL_TRACE(("%s: SIOCGIWAPLIST\n", dev->name)); - wl_iw_send_priv_event(dev, "START"); + if (!extra) + return -EINVAL; -#ifdef SOFTAP - if (!ap_fw_loaded) { - wl_iw_iscan_set_scan_broadcast_prep(dev, 0); + if ((!iscan) || (iscan->sysioc_pid < 0)) { + return wl_iw_get_aplist(dev, info, dwrq, extra); } -#else - wl_iw_iscan_set_scan_broadcast_prep(dev, 0); -#endif - WL_TRACE(("Exited %s\n", __FUNCTION__)); - - return ret; -} + buf = iscan->list_hdr; + + while (buf) { + list = &((wl_iscan_results_t*)buf->iscan_buf)->results; + ASSERT(list->version == WL_BSS_INFO_VERSION); -#ifdef SOFTAP -static struct ap_profile my_ap; -static int set_ap_cfg(struct net_device *dev, struct ap_profile *ap); -static int get_assoc_sta_list(struct net_device *dev, char *buf, int len); -static int set_ap_mac_list(struct net_device *dev, void *buf); + bi = NULL; + for (i = 0, dwrq->length = 0; i < list->count && dwrq->length < IW_MAX_AP; i++) { + bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : list->bss_info; + ASSERT(((uintptr)bi + dtoh32(bi->length)) <= ((uintptr)list + + WLC_IW_ISCAN_MAXLEN)); -#define PTYPE_STRING 0 -#define PTYPE_INTDEC 1 -#define PTYPE_INTHEX 2 -#define PTYPE_STR_HEX 3 + + if (!(dtoh16(bi->capability) & DOT11_CAP_ESS)) + continue; -static int get_parameter_from_string( - char **str_ptr, const char *token, int param_type, void *dst, int param_max_len); + + memcpy(addr[dwrq->length].sa_data, &bi->BSSID, ETHER_ADDR_LEN); + addr[dwrq->length].sa_family = ARPHRD_ETHER; + qual[dwrq->length].qual = rssi_to_qual(dtoh16(bi->RSSI)); + qual[dwrq->length].level = 0x100 + dtoh16(bi->RSSI); + qual[dwrq->length].noise = 0x100 + bi->phy_noise; -static int -hex2num(char c) -{ - if (c >= '0' && c <= '9') - return c - '0'; - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - if (c >= 'A' && c <= 'F') - return c - 'A' + 10; - return -1; -} + +#if WIRELESS_EXT > 18 + qual[dwrq->length].updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; +#else + qual[dwrq->length].updated = 7; +#endif + dwrq->length++; + } + buf = buf->next; + } + if (dwrq->length) { + memcpy(&addr[dwrq->length], qual, sizeof(struct iw_quality) * dwrq->length); + + dwrq->flags = 1; + } + return 0; +} +#if WIRELESS_EXT > 13 static int -hstr_2_buf(const char *txt, u8 *buf, int len) +wl_iw_set_scan( + struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra +) { - int i; + wlc_ssid_t ssid; - for (i = 0; i < len; i++) { - int a, b; - - a = hex2num(*txt++); - if (a < 0) - return -1; - b = hex2num(*txt++); - if (b < 0) - return -1; - *buf++ = (a << 4) | b; + WL_TRACE(("%s: SIOCSIWSCAN\n", dev->name)); + + + memset(&ssid, 0, sizeof(ssid)); + +#if WIRELESS_EXT > 17 + + if (wrqu->data.length == sizeof(struct iw_scan_req)) { + if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { + struct iw_scan_req *req = (struct iw_scan_req *)extra; + ssid.SSID_len = MIN(sizeof(ssid.SSID), req->essid_len); + memcpy(ssid.SSID, req->essid, ssid.SSID_len); + ssid.SSID_len = htod32(ssid.SSID_len); + } } +#endif + + (void) dev_wlc_ioctl(dev, WLC_SCAN, &ssid, sizeof(ssid)); return 0; } - - static int -init_ap_profile_from_string(char *param_str, struct ap_profile *ap_cfg) +wl_iw_iscan_set_scan( + struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra +) { - char *str_ptr = param_str; - char sub_cmd[16]; - int ret = 0; + wlc_ssid_t ssid; + iscan_info_t *iscan = g_iscan; - memset(sub_cmd, 0, sizeof(sub_cmd)); - memset(ap_cfg, 0, sizeof(struct ap_profile)); + WL_TRACE(("%s: SIOCSIWSCAN\n", dev->name)); - if (get_parameter_from_string(&str_ptr, "ASCII_CMD=", - PTYPE_STRING, sub_cmd, SSID_LEN) != 0) { - return -1; + if ((!iscan) || (iscan->sysioc_pid < 0)) { + return wl_iw_set_scan(dev, info, wrqu, extra); } - if (strncmp(sub_cmd, "AP_CFG", 6)) { - WL_ERROR(("ERROR: sub_cmd:%s != 'AP_CFG'!\n", sub_cmd)); - return -1; + if (iscan->iscan_state == ISCAN_STATE_SCANING) { + return 0; } + memset(&ssid, 0, sizeof(ssid)); + +#if WIRELESS_EXT > 17 - ret = get_parameter_from_string(&str_ptr, "SSID=", PTYPE_STRING, ap_cfg->ssid, SSID_LEN); + if (wrqu->data.length == sizeof(struct iw_scan_req)) { + if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { + struct iw_scan_req *req = (struct iw_scan_req *)extra; + ssid.SSID_len = MIN(sizeof(ssid.SSID), req->essid_len); + memcpy(ssid.SSID, req->essid, ssid.SSID_len); + ssid.SSID_len = htod32(ssid.SSID_len); + } + } +#endif - ret |= get_parameter_from_string(&str_ptr, "SEC=", PTYPE_STRING, ap_cfg->sec, SEC_LEN); + iscan->list_cur = iscan->list_hdr; + iscan->iscan_state = ISCAN_STATE_SCANING; - ret |= get_parameter_from_string(&str_ptr, "KEY=", PTYPE_STRING, ap_cfg->key, KEY_LEN); - ret |= get_parameter_from_string(&str_ptr, "CHANNEL=", PTYPE_INTDEC, &ap_cfg->channel, 5); + wl_iw_set_event_mask(dev); + wl_iw_iscan(iscan, &ssid, WL_SCAN_ACTION_START); - - get_parameter_from_string(&str_ptr, "PREAMBLE=", PTYPE_INTDEC, &ap_cfg->preamble, 5); + iscan->timer.expires = jiffies + iscan->timer_ms*HZ/1000; + add_timer(&iscan->timer); + iscan->timer_on = 1; - - get_parameter_from_string(&str_ptr, "MAX_SCB=", PTYPE_INTDEC, &ap_cfg->max_scb, 5); + return 0; +} - - get_parameter_from_string(&str_ptr, "HIDDEN=", - PTYPE_INTDEC, &ap_cfg->closednet, 5); - - - get_parameter_from_string(&str_ptr, "COUNTRY=", - PTYPE_STRING, &ap_cfg->country_code, 3); - - return ret; -} -#endif - - - -#ifdef SOFTAP -static int -iwpriv_set_ap_config(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *ext) +#if WIRELESS_EXT > 17 +static bool +ie_is_wpa_ie(uint8 **wpaie, uint8 **tlvs, int *tlvs_len) { - int res = 0; - char *extra = NULL; - struct ap_profile *ap_cfg = &my_ap; - WL_TRACE(("> Got IWPRIV SET_AP IOCTL: info->cmd:%x, info->flags:%x, u.data:%p, u.len:%d\n", - info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length)); - - if (!ap_fw_loaded) { - WL_ERROR(("Can't execute %s(), SOFTAP fw is not Loaded\n", - __FUNCTION__)); - return -1; - } - if (wrqu->data.length != 0) { + uint8 *ie = *wpaie; - char *str_ptr; + + if ((ie[1] >= 6) && + !bcmp((const void *)&ie[2], (const void *)(WPA_OUI "\x01"), 4)) { + return TRUE; + } - if (!(extra = kmalloc(wrqu->data.length+1, GFP_KERNEL))) - return -ENOMEM; + + ie += ie[1] + 2; + + *tlvs_len -= (int)(ie - *tlvs); + + *tlvs = ie; + return FALSE; +} - if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) { - kfree(extra); - return -EFAULT; - } +static bool +ie_is_wps_ie(uint8 **wpsie, uint8 **tlvs, int *tlvs_len) +{ - extra[wrqu->data.length] = 0; - WL_SOFTAP((" Got str param in iw_point:\n %s\n", extra)); - memset(ap_cfg, 0, sizeof(struct ap_profile)); + uint8 *ie = *wpsie; - + + if ((ie[1] >= 4) && + !bcmp((const void *)&ie[2], (const void *)(WPA_OUI "\x04"), 4)) { + return TRUE; + } - str_ptr = extra; + + ie += ie[1] + 2; + + *tlvs_len -= (int)(ie - *tlvs); + + *tlvs = ie; + return FALSE; +} +#endif - if ((res = init_ap_profile_from_string(extra, ap_cfg)) < 0) { - WL_ERROR(("%s failed to parse %d\n", __FUNCTION__, res)); - kfree(extra); - return -1; +#ifdef BCMWAPI_WPI +static inline int _wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, + size_t len, int uppercase) +{ + size_t i; + char *pos = buf, *end = buf + buf_size; + int ret; + if (buf_size == 0) + return 0; + for (i = 0; i < len; i++) { + ret = snprintf(pos, end - pos, uppercase ? "%02X" : "%02x", + data[i]); + if (ret < 0 || ret >= end - pos) { + end[-1] = '\0'; + return pos - buf; } - - } else { - - WL_ERROR(("IWPRIV argument len = 0 \n")); - return -1; + pos += ret; } + end[-1] = '\0'; + return pos - buf; +} - if ((res = set_ap_cfg(dev, ap_cfg)) < 0) - WL_ERROR(("%s failed to set_ap_cfg %d\n", __FUNCTION__, res)); - - kfree(extra); - return res; +static int +wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len) +{ + return _wpa_snprintf_hex(buf, buf_size, data, len, 0); } #endif - - -#ifdef SOFTAP -static int iwpriv_get_assoc_list(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *p_iwrq, - char *extra) +static int +wl_iw_handle_scanresults_ies(char **event_p, char *end, + struct iw_request_info *info, wl_bss_info_t *bi) { - int i, ret = 0; - char mac_buf[256]; - struct maclist *sta_maclist = (struct maclist *)mac_buf; - - char mac_lst[384]; - char *p_mac_str; - char *p_mac_str_end; - wl_iw_t *iw; +#if WIRELESS_EXT > 17 + struct iw_event iwe; + char *event; +#ifdef BCMWAPI_WPI + char *buf; + int custom_event_len; +#endif - if ((!dev) || (!extra)) { + event = *event_p; + if (bi->ie_length) { - return -EINVAL; - } - - - iw = *(wl_iw_t **)netdev_priv(dev); - - net_os_wake_lock(dev); - DHD_OS_MUTEX_LOCK(&wl_softap_lock); - - WL_TRACE(("\n %s: IWPRIV IOCTL: cmd:%hx, flags:%hx, extra:%p, iwp.len:%d," - "iwp.len:%p, iwp.flags:%x \n", __FUNCTION__, info->cmd, info->flags, - extra, p_iwrq->data.length, p_iwrq->data.pointer, p_iwrq->data.flags)); - - - memset(sta_maclist, 0, sizeof(mac_buf)); - - sta_maclist->count = 8; - - WL_SOFTAP(("%s: net device:%s, buf_sz:%d\n", - __FUNCTION__, dev->name, sizeof(mac_buf))); - - if ((ret = get_assoc_sta_list(dev, mac_buf, sizeof(mac_buf))) < 0) { - WL_ERROR(("%s: sta list ioctl error:%d\n", - __FUNCTION__, ret)); - goto func_exit; - } - - WL_SOFTAP(("%s: got %d stations\n", __FUNCTION__, - sta_maclist->count)); - + bcm_tlv_t *ie; + uint8 *ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t); + int ptr_len = bi->ie_length; - - memset(mac_lst, 0, sizeof(mac_lst)); - p_mac_str = mac_lst; - p_mac_str_end = &mac_lst[sizeof(mac_lst)-1]; + if ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_RSN_ID))) { + iwe.cmd = IWEVGENIE; + iwe.u.data.length = ie->len + 2; + event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)ie); + } + ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t); - for (i = 0; i < 8; i++) { - struct ether_addr * id = &sta_maclist->ea[i]; - if (!ETHER_ISNULLADDR(id->octet)) { - scb_val_t scb_val; - int rssi = 0; - bzero(&scb_val, sizeof(scb_val_t)); +#if defined(WLFBT) + if ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_MDIE_ID))) { + iwe.cmd = IWEVGENIE; + iwe.u.data.length = ie->len + 2; + event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)ie); + } + ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t); +#endif + while ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_WPA_ID))) { - if ((p_mac_str_end - p_mac_str) <= 36) { - WL_ERROR(("%s: mac list buf is < 36 for item[%i] item\n", - __FUNCTION__, i)); + if (ie_is_wps_ie(((uint8 **)&ie), &ptr, &ptr_len)) { + iwe.cmd = IWEVGENIE; + iwe.u.data.length = ie->len + 2; + event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)ie); break; } + } - p_mac_str += snprintf(p_mac_str, MAX_WX_STRING, - "\nMac[%d]=%02X:%02X:%02X:%02X:%02X:%02X,", i, - id->octet[0], id->octet[1], id->octet[2], - id->octet[3], id->octet[4], id->octet[5]); - - - bcopy(id->octet, &scb_val.ea, 6); - ret = dev_wlc_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t)); - if (ret < 0) { - snprintf(p_mac_str, MAX_WX_STRING, "RSSI:ERR"); - WL_ERROR(("%s: RSSI ioctl error:%d\n", - __FUNCTION__, ret)); + ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t); + ptr_len = bi->ie_length; + while ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_WPA_ID))) { + if (ie_is_wpa_ie(((uint8 **)&ie), &ptr, &ptr_len)) { + iwe.cmd = IWEVGENIE; + iwe.u.data.length = ie->len + 2; + event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)ie); break; } - - rssi = dtoh32(scb_val.val); - p_mac_str += snprintf(p_mac_str, MAX_WX_STRING, - "RSSI:%d", rssi); } - } - - p_iwrq->data.length = strlen(mac_lst)+1; - WL_SOFTAP(("%s: data to user:\n%s\n usr_ptr:%p\n", __FUNCTION__, - mac_lst, p_iwrq->data.pointer)); - - if (p_iwrq->data.length) { - bcopy(mac_lst, extra, p_iwrq->data.length); - } +#ifdef BCMWAPI_WPI + ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t); + ptr_len = bi->ie_length; -func_exit: + while ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_WAPI_ID))) { + WL_TRACE(("%s: found a WAPI IE...\n", __FUNCTION__)); +#ifdef WAPI_IE_USE_GENIE + iwe.cmd = IWEVGENIE; + iwe.u.data.length = ie->len + 2; + event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)ie); +#else + iwe.cmd = IWEVCUSTOM; + custom_event_len = strlen("wapi_ie=") + 2*(ie->len + 2); + iwe.u.data.length = custom_event_len; - DHD_OS_MUTEX_UNLOCK(&wl_softap_lock); - net_os_wake_unlock(dev); + buf = kmalloc(custom_event_len+1, GFP_KERNEL); + if (buf == NULL) + { + WL_ERROR(("malloc(%d) returned NULL...\n", custom_event_len)); + break; + } - WL_SOFTAP(("%s: Exited\n", __FUNCTION__)); - return ret; -} + memcpy(buf, "wapi_ie=", 8); + wpa_snprintf_hex(buf + 8, 2+1, &(ie->id), 1); + wpa_snprintf_hex(buf + 10, 2+1, &(ie->len), 1); + wpa_snprintf_hex(buf + 12, 2*ie->len+1, ie->data, ie->len); + event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, buf); #endif + break; + } +#endif + *event_p = event; + } - -#ifdef SOFTAP - -#define MAC_FILT_MAX 8 -static int iwpriv_set_mac_filters(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *ext) +#endif + return 0; +} +static int +wl_iw_get_scan( + struct net_device *dev, + struct iw_request_info *info, + struct iw_point *dwrq, + char *extra +) { - int i, ret = -1; - char * extra = NULL; - int mac_cnt = 0; - int mac_mode = 0; - struct ether_addr *p_ea; - struct mac_list_set mflist_set; - - WL_SOFTAP((">>> Got IWPRIV SET_MAC_FILTER IOCTL: info->cmd:%x," - "info->flags:%x, u.data:%p, u.len:%d\n", - info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length)); + channel_info_t ci; + wl_scan_results_t *list; + struct iw_event iwe; + wl_bss_info_t *bi = NULL; + int error, i, j; + char *event = extra, *end = extra + dwrq->length, *value; + uint buflen = dwrq->length; - if (wrqu->data.length != 0) { + WL_TRACE(("%s: SIOCGIWSCAN\n", dev->name)); - char *str_ptr; + if (!extra) + return -EINVAL; - if (!(extra = kmalloc(wrqu->data.length+1, GFP_KERNEL))) - return -ENOMEM; + + if ((error = dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci)))) + return error; + ci.scan_channel = dtoh32(ci.scan_channel); + if (ci.scan_channel) + return -EAGAIN; - if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) { - kfree(extra); - return -EFAULT; - } + + list = kmalloc(buflen, GFP_KERNEL); + if (!list) + return -ENOMEM; + memset(list, 0, buflen); + list->buflen = htod32(buflen); + if ((error = dev_wlc_ioctl(dev, WLC_SCAN_RESULTS, list, buflen))) { + kfree(list); + return error; + } + list->buflen = dtoh32(list->buflen); + list->version = dtoh32(list->version); + list->count = dtoh32(list->count); - extra[wrqu->data.length] = 0; - WL_SOFTAP((" Got parameter string in iw_point:\n %s \n", extra)); + ASSERT(list->version == WL_BSS_INFO_VERSION); - memset(&mflist_set, 0, sizeof(mflist_set)); + for (i = 0; i < list->count && i < IW_MAX_AP; i++) { + bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : list->bss_info; + ASSERT(((uintptr)bi + dtoh32(bi->length)) <= ((uintptr)list + + buflen)); - str_ptr = extra; - + iwe.cmd = SIOCGIWAP; + iwe.u.ap_addr.sa_family = ARPHRD_ETHER; + memcpy(iwe.u.ap_addr.sa_data, &bi->BSSID, ETHER_ADDR_LEN); + event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_ADDR_LEN); - if (get_parameter_from_string(&str_ptr, "MAC_MODE=", - PTYPE_INTDEC, &mac_mode, 4) != 0) { - WL_ERROR(("ERROR: 'MAC_MODE=' token is missing\n")); - goto exit_proc; - } - - p_ea = &mflist_set.mac_list.ea[0]; - - if (get_parameter_from_string(&str_ptr, "MAC_CNT=", - PTYPE_INTDEC, &mac_cnt, 4) != 0) { - WL_ERROR(("ERROR: 'MAC_CNT=' token param is missing \n")); - goto exit_proc; - } + iwe.u.data.length = dtoh32(bi->SSID_len); + iwe.cmd = SIOCGIWESSID; + iwe.u.data.flags = 1; + event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, bi->SSID); - if (mac_cnt > MAC_FILT_MAX) { - WL_ERROR(("ERROR: number of MAC filters > MAX\n")); - goto exit_proc; + + if (dtoh16(bi->capability) & (DOT11_CAP_ESS | DOT11_CAP_IBSS)) { + iwe.cmd = SIOCGIWMODE; + if (dtoh16(bi->capability) & DOT11_CAP_ESS) + iwe.u.mode = IW_MODE_INFRA; + else + iwe.u.mode = IW_MODE_ADHOC; + event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_UINT_LEN); } - for (i=0; i< mac_cnt; i++) - if (get_parameter_from_string(&str_ptr, "MAC=", - PTYPE_STR_HEX, &p_ea[i], 12) != 0) { - WL_ERROR(("ERROR: MAC_filter[%d] is missing !\n", i)); - goto exit_proc; - } + + iwe.cmd = SIOCGIWFREQ; + iwe.u.freq.m = wf_channel2mhz(CHSPEC_CHANNEL(bi->chanspec), + CHSPEC_CHANNEL(bi->chanspec) <= CH_MAX_2G_CHANNEL ? + WF_CHAN_FACTOR_2_4_G : WF_CHAN_FACTOR_5_G); + iwe.u.freq.e = 6; + event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_FREQ_LEN); - WL_SOFTAP(("MAC_MODE=:%d, MAC_CNT=%d, MACs:..\n", mac_mode, mac_cnt)); - for (i = 0; i < mac_cnt; i++) { - WL_SOFTAP(("mac_filt[%d]:", i)); - dhd_print_buf(&p_ea[i], 6, 0); - } + + iwe.cmd = IWEVQUAL; + iwe.u.qual.qual = rssi_to_qual(dtoh16(bi->RSSI)); + iwe.u.qual.level = 0x100 + dtoh16(bi->RSSI); + iwe.u.qual.noise = 0x100 + bi->phy_noise; + event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_QUAL_LEN); - mflist_set.mode = mac_mode; - mflist_set.mac_list.count = mac_cnt; - set_ap_mac_list(dev, &mflist_set); + wl_iw_handle_scanresults_ies(&event, end, info, bi); - wrqu->data.pointer = NULL; - wrqu->data.length = 0; - ret = 0; + iwe.cmd = SIOCGIWENCODE; + if (dtoh16(bi->capability) & DOT11_CAP_PRIVACY) + iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; + else + iwe.u.data.flags = IW_ENCODE_DISABLED; + iwe.u.data.length = 0; + event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)event); - } else { - - WL_ERROR(("IWPRIV argument len is 0\n")); - return -1; + + if (bi->rateset.count) { + value = event + IW_EV_LCP_LEN; + iwe.cmd = SIOCGIWRATE; + + iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; + for (j = 0; j < bi->rateset.count && j < IW_MAX_BITRATES; j++) { + iwe.u.bitrate.value = (bi->rateset.rates[j] & 0x7f) * 500000; + value = IWE_STREAM_ADD_VALUE(info, event, value, end, &iwe, + IW_EV_PARAM_LEN); + } + event = value; + } } - exit_proc: - kfree(extra); - return ret; -} -#endif - - -#ifdef SOFTAP - -static int iwpriv_set_ap_sta_disassoc(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *ext) -{ - int res = 0; - char sta_mac[6] = {0, 0, 0, 0, 0, 0}; - char cmd_buf[256]; - char *str_ptr = cmd_buf; + kfree(list); - WL_SOFTAP((">>%s called\n args: info->cmd:%x," - " info->flags:%x, u.data.p:%p, u.data.len:%d\n", - __FUNCTION__, info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length)); + dwrq->length = event - extra; + dwrq->flags = 0; - if (wrqu->data.length != 0) { - - if (copy_from_user(cmd_buf, wrqu->data.pointer, wrqu->data.length)) { - return -EFAULT; - } - - if (get_parameter_from_string(&str_ptr, - "MAC=", PTYPE_STR_HEX, sta_mac, 12) == 0) { - res = wl_iw_softap_deassoc_stations(dev, sta_mac); - } else { - WL_ERROR(("ERROR: STA_MAC= token not found\n")); - } - } - - return res; -} -#endif - -#endif - -#if WIRELESS_EXT < 13 -struct iw_request_info -{ - __u16 cmd; - __u16 flags; -}; - -typedef int (*iw_handler)(struct net_device *dev, - struct iw_request_info *info, - void *wrqu, - char *extra); -#endif + return 0; +} static int -wl_iw_config_commit( +wl_iw_iscan_get_scan( struct net_device *dev, struct iw_request_info *info, - void *zwrq, + struct iw_point *dwrq, char *extra ) { - wlc_ssid_t ssid; - int error; - struct sockaddr bssid; - - WL_TRACE(("%s: SIOCSIWCOMMIT\n", dev->name)); - - if ((error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid)))) - return error; + wl_scan_results_t *list; + struct iw_event iwe; + wl_bss_info_t *bi = NULL; + int ii, j; + int apcnt; + char *event = extra, *end = extra + dwrq->length, *value; + iscan_info_t *iscan = g_iscan; + iscan_buf_t * p_buf; - ssid.SSID_len = dtoh32(ssid.SSID_len); + WL_TRACE(("%s: SIOCGIWSCAN\n", dev->name)); - if (!ssid.SSID_len) - return 0; + if (!extra) + return -EINVAL; - bzero(&bssid, sizeof(struct sockaddr)); - if ((error = dev_wlc_ioctl(dev, WLC_REASSOC, &bssid, ETHER_ADDR_LEN))) { - WL_ERROR(("%s: WLC_REASSOC to %s failed \n", __FUNCTION__, ssid.SSID)); - return error; + + if ((!iscan) || (iscan->sysioc_pid < 0)) { + return wl_iw_get_scan(dev, info, dwrq, extra); } - return 0; -} - -static int -wl_iw_get_name( - struct net_device *dev, - struct iw_request_info *info, - char *cwrq, - char *extra -) -{ - WL_TRACE(("%s: SIOCGIWNAME\n", dev->name)); + + if (iscan->iscan_state == ISCAN_STATE_SCANING) + return -EAGAIN; - strcpy(cwrq, "IEEE 802.11-DS"); + apcnt = 0; + p_buf = iscan->list_hdr; + + while (p_buf != iscan->list_cur) { + list = &((wl_iscan_results_t*)p_buf->iscan_buf)->results; - return 0; -} + if (list->version != WL_BSS_INFO_VERSION) { + WL_ERROR(("list->version %d != WL_BSS_INFO_VERSION\n", list->version)); + } -static int -wl_iw_set_freq( - struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *fwrq, - char *extra -) -{ - int error, chan; - uint sf = 0; + bi = NULL; + for (ii = 0; ii < list->count && apcnt < IW_MAX_AP; apcnt++, ii++) { + bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : list->bss_info; + ASSERT(((uintptr)bi + dtoh32(bi->length)) <= ((uintptr)list + + WLC_IW_ISCAN_MAXLEN)); - WL_TRACE(("%s %s: SIOCSIWFREQ\n", __FUNCTION__, dev->name)); + + if (event + ETHER_ADDR_LEN + bi->SSID_len + IW_EV_UINT_LEN + IW_EV_FREQ_LEN + + IW_EV_QUAL_LEN >= end) + return -E2BIG; + + iwe.cmd = SIOCGIWAP; + iwe.u.ap_addr.sa_family = ARPHRD_ETHER; + memcpy(iwe.u.ap_addr.sa_data, &bi->BSSID, ETHER_ADDR_LEN); + event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_ADDR_LEN); -#if defined(SOFTAP) - if (ap_cfg_running) { - WL_TRACE(("%s:>> not executed, 'SOFT_AP is active' \n", __FUNCTION__)); - return 0; - } -#endif + + iwe.u.data.length = dtoh32(bi->SSID_len); + iwe.cmd = SIOCGIWESSID; + iwe.u.data.flags = 1; + event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, bi->SSID); - - if (fwrq->e == 0 && fwrq->m < MAXCHANNEL) { - chan = fwrq->m; - } - - else { - if (fwrq->e >= 6) { - fwrq->e -= 6; - while (fwrq->e--) - fwrq->m *= 10; - } else if (fwrq->e < 6) { - while (fwrq->e++ < 6) - fwrq->m /= 10; + if (dtoh16(bi->capability) & (DOT11_CAP_ESS | DOT11_CAP_IBSS)) { + iwe.cmd = SIOCGIWMODE; + if (dtoh16(bi->capability) & DOT11_CAP_ESS) + iwe.u.mode = IW_MODE_INFRA; + else + iwe.u.mode = IW_MODE_ADHOC; + event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_UINT_LEN); } + - if (fwrq->m > 4000 && fwrq->m < 5000) - sf = WF_CHAN_FACTOR_4_G; + iwe.cmd = SIOCGIWFREQ; + iwe.u.freq.m = wf_channel2mhz(CHSPEC_CHANNEL(bi->chanspec), + CHSPEC_CHANNEL(bi->chanspec) <= CH_MAX_2G_CHANNEL ? + WF_CHAN_FACTOR_2_4_G : WF_CHAN_FACTOR_5_G); + iwe.u.freq.e = 6; + event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_FREQ_LEN); - chan = wf_mhz2channel(fwrq->m, sf); - } + + iwe.cmd = IWEVQUAL; + iwe.u.qual.qual = rssi_to_qual(dtoh16(bi->RSSI)); + iwe.u.qual.level = 0x100 + dtoh16(bi->RSSI); + iwe.u.qual.noise = 0x100 + bi->phy_noise; + event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_QUAL_LEN); - chan = htod32(chan); + + wl_iw_handle_scanresults_ies(&event, end, info, bi); - if ((error = dev_wlc_ioctl(dev, WLC_SET_CHANNEL, &chan, sizeof(chan)))) - return error; + + iwe.cmd = SIOCGIWENCODE; + if (dtoh16(bi->capability) & DOT11_CAP_PRIVACY) + iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; + else + iwe.u.data.flags = IW_ENCODE_DISABLED; + iwe.u.data.length = 0; + event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)event); - g_wl_iw_params.target_channel = chan; + + if (bi->rateset.count) { + if (event + IW_MAX_BITRATES*IW_EV_PARAM_LEN >= end) + return -E2BIG; - - return -EINPROGRESS; + value = event + IW_EV_LCP_LEN; + iwe.cmd = SIOCGIWRATE; + + iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; + for (j = 0; j < bi->rateset.count && j < IW_MAX_BITRATES; j++) { + iwe.u.bitrate.value = (bi->rateset.rates[j] & 0x7f) * 500000; + value = IWE_STREAM_ADD_VALUE(info, event, value, end, &iwe, + IW_EV_PARAM_LEN); + } + event = value; + } + } + p_buf = p_buf->next; + } + + dwrq->length = event - extra; + dwrq->flags = 0; + + return 0; } +#endif + + static int -wl_iw_get_freq( +wl_iw_set_essid( struct net_device *dev, struct iw_request_info *info, - struct iw_freq *fwrq, + struct iw_point *dwrq, char *extra ) { - channel_info_t ci; + wlc_ssid_t ssid; int error; - WL_TRACE(("%s: SIOCGIWFREQ\n", dev->name)); + WL_TRACE(("%s: SIOCSIWESSID\n", dev->name)); - if ((error = dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci)))) - return error; + + memset(&ssid, 0, sizeof(ssid)); + if (dwrq->length && extra) { +#if WIRELESS_EXT > 20 + ssid.SSID_len = MIN(sizeof(ssid.SSID), dwrq->length); +#else + ssid.SSID_len = MIN(sizeof(ssid.SSID), dwrq->length-1); +#endif + memcpy(ssid.SSID, extra, ssid.SSID_len); + ssid.SSID_len = htod32(ssid.SSID_len); + if ((error = dev_wlc_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(ssid)))) + return error; + } - fwrq->m = dtoh32(ci.hw_channel); - fwrq->e = dtoh32(0); + else { + scb_val_t scbval; + bzero(&scbval, sizeof(scb_val_t)); + if ((error = dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t)))) + return error; + } return 0; } static int -wl_iw_set_mode( +wl_iw_get_essid( struct net_device *dev, struct iw_request_info *info, - __u32 *uwrq, + struct iw_point *dwrq, char *extra ) { - int infra = 0, ap = 0, error = 0; + wlc_ssid_t ssid; + int error; - WL_TRACE(("%s: SIOCSIWMODE\n", dev->name)); + WL_TRACE(("%s: SIOCGIWESSID\n", dev->name)); - switch (*uwrq) { - case IW_MODE_MASTER: - infra = ap = 1; - break; - case IW_MODE_ADHOC: - case IW_MODE_AUTO: - break; - case IW_MODE_INFRA: - infra = 1; - break; - default: + if (!extra) return -EINVAL; - } - infra = htod32(infra); - ap = htod32(ap); - if ((error = dev_wlc_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(infra))) || - (error = dev_wlc_ioctl(dev, WLC_SET_AP, &ap, sizeof(ap)))) + if ((error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid)))) { + WL_ERROR(("Error getting the SSID\n")); return error; + } + + ssid.SSID_len = dtoh32(ssid.SSID_len); - return -EINPROGRESS; + memcpy(extra, ssid.SSID, ssid.SSID_len); + + dwrq->length = ssid.SSID_len; + + dwrq->flags = 1; + + return 0; } static int -wl_iw_get_mode( +wl_iw_set_nick( struct net_device *dev, struct iw_request_info *info, - __u32 *uwrq, + struct iw_point *dwrq, char *extra ) { - int error, infra = 0, ap = 0; + wl_iw_t *iw = IW_DEV_IF(dev); + WL_TRACE(("%s: SIOCSIWNICKN\n", dev->name)); - WL_TRACE(("%s: SIOCGIWMODE\n", dev->name)); + if (!extra) + return -EINVAL; - if ((error = dev_wlc_ioctl(dev, WLC_GET_INFRA, &infra, sizeof(infra))) || - (error = dev_wlc_ioctl(dev, WLC_GET_AP, &ap, sizeof(ap)))) - return error; + + if (dwrq->length > sizeof(iw->nickname)) + return -E2BIG; - infra = dtoh32(infra); - ap = dtoh32(ap); - *uwrq = infra ? ap ? IW_MODE_MASTER : IW_MODE_INFRA : IW_MODE_ADHOC; + memcpy(iw->nickname, extra, dwrq->length); + iw->nickname[dwrq->length - 1] = '\0'; return 0; } static int -wl_iw_get_range( +wl_iw_get_nick( struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra ) { - struct iw_range *range = (struct iw_range *) extra; - wl_uint32_list_t *list; - wl_rateset_t rateset; - int8 *channels; - int error, i, k; - uint sf, ch; + wl_iw_t *iw = IW_DEV_IF(dev); + WL_TRACE(("%s: SIOCGIWNICKN\n", dev->name)); - int phytype; - int bw_cap = 0, sgi_tx = 0, nmode = 0; - channel_info_t ci; - uint8 nrate_list2copy = 0; - uint16 nrate_list[4][8] = { {13, 26, 39, 52, 78, 104, 117, 130}, - {14, 29, 43, 58, 87, 116, 130, 144}, - {27, 54, 81, 108, 162, 216, 243, 270}, - {30, 60, 90, 120, 180, 240, 270, 300}}; - - WL_TRACE(("%s: SIOCGIWRANGE\n", dev->name)); - - if (!extra) - return -EINVAL; - - channels = kmalloc((MAXCHANNEL+1)*4, GFP_KERNEL); - if (!channels) { - WL_ERROR(("Could not alloc channels\n")); - return -ENOMEM; - } - list = (wl_uint32_list_t *)channels; - - dwrq->length = sizeof(struct iw_range); - memset(range, 0, sizeof(*range)); - - - range->min_nwid = range->max_nwid = 0; - - - list->count = htod32(MAXCHANNEL); - if ((error = dev_wlc_ioctl(dev, WLC_GET_VALID_CHANNELS, channels, (MAXCHANNEL+1)*4))) { - kfree(channels); - return error; - } - for (i = 0; i < dtoh32(list->count) && i < IW_MAX_FREQUENCIES; i++) { - range->freq[i].i = dtoh32(list->element[i]); - - ch = dtoh32(list->element[i]); - if (ch <= CH_MAX_2G_CHANNEL) - sf = WF_CHAN_FACTOR_2_4_G; - else - sf = WF_CHAN_FACTOR_5_G; - - range->freq[i].m = wf_channel2mhz(ch, sf); - range->freq[i].e = 6; - } - range->num_frequency = range->num_channels = i; - - - range->max_qual.qual = 5; - - range->max_qual.level = 0x100 - 200; - - range->max_qual.noise = 0x100 - 200; - - range->sensitivity = 65535; - -#if WIRELESS_EXT > 11 - - range->avg_qual.qual = 3; - - range->avg_qual.level = 0x100 + WL_IW_RSSI_GOOD; - - range->avg_qual.noise = 0x100 - 75; -#endif - - - if ((error = dev_wlc_ioctl(dev, WLC_GET_CURR_RATESET, &rateset, sizeof(rateset)))) { - kfree(channels); - return error; - } - rateset.count = dtoh32(rateset.count); - range->num_bitrates = rateset.count; - for (i = 0; i < rateset.count && i < IW_MAX_BITRATES; i++) - range->bitrate[i] = (rateset.rates[i]& 0x7f) * 500000; - dev_wlc_intvar_get(dev, "nmode", &nmode); - dev_wlc_ioctl(dev, WLC_GET_PHYTYPE, &phytype, sizeof(phytype)); - - if (nmode == 1 && phytype == WLC_PHY_TYPE_SSN) { - dev_wlc_intvar_get(dev, "mimo_bw_cap", &bw_cap); - dev_wlc_intvar_get(dev, "sgi_tx", &sgi_tx); - dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(channel_info_t)); - ci.hw_channel = dtoh32(ci.hw_channel); - - if (bw_cap == 0 || - (bw_cap == 2 && ci.hw_channel <= 14)) { - if (sgi_tx == 0) - nrate_list2copy = 0; - else - nrate_list2copy = 1; - } - if (bw_cap == 1 || - (bw_cap == 2 && ci.hw_channel >= 36)) { - if (sgi_tx == 0) - nrate_list2copy = 2; - else - nrate_list2copy = 3; - } - range->num_bitrates += 8; - for (k = 0; i < range->num_bitrates; k++, i++) { - - range->bitrate[i] = (nrate_list[nrate_list2copy][k]) * 500000; - } - } - - - if ((error = dev_wlc_ioctl(dev, WLC_GET_PHYTYPE, &i, sizeof(i)))) { - kfree(channels); - return error; - } - i = dtoh32(i); - if (i == WLC_PHY_TYPE_A) - range->throughput = 24000000; - else - range->throughput = 1500000; - - - range->min_rts = 0; - range->max_rts = 2347; - range->min_frag = 256; - range->max_frag = 2346; - - range->max_encoding_tokens = DOT11_MAX_DEFAULT_KEYS; - range->num_encoding_sizes = 4; - range->encoding_size[0] = WEP1_KEY_SIZE; - range->encoding_size[1] = WEP128_KEY_SIZE; -#if WIRELESS_EXT > 17 - range->encoding_size[2] = TKIP_KEY_SIZE; -#else - range->encoding_size[2] = 0; -#endif - range->encoding_size[3] = AES_KEY_SIZE; - - - range->min_pmp = 0; - range->max_pmp = 0; - range->min_pmt = 0; - range->max_pmt = 0; - range->pmp_flags = 0; - range->pm_capa = 0; - - - range->num_txpower = 2; - range->txpower[0] = 1; - range->txpower[1] = 255; - range->txpower_capa = IW_TXPOW_MWATT; - -#if WIRELESS_EXT > 10 - range->we_version_compiled = WIRELESS_EXT; - range->we_version_source = 19; - - - range->retry_capa = IW_RETRY_LIMIT; - range->retry_flags = IW_RETRY_LIMIT; - range->r_time_flags = 0; - - range->min_retry = 1; - range->max_retry = 255; - - range->min_r_time = 0; - range->max_r_time = 0; -#endif - -#if WIRELESS_EXT > 17 - range->enc_capa = IW_ENC_CAPA_WPA; - range->enc_capa |= IW_ENC_CAPA_CIPHER_TKIP; - range->enc_capa |= IW_ENC_CAPA_CIPHER_CCMP; - range->enc_capa |= IW_ENC_CAPA_WPA2; - - - IW_EVENT_CAPA_SET_KERNEL(range->event_capa); - - IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP); - IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN); - IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP); - IW_EVENT_CAPA_SET(range->event_capa, IWEVMICHAELMICFAILURE); - IW_EVENT_CAPA_SET(range->event_capa, IWEVASSOCREQIE); - IW_EVENT_CAPA_SET(range->event_capa, IWEVASSOCRESPIE); - IW_EVENT_CAPA_SET(range->event_capa, IWEVPMKIDCAND); -#endif - - kfree(channels); - - return 0; -} - -static int -rssi_to_qual(int rssi) -{ - if (rssi <= WL_IW_RSSI_NO_SIGNAL) - return 0; - else if (rssi <= WL_IW_RSSI_VERY_LOW) - return 1; - else if (rssi <= WL_IW_RSSI_LOW) - return 2; - else if (rssi <= WL_IW_RSSI_GOOD) - return 3; - else if (rssi <= WL_IW_RSSI_VERY_GOOD) - return 4; - else - return 5; -} - -static int -wl_iw_set_spy( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_iw_t *iw = NETDEV_PRIV(dev); - struct sockaddr *addr = (struct sockaddr *) extra; - int i; - - WL_TRACE(("%s: SIOCSIWSPY\n", dev->name)); - - if (!extra) - return -EINVAL; - - iw->spy_num = MIN(ARRAYSIZE(iw->spy_addr), dwrq->length); - for (i = 0; i < iw->spy_num; i++) - memcpy(&iw->spy_addr[i], addr[i].sa_data, ETHER_ADDR_LEN); - memset(iw->spy_qual, 0, sizeof(iw->spy_qual)); - - return 0; -} - -static int -wl_iw_get_spy( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_iw_t *iw = NETDEV_PRIV(dev); - struct sockaddr *addr = (struct sockaddr *) extra; - struct iw_quality *qual = (struct iw_quality *) &addr[iw->spy_num]; - int i; - - WL_TRACE(("%s: SIOCGIWSPY\n", dev->name)); - - if (!extra) - return -EINVAL; - - dwrq->length = iw->spy_num; - for (i = 0; i < iw->spy_num; i++) { - memcpy(addr[i].sa_data, &iw->spy_addr[i], ETHER_ADDR_LEN); - addr[i].sa_family = AF_UNIX; - memcpy(&qual[i], &iw->spy_qual[i], sizeof(struct iw_quality)); - iw->spy_qual[i].updated = 0; - } - - return 0; -} - - -static int -wl_iw_ch_to_chanspec(int ch, wl_join_params_t *join_params, int *join_params_size) -{ - chanspec_t chanspec = 0; - - if (ch != 0) { - - join_params->params.chanspec_num = 1; - join_params->params.chanspec_list[0] = ch; - - if (join_params->params.chanspec_list[0]) - chanspec |= WL_CHANSPEC_BAND_2G; - else - chanspec |= WL_CHANSPEC_BAND_5G; - - chanspec |= WL_CHANSPEC_BW_20; - chanspec |= WL_CHANSPEC_CTL_SB_NONE; - - - *join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE + - join_params->params.chanspec_num * sizeof(chanspec_t); - - - join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK; - join_params->params.chanspec_list[0] |= chanspec; - join_params->params.chanspec_list[0] = - htodchanspec(join_params->params.chanspec_list[0]); - - join_params->params.chanspec_num = htod32(join_params->params.chanspec_num); - - WL_TRACE(("%s join_params->params.chanspec_list[0]= %X\n", - __FUNCTION__, join_params->params.chanspec_list[0])); - } - return 1; -} - -static int -wl_iw_set_wap( - struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *awrq, - char *extra -) -{ - int error = -EINVAL; - wl_join_params_t join_params; - int join_params_size; - - WL_TRACE(("%s: SIOCSIWAP\n", dev->name)); - - if (awrq->sa_family != ARPHRD_ETHER) { - WL_ERROR(("Invalid Header...sa_family\n")); - return -EINVAL; - } - - - if (ETHER_ISBCAST(awrq->sa_data) || ETHER_ISNULLADDR(awrq->sa_data)) { - scb_val_t scbval; - - bzero(&scbval, sizeof(scb_val_t)); - - (void) dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t)); - return 0; - } - - - - memset(&join_params, 0, sizeof(join_params)); - join_params_size = sizeof(join_params.ssid); - - memcpy(join_params.ssid.SSID, g_ssid.SSID, g_ssid.SSID_len); - join_params.ssid.SSID_len = htod32(g_ssid.SSID_len); - memcpy(&join_params.params.bssid, awrq->sa_data, ETHER_ADDR_LEN); - - - - WL_TRACE(("%s target_channel=%d\n", __FUNCTION__, g_wl_iw_params.target_channel)); - wl_iw_ch_to_chanspec(g_wl_iw_params.target_channel, &join_params, &join_params_size); - - if ((error = dev_wlc_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size))) { - WL_ERROR(("%s Invalid ioctl data=%d\n", __FUNCTION__, error)); - return error; - } - - if (g_ssid.SSID_len) { - WL_TRACE(("%s: join SSID=%s BSSID="MACSTR" ch=%d\n", __FUNCTION__, - g_ssid.SSID, MAC2STR((u8 *)awrq->sa_data), - g_wl_iw_params.target_channel)); - } - - - memset(&g_ssid, 0, sizeof(g_ssid)); - return 0; -} - -static int -wl_iw_get_wap( - struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *awrq, - char *extra -) -{ - WL_TRACE(("%s: SIOCGIWAP\n", dev->name)); - - awrq->sa_family = ARPHRD_ETHER; - memset(awrq->sa_data, 0, ETHER_ADDR_LEN); - - - (void) dev_wlc_ioctl(dev, WLC_GET_BSSID, awrq->sa_data, ETHER_ADDR_LEN); - - return 0; -} - -#if WIRELESS_EXT > 17 -static int -wl_iw_mlme( - struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *awrq, - char *extra -) -{ - struct iw_mlme *mlme; - scb_val_t scbval; - int error = -EINVAL; - - WL_TRACE(("%s: SIOCSIWMLME DISASSOC/DEAUTH\n", dev->name)); - - mlme = (struct iw_mlme *)extra; - if (mlme == NULL) { - WL_ERROR(("Invalid ioctl data.\n")); - return error; - } - - scbval.val = mlme->reason_code; - bcopy(&mlme->addr.sa_data, &scbval.ea, ETHER_ADDR_LEN); - - if (mlme->cmd == IW_MLME_DISASSOC) { - scbval.val = htod32(scbval.val); - error = dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t)); - } - else if (mlme->cmd == IW_MLME_DEAUTH) { - scbval.val = htod32(scbval.val); - error = dev_wlc_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scbval, - sizeof(scb_val_t)); - } - else { - WL_ERROR(("Invalid ioctl data.\n")); - return error; - } - - return error; -} -#endif - -#ifndef WL_IW_USE_ISCAN -static int -wl_iw_get_aplist( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_scan_results_t *list; - struct sockaddr *addr = (struct sockaddr *) extra; - struct iw_quality qual[IW_MAX_AP]; - wl_bss_info_t *bi = NULL; - int error, i; - uint buflen = dwrq->length; - - WL_TRACE(("%s: SIOCGIWAPLIST\n", dev->name)); - - if (!extra) - return -EINVAL; - - - list = kmalloc(buflen, GFP_KERNEL); - if (!list) - return -ENOMEM; - memset(list, 0, buflen); - list->buflen = htod32(buflen); - if ((error = dev_wlc_ioctl(dev, WLC_SCAN_RESULTS, list, buflen))) { - WL_ERROR(("%d: Scan results error %d\n", __LINE__, error)); - kfree(list); - return error; - } - list->buflen = dtoh32(list->buflen); - list->version = dtoh32(list->version); - list->count = dtoh32(list->count); - if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR(("%s : list->version %d != WL_BSS_INFO_VERSION\n", - __FUNCTION__, list->version)); - kfree(list); - return -EINVAL; - } - - for (i = 0, dwrq->length = 0; i < list->count && dwrq->length < IW_MAX_AP; i++) { - bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : list->bss_info; - ASSERT(((uintptr)bi + dtoh32(bi->length)) <= ((uintptr)list + - buflen)); - - - if (!(dtoh16(bi->capability) & DOT11_CAP_ESS)) - continue; - - - memcpy(addr[dwrq->length].sa_data, &bi->BSSID, ETHER_ADDR_LEN); - addr[dwrq->length].sa_family = ARPHRD_ETHER; - qual[dwrq->length].qual = rssi_to_qual(dtoh16(bi->RSSI)); - qual[dwrq->length].level = 0x100 + dtoh16(bi->RSSI); - qual[dwrq->length].noise = 0x100 + bi->phy_noise; - - -#if WIRELESS_EXT > 18 - qual[dwrq->length].updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; -#else - qual[dwrq->length].updated = 7; -#endif - - dwrq->length++; - } - - kfree(list); - - if (dwrq->length) { - memcpy(&addr[dwrq->length], qual, sizeof(struct iw_quality) * dwrq->length); - - dwrq->flags = 1; - } - - return 0; -} -#endif - -#ifdef WL_IW_USE_ISCAN -static int -wl_iw_iscan_get_aplist( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_scan_results_t *list; - iscan_buf_t * buf; - iscan_info_t *iscan = g_iscan; - - struct sockaddr *addr = (struct sockaddr *) extra; - struct iw_quality qual[IW_MAX_AP]; - wl_bss_info_t *bi = NULL; - int i; - - WL_TRACE(("%s: SIOCGIWAPLIST\n", dev->name)); - - if (!extra) - return -EINVAL; - - if ((!iscan) || (iscan->tsk_ctl.thr_pid < 0)) { - WL_ERROR(("%s error\n", __FUNCTION__)); - return 0; - } - - buf = iscan->list_hdr; - - while (buf) { - list = &((wl_iscan_results_t*)buf->iscan_buf)->results; - if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR(("%s : list->version %d != WL_BSS_INFO_VERSION\n", - __FUNCTION__, list->version)); - return -EINVAL; - } - - bi = NULL; - for (i = 0, dwrq->length = 0; i < list->count && dwrq->length < IW_MAX_AP; i++) { - bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) - : list->bss_info; - ASSERT(((uintptr)bi + dtoh32(bi->length)) <= ((uintptr)list + - WLC_IW_ISCAN_MAXLEN)); - - - if (!(dtoh16(bi->capability) & DOT11_CAP_ESS)) - continue; - - - memcpy(addr[dwrq->length].sa_data, &bi->BSSID, ETHER_ADDR_LEN); - addr[dwrq->length].sa_family = ARPHRD_ETHER; - qual[dwrq->length].qual = rssi_to_qual(dtoh16(bi->RSSI)); - qual[dwrq->length].level = 0x100 + dtoh16(bi->RSSI); - qual[dwrq->length].noise = 0x100 + bi->phy_noise; - - -#if WIRELESS_EXT > 18 - qual[dwrq->length].updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; -#else - qual[dwrq->length].updated = 7; -#endif - - dwrq->length++; - } - buf = buf->next; - } - if (dwrq->length) { - memcpy(&addr[dwrq->length], qual, sizeof(struct iw_quality) * dwrq->length); - - dwrq->flags = 1; - } - - return 0; -} - -static int -wl_iw_iscan_prep(wl_scan_params_t *params, wlc_ssid_t *ssid) -{ - int err = 0; - - memcpy(¶ms->bssid, ðer_bcast, ETHER_ADDR_LEN); - params->bss_type = DOT11_BSSTYPE_ANY; - params->scan_type = 0; - params->nprobes = -1; - params->active_time = -1; - params->passive_time = -1; - params->home_time = -1; - params->channel_num = 0; - -#if defined(CONFIG_FIRST_SCAN) - - if (g_first_broadcast_scan == BROADCAST_SCAN_FIRST_STARTED) - params->passive_time = 30; -#endif - params->nprobes = htod32(params->nprobes); - params->active_time = htod32(params->active_time); - params->passive_time = htod32(params->passive_time); - params->home_time = htod32(params->home_time); - if (ssid && ssid->SSID_len) - memcpy(¶ms->ssid, ssid, sizeof(wlc_ssid_t)); - - return err; -} - -static int -wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, uint16 action) -{ - int err = 0; - - iscan->iscan_ex_params_p->version = htod32(ISCAN_REQ_VERSION); - iscan->iscan_ex_params_p->action = htod16(action); - iscan->iscan_ex_params_p->scan_duration = htod16(0); - - WL_SCAN(("%s : nprobes=%d\n", __FUNCTION__, iscan->iscan_ex_params_p->params.nprobes)); - WL_SCAN(("active_time=%d\n", iscan->iscan_ex_params_p->params.active_time)); - WL_SCAN(("passive_time=%d\n", iscan->iscan_ex_params_p->params.passive_time)); - WL_SCAN(("home_time=%d\n", iscan->iscan_ex_params_p->params.home_time)); - WL_SCAN(("scan_type=%d\n", iscan->iscan_ex_params_p->params.scan_type)); - WL_SCAN(("bss_type=%d\n", iscan->iscan_ex_params_p->params.bss_type)); - - if ((dev_iw_iovar_setbuf(iscan->dev, "iscan", iscan->iscan_ex_params_p, - iscan->iscan_ex_param_size, iscan->ioctlbuf, sizeof(iscan->ioctlbuf)))) { - WL_ERROR(("Set ISCAN for %s failed with %d\n", __FUNCTION__, err)); - err = -1; - } - - return err; -} - -static void -wl_iw_timerfunc(ulong data) -{ - iscan_info_t *iscan = (iscan_info_t *)data; - if (iscan) { - iscan->timer_on = 0; - if (iscan->iscan_state != ISCAN_STATE_IDLE) { - WL_TRACE(("timer trigger\n")); - up(&iscan->tsk_ctl.sema); - } - } -} - -static void -wl_iw_set_event_mask(struct net_device *dev) -{ - char eventmask[WL_EVENTING_MASK_LEN]; - char iovbuf[WL_EVENTING_MASK_LEN + 12]; - - dev_iw_iovar_getbuf(dev, "event_msgs", "", 0, iovbuf, sizeof(iovbuf)); - bcopy(iovbuf, eventmask, WL_EVENTING_MASK_LEN); - setbit(eventmask, WLC_E_SCAN_COMPLETE); - dev_iw_iovar_setbuf(dev, "event_msgs", eventmask, WL_EVENTING_MASK_LEN, - iovbuf, sizeof(iovbuf)); -} - -static uint32 -wl_iw_iscan_get(iscan_info_t *iscan) -{ - iscan_buf_t * buf; - iscan_buf_t * ptr; - wl_iscan_results_t * list_buf; - wl_iscan_results_t list; - wl_scan_results_t *results; - uint32 status; - int res = 0; - - DHD_OS_MUTEX_LOCK(&wl_cache_lock); - if (iscan->list_cur) { - buf = iscan->list_cur; - iscan->list_cur = buf->next; - } - else { - buf = kmalloc(sizeof(iscan_buf_t), GFP_KERNEL); - if (!buf) { - WL_ERROR(("%s can't alloc iscan_buf_t : going to abort currect iscan\n", - __FUNCTION__)); - DHD_OS_MUTEX_UNLOCK(&wl_cache_lock); - return WL_SCAN_RESULTS_NO_MEM; - } - buf->next = NULL; - if (!iscan->list_hdr) - iscan->list_hdr = buf; - else { - ptr = iscan->list_hdr; - while (ptr->next) { - ptr = ptr->next; - } - ptr->next = buf; - } - } - memset(buf->iscan_buf, 0, WLC_IW_ISCAN_MAXLEN); - list_buf = (wl_iscan_results_t*)buf->iscan_buf; - results = &list_buf->results; - results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE; - results->version = 0; - results->count = 0; - - memset(&list, 0, sizeof(list)); - list.results.buflen = htod32(WLC_IW_ISCAN_MAXLEN); - res = dev_iw_iovar_getbuf( - iscan->dev, - "iscanresults", - &list, - WL_ISCAN_RESULTS_FIXED_SIZE, - buf->iscan_buf, - WLC_IW_ISCAN_MAXLEN); - if (res == 0) { - results->buflen = dtoh32(results->buflen); - results->version = dtoh32(results->version); - results->count = dtoh32(results->count); - WL_TRACE(("results->count = %d\n", results->count)); - WL_TRACE(("results->buflen = %d\n", results->buflen)); - status = dtoh32(list_buf->status); - } else { - WL_ERROR(("%s returns error %d\n", __FUNCTION__, res)); - - status = WL_SCAN_RESULTS_NO_MEM; - } - DHD_OS_MUTEX_UNLOCK(&wl_cache_lock); - return status; -} - -static void -wl_iw_force_specific_scan(iscan_info_t *iscan) -{ - WL_TRACE(("%s force Specific SCAN for %s\n", __FUNCTION__, g_specific_ssid.SSID)); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - rtnl_lock(); -#endif - - (void) dev_wlc_ioctl(iscan->dev, WLC_SCAN, &g_specific_ssid, sizeof(g_specific_ssid)); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - rtnl_unlock(); -#endif -} - -static void -wl_iw_send_scan_complete(iscan_info_t *iscan) -{ - union iwreq_data wrqu; - - memset(&wrqu, 0, sizeof(wrqu)); - - - wireless_send_event(iscan->dev, SIOCGIWSCAN, &wrqu, NULL); -#if defined(CONFIG_FIRST_SCAN) - if (g_first_broadcast_scan == BROADCAST_SCAN_FIRST_STARTED) - g_first_broadcast_scan = BROADCAST_SCAN_FIRST_RESULT_READY; -#endif - WL_TRACE(("Send Event ISCAN complete\n")); -} - -static int -_iscan_sysioc_thread(void *data) -{ - uint32 status; - - tsk_ctl_t *tsk_ctl = (tsk_ctl_t *)data; - iscan_info_t *iscan = (iscan_info_t *) tsk_ctl->parent; - - - static bool iscan_pass_abort = FALSE; - - DAEMONIZE("iscan_sysioc"); - - status = WL_SCAN_RESULTS_PARTIAL; - - - complete(&tsk_ctl->completed); - - while (down_interruptible(&tsk_ctl->sema) == 0) { - - SMP_RD_BARRIER_DEPENDS(); - if (tsk_ctl->terminated) { - break; - } -#if defined(SOFTAP) - - if (ap_cfg_running) { - WL_TRACE(("%s skipping SCAN ops in AP mode !!!\n", __FUNCTION__)); - net_os_wake_unlock(iscan->dev); - continue; - } -#endif - - if (iscan->timer_on) { - - iscan->timer_on = 0; - del_timer_sync(&iscan->timer); - } - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - rtnl_lock(); -#endif - status = wl_iw_iscan_get(iscan); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - rtnl_unlock(); -#endif - - if (g_scan_specified_ssid && (iscan_pass_abort == TRUE)) { - WL_TRACE(("%s Get results from specific scan status=%d\n", __FUNCTION__, status)); - wl_iw_send_scan_complete(iscan); - iscan_pass_abort = FALSE; - status = -1; - } - - switch (status) { - case WL_SCAN_RESULTS_PARTIAL: - WL_TRACE(("iscanresults incomplete\n")); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - rtnl_lock(); -#endif - - wl_iw_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - rtnl_unlock(); -#endif - - mod_timer(&iscan->timer, jiffies + iscan->timer_ms*HZ/1000); - iscan->timer_on = 1; - break; - case WL_SCAN_RESULTS_SUCCESS: - WL_TRACE(("iscanresults complete\n")); - iscan->iscan_state = ISCAN_STATE_IDLE; - wl_iw_send_scan_complete(iscan); - break; - case WL_SCAN_RESULTS_PENDING: - WL_TRACE(("iscanresults pending\n")); - - mod_timer(&iscan->timer, jiffies + iscan->timer_ms*HZ/1000); - iscan->timer_on = 1; - break; - case WL_SCAN_RESULTS_ABORTED: - WL_TRACE(("iscanresults aborted\n")); - iscan->iscan_state = ISCAN_STATE_IDLE; - if (g_scan_specified_ssid == 0) - wl_iw_send_scan_complete(iscan); - else { - iscan_pass_abort = TRUE; - wl_iw_force_specific_scan(iscan); - } - break; - case WL_SCAN_RESULTS_NO_MEM: - WL_TRACE(("iscanresults can't alloc memory: skip\n")); - iscan->iscan_state = ISCAN_STATE_IDLE; - break; - default: - WL_TRACE(("iscanresults returned unknown status %d\n", status)); - break; - } - - net_os_wake_unlock(iscan->dev); - } - - if (iscan->timer_on) { - iscan->timer_on = 0; - del_timer_sync(&iscan->timer); - } - complete_and_exit(&tsk_ctl->completed, 0); -} -#endif - -#if !defined(CSCAN) - -static void -wl_iw_set_ss_cache_timer_flag(void) -{ - g_ss_cache_ctrl.m_timer_expired = 1; - WL_TRACE(("%s called\n", __FUNCTION__)); -} - - -static int -wl_iw_init_ss_cache_ctrl(void) -{ - WL_TRACE(("%s :\n", __FUNCTION__)); - g_ss_cache_ctrl.m_prev_scan_mode = 0; - g_ss_cache_ctrl.m_cons_br_scan_cnt = 0; - g_ss_cache_ctrl.m_cache_head = NULL; - g_ss_cache_ctrl.m_link_down = 0; - g_ss_cache_ctrl.m_timer_expired = 0; - memset(g_ss_cache_ctrl.m_active_bssid, 0, ETHER_ADDR_LEN); - - g_ss_cache_ctrl.m_timer = kmalloc(sizeof(struct timer_list), GFP_KERNEL); - if (!g_ss_cache_ctrl.m_timer) { - return -ENOMEM; - } - g_ss_cache_ctrl.m_timer->function = (void *)wl_iw_set_ss_cache_timer_flag; - init_timer(g_ss_cache_ctrl.m_timer); - - return 0; -} - - - -static void -wl_iw_free_ss_cache(void) -{ - wl_iw_ss_cache_t *node, *cur; - wl_iw_ss_cache_t **spec_scan_head; - - WL_TRACE(("%s called\n", __FUNCTION__)); - - DHD_OS_MUTEX_LOCK(&wl_cache_lock); - spec_scan_head = &g_ss_cache_ctrl.m_cache_head; - node = *spec_scan_head; - - for (;node;) { - WL_TRACE(("%s : SSID - %s\n", __FUNCTION__, node->bss_info->SSID)); - cur = node; - node = cur->next; - kfree(cur); - } - *spec_scan_head = NULL; - DHD_OS_MUTEX_UNLOCK(&wl_cache_lock); -} - - - -static int -wl_iw_run_ss_cache_timer(int kick_off) -{ - struct timer_list **timer; - - timer = &g_ss_cache_ctrl.m_timer; - - if (*timer) { - if (kick_off) { -#ifdef CONFIG_PRESCANNED - (*timer)->expires = jiffies + 70000 * HZ / 1000; -#else - (*timer)->expires = jiffies + 30000 * HZ / 1000; -#endif - add_timer(*timer); - WL_TRACE(("%s : timer starts \n", __FUNCTION__)); - } else { - del_timer_sync(*timer); - WL_TRACE(("%s : timer stops \n", __FUNCTION__)); - } - } - - return 0; -} - - -static void -wl_iw_release_ss_cache_ctrl(void) -{ - WL_TRACE(("%s :\n", __FUNCTION__)); - wl_iw_free_ss_cache(); - wl_iw_run_ss_cache_timer(0); - if (g_ss_cache_ctrl.m_timer) { - kfree(g_ss_cache_ctrl.m_timer); - } -} - - - -static void -wl_iw_reset_ss_cache(void) -{ - wl_iw_ss_cache_t *node, *prev, *cur; - wl_iw_ss_cache_t **spec_scan_head; - - DHD_OS_MUTEX_LOCK(&wl_cache_lock); - spec_scan_head = &g_ss_cache_ctrl.m_cache_head; - node = *spec_scan_head; - prev = node; - - for (;node;) { - WL_TRACE(("%s : node SSID %s \n", __FUNCTION__, node->bss_info->SSID)); - if (!node->dirty) { - cur = node; - if (cur == *spec_scan_head) { - *spec_scan_head = cur->next; - prev = *spec_scan_head; - } - else { - prev->next = cur->next; - } - node = cur->next; - - WL_TRACE(("%s : Del node : SSID %s\n", __FUNCTION__, cur->bss_info->SSID)); - kfree(cur); - continue; - } - - node->dirty = 0; - prev = node; - node = node->next; - } - DHD_OS_MUTEX_UNLOCK(&wl_cache_lock); -} - - -static int -wl_iw_add_bss_to_ss_cache(wl_scan_results_t *ss_list) -{ - - wl_iw_ss_cache_t *node, *prev, *leaf; - wl_iw_ss_cache_t **spec_scan_head; - wl_bss_info_t *bi = NULL; - int i; - - - if (!ss_list->count) { - return 0; - } - - DHD_OS_MUTEX_LOCK(&wl_cache_lock); - spec_scan_head = &g_ss_cache_ctrl.m_cache_head; - - for (i = 0; i < ss_list->count; i++) { - - node = *spec_scan_head; - prev = node; - - bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : ss_list->bss_info; - - WL_TRACE(("%s : find %d with specific SSID %s\n", __FUNCTION__, i, bi->SSID)); - for (;node;) { - if (!memcmp(&node->bss_info->BSSID, &bi->BSSID, ETHER_ADDR_LEN)) { - - WL_TRACE(("dirty marked : SSID %s\n", bi->SSID)); - node->dirty = 1; - break; - } - prev = node; - node = node->next; - } - - if (node) { - continue; - } - - leaf = kmalloc(bi->length + WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN, GFP_KERNEL); - if (!leaf) { - WL_ERROR(("Memory alloc failure %d\n", - bi->length + WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN)); - DHD_OS_MUTEX_UNLOCK(&wl_cache_lock); - return -ENOMEM; - } - - memcpy(leaf->bss_info, bi, bi->length); - leaf->next = NULL; - leaf->dirty = 1; - leaf->count = 1; - leaf->version = ss_list->version; - - if (!prev) { - *spec_scan_head = leaf; - } - else { - prev->next = leaf; - } - } - DHD_OS_MUTEX_UNLOCK(&wl_cache_lock); - return 0; -} - - -static int -wl_iw_merge_scan_cache(struct iw_request_info *info, char *extra, uint buflen_from_user, -__u16 *merged_len) -{ - wl_iw_ss_cache_t *node; - wl_scan_results_t *list_merge; - - DHD_OS_MUTEX_LOCK(&wl_cache_lock); - node = g_ss_cache_ctrl.m_cache_head; - for (;node;) { - list_merge = (wl_scan_results_t *)&node->buflen; - WL_TRACE(("%s: Cached Specific APs list=%d\n", __FUNCTION__, list_merge->count)); - if (buflen_from_user - *merged_len > 0) { - *merged_len += (__u16) wl_iw_get_scan_prep(list_merge, info, - extra + *merged_len, buflen_from_user - *merged_len); - } - else { - WL_TRACE(("%s: exit with break\n", __FUNCTION__)); - break; - } - node = node->next; - } - DHD_OS_MUTEX_UNLOCK(&wl_cache_lock); - return 0; -} - - -static int -wl_iw_delete_bss_from_ss_cache(void *addr) -{ - - wl_iw_ss_cache_t *node, *prev; - wl_iw_ss_cache_t **spec_scan_head; - - DHD_OS_MUTEX_LOCK(&wl_cache_lock); - spec_scan_head = &g_ss_cache_ctrl.m_cache_head; - node = *spec_scan_head; - prev = node; - for (;node;) { - if (!memcmp(&node->bss_info->BSSID, addr, ETHER_ADDR_LEN)) { - if (node == *spec_scan_head) { - *spec_scan_head = node->next; - } - else { - prev->next = node->next; - } - - WL_TRACE(("%s : Del node : %s\n", __FUNCTION__, node->bss_info->SSID)); - kfree(node); - break; - } - - prev = node; - node = node->next; - } - - memset(addr, 0, ETHER_ADDR_LEN); - DHD_OS_MUTEX_UNLOCK(&wl_cache_lock); - return 0; -} - -#endif - -static int -wl_iw_set_scan( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - int error; - WL_TRACE(("\n:%s dev:%s: SIOCSIWSCAN : SCAN\n", __FUNCTION__, dev->name)); - -#ifdef OEM_CHROMIUMOS - g_set_essid_before_scan = FALSE; -#endif - -#if defined(CSCAN) - WL_ERROR(("%s: Scan from SIOCGIWSCAN not supported\n", __FUNCTION__)); - return -EINVAL; -#endif - -#if defined(SOFTAP) - - if (ap_cfg_running) { - WL_TRACE(("\n>%s: Not executed, reason -'SOFTAP is active'\n", __FUNCTION__)); - return 0; - } -#endif - - - if (g_onoff == G_WLAN_SET_OFF) - return 0; - - - memset(&g_specific_ssid, 0, sizeof(g_specific_ssid)); -#ifndef WL_IW_USE_ISCAN - - g_scan_specified_ssid = 0; -#endif - -#if WIRELESS_EXT > 17 - - if (wrqu->data.length == sizeof(struct iw_scan_req)) { - if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { - struct iw_scan_req *req = (struct iw_scan_req *)extra; -#if defined(CONFIG_FIRST_SCAN) - if (g_first_broadcast_scan != BROADCAST_SCAN_FIRST_RESULT_CONSUMED) { - - WL_TRACE(("%s Ignoring SC %s first BC is not done = %d\n", - __FUNCTION__, req->essid, - g_first_broadcast_scan)); - return -EBUSY; - } -#endif - if (g_scan_specified_ssid) { - WL_TRACE(("%s Specific SCAN is not done ignore scan for = %s \n", - __FUNCTION__, req->essid)); - - return -EBUSY; - } - else { - g_specific_ssid.SSID_len = MIN(sizeof(g_specific_ssid.SSID), - req->essid_len); - memcpy(g_specific_ssid.SSID, req->essid, g_specific_ssid.SSID_len); - g_specific_ssid.SSID_len = htod32(g_specific_ssid.SSID_len); - g_scan_specified_ssid = 1; - WL_TRACE(("### Specific scan ssid=%s len=%d\n", - g_specific_ssid.SSID, g_specific_ssid.SSID_len)); - } - } - } -#endif - - if ((error = dev_wlc_ioctl(dev, WLC_SCAN, &g_specific_ssid, sizeof(g_specific_ssid)))) { - WL_TRACE(("#### Set SCAN for %s failed with %d\n", g_specific_ssid.SSID, error)); - - g_scan_specified_ssid = 0; - return -EBUSY; - } - - return 0; -} - -#ifdef WL_IW_USE_ISCAN -int -wl_iw_iscan_set_scan_broadcast_prep(struct net_device *dev, uint flag) -{ - wlc_ssid_t ssid; - iscan_info_t *iscan = g_iscan; - -#if defined(CONFIG_FIRST_SCAN) - - if (g_first_broadcast_scan == BROADCAST_SCAN_FIRST_IDLE) { - g_first_broadcast_scan = BROADCAST_SCAN_FIRST_STARTED; - WL_TRACE(("%s: First Brodcast scan was forced\n", __FUNCTION__)); - } - else if (g_first_broadcast_scan == BROADCAST_SCAN_FIRST_STARTED) { - WL_TRACE(("%s: ignore ISCAN request first BS is not done yet\n", __FUNCTION__)); - return 0; - } -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - if (flag) - rtnl_lock(); -#endif - - dev_wlc_ioctl(dev, WLC_SET_PASSIVE_SCAN, &iscan->scan_flag, sizeof(iscan->scan_flag)); - wl_iw_set_event_mask(dev); - - WL_TRACE(("+++: Set Broadcast ISCAN\n")); - - memset(&ssid, 0, sizeof(ssid)); - - iscan->list_cur = iscan->list_hdr; - iscan->iscan_state = ISCAN_STATE_SCANING; - - memset(&iscan->iscan_ex_params_p->params, 0, iscan->iscan_ex_param_size); - wl_iw_iscan_prep(&iscan->iscan_ex_params_p->params, &ssid); - wl_iw_iscan(iscan, &ssid, WL_SCAN_ACTION_START); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - if (flag) - rtnl_unlock(); -#endif - - mod_timer(&iscan->timer, jiffies + iscan->timer_ms*HZ/1000); - - iscan->timer_on = 1; - - return 0; -} - -static int -wl_iw_iscan_set_scan( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra -) -{ - wlc_ssid_t ssid; - iscan_info_t *iscan = g_iscan; - int ret = 0; - - WL_TRACE_SCAN(("%s: SIOCSIWSCAN : ISCAN\n", dev->name)); - -#if defined(CSCAN) - WL_ERROR(("%s: Scan from SIOCGIWSCAN not supported\n", __FUNCTION__)); - return -EINVAL; -#endif - - net_os_wake_lock(dev); - - -#if defined(SOFTAP) - if (ap_cfg_running) { - WL_TRACE(("\n>%s: Not executed, reason -'SOFTAP is active'\n", __FUNCTION__)); - goto set_scan_end; - } -#endif - - if (g_onoff == G_WLAN_SET_OFF) { - WL_TRACE(("%s: driver is not up yet after START\n", __FUNCTION__)); - goto set_scan_end; - } - -#ifdef PNO_SUPPORT - - if (dhd_dev_get_pno_status(dev)) { - WL_ERROR(("%s: Scan called when PNO is active\n", __FUNCTION__)); - } -#endif - - - if ((!iscan) || (iscan->tsk_ctl.thr_pid < 0)) { - WL_ERROR(("%s error \n", __FUNCTION__)); - goto set_scan_end; - } - - if (g_scan_specified_ssid) { - WL_TRACE(("%s Specific SCAN already running ignoring BC scan\n", - __FUNCTION__)); - ret = EBUSY; - goto set_scan_end; - } - - - memset(&ssid, 0, sizeof(ssid)); - -#if WIRELESS_EXT > 17 - - if (wrqu->data.length == sizeof(struct iw_scan_req)) { - if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { - int as = 0; - struct iw_scan_req *req = (struct iw_scan_req *)extra; - - ssid.SSID_len = MIN(sizeof(ssid.SSID), req->essid_len); - memcpy(ssid.SSID, req->essid, ssid.SSID_len); - ssid.SSID_len = htod32(ssid.SSID_len); - dev_wlc_ioctl(dev, WLC_SET_PASSIVE_SCAN, &as, sizeof(as)); - wl_iw_set_event_mask(dev); - ret = wl_iw_set_scan(dev, info, wrqu, extra); - goto set_scan_end; - } - else { - g_scan_specified_ssid = 0; - - if (iscan->iscan_state == ISCAN_STATE_SCANING) { - WL_TRACE(("%s ISCAN already in progress \n", __FUNCTION__)); - goto set_scan_end; - } - } - } -#endif - -#if defined(CONFIG_FIRST_SCAN) && !defined(CSCAN) - if (g_first_broadcast_scan < BROADCAST_SCAN_FIRST_RESULT_CONSUMED) { - if (++g_first_counter_scans == MAX_ALLOWED_BLOCK_SCAN_FROM_FIRST_SCAN) { - - WL_ERROR(("%s Clean up First scan flag which is %d\n", - __FUNCTION__, g_first_broadcast_scan)); - g_first_broadcast_scan = BROADCAST_SCAN_FIRST_RESULT_CONSUMED; - } - else { - WL_ERROR(("%s Ignoring Broadcast Scan:First Scan is not done yet %d\n", - __FUNCTION__, g_first_counter_scans)); - ret = -EBUSY; - goto set_scan_end; - } - } -#endif - - wl_iw_iscan_set_scan_broadcast_prep(dev, 0); - -set_scan_end: - net_os_wake_unlock(dev); - return ret; -} -#endif - -#if WIRELESS_EXT > 17 -static bool -ie_is_wpa_ie(uint8 **wpaie, uint8 **tlvs, int *tlvs_len) -{ - - - uint8 *ie = *wpaie; - - - if ((ie[1] >= 6) && - !bcmp((const void *)&ie[2], (const void *)(WPA_OUI "\x01"), 4)) { - return TRUE; - } - - - ie += ie[1] + 2; - - *tlvs_len -= (int)(ie - *tlvs); - - *tlvs = ie; - return FALSE; -} - -static bool -ie_is_wps_ie(uint8 **wpsie, uint8 **tlvs, int *tlvs_len) -{ - - - uint8 *ie = *wpsie; - - - if ((ie[1] >= 4) && - !bcmp((const void *)&ie[2], (const void *)(WPA_OUI "\x04"), 4)) { - return TRUE; - } - - - ie += ie[1] + 2; - - *tlvs_len -= (int)(ie - *tlvs); - - *tlvs = ie; - return FALSE; -} -#endif - - -static int -wl_iw_handle_scanresults_ies(char **event_p, char *end, - struct iw_request_info *info, wl_bss_info_t *bi) -{ -#if WIRELESS_EXT > 17 - struct iw_event iwe; - char *event; - - event = *event_p; - if (bi->ie_length) { - - bcm_tlv_t *ie; - uint8 *ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t); - int ptr_len = bi->ie_length; - - if ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_RSN_ID))) { - iwe.cmd = IWEVGENIE; - iwe.u.data.length = ie->len + 2; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)ie); - } - ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t); - - while ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_WPA_ID))) { - - if (ie_is_wps_ie(((uint8 **)&ie), &ptr, &ptr_len)) { - iwe.cmd = IWEVGENIE; - iwe.u.data.length = ie->len + 2; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)ie); - break; - } - } - - ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t); - ptr_len = bi->ie_length; - while ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_WPA_ID))) { - if (ie_is_wpa_ie(((uint8 **)&ie), &ptr, &ptr_len)) { - iwe.cmd = IWEVGENIE; - iwe.u.data.length = ie->len + 2; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)ie); - break; - } - } - - *event_p = event; - } -#endif - - return 0; -} - -#ifndef CSCAN -static uint -wl_iw_get_scan_prep( - wl_scan_results_t *list, - struct iw_request_info *info, - char *extra, - short max_size) -{ - int i, j; - struct iw_event iwe; - wl_bss_info_t *bi = NULL; - char *event = extra, *end = extra + max_size - WE_ADD_EVENT_FIX, *value; - int ret = 0; - - if (!list) { - WL_ERROR(("%s: Null list pointer", __FUNCTION__)); - return ret; - } - - - - for (i = 0; i < list->count && i < IW_MAX_AP; i++) { - if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR(("%s : list->version %d != WL_BSS_INFO_VERSION\n", - __FUNCTION__, list->version)); - return ret; - } - - bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : list->bss_info; - - WL_TRACE(("%s : %s\n", __FUNCTION__, bi->SSID)); - - - iwe.cmd = SIOCGIWAP; - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe.u.ap_addr.sa_data, &bi->BSSID, ETHER_ADDR_LEN); - event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_ADDR_LEN); - - iwe.u.data.length = dtoh32(bi->SSID_len); - iwe.cmd = SIOCGIWESSID; - iwe.u.data.flags = 1; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, bi->SSID); - - - if (dtoh16(bi->capability) & (DOT11_CAP_ESS | DOT11_CAP_IBSS)) { - iwe.cmd = SIOCGIWMODE; - if (dtoh16(bi->capability) & DOT11_CAP_ESS) - iwe.u.mode = IW_MODE_INFRA; - else - iwe.u.mode = IW_MODE_ADHOC; - event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_UINT_LEN); - } - - - iwe.cmd = SIOCGIWFREQ; - iwe.u.freq.m = wf_channel2mhz(CHSPEC_CHANNEL(bi->chanspec), - CHSPEC_CHANNEL(bi->chanspec) <= CH_MAX_2G_CHANNEL ? - WF_CHAN_FACTOR_2_4_G : WF_CHAN_FACTOR_5_G); - iwe.u.freq.e = 6; - event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_FREQ_LEN); - - - iwe.cmd = IWEVQUAL; - iwe.u.qual.qual = rssi_to_qual(dtoh16(bi->RSSI)); - iwe.u.qual.level = 0x100 + dtoh16(bi->RSSI); - iwe.u.qual.noise = 0x100 + bi->phy_noise; - event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_QUAL_LEN); - - - wl_iw_handle_scanresults_ies(&event, end, info, bi); - - - iwe.cmd = SIOCGIWENCODE; - if (dtoh16(bi->capability) & DOT11_CAP_PRIVACY) - iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - else - iwe.u.data.flags = IW_ENCODE_DISABLED; - iwe.u.data.length = 0; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)event); - - - if (bi->rateset.count) { - if (((event -extra) + IW_EV_LCP_LEN) <= (uintptr)end) { - value = event + IW_EV_LCP_LEN; - iwe.cmd = SIOCGIWRATE; - - iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; - for (j = 0; j < bi->rateset.count && j < IW_MAX_BITRATES; j++) { - iwe.u.bitrate.value = - (bi->rateset.rates[j] & 0x7f) * 500000; - value = IWE_STREAM_ADD_VALUE(info, event, value, end, &iwe, - IW_EV_PARAM_LEN); - } - event = value; - } - } - } - - if ((ret = (event - extra)) < 0) { - WL_ERROR(("==> Wrong size\n")); - ret = 0; - } - - WL_TRACE(("%s: size=%d bytes prepared \n", __FUNCTION__, (unsigned int)(event - extra))); - return (uint)ret; -} - -static int -wl_iw_get_scan( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - channel_info_t ci; - wl_scan_results_t *list_merge; - wl_scan_results_t *list = (wl_scan_results_t *) g_scan; - int error; - uint buflen_from_user = dwrq->length; - uint len = G_SCAN_RESULTS; - __u16 len_ret = 0; -#if !defined(CSCAN) - __u16 merged_len = 0; -#endif -#if defined(WL_IW_USE_ISCAN) - iscan_info_t *iscan = g_iscan; - iscan_buf_t * p_buf; -#if !defined(CSCAN) - uint32 counter = 0; -#endif -#endif - - WL_TRACE(("%s: buflen_from_user %d: \n", dev->name, buflen_from_user)); - - if (!extra) { - WL_TRACE(("%s: wl_iw_get_scan return -EINVAL\n", dev->name)); - return -EINVAL; - } - - - if ((error = dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci)))) - return error; - ci.scan_channel = dtoh32(ci.scan_channel); - if (ci.scan_channel) - return -EAGAIN; - -#if !defined(CSCAN) - if (g_ss_cache_ctrl.m_timer_expired) { - wl_iw_free_ss_cache(); - g_ss_cache_ctrl.m_timer_expired ^= 1; - } - if ((!g_scan_specified_ssid && g_ss_cache_ctrl.m_prev_scan_mode) || - g_ss_cache_ctrl.m_cons_br_scan_cnt > 4) { - g_ss_cache_ctrl.m_cons_br_scan_cnt = 0; - - wl_iw_reset_ss_cache(); - } - g_ss_cache_ctrl.m_prev_scan_mode = g_scan_specified_ssid; - if (g_scan_specified_ssid) { - g_ss_cache_ctrl.m_cons_br_scan_cnt = 0; - } - else { - g_ss_cache_ctrl.m_cons_br_scan_cnt++; - } -#endif - - - - if (g_scan_specified_ssid) { - - list = kmalloc(len, GFP_KERNEL); - if (!list) { - WL_TRACE(("%s: wl_iw_get_scan return -ENOMEM\n", dev->name)); - g_scan_specified_ssid = 0; - return -ENOMEM; - } - } - - memset(list, 0, len); - list->buflen = htod32(len); - if ((error = dev_wlc_ioctl(dev, WLC_SCAN_RESULTS, list, len))) { - WL_ERROR(("%s: %s : Scan_results ERROR %d\n", dev->name, __FUNCTION__, error)); - dwrq->length = len; - if (g_scan_specified_ssid) { - g_scan_specified_ssid = 0; - kfree(list); - } - return 0; - } - list->buflen = dtoh32(list->buflen); - list->version = dtoh32(list->version); - list->count = dtoh32(list->count); - - - if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR(("%s : list->version %d != WL_BSS_INFO_VERSION\n", - __FUNCTION__, list->version)); - if (g_scan_specified_ssid) { - g_scan_specified_ssid = 0; - kfree(list); - } - return -EINVAL; - } - -#if !defined(CSCAN) - if (g_scan_specified_ssid) { - - wl_iw_add_bss_to_ss_cache(list); - kfree(list); - } -#endif - -#if !defined(CSCAN) - DHD_OS_MUTEX_LOCK(&wl_cache_lock); -#if defined(WL_IW_USE_ISCAN) - if (g_scan_specified_ssid) - WL_TRACE(("%s: Specified scan APs from scan=%d\n", __FUNCTION__, list->count)); - p_buf = iscan->list_hdr; - - while (p_buf != iscan->list_cur) { - list_merge = &((wl_iscan_results_t*)p_buf->iscan_buf)->results; - WL_TRACE(("%s: Bcast APs list=%d\n", __FUNCTION__, list_merge->count)); - counter += list_merge->count; - if (list_merge->count > 0) - len_ret += (__u16) wl_iw_get_scan_prep(list_merge, info, - extra+len_ret, buflen_from_user -len_ret); - p_buf = p_buf->next; - } - WL_TRACE(("%s merged with total Bcast APs=%d\n", __FUNCTION__, counter)); -#else - list_merge = (wl_scan_results_t *) g_scan; - len_ret = (__u16) wl_iw_get_scan_prep(list_merge, info, extra, buflen_from_user); -#endif - DHD_OS_MUTEX_UNLOCK(&wl_cache_lock); - if (g_ss_cache_ctrl.m_link_down) { - - wl_iw_delete_bss_from_ss_cache(g_ss_cache_ctrl.m_active_bssid); - } - - wl_iw_merge_scan_cache(info, extra+len_ret, buflen_from_user-len_ret, &merged_len); - len_ret += merged_len; - wl_iw_run_ss_cache_timer(0); - wl_iw_run_ss_cache_timer(1); -#else - - - if (g_scan_specified_ssid) { - WL_TRACE(("%s: Specified scan APs in the list =%d\n", __FUNCTION__, list->count)); - len_ret = (__u16) wl_iw_get_scan_prep(list, info, extra, buflen_from_user); - kfree(list); - -#if defined(WL_IW_USE_ISCAN) - p_buf = iscan->list_hdr; - - while (p_buf != iscan->list_cur) { - list_merge = &((wl_iscan_results_t*)p_buf->iscan_buf)->results; - WL_TRACE(("%s: Bcast APs list=%d\n", __FUNCTION__, list_merge->count)); - if (list_merge->count > 0) - len_ret += (__u16) wl_iw_get_scan_prep(list_merge, info, - extra+len_ret, buflen_from_user -len_ret); - p_buf = p_buf->next; - } -#else - list_merge = (wl_scan_results_t *) g_scan; - WL_TRACE(("%s: Bcast APs list=%d\n", __FUNCTION__, list_merge->count)); - if (list_merge->count > 0) - len_ret += (__u16) wl_iw_get_scan_prep(list_merge, info, extra+len_ret, - buflen_from_user -len_ret); -#endif - } - else { - list = (wl_scan_results_t *) g_scan; - len_ret = (__u16) wl_iw_get_scan_prep(list, info, extra, buflen_from_user); - } -#endif - -#if defined(WL_IW_USE_ISCAN) - - g_scan_specified_ssid = 0; -#endif - - if ((len_ret + WE_ADD_EVENT_FIX) < buflen_from_user) - len = len_ret; - - dwrq->length = len; - dwrq->flags = 0; - - WL_TRACE(("%s return to WE %d bytes APs=%d\n", __FUNCTION__, dwrq->length, list->count)); - return 0; -} -#endif - -#if defined(WL_IW_USE_ISCAN) -static int -wl_iw_iscan_get_scan( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_scan_results_t *list; - struct iw_event iwe; - wl_bss_info_t *bi = NULL; - int ii, j; - int apcnt; - char *event = extra, *end = extra + dwrq->length, *value; - iscan_info_t *iscan = g_iscan; - iscan_buf_t * p_buf; - uint32 counter = 0; - uint8 channel; -#if !defined(CSCAN) - __u16 merged_len = 0; - uint buflen_from_user = dwrq->length; -#endif - - WL_TRACE(("%s %s buflen_from_user %d:\n", dev->name, __FUNCTION__, dwrq->length)); - -#if defined(SOFTAP) - if (ap_cfg_running) { - WL_TRACE(("%s: Not executed, reason -'SOFTAP is active'\n", __FUNCTION__)); - return -EINVAL; - } -#endif - - if (!extra) { - WL_TRACE(("%s: INVALID SIOCGIWSCAN GET bad parameter\n", dev->name)); - return -EINVAL; - } - -#if defined(CONFIG_FIRST_SCAN) - if (g_first_broadcast_scan < BROADCAST_SCAN_FIRST_RESULT_READY) { - WL_TRACE(("%s %s: first ISCAN results are NOT ready yet \n", - dev->name, __FUNCTION__)); - return -EAGAIN; - } -#endif - - if ((!iscan) || (iscan->tsk_ctl.thr_pid < 0)) { - WL_ERROR(("%ssysioc_pid\n", __FUNCTION__)); - return EAGAIN; - } - - - -#if !defined(CSCAN) - if (g_ss_cache_ctrl.m_timer_expired) { - wl_iw_free_ss_cache(); - g_ss_cache_ctrl.m_timer_expired ^= 1; - } - if (g_scan_specified_ssid) { - return wl_iw_get_scan(dev, info, dwrq, extra); - } - else { - if (g_ss_cache_ctrl.m_link_down) { - - wl_iw_delete_bss_from_ss_cache(g_ss_cache_ctrl.m_active_bssid); - } - if (g_ss_cache_ctrl.m_prev_scan_mode || g_ss_cache_ctrl.m_cons_br_scan_cnt > 4) { - g_ss_cache_ctrl.m_cons_br_scan_cnt = 0; - - wl_iw_reset_ss_cache(); - } - g_ss_cache_ctrl.m_prev_scan_mode = g_scan_specified_ssid; - g_ss_cache_ctrl.m_cons_br_scan_cnt++; - } -#endif - - WL_TRACE(("%s: SIOCGIWSCAN GET broadcast results\n", dev->name)); - apcnt = 0; - p_buf = iscan->list_hdr; - - while (p_buf != iscan->list_cur) { - list = &((wl_iscan_results_t*)p_buf->iscan_buf)->results; - - counter += list->count; - - if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR(("%s : list->version %d != WL_BSS_INFO_VERSION\n", - __FUNCTION__, list->version)); - return -EINVAL; - } - - bi = NULL; - for (ii = 0; ii < list->count && apcnt < IW_MAX_AP; apcnt++, ii++) { - bi = (bi ? - (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : - list->bss_info); - ASSERT(((uintptr)bi + dtoh32(bi->length)) <= ((uintptr)list + - WLC_IW_ISCAN_MAXLEN)); - - - if (event + ETHER_ADDR_LEN + bi->SSID_len + - IW_EV_UINT_LEN + IW_EV_FREQ_LEN + IW_EV_QUAL_LEN >= end) - return -E2BIG; - - iwe.cmd = SIOCGIWAP; - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe.u.ap_addr.sa_data, &bi->BSSID, ETHER_ADDR_LEN); - event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_ADDR_LEN); - - - iwe.u.data.length = dtoh32(bi->SSID_len); - iwe.cmd = SIOCGIWESSID; - iwe.u.data.flags = 1; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, bi->SSID); - - - if (dtoh16(bi->capability) & (DOT11_CAP_ESS | DOT11_CAP_IBSS)) { - iwe.cmd = SIOCGIWMODE; - if (dtoh16(bi->capability) & DOT11_CAP_ESS) - iwe.u.mode = IW_MODE_INFRA; - else - iwe.u.mode = IW_MODE_ADHOC; - event = IWE_STREAM_ADD_EVENT(info, event, end, - &iwe, IW_EV_UINT_LEN); - } - - - iwe.cmd = SIOCGIWFREQ; - channel = (bi->ctl_ch == 0) ? CHSPEC_CHANNEL(bi->chanspec) : bi->ctl_ch; - iwe.u.freq.m = wf_channel2mhz(channel, - channel <= CH_MAX_2G_CHANNEL ? - WF_CHAN_FACTOR_2_4_G : WF_CHAN_FACTOR_5_G); - iwe.u.freq.e = 6; - event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_FREQ_LEN); - - - iwe.cmd = IWEVQUAL; - iwe.u.qual.qual = rssi_to_qual(dtoh16(bi->RSSI)); - iwe.u.qual.level = 0x100 + dtoh16(bi->RSSI); - iwe.u.qual.noise = 0x100 + bi->phy_noise; - event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_QUAL_LEN); - - - wl_iw_handle_scanresults_ies(&event, end, info, bi); - - - iwe.cmd = SIOCGIWENCODE; - if (dtoh16(bi->capability) & DOT11_CAP_PRIVACY) - iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - else - iwe.u.data.flags = IW_ENCODE_DISABLED; - iwe.u.data.length = 0; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)event); - - - if (bi->rateset.count) { - if (event + IW_MAX_BITRATES*IW_EV_PARAM_LEN >= end) - return -E2BIG; - - value = event + IW_EV_LCP_LEN; - iwe.cmd = SIOCGIWRATE; - - iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; - for (j = 0; j < bi->rateset.count && j < IW_MAX_BITRATES; j++) { - iwe.u.bitrate.value = - (bi->rateset.rates[j] & 0x7f) * 500000; - value = IWE_STREAM_ADD_VALUE(info, event, value, end, &iwe, - IW_EV_PARAM_LEN); - } - event = value; - } - } - p_buf = p_buf->next; - } - - dwrq->length = event - extra; - dwrq->flags = 0; - -#if !defined(CSCAN) - - wl_iw_merge_scan_cache(info, event, buflen_from_user - dwrq->length, &merged_len); - dwrq->length += merged_len; - wl_iw_run_ss_cache_timer(0); - wl_iw_run_ss_cache_timer(1); -#endif - -#if defined(CONFIG_FIRST_SCAN) - g_first_broadcast_scan = BROADCAST_SCAN_FIRST_RESULT_CONSUMED; -#endif - - WL_TRACE(("%s return to WE %d bytes APs=%d\n", __FUNCTION__, dwrq->length, counter)); - - return 0; -} -#endif - -#define WL_JOIN_PARAMS_MAX 1600 -#ifdef CONFIG_PRESCANNED -static int -check_prescan(wl_join_params_t *join_params, int *join_params_size) -{ - int cnt = 0; - int indx = 0; - wl_iw_ss_cache_t *node = NULL; - wl_bss_info_t *bi = NULL; - iscan_info_t *iscan = g_iscan; - iscan_buf_t * buf; - wl_scan_results_t *list; - char *destbuf; - - buf = iscan->list_hdr; - - while (buf) { - list = &((wl_iscan_results_t*)buf->iscan_buf)->results; - bi = NULL; - for (indx = 0; indx < list->count; indx++) { - bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) - : list->bss_info; - if (!(dtoh16(bi->capability) & DOT11_CAP_ESS)) - continue; - if ((dtoh32(bi->SSID_len) != join_params->ssid.SSID_len) || - memcmp(bi->SSID, join_params->ssid.SSID, - join_params->ssid.SSID_len)) - continue; - memcpy(&join_params->params.chanspec_list[cnt], - &bi->chanspec, sizeof(chanspec_t)); - WL_ERROR(("iscan : chanspec :%d, count %d \n", bi->chanspec, cnt)); - cnt++; - } - buf = buf->next; - } - - if (!cnt) { - MUTEX_LOCK_WL_SCAN_SET(); - node = g_ss_cache_ctrl.m_cache_head; - for (; node; ) { - if (!memcmp(&node->bss_info->SSID, join_params->ssid.SSID, - join_params->ssid.SSID_len)) { - memcpy(&join_params->params.chanspec_list[cnt], - &node->bss_info->chanspec, sizeof(chanspec_t)); - WL_ERROR(("cache_scan : chanspec :%d, count %d \n", - (int)node->bss_info->chanspec, cnt)); - cnt++; - } - node = node->next; - } - MUTEX_UNLOCK_WL_SCAN_SET(); - } - - if (!cnt) { - return 0; - } - - destbuf = (char *)&join_params->params.chanspec_list[cnt]; - *join_params_size = destbuf - (char*)join_params; - join_params->ssid.SSID_len = htod32(g_ssid.SSID_len); - memcpy(&(join_params->params.bssid), ðer_bcast, ETHER_ADDR_LEN); - join_params->params.chanspec_num = htod32(cnt); - - if ((*join_params_size) > WL_JOIN_PARAMS_MAX) { - WL_ERROR(("can't fit bssids for all %d APs found\n", cnt)); - kfree(join_params); - return 0; - } - - WL_ERROR(("Passing %d channel/bssid pairs.\n", cnt)); - return cnt; -} -#endif - -static int -wl_iw_set_essid( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - int error; - wl_join_params_t *join_params; - int join_params_size; - - WL_TRACE(("%s: SIOCSIWESSID\n", dev->name)); - - RETURN_IF_EXTRA_NULL(extra); - -#ifdef OEM_CHROMIUMOS - if (g_set_essid_before_scan) - return -EAGAIN; -#endif - if (!(join_params = kmalloc(WL_JOIN_PARAMS_MAX, GFP_KERNEL))) { - WL_ERROR(("allocation failed for join_params size is %d\n", WL_JOIN_PARAMS_MAX)); - return -ENOMEM; - } - - memset(join_params, 0, WL_JOIN_PARAMS_MAX); - - - memset(&g_ssid, 0, sizeof(g_ssid)); - - if (dwrq->length && extra) { -#if WIRELESS_EXT > 20 - g_ssid.SSID_len = MIN(sizeof(g_ssid.SSID), dwrq->length); -#else - g_ssid.SSID_len = MIN(sizeof(g_ssid.SSID), dwrq->length-1); -#endif - memcpy(g_ssid.SSID, extra, g_ssid.SSID_len); - -#ifdef CONFIG_PRESCANNED - memcpy(join_params->ssid.SSID, g_ssid.SSID, g_ssid.SSID_len); - join_params->ssid.SSID_len = g_ssid.SSID_len; - - if (check_prescan(join_params, &join_params_size)) { - if ((error = dev_wlc_ioctl(dev, WLC_SET_SSID, - join_params, join_params_size))) { - WL_ERROR(("Invalid ioctl data=%d\n", error)); - kfree(join_params); - return error; - } - kfree(join_params); - return 0; - } else { - WL_ERROR(("No matched found\n Trying to join to specific channel\n")); - } -#endif - } else { - - g_ssid.SSID_len = 0; - } - g_ssid.SSID_len = htod32(g_ssid.SSID_len); - - - memset(join_params, 0, sizeof(*join_params)); - join_params_size = sizeof(join_params->ssid); - - memcpy(join_params->ssid.SSID, g_ssid.SSID, g_ssid.SSID_len); - join_params->ssid.SSID_len = htod32(g_ssid.SSID_len); - memcpy(&(join_params->params.bssid), ðer_bcast, ETHER_ADDR_LEN); - - - - wl_iw_ch_to_chanspec(g_wl_iw_params.target_channel, join_params, &join_params_size); - - if ((error = dev_wlc_ioctl(dev, WLC_SET_SSID, join_params, join_params_size))) { - WL_ERROR(("Invalid ioctl data=%d\n", error)); - return error; - } - - if (g_ssid.SSID_len) { - WL_ERROR(("%s: join SSID=%s ch=%d\n", __FUNCTION__, - g_ssid.SSID, g_wl_iw_params.target_channel)); - } - kfree(join_params); - return 0; -} - -static int -wl_iw_get_essid( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wlc_ssid_t ssid; - int error; - - WL_TRACE(("%s: SIOCGIWESSID\n", dev->name)); - - if (!extra) - return -EINVAL; - - if ((error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid)))) { - WL_ERROR(("Error getting the SSID\n")); - return error; - } - - ssid.SSID_len = dtoh32(ssid.SSID_len); - - - memcpy(extra, ssid.SSID, ssid.SSID_len); - - dwrq->length = ssid.SSID_len; - - dwrq->flags = 1; - - return 0; -} - -static int -wl_iw_set_nick( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_iw_t *iw = NETDEV_PRIV(dev); - - WL_TRACE(("%s: SIOCSIWNICKN\n", dev->name)); - - if (!extra) - return -EINVAL; - - - if (dwrq->length > sizeof(iw->nickname)) - return -E2BIG; - - memcpy(iw->nickname, extra, dwrq->length); - iw->nickname[dwrq->length - 1] = '\0'; - - return 0; -} - -static int -wl_iw_get_nick( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_iw_t *iw = NETDEV_PRIV(dev); - - WL_TRACE(("%s: SIOCGIWNICKN\n", dev->name)); - - if (!extra) - return -EINVAL; - - strcpy(extra, iw->nickname); - dwrq->length = strlen(extra) + 1; - - return 0; -} - -static int -wl_iw_set_rate( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - wl_rateset_t rateset; - int error, rate, i, error_bg, error_a; - - WL_TRACE(("%s: SIOCSIWRATE\n", dev->name)); - - - if ((error = dev_wlc_ioctl(dev, WLC_GET_CURR_RATESET, &rateset, sizeof(rateset)))) - return error; - - rateset.count = dtoh32(rateset.count); - - if (vwrq->value < 0) { - - rate = rateset.rates[rateset.count - 1] & 0x7f; - } else if (vwrq->value < rateset.count) { - - rate = rateset.rates[vwrq->value] & 0x7f; - } else { - - rate = vwrq->value / 500000; - } - - if (vwrq->fixed) { - - error_bg = dev_wlc_intvar_set(dev, "bg_rate", rate); - error_a = dev_wlc_intvar_set(dev, "a_rate", rate); - - if (error_bg && error_a) - return (error_bg | error_a); - } else { - - - error_bg = dev_wlc_intvar_set(dev, "bg_rate", 0); - - error_a = dev_wlc_intvar_set(dev, "a_rate", 0); - - if (error_bg && error_a) - return (error_bg | error_a); - - - for (i = 0; i < rateset.count; i++) - if ((rateset.rates[i] & 0x7f) > rate) - break; - rateset.count = htod32(i); - - - if ((error = dev_wlc_ioctl(dev, WLC_SET_RATESET, &rateset, sizeof(rateset)))) - return error; - } - - return 0; -} - -static int -wl_iw_get_rate( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, rate; - - WL_TRACE(("%s: SIOCGIWRATE\n", dev->name)); - - - if ((error = dev_wlc_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate)))) - return error; - rate = dtoh32(rate); - vwrq->value = rate * 500000; - - return 0; -} - -static int -wl_iw_set_rts( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, rts; - - WL_TRACE(("%s: SIOCSIWRTS\n", dev->name)); - - if (vwrq->disabled) - rts = DOT11_DEFAULT_RTS_LEN; - else if (vwrq->value < 0 || vwrq->value > DOT11_DEFAULT_RTS_LEN) - return -EINVAL; - else - rts = vwrq->value; - - if ((error = dev_wlc_intvar_set(dev, "rtsthresh", rts))) - return error; - - return 0; -} - -static int -wl_iw_get_rts( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, rts; - - WL_TRACE(("%s: SIOCGIWRTS\n", dev->name)); - - if ((error = dev_wlc_intvar_get(dev, "rtsthresh", &rts))) - return error; - - vwrq->value = rts; - vwrq->disabled = (rts >= DOT11_DEFAULT_RTS_LEN); - vwrq->fixed = 1; - - return 0; -} - -static int -wl_iw_set_frag( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, frag; - - WL_TRACE(("%s: SIOCSIWFRAG\n", dev->name)); - - if (vwrq->disabled) - frag = DOT11_DEFAULT_FRAG_LEN; - else if (vwrq->value < 0 || vwrq->value > DOT11_DEFAULT_FRAG_LEN) - return -EINVAL; - else - frag = vwrq->value; - - if ((error = dev_wlc_intvar_set(dev, "fragthresh", frag))) - return error; - - return 0; -} - -static int -wl_iw_get_frag( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, fragthreshold; - - WL_TRACE(("%s: SIOCGIWFRAG\n", dev->name)); - - if ((error = dev_wlc_intvar_get(dev, "fragthresh", &fragthreshold))) - return error; - - vwrq->value = fragthreshold; - vwrq->disabled = (fragthreshold >= DOT11_DEFAULT_FRAG_LEN); - vwrq->fixed = 1; - - return 0; -} - -static int -wl_iw_set_txpow( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, disable; - uint16 txpwrmw; - WL_TRACE(("%s: SIOCSIWTXPOW\n", dev->name)); - - - disable = vwrq->disabled ? WL_RADIO_SW_DISABLE : 0; - disable += WL_RADIO_SW_DISABLE << 16; - - disable = htod32(disable); - if ((error = dev_wlc_ioctl(dev, WLC_SET_RADIO, &disable, sizeof(disable)))) - return error; - - - if (disable & WL_RADIO_SW_DISABLE) - return 0; - - - if (!(vwrq->flags & IW_TXPOW_MWATT)) - return -EINVAL; - - - if (vwrq->value < 0) - return 0; - - if (vwrq->value > 0xffff) txpwrmw = 0xffff; - else txpwrmw = (uint16)vwrq->value; - - - error = dev_wlc_intvar_set(dev, "qtxpower", (int)(bcm_mw_to_qdbm(txpwrmw))); - return error; -} - -static int -wl_iw_get_txpow( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, disable, txpwrdbm; - uint8 result; - - WL_TRACE(("%s: SIOCGIWTXPOW\n", dev->name)); - - if ((error = dev_wlc_ioctl(dev, WLC_GET_RADIO, &disable, sizeof(disable))) || - (error = dev_wlc_intvar_get(dev, "qtxpower", &txpwrdbm))) - return error; - - disable = dtoh32(disable); - result = (uint8)(txpwrdbm & ~WL_TXPWR_OVERRIDE); - vwrq->value = (int32)bcm_qdbm_to_mw(result); - vwrq->fixed = 0; - vwrq->disabled = (disable & (WL_RADIO_SW_DISABLE | WL_RADIO_HW_DISABLE)) ? 1 : 0; - vwrq->flags = IW_TXPOW_MWATT; - - return 0; -} - -#if WIRELESS_EXT > 10 -static int -wl_iw_set_retry( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, lrl, srl; - - WL_TRACE(("%s: SIOCSIWRETRY\n", dev->name)); - - - if (vwrq->disabled || (vwrq->flags & IW_RETRY_LIFETIME)) - return -EINVAL; - - - if (vwrq->flags & IW_RETRY_LIMIT) { - - -#if WIRELESS_EXT > 20 - if ((vwrq->flags & IW_RETRY_LONG) ||(vwrq->flags & IW_RETRY_MAX) || - !((vwrq->flags & IW_RETRY_SHORT) || (vwrq->flags & IW_RETRY_MIN))) { -#else - if ((vwrq->flags & IW_RETRY_MAX) || !(vwrq->flags & IW_RETRY_MIN)) { -#endif - lrl = htod32(vwrq->value); - if ((error = dev_wlc_ioctl(dev, WLC_SET_LRL, &lrl, sizeof(lrl)))) - return error; - } - - -#if WIRELESS_EXT > 20 - if ((vwrq->flags & IW_RETRY_SHORT) ||(vwrq->flags & IW_RETRY_MIN) || - !((vwrq->flags & IW_RETRY_LONG) || (vwrq->flags & IW_RETRY_MAX))) { -#else - if ((vwrq->flags & IW_RETRY_MIN) || !(vwrq->flags & IW_RETRY_MAX)) { -#endif - srl = htod32(vwrq->value); - if ((error = dev_wlc_ioctl(dev, WLC_SET_SRL, &srl, sizeof(srl)))) - return error; - } - } - return 0; -} - -static int -wl_iw_get_retry( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, lrl, srl; - - WL_TRACE(("%s: SIOCGIWRETRY\n", dev->name)); - - vwrq->disabled = 0; - - - if ((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) - return -EINVAL; - - - if ((error = dev_wlc_ioctl(dev, WLC_GET_LRL, &lrl, sizeof(lrl))) || - (error = dev_wlc_ioctl(dev, WLC_GET_SRL, &srl, sizeof(srl)))) - return error; - - lrl = dtoh32(lrl); - srl = dtoh32(srl); - - - if (vwrq->flags & IW_RETRY_MAX) { - vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; - vwrq->value = lrl; - } else { - vwrq->flags = IW_RETRY_LIMIT; - vwrq->value = srl; - if (srl != lrl) - vwrq->flags |= IW_RETRY_MIN; - } - - return 0; -} -#endif - -static int -wl_iw_set_encode( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_wsec_key_t key; - int error, val, wsec; - - WL_TRACE(("%s: SIOCSIWENCODE index %d, len %d, flags %04x (%s%s%s%s%s)\n", - dev->name, dwrq->flags & IW_ENCODE_INDEX, dwrq->length, dwrq->flags, - dwrq->flags & IW_ENCODE_NOKEY ? "NOKEY" : "", - dwrq->flags & IW_ENCODE_DISABLED ? " DISABLED" : "", - dwrq->flags & IW_ENCODE_RESTRICTED ? " RESTRICTED" : "", - dwrq->flags & IW_ENCODE_OPEN ? " OPEN" : "", - dwrq->flags & IW_ENCODE_TEMP ? " TEMP" : "")); - - memset(&key, 0, sizeof(key)); - - if ((dwrq->flags & IW_ENCODE_INDEX) == 0) { - - for (key.index = 0; key.index < DOT11_MAX_DEFAULT_KEYS; key.index++) { - val = htod32(key.index); - if ((error = dev_wlc_ioctl(dev, WLC_GET_KEY_PRIMARY, &val, sizeof(val)))) - return error; - val = dtoh32(val); - if (val) - break; - } - - if (key.index == DOT11_MAX_DEFAULT_KEYS) - key.index = 0; - } else { - key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1; - if (key.index >= DOT11_MAX_DEFAULT_KEYS) - return -EINVAL; - } - - - if (!extra || !dwrq->length || (dwrq->flags & IW_ENCODE_NOKEY)) { - - val = htod32(key.index); - if ((error = dev_wlc_ioctl(dev, WLC_SET_KEY_PRIMARY, &val, sizeof(val)))) - return error; - } else { - key.len = dwrq->length; - - if (dwrq->length > sizeof(key.data)) - return -EINVAL; - - memcpy(key.data, extra, dwrq->length); - - key.flags = WL_PRIMARY_KEY; - switch (key.len) { - case WEP1_KEY_SIZE: - key.algo = CRYPTO_ALGO_WEP1; - break; - case WEP128_KEY_SIZE: - key.algo = CRYPTO_ALGO_WEP128; - break; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14) - case TKIP_KEY_SIZE: - key.algo = CRYPTO_ALGO_TKIP; - break; -#endif - case AES_KEY_SIZE: - key.algo = CRYPTO_ALGO_AES_CCM; - break; - default: - return -EINVAL; - } - - - swap_key_from_BE(&key); - if ((error = dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)))) - return error; - } - - - val = (dwrq->flags & IW_ENCODE_DISABLED) ? 0 : WEP_ENABLED; - - if ((error = dev_wlc_intvar_get(dev, "wsec", &wsec))) - return error; - - wsec &= ~(WEP_ENABLED); - wsec |= val; - - if ((error = dev_wlc_intvar_set(dev, "wsec", wsec))) - return error; - - - val = (dwrq->flags & IW_ENCODE_RESTRICTED) ? 1 : 0; - val = htod32(val); - if ((error = dev_wlc_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val)))) - return error; - - return 0; -} - -static int -wl_iw_get_encode( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_wsec_key_t key; - int error, val, wsec, auth; - - WL_TRACE(("%s: SIOCGIWENCODE\n", dev->name)); - - - bzero(&key, sizeof(wl_wsec_key_t)); - - if ((dwrq->flags & IW_ENCODE_INDEX) == 0) { - - for (key.index = 0; key.index < DOT11_MAX_DEFAULT_KEYS; key.index++) { - val = key.index; - if ((error = dev_wlc_ioctl(dev, WLC_GET_KEY_PRIMARY, &val, sizeof(val)))) - return error; - val = dtoh32(val); - if (val) - break; - } - } else - key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1; - - if (key.index >= DOT11_MAX_DEFAULT_KEYS) - key.index = 0; - - - - if ((error = dev_wlc_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec))) || - (error = dev_wlc_ioctl(dev, WLC_GET_AUTH, &auth, sizeof(auth)))) - return error; - - swap_key_to_BE(&key); - - wsec = dtoh32(wsec); - auth = dtoh32(auth); - - dwrq->length = MIN(DOT11_MAX_KEY_SIZE, key.len); - - - dwrq->flags = key.index + 1; - if (!(wsec & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED))) { - - dwrq->flags |= IW_ENCODE_DISABLED; - } - if (auth) { - - dwrq->flags |= IW_ENCODE_RESTRICTED; - } - - - if (dwrq->length && extra) - memcpy(extra, key.data, dwrq->length); - - return 0; -} - -static int -wl_iw_set_power( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, pm; - - WL_TRACE(("%s: SIOCSIWPOWER\n", dev->name)); - - pm = vwrq->disabled ? PM_OFF : PM_MAX; - - pm = htod32(pm); - if ((error = dev_wlc_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm)))) - return error; - - return 0; -} - -static int -wl_iw_get_power( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error, pm; - - WL_TRACE(("%s: SIOCGIWPOWER\n", dev->name)); - - if ((error = dev_wlc_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm)))) - return error; - - pm = dtoh32(pm); - vwrq->disabled = pm ? 0 : 1; - vwrq->flags = IW_POWER_ALL_R; - - return 0; -} - -#if WIRELESS_EXT > 17 -static int -wl_iw_set_wpaie( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *iwp, - char *extra -) -{ - - WL_TRACE(("%s: SIOCSIWGENIE\n", dev->name)); - - RETURN_IF_EXTRA_NULL(extra); - -#ifdef DHD_DEBUG - { - int i; - - for (i = 0; i < iwp->length; i++) - WL_TRACE(("%02X ", extra[i])); - WL_TRACE(("\n")); - } -#endif - - dev_wlc_bufvar_set(dev, "wpaie", extra, iwp->length); - - return 0; -} - -static int -wl_iw_get_wpaie( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *iwp, - char *extra -) -{ - WL_TRACE(("%s: SIOCGIWGENIE\n", dev->name)); - iwp->length = 64; - dev_wlc_bufvar_get(dev, "wpaie", extra, iwp->length); - return 0; -} - -static int -wl_iw_set_encodeext( - struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra -) -{ - wl_wsec_key_t key; - int error; - struct iw_encode_ext *iwe; - - WL_TRACE(("%s: SIOCSIWENCODEEXT\n", dev->name)); - - RETURN_IF_EXTRA_NULL(extra); - - memset(&key, 0, sizeof(key)); - iwe = (struct iw_encode_ext *)extra; - - - if (dwrq->flags & IW_ENCODE_DISABLED) { - - } - - - key.index = 0; - if (dwrq->flags & IW_ENCODE_INDEX) - key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1; - - key.len = iwe->key_len; - - - if (!ETHER_ISMULTI(iwe->addr.sa_data)) - bcopy((void *)&iwe->addr.sa_data, (char *)&key.ea, ETHER_ADDR_LEN); - - - if (key.len == 0) { - if (iwe->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { - WL_WSEC(("Changing the the primary Key to %d\n", key.index)); - - key.index = htod32(key.index); - error = dev_wlc_ioctl(dev, WLC_SET_KEY_PRIMARY, - &key.index, sizeof(key.index)); - if (error) - return error; - } - - else { - swap_key_from_BE(&key); - dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); - } - } - else { - if (iwe->key_len > sizeof(key.data)) - return -EINVAL; - - WL_WSEC(("Setting the key index %d\n", key.index)); - if (iwe->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { - WL_WSEC(("key is a Primary Key\n")); - key.flags = WL_PRIMARY_KEY; - } - - bcopy((void *)iwe->key, key.data, iwe->key_len); - - if (iwe->alg == IW_ENCODE_ALG_TKIP) { - uint8 keybuf[8]; - bcopy(&key.data[24], keybuf, sizeof(keybuf)); - bcopy(&key.data[16], &key.data[24], sizeof(keybuf)); - bcopy(keybuf, &key.data[16], sizeof(keybuf)); - } - - - if (iwe->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { - uchar *ivptr; - ivptr = (uchar *)iwe->rx_seq; - key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) | - (ivptr[3] << 8) | ivptr[2]; - key.rxiv.lo = (ivptr[1] << 8) | ivptr[0]; - key.iv_initialized = TRUE; - } - - switch (iwe->alg) { - case IW_ENCODE_ALG_NONE: - key.algo = CRYPTO_ALGO_OFF; - break; - case IW_ENCODE_ALG_WEP: - if (iwe->key_len == WEP1_KEY_SIZE) - key.algo = CRYPTO_ALGO_WEP1; - else - key.algo = CRYPTO_ALGO_WEP128; - break; - case IW_ENCODE_ALG_TKIP: - key.algo = CRYPTO_ALGO_TKIP; - break; - case IW_ENCODE_ALG_CCMP: - key.algo = CRYPTO_ALGO_AES_CCM; - break; - default: - break; - } - swap_key_from_BE(&key); - - dhd_wait_pend8021x(dev); - - error = dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); - if (error) - return error; - } - return 0; -} - -#if WIRELESS_EXT > 17 -struct { - pmkid_list_t pmkids; - pmkid_t foo[MAXPMKID-1]; -} pmkid_list; - -static int -wl_iw_set_pmksa( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - struct iw_pmksa *iwpmksa; - uint i; - int ret = 0; - char eabuf[ETHER_ADDR_STR_LEN]; - pmkid_t * pmkid_array = pmkid_list.pmkids.pmkid; - - WL_WSEC(("%s: SIOCSIWPMKSA\n", dev->name)); - - RETURN_IF_EXTRA_NULL(extra); - - iwpmksa = (struct iw_pmksa *)extra; - bzero((char *)eabuf, ETHER_ADDR_STR_LEN); - - if (iwpmksa->cmd == IW_PMKSA_FLUSH) { - WL_WSEC(("wl_iw_set_pmksa - IW_PMKSA_FLUSH\n")); - bzero((char *)&pmkid_list, sizeof(pmkid_list)); - } - - else if (iwpmksa->cmd == IW_PMKSA_REMOVE) { - { - pmkid_list_t pmkid, *pmkidptr; - uint j; - pmkidptr = &pmkid; - - bcopy(&iwpmksa->bssid.sa_data[0], &pmkidptr->pmkid[0].BSSID, - ETHER_ADDR_LEN); - bcopy(&iwpmksa->pmkid[0], &pmkidptr->pmkid[0].PMKID, WPA2_PMKID_LEN); - - WL_WSEC(("wl_iw_set_pmksa,IW_PMKSA_REMOVE - PMKID: %s = ", - bcm_ether_ntoa(&pmkidptr->pmkid[0].BSSID, - eabuf))); - for (j = 0; j < WPA2_PMKID_LEN; j++) - WL_WSEC(("%02x ", pmkidptr->pmkid[0].PMKID[j])); - WL_WSEC(("\n")); - } - - for (i = 0; i < pmkid_list.pmkids.npmkid; i++) - if (!bcmp(&iwpmksa->bssid.sa_data[0], &pmkid_array[i].BSSID, - ETHER_ADDR_LEN)) - break; - - if ((pmkid_list.pmkids.npmkid > 0) && (i < pmkid_list.pmkids.npmkid)) { - bzero(&pmkid_array[i], sizeof(pmkid_t)); - for (; i < (pmkid_list.pmkids.npmkid - 1); i++) { - bcopy(&pmkid_array[i+1].BSSID, - &pmkid_array[i].BSSID, - ETHER_ADDR_LEN); - bcopy(&pmkid_array[i+1].PMKID, - &pmkid_array[i].PMKID, - WPA2_PMKID_LEN); - } - pmkid_list.pmkids.npmkid--; - } - else - ret = -EINVAL; - } - - else if (iwpmksa->cmd == IW_PMKSA_ADD) { - for (i = 0; i < pmkid_list.pmkids.npmkid; i++) - if (!bcmp(&iwpmksa->bssid.sa_data[0], &pmkid_array[i].BSSID, - ETHER_ADDR_LEN)) - break; - if (i < MAXPMKID) { - bcopy(&iwpmksa->bssid.sa_data[0], - &pmkid_array[i].BSSID, - ETHER_ADDR_LEN); - bcopy(&iwpmksa->pmkid[0], &pmkid_array[i].PMKID, - WPA2_PMKID_LEN); - if (i == pmkid_list.pmkids.npmkid) - pmkid_list.pmkids.npmkid++; - } - else - ret = -EINVAL; - - { - uint j; - uint k; - k = pmkid_list.pmkids.npmkid; - WL_WSEC(("wl_iw_set_pmksa,IW_PMKSA_ADD - PMKID: %s = ", - bcm_ether_ntoa(&pmkid_array[k].BSSID, - eabuf))); - for (j = 0; j < WPA2_PMKID_LEN; j++) - WL_WSEC(("%02x ", pmkid_array[k].PMKID[j])); - WL_WSEC(("\n")); - } - } - WL_WSEC(("PRINTING pmkid LIST - No of elements %d", pmkid_list.pmkids.npmkid)); - for (i = 0; i < pmkid_list.pmkids.npmkid; i++) { - uint j; - WL_WSEC(("\nPMKID[%d]: %s = ", i, - bcm_ether_ntoa(&pmkid_array[i].BSSID, - eabuf))); - for (j = 0; j < WPA2_PMKID_LEN; j++) - WL_WSEC(("%02x ", pmkid_array[i].PMKID[j])); - } - WL_WSEC(("\n")); - - if (!ret) - ret = dev_wlc_bufvar_set(dev, "pmkid_info", (char *)&pmkid_list, - sizeof(pmkid_list)); - return ret; -} -#endif - -static int -wl_iw_get_encodeext( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - WL_TRACE(("%s: SIOCGIWENCODEEXT\n", dev->name)); - return 0; -} - - -static uint32 -wl_iw_create_wpaauth_wsec(struct net_device *dev) -{ - wl_iw_t *iw = NETDEV_PRIV(dev); - uint32 wsec; - - - if (iw->pcipher & (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104)) - wsec = WEP_ENABLED; - else if (iw->pcipher & IW_AUTH_CIPHER_TKIP) - wsec = TKIP_ENABLED; - else if (iw->pcipher & IW_AUTH_CIPHER_CCMP) - wsec = AES_ENABLED; - else - wsec = 0; - - - if (iw->gcipher & (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104)) - wsec |= WEP_ENABLED; - else if (iw->gcipher & IW_AUTH_CIPHER_TKIP) - wsec |= TKIP_ENABLED; - else if (iw->gcipher & IW_AUTH_CIPHER_CCMP) - wsec |= AES_ENABLED; - - - if (wsec == 0 && iw->privacy_invoked) - wsec = WEP_ENABLED; - - WL_INFORM(("%s: returning wsec of %d\n", __FUNCTION__, wsec)); - - return wsec; -} - -static int -wl_iw_set_wpaauth( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error = 0; - int paramid; - int paramval; - int val = 0; - wl_iw_t *iw = NETDEV_PRIV(dev); - - paramid = vwrq->flags & IW_AUTH_INDEX; - paramval = vwrq->value; - - WL_TRACE(("%s: SIOCSIWAUTH, %s(%d), paramval = 0x%0x\n", - dev->name, - paramid == IW_AUTH_WPA_VERSION ? "IW_AUTH_WPA_VERSION" : - paramid == IW_AUTH_CIPHER_PAIRWISE ? "IW_AUTH_CIPHER_PAIRWISE" : - paramid == IW_AUTH_CIPHER_GROUP ? "IW_AUTH_CIPHER_GROUP" : - paramid == IW_AUTH_KEY_MGMT ? "IW_AUTH_KEY_MGMT" : - paramid == IW_AUTH_TKIP_COUNTERMEASURES ? "IW_AUTH_TKIP_COUNTERMEASURES" : - paramid == IW_AUTH_DROP_UNENCRYPTED ? "IW_AUTH_DROP_UNENCRYPTED" : - paramid == IW_AUTH_80211_AUTH_ALG ? "IW_AUTH_80211_AUTH_ALG" : - paramid == IW_AUTH_WPA_ENABLED ? "IW_AUTH_WPA_ENABLED" : - paramid == IW_AUTH_RX_UNENCRYPTED_EAPOL ? "IW_AUTH_RX_UNENCRYPTED_EAPOL" : - paramid == IW_AUTH_ROAMING_CONTROL ? "IW_AUTH_ROAMING_CONTROL" : - paramid == IW_AUTH_PRIVACY_INVOKED ? "IW_AUTH_PRIVACY_INVOKED" : - "UNKNOWN", - paramid, paramval)); - -#if defined(SOFTAP) - if (ap_cfg_running) { - WL_TRACE(("%s: Not executed, reason -'SOFTAP is active'\n", __FUNCTION__)); - return 0; - } -#endif - - switch (paramid) { - case IW_AUTH_WPA_VERSION: - - if (paramval & IW_AUTH_WPA_VERSION_DISABLED) - val = WPA_AUTH_DISABLED; - else if (paramval & (IW_AUTH_WPA_VERSION_WPA)) - val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED; - else if (paramval & IW_AUTH_WPA_VERSION_WPA2) - val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED; - WL_ERROR(("%s: %d: setting wpa_auth to 0x%0x\n", __FUNCTION__, __LINE__, val)); - if ((error = dev_wlc_intvar_set(dev, "wpa_auth", val))) - return error; - break; - - case IW_AUTH_CIPHER_PAIRWISE: - iw->pcipher = paramval; - val = wl_iw_create_wpaauth_wsec(dev); - if ((error = dev_wlc_intvar_set(dev, "wsec", val))) - return error; - break; - - case IW_AUTH_CIPHER_GROUP: - iw->gcipher = paramval; - val = wl_iw_create_wpaauth_wsec(dev); - if ((error = dev_wlc_intvar_set(dev, "wsec", val))) - return error; - break; - - case IW_AUTH_KEY_MGMT: - if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val))) - return error; - - if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) { - if (paramval & IW_AUTH_KEY_MGMT_PSK) - val = WPA_AUTH_PSK; - else - val = WPA_AUTH_UNSPECIFIED; - if (paramval & 0x04) - val |= WPA2_AUTH_FT; - } - else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) { - if (paramval & IW_AUTH_KEY_MGMT_PSK) - val = WPA2_AUTH_PSK; - else - val = WPA2_AUTH_UNSPECIFIED; - if (paramval & 0x04) - val |= WPA2_AUTH_FT; - } - - else if (paramval & IW_AUTH_KEY_MGMT_PSK) { - if (iw->wpaversion == IW_AUTH_WPA_VERSION_WPA) - val = WPA_AUTH_PSK; - else if (iw->wpaversion == IW_AUTH_WPA_VERSION_WPA2) - val = WPA2_AUTH_PSK; - else - val = WPA_AUTH_DISABLED; - } else if (paramval & IW_AUTH_KEY_MGMT_802_1X) { - if (iw->wpaversion == IW_AUTH_WPA_VERSION_WPA) - val = WPA_AUTH_UNSPECIFIED; - else if (iw->wpaversion == IW_AUTH_WPA_VERSION_WPA2) - val = WPA2_AUTH_UNSPECIFIED; - else - val = WPA_AUTH_DISABLED; - } - else - val = WPA_AUTH_DISABLED; - - WL_INFORM(("%s: %d: setting wpa_auth to %d\n", __FUNCTION__, __LINE__, val)); - if ((error = dev_wlc_intvar_set(dev, "wpa_auth", val))) - return error; - break; - - case IW_AUTH_TKIP_COUNTERMEASURES: - dev_wlc_bufvar_set(dev, "tkip_countermeasures", (char *)¶mval, 1); - break; - - case IW_AUTH_80211_AUTH_ALG: - - WL_INFORM(("Setting the D11auth %d\n", paramval)); - if (paramval == IW_AUTH_ALG_OPEN_SYSTEM) - val = 0; - else if (paramval == IW_AUTH_ALG_SHARED_KEY) - val = 1; - else if (paramval == (IW_AUTH_ALG_OPEN_SYSTEM | IW_AUTH_ALG_SHARED_KEY)) - val = 2; - else - error = 1; - if (!error && (error = dev_wlc_intvar_set(dev, "auth", val))) - return error; - break; - - case IW_AUTH_WPA_ENABLED: - if (paramval == 0) { - iw->privacy_invoked = 0; - iw->pcipher = 0; - iw->gcipher = 0; - val = wl_iw_create_wpaauth_wsec(dev); - if ((error = dev_wlc_intvar_set(dev, "wsec", val))) - return error; - WL_INFORM(("%s: %d: setting wpa_auth to %d, wsec to %d\n", - __FUNCTION__, __LINE__, paramval, val)); - dev_wlc_intvar_set(dev, "wpa_auth", paramval); - return error; - } - - - break; - - case IW_AUTH_DROP_UNENCRYPTED: - if ((error = dev_wlc_intvar_set(dev, "wsec_restrict", paramval))) - return error; - break; - - case IW_AUTH_RX_UNENCRYPTED_EAPOL: - dev_wlc_bufvar_set(dev, "rx_unencrypted_eapol", (char *)¶mval, 1); - break; - -#if WIRELESS_EXT > 17 - case IW_AUTH_ROAMING_CONTROL: - WL_INFORM(("%s: IW_AUTH_ROAMING_CONTROL\n", __FUNCTION__)); - - break; - - case IW_AUTH_PRIVACY_INVOKED: - iw->privacy_invoked = paramval; - val = wl_iw_create_wpaauth_wsec(dev); - if ((error = dev_wlc_intvar_set(dev, "wsec", val))) - return error; - break; - -#endif - default: - break; - } - return 0; -} -#define VAL_PSK(_val) (((_val) & WPA_AUTH_PSK) || ((_val) & WPA2_AUTH_PSK)) - -static int -wl_iw_get_wpaauth( - struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, - char *extra -) -{ - int error; - int paramid; - int paramval = 0; - int val; - wl_iw_t *iw = NETDEV_PRIV(dev); - - WL_TRACE(("%s: SIOCGIWAUTH\n", dev->name)); - - paramid = vwrq->flags & IW_AUTH_INDEX; - - switch (paramid) { - case IW_AUTH_WPA_VERSION: - paramval = iw->wpaversion; - break; - - case IW_AUTH_CIPHER_PAIRWISE: - paramval = iw->pcipher; - break; - - case IW_AUTH_CIPHER_GROUP: - paramval = iw->gcipher; - break; - - case IW_AUTH_KEY_MGMT: - - if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val))) - return error; - if (VAL_PSK(val)) - paramval = IW_AUTH_KEY_MGMT_PSK; - else - paramval = IW_AUTH_KEY_MGMT_802_1X; - - break; - - case IW_AUTH_TKIP_COUNTERMEASURES: - dev_wlc_bufvar_get(dev, "tkip_countermeasures", (char *)¶mval, 1); - break; - - case IW_AUTH_DROP_UNENCRYPTED: - dev_wlc_intvar_get(dev, "wsec_restrict", ¶mval); - break; - - case IW_AUTH_RX_UNENCRYPTED_EAPOL: - dev_wlc_bufvar_get(dev, "rx_unencrypted_eapol", (char *)¶mval, 1); - break; - - case IW_AUTH_80211_AUTH_ALG: - - if ((error = dev_wlc_intvar_get(dev, "auth", &val))) - return error; - if (!val) - paramval = IW_AUTH_ALG_OPEN_SYSTEM; - else - paramval = IW_AUTH_ALG_SHARED_KEY; - break; - case IW_AUTH_WPA_ENABLED: - if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val))) - return error; - if (val) - paramval = TRUE; - else - paramval = FALSE; - break; -#if WIRELESS_EXT > 17 - case IW_AUTH_ROAMING_CONTROL: - WL_ERROR(("%s: IW_AUTH_ROAMING_CONTROL\n", __FUNCTION__)); - - break; - case IW_AUTH_PRIVACY_INVOKED: - paramval = iw->privacy_invoked; - break; - -#endif - } - vwrq->value = paramval; - return 0; -} -#endif - - -#ifdef SOFTAP - -static int ap_macmode = MACLIST_MODE_DISABLED; -static struct mflist ap_black_list; - -static int -wl_iw_parse_wep(char *keystr, wl_wsec_key_t *key) -{ - char hex[] = "XX"; - unsigned char *data = key->data; - - switch (strlen(keystr)) { - case 5: - case 13: - case 16: - key->len = strlen(keystr); - memcpy(data, keystr, key->len + 1); - break; - case 12: - case 28: - case 34: - case 66: - - if (!strnicmp(keystr, "0x", 2)) - keystr += 2; - else - return -1; - - case 10: - case 26: - case 32: - case 64: - key->len = strlen(keystr) / 2; - while (*keystr) { - strncpy(hex, keystr, 2); - *data++ = (char) bcm_strtoul(hex, NULL, 16); - keystr += 2; - } - break; - default: - return -1; - } - - switch (key->len) { - case 5: - key->algo = CRYPTO_ALGO_WEP1; - break; - case 13: - key->algo = CRYPTO_ALGO_WEP128; - break; - case 16: - - key->algo = CRYPTO_ALGO_AES_CCM; - break; - case 32: - key->algo = CRYPTO_ALGO_TKIP; - break; - default: - return -1; - } - - - key->flags |= WL_PRIMARY_KEY; - - return 0; -} - -#ifdef EXT_WPA_CRYPTO -#define SHA1HashSize 20 -extern void pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len, - int iterations, u8 *buf, size_t buflen); - -#else - -#define SHA1HashSize 20 -static int -pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len, - int iterations, u8 *buf, size_t buflen) -{ - WL_ERROR(("WARNING: %s is not implemented !!!\n", __FUNCTION__)); - return -1; -} - -#endif - - -static int -dev_iw_write_cfg1_bss_var(struct net_device *dev, int val) -{ - struct { - int cfg; - int val; - } bss_setbuf; - - int bss_set_res; - char smbuf[WLC_IOCTL_SMLEN]; - memset(smbuf, 0, sizeof(smbuf)); - - bss_setbuf.cfg = 1; - bss_setbuf.val = val; - - bss_set_res = dev_iw_iovar_setbuf(dev, "bss", - &bss_setbuf, sizeof(bss_setbuf), smbuf, sizeof(smbuf)); - WL_TRACE(("%s: bss_set_result:%d set with %d\n", __FUNCTION__, bss_set_res, val)); - - return bss_set_res; -} - - - -#ifndef AP_ONLY -static int -wl_bssiovar_mkbuf( - const char *iovar, - int bssidx, - void *param, - int paramlen, - void *bufptr, - int buflen, - int *perr) -{ - const char *prefix = "bsscfg:"; - int8* p; - uint prefixlen; - uint namelen; - uint iolen; - - prefixlen = strlen(prefix); - namelen = strlen(iovar) + 1; - iolen = prefixlen + namelen + sizeof(int) + paramlen; - - - if (buflen < 0 || iolen > (uint)buflen) { - *perr = BCME_BUFTOOSHORT; - return 0; - } - - p = (int8*)bufptr; - - - memcpy(p, prefix, prefixlen); - p += prefixlen; - - - memcpy(p, iovar, namelen); - p += namelen; - - - bssidx = htod32(bssidx); - memcpy(p, &bssidx, sizeof(int32)); - p += sizeof(int32); - - - if (paramlen) - memcpy(p, param, paramlen); - - *perr = 0; - return iolen; -} -#endif - - - - -#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base)) - - -#if defined(CSCAN) - - - -static int -wl_iw_combined_scan_set(struct net_device *dev, wlc_ssid_t* ssids_local, int nssid, int nchan) -{ - int params_size = WL_SCAN_PARAMS_FIXED_SIZE + WL_NUMCHANNELS * sizeof(uint16); - int err = 0; - char *p; - int i; - iscan_info_t *iscan = g_iscan; - - WL_TRACE(("%s nssid=%d nchan=%d\n", __FUNCTION__, nssid, nchan)); - - if ((!dev) && (!g_iscan) && (!iscan->iscan_ex_params_p)) { - WL_ERROR(("%s error exit\n", __FUNCTION__)); - err = -1; - goto exit; - } - -#ifdef PNO_SUPPORT - - if (dhd_dev_get_pno_status(dev)) { - WL_ERROR(("%s: Scan called when PNO is active\n", __FUNCTION__)); - } -#endif - - params_size += WL_SCAN_PARAMS_SSID_MAX * sizeof(wlc_ssid_t); - - - if (nssid > 0) { - i = OFFSETOF(wl_scan_params_t, channel_list) + nchan * sizeof(uint16); - i = ROUNDUP(i, sizeof(uint32)); - if (i + nssid * sizeof(wlc_ssid_t) > params_size) { - printf("additional ssids exceed params_size\n"); - err = -1; - goto exit; - } - - p = ((char*)&iscan->iscan_ex_params_p->params) + i; - memcpy(p, ssids_local, nssid * sizeof(wlc_ssid_t)); - p += nssid * sizeof(wlc_ssid_t); - } else { - p = (char*)iscan->iscan_ex_params_p->params.channel_list + nchan * sizeof(uint16); - } - - - iscan->iscan_ex_params_p->params.channel_num = - htod32((nssid << WL_SCAN_PARAMS_NSSID_SHIFT) | - (nchan & WL_SCAN_PARAMS_COUNT_MASK)); - - nssid = (uint) - ((iscan->iscan_ex_params_p->params.channel_num >> WL_SCAN_PARAMS_NSSID_SHIFT) & - WL_SCAN_PARAMS_COUNT_MASK); - - - params_size = (int) (p - (char*)iscan->iscan_ex_params_p + nssid * sizeof(wlc_ssid_t)); - iscan->iscan_ex_param_size = params_size; - - iscan->list_cur = iscan->list_hdr; - iscan->iscan_state = ISCAN_STATE_SCANING; - wl_iw_set_event_mask(dev); - mod_timer(&iscan->timer, jiffies + iscan->timer_ms*HZ/1000); - - iscan->timer_on = 1; - -#ifdef SCAN_DUMP - { - int i; - WL_SCAN(("\n### List of SSIDs to scan ###\n")); - for (i = 0; i < nssid; i++) { - if (!ssids_local[i].SSID_len) - WL_SCAN(("%d: Broadcast scan\n", i)); - else - WL_SCAN(("%d: scan for %s size =%d\n", i, - ssids_local[i].SSID, ssids_local[i].SSID_len)); - } - WL_SCAN(("### List of channels to scan ###\n")); - for (i = 0; i < nchan; i++) - { - WL_SCAN(("%d ", iscan->iscan_ex_params_p->params.channel_list[i])); - } - WL_SCAN(("\nnprobes=%d\n", iscan->iscan_ex_params_p->params.nprobes)); - WL_SCAN(("active_time=%d\n", iscan->iscan_ex_params_p->params.active_time)); - WL_SCAN(("passive_time=%d\n", iscan->iscan_ex_params_p->params.passive_time)); - WL_SCAN(("home_time=%d\n", iscan->iscan_ex_params_p->params.home_time)); - WL_SCAN(("scan_type=%d\n", iscan->iscan_ex_params_p->params.scan_type)); - WL_SCAN(("\n###################\n")); - } -#endif - - if (params_size > WLC_IOCTL_MEDLEN) { - WL_ERROR(("Set ISCAN for %s due to params_size=%d \n", - __FUNCTION__, params_size)); - err = -1; - } + if (!extra) + return -EINVAL; - if ((err = dev_iw_iovar_setbuf(dev, "iscan", iscan->iscan_ex_params_p, - iscan->iscan_ex_param_size, - iscan->ioctlbuf, sizeof(iscan->ioctlbuf)))) { - WL_TRACE(("Set ISCAN for %s failed with %d\n", __FUNCTION__, err)); - err = -1; - } + strcpy(extra, iw->nickname); + dwrq->length = strlen(extra) + 1; -exit: - return err; + return 0; } - -static int -iwpriv_set_cscan(struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, char *ext) +static int wl_iw_set_rate( + struct net_device *dev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra +) { - int res; - char *extra = NULL; - iscan_info_t *iscan = g_iscan; - wlc_ssid_t ssids_local[WL_SCAN_PARAMS_SSID_MAX]; - int nssid = 0; - int nchan = 0; - char *str_ptr; - - WL_TRACE(("%s: info->cmd:%x, info->flags:%x, u.data=0x%p, u.len=%d\n", - __FUNCTION__, info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length)); - - if (g_onoff == G_WLAN_SET_OFF) { - WL_TRACE(("%s: driver is not up yet after START\n", __FUNCTION__)); - return -ENODEV; - } + wl_rateset_t rateset; + int error, rate, i, error_bg, error_a; - if (wrqu->data.length == 0) { - WL_ERROR(("IWPRIV argument len = 0\n")); - return -EINVAL; - } + WL_TRACE(("%s: SIOCSIWRATE\n", dev->name)); - if (!iscan->iscan_ex_params_p) { - return -EFAULT; - } + + if ((error = dev_wlc_ioctl(dev, WLC_GET_CURR_RATESET, &rateset, sizeof(rateset)))) + return error; - if (!(extra = kmalloc(wrqu->data.length+1, GFP_KERNEL))) - return -ENOMEM; + rateset.count = dtoh32(rateset.count); - if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) { - res = -EFAULT; - goto exit_proc; + if (vwrq->value < 0) { + + rate = rateset.rates[rateset.count - 1] & 0x7f; + } else if (vwrq->value < rateset.count) { + + rate = rateset.rates[vwrq->value] & 0x7f; + } else { + + rate = vwrq->value / 500000; } - extra[wrqu->data.length] = 0; - WL_ERROR(("Got str param in iw_point:\n %s\n", extra)); - - str_ptr = extra; - - - if (strncmp(str_ptr, GET_SSID, strlen(GET_SSID))) { - WL_ERROR(("%s Error: extracting SSID='' string\n", __FUNCTION__)); - res = -EINVAL; - goto exit_proc; - } + if (vwrq->fixed) { + + error_bg = dev_wlc_intvar_set(dev, "bg_rate", rate); + error_a = dev_wlc_intvar_set(dev, "a_rate", rate); - str_ptr += strlen(GET_SSID); - nssid = wl_iw_parse_ssid_list(&str_ptr, ssids_local, nssid, - WL_SCAN_PARAMS_SSID_MAX); - if (nssid == -1) { - WL_ERROR(("%s wrong ssid list", __FUNCTION__)); - res = -EINVAL; - goto exit_proc; - } + if (error_bg && error_a) + return (error_bg | error_a); + } else { + + + error_bg = dev_wlc_intvar_set(dev, "bg_rate", 0); + + error_a = dev_wlc_intvar_set(dev, "a_rate", 0); - memset(iscan->iscan_ex_params_p, 0, iscan->iscan_ex_param_size); - ASSERT(iscan->iscan_ex_param_size < WLC_IOCTL_MAXLEN); + if (error_bg && error_a) + return (error_bg | error_a); - - wl_iw_iscan_prep(&iscan->iscan_ex_params_p->params, NULL); - iscan->iscan_ex_params_p->version = htod32(ISCAN_REQ_VERSION); - iscan->iscan_ex_params_p->action = htod16(WL_SCAN_ACTION_START); - iscan->iscan_ex_params_p->scan_duration = htod16(0); + + for (i = 0; i < rateset.count; i++) + if ((rateset.rates[i] & 0x7f) > rate) + break; + rateset.count = htod32(i); - - if ((nchan = wl_iw_parse_channel_list(&str_ptr, - &iscan->iscan_ex_params_p->params.channel_list[0], - WL_NUMCHANNELS)) == -1) { - WL_ERROR(("%s missing channel list\n", __FUNCTION__)); - res = -EINVAL; - goto exit_proc; + + if ((error = dev_wlc_ioctl(dev, WLC_SET_RATESET, &rateset, sizeof(rateset)))) + return error; } - - get_parameter_from_string(&str_ptr, - GET_NPROBE, PTYPE_INTDEC, - &iscan->iscan_ex_params_p->params.nprobes, 2); - - get_parameter_from_string(&str_ptr, GET_ACTIVE_ASSOC_DWELL, PTYPE_INTDEC, - &iscan->iscan_ex_params_p->params.active_time, 4); - - get_parameter_from_string(&str_ptr, GET_PASSIVE_ASSOC_DWELL, PTYPE_INTDEC, - &iscan->iscan_ex_params_p->params.passive_time, 4); + return 0; +} - get_parameter_from_string(&str_ptr, GET_HOME_DWELL, PTYPE_INTDEC, - &iscan->iscan_ex_params_p->params.home_time, 4); +static int wl_iw_get_rate( + struct net_device *dev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra +) +{ + int error, rate; - get_parameter_from_string(&str_ptr, GET_SCAN_TYPE, PTYPE_INTDEC, - &iscan->iscan_ex_params_p->params.scan_type, 1); + WL_TRACE(("%s: SIOCGIWRATE\n", dev->name)); - res = wl_iw_combined_scan_set(dev, ssids_local, nssid, nchan); - -exit_proc: - kfree(extra); + if ((error = dev_wlc_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate)))) + return error; + rate = dtoh32(rate); + vwrq->value = rate * 500000; - return res; + return 0; } - static int -wl_iw_set_cscan( +wl_iw_set_rts( struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, + struct iw_param *vwrq, char *extra ) { - int res = -1; - iscan_info_t *iscan = g_iscan; - wlc_ssid_t ssids_local[WL_SCAN_PARAMS_SSID_MAX]; - int nssid = 0; - int nchan = 0; - cscan_tlv_t *cscan_tlv_temp; - char type; - char *str_ptr; - int tlv_size_left; -#ifdef TLV_DEBUG - int i; - char tlv_in_example[] = { - 'C', 'S', 'C', 'A', 'N', ' ', - 0x53, 0x01, 0x00, 0x00, - 'S', - 0x00, - 'S', - 0x04, - 'B', 'R', 'C', 'M', - 'C', - 0x06, - 'P', - 0x94, - 0x11, - 'T', - 0x01 - }; -#endif - - WL_TRACE(("\n### %s: info->cmd:%x, info->flags:%x, u.data=0x%p, u.len=%d\n", - __FUNCTION__, info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length)); - - net_os_wake_lock(dev); - - if (g_onoff == G_WLAN_SET_OFF) { - WL_TRACE(("%s: driver is not up yet after START\n", __FUNCTION__)); - return -1; - } - - if (wrqu->data.length < (strlen(CSCAN_COMMAND) + sizeof(cscan_tlv_t))) { - WL_ERROR(("%s argument=%d less %d\n", __FUNCTION__, - wrqu->data.length, (int)(strlen(CSCAN_COMMAND) + sizeof(cscan_tlv_t)))); - return -1; - } - -#ifdef TLV_DEBUG - memcpy(extra, tlv_in_example, sizeof(tlv_in_example)); - wrqu->data.length = sizeof(tlv_in_example); - for (i = 0; i < wrqu->data.length; i++) - printf("%02X ", extra[i]); - printf("\n"); -#endif - - str_ptr = extra; - str_ptr += strlen(CSCAN_COMMAND); - tlv_size_left = wrqu->data.length - strlen(CSCAN_COMMAND); - - cscan_tlv_temp = (cscan_tlv_t *)str_ptr; - memset(ssids_local, 0, sizeof(ssids_local)); - - if ((cscan_tlv_temp->prefix == CSCAN_TLV_PREFIX) && - (cscan_tlv_temp->version == CSCAN_TLV_VERSION) && - (cscan_tlv_temp->subver == CSCAN_TLV_SUBVERSION)) - { - str_ptr += sizeof(cscan_tlv_t); - tlv_size_left -= sizeof(cscan_tlv_t); - - - if ((nssid = wl_iw_parse_ssid_list_tlv(&str_ptr, ssids_local, - WL_SCAN_PARAMS_SSID_MAX, &tlv_size_left)) <= 0) { - WL_ERROR(("SSID is not presented or corrupted ret=%d\n", nssid)); - goto exit_proc; - } - else { - - memset(iscan->iscan_ex_params_p, 0, iscan->iscan_ex_param_size); - - - wl_iw_iscan_prep(&iscan->iscan_ex_params_p->params, NULL); - iscan->iscan_ex_params_p->version = htod32(ISCAN_REQ_VERSION); - iscan->iscan_ex_params_p->action = htod16(WL_SCAN_ACTION_START); - iscan->iscan_ex_params_p->scan_duration = htod16(0); - - - while (tlv_size_left > 0) - { - type = str_ptr[0]; - switch (type) { - case CSCAN_TLV_TYPE_CHANNEL_IE: - - if ((nchan = wl_iw_parse_channel_list_tlv(&str_ptr, - &iscan->iscan_ex_params_p->params.channel_list[0], - WL_NUMCHANNELS, &tlv_size_left)) == -1) { - WL_ERROR(("%s missing channel list\n", - __FUNCTION__)); - goto exit_proc; - } - break; - case CSCAN_TLV_TYPE_NPROBE_IE: - if ((res = wl_iw_parse_data_tlv(&str_ptr, - &iscan->iscan_ex_params_p->params.nprobes, - sizeof(iscan->iscan_ex_params_p->params.nprobes), - type, sizeof(char), &tlv_size_left)) == -1) { - WL_ERROR(("%s return %d\n", - __FUNCTION__, res)); - goto exit_proc; - } - break; - case CSCAN_TLV_TYPE_ACTIVE_IE: - if ((res = wl_iw_parse_data_tlv(&str_ptr, - &iscan->iscan_ex_params_p->params.active_time, - sizeof(iscan->iscan_ex_params_p->params.active_time), - type, sizeof(short), &tlv_size_left)) == -1) { - WL_ERROR(("%s return %d\n", - __FUNCTION__, res)); - goto exit_proc; - } - break; - case CSCAN_TLV_TYPE_PASSIVE_IE: - if ((res = wl_iw_parse_data_tlv(&str_ptr, - &iscan->iscan_ex_params_p->params.passive_time, - sizeof(iscan->iscan_ex_params_p->params.passive_time), - type, sizeof(short), &tlv_size_left)) == -1) { - WL_ERROR(("%s return %d\n", - __FUNCTION__, res)); - goto exit_proc; - } - break; - case CSCAN_TLV_TYPE_HOME_IE: - if ((res = wl_iw_parse_data_tlv(&str_ptr, - &iscan->iscan_ex_params_p->params.home_time, - sizeof(iscan->iscan_ex_params_p->params.home_time), - type, sizeof(short), &tlv_size_left)) == -1) { - WL_ERROR(("%s return %d\n", - __FUNCTION__, res)); - goto exit_proc; - } - break; - case CSCAN_TLV_TYPE_STYPE_IE: - if ((res = wl_iw_parse_data_tlv(&str_ptr, - &iscan->iscan_ex_params_p->params.scan_type, - sizeof(iscan->iscan_ex_params_p->params.scan_type), - type, sizeof(char), &tlv_size_left)) == -1) { - WL_ERROR(("%s return %d\n", - __FUNCTION__, res)); - goto exit_proc; - } - break; + int error, rts; - default : - WL_ERROR(("%s get unkwown type %X\n", - __FUNCTION__, type)); - goto exit_proc; - break; - } - } - } - } - else { - WL_ERROR(("%s get wrong TLV command\n", __FUNCTION__)); - goto exit_proc; - } + WL_TRACE(("%s: SIOCSIWRTS\n", dev->name)); -#if defined(CONFIG_FIRST_SCAN) - if (g_first_broadcast_scan < BROADCAST_SCAN_FIRST_RESULT_CONSUMED) { - if (++g_first_counter_scans == MAX_ALLOWED_BLOCK_SCAN_FROM_FIRST_SCAN) { - - WL_ERROR(("%s Clean up First scan flag which is %d\n", - __FUNCTION__, g_first_broadcast_scan)); - g_first_broadcast_scan = BROADCAST_SCAN_FIRST_RESULT_CONSUMED; - } - else { - WL_ERROR(("%s Ignoring CSCAN : First Scan is not done yet %d\n", - __FUNCTION__, g_first_counter_scans)); - return -EBUSY; - } - } -#endif + if (vwrq->disabled) + rts = DOT11_DEFAULT_RTS_LEN; + else if (vwrq->value < 0 || vwrq->value > DOT11_DEFAULT_RTS_LEN) + return -EINVAL; + else + rts = vwrq->value; - - res = wl_iw_combined_scan_set(dev, ssids_local, nssid, nchan); + if ((error = dev_wlc_intvar_set(dev, "rtsthresh", rts))) + return error; -exit_proc: - net_os_wake_unlock(dev); - return res; + return 0; } -#endif - -#ifdef CONFIG_WPS2 static int -wl_iw_del_wps_probe_req_ie( +wl_iw_get_rts( struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, + struct iw_param *vwrq, char *extra ) { - int ret; - vndr_ie_setbuf_t *ie_delbuf; + int error, rts; - if (g_wps_probe_req_ie) { - ie_delbuf = (vndr_ie_setbuf_t *)(g_wps_probe_req_ie + strlen("vndr_ie ")); - strncpy(ie_delbuf->cmd, "del", 3); - ie_delbuf->cmd[3] = '\0'; + WL_TRACE(("%s: SIOCGIWRTS\n", dev->name)); - ret = dev_wlc_ioctl(dev, WLC_SET_VAR, g_wps_probe_req_ie, g_wps_probe_req_ie_len); - if (ret) { - WL_ERROR(("ioctl failed %d \n", ret)); - } + if ((error = dev_wlc_intvar_get(dev, "rtsthresh", &rts))) + return error; - kfree(g_wps_probe_req_ie); - g_wps_probe_req_ie = NULL; - g_wps_probe_req_ie_len = 0; - } + vwrq->value = rts; + vwrq->disabled = (rts >= DOT11_DEFAULT_RTS_LEN); + vwrq->fixed = 1; return 0; } static int -wl_iw_add_wps_probe_req_ie( +wl_iw_set_frag( struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, + struct iw_param *vwrq, char *extra ) { - char *str_ptr = NULL; - char *bufptr = NULL; - uint buflen, datalen, iecount, pktflag, iolen, total_len; - int ret = 0; - vndr_ie_setbuf_t *ie_setbuf = NULL; - - if (!g_wps_probe_req_ie) { - ret = -1; - str_ptr = extra; - str_ptr += WPS_PROBE_REQ_IE_CMD_LENGTH; - datalen = wrqu->data.length - WPS_PROBE_REQ_IE_CMD_LENGTH; - - - - buflen = sizeof(vndr_ie_setbuf_t) + datalen - sizeof(vndr_ie_t); - ie_setbuf = (vndr_ie_setbuf_t *)kmalloc(buflen, GFP_KERNEL); - if (!ie_setbuf) { - WL_ERROR(("memory alloc failure ie_setbuf\n")); - return ret; - } - - memset(ie_setbuf, 0x00, buflen); - - - strncpy(ie_setbuf->cmd, "add", VNDR_IE_CMD_LEN - 1); - ie_setbuf->cmd[VNDR_IE_CMD_LEN - 1] = '\0'; - - - iecount = htod32(1); - memcpy((void *)&ie_setbuf->vndr_ie_buffer.iecount, &iecount, sizeof(int)); - - - pktflag = 0x10; - memcpy((void *)&ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].pktflag, - &pktflag, sizeof(uint32)); - - memcpy((void *)&ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data, - str_ptr, datalen); - - total_len = strlen("vndr_ie ") + buflen; - bufptr = (char *)kmalloc(total_len, GFP_KERNEL); - if (!bufptr) { - WL_ERROR(("memory alloc failure bufptr\n")); - goto fail; - } - - iolen = bcm_mkiovar("vndr_ie", (char *)ie_setbuf, buflen, bufptr, total_len); - if (iolen == 0) { - WL_ERROR(("Buffer length is illegal\n")); - goto fail2; - } + int error, frag; - ret = dev_wlc_ioctl(dev, WLC_SET_VAR, bufptr, iolen); - if (ret) { - WL_ERROR(("ioctl failed\n")); - goto fail2; - } + WL_TRACE(("%s: SIOCSIWFRAG\n", dev->name)); - g_wps_probe_req_ie = (char *)kmalloc(iolen, GFP_KERNEL); - if (!g_wps_probe_req_ie) { - WL_ERROR(("memory alloc failure g_wps_probe_req_ie\n")); - goto fail2; - } + if (vwrq->disabled) + frag = DOT11_DEFAULT_FRAG_LEN; + else if (vwrq->value < 0 || vwrq->value > DOT11_DEFAULT_FRAG_LEN) + return -EINVAL; + else + frag = vwrq->value; - memcpy(g_wps_probe_req_ie, bufptr, iolen); - g_wps_probe_req_ie_len = iolen; - } + if ((error = dev_wlc_intvar_set(dev, "fragthresh", frag))) + return error; -fail2: - if (bufptr) { - kfree(bufptr); - bufptr = NULL; - } -fail: - if (ie_setbuf) { - kfree(ie_setbuf); - ie_setbuf = NULL; - } - return ret; + return 0; } -#endif - - -#ifdef SOFTAP -#ifndef AP_ONLY - static int -thr_wait_for_2nd_eth_dev(void *data) +wl_iw_get_frag( + struct net_device *dev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra +) { - wl_iw_t *iw; - int ret = 0; - unsigned long flags = 0; - - tsk_ctl_t *tsk_ctl = (tsk_ctl_t *)data; - struct net_device *dev = (struct net_device *)tsk_ctl->parent; - iw = *(wl_iw_t **)netdev_priv(dev); - - DAEMONIZE("wl0_eth_wthread"); + int error, fragthreshold; + WL_TRACE(("%s: SIOCGIWFRAG\n", dev->name)); - WL_SOFTAP(("\n>%s threda started:, PID:%x\n", __FUNCTION__, current->pid)); + if ((error = dev_wlc_intvar_get(dev, "fragthresh", &fragthreshold))) + return error; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - if (!iw) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - tsk_ctl->thr_pid = -1; - complete(&tsk_ctl->completed); - return -1; - } - DHD_OS_WAKE_LOCK(iw->pub); - complete(&tsk_ctl->completed); - if (down_timeout(&tsk_ctl->sema, msecs_to_jiffies(1000)) != 0) { -#else - if (down_interruptible(&tsk_ctl->sema) != 0) { -#endif - WL_ERROR(("\n%s: sap_eth_sema timeout \n", __FUNCTION__)); - ret = -1; - goto fail; - } + vwrq->value = fragthreshold; + vwrq->disabled = (fragthreshold >= DOT11_DEFAULT_FRAG_LEN); + vwrq->fixed = 1; - SMP_RD_BARRIER_DEPENDS(); - if (tsk_ctl->terminated) { - ret = -1; - goto fail; - } + return 0; +} - flags = dhd_os_spin_lock(iw->pub); - if (!ap_net_dev) { - WL_ERROR((" ap_net_dev is null !!!")); - ret = -1; - dhd_os_spin_unlock(iw->pub, flags); - goto fail; - } +static int +wl_iw_set_txpow( + struct net_device *dev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra +) +{ + int error, disable; + uint16 txpwrmw; + WL_TRACE(("%s: SIOCSIWTXPOW\n", dev->name)); - WL_SOFTAP(("\n>%s: Thread:'softap ethdev IF:%s is detected!'\n\n", - __FUNCTION__, ap_net_dev->name)); + + disable = vwrq->disabled ? WL_RADIO_SW_DISABLE : 0; + disable += WL_RADIO_SW_DISABLE << 16; - ap_cfg_running = TRUE; + disable = htod32(disable); + if ((error = dev_wlc_ioctl(dev, WLC_SET_RADIO, &disable, sizeof(disable)))) + return error; - dhd_os_spin_unlock(iw->pub, flags); - bcm_mdelay(500); + + if (disable & WL_RADIO_SW_DISABLE) + return 0; - wl_iw_send_priv_event(priv_dev, "AP_SET_CFG_OK"); + if (!(vwrq->flags & IW_TXPOW_MWATT)) + return -EINVAL; -fail: + + if (vwrq->value < 0) + return 0; - DHD_OS_WAKE_UNLOCK(iw->pub); + if (vwrq->value > 0xffff) txpwrmw = 0xffff; + else txpwrmw = (uint16)vwrq->value; - WL_SOFTAP(("\n>%s, thread completed\n", __FUNCTION__)); - complete_and_exit(&tsk_ctl->completed, 0); - return ret; + error = dev_wlc_intvar_set(dev, "qtxpower", (int)(bcm_mw_to_qdbm(txpwrmw))); + return error; } -#endif -#ifndef AP_ONLY -static int last_auto_channel = 6; -#endif static int -get_softap_auto_channel(struct net_device *dev, struct ap_profile *ap) +wl_iw_get_txpow( + struct net_device *dev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra +) { - int chosen = 0; - wl_uint32_list_t request; - int retry = 0; - int updown = 0; - int ret = 0; - wlc_ssid_t null_ssid; - int res = 0; -#ifndef AP_ONLY - int iolen = 0; - int mkvar_err = 0; - int bsscfg_index = 1; - char buf[WLC_IOCTL_SMLEN]; -#endif - WL_SOFTAP(("Enter %s\n", __FUNCTION__)); - -#ifndef AP_ONLY - if (ap_cfg_running) { - ap->channel = last_auto_channel; - return res; - } -#endif - - memset(&null_ssid, 0, sizeof(wlc_ssid_t)); - res |= dev_wlc_ioctl(dev, WLC_UP, &updown, sizeof(updown)); - -#ifdef AP_ONLY - res |= dev_wlc_ioctl(dev, WLC_SET_SSID, &null_ssid, sizeof(null_ssid)); -#else - - iolen = wl_bssiovar_mkbuf("ssid", bsscfg_index, (char *)(&null_ssid), - null_ssid.SSID_len+4, buf, sizeof(buf), &mkvar_err); - ASSERT(iolen); - res |= dev_wlc_ioctl(dev, WLC_SET_VAR, buf, iolen); - -#endif - - request.count = htod32(0); - ret = dev_wlc_ioctl(dev, WLC_START_CHANNEL_SEL, &request, sizeof(request)); - if (ret < 0) { - WL_ERROR(("can't start auto channel scan\n")); - goto fail; - } - - get_channel_retry: - bcm_mdelay(350); - - ret = dev_wlc_ioctl(dev, WLC_GET_CHANNEL_SEL, &chosen, sizeof(chosen)); - if (ret < 0 || dtoh32(chosen) == 0) { - if (retry++ < 15) { - goto get_channel_retry; - } else { - if (ret < 0) { - WL_ERROR(("can't get auto channel sel, err = %d, " - "chosen = 0x%04X\n", ret, (uint16)chosen)); - goto fail; - } else { - ap->channel = (uint16)last_auto_channel; - WL_ERROR(("auto channel sel timed out. we get channel %d\n", - ap->channel)); - } - } - } - - if (chosen) { - ap->channel = (uint16)chosen & 0x00FF; - WL_SOFTAP(("%s: Got auto channel = %d, attempt:%d\n", - __FUNCTION__, ap->channel, retry)); - } + int error, disable, txpwrdbm; + uint8 result; - if ((res = dev_wlc_ioctl(dev, WLC_DOWN, &updown, sizeof(updown))) < 0) { - WL_ERROR(("%s fail to set up err =%d\n", __FUNCTION__, res)); - goto fail; - } + WL_TRACE(("%s: SIOCGIWTXPOW\n", dev->name)); -#ifndef AP_ONLY - if (!res || !ret) - last_auto_channel = ap->channel; -#endif + if ((error = dev_wlc_ioctl(dev, WLC_GET_RADIO, &disable, sizeof(disable))) || + (error = dev_wlc_intvar_get(dev, "qtxpower", &txpwrdbm))) + return error; -fail : - if (ret < 0) { - WL_TRACE(("%s: return value %d\n", __FUNCTION__, ret)); - return ret; - } - return res; -} + disable = dtoh32(disable); + result = (uint8)(txpwrdbm & ~WL_TXPWR_OVERRIDE); + vwrq->value = (int32)bcm_qdbm_to_mw(result); + vwrq->fixed = 0; + vwrq->disabled = (disable & (WL_RADIO_SW_DISABLE | WL_RADIO_HW_DISABLE)) ? 1 : 0; + vwrq->flags = IW_TXPOW_MWATT; + return 0; +} +#if WIRELESS_EXT > 10 static int -set_ap_cfg(struct net_device *dev, struct ap_profile *ap) +wl_iw_set_retry( + struct net_device *dev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra +) { - int updown = 0; - int channel = 0; - - wlc_ssid_t ap_ssid; - int max_assoc = 8; - - int res = 0; - int apsta_var = 0; -#ifndef AP_ONLY - int mpc = 0; - int iolen = 0; - int mkvar_err = 0; - int bsscfg_index = 1; - char buf[WLC_IOCTL_SMLEN]; -#endif - - if (!dev) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - return -1; - } + int error, lrl, srl; - net_os_wake_lock(dev); - DHD_OS_MUTEX_LOCK(&wl_softap_lock); - - WL_SOFTAP(("wl_iw: set ap profile:\n")); - WL_SOFTAP((" ssid = '%s'\n", ap->ssid)); - WL_SOFTAP((" security = '%s'\n", ap->sec)); - if (ap->key[0] != '\0') - WL_SOFTAP((" key = '%s'\n", ap->key)); - WL_SOFTAP((" channel = %d\n", ap->channel)); - WL_SOFTAP((" max scb = %d\n", ap->max_scb)); - -#ifdef AP_ONLY - if (ap_cfg_running) { - wl_iw_softap_deassoc_stations(dev, NULL); - ap_cfg_running = FALSE; - } -#endif + WL_TRACE(("%s: SIOCSIWRETRY\n", dev->name)); - if (ap_cfg_running == FALSE) { - -#ifndef AP_ONLY - - - sema_init(&ap_eth_ctl.sema, 0); - - mpc = 0; - if ((res = dev_wlc_intvar_set(dev, "mpc", mpc))) { - WL_ERROR(("%s fail to set mpc\n", __FUNCTION__)); - goto fail; - } -#endif - - updown = 0; - if ((res = dev_wlc_ioctl(dev, WLC_DOWN, &updown, sizeof(updown)))) { - WL_ERROR(("%s fail to set updown\n", __FUNCTION__)); - goto fail; - } + if (vwrq->disabled || (vwrq->flags & IW_RETRY_LIFETIME)) + return -EINVAL; -#ifdef AP_ONLY + + if (vwrq->flags & IW_RETRY_LIMIT) { - apsta_var = 0; - if ((res = dev_wlc_ioctl(dev, WLC_SET_AP, &apsta_var, sizeof(apsta_var)))) { - WL_ERROR(("%s fail to set apsta_var 0\n", __FUNCTION__)); - goto fail; - } - apsta_var = 1; - if ((res = dev_wlc_ioctl(dev, WLC_SET_AP, &apsta_var, sizeof(apsta_var)))) { - WL_ERROR(("%s fail to set apsta_var 1\n", __FUNCTION__)); - goto fail; - } - res = dev_wlc_ioctl(dev, WLC_GET_AP, &apsta_var, sizeof(apsta_var)); +#if WIRELESS_EXT > 20 + if ((vwrq->flags & IW_RETRY_LONG) ||(vwrq->flags & IW_RETRY_MAX) || + !((vwrq->flags & IW_RETRY_SHORT) || (vwrq->flags & IW_RETRY_MIN))) { #else - - apsta_var = 1; - iolen = wl_bssiovar_mkbuf("apsta", - bsscfg_index, &apsta_var, sizeof(apsta_var)+4, - buf, sizeof(buf), &mkvar_err); - ASSERT(iolen); - if ((res = dev_wlc_ioctl(dev, WLC_SET_VAR, buf, iolen)) < 0) { - WL_ERROR(("%s fail to set apsta \n", __FUNCTION__)); - goto fail; - } - WL_TRACE(("\n>in %s: apsta set result: %d \n", __FUNCTION__, res)); - - - mpc = 0; - if ((res = dev_wlc_intvar_set(dev, "mpc", mpc))) { - WL_ERROR(("%s fail to set mpc\n", __FUNCTION__)); - goto fail; - } - - + if ((vwrq->flags & IW_RETRY_MAX) || !(vwrq->flags & IW_RETRY_MIN)) { #endif - updown = 1; - if ((res = dev_wlc_ioctl(dev, WLC_UP, &updown, sizeof(updown))) < 0) { - WL_ERROR(("%s fail to set apsta \n", __FUNCTION__)); - goto fail; + lrl = htod32(vwrq->value); + if ((error = dev_wlc_ioctl(dev, WLC_SET_LRL, &lrl, sizeof(lrl)))) + return error; } - - } else { - if (!ap_net_dev) { - WL_ERROR(("%s: ap_net_dev is null\n", __FUNCTION__)); - goto fail; - } - - res = wl_iw_softap_deassoc_stations(ap_net_dev, NULL); +#if WIRELESS_EXT > 20 + if ((vwrq->flags & IW_RETRY_SHORT) ||(vwrq->flags & IW_RETRY_MIN) || + !((vwrq->flags & IW_RETRY_LONG) || (vwrq->flags & IW_RETRY_MAX))) { +#else + if ((vwrq->flags & IW_RETRY_MIN) || !(vwrq->flags & IW_RETRY_MAX)) { +#endif - - if ((res = dev_iw_write_cfg1_bss_var(dev, 0)) < 0) { - WL_ERROR(("%s fail to set bss down\n", __FUNCTION__)); - goto fail; + srl = htod32(vwrq->value); + if ((error = dev_wlc_ioctl(dev, WLC_SET_SRL, &srl, sizeof(srl)))) + return error; } } + return 0; +} - if (strlen(ap->country_code)) { - WL_ERROR(("%s: Igonored: Country MUST be specified" - "COUNTRY command with \n", __FUNCTION__)); - } else { - WL_SOFTAP(("%s: Country code is not specified," - " will use Radio's default\n", - __FUNCTION__)); - - } - iolen = wl_bssiovar_mkbuf("closednet", - bsscfg_index, &ap->closednet, sizeof(ap->closednet)+4, - buf, sizeof(buf), &mkvar_err); - ASSERT(iolen); - if ((res = dev_wlc_ioctl(dev, WLC_SET_VAR, buf, iolen)) < 0) { - WL_ERROR(("%s failed to set 'closednet'for apsta \n", __FUNCTION__)); - goto fail; - } - - - if ((ap->channel == 0) && (get_softap_auto_channel(dev, ap) < 0)) { - ap->channel = 1; - WL_ERROR(("%s auto channel failed, use channel=%d\n", - __FUNCTION__, ap->channel)); - } +static int +wl_iw_get_retry( + struct net_device *dev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra +) +{ + int error, lrl, srl; - channel = ap->channel; - if ((res = dev_wlc_ioctl(dev, WLC_SET_CHANNEL, &channel, sizeof(channel)))) { - WL_ERROR(("%s fail to set channel\n", __FUNCTION__)); - } + WL_TRACE(("%s: SIOCGIWRETRY\n", dev->name)); + vwrq->disabled = 0; - if (ap_cfg_running == FALSE) { - updown = 0; - if ((res = dev_wlc_ioctl(dev, WLC_UP, &updown, sizeof(updown)))) { - WL_ERROR(("%s fail to set up\n", __FUNCTION__)); - goto fail; - } - } + + if ((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) + return -EINVAL; - max_assoc = ap->max_scb; - if ((res = dev_wlc_intvar_set(dev, "maxassoc", max_assoc))) { - WL_ERROR(("%s fail to set maxassoc\n", __FUNCTION__)); - goto fail; - } + + if ((error = dev_wlc_ioctl(dev, WLC_GET_LRL, &lrl, sizeof(lrl))) || + (error = dev_wlc_ioctl(dev, WLC_GET_SRL, &srl, sizeof(srl)))) + return error; - ap_ssid.SSID_len = strlen(ap->ssid); - strncpy(ap_ssid.SSID, ap->ssid, ap_ssid.SSID_len); + lrl = dtoh32(lrl); + srl = dtoh32(srl); -#ifdef AP_ONLY - if ((res = wl_iw_set_ap_security(dev, &my_ap)) != 0) { - WL_ERROR(("ERROR:%d in:%s, wl_iw_set_ap_security is skipped\n", - res, __FUNCTION__)); - goto fail; - } - wl_iw_send_priv_event(dev, "ASCII_CMD=AP_BSS_START"); - ap_cfg_running = TRUE; -#else - - iolen = wl_bssiovar_mkbuf("ssid", bsscfg_index, (char *)(&ap_ssid), - ap_ssid.SSID_len+4, buf, sizeof(buf), &mkvar_err); - ASSERT(iolen); - if ((res = dev_wlc_ioctl(dev, WLC_SET_VAR, buf, iolen)) != 0) { - WL_ERROR(("ERROR:%d in:%s, Security & BSS reconfiguration is skipped\n", - res, __FUNCTION__)); - goto fail; - } - if (ap_cfg_running == FALSE) { - - PROC_START(thr_wait_for_2nd_eth_dev, dev, &ap_eth_ctl, 0); + if (vwrq->flags & IW_RETRY_MAX) { + vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; + vwrq->value = lrl; } else { - ap_eth_ctl.thr_pid = -1; - - if (ap_net_dev == NULL) { - WL_ERROR(("%s ERROR: ap_net_dev is NULL !!!\n", __FUNCTION__)); - goto fail; - } - - WL_ERROR(("%s: %s Configure security & restart AP bss \n", - __FUNCTION__, ap_net_dev->name)); - - - if ((res = wl_iw_set_ap_security(ap_net_dev, &my_ap)) < 0) { - WL_ERROR(("%s fail to set security : %d\n", __FUNCTION__, res)); - goto fail; - } - - - if ((res = dev_iw_write_cfg1_bss_var(dev, 1)) < 0) { - WL_ERROR(("%s fail to set bss up\n", __FUNCTION__)); - goto fail; - } + vwrq->flags = IW_RETRY_LIMIT; + vwrq->value = srl; + if (srl != lrl) + vwrq->flags |= IW_RETRY_MIN; } -#endif -fail: - WL_SOFTAP(("%s exit with %d\n", __FUNCTION__, res)); - - DHD_OS_MUTEX_UNLOCK(&wl_softap_lock); - net_os_wake_unlock(dev); - return res; + return 0; } #endif - - static int -wl_iw_set_ap_security(struct net_device *dev, struct ap_profile *ap) +wl_iw_set_encode( + struct net_device *dev, + struct iw_request_info *info, + struct iw_point *dwrq, + char *extra +) { - int wsec = 0; - int wpa_auth = 0; - int res = 0; - int i; - char *ptr; -#ifdef AP_ONLY - int mpc = 0; - wlc_ssid_t ap_ssid; -#endif wl_wsec_key_t key; + int error, val, wsec; - WL_SOFTAP(("\nsetting SOFTAP security mode:\n")); - WL_SOFTAP(("wl_iw: set ap profile:\n")); - WL_SOFTAP((" ssid = '%s'\n", ap->ssid)); - WL_SOFTAP((" security = '%s'\n", ap->sec)); - if (ap->key[0] != '\0') - WL_SOFTAP((" key = '%s'\n", ap->key)); - WL_SOFTAP((" channel = %d\n", ap->channel)); - WL_SOFTAP((" max scb = %d\n", ap->max_scb)); - - - if (strnicmp(ap->sec, "open", strlen("open")) == 0) { - - - wsec = 0; - res = dev_wlc_intvar_set(dev, "wsec", wsec); - wpa_auth = WPA_AUTH_DISABLED; - res |= dev_wlc_intvar_set(dev, "wpa_auth", wpa_auth); - - WL_SOFTAP(("=====================\n")); - WL_SOFTAP((" wsec & wpa_auth set 'OPEN', result:&d %d\n", res)); - WL_SOFTAP(("=====================\n")); - - } else if (strnicmp(ap->sec, "wep", strlen("wep")) == 0) { - - - memset(&key, 0, sizeof(key)); - - wsec = WEP_ENABLED; - res = dev_wlc_intvar_set(dev, "wsec", wsec); - - key.index = 0; - if (wl_iw_parse_wep(ap->key, &key)) { - WL_SOFTAP(("wep key parse err!\n")); - return -1; - } - - key.index = htod32(key.index); - key.len = htod32(key.len); - key.algo = htod32(key.algo); - key.flags = htod32(key.flags); - - res |= dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); - - wpa_auth = WPA_AUTH_DISABLED; - res |= dev_wlc_intvar_set(dev, "wpa_auth", wpa_auth); - - WL_SOFTAP(("=====================\n")); - WL_SOFTAP((" wsec & auth set 'WEP', result:&d %d\n", res)); - WL_SOFTAP(("=====================\n")); - - } else if (strnicmp(ap->sec, "wpa2-psk", strlen("wpa2-psk")) == 0) { - - - - wsec_pmk_t psk; - size_t key_len; - - wsec = AES_ENABLED; - dev_wlc_intvar_set(dev, "wsec", wsec); + WL_TRACE(("%s: SIOCSIWENCODE\n", dev->name)); - key_len = strlen(ap->key); - if (key_len < WSEC_MIN_PSK_LEN || key_len > WSEC_MAX_PSK_LEN) { - WL_SOFTAP(("passphrase must be between %d and %d characters long\n", - WSEC_MIN_PSK_LEN, WSEC_MAX_PSK_LEN)); - return -1; - } + memset(&key, 0, sizeof(key)); + if ((dwrq->flags & IW_ENCODE_INDEX) == 0) { - if (key_len < WSEC_MAX_PSK_LEN) { - unsigned char output[2*SHA1HashSize]; - char key_str_buf[WSEC_MAX_PSK_LEN+1]; - - - memset(output, 0, sizeof(output)); - pbkdf2_sha1(ap->key, ap->ssid, strlen(ap->ssid), 4096, output, 32); - - ptr = key_str_buf; - for (i = 0; i < (WSEC_MAX_PSK_LEN/8); i++) { - - sprintf(ptr, "%02x%02x%02x%02x", (uint)output[i*4], - (uint)output[i*4+1], (uint)output[i*4+2], - (uint)output[i*4+3]); - ptr += 8; - } - WL_SOFTAP(("%s: passphase = %s\n", __FUNCTION__, key_str_buf)); - - psk.key_len = htod16((ushort)WSEC_MAX_PSK_LEN); - memcpy(psk.key, key_str_buf, psk.key_len); - } else { - psk.key_len = htod16((ushort) key_len); - memcpy(psk.key, ap->key, key_len); + for (key.index = 0; key.index < DOT11_MAX_DEFAULT_KEYS; key.index++) { + val = htod32(key.index); + if ((error = dev_wlc_ioctl(dev, WLC_GET_KEY_PRIMARY, &val, sizeof(val)))) + return error; + val = dtoh32(val); + if (val) + break; } - psk.flags = htod16(WSEC_PASSPHRASE); - dev_wlc_ioctl(dev, WLC_SET_WSEC_PMK, &psk, sizeof(psk)); + + if (key.index == DOT11_MAX_DEFAULT_KEYS) + key.index = 0; + } else { + key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1; + if (key.index >= DOT11_MAX_DEFAULT_KEYS) + return -EINVAL; + } - wpa_auth = WPA2_AUTH_PSK; - dev_wlc_intvar_set(dev, "wpa_auth", wpa_auth); + + wsec = (dwrq->flags & IW_ENCODE_DISABLED) ? 0 : WEP_ENABLED; - } else if (strnicmp(ap->sec, "wpa-psk", strlen("wpa-psk")) == 0) { + if ((error = dev_wlc_intvar_set(dev, "wsec", wsec))) + return error; + + if (!extra || !dwrq->length || (dwrq->flags & IW_ENCODE_NOKEY)) { - wsec_pmk_t psk; - size_t key_len; + val = htod32(key.index); + if ((error = dev_wlc_ioctl(dev, WLC_SET_KEY_PRIMARY, &val, sizeof(val)))) + return error; + } else { + key.len = dwrq->length; + + if (dwrq->length > sizeof(key.data)) + return -EINVAL; - wsec = TKIP_ENABLED; - res = dev_wlc_intvar_set(dev, "wsec", wsec); + memcpy(key.data, extra, dwrq->length); - key_len = strlen(ap->key); - if (key_len < WSEC_MIN_PSK_LEN || key_len > WSEC_MAX_PSK_LEN) { - WL_SOFTAP(("passphrase must be between %d and %d characters long\n", - WSEC_MIN_PSK_LEN, WSEC_MAX_PSK_LEN)); - return -1; + key.flags = WL_PRIMARY_KEY; + switch (key.len) { + case WEP1_KEY_SIZE: + key.algo = CRYPTO_ALGO_WEP1; + break; + case WEP128_KEY_SIZE: + key.algo = CRYPTO_ALGO_WEP128; + break; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14) + case TKIP_KEY_SIZE: + key.algo = CRYPTO_ALGO_TKIP; + break; +#endif + case AES_KEY_SIZE: + key.algo = CRYPTO_ALGO_AES_CCM; + break; + default: + return -EINVAL; } - if (key_len < WSEC_MAX_PSK_LEN) { - unsigned char output[2*SHA1HashSize]; - char key_str_buf[WSEC_MAX_PSK_LEN+1]; - bzero(output, 2*SHA1HashSize); - - WL_SOFTAP(("%s: do passhash...\n", __FUNCTION__)); - - pbkdf2_sha1(ap->key, ap->ssid, strlen(ap->ssid), 4096, output, 32); - - ptr = key_str_buf; - for (i = 0; i < (WSEC_MAX_PSK_LEN/8); i++) { - WL_SOFTAP(("[%02d]: %08x\n", i, *((unsigned int*)&output[i*4]))); - - sprintf(ptr, "%02x%02x%02x%02x", (uint)output[i*4], - (uint)output[i*4+1], (uint)output[i*4+2], - (uint)output[i*4+3]); - ptr += 8; - } - printk("%s: passphase = %s\n", __FUNCTION__, key_str_buf); - - psk.key_len = htod16((ushort)WSEC_MAX_PSK_LEN); - memcpy(psk.key, key_str_buf, psk.key_len); - } else { - psk.key_len = htod16((ushort) key_len); - memcpy(psk.key, ap->key, key_len); - } - - psk.flags = htod16(WSEC_PASSPHRASE); - res |= dev_wlc_ioctl(dev, WLC_SET_WSEC_PMK, &psk, sizeof(psk)); - - wpa_auth = WPA_AUTH_PSK; - res |= dev_wlc_intvar_set(dev, "wpa_auth", wpa_auth); - - WL_SOFTAP((" wsec & auth set 'wpa-psk' (TKIP), result:&d %d\n", res)); + swap_key_from_BE(&key); + if ((error = dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)))) + return error; } -#ifdef AP_ONLY - ap_ssid.SSID_len = strlen(ap->ssid); - strncpy(ap_ssid.SSID, ap->ssid, ap_ssid.SSID_len); - res |= dev_wlc_ioctl(dev, WLC_SET_SSID, &ap_ssid, sizeof(ap_ssid)); - mpc = 0; - res |= dev_wlc_intvar_set(dev, "mpc", mpc); - if (strnicmp(ap->sec, "wep", strlen("wep")) == 0) { - res |= dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); - } -#endif - return res; -} - + + val = (dwrq->flags & IW_ENCODE_RESTRICTED) ? 1 : 0; + val = htod32(val); + if ((error = dev_wlc_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val)))) + return error; + return 0; +} static int -get_parameter_from_string( - char **str_ptr, const char *token, - int param_type, void *dst, int param_max_len) +wl_iw_get_encode( + struct net_device *dev, + struct iw_request_info *info, + struct iw_point *dwrq, + char *extra +) { - char int_str[7] = "0"; - int parm_str_len; - char *param_str_begin; - char *param_str_end; - char *orig_str = *str_ptr; + wl_wsec_key_t key; + int error, val, wsec, auth; - if ((*str_ptr) && !strncmp(*str_ptr, token, strlen(token))) { + WL_TRACE(("%s: SIOCGIWENCODE\n", dev->name)); - strsep(str_ptr, "=,"); - param_str_begin = *str_ptr; - strsep(str_ptr, "=,"); + + bzero(&key, sizeof(wl_wsec_key_t)); - if (*str_ptr == NULL) { - - parm_str_len = strlen(param_str_begin); - } else { - param_str_end = *str_ptr-1; - parm_str_len = param_str_end - param_str_begin; + if ((dwrq->flags & IW_ENCODE_INDEX) == 0) { + + for (key.index = 0; key.index < DOT11_MAX_DEFAULT_KEYS; key.index++) { + val = key.index; + if ((error = dev_wlc_ioctl(dev, WLC_GET_KEY_PRIMARY, &val, sizeof(val)))) + return error; + val = dtoh32(val); + if (val) + break; } + } else + key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1; - WL_TRACE((" 'token:%s', len:%d, ", token, parm_str_len)); + if (key.index >= DOT11_MAX_DEFAULT_KEYS) + key.index = 0; - if (parm_str_len > param_max_len) { - WL_ERROR((" WARNING: extracted param len:%d is > MAX:%d\n", - parm_str_len, param_max_len)); + - parm_str_len = param_max_len; - } + if ((error = dev_wlc_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec))) || + (error = dev_wlc_ioctl(dev, WLC_GET_AUTH, &auth, sizeof(auth)))) + return error; - switch (param_type) { + swap_key_to_BE(&key); - case PTYPE_INTDEC: { - - int *pdst_int = dst; - char *eptr; + wsec = dtoh32(wsec); + auth = dtoh32(auth); + + dwrq->length = MIN(IW_ENCODING_TOKEN_MAX, key.len); - if (parm_str_len > sizeof(int_str)) - parm_str_len = sizeof(int_str); + + dwrq->flags = key.index + 1; + if (!(wsec & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED))) { + + dwrq->flags |= IW_ENCODE_DISABLED; + } + if (auth) { + + dwrq->flags |= IW_ENCODE_RESTRICTED; + } - memcpy(int_str, param_str_begin, parm_str_len); + + if (dwrq->length && extra) + memcpy(extra, key.data, dwrq->length); - *pdst_int = simple_strtoul(int_str, &eptr, 10); + return 0; +} - WL_TRACE((" written as integer:%d\n", *pdst_int)); - } - break; - case PTYPE_STR_HEX: { - u8 *buf = dst; - - param_max_len = param_max_len >> 1; - hstr_2_buf(param_str_begin, buf, param_max_len); - dhd_print_buf(buf, param_max_len, 0); - } - break; - default: - - memcpy(dst, param_str_begin, parm_str_len); - *((char *)dst + parm_str_len) = 0; - WL_ERROR((" written as a string:%s\n", (char *)dst)); - break; +static int +wl_iw_set_power( + struct net_device *dev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra +) +{ + int error, pm; - } + WL_TRACE(("%s: SIOCSIWPOWER\n", dev->name)); - return 0; - } else { - WL_ERROR(("\n %s: ERROR: can't find token:%s in str:%s \n", - __FUNCTION__, token, orig_str)); + pm = vwrq->disabled ? PM_OFF : PM_MAX; - return -1; - } + pm = htod32(pm); + if ((error = dev_wlc_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm)))) + return error; + + return 0; } -static int wl_iw_softap_deassoc_stations(struct net_device *dev, u8 *mac) +static int +wl_iw_get_power( + struct net_device *dev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra +) { - int i; - int res = 0; - char mac_buf[128] = {0}; - char z_mac[6] = {0, 0, 0, 0, 0, 0}; - char *sta_mac; - struct maclist *assoc_maclist = (struct maclist *) mac_buf; - bool deauth_all = FALSE; - - - if (mac == NULL) { - deauth_all = TRUE; - sta_mac = z_mac; - } else { - sta_mac = mac; - } - - memset(assoc_maclist, 0, sizeof(mac_buf)); - assoc_maclist->count = 8; + int error, pm; - res = dev_wlc_ioctl(dev, WLC_GET_ASSOCLIST, assoc_maclist, 128); - if (res != 0) { - WL_SOFTAP(("%s: Error:%d Couldn't get ASSOC List\n", __FUNCTION__, res)); - return res; - } + WL_TRACE(("%s: SIOCGIWPOWER\n", dev->name)); - if (assoc_maclist->count) - for (i = 0; i < assoc_maclist->count; i++) { - scb_val_t scbval; - scbval.val = htod32(1); - - bcopy(&assoc_maclist->ea[i], &scbval.ea, ETHER_ADDR_LEN); + if ((error = dev_wlc_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm)))) + return error; - if (deauth_all || (memcmp(&scbval.ea, sta_mac, ETHER_ADDR_LEN) == 0)) { - - WL_SOFTAP(("%s, deauth STA:%d \n", __FUNCTION__, i)); - res |= dev_wlc_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, - &scbval, sizeof(scb_val_t)); - } - } else WL_SOFTAP(("%s: No Stations \n", __FUNCTION__)); + pm = dtoh32(pm); + vwrq->disabled = pm ? 0 : 1; + vwrq->flags = IW_POWER_ALL_R; - if (res != 0) { - WL_ERROR(("%s: Error:%d\n", __FUNCTION__, res)); - } else if (assoc_maclist->count) { - - bcm_mdelay(200); - } - return res; + return 0; } - - +#if WIRELESS_EXT > 17 static int -iwpriv_softap_stop(struct net_device *dev, +wl_iw_set_wpaie( + struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, - char *ext) + struct iw_point *iwp, + char *extra +) { - int res = 0; +#if defined(BCMWAPI_WPI) + uchar buf[WLC_IOCTL_SMLEN] = {0}; + uchar *p = buf; + int wapi_ie_size; - WL_SOFTAP(("got iwpriv AP_BSS_STOP \n")); + WL_TRACE(("%s: SIOCSIWGENIE\n", dev->name)); - if ((!dev) && (!ap_net_dev)) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - return res; + if (extra[0] == DOT11_MNG_WAPI_ID) + { + wapi_ie_size = iwp->length; + memcpy(p, extra, iwp->length); + dev_wlc_bufvar_set(dev, "wapiie", buf, wapi_ie_size); } - - net_os_wake_lock(dev); - DHD_OS_MUTEX_LOCK(&wl_softap_lock); - - if ((ap_cfg_running == TRUE)) { -#ifdef AP_ONLY - wl_iw_softap_deassoc_stations(dev, NULL); -#else - wl_iw_softap_deassoc_stations(ap_net_dev, NULL); - if ((res = dev_iw_write_cfg1_bss_var(dev, 2)) < 0) - WL_ERROR(("%s failed to del BSS err = %d", __FUNCTION__, res)); + else #endif + dev_wlc_bufvar_set(dev, "wpaie", extra, iwp->length); - - bcm_mdelay(100); - - wrqu->data.length = 0; - ap_cfg_running = FALSE; - } else - WL_ERROR(("%s: was called when SoftAP is OFF : move on\n", __FUNCTION__)); - - WL_SOFTAP(("%s Done with %d\n", __FUNCTION__, res)); - DHD_OS_MUTEX_UNLOCK(&wl_softap_lock); - net_os_wake_unlock(dev); - - return res; + return 0; } - +static int +wl_iw_get_wpaie( + struct net_device *dev, + struct iw_request_info *info, + struct iw_point *iwp, + char *extra +) +{ + WL_TRACE(("%s: SIOCGIWGENIE\n", dev->name)); + iwp->length = 64; + dev_wlc_bufvar_get(dev, "wpaie", extra, iwp->length); + return 0; +} static int -iwpriv_fw_reload(struct net_device *dev, +wl_iw_set_encodeext( + struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, - char *ext) + struct iw_point *dwrq, + char *extra +) { - int ret = -1; - char extra[256]; - char *fwstr = fw_path ; + wl_wsec_key_t key; + int error; + struct iw_encode_ext *iwe; + + WL_TRACE(("%s: SIOCSIWENCODEEXT\n", dev->name)); - WL_SOFTAP(("current firmware_path[]=%s\n", fwstr)); + memset(&key, 0, sizeof(key)); + iwe = (struct iw_encode_ext *)extra; - WL_TRACE((">Got FW_RELOAD cmd:" - "info->cmd:%x, info->flags:%x, u.data:%p, u.len:%d, " - "fw_path:%p, len:%d \n", - info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length, fwstr, strlen(fwstr))); + + if (dwrq->flags & IW_ENCODE_DISABLED) { - if ((wrqu->data.length > 4) && (wrqu->data.length < sizeof(extra))) { - char *str_ptr; + } - if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) { - ret = -EFAULT; - goto exit_proc; - } + + key.index = 0; + if (dwrq->flags & IW_ENCODE_INDEX) + key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1; - - extra[wrqu->data.length] = 8; - str_ptr = extra; + key.len = iwe->key_len; - if (get_parameter_from_string(&str_ptr, - "FW_PATH=", PTYPE_STRING, fwstr, 255) != 0) { - WL_ERROR(("Error: extracting FW_PATH='' string\n")); - goto exit_proc; - } + + if (!ETHER_ISMULTI(iwe->addr.sa_data)) + bcopy((void *)&iwe->addr.sa_data, (char *)&key.ea, ETHER_ADDR_LEN); - if (strstr(fwstr, "apsta") != NULL) { - WL_SOFTAP(("GOT APSTA FIRMWARE\n")); - ap_fw_loaded = TRUE; - } else { - WL_SOFTAP(("GOT STA FIRMWARE\n")); - ap_fw_loaded = FALSE; + + if (key.len == 0) { + if (iwe->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { + WL_WSEC(("Changing the the primary Key to %d\n", key.index)); + + key.index = htod32(key.index); + error = dev_wlc_ioctl(dev, WLC_SET_KEY_PRIMARY, + &key.index, sizeof(key.index)); + if (error) + return error; + } + + else { + swap_key_from_BE(&key); + error = dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); + if (error) + return error; } - - WL_SOFTAP(("SET firmware_path[]=%s , str_p:%p\n", fwstr, fwstr)); - ret = 0; - } else { - WL_ERROR(("Error: ivalid param len:%d\n", wrqu->data.length)); } +#if (defined(BCMSUP_PSK) && defined(WLFBT)) + + else if (iwe->alg == IW_ENCODE_ALG_PMK) { + int j; + wsec_pmk_t pmk; + char keystring[WSEC_MAX_PSK_LEN + 1]; + char* charptr = keystring; + uint len; -exit_proc: - return ret; -} - -#ifdef SOFTAP + + for (j = 0; j < (WSEC_MAX_PSK_LEN / 2); j++) { + sprintf(charptr, "%02x", iwe->key[j]); + charptr += 2; + } + len = strlen(keystring); + pmk.key_len = htod16(len); + bcopy(keystring, pmk.key, len); + pmk.flags = htod16(WSEC_PASSPHRASE); -static int -iwpriv_wpasupp_loop_tst(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *ext) -{ - int res = 0; - char *params = NULL; + error = dev_wlc_ioctl(dev, WLC_SET_WSEC_PMK, &pmk, sizeof(pmk)); + if (error) + return error; + } +#endif - WL_TRACE((">Got IWPRIV wp_supp loopback cmd test:" - "info->cmd:%x, info->flags:%x, u.data:%p, u.len:%d\n", - info->cmd, info->flags, - wrqu->data.pointer, wrqu->data.length)); + else { + if (iwe->key_len > sizeof(key.data)) + return -EINVAL; - if (wrqu->data.length != 0) { + WL_WSEC(("Setting the key index %d\n", key.index)); + if (iwe->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { + WL_WSEC(("key is a Primary Key\n")); + key.flags = WL_PRIMARY_KEY; + } - if (!(params = kmalloc(wrqu->data.length+1, GFP_KERNEL))) - return -ENOMEM; + bcopy((void *)iwe->key, key.data, iwe->key_len); + if (iwe->alg == IW_ENCODE_ALG_TKIP) { + uint8 keybuf[8]; + bcopy(&key.data[24], keybuf, sizeof(keybuf)); + bcopy(&key.data[16], &key.data[24], sizeof(keybuf)); + bcopy(keybuf, &key.data[16], sizeof(keybuf)); + } - if (copy_from_user(params, wrqu->data.pointer, wrqu->data.length)) { - kfree(params); - return -EFAULT; + + if (iwe->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { + uchar *ivptr; + ivptr = (uchar *)iwe->rx_seq; + key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) | + (ivptr[3] << 8) | ivptr[2]; + key.rxiv.lo = (ivptr[1] << 8) | ivptr[0]; + key.iv_initialized = TRUE; } - params[wrqu->data.length] = 0; - WL_SOFTAP(("\n>> copied from user:\n %s\n", params)); - } else { - WL_ERROR(("ERROR param length is 0\n")); - return -EFAULT; - } + switch (iwe->alg) { + case IW_ENCODE_ALG_NONE: + key.algo = CRYPTO_ALGO_OFF; + break; + case IW_ENCODE_ALG_WEP: + if (iwe->key_len == WEP1_KEY_SIZE) + key.algo = CRYPTO_ALGO_WEP1; + else + key.algo = CRYPTO_ALGO_WEP128; + break; + case IW_ENCODE_ALG_TKIP: + key.algo = CRYPTO_ALGO_TKIP; + break; + case IW_ENCODE_ALG_CCMP: + key.algo = CRYPTO_ALGO_AES_CCM; + break; +#ifdef BCMWAPI_WPI + case IW_ENCODE_ALG_SM4: + key.algo = CRYPTO_ALGO_SMS4; + if (iwe->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { + key.flags &= ~WL_PRIMARY_KEY; + } + break; +#endif + default: + break; + } + swap_key_from_BE(&key); - - res = wl_iw_send_priv_event(dev, params); - kfree(params); + dhd_wait_pend8021x(dev); - return res; + error = dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); + if (error) + return error; + } + return 0; } -#endif +#if WIRELESS_EXT > 17 +struct { + pmkid_list_t pmkids; + pmkid_t foo[MAXPMKID-1]; +} pmkid_list; static int -iwpriv_en_ap_bss( +wl_iw_set_pmksa( struct net_device *dev, struct iw_request_info *info, - void *wrqu, - char *extra) + struct iw_param *vwrq, + char *extra +) { - int res = 0; + struct iw_pmksa *iwpmksa; + uint i; + char eabuf[ETHER_ADDR_STR_LEN]; + pmkid_t * pmkid_array = pmkid_list.pmkids.pmkid; - if (!dev) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - return -1; + WL_TRACE(("%s: SIOCSIWPMKSA\n", dev->name)); + iwpmksa = (struct iw_pmksa *)extra; + bzero((char *)eabuf, ETHER_ADDR_STR_LEN); + if (iwpmksa->cmd == IW_PMKSA_FLUSH) { + WL_TRACE(("wl_iw_set_pmksa - IW_PMKSA_FLUSH\n")); + bzero((char *)&pmkid_list, sizeof(pmkid_list)); } - - net_os_wake_lock(dev); - DHD_OS_MUTEX_LOCK(&wl_softap_lock); - - WL_TRACE(("%s: rcvd IWPRIV IOCTL: for dev:%s\n", __FUNCTION__, dev->name)); - - -#ifndef AP_ONLY - if ((res = wl_iw_set_ap_security(dev, &my_ap)) != 0) { - WL_ERROR((" %s ERROR setting SOFTAP security in :%d\n", __FUNCTION__, res)); + if (iwpmksa->cmd == IW_PMKSA_REMOVE) { + pmkid_list_t pmkid, *pmkidptr; + pmkidptr = &pmkid; + bcopy(&iwpmksa->bssid.sa_data[0], &pmkidptr->pmkid[0].BSSID, ETHER_ADDR_LEN); + bcopy(&iwpmksa->pmkid[0], &pmkidptr->pmkid[0].PMKID, WPA2_PMKID_LEN); + { + uint j; + WL_TRACE(("wl_iw_set_pmksa,IW_PMKSA_REMOVE - PMKID: %s = ", + bcm_ether_ntoa(&pmkidptr->pmkid[0].BSSID, + eabuf))); + for (j = 0; j < WPA2_PMKID_LEN; j++) + WL_TRACE(("%02x ", pmkidptr->pmkid[0].PMKID[j])); + WL_TRACE(("\n")); + } + for (i = 0; i < pmkid_list.pmkids.npmkid; i++) + if (!bcmp(&iwpmksa->bssid.sa_data[0], &pmkid_array[i].BSSID, + ETHER_ADDR_LEN)) + break; + for (; i < pmkid_list.pmkids.npmkid; i++) { + bcopy(&pmkid_array[i+1].BSSID, + &pmkid_array[i].BSSID, + ETHER_ADDR_LEN); + bcopy(&pmkid_array[i+1].PMKID, + &pmkid_array[i].PMKID, + WPA2_PMKID_LEN); + } + pmkid_list.pmkids.npmkid--; } - else { - - if ((res = dev_iw_write_cfg1_bss_var(dev, 1)) < 0) - WL_ERROR(("%s fail to set bss up err=%d\n", __FUNCTION__, res)); - else - - bcm_mdelay(100); + if (iwpmksa->cmd == IW_PMKSA_ADD) { + bcopy(&iwpmksa->bssid.sa_data[0], + &pmkid_array[pmkid_list.pmkids.npmkid].BSSID, + ETHER_ADDR_LEN); + bcopy(&iwpmksa->pmkid[0], &pmkid_array[pmkid_list.pmkids.npmkid].PMKID, + WPA2_PMKID_LEN); + { + uint j; + uint k; + k = pmkid_list.pmkids.npmkid; + BCM_REFERENCE(k); + WL_TRACE(("wl_iw_set_pmksa,IW_PMKSA_ADD - PMKID: %s = ", + bcm_ether_ntoa(&pmkid_array[k].BSSID, + eabuf))); + for (j = 0; j < WPA2_PMKID_LEN; j++) + WL_TRACE(("%02x ", pmkid_array[k].PMKID[j])); + WL_TRACE(("\n")); + } + pmkid_list.pmkids.npmkid++; } - -#endif - WL_SOFTAP(("%s done with res %d \n", __FUNCTION__, res)); - - DHD_OS_MUTEX_UNLOCK(&wl_softap_lock); - net_os_wake_unlock(dev); - - return res; + WL_TRACE(("PRINTING pmkid LIST - No of elements %d\n", pmkid_list.pmkids.npmkid)); + for (i = 0; i < pmkid_list.pmkids.npmkid; i++) { + uint j; + WL_TRACE(("PMKID[%d]: %s = ", i, + bcm_ether_ntoa(&pmkid_array[i].BSSID, + eabuf))); + for (j = 0; j < WPA2_PMKID_LEN; j++) + WL_TRACE(("%02x ", pmkid_array[i].PMKID[j])); + printf("\n"); + } + WL_TRACE(("\n")); + dev_wlc_bufvar_set(dev, "pmkid_info", (char *)&pmkid_list, sizeof(pmkid_list)); + return 0; } +#endif static int -get_assoc_sta_list(struct net_device *dev, char *buf, int len) -{ - - WL_TRACE(("%s: dev_wlc_ioctl(dev:%p, cmd:%d, buf:%p, len:%d)\n", - __FUNCTION__, dev, WLC_GET_ASSOCLIST, buf, len)); - - return dev_wlc_ioctl(dev, WLC_GET_ASSOCLIST, buf, len); - -} - - -void check_error(int res, const char *msg, const char *func, int line) +wl_iw_get_encodeext( + struct net_device *dev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra +) { - if (res != 0) - WL_ERROR(("%s, %d function:%s, line:%d\n", msg, res, func, line)); + WL_TRACE(("%s: SIOCGIWENCODEEXT\n", dev->name)); + return 0; } static int -set_ap_mac_list(struct net_device *dev, void *buf) +wl_iw_set_wpaauth( + struct net_device *dev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra +) { - struct mac_list_set *mac_list_set = (struct mac_list_set *)buf; - struct maclist *maclist = (struct maclist *)&mac_list_set->mac_list; - int length; - int i; - int mac_mode = mac_list_set->mode; - int ioc_res = 0; - ap_macmode = mac_list_set->mode; + int error = 0; + int paramid; + int paramval; + uint32 cipher_combined; + int val = 0; + wl_iw_t *iw = IW_DEV_IF(dev); - - bzero(&ap_black_list, sizeof(struct mflist)); + WL_TRACE(("%s: SIOCSIWAUTH\n", dev->name)); - if (mac_mode == MACLIST_MODE_DISABLED) { - - ioc_res = dev_wlc_ioctl(dev, WLC_SET_MACMODE, &mac_mode, sizeof(mac_mode)); - check_error(ioc_res, "ioctl ERROR:", __FUNCTION__, __LINE__); - WL_SOFTAP(("%s: MAC filtering disabled\n", __FUNCTION__)); - } else { - - scb_val_t scbval; - char mac_buf[256] = {0}; - struct maclist *assoc_maclist = (struct maclist *) mac_buf; + paramid = vwrq->flags & IW_AUTH_INDEX; + paramval = vwrq->value; - - bcopy(maclist, &ap_black_list, sizeof(ap_black_list)); + WL_TRACE(("%s: SIOCSIWAUTH, paramid = 0x%0x, paramval = 0x%0x\n", + dev->name, paramid, paramval)); - - ioc_res = dev_wlc_ioctl(dev, WLC_SET_MACMODE, &mac_mode, sizeof(mac_mode)); - check_error(ioc_res, "ioctl ERROR:", __FUNCTION__, __LINE__); + switch (paramid) { + case IW_AUTH_WPA_VERSION: - length = sizeof(maclist->count) + maclist->count*ETHER_ADDR_LEN; - dev_wlc_ioctl(dev, WLC_SET_MACLIST, maclist, length); - - WL_SOFTAP(("%s: applied MAC List, mode:%d, length %d:\n", - __FUNCTION__, mac_mode, length)); + if (paramval & IW_AUTH_WPA_VERSION_DISABLED) + val = WPA_AUTH_DISABLED; + else if (paramval & (IW_AUTH_WPA_VERSION_WPA)) + val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED; + else if (paramval & IW_AUTH_WPA_VERSION_WPA2) + val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED; +#ifdef BCMWAPI_WPI + else if (paramval & IW_AUTH_WAPI_VERSION_1) + val = WAPI_AUTH_UNSPECIFIED; +#endif + WL_TRACE(("%s: %d: setting wpa_auth to 0x%0x\n", __FUNCTION__, __LINE__, val)); + if ((error = dev_wlc_intvar_set(dev, "wpa_auth", val))) + return error; + break; - for (i = 0; i < maclist->count; i++) - WL_SOFTAP(("mac %d: %02X:%02X:%02X:%02X:%02X:%02X\n", - i, maclist->ea[i].octet[0], maclist->ea[i].octet[1], - maclist->ea[i].octet[2], - maclist->ea[i].octet[3], maclist->ea[i].octet[4], - maclist->ea[i].octet[5])); + case IW_AUTH_CIPHER_PAIRWISE: + case IW_AUTH_CIPHER_GROUP: - - assoc_maclist->count = 8; - ioc_res = dev_wlc_ioctl(dev, WLC_GET_ASSOCLIST, assoc_maclist, 256); - check_error(ioc_res, "ioctl ERROR:", __FUNCTION__, __LINE__); - WL_SOFTAP((" Cur assoc clients:%d\n", assoc_maclist->count)); + if (paramid == IW_AUTH_CIPHER_PAIRWISE) { + iw->pwsec = paramval; + } + else { + iw->gwsec = paramval; + } - - if (assoc_maclist->count) - for (i = 0; i < assoc_maclist->count; i++) { - int j; - bool assoc_mac_matched = FALSE; - - WL_SOFTAP(("\n Cheking assoc STA: ")); - dhd_print_buf(&assoc_maclist->ea[i], 6, 7); - WL_SOFTAP(("with the b/w list:")); - - for (j = 0; j < maclist->count; j++) - if (!bcmp(&assoc_maclist->ea[i], &maclist->ea[j], - ETHER_ADDR_LEN)) { - - assoc_mac_matched = TRUE; - break; - } + if ((error = dev_wlc_intvar_get(dev, "wsec", &val))) + return error; - - if (((mac_mode == MACLIST_MODE_ALLOW) && !assoc_mac_matched) || - ((mac_mode == MACLIST_MODE_DENY) && assoc_mac_matched)) { - - WL_SOFTAP(("b-match or w-mismatch," - " do deauth/disassoc \n")); - scbval.val = htod32(1); - bcopy(&assoc_maclist->ea[i], &scbval.ea, - ETHER_ADDR_LEN); - ioc_res = dev_wlc_ioctl(dev, - WLC_SCB_DEAUTHENTICATE_FOR_REASON, - &scbval, sizeof(scb_val_t)); - check_error(ioc_res, - "ioctl ERROR:", - __FUNCTION__, __LINE__); - - } else { - WL_SOFTAP((" no b/w list hits, let it be\n")); - } - } else { - WL_SOFTAP(("No ASSOC CLIENTS\n")); - } + cipher_combined = iw->gwsec | iw->pwsec; + val &= ~(WEP_ENABLED | TKIP_ENABLED | AES_ENABLED); + if (cipher_combined & (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104)) + val |= WEP_ENABLED; + if (cipher_combined & IW_AUTH_CIPHER_TKIP) + val |= TKIP_ENABLED; + if (cipher_combined & IW_AUTH_CIPHER_CCMP) + val |= AES_ENABLED; +#ifdef BCMWAPI_WPI + val &= ~SMS4_ENABLED; + if (cipher_combined & IW_AUTH_CIPHER_SMS4) + val |= SMS4_ENABLED; +#endif - } + if (iw->privacy_invoked && !val) { + WL_WSEC(("%s: %s: 'Privacy invoked' TRUE but clearing wsec, assuming " + "we're a WPS enrollee\n", dev->name, __FUNCTION__)); + if ((error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", TRUE))) { + WL_WSEC(("Failed to set iovar is_WPS_enrollee\n")); + return error; + } + } else if (val) { + if ((error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", FALSE))) { + WL_WSEC(("Failed to clear iovar is_WPS_enrollee\n")); + return error; + } + } - WL_SOFTAP(("%s iocres:%d\n", __FUNCTION__, ioc_res)); - return ioc_res; -} + if ((error = dev_wlc_intvar_set(dev, "wsec", val))) + return error; +#ifdef WLFBT + if ((paramid == IW_AUTH_CIPHER_PAIRWISE) && (val | AES_ENABLED)) { + if ((error = dev_wlc_intvar_set(dev, "sup_wpa", 1))) + return error; + } + else if (val == 0) { + if ((error = dev_wlc_intvar_set(dev, "sup_wpa", 0))) + return error; + } #endif + break; + case IW_AUTH_KEY_MGMT: + if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val))) + return error; + if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) { + if (paramval & IW_AUTH_KEY_MGMT_PSK) + val = WPA_AUTH_PSK; + else + val = WPA_AUTH_UNSPECIFIED; + } + else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) { + if (paramval & IW_AUTH_KEY_MGMT_PSK) + val = WPA2_AUTH_PSK; + else + val = WPA2_AUTH_UNSPECIFIED; + } +#ifdef BCMWAPI_WPI + if (paramval & (IW_AUTH_KEY_MGMT_WAPI_PSK | IW_AUTH_KEY_MGMT_WAPI_CERT)) + val = WAPI_AUTH_UNSPECIFIED; +#endif + WL_TRACE(("%s: %d: setting wpa_auth to %d\n", __FUNCTION__, __LINE__, val)); + if ((error = dev_wlc_intvar_set(dev, "wpa_auth", val))) + return error; + break; -#ifdef SOFTAP -#define PARAM_OFFSET PROFILE_OFFSET - -static int -wl_iw_process_private_ascii_cmd( - struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *dwrq, - char *cmd_str) -{ - int ret = 0; - char *sub_cmd = cmd_str + PROFILE_OFFSET + strlen("ASCII_CMD="); - - WL_SOFTAP(("\n %s: ASCII_CMD: offs_0:%s, offset_32:\n'%s'\n", - __FUNCTION__, cmd_str, cmd_str + PROFILE_OFFSET)); - - if (strnicmp(sub_cmd, "AP_CFG", strlen("AP_CFG")) == 0) { - - WL_SOFTAP((" AP_CFG \n")); + case IW_AUTH_TKIP_COUNTERMEASURES: + dev_wlc_bufvar_set(dev, "tkip_countermeasures", (char *)¶mval, 1); + break; + case IW_AUTH_80211_AUTH_ALG: - if (init_ap_profile_from_string(cmd_str+PROFILE_OFFSET, &my_ap) != 0) { - WL_ERROR(("ERROR: SoftAP CFG prams !\n")); - ret = -1; - } else { - ret = set_ap_cfg(dev, &my_ap); + WL_ERROR(("Setting the D11auth %d\n", paramval)); + if (paramval & IW_AUTH_ALG_OPEN_SYSTEM) + val = 0; + else if (paramval & IW_AUTH_ALG_SHARED_KEY) + val = 1; + else + error = 1; + if (!error && (error = dev_wlc_intvar_set(dev, "auth", val))) + return error; + break; + + case IW_AUTH_WPA_ENABLED: + if (paramval == 0) { + val = 0; + WL_TRACE(("%s: %d: setting wpa_auth to %d\n", __FUNCTION__, __LINE__, val)); + error = dev_wlc_intvar_set(dev, "wpa_auth", val); + return error; } + else { + + } + break; - } else if (strnicmp(sub_cmd, "AP_BSS_START", strlen("AP_BSS_START")) == 0) { + case IW_AUTH_DROP_UNENCRYPTED: + dev_wlc_bufvar_set(dev, "wsec_restrict", (char *)¶mval, 1); + break; + + case IW_AUTH_RX_UNENCRYPTED_EAPOL: + dev_wlc_bufvar_set(dev, "rx_unencrypted_eapol", (char *)¶mval, 1); + break; - WL_SOFTAP(("\n SOFTAP - ENABLE BSS \n")); +#if WIRELESS_EXT > 17 + case IW_AUTH_ROAMING_CONTROL: + WL_TRACE(("%s: IW_AUTH_ROAMING_CONTROL\n", __FUNCTION__)); - WL_SOFTAP(("\n!!! got 'WL_AP_EN_BSS' from WPA supplicant, dev:%s\n", dev->name)); + break; + + case IW_AUTH_PRIVACY_INVOKED: { + int wsec; -#ifndef AP_ONLY - if (ap_net_dev == NULL) { - printf("\n ERROR: SOFTAP net_dev* is NULL !!!\n"); + if (paramval == 0) { + iw->privacy_invoked = FALSE; + if ((error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", FALSE))) { + WL_WSEC(("Failed to clear iovar is_WPS_enrollee\n")); + return error; + } } else { - - if ((ret = iwpriv_en_ap_bss(ap_net_dev, info, dwrq, cmd_str)) < 0) - WL_ERROR(("%s line %d fail to set bss up\n", - __FUNCTION__, __LINE__)); + iw->privacy_invoked = TRUE; + if ((error = dev_wlc_intvar_get(dev, "wsec", &wsec))) + return error; + + if (!WSEC_ENABLED(wsec)) { + + if ((error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", TRUE))) { + WL_WSEC(("Failed to set iovar is_WPS_enrollee\n")); + return error; + } + } else { + if ((error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", FALSE))) { + WL_WSEC(("Failed to clear iovar is_WPS_enrollee\n")); + return error; + } + } } -#else - if ((ret = iwpriv_en_ap_bss(dev, info, dwrq, cmd_str)) < 0) - WL_ERROR(("%s line %d fail to set bss up\n", - __FUNCTION__, __LINE__)); -#endif - } else if (strnicmp(sub_cmd, "ASSOC_LST", strlen("ASSOC_LST")) == 0) { + break; + } - - } else if (strnicmp(sub_cmd, "AP_BSS_STOP", strlen("AP_BSS_STOP")) == 0) { +#endif + +#ifdef BCMWAPI_WPI - WL_SOFTAP((" \n temp DOWN SOFTAP\n")); -#ifndef AP_ONLY - if ((ret = dev_iw_write_cfg1_bss_var(dev, 0)) < 0) { - WL_ERROR(("%s line %d fail to set bss down\n", - __FUNCTION__, __LINE__)); + case IW_AUTH_WAPI_ENABLED: + if ((error = dev_wlc_intvar_get(dev, "wsec", &val))) + return error; + if (paramval) { + val |= SMS4_ENABLED; + if ((error = dev_wlc_intvar_set(dev, "wsec", val))) { + WL_ERROR(("%s: setting wsec to 0x%0x returned error %d\n", + __FUNCTION__, val, error)); + return error; + } + if ((error = dev_wlc_intvar_set(dev, "wpa_auth", WAPI_AUTH_UNSPECIFIED))) { + WL_ERROR(("%s: setting wpa_auth(%d) returned %d\n", + __FUNCTION__, WAPI_AUTH_UNSPECIFIED, + error)); + return error; + } } -#endif - } - return ret; + break; -} #endif + default: + break; + } + return 0; +} +#define VAL_PSK(_val) (((_val) & WPA_AUTH_PSK) || ((_val) & WPA2_AUTH_PSK)) static int -wl_iw_set_priv( +wl_iw_get_wpaauth( struct net_device *dev, struct iw_request_info *info, - struct iw_point *dwrq, - char *ext + struct iw_param *vwrq, + char *extra ) { - int ret = 0; - char * extra; + int error; + int paramid; + int paramval = 0; + int val; + wl_iw_t *iw = IW_DEV_IF(dev); - if (!(extra = kmalloc(dwrq->length, GFP_KERNEL))) - return -ENOMEM; + WL_TRACE(("%s: SIOCGIWAUTH\n", dev->name)); - if (copy_from_user(extra, dwrq->pointer, dwrq->length)) { - kfree(extra); - return -EFAULT; - } + paramid = vwrq->flags & IW_AUTH_INDEX; - WL_TRACE(("%s: SIOCSIWPRIV request %s, info->cmd:%x, info->flags:%d\n dwrq->length:%d\n", - dev->name, extra, info->cmd, info->flags, dwrq->length)); + switch (paramid) { + case IW_AUTH_WPA_VERSION: + + if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val))) + return error; + if (val & (WPA_AUTH_NONE | WPA_AUTH_DISABLED)) + paramval = IW_AUTH_WPA_VERSION_DISABLED; + else if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) + paramval = IW_AUTH_WPA_VERSION_WPA; + else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) + paramval = IW_AUTH_WPA_VERSION_WPA2; + break; - + case IW_AUTH_CIPHER_PAIRWISE: + paramval = iw->pwsec; + break; - net_os_wake_lock(dev); + case IW_AUTH_CIPHER_GROUP: + paramval = iw->gwsec; + break; - if (dwrq->length && extra) { - if (strnicmp(extra, "START", strlen("START")) == 0) { - wl_iw_control_wl_on(dev, info); - WL_TRACE(("%s, Received regular START command\n", __FUNCTION__)); - } + case IW_AUTH_KEY_MGMT: + + if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val))) + return error; + if (VAL_PSK(val)) + paramval = IW_AUTH_KEY_MGMT_PSK; + else + paramval = IW_AUTH_KEY_MGMT_802_1X; - if (g_onoff == G_WLAN_SET_OFF) { - WL_TRACE(("%s, missing START, Fail\n", __FUNCTION__)); - kfree(extra); - net_os_wake_unlock(dev); - return -EFAULT; - } + break; + case IW_AUTH_TKIP_COUNTERMEASURES: + dev_wlc_bufvar_get(dev, "tkip_countermeasures", (char *)¶mval, 1); + break; - if (strnicmp(extra, "SCAN-ACTIVE", strlen("SCAN-ACTIVE")) == 0) { -#ifdef ENABLE_ACTIVE_PASSIVE_SCAN_SUPPRESS - WL_TRACE(("%s: active scan setting suppressed\n", dev->name)); -#else - ret = wl_iw_set_active_scan(dev, info, (union iwreq_data *)dwrq, extra); -#endif - } - else if (strnicmp(extra, "SCAN-PASSIVE", strlen("SCAN-PASSIVE")) == 0) -#ifdef ENABLE_ACTIVE_PASSIVE_SCAN_SUPPRESS - WL_TRACE(("%s: passive scan setting suppressed\n", dev->name)); -#else - ret = wl_iw_set_passive_scan(dev, info, (union iwreq_data *)dwrq, extra); -#endif - else if (strnicmp(extra, "RSSI", strlen("RSSI")) == 0) - ret = wl_iw_get_rssi(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, "LINKSPEED", strlen("LINKSPEED")) == 0) - ret = wl_iw_get_link_speed(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, "MACADDR", strlen("MACADDR")) == 0) - ret = wl_iw_get_macaddr(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, "COUNTRY", strlen("COUNTRY")) == 0) - ret = wl_iw_set_country(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, "STOP", strlen("STOP")) == 0) - ret = wl_iw_control_wl_off(dev, info); - else if (strnicmp(extra, BAND_GET_CMD, strlen(BAND_GET_CMD)) == 0) - ret = wl_iw_get_band(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, BAND_SET_CMD, strlen(BAND_SET_CMD)) == 0) - ret = wl_iw_set_band(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, DTIM_SKIP_GET_CMD, strlen(DTIM_SKIP_GET_CMD)) == 0) - ret = wl_iw_get_dtim_skip(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, DTIM_SKIP_SET_CMD, strlen(DTIM_SKIP_SET_CMD)) == 0) - ret = wl_iw_set_dtim_skip(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, SETSUSPEND_CMD, strlen(SETSUSPEND_CMD)) == 0) - ret = wl_iw_set_suspend(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, TXPOWER_SET_CMD, strlen(TXPOWER_SET_CMD)) == 0) - ret = wl_iw_set_txpower(dev, info, (union iwreq_data *)dwrq, extra); -#if defined(PNO_SUPPORT) - else if (strnicmp(extra, PNOSSIDCLR_SET_CMD, strlen(PNOSSIDCLR_SET_CMD)) == 0) - ret = wl_iw_set_pno_reset(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, PNOSETUP_SET_CMD, strlen(PNOSETUP_SET_CMD)) == 0) - ret = wl_iw_set_pno_set(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, PNOSETADD_SET_CMD, strlen(PNOSETADD_SET_CMD)) == 0) - ret = wl_iw_set_pno_setadd(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, PNOENABLE_SET_CMD, strlen(PNOENABLE_SET_CMD)) == 0) - ret = wl_iw_set_pno_enable(dev, info, (union iwreq_data *)dwrq, extra); -#endif -#if defined(CSCAN) - - else if (strnicmp(extra, CSCAN_COMMAND, strlen(CSCAN_COMMAND)) == 0) - ret = wl_iw_set_cscan(dev, info, (union iwreq_data *)dwrq, extra); -#endif -#ifdef CONFIG_WPS2 - else if (strnicmp(extra, WPS_ADD_PROBE_REQ_IE_CMD, - strlen(WPS_ADD_PROBE_REQ_IE_CMD)) == 0) - ret = wl_iw_add_wps_probe_req_ie(dev, info, - (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, WPS_DEL_PROBE_REQ_IE_CMD, - strlen(WPS_DEL_PROBE_REQ_IE_CMD)) == 0) - ret = wl_iw_del_wps_probe_req_ie(dev, info, - (union iwreq_data *)dwrq, extra); -#endif - else if (strnicmp(extra, "POWERMODE", strlen("POWERMODE")) == 0) - ret = wl_iw_set_power_mode(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, "BTCOEXMODE", strlen("BTCOEXMODE")) == 0) - ret = wl_iw_set_btcoex_dhcp(dev, info, (union iwreq_data *)dwrq, extra); - else if (strnicmp(extra, "GETPOWER", strlen("GETPOWER")) == 0) - ret = wl_iw_get_power_mode(dev, info, (union iwreq_data *)dwrq, extra); -#ifdef SOFTAP - else if (strnicmp(extra, "ASCII_CMD", strlen("ASCII_CMD")) == 0) { - wl_iw_process_private_ascii_cmd(dev, info, (union iwreq_data *)dwrq, extra); - } - else if (strnicmp(extra, "AP_MAC_LIST_SET", strlen("AP_MAC_LIST_SET")) == 0) { - WL_SOFTAP(("penguin, set AP_MAC_LIST_SET\n")); - set_ap_mac_list(dev, (extra + PROFILE_OFFSET)); - } -#endif - else { - WL_ERROR(("Unknown PRIVATE command %s - ignored\n", extra)); - snprintf(extra, MAX_WX_STRING, "OK"); - dwrq->length = strlen("OK") + 1; - } - } + case IW_AUTH_DROP_UNENCRYPTED: + dev_wlc_bufvar_get(dev, "wsec_restrict", (char *)¶mval, 1); + break; - net_os_wake_unlock(dev); + case IW_AUTH_RX_UNENCRYPTED_EAPOL: + dev_wlc_bufvar_get(dev, "rx_unencrypted_eapol", (char *)¶mval, 1); + break; - if (extra) { - if (copy_to_user(dwrq->pointer, extra, dwrq->length)) { - kfree(extra); - return -EFAULT; - } + case IW_AUTH_80211_AUTH_ALG: + + if ((error = dev_wlc_intvar_get(dev, "auth", &val))) + return error; + if (!val) + paramval = IW_AUTH_ALG_OPEN_SYSTEM; + else + paramval = IW_AUTH_ALG_SHARED_KEY; + break; + case IW_AUTH_WPA_ENABLED: + if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val))) + return error; + if (val) + paramval = TRUE; + else + paramval = FALSE; + break; - kfree(extra); - } +#if WIRELESS_EXT > 17 - return ret; + case IW_AUTH_ROAMING_CONTROL: + WL_ERROR(("%s: IW_AUTH_ROAMING_CONTROL\n", __FUNCTION__)); + + break; + + case IW_AUTH_PRIVACY_INVOKED: + paramval = iw->privacy_invoked; + break; + +#endif + } + vwrq->value = paramval; + return 0; } +#endif static const iw_handler wl_iw_handler[] = { @@ -7683,7 +2913,7 @@ static const iw_handler wl_iw_handler[] = (iw_handler) NULL, (iw_handler) NULL, (iw_handler) wl_iw_get_range, - (iw_handler) wl_iw_set_priv, + (iw_handler) NULL, (iw_handler) NULL, (iw_handler) NULL, (iw_handler) NULL, @@ -7698,19 +2928,10 @@ static const iw_handler wl_iw_handler[] = #else (iw_handler) NULL, #endif -#if defined(WL_IW_USE_ISCAN) (iw_handler) wl_iw_iscan_get_aplist, -#else - (iw_handler) wl_iw_get_aplist, -#endif #if WIRELESS_EXT > 13 -#if defined(WL_IW_USE_ISCAN) (iw_handler) wl_iw_iscan_set_scan, (iw_handler) wl_iw_iscan_get_scan, -#else - (iw_handler) wl_iw_set_scan, - (iw_handler) wl_iw_get_scan, -#endif #else (iw_handler) NULL, (iw_handler) NULL, @@ -7746,187 +2967,58 @@ static const iw_handler wl_iw_handler[] = (iw_handler) wl_iw_get_wpaauth, (iw_handler) wl_iw_set_encodeext, (iw_handler) wl_iw_get_encodeext, - (iw_handler) wl_iw_set_pmksa, + (iw_handler) wl_iw_set_pmksa, #endif }; #if WIRELESS_EXT > 12 -static const iw_handler wl_iw_priv_handler[] = { - NULL, - (iw_handler)wl_iw_set_active_scan, - NULL, - (iw_handler)wl_iw_get_rssi, - NULL, - (iw_handler)wl_iw_set_passive_scan, - NULL, - (iw_handler)wl_iw_get_link_speed, - NULL, - (iw_handler)wl_iw_get_macaddr, - NULL, - (iw_handler)wl_iw_control_wl_off, - NULL, - (iw_handler)wl_iw_control_wl_on, -#ifdef SOFTAP - - - NULL, - (iw_handler)iwpriv_set_ap_config, - - - - NULL, - (iw_handler)iwpriv_get_assoc_list, - - - NULL, - (iw_handler)iwpriv_set_mac_filters, - - - NULL, - (iw_handler)iwpriv_en_ap_bss, - - - NULL, - (iw_handler)iwpriv_wpasupp_loop_tst, - - NULL, - (iw_handler)iwpriv_softap_stop, - - NULL, - (iw_handler)iwpriv_fw_reload, - NULL, - (iw_handler)iwpriv_set_ap_sta_disassoc, -#endif -#if defined(CSCAN) - - NULL, - (iw_handler)iwpriv_set_cscan -#endif +enum { + WL_IW_SET_LEDDC = SIOCIWFIRSTPRIV, + WL_IW_SET_VLANMODE, + WL_IW_SET_PM }; -static const struct iw_priv_args wl_iw_priv_args[] = -{ - { - WL_IW_SET_ACTIVE_SCAN, - 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - "SCAN-ACTIVE" - }, - { - WL_IW_GET_RSSI, - 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - "RSSI" - }, - { - WL_IW_SET_PASSIVE_SCAN, - 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - "SCAN-PASSIVE" - }, - { - WL_IW_GET_LINK_SPEED, - 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - "LINKSPEED" - }, - { - WL_IW_GET_CURR_MACADDR, - 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - "Macaddr" - }, - { - WL_IW_SET_STOP, - 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - "STOP" - }, - { - WL_IW_SET_START, - 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - "START" - }, +static iw_handler wl_iw_priv_handler[] = { + wl_iw_set_leddc, + wl_iw_set_vlanmode, + wl_iw_set_pm +}; -#ifdef SOFTAP - - +static struct iw_priv_args wl_iw_priv_args[] = { { - WL_SET_AP_CFG, - IW_PRIV_TYPE_CHAR | 256, + WL_IW_SET_LEDDC, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, - "AP_SET_CFG" - }, - - { - WL_AP_STA_LIST, - IW_PRIV_TYPE_CHAR | 0, - IW_PRIV_TYPE_CHAR | 1024, - "AP_GET_STA_LIST" + "set_leddc" }, - { - WL_AP_MAC_FLTR, - IW_PRIV_TYPE_CHAR | 256, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 0, - "AP_SET_MAC_FLTR" - }, - - { - WL_AP_BSS_START, + WL_IW_SET_VLANMODE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - "AP_BSS_START" + "set_vlanmode" }, - { - AP_LPB_CMD, - IW_PRIV_TYPE_CHAR | 256, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 0, - "AP_LPB_CMD" - }, - - { - WL_AP_STOP, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 0, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 0, - "AP_BSS_STOP" - }, - { - WL_FW_RELOAD, - IW_PRIV_TYPE_CHAR | 256, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 0, - "WL_FW_RELOAD" - }, -#endif -#if defined(CSCAN) - { - WL_COMBO_SCAN, - IW_PRIV_TYPE_CHAR | 1024, + WL_IW_SET_PM, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, - "CSCAN" - }, -#endif - }; + "set_pm" + } +}; const struct iw_handler_def wl_iw_handler_def = { .num_standard = ARRAYSIZE(wl_iw_handler), - .standard = (iw_handler *) wl_iw_handler, - .num_private = ARRAYSIZE(wl_iw_priv_handler), + .num_private = ARRAY_SIZE(wl_iw_priv_handler), .num_private_args = ARRAY_SIZE(wl_iw_priv_args), - .private = (iw_handler *)wl_iw_priv_handler, - .private_args = (void *) wl_iw_priv_args, - + .standard = (iw_handler *) wl_iw_handler, + .private = wl_iw_priv_handler, + .private_args = wl_iw_priv_args, #if WIRELESS_EXT >= 19 get_wireless_stats: dhd_get_wireless_stats, #endif }; #endif - - int wl_iw_ioctl( struct net_device *dev, @@ -7941,16 +3033,10 @@ wl_iw_ioctl( size_t token_size = 1; int max_tokens = 0, ret = 0; - net_os_wake_lock(dev); - - WL_TRACE(("\n%s, cmd:%x called via dhd->do_ioctl()entry point\n", __FUNCTION__, cmd)); if (cmd < SIOCIWFIRST || IW_IOCTL_IDX(cmd) >= ARRAYSIZE(wl_iw_handler) || - !(handler = wl_iw_handler[IW_IOCTL_IDX(cmd)])) { - WL_ERROR(("%s: error in cmd=%x : not supported\n", __FUNCTION__, cmd)); - net_os_wake_unlock(dev); - return -EOPNOTSUPP; - } + !(handler = wl_iw_handler[IW_IOCTL_IDX(cmd)])) + return -EOPNOTSUPP; switch (cmd) { @@ -7967,12 +3053,11 @@ wl_iw_ioctl( case SIOCSIWENCODEEXT: case SIOCGIWENCODEEXT: #endif - max_tokens = wrq->u.data.length; + max_tokens = IW_ENCODING_TOKEN_MAX; break; case SIOCGIWRANGE: - - max_tokens = sizeof(struct iw_range) + 500; + max_tokens = sizeof(struct iw_range); break; case SIOCGIWAPLIST: @@ -7982,11 +3067,9 @@ wl_iw_ioctl( #if WIRELESS_EXT > 13 case SIOCGIWSCAN: -#if defined(WL_IW_USE_ISCAN) if (g_iscan) max_tokens = wrq->u.data.length; else -#endif max_tokens = IW_SCAN_MAX_DATA; break; #endif @@ -8000,32 +3083,20 @@ wl_iw_ioctl( token_size = sizeof(struct sockaddr) + sizeof(struct iw_quality); max_tokens = IW_MAX_SPY; break; - -#if WIRELESS_EXT > 17 - case SIOCSIWPMKSA: - case SIOCSIWGENIE: -#endif - case SIOCSIWPRIV: - max_tokens = wrq->u.data.length; + default: break; } if (max_tokens && wrq->u.data.pointer) { - if (wrq->u.data.length > max_tokens) { - WL_ERROR(("%s: error in cmd=%x wrq->u.data.length=%d > max_tokens=%d\n", - __FUNCTION__, cmd, wrq->u.data.length, max_tokens)); - ret = -E2BIG; - goto wl_iw_ioctl_done; - } - if (!(extra = kmalloc(max_tokens * token_size, GFP_KERNEL))) { - ret = -ENOMEM; - goto wl_iw_ioctl_done; - } + if (wrq->u.data.length > max_tokens) + return -E2BIG; + + if (!(extra = kmalloc(max_tokens * token_size, GFP_KERNEL))) + return -ENOMEM; if (copy_from_user(extra, wrq->u.data.pointer, wrq->u.data.length * token_size)) { kfree(extra); - ret = -EFAULT; - goto wl_iw_ioctl_done; + return -EFAULT; } } @@ -8037,22 +3108,17 @@ wl_iw_ioctl( if (extra) { if (copy_to_user(wrq->u.data.pointer, extra, wrq->u.data.length * token_size)) { kfree(extra); - ret = -EFAULT; - goto wl_iw_ioctl_done; + return -EFAULT; } kfree(extra); } -wl_iw_ioctl_done: - - net_os_wake_unlock(dev); - return ret; } -static bool +bool wl_iw_conn_status_str(uint32 event_type, uint32 status, uint32 reason, char* stringBuf, uint buflen) { @@ -8065,7 +3131,7 @@ wl_iw_conn_status_str(uint32 event_type, uint32 status, uint32 reason, } conn_fail_event_map_t; -#define WL_IW_DONT_CARE 9999 +# define WL_IW_DONT_CARE 9999 const conn_fail_event_map_t event_map [] = { @@ -8124,14 +3190,14 @@ wl_iw_conn_status_str(uint32 event_type, uint32 status, uint32 reason, memset(stringBuf, 0, buflen); snprintf(stringBuf, buflen, "%s %s %02d %02d", name, cause, status, reason); - WL_INFORM(("Connection status: %s\n", stringBuf)); + WL_TRACE(("Connection status: %s\n", stringBuf)); return TRUE; } else { return FALSE; } } -#if WIRELESS_EXT > 14 +#if (WIRELESS_EXT > 14) static bool wl_iw_check_conn_fail(wl_event_msg_t *e, char* stringBuf, uint buflen) @@ -8142,9 +3208,10 @@ wl_iw_check_conn_fail(wl_event_msg_t *e, char* stringBuf, uint buflen) if (wl_iw_conn_status_str(event, status, reason, stringBuf, buflen)) { return TRUE; - } - else + } else + { return FALSE; + } } #endif @@ -8163,146 +3230,39 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data) uint16 flags = ntoh16(e->flags); uint32 datalen = ntoh32(e->datalen); uint32 status = ntoh32(e->status); - uint32 toto; + memset(&wrqu, 0, sizeof(wrqu)); memset(extra, 0, sizeof(extra)); - if (!dev) { - WL_ERROR(("%s: dev is null\n", __FUNCTION__)); - return; - } - - net_os_wake_lock(dev); - - WL_TRACE(("%s: dev=%s event=%d \n", __FUNCTION__, dev->name, event_type)); + memcpy(wrqu.addr.sa_data, &e->addr, ETHER_ADDR_LEN); + wrqu.addr.sa_family = ARPHRD_ETHER; - switch (event_type) { -#if defined(SOFTAP) - case WLC_E_PRUNE: - if (ap_cfg_running) { - char *macaddr = (char *)&e->addr; - WL_SOFTAP(("PRUNE received, %02X:%02X:%02X:%02X:%02X:%02X!\n", - macaddr[0], macaddr[1], macaddr[2], macaddr[3], - macaddr[4], macaddr[5])); - - - if (ap_macmode) - { - int i; - for (i = 0; i < ap_black_list.count; i++) { - if (!bcmp(macaddr, &ap_black_list.ea[i], - sizeof(struct ether_addr))) { - WL_SOFTAP(("mac in black list, ignore it\n")); - break; - } - } - - if (i == ap_black_list.count) { - - char mac_buf[32] = {0}; - sprintf(mac_buf, "STA_BLOCK %02X:%02X:%02X:%02X:%02X:%02X", - macaddr[0], macaddr[1], macaddr[2], - macaddr[3], macaddr[4], macaddr[5]); - wl_iw_send_priv_event(priv_dev, mac_buf); - } - } - } - break; -#endif case WLC_E_TXFAIL: cmd = IWEVTXDROP; - memcpy(wrqu.addr.sa_data, &e->addr, ETHER_ADDR_LEN); - wrqu.addr.sa_family = ARPHRD_ETHER; break; #if WIRELESS_EXT > 14 case WLC_E_JOIN: case WLC_E_ASSOC_IND: case WLC_E_REASSOC_IND: -#if defined(SOFTAP) - WL_SOFTAP(("STA connect received %d\n", event_type)); - if (ap_cfg_running) { - wl_iw_send_priv_event(priv_dev, "STA_JOIN"); - goto wl_iw_event_end; - } -#endif - memcpy(wrqu.addr.sa_data, &e->addr, ETHER_ADDR_LEN); - wrqu.addr.sa_family = ARPHRD_ETHER; cmd = IWEVREGISTERED; break; - case WLC_E_ROAM: - if (status == WLC_E_STATUS_SUCCESS) { - WL_ASSOC((" WLC_E_ROAM : success \n")); - goto wl_iw_event_end; - } - break; - case WLC_E_DEAUTH_IND: case WLC_E_DISASSOC_IND: -#if defined(SOFTAP) - WL_SOFTAP(("STA disconnect received %d\n", event_type)); - if (ap_cfg_running) { - wl_iw_send_priv_event(priv_dev, "STA_LEAVE"); - goto wl_iw_event_end; - } -#endif cmd = SIOCGIWAP; + wrqu.data.length = strlen(extra); bzero(wrqu.addr.sa_data, ETHER_ADDR_LEN); - wrqu.addr.sa_family = ARPHRD_ETHER; bzero(&extra, ETHER_ADDR_LEN); break; + case WLC_E_LINK: case WLC_E_NDIS_LINK: cmd = SIOCGIWAP; + wrqu.data.length = strlen(extra); if (!(flags & WLC_EVENT_MSG_LINK)) { - - -#ifdef SOFTAP -#ifdef AP_ONLY - if (ap_cfg_running) { -#else - if (ap_cfg_running && !strncmp(dev->name, "wl0.1", 5)) { -#endif - - WL_SOFTAP(("AP DOWN %d\n", event_type)); - wl_iw_send_priv_event(priv_dev, "AP_DOWN"); - } else { - WL_TRACE(("STA_Link Down\n")); - g_ss_cache_ctrl.m_link_down = 1; - } -#else - g_ss_cache_ctrl.m_link_down = 1; -#endif - WL_TRACE(("Link Down\n")); - bzero(wrqu.addr.sa_data, ETHER_ADDR_LEN); bzero(&extra, ETHER_ADDR_LEN); } - else { - - memcpy(wrqu.addr.sa_data, &e->addr, ETHER_ADDR_LEN); - g_ss_cache_ctrl.m_link_down = 0; - - memcpy(g_ss_cache_ctrl.m_active_bssid, &e->addr, ETHER_ADDR_LEN); -#ifdef SOFTAP - -#ifdef AP_ONLY - if (ap_cfg_running) { -#else - if (ap_cfg_running && !strncmp(dev->name, "wl0.1", 5)) { -#endif - - WL_SOFTAP(("AP UP %d\n", event_type)); - wl_iw_send_priv_event(priv_dev, "AP_UP"); - } else { - WL_TRACE(("STA_LINK_UP\n")); - } -#else -#endif - WL_TRACE(("Link UP\n")); - - } - wrqu.addr.sa_family = ARPHRD_ETHER; break; case WLC_E_ACTION_FRAME: cmd = IWEVCUSTOM; @@ -8316,13 +3276,11 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data) case WLC_E_ACTION_FRAME_COMPLETE: cmd = IWEVCUSTOM; - memcpy(&toto, data, 4); if (sizeof(status) + 1 <= sizeof(extra)) { wrqu.data.length = sizeof(status) + 1; extra[0] = WLC_E_ACTION_FRAME_COMPLETE; memcpy(&extra[1], &status, sizeof(status)); - printf("wl_iw_event status %d PacketId %d \n", status, toto); - printf("WLC_E_ACTION_FRAME_COMPLETE len %d \n", wrqu.data.length); + WL_TRACE(("wl_iw_event status %d \n", status)); } break; #endif @@ -8356,85 +3314,54 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data) break; case WLC_E_PMKID_CACHE: { - if (data) - { - struct iw_pmkid_cand *iwpmkidcand = (struct iw_pmkid_cand *)&extra; - pmkid_cand_list_t *pmkcandlist; - pmkid_cand_t *pmkidcand; - int count; - - cmd = IWEVPMKIDCAND; - pmkcandlist = data; - count = ntoh32_ua((uint8 *)&pmkcandlist->npmkid_cand); - ASSERT(count >= 0); - wrqu.data.length = sizeof(struct iw_pmkid_cand); - pmkidcand = pmkcandlist->pmkid_cand; - while (count) { - bzero(iwpmkidcand, sizeof(struct iw_pmkid_cand)); - if (pmkidcand->preauth) - iwpmkidcand->flags |= IW_PMKID_CAND_PREAUTH; - bcopy(&pmkidcand->BSSID, &iwpmkidcand->bssid.sa_data, - ETHER_ADDR_LEN); - wireless_send_event(dev, cmd, &wrqu, extra); - pmkidcand++; - count--; - } + struct iw_pmkid_cand *iwpmkidcand = (struct iw_pmkid_cand *)&extra; + pmkid_cand_list_t *pmkcandlist; + pmkid_cand_t *pmkidcand; + int count; + + if (data == NULL) + break; + + cmd = IWEVPMKIDCAND; + pmkcandlist = data; + count = ntoh32_ua((uint8 *)&pmkcandlist->npmkid_cand); + wrqu.data.length = sizeof(struct iw_pmkid_cand); + pmkidcand = pmkcandlist->pmkid_cand; + while (count) { + bzero(iwpmkidcand, sizeof(struct iw_pmkid_cand)); + if (pmkidcand->preauth) + iwpmkidcand->flags |= IW_PMKID_CAND_PREAUTH; + bcopy(&pmkidcand->BSSID, &iwpmkidcand->bssid.sa_data, + ETHER_ADDR_LEN); + wireless_send_event(dev, cmd, &wrqu, extra); + pmkidcand++; + count--; } - goto wl_iw_event_end; + break; } #endif case WLC_E_SCAN_COMPLETE: -#if defined(WL_IW_USE_ISCAN) - if (!g_iscan) { - WL_ERROR(("Event WLC_E_SCAN_COMPLETE on g_iscan NULL!")); - goto wl_iw_event_end; - } - - if ((g_iscan) && (g_iscan->tsk_ctl.thr_pid >= 0) && - (g_iscan->iscan_state != ISCAN_STATE_IDLE)) - { - up(&g_iscan->tsk_ctl.sema); - } else { - cmd = SIOCGIWSCAN; - wrqu.data.length = strlen(extra); - WL_TRACE(("Event WLC_E_SCAN_COMPLETE from specific scan %d\n", - g_iscan->iscan_state)); - } -#else +#if WIRELESS_EXT > 14 cmd = SIOCGIWSCAN; - wrqu.data.length = strlen(extra); - WL_TRACE(("Event WLC_E_SCAN_COMPLETE\n")); -#endif - break; - - - case WLC_E_PFN_NET_FOUND: - { - wl_pfn_net_info_t *netinfo; - netinfo = (wl_pfn_net_info_t *)(data + sizeof(wl_pfn_scanresults_t) - - sizeof(wl_pfn_net_info_t)); - WL_ERROR(("%s Event WLC_E_PFN_NET_FOUND, send %s up : find %s len=%d\n", - __FUNCTION__, PNO_EVENT_UP, netinfo->pfnsubnet.SSID, - netinfo->pfnsubnet.SSID_len)); - cmd = IWEVCUSTOM; - memset(&wrqu, 0, sizeof(wrqu)); - strcpy(extra, PNO_EVENT_UP); - wrqu.data.length = strlen(extra); - } - break; +#endif + WL_TRACE(("event WLC_E_SCAN_COMPLETE\n")); + if ((g_iscan) && (g_iscan->sysioc_pid >= 0) && + (g_iscan->iscan_state != ISCAN_STATE_IDLE)) + up(&g_iscan->sysioc_sem); + break; default: - WL_TRACE(("Unknown Event %d: ignoring\n", event_type)); break; } - if (cmd) { - if (cmd == SIOCGIWSCAN) - wireless_send_event(dev, cmd, &wrqu, NULL); - else - wireless_send_event(dev, cmd, &wrqu, extra); - } + + if (cmd) { + if (cmd == SIOCGIWSCAN) + wireless_send_event(dev, cmd, &wrqu, NULL); + else + wireless_send_event(dev, cmd, &wrqu, extra); + } #if WIRELESS_EXT > 14 @@ -8446,15 +3373,10 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data) } #endif - goto wl_iw_event_end; -wl_iw_event_end: - - net_os_wake_unlock(dev); #endif } -int -wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats) +int wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats) { int res = 0; wl_cnt_t cnt; @@ -8467,14 +3389,14 @@ wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats) goto done; phy_noise = dtoh32(phy_noise); - WL_TRACE(("wl_iw_get_wireless_stats phy noise=%d\n", phy_noise)); + WL_TRACE(("wl_iw_get_wireless_stats phy noise=%d\n *****", phy_noise)); - bzero(&scb_val, sizeof(scb_val_t)); + scb_val.val = 0; if ((res = dev_wlc_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t)))) goto done; rssi = dtoh32(scb_val.val); - WL_TRACE(("wl_iw_get_wireless_stats rssi=%d\n", rssi)); + WL_TRACE(("wl_iw_get_wireless_stats rssi=%d ****** \n", rssi)); if (rssi <= WL_IW_RSSI_NO_SIGNAL) wstats->qual.qual = 0; else if (rssi <= WL_IW_RSSI_VERY_LOW) @@ -8498,13 +3420,13 @@ wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats) #endif #if WIRELESS_EXT > 11 - WL_TRACE(("wl_iw_get_wireless_stats counters=%d\n", (int)sizeof(wl_cnt_t))); + WL_TRACE(("wl_iw_get_wireless_stats counters=%d\n *****", (int)sizeof(wl_cnt_t))); memset(&cnt, 0, sizeof(wl_cnt_t)); res = dev_wlc_bufvar_get(dev, "counters", (char *)&cnt, sizeof(wl_cnt_t)); if (res) { - WL_ERROR(("wl_iw_get_wireless_stats counters failed error=%d\n", res)); + WL_ERROR(("wl_iw_get_wireless_stats counters failed error=%d ****** \n", res)); goto done; } @@ -8537,334 +3459,270 @@ wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats) done: return res; } -#if defined(COEX_DHCP) + static void -wl_iw_bt_flag_set( - struct net_device *dev, - bool set) +wl_iw_timerfunc(ulong data) { -#if defined(BT_DHCP_USE_FLAGS) - char buf_flag7_dhcp_on[8] = { 7, 00, 00, 00, 0x1, 0x0, 0x00, 0x00 }; - char buf_flag7_default[8] = { 7, 00, 00, 00, 0x0, 0x00, 0x00, 0x00}; -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - rtnl_lock(); -#endif - - -#if defined(BT_DHCP_eSCO_FIX) - - set_btc_esco_params(dev, set); -#endif - - -#if defined(BT_DHCP_USE_FLAGS) - WL_TRACE_COEX(("WI-FI priority boost via bt flags, set:%d\n", set)); - if (set == TRUE) { - - dev_wlc_bufvar_set(dev, "btc_flags", - (char *)&buf_flag7_dhcp_on[0], sizeof(buf_flag7_dhcp_on)); - } - else { - - dev_wlc_bufvar_set(dev, "btc_flags", - (char *)&buf_flag7_default[0], sizeof(buf_flag7_default)); + iscan_info_t *iscan = (iscan_info_t *)data; + iscan->timer_on = 0; + if (iscan->iscan_state != ISCAN_STATE_IDLE) { + WL_TRACE(("timer trigger\n")); + up(&iscan->sysioc_sem); } -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - rtnl_unlock(); -#endif } static void -wl_iw_bt_timerfunc(ulong data) +wl_iw_set_event_mask(struct net_device *dev) { - bt_info_t *bt_local = (bt_info_t *)data; - bt_local->timer_on = 0; - WL_TRACE(("%s\n", __FUNCTION__)); - - up(&bt_local->tsk_ctl.sema); + char eventmask[WL_EVENTING_MASK_LEN]; + char iovbuf[WL_EVENTING_MASK_LEN + 12]; + + dev_iw_iovar_getbuf(dev, "event_msgs", "", 0, iovbuf, sizeof(iovbuf)); + bcopy(iovbuf, eventmask, WL_EVENTING_MASK_LEN); + setbit(eventmask, WLC_E_SCAN_COMPLETE); + dev_iw_iovar_setbuf(dev, "event_msgs", eventmask, WL_EVENTING_MASK_LEN, + iovbuf, sizeof(iovbuf)); + } static int -_bt_dhcp_sysioc_thread(void *data) +wl_iw_iscan_prep(wl_scan_params_t *params, wlc_ssid_t *ssid) { - tsk_ctl_t *tsk_ctl = (tsk_ctl_t *)data; - - DAEMONIZE("dhcp_sysioc"); + int err = 0; - complete(&tsk_ctl->completed); + memcpy(¶ms->bssid, ðer_bcast, ETHER_ADDR_LEN); + params->bss_type = DOT11_BSSTYPE_ANY; + params->scan_type = 0; + params->nprobes = -1; + params->active_time = -1; + params->passive_time = -1; + params->home_time = -1; + params->channel_num = 0; - while (down_interruptible(&tsk_ctl->sema) == 0) { + params->nprobes = htod32(params->nprobes); + params->active_time = htod32(params->active_time); + params->passive_time = htod32(params->passive_time); + params->home_time = htod32(params->home_time); + if (ssid && ssid->SSID_len) + memcpy(¶ms->ssid, ssid, sizeof(wlc_ssid_t)); - SMP_RD_BARRIER_DEPENDS(); - if (tsk_ctl->terminated) { - break; - } + return err; +} - if (g_bt->timer_on) { - g_bt->timer_on = 0; - del_timer_sync(&g_bt->timer); - } +static int +wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, uint16 action) +{ + int params_size = (WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_iscan_params_t, params)); + wl_iscan_params_t *params; + int err = 0; - switch (g_bt->bt_state) { - case BT_DHCP_START: - - WL_TRACE_COEX(("%s bt_dhcp stm: started \n", __FUNCTION__)); - g_bt->bt_state = BT_DHCP_OPPORTUNITY_WINDOW; - mod_timer(&g_bt->timer, - jiffies + BT_DHCP_OPPORTUNITY_WINDOW_TIME*HZ/1000); - g_bt->timer_on = 1; - break; + if (ssid && ssid->SSID_len) { + params_size += sizeof(wlc_ssid_t); + } + params = (wl_iscan_params_t*)kmalloc(params_size, GFP_KERNEL); + if (params == NULL) { + return -ENOMEM; + } + memset(params, 0, params_size); + ASSERT(params_size < WLC_IOCTL_SMLEN); - case BT_DHCP_OPPORTUNITY_WINDOW: - if (g_bt->dhcp_done) { - WL_TRACE_COEX(("%s DHCP Done before T1 expiration\n", - __FUNCTION__)); - goto btc_coex_idle; - } + err = wl_iw_iscan_prep(¶ms->params, ssid); - - WL_TRACE_COEX(("%s DHCP T1:%d expired\n", - __FUNCTION__, BT_DHCP_OPPORTUNITY_WINDOW_TIME)); - - if (g_bt->dev) wl_iw_bt_flag_set(g_bt->dev, TRUE); - g_bt->bt_state = BT_DHCP_FLAG_FORCE_TIMEOUT; - mod_timer(&g_bt->timer, jiffies + BT_DHCP_FLAG_FORCE_TIME*HZ/1000); - g_bt->timer_on = 1; - break; + if (!err) { + params->version = htod32(ISCAN_REQ_VERSION); + params->action = htod16(action); + params->scan_duration = htod16(0); - case BT_DHCP_FLAG_FORCE_TIMEOUT: - if (g_bt->dhcp_done) { - WL_TRACE_COEX(("%s DHCP Done before T2 expiration\n", - __FUNCTION__)); - } else { - - WL_TRACE_COEX(("%s DHCP wait interval T2:%d msec expired\n", - __FUNCTION__, BT_DHCP_FLAG_FORCE_TIME)); - } + + (void) dev_iw_iovar_setbuf(iscan->dev, "iscan", params, params_size, + iscan->ioctlbuf, WLC_IOCTL_SMLEN); + } - - if (g_bt->dev) wl_iw_bt_flag_set(g_bt->dev, FALSE); - btc_coex_idle: - g_bt->bt_state = BT_DHCP_IDLE; - g_bt->timer_on = 0; - break; + kfree(params); + return err; +} - default: - WL_ERROR(("%s error g_status=%d !!!\n", __FUNCTION__, - g_bt->bt_state)); - if (g_bt->dev) wl_iw_bt_flag_set(g_bt->dev, FALSE); - g_bt->bt_state = BT_DHCP_IDLE; - g_bt->timer_on = 0; - break; - } +static uint32 +wl_iw_iscan_get(iscan_info_t *iscan) +{ + iscan_buf_t * buf; + iscan_buf_t * ptr; + wl_iscan_results_t * list_buf; + wl_iscan_results_t list; + wl_scan_results_t *results; + uint32 status; - net_os_wake_unlock(g_bt->dev); + + if (iscan->list_cur) { + buf = iscan->list_cur; + iscan->list_cur = buf->next; } - - if (g_bt->timer_on) { - g_bt->timer_on = 0; - del_timer_sync(&g_bt->timer); + else { + buf = kmalloc(sizeof(iscan_buf_t), GFP_KERNEL); + if (!buf) + return WL_SCAN_RESULTS_ABORTED; + buf->next = NULL; + if (!iscan->list_hdr) + iscan->list_hdr = buf; + else { + ptr = iscan->list_hdr; + while (ptr->next) { + ptr = ptr->next; + } + ptr->next = buf; + } } - complete_and_exit(&tsk_ctl->completed, 0); + memset(buf->iscan_buf, 0, WLC_IW_ISCAN_MAXLEN); + list_buf = (wl_iscan_results_t*)buf->iscan_buf; + results = &list_buf->results; + results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE; + results->version = 0; + results->count = 0; + + memset(&list, 0, sizeof(list)); + list.results.buflen = htod32(WLC_IW_ISCAN_MAXLEN); + (void) dev_iw_iovar_getbuf( + iscan->dev, + "iscanresults", + &list, + WL_ISCAN_RESULTS_FIXED_SIZE, + buf->iscan_buf, + WLC_IW_ISCAN_MAXLEN); + results->buflen = dtoh32(results->buflen); + results->version = dtoh32(results->version); + results->count = dtoh32(results->count); + WL_TRACE(("results->count = %d\n", results->count)); + + WL_TRACE(("results->buflen = %d\n", results->buflen)); + status = dtoh32(list_buf->status); + return status; } -static void -wl_iw_bt_release(void) +static void wl_iw_send_scan_complete(iscan_info_t *iscan) { - bt_info_t *bt_local = g_bt; - - if (!bt_local) { - return; - } + union iwreq_data wrqu; + char extra[IW_CUSTOM_MAX + 1]; - if (bt_local->tsk_ctl.thr_pid >= 0) { - PROC_STOP(&bt_local->tsk_ctl); - } - kfree(bt_local); - g_bt = NULL; + memset(&wrqu, 0, sizeof(wrqu)); + memset(extra, 0, sizeof(extra)); + wireless_send_event(iscan->dev, SIOCGIWSCAN, &wrqu, extra); } static int -wl_iw_bt_init(struct net_device *dev) +_iscan_sysioc_thread(void *data) { - bt_info_t *bt_dhcp = NULL; + uint32 status; + iscan_info_t *iscan = (iscan_info_t *)data; - bt_dhcp = kmalloc(sizeof(bt_info_t), GFP_KERNEL); - if (!bt_dhcp) - return -ENOMEM; + DAEMONIZE("iscan_sysioc"); - memset(bt_dhcp, 0, sizeof(bt_info_t)); + status = WL_SCAN_RESULTS_PARTIAL; + while (down_interruptible(&iscan->sysioc_sem) == 0) { + if (iscan->timer_on) { + del_timer(&iscan->timer); + iscan->timer_on = 0; + } - g_bt = bt_dhcp; - bt_dhcp->dev = dev; - bt_dhcp->bt_state = BT_DHCP_IDLE; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) + rtnl_lock(); +#endif + status = wl_iw_iscan_get(iscan); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) + rtnl_unlock(); +#endif - - bt_dhcp->timer_ms = 10; - init_timer(&bt_dhcp->timer); - bt_dhcp->timer.data = (ulong)bt_dhcp; - bt_dhcp->timer.function = wl_iw_bt_timerfunc; - bt_dhcp->ts_dhcp_start = 0; - bt_dhcp->ts_dhcp_ok = 0; - - PROC_START(_bt_dhcp_sysioc_thread, bt_dhcp, &bt_dhcp->tsk_ctl, 0); - if (bt_dhcp->tsk_ctl.thr_pid < 0) { - WL_ERROR(("Failed in %s\n", __FUNCTION__)); - return -ENOMEM; + switch (status) { + case WL_SCAN_RESULTS_PARTIAL: + WL_TRACE(("iscanresults incomplete\n")); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) + rtnl_lock(); +#endif + + wl_iw_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) + rtnl_unlock(); +#endif + + iscan->timer.expires = jiffies + iscan->timer_ms*HZ/1000; + add_timer(&iscan->timer); + iscan->timer_on = 1; + break; + case WL_SCAN_RESULTS_SUCCESS: + WL_TRACE(("iscanresults complete\n")); + iscan->iscan_state = ISCAN_STATE_IDLE; + wl_iw_send_scan_complete(iscan); + break; + case WL_SCAN_RESULTS_PENDING: + WL_TRACE(("iscanresults pending\n")); + + iscan->timer.expires = jiffies + iscan->timer_ms*HZ/1000; + add_timer(&iscan->timer); + iscan->timer_on = 1; + break; + case WL_SCAN_RESULTS_ABORTED: + WL_TRACE(("iscanresults aborted\n")); + iscan->iscan_state = ISCAN_STATE_IDLE; + wl_iw_send_scan_complete(iscan); + break; + default: + WL_TRACE(("iscanresults returned unknown status %d\n", status)); + break; + } } - - return 0; + complete_and_exit(&iscan->sysioc_exited, 0); } -#endif int wl_iw_attach(struct net_device *dev, void * dhdp) { -#if defined(WL_IW_USE_ISCAN) - int params_size = 0; -#endif - wl_iw_t *iw; -#if defined(WL_IW_USE_ISCAN) iscan_info_t *iscan = NULL; -#endif - - DHD_OS_MUTEX_INIT(&wl_cache_lock); - DHD_OS_MUTEX_INIT(&wl_softap_lock); -#if defined(WL_IW_USE_ISCAN) if (!dev) return 0; - - memset(&g_wl_iw_params, 0, sizeof(wl_iw_extra_params_t)); - - -#ifdef CSCAN - params_size = (WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_iscan_params_t, params)) + - (WL_NUMCHANNELS * sizeof(uint16)) + WL_SCAN_PARAMS_SSID_MAX * sizeof(wlc_ssid_t); -#else - params_size = (WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_iscan_params_t, params)); -#endif iscan = kmalloc(sizeof(iscan_info_t), GFP_KERNEL); if (!iscan) return -ENOMEM; memset(iscan, 0, sizeof(iscan_info_t)); - - - iscan->iscan_ex_params_p = (wl_iscan_params_t*)kmalloc(params_size, GFP_KERNEL); - if (!iscan->iscan_ex_params_p) { - kfree(iscan); - return -ENOMEM; - } - iscan->iscan_ex_param_size = params_size; - + iscan->sysioc_pid = -1; g_iscan = iscan; iscan->dev = dev; iscan->iscan_state = ISCAN_STATE_IDLE; -#if defined(CONFIG_FIRST_SCAN) - g_first_broadcast_scan = BROADCAST_SCAN_FIRST_IDLE; - g_first_counter_scans = 0; - g_iscan->scan_flag = 0; -#endif -#ifdef CONFIG_WPS2 - g_wps_probe_req_ie = NULL; - g_wps_probe_req_ie_len = 0; -#endif - iscan->timer_ms = 8000; + iscan->timer_ms = 2000; init_timer(&iscan->timer); iscan->timer.data = (ulong)iscan; iscan->timer.function = wl_iw_timerfunc; - PROC_START(_iscan_sysioc_thread, iscan, &iscan->tsk_ctl, 0); - if (iscan->tsk_ctl.thr_pid < 0) - return -ENOMEM; -#endif - - iw = *(wl_iw_t **)netdev_priv(dev); - iw->pub = (dhd_pub_t *)dhdp; -#ifdef SOFTAP - priv_dev = dev; -#endif - g_scan = NULL; - - - g_scan = (void *)kmalloc(G_SCAN_RESULTS, GFP_KERNEL); - if (!g_scan) + sema_init(&iscan->sysioc_sem, 0); + init_completion(&iscan->sysioc_exited); + iscan->sysioc_pid = kernel_thread(_iscan_sysioc_thread, iscan, 0); + if (iscan->sysioc_pid < 0) return -ENOMEM; - - memset(g_scan, 0, G_SCAN_RESULTS); - g_scan_specified_ssid = 0; - -#if !defined(CSCAN) - - wl_iw_init_ss_cache_ctrl(); -#endif -#ifdef COEX_DHCP - - wl_iw_bt_init(dev); -#endif - - return 0; } -void -wl_iw_detach(void) +void wl_iw_detach(void) { -#if defined(WL_IW_USE_ISCAN) iscan_buf_t *buf; iscan_info_t *iscan = g_iscan; - if (!iscan) return; - if (iscan->tsk_ctl.thr_pid >= 0) { - PROC_STOP(&iscan->tsk_ctl); + if (iscan->sysioc_pid >= 0) { + KILL_PROC(iscan->sysioc_pid, SIGTERM); + wait_for_completion(&iscan->sysioc_exited); } - DHD_OS_MUTEX_LOCK(&wl_cache_lock); + while (iscan->list_hdr) { buf = iscan->list_hdr->next; kfree(iscan->list_hdr); iscan->list_hdr = buf; } - kfree(iscan->iscan_ex_params_p); kfree(iscan); g_iscan = NULL; - DHD_OS_MUTEX_UNLOCK(&wl_cache_lock); -#endif - - if (g_scan) - kfree(g_scan); - - g_scan = NULL; -#ifdef CONFIG_WPS2 +} - if (g_wps_probe_req_ie) { - kfree(g_wps_probe_req_ie); - g_wps_probe_req_ie = NULL; - g_wps_probe_req_ie_len = 0; - } -#endif -#if !defined(CSCAN) - wl_iw_release_ss_cache_ctrl(); -#endif -#ifdef COEX_DHCP - wl_iw_bt_release(); #endif - -#ifdef SOFTAP - if (ap_cfg_running) { - WL_TRACE(("\n%s AP is going down\n", __FUNCTION__)); - - wl_iw_send_priv_event(priv_dev, "AP_DOWN"); - } -#endif - -} diff --git a/drivers/net/wireless/bcmdhd/wl_iw.h b/drivers/net/wireless/bcmdhd/wl_iw.h index faca5f72e22..2afb5a683bb 100644 --- a/drivers/net/wireless/bcmdhd/wl_iw.h +++ b/drivers/net/wireless/bcmdhd/wl_iw.h @@ -1,9 +1,9 @@ /* * Linux Wireless Extensions support * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,10 +21,9 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: wl_iw.h,v 1.15.80.6 2010-12-23 01:13:23 $ + * $Id: wl_iw.h 291086 2011-10-21 01:17:24Z $ */ - #ifndef _wl_iw_h_ #define _wl_iw_h_ @@ -51,10 +50,9 @@ #define PNOSSIDCLR_SET_CMD "PNOSSIDCLR" #define PNOSETUP_SET_CMD "PNOSETUP " -#define PNOSETADD_SET_CMD "PNOSETADD" #define PNOENABLE_SET_CMD "PNOFORCE" #define PNODEBUG_SET_CMD "PNODEBUG" -#define TXPOWER_SET_CMD "TXPOWER" +#define TXPOWER_SET_CMD "TXPOWER" #define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] #define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" @@ -80,6 +78,7 @@ struct cntry_locales_custom { #define WL_IW_RSSI_EXCELLENT -57 #define WL_IW_RSSI_INVALID 0 #define MAX_WX_STRING 80 +#define SSID_FMT_BUF_LEN ((4 * 32) + 1) #define isprint(c) bcm_isprint(c) #define WL_IW_SET_ACTIVE_SCAN (SIOCIWFIRSTPRIV+1) #define WL_IW_GET_RSSI (SIOCIWFIRSTPRIV+3) @@ -89,28 +88,11 @@ struct cntry_locales_custom { #define WL_IW_SET_STOP (SIOCIWFIRSTPRIV+11) #define WL_IW_SET_START (SIOCIWFIRSTPRIV+13) - -#define WL_SET_AP_CFG (SIOCIWFIRSTPRIV+15) -#define WL_AP_STA_LIST (SIOCIWFIRSTPRIV+17) -#define WL_AP_MAC_FLTR (SIOCIWFIRSTPRIV+19) -#define WL_AP_BSS_START (SIOCIWFIRSTPRIV+21) -#define AP_LPB_CMD (SIOCIWFIRSTPRIV+23) -#define WL_AP_STOP (SIOCIWFIRSTPRIV+25) -#define WL_FW_RELOAD (SIOCIWFIRSTPRIV+27) -#define WL_AP_STA_DISASSOC (SIOCIWFIRSTPRIV+29) -#define WL_COMBO_SCAN (SIOCIWFIRSTPRIV+31) - - -#define G_SCAN_RESULTS 8*1024 +#define G_SCAN_RESULTS 8*1024 #define WE_ADD_EVENT_FIX 0x80 #define G_WLAN_SET_ON 0 #define G_WLAN_SET_OFF 1 -#define CHECK_EXTRA_FOR_NULL(extra) \ -if (!extra) { \ - WL_ERROR(("%s: error : extra is null pointer\n", __FUNCTION__)); \ - return -EINVAL; \ -} typedef struct wl_iw { char nickname[IW_ESSID_MAX_SIZE]; @@ -118,78 +100,23 @@ typedef struct wl_iw { struct iw_statistics wstats; int spy_num; - int wpaversion; - int pcipher; - int gcipher; - int privacy_invoked; - + uint32 pwsec; + uint32 gwsec; + bool privacy_invoked; struct ether_addr spy_addr[IW_MAX_SPY]; struct iw_quality spy_qual[IW_MAX_SPY]; void *wlinfo; - dhd_pub_t * pub; } wl_iw_t; -int wl_control_wl_start(struct net_device *dev); -#define WLC_IW_SS_CACHE_MAXLEN 2048 -#define WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN 32 -#define WLC_IW_BSS_INFO_MAXLEN \ - (WLC_IW_SS_CACHE_MAXLEN - WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN) - -typedef struct wl_iw_ss_cache { - struct wl_iw_ss_cache *next; - int dirty; - uint32 buflen; - uint32 version; - uint32 count; - wl_bss_info_t bss_info[1]; -} wl_iw_ss_cache_t; - -typedef struct wl_iw_ss_cache_ctrl { - wl_iw_ss_cache_t *m_cache_head; - int m_link_down; - int m_timer_expired; - char m_active_bssid[ETHER_ADDR_LEN]; - uint m_prev_scan_mode; - uint m_cons_br_scan_cnt; - struct timer_list *m_timer; -} wl_iw_ss_cache_ctrl_t; - -typedef enum broadcast_first_scan { - BROADCAST_SCAN_FIRST_IDLE = 0, - BROADCAST_SCAN_FIRST_STARTED, - BROADCAST_SCAN_FIRST_RESULT_READY, - BROADCAST_SCAN_FIRST_RESULT_CONSUMED -} broadcast_first_scan_t; -#ifdef SOFTAP -#define SSID_LEN 33 -#define SEC_LEN 16 -#define KEY_LEN 65 -#define PROFILE_OFFSET 32 -struct ap_profile { - uint8 ssid[SSID_LEN]; - uint8 sec[SEC_LEN]; - uint8 key[KEY_LEN]; - uint32 channel; - uint32 preamble; - uint32 max_scb; - uint32 closednet; - char country_code[WLC_CNTRY_BUF_SZ]; +struct wl_ctrl { + struct timer_list *timer; + struct net_device *dev; + long sysioc_pid; + struct semaphore sysioc_sem; + struct completion sysioc_exited; }; -#define MACLIST_MODE_DISABLED 0 -#define MACLIST_MODE_DENY 1 -#define MACLIST_MODE_ALLOW 2 -struct mflist { - uint count; - struct ether_addr ea[16]; -}; -struct mac_list_set { - uint32 mode; - struct mflist mac_list; -}; -#endif - #if WIRELESS_EXT > 12 #include extern const struct iw_handler_def wl_iw_handler_def; @@ -199,17 +126,21 @@ extern int wl_iw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); extern void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data); extern int wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats); int wl_iw_attach(struct net_device *dev, void * dhdp); +int wl_iw_send_priv_event(struct net_device *dev, char *flag); + void wl_iw_detach(void); -extern int net_os_wake_lock(struct net_device *dev); -extern int net_os_wake_unlock(struct net_device *dev); -extern int net_os_wake_lock_timeout(struct net_device *dev); -extern int net_os_wake_lock_timeout_enable(struct net_device *dev, int val); -extern int net_os_set_suspend_disable(struct net_device *dev, int val); -extern int net_os_set_suspend(struct net_device *dev, int val); -extern int net_os_set_dtim_skip(struct net_device *dev, int val); -extern int net_os_send_hang_message(struct net_device *dev); -extern void get_customized_country_code(char *country_iso_code, wl_country_t *cspec); +#define CSCAN_COMMAND "CSCAN " +#define CSCAN_TLV_PREFIX 'S' +#define CSCAN_TLV_VERSION 1 +#define CSCAN_TLV_SUBVERSION 0 +#define CSCAN_TLV_TYPE_SSID_IE 'S' +#define CSCAN_TLV_TYPE_CHANNEL_IE 'C' +#define CSCAN_TLV_TYPE_NPROBE_IE 'N' +#define CSCAN_TLV_TYPE_ACTIVE_IE 'A' +#define CSCAN_TLV_TYPE_PASSIVE_IE 'P' +#define CSCAN_TLV_TYPE_HOME_IE 'H' +#define CSCAN_TLV_TYPE_STYPE_IE 'T' #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) #define IWE_STREAM_ADD_EVENT(info, stream, ends, iwe, extra) \ @@ -227,93 +158,4 @@ extern void get_customized_country_code(char *country_iso_code, wl_country_t *cs iwe_stream_add_point(stream, ends, iwe, extra) #endif -extern int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled); -extern int dhd_pno_clean(dhd_pub_t *dhd); -extern int dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, - ushort scan_fr, int pno_repeat, int pno_freq_expo_max); -extern int dhd_pno_get_status(dhd_pub_t *dhd); -extern int dhd_dev_pno_reset(struct net_device *dev); -extern int dhd_dev_pno_set(struct net_device *dev, wlc_ssid_t* ssids_local, - int nssid, ushort scan_fr, int pno_repeat, int pno_freq_expo_max); -extern int dhd_dev_pno_enable(struct net_device *dev, int pfn_enabled); -extern int dhd_dev_get_pno_status(struct net_device *dev); -extern int dhd_get_dtim_skip(dhd_pub_t *dhd); - -void dhd_bus_country_set(struct net_device *dev, wl_country_t *cspec); - -#define PNO_TLV_PREFIX 'S' -#define PNO_TLV_VERSION '1' -#define PNO_TLV_SUBVERSION '2' -#define PNO_TLV_RESERVED '0' -#define PNO_TLV_TYPE_SSID_IE 'S' -#define PNO_TLV_TYPE_TIME 'T' -#define PNO_TLV_FREQ_REPEAT 'R' -#define PNO_TLV_FREQ_EXPO_MAX 'M' -#define PNO_EVENT_UP "PNO_EVENT" - -typedef struct cmd_tlv { - char prefix; - char version; - char subver; - char reserved; -} cmd_tlv_t; - - - - -typedef struct cscan_tlv { - char prefix; - char version; - char subver; - char reserved; -} cscan_tlv_t; - -#define CSCAN_COMMAND "CSCAN " -#define CSCAN_TLV_PREFIX 'S' -#define CSCAN_TLV_VERSION 1 -#define CSCAN_TLV_SUBVERSION 0 -#define CSCAN_TLV_TYPE_SSID_IE 'S' -#define CSCAN_TLV_TYPE_CHANNEL_IE 'C' -#define CSCAN_TLV_TYPE_NPROBE_IE 'N' -#define CSCAN_TLV_TYPE_ACTIVE_IE 'A' -#define CSCAN_TLV_TYPE_PASSIVE_IE 'P' -#define CSCAN_TLV_TYPE_HOME_IE 'H' -#define CSCAN_TLV_TYPE_STYPE_IE 'T' - -#ifdef SOFTAP_TLV_CFG - -#define SOFTAP_SET_CMD "SOFTAPSET " -#define SOFTAP_TLV_PREFIX 'A' -#define SOFTAP_TLV_VERSION '1' -#define SOFTAP_TLV_SUBVERSION '0' -#define SOFTAP_TLV_RESERVED '0' - -#define TLV_TYPE_SSID 'S' -#define TLV_TYPE_SECUR 'E' -#define TLV_TYPE_KEY 'K' -#define TLV_TYPE_CHANNEL 'C' -#endif - -extern int wl_iw_parse_channel_list_tlv(char** list_str, uint16* channel_list, - int channel_num, int *bytes_left); - -extern int wl_iw_parse_data_tlv(char** list_str, void *dst, int dst_size, - const char token, int input_size, int *bytes_left); - -extern int wl_iw_parse_ssid_list_tlv(char** list_str, wlc_ssid_t* ssid, - int max, int *bytes_left); - -extern int wl_iw_parse_ssid_list(char** list_str, wlc_ssid_t* ssid, int idx, int max); - -extern int wl_iw_parse_channel_list(char** list_str, uint16* channel_list, int channel_num); - - -#define NETDEV_PRIV(dev) (*(wl_iw_t **)netdev_priv(dev)) - -#ifdef CONFIG_WPS2 -#define WPS_ADD_PROBE_REQ_IE_CMD "ADD_WPS_PROBE_REQ_IE " -#define WPS_DEL_PROBE_REQ_IE_CMD "DEL_WPS_PROBE_REQ_IE " -#define WPS_PROBE_REQ_IE_CMD_LENGTH 21 -#endif - #endif diff --git a/drivers/net/wireless/bcmdhd/wl_linux_mon.c b/drivers/net/wireless/bcmdhd/wl_linux_mon.c index 243850ce85e..ab6d6f4d113 100644 --- a/drivers/net/wireless/bcmdhd/wl_linux_mon.c +++ b/drivers/net/wireless/bcmdhd/wl_linux_mon.c @@ -1,9 +1,9 @@ /* * Broadcom Dongle Host Driver (DHD), Linux monitor network interface * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -21,9 +21,10 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: wl_linux_mon.c 303266 2011-12-16 00:15:23Z $ + * $Id: dhd_linux_mon.c 280623 2011-08-30 14:49:39Z $ */ +#include #include #include #include @@ -35,7 +36,6 @@ #include #include -#include #include #include #include @@ -47,11 +47,18 @@ typedef enum monitor_states MONITOR_STATE_INTERFACE_ADDED = 0x2, MONITOR_STATE_INTERFACE_DELETED = 0x4 } monitor_states_t; +int dhd_add_monitor(char *name, struct net_device **new_ndev); extern int dhd_start_xmit(struct sk_buff *skb, struct net_device *net); +int dhd_del_monitor(struct net_device *ndev); +int dhd_monitor_init(void *dhd_pub); +int dhd_monitor_uninit(void); /** * Local declarations and defintions (not exposed) */ +#ifndef DHD_MAX_IFS +#define DHD_MAX_IFS 16 +#endif #define MON_PRINT(format, ...) printk("DHD-MON: %s " format, __func__, ##__VA_ARGS__) #define MON_TRACE MON_PRINT @@ -82,8 +89,12 @@ static const struct net_device_ops dhd_mon_if_ops = { .ndo_open = dhd_mon_if_open, .ndo_stop = dhd_mon_if_stop, .ndo_start_xmit = dhd_mon_if_subif_start_xmit, - .ndo_set_rx_mode = dhd_mon_if_set_multicast_list, - .ndo_set_mac_address = dhd_mon_if_change_mac, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) + .ndo_set_rx_mode = dhd_mon_if_set_multicast_list, +#else + .ndo_set_multicast_list = dhd_mon_if_set_multicast_list, +#endif + .ndo_set_mac_address = dhd_mon_if_change_mac, }; /** @@ -95,11 +106,12 @@ static const struct net_device_ops dhd_mon_if_ops = { */ static struct net_device* lookup_real_netdev(char *name) { + struct net_device *ndev_found = NULL; + int i; int len = 0; int last_name_len = 0; struct net_device *ndev; - struct net_device *ndev_found = NULL; /* We need to find interface "p2p-p2p-0" corresponding to monitor interface "mon-p2p-0", * Once mon iface name reaches IFNAMSIZ, it is reset to p2p0-0 and corresponding mon diff --git a/drivers/net/wireless/bcmdhd/wldev_common.c b/drivers/net/wireless/bcmdhd/wldev_common.c index d9a0b93d689..f83df791e13 100644 --- a/drivers/net/wireless/bcmdhd/wldev_common.c +++ b/drivers/net/wireless/bcmdhd/wldev_common.c @@ -1,9 +1,9 @@ /* * Common function shared by Linux WEXT, cfg80211 and p2p drivers * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the @@ -53,6 +53,7 @@ s32 wldev_ioctl( s32 ret = 0; struct wl_ioctl ioc; + memset(&ioc, 0, sizeof(ioc)); ioc.cmd = cmd; ioc.buf = arg; @@ -60,6 +61,7 @@ s32 wldev_ioctl( ioc.set = set; ret = dhd_ioctl_entry_local(dev, &ioc, cmd); + return ret; } @@ -82,11 +84,10 @@ s32 wldev_iovar_getbuf( void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync) { s32 ret = 0; - s32 iovar_len = 0; if (buf_sync) { mutex_lock(buf_sync); } - iovar_len = wldev_mkiovar(iovar_name, param, paramlen, buf, buflen); + wldev_mkiovar(iovar_name, param, paramlen, buf, buflen); ret = wldev_ioctl(dev, WLC_GET_VAR, buf, buflen, FALSE); if (buf_sync) mutex_unlock(buf_sync); @@ -196,11 +197,11 @@ s32 wldev_iovar_getbuf_bsscfg( void *param, s32 paramlen, void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync) { s32 ret = 0; - s32 iovar_len = 0; if (buf_sync) { mutex_lock(buf_sync); } - iovar_len = wldev_mkiovar_bsscfg(iovar_name, param, paramlen, buf, buflen, bsscfg_idx); + + wldev_mkiovar_bsscfg(iovar_name, param, paramlen, buf, buflen, bsscfg_idx); ret = wldev_ioctl(dev, WLC_GET_VAR, buf, buflen, FALSE); if (buf_sync) { mutex_unlock(buf_sync); @@ -219,7 +220,6 @@ s32 wldev_iovar_setbuf_bsscfg( mutex_lock(buf_sync); } iovar_len = wldev_mkiovar_bsscfg(iovar_name, param, paramlen, buf, buflen, bsscfg_idx); - ret = wldev_ioctl(dev, WLC_SET_VAR, buf, iovar_len, TRUE); if (buf_sync) { mutex_unlock(buf_sync); diff --git a/drivers/net/wireless/bcmdhd/wldev_common.h b/drivers/net/wireless/bcmdhd/wldev_common.h index 6a1ba153360..16a071f5e5a 100644 --- a/drivers/net/wireless/bcmdhd/wldev_common.h +++ b/drivers/net/wireless/bcmdhd/wldev_common.h @@ -1,9 +1,9 @@ /* * Common function shared by Linux WEXT, cfg80211 and p2p drivers * - * Copyright (C) 1999-2011, Broadcom Corporation + * Copyright (C) 1999-2012, Broadcom Corporation * - * Unless you and Broadcom execute a separate written software license + * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the -- cgit v1.2.3 From 3c63797031913f63fe31671d6de47014f00af415 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sat, 11 Feb 2012 00:00:11 +0100 Subject: PM / Sleep: Initialize wakeup source locks in wakeup_source_add() Initialize wakeup source locks in wakeup_source_add() instead of wakeup_source_create(), because otherwise the locks of the wakeup sources that haven't been allocated with wakeup_source_create() aren't initialized and handled properly. Signed-off-by: Rafael J. Wysocki --- drivers/base/power/wakeup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index caf995fb774..6e591a8a49d 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -64,7 +64,6 @@ struct wakeup_source *wakeup_source_create(const char *name) if (!ws) return NULL; - spin_lock_init(&ws->lock); if (name) ws->name = kstrdup(name, GFP_KERNEL); @@ -105,6 +104,7 @@ void wakeup_source_add(struct wakeup_source *ws) if (WARN_ON(!ws)) return; + spin_lock_init(&ws->lock); setup_timer(&ws->timer, pm_wakeup_timer_fn, (unsigned long)ws); ws->active = false; -- cgit v1.2.3 From 649caa0ad80f49bbb7b90012433973809ead8826 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 17 Feb 2012 23:39:20 +0100 Subject: PM / Sleep: Fix possible infinite loop during wakeup source destruction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If wakeup_source_destroy() is called for an active wakeup source that is never deactivated, it will spin forever. To prevent that from happening, make wakeup_source_destroy() call __pm_relax() for the wakeup source object it is about to free instead of waiting until it will be deactivated by someone else. However, for this to work it also needs to make sure that the timer function will not be executed after the final __pm_relax(), so make it run del_timer_sync() on the wakeup source's timer beforehand. Additionally, update the kerneldoc comment to document the requirement that __pm_stay_awake() and __pm_wakeup_event() must not be run in parallel with wakeup_source_destroy(). Reported-by: Arve Hjønnevåg Signed-off-by: Rafael J. Wysocki --- drivers/base/power/wakeup.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index 6e591a8a49d..d279f462d62 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -74,22 +74,17 @@ EXPORT_SYMBOL_GPL(wakeup_source_create); /** * wakeup_source_destroy - Destroy a struct wakeup_source object. * @ws: Wakeup source to destroy. + * + * Callers must ensure that __pm_stay_awake() or __pm_wakeup_event() will never + * be run in parallel with this function for the same wakeup source object. */ void wakeup_source_destroy(struct wakeup_source *ws) { if (!ws) return; - spin_lock_irq(&ws->lock); - while (ws->active) { - spin_unlock_irq(&ws->lock); - - schedule_timeout_interruptible(msecs_to_jiffies(TIMEOUT)); - - spin_lock_irq(&ws->lock); - } - spin_unlock_irq(&ws->lock); - + del_timer_sync(&ws->timer); + __pm_relax(ws); kfree(ws->name); kfree(ws); } -- cgit v1.2.3 From 91b83809ffb978a4477c25dbef86a800149f2bd1 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 17 Feb 2012 23:39:33 +0100 Subject: PM / Sleep: Fix race conditions related to wakeup source timer function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If __pm_wakeup_event() has been used (with a nonzero timeout) to report a wakeup event and then __pm_relax() immediately followed by __pm_stay_awake() is called or __pm_wakeup_event() is called once again for the same wakeup source object before its timer expires, the timer function pm_wakeup_timer_fn() may still be run as a result of the previous __pm_wakeup_event() call. In either of those cases it may mistakenly deactivate the wakeup source that has just been activated. To prevent that from happening, make wakeup_source_deactivate() clear the wakeup source's timer_expires field and make pm_wakeup_timer_fn() check if timer_expires is different from zero and if it's not in future before calling wakeup_source_deactivate() (if timer_expires is 0, it means that the timer has just been deleted and if timer_expires is in future, it means that the timer has just been rescheduled to a different time). Reported-by: Arve Hjønnevåg Signed-off-by: Rafael J. Wysocki --- drivers/base/power/wakeup.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index d279f462d62..b38bb9afb71 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -433,6 +433,7 @@ static void wakeup_source_deactivate(struct wakeup_source *ws) ws->max_time = duration; del_timer(&ws->timer); + ws->timer_expires = 0; /* * Increment the counter of registered wakeup events and decrement the @@ -487,11 +488,22 @@ EXPORT_SYMBOL_GPL(pm_relax); * pm_wakeup_timer_fn - Delayed finalization of a wakeup event. * @data: Address of the wakeup source object associated with the event source. * - * Call __pm_relax() for the wakeup source whose address is stored in @data. + * Call wakeup_source_deactivate() for the wakeup source whose address is stored + * in @data if it is currently active and its timer has not been canceled and + * the expiration time of the timer is not in future. */ static void pm_wakeup_timer_fn(unsigned long data) { - __pm_relax((struct wakeup_source *)data); + struct wakeup_source *ws = (struct wakeup_source *)data; + unsigned long flags; + + spin_lock_irqsave(&ws->lock, flags); + + if (ws->active && ws->timer_expires + && time_after_eq(jiffies, ws->timer_expires)) + wakeup_source_deactivate(ws); + + spin_unlock_irqrestore(&ws->lock, flags); } /** -- cgit v1.2.3 From dd84d8514db926fc84a2332ebf5f254cf46fe740 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 17 Feb 2012 23:39:39 +0100 Subject: PM / Sleep: Make __pm_stay_awake() delete wakeup source timers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If __pm_stay_awake() is called after __pm_wakeup_event() for the same wakep source object before its timer expires, it won't cancel the timer, so the wakeup source will be deactivated from the timer function as scheduled by __pm_wakeup_event(). In that case __pm_stay_awake() doesn't have any effect beyond incrementing the wakeup source's event_count field, although it should cancel the timer and make the wakeup source stay active until __pm_relax() is called for it. To fix this problem make __pm_stay_awake() delete the wakeup source's timer and ensure that it won't be deactivated from the timer funtion afterwards by clearing its timer_expires field. Reported-by: Arve Hjønnevåg Signed-off-by: Rafael J. Wysocki --- drivers/base/power/wakeup.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index b38bb9afb71..7c5ab70b9ef 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -344,7 +344,6 @@ static void wakeup_source_activate(struct wakeup_source *ws) { ws->active = true; ws->active_count++; - ws->timer_expires = jiffies; ws->last_time = ktime_get(); /* Increment the counter of events in progress. */ @@ -365,9 +364,14 @@ void __pm_stay_awake(struct wakeup_source *ws) return; spin_lock_irqsave(&ws->lock, flags); + ws->event_count++; if (!ws->active) wakeup_source_activate(ws); + + del_timer(&ws->timer); + ws->timer_expires = 0; + spin_unlock_irqrestore(&ws->lock, flags); } EXPORT_SYMBOL_GPL(__pm_stay_awake); @@ -541,7 +545,7 @@ void __pm_wakeup_event(struct wakeup_source *ws, unsigned int msec) if (!expires) expires = 1; - if (time_after(expires, ws->timer_expires)) { + if (!ws->timer_expires || time_after(expires, ws->timer_expires)) { mod_timer(&ws->timer, expires); ws->timer_expires = expires; } -- cgit v1.2.3 From d916481e7a1603ae5aec6350d089343e9bc70fcc Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 21 Feb 2012 23:47:56 +0100 Subject: PM / Sleep: Add more wakeup source initialization routines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The existing wakeup source initialization routines are not particularly useful for wakeup sources that aren't created by wakeup_source_create(), because their users have to open code filling the objects with zeros and setting their names. For this reason, introduce routines that can be used for initializing, for example, static wakeup source objects. Requested-by: Arve Hjønnevåg Signed-off-by: Rafael J. Wysocki --- drivers/base/power/wakeup.c | 50 +++++++++++++++++++++++++++++++++++++-------- include/linux/pm_wakeup.h | 22 +++++++++++++++++++- 2 files changed, 62 insertions(+), 10 deletions(-) diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index 7c5ab70b9ef..2a3e581b8dc 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -52,6 +52,23 @@ static void pm_wakeup_timer_fn(unsigned long data); static LIST_HEAD(wakeup_sources); +/** + * wakeup_source_prepare - Prepare a new wakeup source for initialization. + * @ws: Wakeup source to prepare. + * @name: Pointer to the name of the new wakeup source. + * + * Callers must ensure that the @name string won't be freed when @ws is still in + * use. + */ +void wakeup_source_prepare(struct wakeup_source *ws, const char *name) +{ + if (ws) { + memset(ws, 0, sizeof(*ws)); + ws->name = name; + } +} +EXPORT_SYMBOL_GPL(wakeup_source_prepare); + /** * wakeup_source_create - Create a struct wakeup_source object. * @name: Name of the new wakeup source. @@ -60,31 +77,44 @@ struct wakeup_source *wakeup_source_create(const char *name) { struct wakeup_source *ws; - ws = kzalloc(sizeof(*ws), GFP_KERNEL); + ws = kmalloc(sizeof(*ws), GFP_KERNEL); if (!ws) return NULL; - if (name) - ws->name = kstrdup(name, GFP_KERNEL); - + wakeup_source_prepare(ws, name ? kstrdup(name, GFP_KERNEL) : NULL); return ws; } EXPORT_SYMBOL_GPL(wakeup_source_create); /** - * wakeup_source_destroy - Destroy a struct wakeup_source object. - * @ws: Wakeup source to destroy. + * wakeup_source_drop - Prepare a struct wakeup_source object for destruction. + * @ws: Wakeup source to prepare for destruction. * * Callers must ensure that __pm_stay_awake() or __pm_wakeup_event() will never * be run in parallel with this function for the same wakeup source object. */ -void wakeup_source_destroy(struct wakeup_source *ws) +void wakeup_source_drop(struct wakeup_source *ws) { if (!ws) return; del_timer_sync(&ws->timer); __pm_relax(ws); +} +EXPORT_SYMBOL_GPL(wakeup_source_drop); + +/** + * wakeup_source_destroy - Destroy a struct wakeup_source object. + * @ws: Wakeup source to destroy. + * + * Use only for wakeup source objects created with wakeup_source_create(). + */ +void wakeup_source_destroy(struct wakeup_source *ws) +{ + if (!ws) + return; + + wakeup_source_drop(ws); kfree(ws->name); kfree(ws); } @@ -147,8 +177,10 @@ EXPORT_SYMBOL_GPL(wakeup_source_register); */ void wakeup_source_unregister(struct wakeup_source *ws) { - wakeup_source_remove(ws); - wakeup_source_destroy(ws); + if (ws) { + wakeup_source_remove(ws); + wakeup_source_destroy(ws); + } } EXPORT_SYMBOL_GPL(wakeup_source_unregister); diff --git a/include/linux/pm_wakeup.h b/include/linux/pm_wakeup.h index a32da962d69..d9f05113e5f 100644 --- a/include/linux/pm_wakeup.h +++ b/include/linux/pm_wakeup.h @@ -41,7 +41,7 @@ * @active: Status of the wakeup source. */ struct wakeup_source { - char *name; + const char *name; struct list_head entry; spinlock_t lock; struct timer_list timer; @@ -73,7 +73,9 @@ static inline bool device_may_wakeup(struct device *dev) } /* drivers/base/power/wakeup.c */ +extern void wakeup_source_prepare(struct wakeup_source *ws, const char *name); extern struct wakeup_source *wakeup_source_create(const char *name); +extern void wakeup_source_drop(struct wakeup_source *ws); extern void wakeup_source_destroy(struct wakeup_source *ws); extern void wakeup_source_add(struct wakeup_source *ws); extern void wakeup_source_remove(struct wakeup_source *ws); @@ -103,11 +105,16 @@ static inline bool device_can_wakeup(struct device *dev) return dev->power.can_wakeup; } +static inline void wakeup_source_prepare(struct wakeup_source *ws, + const char *name) {} + static inline struct wakeup_source *wakeup_source_create(const char *name) { return NULL; } +static inline void wakeup_source_drop(struct wakeup_source *ws) {} + static inline void wakeup_source_destroy(struct wakeup_source *ws) {} static inline void wakeup_source_add(struct wakeup_source *ws) {} @@ -165,4 +172,17 @@ static inline void pm_wakeup_event(struct device *dev, unsigned int msec) {} #endif /* !CONFIG_PM_SLEEP */ +static inline void wakeup_source_init(struct wakeup_source *ws, + const char *name) +{ + wakeup_source_prepare(ws, name); + wakeup_source_add(ws); +} + +static inline void wakeup_source_trash(struct wakeup_source *ws) +{ + wakeup_source_remove(ws); + wakeup_source_drop(ws); +} + #endif /* _LINUX_PM_WAKEUP_H */ -- cgit v1.2.3 From 5f4f3e1ccb796faf0e8cdab7128f28a6a9d8bf01 Mon Sep 17 00:00:00 2001 From: Arve Hjønnevåg Date: Fri, 16 Mar 2012 17:38:31 -0700 Subject: Revert "PM: Backoff suspend if repeated attempts fail" This reverts commit b5989152ac6a54f792eee3fc43a5bdbe940da189. Change-Id: I8bc0be116d8d5ced3f16f2bfe897a2891e4f4826 --- kernel/power/wakelock.c | 39 ++++----------------------------------- 1 file changed, 4 insertions(+), 35 deletions(-) diff --git a/kernel/power/wakelock.c b/kernel/power/wakelock.c index 81e1b7c65ca..2ee459fe445 100644 --- a/kernel/power/wakelock.c +++ b/kernel/power/wakelock.c @@ -48,12 +48,6 @@ struct workqueue_struct *suspend_work_queue; struct wake_lock main_wake_lock; suspend_state_t requested_suspend_state = PM_SUSPEND_MEM; static struct wake_lock unknown_wakeup; -static struct wake_lock suspend_backoff_lock; - -#define SUSPEND_BACKOFF_THRESHOLD 10 -#define SUSPEND_BACKOFF_INTERVAL 10000 - -static unsigned suspend_short_count; #ifdef CONFIG_WAKELOCK_STAT static struct wake_lock deleted_wake_locks; @@ -261,18 +255,10 @@ long has_wake_lock(int type) return ret; } -static void suspend_backoff(void) -{ - pr_info("suspend: too many immediate wakeups, back off\n"); - wake_lock_timeout(&suspend_backoff_lock, - msecs_to_jiffies(SUSPEND_BACKOFF_INTERVAL)); -} - static void suspend(struct work_struct *work) { int ret; int entry_event_num; - struct timespec ts_entry, ts_exit; if (has_wake_lock(WAKE_LOCK_SUSPEND)) { if (debug_mask & DEBUG_SUSPEND) @@ -284,30 +270,17 @@ static void suspend(struct work_struct *work) sys_sync(); if (debug_mask & DEBUG_SUSPEND) pr_info("suspend: enter suspend\n"); - getnstimeofday(&ts_entry); ret = pm_suspend(requested_suspend_state); - getnstimeofday(&ts_exit); - if (debug_mask & DEBUG_EXIT_SUSPEND) { + struct timespec ts; struct rtc_time tm; - rtc_time_to_tm(ts_exit.tv_sec, &tm); + getnstimeofday(&ts); + rtc_time_to_tm(ts.tv_sec, &tm); pr_info("suspend: exit suspend, ret = %d " "(%d-%02d-%02d %02d:%02d:%02d.%09lu UTC)\n", ret, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec, ts_exit.tv_nsec); + tm.tm_hour, tm.tm_min, tm.tm_sec, ts.tv_nsec); } - - if (ts_exit.tv_sec - ts_entry.tv_sec <= 1) { - ++suspend_short_count; - - if (suspend_short_count == SUSPEND_BACKOFF_THRESHOLD) { - suspend_backoff(); - suspend_short_count = 0; - } - } else { - suspend_short_count = 0; - } - if (current_event_num == entry_event_num) { if (debug_mask & DEBUG_SUSPEND) pr_info("suspend: pm_suspend returned with no event\n"); @@ -574,8 +547,6 @@ static int __init wakelocks_init(void) wake_lock_init(&main_wake_lock, WAKE_LOCK_SUSPEND, "main"); wake_lock(&main_wake_lock); wake_lock_init(&unknown_wakeup, WAKE_LOCK_SUSPEND, "unknown_wakeups"); - wake_lock_init(&suspend_backoff_lock, WAKE_LOCK_SUSPEND, - "suspend_backoff"); ret = platform_device_register(&power_device); if (ret) { @@ -605,7 +576,6 @@ err_suspend_work_queue: err_platform_driver_register: platform_device_unregister(&power_device); err_platform_device_register: - wake_lock_destroy(&suspend_backoff_lock); wake_lock_destroy(&unknown_wakeup); wake_lock_destroy(&main_wake_lock); #ifdef CONFIG_WAKELOCK_STAT @@ -622,7 +592,6 @@ static void __exit wakelocks_exit(void) destroy_workqueue(suspend_work_queue); platform_driver_unregister(&power_driver); platform_device_unregister(&power_device); - wake_lock_destroy(&suspend_backoff_lock); wake_lock_destroy(&unknown_wakeup); wake_lock_destroy(&main_wake_lock); #ifdef CONFIG_WAKELOCK_STAT -- cgit v1.2.3 From 4e5efb80aff84d7ae5b6efd00533536bb3de0fda Mon Sep 17 00:00:00 2001 From: Arve Hjønnevåg Date: Fri, 16 Mar 2012 17:38:49 -0700 Subject: Revert "PM: wakelock: Don't dump unfrozen task list when aborting try_to_freeze_tasks after less than one second" This reverts commit 6e4b6932f7f1d7a9ce5b537b545fa924b83f21b6. Change-Id: Ib87877dd899c1bb95dec4407de15969773c70b02 --- kernel/power/process.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kernel/power/process.c b/kernel/power/process.c index 581df782512..8fee8d00e3a 100644 --- a/kernel/power/process.c +++ b/kernel/power/process.c @@ -118,8 +118,7 @@ static int try_to_freeze_tasks(bool user_only) read_lock(&tasklist_lock); do_each_thread(g, p) { if (!wakeup && !freezer_should_skip(p) && - p != current && freezing(p) && !frozen(p) && - elapsed_csecs > 100) + p != current && freezing(p) && !frozen(p)) sched_show_task(p); } while_each_thread(g, p); read_unlock(&tasklist_lock); -- cgit v1.2.3 From 8ef22d7f625ad06bea63351eb48b5418f2f5a7e2 Mon Sep 17 00:00:00 2001 From: Arve Hjønnevåg Date: Fri, 16 Mar 2012 17:39:10 -0700 Subject: Revert "PM: wakelock: Abort task freezing if a wake lock is held." This reverts commit dce3610a81ec6ef81ee90b2640d2dac7efcc0a15. Change-Id: Icb94f687cda4cee22c8ca582dba60aa15b3c9e57 --- kernel/power/process.c | 29 ++++++----------------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/kernel/power/process.c b/kernel/power/process.c index 8fee8d00e3a..7e426459e60 100644 --- a/kernel/power/process.c +++ b/kernel/power/process.c @@ -16,7 +16,6 @@ #include #include #include -#include /* * Timeout for stopping processes @@ -71,10 +70,6 @@ static int try_to_freeze_tasks(bool user_only) todo += wq_busy; } - if (todo && has_wake_lock(WAKE_LOCK_SUSPEND)) { - wakeup = 1; - break; - } if (!todo || time_after(jiffies, end_time)) break; @@ -96,24 +91,12 @@ static int try_to_freeze_tasks(bool user_only) elapsed_csecs = elapsed_csecs64; if (todo) { - /* This does not unfreeze processes that are already frozen - * (we have slightly ugly calling convention in that respect, - * and caller must call thaw_processes() if something fails), - * but it cleans up leftover PF_FREEZE requests. - */ - if(wakeup) { - printk("\n"); - printk(KERN_ERR "Freezing of %s aborted\n", - user_only ? "user space " : "tasks "); - } - else { - printk("\n"); - printk(KERN_ERR "Freezing of tasks %s after %d.%02d seconds " - "(%d tasks refusing to freeze, wq_busy=%d):\n", - wakeup ? "aborted" : "failed", - elapsed_csecs / 100, elapsed_csecs % 100, - todo - wq_busy, wq_busy); - } + printk("\n"); + printk(KERN_ERR "Freezing of tasks %s after %d.%02d seconds " + "(%d tasks refusing to freeze, wq_busy=%d):\n", + wakeup ? "aborted" : "failed", + elapsed_csecs / 100, elapsed_csecs % 100, + todo - wq_busy, wq_busy); read_lock(&tasklist_lock); do_each_thread(g, p) { -- cgit v1.2.3 From c81843338fb936ce5c582acbd0f56606a6fdd5c8 Mon Sep 17 00:00:00 2001 From: Arve Hjønnevåg Date: Fri, 16 Mar 2012 17:39:38 -0700 Subject: Revert "PM: Add user-space wake lock api." This reverts commit 92e7a6e6a59c3cf0742621309a1d534eaecab5f5. Change-Id: I1d44ce687b0053c6a8e29f49e02c508d1741c081 --- kernel/power/Kconfig | 10 -- kernel/power/Makefile | 1 - kernel/power/main.c | 9 -- kernel/power/power.h | 11 --- kernel/power/userwakelock.c | 219 -------------------------------------------- 5 files changed, 250 deletions(-) delete mode 100644 kernel/power/userwakelock.c diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index aa728bc65ae..4916349285b 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig @@ -37,16 +37,6 @@ config WAKELOCK_STAT ---help--- Report wake lock stats in /proc/wakelocks -config USER_WAKELOCK - bool "Userspace wake locks" - depends on WAKELOCK - default y - ---help--- - User-space wake lock api. Write "lockname" or "lockname timeout" - to /sys/power/wake_lock lock and if needed create a wake lock. - Write "lockname" to /sys/power/wake_unlock to unlock a user wake - lock. - config HIBERNATE_CALLBACKS bool diff --git a/kernel/power/Makefile b/kernel/power/Makefile index 58eb0aac0b3..0f41f20311c 100644 --- a/kernel/power/Makefile +++ b/kernel/power/Makefile @@ -9,7 +9,6 @@ obj-$(CONFIG_PM_TEST_SUSPEND) += suspend_test.o obj-$(CONFIG_HIBERNATION) += hibernate.o snapshot.o swap.o user.o \ block_io.o obj-$(CONFIG_WAKELOCK) += wakelock.o -obj-$(CONFIG_USER_WAKELOCK) += userwakelock.o obj-$(CONFIG_SUSPEND_TIME) += suspend_time.o obj-$(CONFIG_MAGIC_SYSRQ) += poweroff.o diff --git a/kernel/power/main.c b/kernel/power/main.c index 1edafb23ee9..9824b41e5a1 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -402,11 +402,6 @@ power_attr(pm_trace_dev_match); #endif /* CONFIG_PM_TRACE */ -#ifdef CONFIG_USER_WAKELOCK -power_attr(wake_lock); -power_attr(wake_unlock); -#endif - static struct attribute * g[] = { &state_attr.attr, #ifdef CONFIG_PM_TRACE @@ -419,10 +414,6 @@ static struct attribute * g[] = { #ifdef CONFIG_PM_DEBUG &pm_test_attr.attr, #endif -#ifdef CONFIG_USER_WAKELOCK - &wake_lock_attr.attr, - &wake_unlock_attr.attr, -#endif #endif NULL, }; diff --git a/kernel/power/power.h b/kernel/power/power.h index a16bcef540a..fcf91e3d181 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h @@ -276,14 +276,3 @@ extern struct workqueue_struct *suspend_work_queue; extern struct wake_lock main_wake_lock; extern suspend_state_t requested_suspend_state; #endif - -#ifdef CONFIG_USER_WAKELOCK -ssize_t wake_lock_show(struct kobject *kobj, struct kobj_attribute *attr, - char *buf); -ssize_t wake_lock_store(struct kobject *kobj, struct kobj_attribute *attr, - const char *buf, size_t n); -ssize_t wake_unlock_show(struct kobject *kobj, struct kobj_attribute *attr, - char *buf); -ssize_t wake_unlock_store(struct kobject *kobj, struct kobj_attribute *attr, - const char *buf, size_t n); -#endif diff --git a/kernel/power/userwakelock.c b/kernel/power/userwakelock.c deleted file mode 100644 index a28a8db4146..00000000000 --- a/kernel/power/userwakelock.c +++ /dev/null @@ -1,219 +0,0 @@ -/* kernel/power/userwakelock.c - * - * Copyright (C) 2005-2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include - -#include "power.h" - -enum { - DEBUG_FAILURE = BIT(0), - DEBUG_ERROR = BIT(1), - DEBUG_NEW = BIT(2), - DEBUG_ACCESS = BIT(3), - DEBUG_LOOKUP = BIT(4), -}; -static int debug_mask = DEBUG_FAILURE; -module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); - -static DEFINE_MUTEX(tree_lock); - -struct user_wake_lock { - struct rb_node node; - struct wake_lock wake_lock; - char name[0]; -}; -struct rb_root user_wake_locks; - -static struct user_wake_lock *lookup_wake_lock_name( - const char *buf, int allocate, long *timeoutptr) -{ - struct rb_node **p = &user_wake_locks.rb_node; - struct rb_node *parent = NULL; - struct user_wake_lock *l; - int diff; - u64 timeout; - int name_len; - const char *arg; - - /* Find length of lock name and start of optional timeout string */ - arg = buf; - while (*arg && !isspace(*arg)) - arg++; - name_len = arg - buf; - if (!name_len) - goto bad_arg; - while (isspace(*arg)) - arg++; - - /* Process timeout string */ - if (timeoutptr && *arg) { - timeout = simple_strtoull(arg, (char **)&arg, 0); - while (isspace(*arg)) - arg++; - if (*arg) - goto bad_arg; - /* convert timeout from nanoseconds to jiffies > 0 */ - timeout += (NSEC_PER_SEC / HZ) - 1; - do_div(timeout, (NSEC_PER_SEC / HZ)); - if (timeout <= 0) - timeout = 1; - *timeoutptr = timeout; - } else if (*arg) - goto bad_arg; - else if (timeoutptr) - *timeoutptr = 0; - - /* Lookup wake lock in rbtree */ - while (*p) { - parent = *p; - l = rb_entry(parent, struct user_wake_lock, node); - diff = strncmp(buf, l->name, name_len); - if (!diff && l->name[name_len]) - diff = -1; - if (debug_mask & DEBUG_ERROR) - pr_info("lookup_wake_lock_name: compare %.*s %s %d\n", - name_len, buf, l->name, diff); - - if (diff < 0) - p = &(*p)->rb_left; - else if (diff > 0) - p = &(*p)->rb_right; - else - return l; - } - - /* Allocate and add new wakelock to rbtree */ - if (!allocate) { - if (debug_mask & DEBUG_ERROR) - pr_info("lookup_wake_lock_name: %.*s not found\n", - name_len, buf); - return ERR_PTR(-EINVAL); - } - l = kzalloc(sizeof(*l) + name_len + 1, GFP_KERNEL); - if (l == NULL) { - if (debug_mask & DEBUG_FAILURE) - pr_err("lookup_wake_lock_name: failed to allocate " - "memory for %.*s\n", name_len, buf); - return ERR_PTR(-ENOMEM); - } - memcpy(l->name, buf, name_len); - if (debug_mask & DEBUG_NEW) - pr_info("lookup_wake_lock_name: new wake lock %s\n", l->name); - wake_lock_init(&l->wake_lock, WAKE_LOCK_SUSPEND, l->name); - rb_link_node(&l->node, parent, p); - rb_insert_color(&l->node, &user_wake_locks); - return l; - -bad_arg: - if (debug_mask & DEBUG_ERROR) - pr_info("lookup_wake_lock_name: wake lock, %.*s, bad arg, %s\n", - name_len, buf, arg); - return ERR_PTR(-EINVAL); -} - -ssize_t wake_lock_show( - struct kobject *kobj, struct kobj_attribute *attr, char *buf) -{ - char *s = buf; - char *end = buf + PAGE_SIZE; - struct rb_node *n; - struct user_wake_lock *l; - - mutex_lock(&tree_lock); - - for (n = rb_first(&user_wake_locks); n != NULL; n = rb_next(n)) { - l = rb_entry(n, struct user_wake_lock, node); - if (wake_lock_active(&l->wake_lock)) - s += scnprintf(s, end - s, "%s ", l->name); - } - s += scnprintf(s, end - s, "\n"); - - mutex_unlock(&tree_lock); - return (s - buf); -} - -ssize_t wake_lock_store( - struct kobject *kobj, struct kobj_attribute *attr, - const char *buf, size_t n) -{ - long timeout; - struct user_wake_lock *l; - - mutex_lock(&tree_lock); - l = lookup_wake_lock_name(buf, 1, &timeout); - if (IS_ERR(l)) { - n = PTR_ERR(l); - goto bad_name; - } - - if (debug_mask & DEBUG_ACCESS) - pr_info("wake_lock_store: %s, timeout %ld\n", l->name, timeout); - - if (timeout) - wake_lock_timeout(&l->wake_lock, timeout); - else - wake_lock(&l->wake_lock); -bad_name: - mutex_unlock(&tree_lock); - return n; -} - - -ssize_t wake_unlock_show( - struct kobject *kobj, struct kobj_attribute *attr, char *buf) -{ - char *s = buf; - char *end = buf + PAGE_SIZE; - struct rb_node *n; - struct user_wake_lock *l; - - mutex_lock(&tree_lock); - - for (n = rb_first(&user_wake_locks); n != NULL; n = rb_next(n)) { - l = rb_entry(n, struct user_wake_lock, node); - if (!wake_lock_active(&l->wake_lock)) - s += scnprintf(s, end - s, "%s ", l->name); - } - s += scnprintf(s, end - s, "\n"); - - mutex_unlock(&tree_lock); - return (s - buf); -} - -ssize_t wake_unlock_store( - struct kobject *kobj, struct kobj_attribute *attr, - const char *buf, size_t n) -{ - struct user_wake_lock *l; - - mutex_lock(&tree_lock); - l = lookup_wake_lock_name(buf, 0, NULL); - if (IS_ERR(l)) { - n = PTR_ERR(l); - goto not_found; - } - - if (debug_mask & DEBUG_ACCESS) - pr_info("wake_unlock_store: %s\n", l->name); - - wake_unlock(&l->wake_lock); -not_found: - mutex_unlock(&tree_lock); - return n; -} - -- cgit v1.2.3 From e42744039e4536975ddd1a81219f41c30576c1ad Mon Sep 17 00:00:00 2001 From: Arve Hjønnevåg Date: Fri, 16 Mar 2012 17:40:01 -0700 Subject: Revert "PM: Implement wakelock api." This reverts commit 596f2eedbddfce675d86d0c4ba992294cd39aaba. Change-Id: I7bf20d381ad21edc1720e411de16b2d617ae1a63 --- kernel/power/Kconfig | 19 -- kernel/power/Makefile | 1 - kernel/power/power.h | 7 - kernel/power/wakelock.c | 603 ------------------------------------------------ 4 files changed, 630 deletions(-) delete mode 100644 kernel/power/wakelock.c diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index 4916349285b..1878b6ef2a2 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig @@ -18,25 +18,6 @@ config SUSPEND_FREEZER Turning OFF this setting is NOT recommended! If in doubt, say Y. -config HAS_WAKELOCK - bool - -config WAKELOCK - bool "Wake lock" - depends on PM && RTC_CLASS - default n - select HAS_WAKELOCK - ---help--- - Enable wakelocks. When user space request a sleep state the - sleep request will be delayed until no wake locks are held. - -config WAKELOCK_STAT - bool "Wake lock stats" - depends on WAKELOCK - default y - ---help--- - Report wake lock stats in /proc/wakelocks - config HIBERNATE_CALLBACKS bool diff --git a/kernel/power/Makefile b/kernel/power/Makefile index 0f41f20311c..58f237137c9 100644 --- a/kernel/power/Makefile +++ b/kernel/power/Makefile @@ -8,7 +8,6 @@ obj-$(CONFIG_SUSPEND) += suspend.o obj-$(CONFIG_PM_TEST_SUSPEND) += suspend_test.o obj-$(CONFIG_HIBERNATION) += hibernate.o snapshot.o swap.o user.o \ block_io.o -obj-$(CONFIG_WAKELOCK) += wakelock.o obj-$(CONFIG_SUSPEND_TIME) += suspend_time.o obj-$(CONFIG_MAGIC_SYSRQ) += poweroff.o diff --git a/kernel/power/power.h b/kernel/power/power.h index fcf91e3d181..21724eee520 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h @@ -269,10 +269,3 @@ static inline void suspend_thaw_processes(void) { } #endif - -#ifdef CONFIG_WAKELOCK -/* kernel/power/wakelock.c */ -extern struct workqueue_struct *suspend_work_queue; -extern struct wake_lock main_wake_lock; -extern suspend_state_t requested_suspend_state; -#endif diff --git a/kernel/power/wakelock.c b/kernel/power/wakelock.c deleted file mode 100644 index 2ee459fe445..00000000000 --- a/kernel/power/wakelock.c +++ /dev/null @@ -1,603 +0,0 @@ -/* kernel/power/wakelock.c - * - * Copyright (C) 2005-2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include /* sys_sync */ -#include -#ifdef CONFIG_WAKELOCK_STAT -#include -#endif -#include "power.h" - -enum { - DEBUG_EXIT_SUSPEND = 1U << 0, - DEBUG_WAKEUP = 1U << 1, - DEBUG_SUSPEND = 1U << 2, - DEBUG_EXPIRE = 1U << 3, - DEBUG_WAKE_LOCK = 1U << 4, -}; -static int debug_mask = DEBUG_EXIT_SUSPEND | DEBUG_WAKEUP; -module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); - -#define WAKE_LOCK_TYPE_MASK (0x0f) -#define WAKE_LOCK_INITIALIZED (1U << 8) -#define WAKE_LOCK_ACTIVE (1U << 9) -#define WAKE_LOCK_AUTO_EXPIRE (1U << 10) -#define WAKE_LOCK_PREVENTING_SUSPEND (1U << 11) - -static DEFINE_SPINLOCK(list_lock); -static LIST_HEAD(inactive_locks); -static struct list_head active_wake_locks[WAKE_LOCK_TYPE_COUNT]; -static int current_event_num; -struct workqueue_struct *suspend_work_queue; -struct wake_lock main_wake_lock; -suspend_state_t requested_suspend_state = PM_SUSPEND_MEM; -static struct wake_lock unknown_wakeup; - -#ifdef CONFIG_WAKELOCK_STAT -static struct wake_lock deleted_wake_locks; -static ktime_t last_sleep_time_update; -static int wait_for_wakeup; - -int get_expired_time(struct wake_lock *lock, ktime_t *expire_time) -{ - struct timespec ts; - struct timespec kt; - struct timespec tomono; - struct timespec delta; - struct timespec sleep; - long timeout; - - if (!(lock->flags & WAKE_LOCK_AUTO_EXPIRE)) - return 0; - get_xtime_and_monotonic_and_sleep_offset(&kt, &tomono, &sleep); - timeout = lock->expires - jiffies; - if (timeout > 0) - return 0; - jiffies_to_timespec(-timeout, &delta); - set_normalized_timespec(&ts, kt.tv_sec + tomono.tv_sec - delta.tv_sec, - kt.tv_nsec + tomono.tv_nsec - delta.tv_nsec); - *expire_time = timespec_to_ktime(ts); - return 1; -} - - -static int print_lock_stat(struct seq_file *m, struct wake_lock *lock) -{ - int lock_count = lock->stat.count; - int expire_count = lock->stat.expire_count; - ktime_t active_time = ktime_set(0, 0); - ktime_t total_time = lock->stat.total_time; - ktime_t max_time = lock->stat.max_time; - - ktime_t prevent_suspend_time = lock->stat.prevent_suspend_time; - if (lock->flags & WAKE_LOCK_ACTIVE) { - ktime_t now, add_time; - int expired = get_expired_time(lock, &now); - if (!expired) - now = ktime_get(); - add_time = ktime_sub(now, lock->stat.last_time); - lock_count++; - if (!expired) - active_time = add_time; - else - expire_count++; - total_time = ktime_add(total_time, add_time); - if (lock->flags & WAKE_LOCK_PREVENTING_SUSPEND) - prevent_suspend_time = ktime_add(prevent_suspend_time, - ktime_sub(now, last_sleep_time_update)); - if (add_time.tv64 > max_time.tv64) - max_time = add_time; - } - - return seq_printf(m, - "\"%s\"\t%d\t%d\t%d\t%lld\t%lld\t%lld\t%lld\t%lld\n", - lock->name, lock_count, expire_count, - lock->stat.wakeup_count, ktime_to_ns(active_time), - ktime_to_ns(total_time), - ktime_to_ns(prevent_suspend_time), ktime_to_ns(max_time), - ktime_to_ns(lock->stat.last_time)); -} - -static int wakelock_stats_show(struct seq_file *m, void *unused) -{ - unsigned long irqflags; - struct wake_lock *lock; - int ret; - int type; - - spin_lock_irqsave(&list_lock, irqflags); - - ret = seq_puts(m, "name\tcount\texpire_count\twake_count\tactive_since" - "\ttotal_time\tsleep_time\tmax_time\tlast_change\n"); - list_for_each_entry(lock, &inactive_locks, link) - ret = print_lock_stat(m, lock); - for (type = 0; type < WAKE_LOCK_TYPE_COUNT; type++) { - list_for_each_entry(lock, &active_wake_locks[type], link) - ret = print_lock_stat(m, lock); - } - spin_unlock_irqrestore(&list_lock, irqflags); - return 0; -} - -static void wake_unlock_stat_locked(struct wake_lock *lock, int expired) -{ - ktime_t duration; - ktime_t now; - if (!(lock->flags & WAKE_LOCK_ACTIVE)) - return; - if (get_expired_time(lock, &now)) - expired = 1; - else - now = ktime_get(); - lock->stat.count++; - if (expired) - lock->stat.expire_count++; - duration = ktime_sub(now, lock->stat.last_time); - lock->stat.total_time = ktime_add(lock->stat.total_time, duration); - if (ktime_to_ns(duration) > ktime_to_ns(lock->stat.max_time)) - lock->stat.max_time = duration; - lock->stat.last_time = ktime_get(); - if (lock->flags & WAKE_LOCK_PREVENTING_SUSPEND) { - duration = ktime_sub(now, last_sleep_time_update); - lock->stat.prevent_suspend_time = ktime_add( - lock->stat.prevent_suspend_time, duration); - lock->flags &= ~WAKE_LOCK_PREVENTING_SUSPEND; - } -} - -static void update_sleep_wait_stats_locked(int done) -{ - struct wake_lock *lock; - ktime_t now, etime, elapsed, add; - int expired; - - now = ktime_get(); - elapsed = ktime_sub(now, last_sleep_time_update); - list_for_each_entry(lock, &active_wake_locks[WAKE_LOCK_SUSPEND], link) { - expired = get_expired_time(lock, &etime); - if (lock->flags & WAKE_LOCK_PREVENTING_SUSPEND) { - if (expired) - add = ktime_sub(etime, last_sleep_time_update); - else - add = elapsed; - lock->stat.prevent_suspend_time = ktime_add( - lock->stat.prevent_suspend_time, add); - } - if (done || expired) - lock->flags &= ~WAKE_LOCK_PREVENTING_SUSPEND; - else - lock->flags |= WAKE_LOCK_PREVENTING_SUSPEND; - } - last_sleep_time_update = now; -} -#endif - - -static void expire_wake_lock(struct wake_lock *lock) -{ -#ifdef CONFIG_WAKELOCK_STAT - wake_unlock_stat_locked(lock, 1); -#endif - lock->flags &= ~(WAKE_LOCK_ACTIVE | WAKE_LOCK_AUTO_EXPIRE); - list_del(&lock->link); - list_add(&lock->link, &inactive_locks); - if (debug_mask & (DEBUG_WAKE_LOCK | DEBUG_EXPIRE)) - pr_info("expired wake lock %s\n", lock->name); -} - -/* Caller must acquire the list_lock spinlock */ -static void print_active_locks(int type) -{ - struct wake_lock *lock; - bool print_expired = true; - - BUG_ON(type >= WAKE_LOCK_TYPE_COUNT); - list_for_each_entry(lock, &active_wake_locks[type], link) { - if (lock->flags & WAKE_LOCK_AUTO_EXPIRE) { - long timeout = lock->expires - jiffies; - if (timeout > 0) - pr_info("active wake lock %s, time left %ld\n", - lock->name, timeout); - else if (print_expired) - pr_info("wake lock %s, expired\n", lock->name); - } else { - pr_info("active wake lock %s\n", lock->name); - if (!(debug_mask & DEBUG_EXPIRE)) - print_expired = false; - } - } -} - -static long has_wake_lock_locked(int type) -{ - struct wake_lock *lock, *n; - long max_timeout = 0; - - BUG_ON(type >= WAKE_LOCK_TYPE_COUNT); - list_for_each_entry_safe(lock, n, &active_wake_locks[type], link) { - if (lock->flags & WAKE_LOCK_AUTO_EXPIRE) { - long timeout = lock->expires - jiffies; - if (timeout <= 0) - expire_wake_lock(lock); - else if (timeout > max_timeout) - max_timeout = timeout; - } else - return -1; - } - return max_timeout; -} - -long has_wake_lock(int type) -{ - long ret; - unsigned long irqflags; - spin_lock_irqsave(&list_lock, irqflags); - ret = has_wake_lock_locked(type); - if (ret && (debug_mask & DEBUG_WAKEUP) && type == WAKE_LOCK_SUSPEND) - print_active_locks(type); - spin_unlock_irqrestore(&list_lock, irqflags); - return ret; -} - -static void suspend(struct work_struct *work) -{ - int ret; - int entry_event_num; - - if (has_wake_lock(WAKE_LOCK_SUSPEND)) { - if (debug_mask & DEBUG_SUSPEND) - pr_info("suspend: abort suspend\n"); - return; - } - - entry_event_num = current_event_num; - sys_sync(); - if (debug_mask & DEBUG_SUSPEND) - pr_info("suspend: enter suspend\n"); - ret = pm_suspend(requested_suspend_state); - if (debug_mask & DEBUG_EXIT_SUSPEND) { - struct timespec ts; - struct rtc_time tm; - getnstimeofday(&ts); - rtc_time_to_tm(ts.tv_sec, &tm); - pr_info("suspend: exit suspend, ret = %d " - "(%d-%02d-%02d %02d:%02d:%02d.%09lu UTC)\n", ret, - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec, ts.tv_nsec); - } - if (current_event_num == entry_event_num) { - if (debug_mask & DEBUG_SUSPEND) - pr_info("suspend: pm_suspend returned with no event\n"); - wake_lock_timeout(&unknown_wakeup, HZ / 2); - } -} -static DECLARE_WORK(suspend_work, suspend); - -static void expire_wake_locks(unsigned long data) -{ - long has_lock; - unsigned long irqflags; - if (debug_mask & DEBUG_EXPIRE) - pr_info("expire_wake_locks: start\n"); - spin_lock_irqsave(&list_lock, irqflags); - if (debug_mask & DEBUG_SUSPEND) - print_active_locks(WAKE_LOCK_SUSPEND); - has_lock = has_wake_lock_locked(WAKE_LOCK_SUSPEND); - if (debug_mask & DEBUG_EXPIRE) - pr_info("expire_wake_locks: done, has_lock %ld\n", has_lock); - if (has_lock == 0) - queue_work(suspend_work_queue, &suspend_work); - spin_unlock_irqrestore(&list_lock, irqflags); -} -static DEFINE_TIMER(expire_timer, expire_wake_locks, 0, 0); - -static int power_suspend_late(struct device *dev) -{ - int ret = has_wake_lock(WAKE_LOCK_SUSPEND) ? -EAGAIN : 0; -#ifdef CONFIG_WAKELOCK_STAT - wait_for_wakeup = !ret; -#endif - if (debug_mask & DEBUG_SUSPEND) - pr_info("power_suspend_late return %d\n", ret); - return ret; -} - -static struct dev_pm_ops power_driver_pm_ops = { - .suspend_noirq = power_suspend_late, -}; - -static struct platform_driver power_driver = { - .driver.name = "power", - .driver.pm = &power_driver_pm_ops, -}; -static struct platform_device power_device = { - .name = "power", -}; - -void wake_lock_init(struct wake_lock *lock, int type, const char *name) -{ - unsigned long irqflags = 0; - - if (name) - lock->name = name; - BUG_ON(!lock->name); - - if (debug_mask & DEBUG_WAKE_LOCK) - pr_info("wake_lock_init name=%s\n", lock->name); -#ifdef CONFIG_WAKELOCK_STAT - lock->stat.count = 0; - lock->stat.expire_count = 0; - lock->stat.wakeup_count = 0; - lock->stat.total_time = ktime_set(0, 0); - lock->stat.prevent_suspend_time = ktime_set(0, 0); - lock->stat.max_time = ktime_set(0, 0); - lock->stat.last_time = ktime_set(0, 0); -#endif - lock->flags = (type & WAKE_LOCK_TYPE_MASK) | WAKE_LOCK_INITIALIZED; - - INIT_LIST_HEAD(&lock->link); - spin_lock_irqsave(&list_lock, irqflags); - list_add(&lock->link, &inactive_locks); - spin_unlock_irqrestore(&list_lock, irqflags); -} -EXPORT_SYMBOL(wake_lock_init); - -void wake_lock_destroy(struct wake_lock *lock) -{ - unsigned long irqflags; - if (debug_mask & DEBUG_WAKE_LOCK) - pr_info("wake_lock_destroy name=%s\n", lock->name); - spin_lock_irqsave(&list_lock, irqflags); - lock->flags &= ~WAKE_LOCK_INITIALIZED; -#ifdef CONFIG_WAKELOCK_STAT - if (lock->stat.count) { - deleted_wake_locks.stat.count += lock->stat.count; - deleted_wake_locks.stat.expire_count += lock->stat.expire_count; - deleted_wake_locks.stat.total_time = - ktime_add(deleted_wake_locks.stat.total_time, - lock->stat.total_time); - deleted_wake_locks.stat.prevent_suspend_time = - ktime_add(deleted_wake_locks.stat.prevent_suspend_time, - lock->stat.prevent_suspend_time); - deleted_wake_locks.stat.max_time = - ktime_add(deleted_wake_locks.stat.max_time, - lock->stat.max_time); - } -#endif - list_del(&lock->link); - spin_unlock_irqrestore(&list_lock, irqflags); -} -EXPORT_SYMBOL(wake_lock_destroy); - -static void wake_lock_internal( - struct wake_lock *lock, long timeout, int has_timeout) -{ - int type; - unsigned long irqflags; - long expire_in; - - spin_lock_irqsave(&list_lock, irqflags); - type = lock->flags & WAKE_LOCK_TYPE_MASK; - BUG_ON(type >= WAKE_LOCK_TYPE_COUNT); - BUG_ON(!(lock->flags & WAKE_LOCK_INITIALIZED)); -#ifdef CONFIG_WAKELOCK_STAT - if (type == WAKE_LOCK_SUSPEND && wait_for_wakeup) { - if (debug_mask & DEBUG_WAKEUP) - pr_info("wakeup wake lock: %s\n", lock->name); - wait_for_wakeup = 0; - lock->stat.wakeup_count++; - } - if ((lock->flags & WAKE_LOCK_AUTO_EXPIRE) && - (long)(lock->expires - jiffies) <= 0) { - wake_unlock_stat_locked(lock, 0); - lock->stat.last_time = ktime_get(); - } -#endif - if (!(lock->flags & WAKE_LOCK_ACTIVE)) { - lock->flags |= WAKE_LOCK_ACTIVE; -#ifdef CONFIG_WAKELOCK_STAT - lock->stat.last_time = ktime_get(); -#endif - } - list_del(&lock->link); - if (has_timeout) { - if (debug_mask & DEBUG_WAKE_LOCK) - pr_info("wake_lock: %s, type %d, timeout %ld.%03lu\n", - lock->name, type, timeout / HZ, - (timeout % HZ) * MSEC_PER_SEC / HZ); - lock->expires = jiffies + timeout; - lock->flags |= WAKE_LOCK_AUTO_EXPIRE; - list_add_tail(&lock->link, &active_wake_locks[type]); - } else { - if (debug_mask & DEBUG_WAKE_LOCK) - pr_info("wake_lock: %s, type %d\n", lock->name, type); - lock->expires = LONG_MAX; - lock->flags &= ~WAKE_LOCK_AUTO_EXPIRE; - list_add(&lock->link, &active_wake_locks[type]); - } - if (type == WAKE_LOCK_SUSPEND) { - current_event_num++; -#ifdef CONFIG_WAKELOCK_STAT - if (lock == &main_wake_lock) - update_sleep_wait_stats_locked(1); - else if (!wake_lock_active(&main_wake_lock)) - update_sleep_wait_stats_locked(0); -#endif - if (has_timeout) - expire_in = has_wake_lock_locked(type); - else - expire_in = -1; - if (expire_in > 0) { - if (debug_mask & DEBUG_EXPIRE) - pr_info("wake_lock: %s, start expire timer, " - "%ld\n", lock->name, expire_in); - mod_timer(&expire_timer, jiffies + expire_in); - } else { - if (del_timer(&expire_timer)) - if (debug_mask & DEBUG_EXPIRE) - pr_info("wake_lock: %s, stop expire timer\n", - lock->name); - if (expire_in == 0) - queue_work(suspend_work_queue, &suspend_work); - } - } - spin_unlock_irqrestore(&list_lock, irqflags); -} - -void wake_lock(struct wake_lock *lock) -{ - wake_lock_internal(lock, 0, 0); -} -EXPORT_SYMBOL(wake_lock); - -void wake_lock_timeout(struct wake_lock *lock, long timeout) -{ - wake_lock_internal(lock, timeout, 1); -} -EXPORT_SYMBOL(wake_lock_timeout); - -void wake_unlock(struct wake_lock *lock) -{ - int type; - unsigned long irqflags; - spin_lock_irqsave(&list_lock, irqflags); - type = lock->flags & WAKE_LOCK_TYPE_MASK; -#ifdef CONFIG_WAKELOCK_STAT - wake_unlock_stat_locked(lock, 0); -#endif - if (debug_mask & DEBUG_WAKE_LOCK) - pr_info("wake_unlock: %s\n", lock->name); - lock->flags &= ~(WAKE_LOCK_ACTIVE | WAKE_LOCK_AUTO_EXPIRE); - list_del(&lock->link); - list_add(&lock->link, &inactive_locks); - if (type == WAKE_LOCK_SUSPEND) { - long has_lock = has_wake_lock_locked(type); - if (has_lock > 0) { - if (debug_mask & DEBUG_EXPIRE) - pr_info("wake_unlock: %s, start expire timer, " - "%ld\n", lock->name, has_lock); - mod_timer(&expire_timer, jiffies + has_lock); - } else { - if (del_timer(&expire_timer)) - if (debug_mask & DEBUG_EXPIRE) - pr_info("wake_unlock: %s, stop expire " - "timer\n", lock->name); - if (has_lock == 0) - queue_work(suspend_work_queue, &suspend_work); - } - if (lock == &main_wake_lock) { - if (debug_mask & DEBUG_SUSPEND) - print_active_locks(WAKE_LOCK_SUSPEND); -#ifdef CONFIG_WAKELOCK_STAT - update_sleep_wait_stats_locked(0); -#endif - } - } - spin_unlock_irqrestore(&list_lock, irqflags); -} -EXPORT_SYMBOL(wake_unlock); - -int wake_lock_active(struct wake_lock *lock) -{ - return !!(lock->flags & WAKE_LOCK_ACTIVE); -} -EXPORT_SYMBOL(wake_lock_active); - -static int wakelock_stats_open(struct inode *inode, struct file *file) -{ - return single_open(file, wakelock_stats_show, NULL); -} - -static const struct file_operations wakelock_stats_fops = { - .owner = THIS_MODULE, - .open = wakelock_stats_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int __init wakelocks_init(void) -{ - int ret; - int i; - - for (i = 0; i < ARRAY_SIZE(active_wake_locks); i++) - INIT_LIST_HEAD(&active_wake_locks[i]); - -#ifdef CONFIG_WAKELOCK_STAT - wake_lock_init(&deleted_wake_locks, WAKE_LOCK_SUSPEND, - "deleted_wake_locks"); -#endif - wake_lock_init(&main_wake_lock, WAKE_LOCK_SUSPEND, "main"); - wake_lock(&main_wake_lock); - wake_lock_init(&unknown_wakeup, WAKE_LOCK_SUSPEND, "unknown_wakeups"); - - ret = platform_device_register(&power_device); - if (ret) { - pr_err("wakelocks_init: platform_device_register failed\n"); - goto err_platform_device_register; - } - ret = platform_driver_register(&power_driver); - if (ret) { - pr_err("wakelocks_init: platform_driver_register failed\n"); - goto err_platform_driver_register; - } - - suspend_work_queue = create_singlethread_workqueue("suspend"); - if (suspend_work_queue == NULL) { - ret = -ENOMEM; - goto err_suspend_work_queue; - } - -#ifdef CONFIG_WAKELOCK_STAT - proc_create("wakelocks", S_IRUGO, NULL, &wakelock_stats_fops); -#endif - - return 0; - -err_suspend_work_queue: - platform_driver_unregister(&power_driver); -err_platform_driver_register: - platform_device_unregister(&power_device); -err_platform_device_register: - wake_lock_destroy(&unknown_wakeup); - wake_lock_destroy(&main_wake_lock); -#ifdef CONFIG_WAKELOCK_STAT - wake_lock_destroy(&deleted_wake_locks); -#endif - return ret; -} - -static void __exit wakelocks_exit(void) -{ -#ifdef CONFIG_WAKELOCK_STAT - remove_proc_entry("wakelocks", NULL); -#endif - destroy_workqueue(suspend_work_queue); - platform_driver_unregister(&power_driver); - platform_device_unregister(&power_device); - wake_lock_destroy(&unknown_wakeup); - wake_lock_destroy(&main_wake_lock); -#ifdef CONFIG_WAKELOCK_STAT - wake_lock_destroy(&deleted_wake_locks); -#endif -} - -core_initcall(wakelocks_init); -module_exit(wakelocks_exit); -- cgit v1.2.3 From f879465ef6810defcb9f40f1679cebe22ea4a78b Mon Sep 17 00:00:00 2001 From: Arve Hjønnevåg Date: Fri, 16 Mar 2012 17:44:36 -0700 Subject: Revert "PM: Add wake lock api." This reverts commit 29da5497e11428cdafa6f7586d63ee0a4f2bced3. Change-Id: I5b672abefe76e9279bd8f7b00927bf3f057ff38b --- include/linux/wakelock.h | 91 ------------------------------------------------ 1 file changed, 91 deletions(-) delete mode 100755 include/linux/wakelock.h diff --git a/include/linux/wakelock.h b/include/linux/wakelock.h deleted file mode 100755 index a096d24ada1..00000000000 --- a/include/linux/wakelock.h +++ /dev/null @@ -1,91 +0,0 @@ -/* include/linux/wakelock.h - * - * Copyright (C) 2007-2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _LINUX_WAKELOCK_H -#define _LINUX_WAKELOCK_H - -#include -#include - -/* A wake_lock prevents the system from entering suspend or other low power - * states when active. If the type is set to WAKE_LOCK_SUSPEND, the wake_lock - * prevents a full system suspend. If the type is WAKE_LOCK_IDLE, low power - * states that cause large interrupt latencies or that disable a set of - * interrupts will not entered from idle until the wake_locks are released. - */ - -enum { - WAKE_LOCK_SUSPEND, /* Prevent suspend */ - WAKE_LOCK_IDLE, /* Prevent low power idle */ - WAKE_LOCK_TYPE_COUNT -}; - -struct wake_lock { -#ifdef CONFIG_HAS_WAKELOCK - struct list_head link; - int flags; - const char *name; - unsigned long expires; -#ifdef CONFIG_WAKELOCK_STAT - struct { - int count; - int expire_count; - int wakeup_count; - ktime_t total_time; - ktime_t prevent_suspend_time; - ktime_t max_time; - ktime_t last_time; - } stat; -#endif -#endif -}; - -#ifdef CONFIG_HAS_WAKELOCK - -void wake_lock_init(struct wake_lock *lock, int type, const char *name); -void wake_lock_destroy(struct wake_lock *lock); -void wake_lock(struct wake_lock *lock); -void wake_lock_timeout(struct wake_lock *lock, long timeout); -void wake_unlock(struct wake_lock *lock); - -/* wake_lock_active returns a non-zero value if the wake_lock is currently - * locked. If the wake_lock has a timeout, it does not check the timeout - * but if the timeout had aready been checked it will return 0. - */ -int wake_lock_active(struct wake_lock *lock); - -/* has_wake_lock returns 0 if no wake locks of the specified type are active, - * and non-zero if one or more wake locks are held. Specifically it returns - * -1 if one or more wake locks with no timeout are active or the - * number of jiffies until all active wake locks time out. - */ -long has_wake_lock(int type); - -#else - -static inline void wake_lock_init(struct wake_lock *lock, int type, - const char *name) {} -static inline void wake_lock_destroy(struct wake_lock *lock) {} -static inline void wake_lock(struct wake_lock *lock) {} -static inline void wake_lock_timeout(struct wake_lock *lock, long timeout) {} -static inline void wake_unlock(struct wake_lock *lock) {} - -static inline int wake_lock_active(struct wake_lock *lock) { return 0; } -static inline long has_wake_lock(int type) { return 0; } - -#endif - -#endif - -- cgit v1.2.3 From 0b956764bfedec811fbb83c69376997977131621 Mon Sep 17 00:00:00 2001 From: Arve Hjønnevåg Date: Fri, 16 Mar 2012 17:44:42 -0700 Subject: PM / Sleep: Add wake lock api wrapper on top of wakeup sources MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Icaad02fe1e8856fdc2e4215f380594a5dde8e002 Signed-off-by: Arve Hjønnevåg --- include/linux/wakelock.h | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ kernel/power/Kconfig | 8 ++++++ 2 files changed, 75 insertions(+) create mode 100644 include/linux/wakelock.h diff --git a/include/linux/wakelock.h b/include/linux/wakelock.h new file mode 100644 index 00000000000..f4a698a2288 --- /dev/null +++ b/include/linux/wakelock.h @@ -0,0 +1,67 @@ +/* include/linux/wakelock.h + * + * Copyright (C) 2007-2012 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _LINUX_WAKELOCK_H +#define _LINUX_WAKELOCK_H + +#include +#include + +/* A wake_lock prevents the system from entering suspend or other low power + * states when active. If the type is set to WAKE_LOCK_SUSPEND, the wake_lock + * prevents a full system suspend. + */ + +enum { + WAKE_LOCK_SUSPEND, /* Prevent suspend */ + WAKE_LOCK_TYPE_COUNT +}; + +struct wake_lock { + struct wakeup_source ws; +}; + +static inline void wake_lock_init(struct wake_lock *lock, int type, + const char *name) +{ + wakeup_source_init(&lock->ws, name); +} + +static inline void wake_lock_destroy(struct wake_lock *lock) +{ + wakeup_source_trash(&lock->ws); +} + +static inline void wake_lock(struct wake_lock *lock) +{ + __pm_stay_awake(&lock->ws); +} + +static inline void wake_lock_timeout(struct wake_lock *lock, long timeout) +{ + __pm_wakeup_event(&lock->ws, jiffies_to_msecs(timeout)); +} + +static inline void wake_unlock(struct wake_lock *lock) +{ + __pm_relax(&lock->ws); +} + +static inline int wake_lock_active(struct wake_lock *lock) +{ + return lock->ws.active; +} + +#endif diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index 1878b6ef2a2..e4d8a4dd7f9 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig @@ -18,6 +18,14 @@ config SUSPEND_FREEZER Turning OFF this setting is NOT recommended! If in doubt, say Y. +config HAS_WAKELOCK + bool + default y + +config WAKELOCK + bool + default y + config HIBERNATE_CALLBACKS bool -- cgit v1.2.3 From 4d09c863239d323e34a8e59cc738f126d7ed3382 Mon Sep 17 00:00:00 2001 From: Arve Hjønnevåg Date: Thu, 9 Oct 2008 21:01:46 -0700 Subject: PM: Add user-space wake lock api. This adds /sys/power/wake_lock and /sys/power/wake_unlock. Writing a string to wake_lock creates a wake lock the first time is sees a string and locks it. Optionally, the string can be followed by a timeout. To unlock the wake lock, write the same string to wake_unlock. Change-Id: I66c6e3fe6487d17f9c2fafde1174042e57d15cd7 --- kernel/power/Kconfig | 10 ++ kernel/power/Makefile | 1 + kernel/power/main.c | 9 ++ kernel/power/power.h | 11 +++ kernel/power/userwakelock.c | 219 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 250 insertions(+) create mode 100644 kernel/power/userwakelock.c diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index e4d8a4dd7f9..1e9acb47e9f 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig @@ -26,6 +26,16 @@ config WAKELOCK bool default y +config USER_WAKELOCK + bool "Userspace wake locks" + depends on PM_SLEEP + default y + ---help--- + User-space wake lock api. Write "lockname" or "lockname timeout" + to /sys/power/wake_lock lock and if needed create a wake lock. + Write "lockname" to /sys/power/wake_unlock to unlock a user wake + lock. + config HIBERNATE_CALLBACKS bool diff --git a/kernel/power/Makefile b/kernel/power/Makefile index 58f237137c9..e9ee7a2f690 100644 --- a/kernel/power/Makefile +++ b/kernel/power/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_SUSPEND) += suspend.o obj-$(CONFIG_PM_TEST_SUSPEND) += suspend_test.o obj-$(CONFIG_HIBERNATION) += hibernate.o snapshot.o swap.o user.o \ block_io.o +obj-$(CONFIG_USER_WAKELOCK) += userwakelock.o obj-$(CONFIG_SUSPEND_TIME) += suspend_time.o obj-$(CONFIG_MAGIC_SYSRQ) += poweroff.o diff --git a/kernel/power/main.c b/kernel/power/main.c index 9824b41e5a1..1edafb23ee9 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -402,6 +402,11 @@ power_attr(pm_trace_dev_match); #endif /* CONFIG_PM_TRACE */ +#ifdef CONFIG_USER_WAKELOCK +power_attr(wake_lock); +power_attr(wake_unlock); +#endif + static struct attribute * g[] = { &state_attr.attr, #ifdef CONFIG_PM_TRACE @@ -414,6 +419,10 @@ static struct attribute * g[] = { #ifdef CONFIG_PM_DEBUG &pm_test_attr.attr, #endif +#ifdef CONFIG_USER_WAKELOCK + &wake_lock_attr.attr, + &wake_unlock_attr.attr, +#endif #endif NULL, }; diff --git a/kernel/power/power.h b/kernel/power/power.h index 21724eee520..d8eea4ba3e3 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h @@ -269,3 +269,14 @@ static inline void suspend_thaw_processes(void) { } #endif + +#ifdef CONFIG_USER_WAKELOCK +ssize_t wake_lock_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf); +ssize_t wake_lock_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t n); +ssize_t wake_unlock_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf); +ssize_t wake_unlock_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t n); +#endif diff --git a/kernel/power/userwakelock.c b/kernel/power/userwakelock.c new file mode 100644 index 00000000000..a28a8db4146 --- /dev/null +++ b/kernel/power/userwakelock.c @@ -0,0 +1,219 @@ +/* kernel/power/userwakelock.c + * + * Copyright (C) 2005-2008 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include + +#include "power.h" + +enum { + DEBUG_FAILURE = BIT(0), + DEBUG_ERROR = BIT(1), + DEBUG_NEW = BIT(2), + DEBUG_ACCESS = BIT(3), + DEBUG_LOOKUP = BIT(4), +}; +static int debug_mask = DEBUG_FAILURE; +module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); + +static DEFINE_MUTEX(tree_lock); + +struct user_wake_lock { + struct rb_node node; + struct wake_lock wake_lock; + char name[0]; +}; +struct rb_root user_wake_locks; + +static struct user_wake_lock *lookup_wake_lock_name( + const char *buf, int allocate, long *timeoutptr) +{ + struct rb_node **p = &user_wake_locks.rb_node; + struct rb_node *parent = NULL; + struct user_wake_lock *l; + int diff; + u64 timeout; + int name_len; + const char *arg; + + /* Find length of lock name and start of optional timeout string */ + arg = buf; + while (*arg && !isspace(*arg)) + arg++; + name_len = arg - buf; + if (!name_len) + goto bad_arg; + while (isspace(*arg)) + arg++; + + /* Process timeout string */ + if (timeoutptr && *arg) { + timeout = simple_strtoull(arg, (char **)&arg, 0); + while (isspace(*arg)) + arg++; + if (*arg) + goto bad_arg; + /* convert timeout from nanoseconds to jiffies > 0 */ + timeout += (NSEC_PER_SEC / HZ) - 1; + do_div(timeout, (NSEC_PER_SEC / HZ)); + if (timeout <= 0) + timeout = 1; + *timeoutptr = timeout; + } else if (*arg) + goto bad_arg; + else if (timeoutptr) + *timeoutptr = 0; + + /* Lookup wake lock in rbtree */ + while (*p) { + parent = *p; + l = rb_entry(parent, struct user_wake_lock, node); + diff = strncmp(buf, l->name, name_len); + if (!diff && l->name[name_len]) + diff = -1; + if (debug_mask & DEBUG_ERROR) + pr_info("lookup_wake_lock_name: compare %.*s %s %d\n", + name_len, buf, l->name, diff); + + if (diff < 0) + p = &(*p)->rb_left; + else if (diff > 0) + p = &(*p)->rb_right; + else + return l; + } + + /* Allocate and add new wakelock to rbtree */ + if (!allocate) { + if (debug_mask & DEBUG_ERROR) + pr_info("lookup_wake_lock_name: %.*s not found\n", + name_len, buf); + return ERR_PTR(-EINVAL); + } + l = kzalloc(sizeof(*l) + name_len + 1, GFP_KERNEL); + if (l == NULL) { + if (debug_mask & DEBUG_FAILURE) + pr_err("lookup_wake_lock_name: failed to allocate " + "memory for %.*s\n", name_len, buf); + return ERR_PTR(-ENOMEM); + } + memcpy(l->name, buf, name_len); + if (debug_mask & DEBUG_NEW) + pr_info("lookup_wake_lock_name: new wake lock %s\n", l->name); + wake_lock_init(&l->wake_lock, WAKE_LOCK_SUSPEND, l->name); + rb_link_node(&l->node, parent, p); + rb_insert_color(&l->node, &user_wake_locks); + return l; + +bad_arg: + if (debug_mask & DEBUG_ERROR) + pr_info("lookup_wake_lock_name: wake lock, %.*s, bad arg, %s\n", + name_len, buf, arg); + return ERR_PTR(-EINVAL); +} + +ssize_t wake_lock_show( + struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + char *s = buf; + char *end = buf + PAGE_SIZE; + struct rb_node *n; + struct user_wake_lock *l; + + mutex_lock(&tree_lock); + + for (n = rb_first(&user_wake_locks); n != NULL; n = rb_next(n)) { + l = rb_entry(n, struct user_wake_lock, node); + if (wake_lock_active(&l->wake_lock)) + s += scnprintf(s, end - s, "%s ", l->name); + } + s += scnprintf(s, end - s, "\n"); + + mutex_unlock(&tree_lock); + return (s - buf); +} + +ssize_t wake_lock_store( + struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t n) +{ + long timeout; + struct user_wake_lock *l; + + mutex_lock(&tree_lock); + l = lookup_wake_lock_name(buf, 1, &timeout); + if (IS_ERR(l)) { + n = PTR_ERR(l); + goto bad_name; + } + + if (debug_mask & DEBUG_ACCESS) + pr_info("wake_lock_store: %s, timeout %ld\n", l->name, timeout); + + if (timeout) + wake_lock_timeout(&l->wake_lock, timeout); + else + wake_lock(&l->wake_lock); +bad_name: + mutex_unlock(&tree_lock); + return n; +} + + +ssize_t wake_unlock_show( + struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + char *s = buf; + char *end = buf + PAGE_SIZE; + struct rb_node *n; + struct user_wake_lock *l; + + mutex_lock(&tree_lock); + + for (n = rb_first(&user_wake_locks); n != NULL; n = rb_next(n)) { + l = rb_entry(n, struct user_wake_lock, node); + if (!wake_lock_active(&l->wake_lock)) + s += scnprintf(s, end - s, "%s ", l->name); + } + s += scnprintf(s, end - s, "\n"); + + mutex_unlock(&tree_lock); + return (s - buf); +} + +ssize_t wake_unlock_store( + struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t n) +{ + struct user_wake_lock *l; + + mutex_lock(&tree_lock); + l = lookup_wake_lock_name(buf, 0, NULL); + if (IS_ERR(l)) { + n = PTR_ERR(l); + goto not_found; + } + + if (debug_mask & DEBUG_ACCESS) + pr_info("wake_unlock_store: %s\n", l->name); + + wake_unlock(&l->wake_lock); +not_found: + mutex_unlock(&tree_lock); + return n; +} + -- cgit v1.2.3 From a82e9f5a7ee65687bda08d70256983fdade2d0d2 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Sun, 18 Mar 2012 15:25:55 -0700 Subject: ARM: fiq_debugger: fix multiple consoles and make it a preferred console Fix setting up consoles on multiple fiq debugger devices by splitting the tty driver init into the initcall, and initializing the single tty device during probe. Has the side effect of moving the tty device node to /dev/ttyFIQx, where x is the platform device id, which should normally match the serial port. To avoid having to pass a different console=/dev/ttyFIQx for every device, make the fiq debugger a preferred console that will be used by default if no console was passed on the command line. Change-Id: I6cc2670628a41e84615859bc96adba189966d647 Signed-off-by: Colin Cross --- arch/arm/common/fiq_debugger.c | 109 ++++++++++++++++++++++++++++++----------- 1 file changed, 81 insertions(+), 28 deletions(-) diff --git a/arch/arm/common/fiq_debugger.c b/arch/arm/common/fiq_debugger.c index 1f64d7dc83b..1908ba95a90 100644 --- a/arch/arm/common/fiq_debugger.c +++ b/arch/arm/common/fiq_debugger.c @@ -45,6 +45,8 @@ #define DEBUG_MAX 64 #define MAX_UNHANDLED_FIQ_COUNT 1000000 +#define MAX_FIQ_DEBUGGER_PORTS 4 + #define THREAD_INFO(sp) ((struct thread_info *) \ ((unsigned long)(sp) & ~(THREAD_SIZE - 1))) @@ -81,7 +83,6 @@ struct fiq_debugger_state { #ifdef CONFIG_FIQ_DEBUGGER_CONSOLE struct console console; - struct tty_driver *tty_driver; struct tty_struct *tty; int tty_open_count; struct fiq_debugger_ringbuf *tty_rbuf; @@ -92,6 +93,10 @@ struct fiq_debugger_state { unsigned int last_local_timer_irqs[NR_CPUS]; }; +#ifdef CONFIG_FIQ_DEBUGGER_CONSOLE +struct tty_driver *fiq_tty_driver; +#endif + #ifdef CONFIG_FIQ_DEBUGGER_NO_SLEEP static bool initial_no_sleep = true; #else @@ -913,10 +918,8 @@ static void debug_resume(struct fiq_glue_handler *h) #if defined(CONFIG_FIQ_DEBUGGER_CONSOLE) struct tty_driver *debug_console_device(struct console *co, int *index) { - struct fiq_debugger_state *state; - state = container_of(co, struct fiq_debugger_state, console); - *index = 0; - return state->tty_driver; + *index = co->index; + return fiq_tty_driver; } static void debug_console_write(struct console *co, @@ -948,7 +951,9 @@ static struct console fiq_debugger_console = { int fiq_tty_open(struct tty_struct *tty, struct file *filp) { - struct fiq_debugger_state *state = tty->driver->driver_state; + int line = tty->index; + struct fiq_debugger_state **states = tty->driver->driver_state; + struct fiq_debugger_state *state = states[line]; if (state->tty_open_count++) return 0; @@ -1035,36 +1040,66 @@ static const struct tty_operations fiq_tty_driver_ops = { #endif }; -static int fiq_debugger_tty_init(struct fiq_debugger_state *state) +static int fiq_debugger_tty_init(void) { - int ret = -EINVAL; + int ret; + struct fiq_debugger_state **states = NULL; - state->tty_driver = alloc_tty_driver(1); - if (!state->tty_driver) { - pr_err("Failed to allocate fiq debugger tty\n"); + states = kzalloc(sizeof(*states) * MAX_FIQ_DEBUGGER_PORTS, GFP_KERNEL); + if (!states) { + pr_err("Failed to allocate fiq debugger state structres\n"); return -ENOMEM; } - state->tty_driver->owner = THIS_MODULE; - state->tty_driver->driver_name = "fiq-debugger"; - state->tty_driver->name = "ttyFIQ"; - state->tty_driver->type = TTY_DRIVER_TYPE_SERIAL; - state->tty_driver->subtype = SERIAL_TYPE_NORMAL; - state->tty_driver->init_termios = tty_std_termios; - state->tty_driver->init_termios.c_cflag = + fiq_tty_driver = alloc_tty_driver(MAX_FIQ_DEBUGGER_PORTS); + if (!fiq_tty_driver) { + pr_err("Failed to allocate fiq debugger tty\n"); + ret = -ENOMEM; + goto err_free_state; + } + + fiq_tty_driver->owner = THIS_MODULE; + fiq_tty_driver->driver_name = "fiq-debugger"; + fiq_tty_driver->name = "ttyFIQ"; + fiq_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; + fiq_tty_driver->subtype = SERIAL_TYPE_NORMAL; + fiq_tty_driver->init_termios = tty_std_termios; + fiq_tty_driver->flags = TTY_DRIVER_REAL_RAW | + TTY_DRIVER_DYNAMIC_DEV; + fiq_tty_driver->driver_state = states; + + fiq_tty_driver->init_termios.c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL; - state->tty_driver->init_termios.c_ispeed = - state->tty_driver->init_termios.c_ospeed = 115200; - state->tty_driver->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(state->tty_driver, &fiq_tty_driver_ops); - state->tty_driver->driver_state = state; + fiq_tty_driver->init_termios.c_ispeed = 115200; + fiq_tty_driver->init_termios.c_ospeed = 115200; - ret = tty_register_driver(state->tty_driver); + tty_set_operations(fiq_tty_driver, &fiq_tty_driver_ops); + + ret = tty_register_driver(fiq_tty_driver); if (ret) { pr_err("Failed to register fiq tty: %d\n", ret); - goto err; + goto err_free_tty; } + pr_info("Registered FIQ tty driver\n"); + return 0; + +err_free_tty: + put_tty_driver(fiq_tty_driver); + fiq_tty_driver = NULL; +err_free_state: + kfree(states); + return ret; +} + +static int fiq_debugger_tty_init_one(struct fiq_debugger_state *state) +{ + int ret; + struct device *tty_dev; + struct fiq_debugger_state **states = fiq_tty_driver->driver_state; + + states[state->pdev->id] = state; + state->tty_rbuf = fiq_debugger_ringbuf_alloc(1024); if (!state->tty_rbuf) { pr_err("Failed to allocate fiq debugger ringbuf\n"); @@ -1072,13 +1107,23 @@ static int fiq_debugger_tty_init(struct fiq_debugger_state *state) goto err; } - pr_info("Registered FIQ tty driver %p\n", state->tty_driver); + tty_dev = tty_register_device(fiq_tty_driver, state->pdev->id, + &state->pdev->dev); + if (IS_ERR(tty_dev)) { + pr_err("Failed to register fiq debugger tty device\n"); + ret = PTR_ERR(tty_dev); + goto err; + } + + device_set_wakeup_capable(tty_dev, 1); + + pr_info("Registered fiq debugger ttyFIQ%d\n", state->pdev->id); + return 0; err: fiq_debugger_ringbuf_free(state->tty_rbuf); state->tty_rbuf = NULL; - put_tty_driver(state->tty_driver); return ret; } #endif @@ -1111,6 +1156,9 @@ static int fiq_debugger_probe(struct platform_device *pdev) int fiq; int uart_irq; + if (pdev->id >= MAX_FIQ_DEBUGGER_PORTS) + return -EINVAL; + if (!pdata->uart_getc || !pdata->uart_putc) return -EINVAL; if ((pdata->uart_enable && !pdata->uart_disable) || @@ -1228,8 +1276,12 @@ static int fiq_debugger_probe(struct platform_device *pdev) #if defined(CONFIG_FIQ_DEBUGGER_CONSOLE) state->console = fiq_debugger_console; + state->console.index = pdev->id; + if (!console_set_on_cmdline) + add_preferred_console(state->console.name, + state->console.index, NULL); register_console(&state->console); - fiq_debugger_tty_init(state); + fiq_debugger_tty_init_one(state); #endif return 0; @@ -1263,6 +1315,7 @@ static struct platform_driver fiq_debugger_driver = { static int __init fiq_debugger_init(void) { + fiq_debugger_tty_init(); return platform_driver_register(&fiq_debugger_driver); } -- cgit v1.2.3 From 5275e74ae5e7e92b05bd1361e2573bb38d381358 Mon Sep 17 00:00:00 2001 From: Dmitry Shmidt Date: Tue, 20 Mar 2012 09:54:44 -0700 Subject: net: wireless: bcmdhd: Daemonize wl_event_handler Daemonizing makes thread (besides other things) NON-FREEZABLE, and it will not get fake signal on suspend to quite down_interruptible() Signed-off-by: Dmitry Shmidt --- drivers/net/wireless/bcmdhd/dhd_linux.c | 19 ------------------- drivers/net/wireless/bcmdhd/include/linuxver.h | 17 +++++++++++++++++ drivers/net/wireless/bcmdhd/wl_cfg80211.c | 1 + 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.c b/drivers/net/wireless/bcmdhd/dhd_linux.c index 0ef8ae5c0a9..1c8437b900a 100644 --- a/drivers/net/wireless/bcmdhd/dhd_linux.c +++ b/drivers/net/wireless/bcmdhd/dhd_linux.c @@ -376,25 +376,6 @@ uint dhd_radio_up = 1; char iface_name[IFNAMSIZ] = {'\0'}; module_param_string(iface_name, iface_name, IFNAMSIZ, 0); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -#define DAEMONIZE(a) daemonize(a); \ - allow_signal(SIGKILL); \ - allow_signal(SIGTERM); -#else /* Linux 2.4 (w/o preemption patch) */ -#define RAISE_RX_SOFTIRQ() \ - cpu_raise_softirq(smp_processor_id(), NET_RX_SOFTIRQ) -#define DAEMONIZE(a) daemonize(); \ - do { if (a) \ - strncpy(current->comm, a, MIN(sizeof(current->comm), (strlen(a) + 1))); \ - } while (0); -#endif /* LINUX_VERSION_CODE */ - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -#define BLOCKABLE() (!in_atomic()) -#else -#define BLOCKABLE() (!in_interrupt()) -#endif - /* The following are specific to the SDIO dongle */ /* IOCTL response timeout */ diff --git a/drivers/net/wireless/bcmdhd/include/linuxver.h b/drivers/net/wireless/bcmdhd/include/linuxver.h index 058f2a79863..b4f21200875 100644 --- a/drivers/net/wireless/bcmdhd/include/linuxver.h +++ b/drivers/net/wireless/bcmdhd/include/linuxver.h @@ -512,7 +512,24 @@ typedef struct { (tsk_ctl)->thr_pid = -1; \ } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) +#define DAEMONIZE(a) daemonize(a); \ + allow_signal(SIGKILL); \ + allow_signal(SIGTERM); +#else /* Linux 2.4 (w/o preemption patch) */ +#define RAISE_RX_SOFTIRQ() \ + cpu_raise_softirq(smp_processor_id(), NET_RX_SOFTIRQ) +#define DAEMONIZE(a) daemonize(); \ + do { if (a) \ + strncpy(current->comm, a, MIN(sizeof(current->comm), (strlen(a) + 1))); \ + } while (0); +#endif /* LINUX_VERSION_CODE */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) +#define BLOCKABLE() (!in_atomic()) +#else +#define BLOCKABLE() (!in_interrupt()) +#endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)) #define KILL_PROC(nr, sig) \ diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/wl_cfg80211.c index f7786ab1185..20bbb208291 100644 --- a/drivers/net/wireless/bcmdhd/wl_cfg80211.c +++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.c @@ -6390,6 +6390,7 @@ static s32 wl_event_handler(void *data) tsk_ctl_t *tsk = (tsk_ctl_t *)data; wl = (struct wl_priv *)tsk->parent; + DAEMONIZE("dhd_cfg80211_event"); complete(&tsk->completed); while (down_interruptible (&tsk->sema) == 0) { -- cgit v1.2.3 From 1df760f233995de856f6a54326267d0987fdb85d Mon Sep 17 00:00:00 2001 From: Andrey Konovalov Date: Wed, 21 Mar 2012 18:38:41 -0700 Subject: android-paranoid-net: Fix compile issue This gets rid of the "'AID_NET_RAW' and 'AID_NET_ADMIN' undeclared" compilation error. Signed-off-by: John Stultz --- security/commoncap.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/security/commoncap.c b/security/commoncap.c index 5bfc35b9b56..d7299c4bd6f 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -78,10 +78,12 @@ int cap_netlink_send(struct sock *sk, struct sk_buff *skb) int cap_capable(const struct cred *cred, struct user_namespace *targ_ns, int cap, int audit) { +#ifdef CONFIG_ANDROID_PARANOID_NETWORK if (cap == CAP_NET_RAW && in_egroup_p(AID_NET_RAW)) return 0; if (cap == CAP_NET_ADMIN && in_egroup_p(AID_NET_ADMIN)) return 0; +#endif for (;;) { /* The creator of the user namespace has all caps. */ -- cgit v1.2.3