diff -rupN linux-sunxi/arch/arm/mach-sun7i/Makefile linux-sunxi-new/arch/arm/mach-sun7i/Makefile --- linux-sunxi/arch/arm/mach-sun7i/Makefile 2014-01-27 01:30:27.720384985 +0100 +++ linux-sunxi-new/arch/arm/mach-sun7i/Makefile 2014-02-15 00:44:23.375867879 +0100 @@ -4,6 +4,7 @@ obj-y = clock/ obj-y += dma/ +obj-y += rf/ obj-$(CONFIG_CPU_FREQ) += cpu-freq/ obj-$(CONFIG_PM) += pm/ obj-$(CONFIG_AW_TIME_DELAY) += delay.o diff -rupN linux-sunxi/arch/arm/mach-sun7i/pm/pm_types.h linux-sunxi-new/arch/arm/mach-sun7i/pm/pm_types.h --- linux-sunxi/arch/arm/mach-sun7i/pm/pm_types.h 2014-01-27 01:30:27.721385005 +0100 +++ linux-sunxi-new/arch/arm/mach-sun7i/pm/pm_types.h 2014-02-15 00:44:23.377867923 +0100 @@ -8,12 +8,20 @@ * under the terms of the GNU General Public License version 2 as published by * the Free Software Foundation. */ - -#include - + #ifndef __uxx_sxx_name #define __uxx_sxx_name +typedef signed char __s8; +typedef unsigned char __u8; +typedef signed short __s16; +typedef unsigned short __u16; +typedef signed int __s32; +typedef unsigned int __u32; +typedef signed long long __s64; +typedef unsigned long long __u64; +typedef unsigned int size_t; +//typedef unsigned int ptrdiff_t; //------------------------------------------------------------------------------ //return value defines //------------------------------------------------------------------------------ @@ -22,6 +30,7 @@ #define TRUE (1) #define FALSE (0) -#endif -#endif /*_PM_TYPES_H*/ +#endif + +#endif /*_PM_TYPES_H*/ \ No newline at end of file diff -rupN linux-sunxi/arch/arm/mach-sun7i/rf/bt_pm.c linux-sunxi-new/arch/arm/mach-sun7i/rf/bt_pm.c --- linux-sunxi/arch/arm/mach-sun7i/rf/bt_pm.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-sunxi-new/arch/arm/mach-sun7i/rf/bt_pm.c 2014-02-15 00:44:23.376867901 +0100 @@ -0,0 +1,155 @@ +#include +#include +#include +#include +#include +#include + +#define RF_MSG(...) do {printk("[rfkill]: "__VA_ARGS__);} while(0) + +#if (defined CONFIG_MMC) +extern int wifi_pm_get_mod_type(void); +extern int wifi_pm_gpio_ctrl(char* name, int level); +#else +static __inline int wifi_pm_get_mod_type(void) +{ + pr_warning("[%s] not implemented!\n", __FUNCTION__); + return 0; +} +static __inline int wifi_pm_gpio_ctrl(char* name, int level) +{ + pr_warning("[%s] not implemented!\n", __FUNCTION__); + return -1; +} +#endif + +static const char bt_name[] = "bcm40183"; +static struct rfkill *sw_rfkill; +static int bt_used; + +static int rfkill_set_power(void *data, bool blocked) +{ + unsigned int mod_sel = wifi_pm_get_mod_type(); + + RF_MSG("rfkill set power %d\n", blocked); + + switch (mod_sel) + { + case 2: /* bcm40183 */ + if (!blocked) { + wifi_pm_gpio_ctrl("bcm40183_bt_regon", 1); + wifi_pm_gpio_ctrl("bcm40183_bt_rst", 1); + } else { + wifi_pm_gpio_ctrl("bcm40183_bt_rst", 0); + wifi_pm_gpio_ctrl("bcm40183_bt_regon", 0); + } + break; + case 3: /* realtek rtl8723as */ + if (!blocked) { + wifi_pm_gpio_ctrl("rtk_rtl8723as_bt_dis", 1); + } else { + wifi_pm_gpio_ctrl("rtk_rtl8723as_bt_dis", 0); + } + break; + case 7: /* ap6210 */ + case 8: /* ap6330 */ + if (!blocked) { + wifi_pm_gpio_ctrl("ap6xxx_bt_regon", 1); + } else { + wifi_pm_gpio_ctrl("ap6xxx_bt_regon", 0); + } + break; + case 10: /* realtek rtl8723au */ + if (!blocked) { + wifi_pm_gpio_ctrl("rtl8723au_bt", 1); + } else { + wifi_pm_gpio_ctrl("rtl8723au_bt", 0); + } + break; + default: + RF_MSG("no bt module matched !!\n"); + } + + msleep(10); + return 0; +} + +static struct rfkill_ops sw_rfkill_ops = { + .set_block = rfkill_set_power, +}; + +static int sw_rfkill_probe(struct platform_device *pdev) +{ + int ret = 0; + + sw_rfkill = rfkill_alloc(bt_name, &pdev->dev, + RFKILL_TYPE_BLUETOOTH, &sw_rfkill_ops, NULL); + if (unlikely(!sw_rfkill)) + return -ENOMEM; + + ret = rfkill_register(sw_rfkill); + if (unlikely(ret)) { + rfkill_destroy(sw_rfkill); + } + return ret; +} + +static int sw_rfkill_remove(struct platform_device *pdev) +{ + if (likely(sw_rfkill)) { + rfkill_unregister(sw_rfkill); + rfkill_destroy(sw_rfkill); + } + return 0; +} + +static struct platform_driver sw_rfkill_driver = { + .probe = sw_rfkill_probe, + .remove = sw_rfkill_remove, + .driver = { + .name = "sunxi-rfkill", + .owner = THIS_MODULE, + }, +}; + +static struct platform_device sw_rfkill_dev = { + .name = "sunxi-rfkill", +}; + +static int __init sw_rfkill_init(void) +{ + int type; + + + if (SCRIPT_PARSER_OK != script_parser_fetch("bt_para", "bt_used", &bt_used, 1)) { + pr_warning("[PM] parse bt_used failed\n"); + return -1; + } + + if (!bt_used) { + pr_info("[PM] bt is disable at script fex\n"); + return 0; + } + + platform_device_register(&sw_rfkill_dev); + return platform_driver_register(&sw_rfkill_driver); +} + +static void __exit sw_rfkill_exit(void) +{ + if (!bt_used) { + pr_info("[PM] exit no bt used in configuration"); + return ; + } + + platform_device_unregister(&sw_rfkill_dev); + platform_driver_unregister(&sw_rfkill_driver); +} + +module_init(sw_rfkill_init); +module_exit(sw_rfkill_exit); + +MODULE_DESCRIPTION("sunxi-rfkill driver"); +MODULE_AUTHOR("Aaron.magic"); +MODULE_LICENSE("GPL"); + diff -rupN linux-sunxi/arch/arm/mach-sun7i/rf/Makefile linux-sunxi-new/arch/arm/mach-sun7i/rf/Makefile --- linux-sunxi/arch/arm/mach-sun7i/rf/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-sunxi-new/arch/arm/mach-sun7i/rf/Makefile 2014-02-15 00:44:23.376867901 +0100 @@ -0,0 +1,5 @@ +obj-y += wifi_gpio.o +wifi_gpio-y := wifi_pm.o wifi_pm_ap6xxx.o +obj-y += bt_gpio.o +bt_gpio-y := bt_pm.o + diff -rupN linux-sunxi/arch/arm/mach-sun7i/rf/wifi_pm_ap6xxx.c linux-sunxi-new/arch/arm/mach-sun7i/rf/wifi_pm_ap6xxx.c --- linux-sunxi/arch/arm/mach-sun7i/rf/wifi_pm_ap6xxx.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-sunxi-new/arch/arm/mach-sun7i/rf/wifi_pm_ap6xxx.c 2014-02-15 00:44:23.376867901 +0100 @@ -0,0 +1,150 @@ +/* + * ap6xxx sdio wifi power management API + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wifi_pm.h" + +#define ap6xxx_msg(...) do {printk("[ap6xxx]: "__VA_ARGS__);} while(0) + +static int ap6xxx_wl_regon = 0; +static int ap6xxx_bt_regon = 0; + +static int ap6xxx_gpio_ctrl(char* name, int level) +{ + int i = 0; + int ret = 0; + int gpio = 0; + char * gpio_name[2] = {"ap6xxx_wl_regon", "ap6xxx_bt_regon"}; + + for (i = 0; i < 2; i++) { + if (strcmp(name, gpio_name[i]) == 0) { + switch (i) + { + case 0: /*ap6xxx_wl_regon*/ + gpio = ap6xxx_wl_regon; + break; + case 1: /*ap6xxx_bt_regon*/ + gpio = ap6xxx_bt_regon; + break; + default: + ap6xxx_msg("no matched gpio.\n"); + } + break; + } + } + + ret = gpio_write_one_pin_value(gpio, level, name); + + return 0; +} + +static int ap6xxx_gpio_read(char* name) +{ + int i = 0; + int gpio = 0; + int val = 0; + char * gpio_name[2] = {"ap6xxx_wl_regon", "ap6xxx_bt_regon"}; + + for (i = 0; i < 2; i++) { + if (strcmp(name, gpio_name[i]) == 0) { + switch (i) + { + case 0: /*ap6xxx_wl_regon*/ + gpio = ap6xxx_wl_regon; + break; + case 1: /*ap6xxx_bt_regon*/ + gpio = ap6xxx_bt_regon; + break; + default: + ap6xxx_msg("no matched gpio.\n"); + } + break; + } + } + + val = gpio_read_one_pin_value(gpio, name); + + return val; +} + + +void ap6xxx_power(int mode, int *updown) +{ + if (mode) { + if (*updown) { + ap6xxx_gpio_ctrl("ap6xxx_wl_regon", 1); + mdelay(100); + } else { + ap6xxx_gpio_ctrl("ap6xxx_wl_regon", 0); + mdelay(100); + } + pr_info("sdio wifi power state: %s\n", *updown ? "on" : "off"); + } else { + *updown = ap6xxx_gpio_read("ap6xxx_wl_regon"); + } + + return; +} + +static void cfg_gpio_32k_clkout(int gpio_index) +{ + int ret; + struct clk *clk_32k, *parent; + + parent = clk_get(NULL, CLK_SYS_LOSC); + clk_32k = clk_get(NULL, CLK_MOD_OUTA); + ret = clk_set_parent(clk_32k, parent); + + if(ret){ + pr_err("ap6xxx: 32k clk_set_parent fail\n"); + return; + } + + ret = clk_set_rate(clk_32k, 32768); + if(ret){ + pr_err("ap6xxx: 32k clk_set_rate fail\n"); + return; + } + + clk_enable(clk_32k); +} +void ap6xxx_gpio_init(void) +{ + struct wifi_pm_ops *ops = &wifi_select_pm_ops; + int ap6xxx_lpo = 0; + +/* CT expected ap6xxx_lpo as a GPIO */ + ap6xxx_lpo = gpio_request_ex(wifi_para, "ap6xxx_lpo"); + if (!ap6xxx_lpo) { + pr_err("ap6xxx: request lpo gpio failed\n"); + return; + } + + if(ap6xxx_lpo) { + pr_info("ap6xxx: config 32k clock\n"); + cfg_gpio_32k_clkout(ap6xxx_lpo); + } + + ap6xxx_wl_regon = gpio_request_ex(wifi_para, "ap6xxx_wl_regon"); + if (!ap6xxx_wl_regon) { + pr_err("ap6xxx: request wl_regon gpio failed\n"); + return; + } + + ap6xxx_bt_regon = gpio_request_ex(wifi_para, "ap6xxx_bt_regon"); + if (!ap6xxx_bt_regon) { + pr_err("ap6xxx: request ap6xxx_bt_regon gpio failed\n"); + return; + } + + ops->gpio_ctrl = ap6xxx_gpio_ctrl; + ops->power = ap6xxx_power; +} diff -rupN linux-sunxi/arch/arm/mach-sun7i/rf/wifi_pm.c linux-sunxi-new/arch/arm/mach-sun7i/rf/wifi_pm.c --- linux-sunxi/arch/arm/mach-sun7i/rf/wifi_pm.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-sunxi-new/arch/arm/mach-sun7i/rf/wifi_pm.c 2014-02-15 00:44:23.376867901 +0100 @@ -0,0 +1,265 @@ +#include +#include +#include +#include +#include +#include +#include +#include "wifi_pm.h" + +#define wifi_pm_msg(...) do {printk("[wifi_pm]: "__VA_ARGS__);} while(0) + + +struct wifi_pm_ops wifi_select_pm_ops; +static char* wifi_mod[] = {" ", + "bcm40181", /* 1 - BCM40181(BCM4330)*/ + "bcm40183", /* 2 - BCM40183(BCM4330)*/ + "rtl8723as", /* 3 - RTL8723AS(RF-SM02B) */ + "rtl8189es", /* 4 - RTL8189ES(SM89E00) */ + "rtl8192cu", /* 5 - RTL8192CU*/ + "rtl8188eu", /* 6 - RTL8188EU*/ + "ap6210", /* 7 - AP6210*/ + "ap6330", /* 8 - AP6330*/ + "ap6181", /* 9 - AP6181*/ + "rtl8723au", /* 10 - RTL8723AU */ +}; + +int wifi_pm_get_mod_type(void) +{ + struct wifi_pm_ops *ops = &wifi_select_pm_ops; + if (ops->wifi_used) + return ops->module_sel; + else { + wifi_pm_msg("No select wifi, please check your config !!\n"); + return 0; + } +} +EXPORT_SYMBOL(wifi_pm_get_mod_type); + +int wifi_pm_gpio_ctrl(char* name, int level) +{ + struct wifi_pm_ops *ops = &wifi_select_pm_ops; + if (ops->wifi_used && ops->gpio_ctrl) + return ops->gpio_ctrl(name, level); + else { + wifi_pm_msg("No select wifi, please check your config !!\n"); + return -1; + } +} +EXPORT_SYMBOL(wifi_pm_gpio_ctrl); + +void wifi_pm_power(int on) +{ + struct wifi_pm_ops *ops = &wifi_select_pm_ops; + int power = on; + + if (ops->wifi_used && ops->power) + return ops->power(1, &power); + else { + wifi_pm_msg("No select wifi, please check your config !!\n"); + return; + } +} +EXPORT_SYMBOL(wifi_pm_power); + +#ifdef CONFIG_PROC_FS +static int wifi_pm_power_stat(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + struct wifi_pm_ops *ops = (struct wifi_pm_ops *)data; + char *p = page; + int power = 0; + + if (ops->power) + ops->power(0, &power); + + p += sprintf(p, "%s : power state %s\n", ops->mod_name, power ? "on" : "off"); + return p - page; +} + +static int wifi_pm_power_ctrl(struct file *file, const char __user *buffer, unsigned long count, void *data) +{ + struct wifi_pm_ops *ops = (struct wifi_pm_ops *)data; + int power = simple_strtoul(buffer, NULL, 10); + + power = power ? 1 : 0; + if (ops->power) + ops->power(1, &power); + else + wifi_pm_msg("No power control for %s\n", ops->mod_name); + return sizeof(power); +} + +static inline void awwifi_procfs_attach(void) +{ + char proc_rootname[] = "driver/wifi-pm"; + struct wifi_pm_ops *ops = &wifi_select_pm_ops; + + ops->proc_root = proc_mkdir(proc_rootname, NULL); + if (IS_ERR(ops->proc_root)) + { + wifi_pm_msg("failed to create procfs \"driver/wifi-pm\".\n"); + } + + ops->proc_power = create_proc_entry("power", 0644, ops->proc_root); + if (IS_ERR(ops->proc_power)) + { + wifi_pm_msg("failed to create procfs \"power\".\n"); + } + ops->proc_power->data = ops; + ops->proc_power->read_proc = wifi_pm_power_stat; + ops->proc_power->write_proc = wifi_pm_power_ctrl; +} + +static inline void awwifi_procfs_remove(void) +{ + struct wifi_pm_ops *ops = &wifi_select_pm_ops; + char proc_rootname[] = "driver/wifi-pm"; + + remove_proc_entry("power", ops->proc_root); + remove_proc_entry(proc_rootname, NULL); +} +#else +static inline void awwifi_procfs_attach(void) {} +static inline void awwifi_procfs_remove(void) {} +#endif + +static int wifi_pm_get_res(void) +{ + struct wifi_pm_ops *ops = &wifi_select_pm_ops; + + if (SCRIPT_PARSER_OK != script_parser_fetch(wifi_para, "wifi_used", &ops->wifi_used, 1)) { + pr_warning("pm: parse wifi_used failed\n"); + return -1; + } + if (!ops->wifi_used) { + pr_info("pm: wifi pm is disable in config\n"); + return -1; + } + + if (SCRIPT_PARSER_OK != script_parser_fetch(wifi_para, "wifi_sdc_id", &ops->sdio_id, 1)) { + pr_warning("pm: parse wifi_sdc_id failed\n"); + return -1; + } + + if (SCRIPT_PARSER_OK != script_parser_fetch(wifi_para, "wifi_usbc_id", &ops->usb_id, 1)) { + pr_warning("pm: parse wifi_sdc_id failed\n"); + return -1; + } + + if (SCRIPT_PARSER_OK != script_parser_fetch(wifi_para, "wifi_mod_sel", &ops->module_sel, 1)) { + pr_warning("pm: parse wifi_sdc_id failed\n"); + return -1; + } + + ops->mod_name = wifi_mod[ops->module_sel]; + + printk("pm: select wifi: %s\n", wifi_mod[ops->module_sel]); + + return 0; +} + +static int __devinit wifi_pm_probe(struct platform_device *pdev) +{ + struct wifi_pm_ops *ops = &wifi_select_pm_ops; + + switch (ops->module_sel) { + case 1: /* BCM40181 */ + case 2: /* BCM40183 */ + case 3: /* RTL8723AS */ + case 4: /* RTL8189ES */ + case 5: /* RTL8192CU */ + case 6: /* RTL8188EU */ + pr_warning("wifi_pm: Unsupported wifi type!\n"); + break; + case 7: /* AP6210 */ + case 8: /* AP6330 */ + case 9: /* AP6181 */ + ap6xxx_gpio_init(); + break; + case 10: /* RTL8723AU */ + pr_warning("wifi_pm: Unsupported wifi type!\n"); + break; + default: + pr_warning("wifi_pm: Unsupported wifi type!\n"); + } + + awwifi_procfs_attach(); + wifi_pm_msg("wifi gpio init is OK !!\n"); + return 0; +} + +static int __devexit wifi_pm_remove(struct platform_device *pdev) +{ + awwifi_procfs_remove(); + wifi_pm_msg("wifi gpio is released !!\n"); + return 0; +} + +#ifdef CONFIG_PM +static int wifi_pm_suspend(struct device *dev) +{ + struct wifi_pm_ops *ops = &wifi_select_pm_ops; + + if (ops->standby) + ops->standby(1); + return 0; +} + +static int wifi_pm_resume(struct device *dev) +{ + struct wifi_pm_ops *ops = &wifi_select_pm_ops; + + if (ops->standby) + ops->standby(0); + return 0; +} + +static struct dev_pm_ops wifi_dev_pm_ops = { + .suspend = wifi_pm_suspend, + .resume = wifi_pm_resume, +}; +#endif + +static struct platform_device wifi_pm_dev = { + .name = "wifi_pm", +}; + +static struct platform_driver wifi_pm_driver = { + .driver.name = "wifi_pm", + .driver.owner = THIS_MODULE, +#ifdef CONFIG_PM + .driver.pm = &wifi_dev_pm_ops, +#endif + .probe = wifi_pm_probe, + .remove = __devexit_p(wifi_pm_remove), +}; + +static int __init wifi_pm_init(void) +{ + struct wifi_pm_ops *ops = &wifi_select_pm_ops; + + memset(ops, 0, sizeof(struct wifi_pm_ops)); + wifi_pm_get_res(); + if (!ops->wifi_used) + return 0; + + platform_device_register(&wifi_pm_dev); + return platform_driver_register(&wifi_pm_driver); +} + +static void __exit wifi_pm_exit(void) +{ + struct wifi_pm_ops *ops = &wifi_select_pm_ops; + if (!ops->wifi_used) + return; + + platform_driver_unregister(&wifi_pm_driver); + memset(ops, 0, sizeof(struct wifi_pm_ops)); +} + +module_init(wifi_pm_init); +module_exit(wifi_pm_exit); + +MODULE_LICENSE("GPL"); + + diff -rupN linux-sunxi/arch/arm/mach-sun7i/rf/wifi_pm.h linux-sunxi-new/arch/arm/mach-sun7i/rf/wifi_pm.h --- linux-sunxi/arch/arm/mach-sun7i/rf/wifi_pm.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-sunxi-new/arch/arm/mach-sun7i/rf/wifi_pm.h 2014-02-15 00:44:23.376867901 +0100 @@ -0,0 +1,30 @@ +#ifndef WIFI__PM__H +#define WIFI__PM__H + +#include +#define SDIO_WIFI_POWERUP (1) +#define SDIO_WIFI_INSUSPEND (2) +static char* wifi_para = "wifi_para"; + +struct wifi_pm_ops { + char* mod_name; + int wifi_used; + int sdio_id; + int usb_id; + int module_sel; + int (*gpio_ctrl)(char* name, int level); + void (*standby)(int in); + void (*power)(int mode, int *updown); + +#ifdef CONFIG_PROC_FS + struct proc_dir_entry *proc_root; + struct proc_dir_entry *proc_power; +#endif +}; + +void ap6xxx_gpio_init(void); + +extern struct wifi_pm_ops wifi_select_pm_ops; +extern void sw_mci_rescan_card(unsigned id, unsigned insert); + +#endif diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/aiutils.c linux-sunxi-new/drivers/net/wireless/bcmdhd/aiutils.c --- linux-sunxi/drivers/net/wireless/bcmdhd/aiutils.c 2014-01-27 01:30:30.108433411 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/aiutils.c 2014-02-15 00:43:44.795014136 +0100 @@ -2,7 +2,7 @@ * Misc utility routines for accessing chip-specific features * of the SiliconBackplane-based Broadcom chips. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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: aiutils.c 385510 2013-02-15 21:02:07Z $ + * $Id: aiutils.c 347614 2012-07-27 10:24:51Z $ */ #include #include @@ -38,7 +38,6 @@ #define BCM47162_DMP() (0) #define BCM5357_DMP() (0) -#define BCM4707_DMP() (0) #define remap_coreid(sih, coreid) (coreid) #define remap_corerev(sih, corerev) (corerev) @@ -208,7 +207,7 @@ ai_scan(si_t *sih, void *regs, uint devi sii->oob_router = addrl; } } - if (cid != GMAC_COMMON_4706_CORE_ID && cid != NS_CCB_CORE_ID) + if (cid != GMAC_COMMON_4706_CORE_ID) continue; } @@ -250,10 +249,10 @@ ai_scan(si_t *sih, void *regs, uint devi "0x%x\n", addrh, sizeh, sizel)); SI_ERROR(("First Slave ASD for" "core 0x%04x malformed " - "(0x%08x)\n", cid, asd)); - goto error; - } + "(0x%08x)\n", cid, asd)); + goto error; } + } } while (1); } sii->coresba[idx] = addrl; @@ -366,7 +365,7 @@ ai_setcoreidx(si_t *sih, uint coreidx) ASSERT(GOODREGS(sii->regs[coreidx])); } sii->curmap = regs = sii->regs[coreidx]; - if (!sii->wrappers[coreidx] && (wrap != 0)) { + if (!sii->wrappers[coreidx]) { sii->wrappers[coreidx] = REG_MAP(wrap, SI_CORE_SIZE); ASSERT(GOODREGS(sii->wrappers[coreidx])); } @@ -542,41 +541,11 @@ ai_flag(si_t *sih) SI_ERROR(("%s: Attempting to read USB20H DMP registers on 5357b0\n", __FUNCTION__)); return sii->curidx; } - if (BCM4707_DMP()) { - SI_ERROR(("%s: Attempting to read CHIPCOMMONB DMP registers on 4707\n", - __FUNCTION__)); - return sii->curidx; - } ai = sii->curwrap; return (R_REG(sii->osh, &ai->oobselouta30) & 0x1f); } -uint -ai_flag_alt(si_t *sih) -{ - si_info_t *sii; - 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; - } - if (BCM4707_DMP()) { - SI_ERROR(("%s: Attempting to read CHIPCOMMONB DMP registers on 4707\n", - __FUNCTION__)); - return sii->curidx; - } - ai = sii->curwrap; - - return ((R_REG(sii->osh, &ai->oobselouta30) >> AI_OOBSEL_1_SHIFT) & AI_OOBSEL_MASK); -} - void ai_setint(si_t *sih, int siflag) { @@ -755,15 +724,15 @@ ai_core_disable(si_t *sih, uint32 bits) /* this is in big hammer path, so don't call wl_reinit in this case... */ } - W_REG(sii->osh, &ai->resetctrl, AIRC_RESET); - dummy = R_REG(sii->osh, &ai->resetctrl); - BCM_REFERENCE(dummy); - OSL_DELAY(1); - 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); } /* reset and re-enable a core @@ -824,11 +793,6 @@ ai_core_cflags_wo(si_t *sih, uint32 mask __FUNCTION__)); return; } - if (BCM4707_DMP()) { - SI_ERROR(("%s: Accessing CHIPCOMMONB DMP register (ioctrl) on 4707\n", - __FUNCTION__)); - return; - } ASSERT(GOODREGS(sii->curwrap)); ai = sii->curwrap; @@ -859,11 +823,6 @@ ai_core_cflags(si_t *sih, uint32 mask, u __FUNCTION__)); return 0; } - if (BCM4707_DMP()) { - SI_ERROR(("%s: Accessing CHIPCOMMONB DMP register (ioctrl) on 4707\n", - __FUNCTION__)); - return 0; - } ASSERT(GOODREGS(sii->curwrap)); ai = sii->curwrap; @@ -896,11 +855,6 @@ ai_core_sflags(si_t *sih, uint32 mask, u __FUNCTION__)); return 0; } - if (BCM4707_DMP()) { - SI_ERROR(("%s: Accessing CHIPCOMMONB DMP register (ioctrl) on 4707\n", - __FUNCTION__)); - return 0; - } ASSERT(GOODREGS(sii->curwrap)); ai = sii->curwrap; diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/bcmevent.c linux-sunxi-new/drivers/net/wireless/bcmdhd/bcmevent.c --- linux-sunxi/drivers/net/wireless/bcmdhd/bcmevent.c 2014-01-27 01:30:30.100433249 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/bcmevent.c 2014-02-15 00:43:44.791014047 +0100 @@ -1,7 +1,7 @@ /* * bcmevent read-only data shared by kernel or app layers * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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 389384 2013-03-06 12:20:17Z $ + * $Id: bcmevent.c 370587 2012-11-22 09:32:38Z $ */ #include @@ -29,7 +29,7 @@ #include #include -#if WLC_E_LAST != 125 +#if WLC_E_LAST != 107 #error "You need to add an entry to bcmevent_names[] for the new event" #endif @@ -83,6 +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" }, @@ -95,7 +98,11 @@ const bcmevent_name_t bcmevent_names[] = { WLC_E_ACTION_FRAME_RX, "ACTION_FRAME_RX" }, { WLC_E_ACTION_FRAME_COMPLETE, "ACTION_FRAME_COMPLETE" }, #endif -#if 0 && (0>= 0x0620) +#ifdef BCMWAPI_WAI + { WLC_E_WAI_STA_EVENT, "WAI_STA_EVENT" }, + { WLC_E_WAI_MSG, "WAI_MSG" }, +#endif /* BCMWAPI_WAI */ +#if 0 && (NDISVER >= 0x0620) { WLC_E_PRE_ASSOC_IND, "ASSOC_RECV" }, { WLC_E_PRE_REASSOC_IND, "REASSOC_RECV" }, { WLC_E_CHANNEL_ADOPTED, "CHANNEL_ADOPTED" }, @@ -106,7 +113,6 @@ const bcmevent_name_t bcmevent_names[] = { WLC_E_REASSOC_IND_NDIS, "REASSOC_IND_NDIS"}, { WLC_E_ACTION_FRAME_RX_NDIS, "WLC_E_ACTION_FRAME_RX_NDIS" }, { WLC_E_AUTH_REQ, "WLC_E_AUTH_REQ" }, - { WLC_E_IBSS_COALESCE, "IBSS COALESCE" }, #endif { WLC_E_ESCAN_RESULT, "WLC_E_ESCAN_RESULT" }, { WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE, "WLC_E_AF_OFF_CHAN_COMPLETE" }, @@ -137,22 +143,9 @@ const bcmevent_name_t bcmevent_names[] = #ifdef WLTDLS { WLC_E_TDLS_PEER_EVENT, "TDLS_PEER_EVENT" }, #endif /* WLTDLS */ - { WLC_E_NATIVE, "NATIVE" }, -#ifdef WLPKTDLYSTAT - { WLC_E_PKTDELAY_IND, "PKTDELAY_IND" }, -#endif /* WLPKTDLYSTAT */ { WLC_E_SERVICE_FOUND, "SERVICE_FOUND" }, - { WLC_E_GAS_FRAGMENT_RX, "GAS_FRAGMENT_RX" }, - { WLC_E_GAS_COMPLETE, "GAS_COMPLETE" }, { WLC_E_P2PO_ADD_DEVICE, "P2PO_DEV_FOUND" }, { WLC_E_P2PO_DEL_DEVICE, "P2PO_DEV_LOST" }, -#ifdef WLWNM - { WLC_E_WNM_STA_SLEEP, "WMM_STA_SLEEP" }, -#endif /* WLWNM */ -#if defined(WL_PROXDETECT) - { WLC_E_PROXD, "WLC_E_PROXD" }, -#endif - { WLC_E_CCA_CHAN_QUAL, "CCA_BASED_CHANNEL_QUALITY" }, }; const int bcmevent_names_size = ARRAYSIZE(bcmevent_names); diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/bcmsdh.c linux-sunxi-new/drivers/net/wireless/bcmdhd/bcmsdh.c --- linux-sunxi/drivers/net/wireless/bcmdhd/bcmsdh.c 2014-01-27 01:30:30.108433411 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/bcmsdh.c 2014-02-15 00:43:44.795014136 +0100 @@ -2,7 +2,7 @@ * BCMSDH interface glue * implement bcmsdh API for SDIOH driver * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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 373331 2012-12-07 04:46:22Z $ + * $Id: bcmsdh.c 373330 2012-12-07 04:46:17Z $ */ /** @@ -74,6 +74,26 @@ bcmsdh_enable_hw_oob_intr(bcmsdh_info_t } #endif +#if defined(HW_OOB) +#include +void +bcmsdh_config_hw_oob_intr(bcmsdh_info_t *sdh, uint chip) +{ + uint32 gpiocontrol, addr; + + printf("%s: Enter\n", __FUNCTION__); + if (CHIPID(chip) == BCM43362_CHIP_ID) { + 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 + /* Attach BCMSDH layer to SDIO Host Controller Driver * * @param osh OSL Handle. @@ -728,10 +748,10 @@ bcmsdh_gpioout(void *sdh, uint32 gpio, b #ifdef BCMSDIOH_TXGLOM void -bcmsdh_glom_post(void *sdh, uint8 *frame, void *pkt, uint len) +bcmsdh_glom_post(void *sdh, uint8 *frame, uint len) { bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - sdioh_glom_post(bcmsdh->sdioh, frame, pkt, len); + sdioh_glom_post(bcmsdh->sdioh, frame, len); } void diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/bcmsdh_linux.c linux-sunxi-new/drivers/net/wireless/bcmdhd/bcmsdh_linux.c --- linux-sunxi/drivers/net/wireless/bcmdhd/bcmsdh_linux.c 2014-01-27 01:30:30.108433411 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/bcmsdh_linux.c 2014-02-15 00:43:44.795014136 +0100 @@ -1,7 +1,7 @@ /* * SDIO access interface for drivers - linux specific (pci only) * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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 414953 2013-07-26 17:36:27Z $ + * $Id: bcmsdh_linux.c 373359 2012-12-07 06:36:37Z $ */ /** @@ -40,6 +40,8 @@ #include #include #include +#include +#include #if defined(OOB_INTR_ONLY) #include @@ -47,8 +49,11 @@ extern void dhdsdio_isr(void * args); #include #include #include +#include +#include #endif + /** * SDIO Host Controller info */ @@ -75,13 +80,11 @@ struct bcmsdh_hc { }; static bcmsdh_hc_t *sdhcinfo = NULL; -struct device *pm_dev; - /* driver info, initialized when bcmsdh_register is called */ static bcmsdh_driver_t drvinfo = {NULL, NULL}; /* debugging macros */ -#define SDLX_MSG(x) +#define SDLX_MSG(x) printf x /** * Checks to see if vendor and device IDs match a supported SDIO Host Controller. @@ -154,7 +157,7 @@ static int bcmsdh_probe(struct device *dev) { osl_t *osh = NULL; - bcmsdh_hc_t *sdhc = NULL, *sdhc_org = sdhcinfo; + bcmsdh_hc_t *sdhc = NULL; ulong regs = 0; bcmsdh_info_t *sdh = NULL; #if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS) @@ -169,7 +172,7 @@ int bcmsdh_probe(struct device *dev) pdev = to_platform_device(dev); r = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq = platform_get_irq(pdev, 0); - if (!r || irq < 0) + if (!r || irq == NO_IRQ) return -ENXIO; #endif @@ -183,9 +186,13 @@ int bcmsdh_probe(struct device *dev) /* Get customer specific OOB IRQ parametres: IRQ number as IRQ type */ irq = dhd_customer_oob_irq_map(&irq_flags); +#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI) + /* Do not disable this IRQ during suspend */ + irq_flags |= IRQF_NO_SUSPEND; +#endif /* defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI) */ if (irq < 0) { SDLX_MSG(("%s: Host irq is not defined\n", __FUNCTION__)); - goto err; + return 1; } #endif /* allocate SDIO Host Controller state info */ @@ -230,11 +237,6 @@ int bcmsdh_probe(struct device *dev) sdhc->next = sdhcinfo; sdhcinfo = sdhc; -#if !defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) - if (!device_init_wakeup(dev, 1)) - pm_dev = dev; -#endif /* !CONFIG_HAS_WAKELOCK */ - /* Read the vendor/device ID from the CIS */ vendevid = bcmsdh_query_device(sdh); /* try to attach to the target device */ @@ -253,7 +255,6 @@ err: if (sdhc->sdh) bcmsdh_detach(sdhc->osh, sdhc->sdh); MFREE(osh, sdhc, sizeof(bcmsdh_hc_t)); - sdhcinfo = sdhc_org; } if (osh) osl_detach(osh); @@ -267,20 +268,18 @@ int bcmsdh_remove(struct device *dev) { bcmsdh_hc_t *sdhc, *prev; osl_t *osh; - int sdhcinfo_null = false; + + sdhc = sdhcinfo; + drvinfo.detach(sdhc->ch); + bcmsdh_detach(sdhc->osh, sdhc->sdh); /* find the SDIO Host Controller state for this pdev and take it out from the list */ for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) { if (sdhc->dev == (void *)dev) { if (prev) prev->next = sdhc->next; - else { - if (sdhc->next != NULL) { - SDLX_MSG(("%s: more SDHC exist, should be care about it\n", - __FUNCTION__)); - } - sdhcinfo_null = true; - } + else + sdhcinfo = NULL; break; } prev = sdhc; @@ -290,20 +289,6 @@ int bcmsdh_remove(struct device *dev) return 0; } - /* detach ch & sdhc if dev is valid */ - drvinfo.detach(sdhc->ch); - bcmsdh_detach(sdhc->osh, sdhc->sdh); - -#if !defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) - if (pm_dev) { - device_init_wakeup(pm_dev, 0); - pm_dev = NULL; - } -#endif /* !CONFIG_HAS_WAKELOCK */ - - if (sdhcinfo_null == true) - sdhcinfo = NULL; - /* release SDIO Host Controller info */ osh = sdhc->osh; MFREE(osh, sdhc, sizeof(bcmsdh_hc_t)); @@ -428,10 +413,6 @@ bcmsdh_pci_probe(struct pci_dev *pdev, c /* match this pci device with what we support */ /* we can't solely rely on this to believe it is our SDIO Host Controller! */ if (!bcmsdh_chipmatch(pdev->vendor, pdev->device)) { - if (pdev->vendor == VENDOR_BROADCOM) { - SDLX_MSG(("%s: Unknown Broadcom device (vendor: %#x, device: %#x).\n", - __FUNCTION__, pdev->vendor, pdev->device)); - } return -ENODEV; } @@ -601,7 +582,18 @@ bcmsdh_unregister(void) #endif /* BCMPLATFORM_BUS */ } +int bcmsdh_set_drvdata(void * dhdp) +{ + SDLX_MSG(("%s Enter \n", __FUNCTION__)); + + dev_set_drvdata(sdhcinfo->dev, dhdp); + + return 0; +} + #if defined(OOB_INTR_ONLY) +#define CONFIG_ARCH_SUN6I_BCMDHD 1 + void bcmsdh_oob_intr_set(bool enable) { static bool curstate = 1; @@ -609,12 +601,15 @@ void bcmsdh_oob_intr_set(bool enable) spin_lock_irqsave(&sdhcinfo->irq_lock, flags); if (curstate != enable) { - if (enable) - enable_irq(sdhcinfo->oob_irq); - else - disable_irq_nosync(sdhcinfo->oob_irq); + if(enable) { + enable_irq(sdhcinfo->oob_irq); + } + else { + disable_irq_nosync(sdhcinfo->oob_irq); + } curstate = enable; } + spin_unlock_irqrestore(&sdhcinfo->irq_lock, flags); } @@ -636,26 +631,39 @@ static irqreturn_t wlan_oob_irq(int irq, return IRQ_HANDLED; } +extern int wl_host_wake_irqno; +irqreturn_t bcmdhd_gpio_irq_handler(int irq, void *dev) +{ + wlan_oob_irq(0, NULL); + return IRQ_HANDLED; +} + int bcmsdh_register_oob_intr(void * dhdp) { int error = 0; - + int ret; SDLX_MSG(("%s Enter \n", __FUNCTION__)); /* IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE; */ - dev_set_drvdata(sdhcinfo->dev, dhdp); if (!sdhcinfo->oob_irq_registered) { SDLX_MSG(("%s IRQ=%d Type=%X \n", __FUNCTION__, (int)sdhcinfo->oob_irq, (int)sdhcinfo->oob_flags)); - /* Refer to customer Host IRQ docs about proper irqflags definition */ - error = request_irq(sdhcinfo->oob_irq, wlan_oob_irq, sdhcinfo->oob_flags, - "bcmsdh_sdmmc", NULL); - if (error) - return -ENODEV; + ret = request_irq(wl_host_wake_irqno, bcmdhd_gpio_irq_handler, IRQF_DISABLED| IRQF_SHARED| IRQF_TRIGGER_HIGH, "bcmdhd_gpio_irq", (void *)&wl_host_wake_irqno); + if (ret) { + pr_err("bcmdhd: request irq%d failed\n", wl_host_wake_irqno); + return -1; + } + +#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI) || defined(CONFIG_ARCH_SUN6I_BCMDHD) + if (device_may_wakeup(sdhcinfo->dev)) { +#endif error = enable_irq_wake(sdhcinfo->oob_irq); +#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI) || defined(CONFIG_ARCH_SUN6I_BCMDHD) + } +#endif if (error) SDLX_MSG(("%s enable_irq_wake error=%d \n", __FUNCTION__, error)); sdhcinfo->oob_irq_registered = TRUE; @@ -668,13 +676,22 @@ int bcmsdh_register_oob_intr(void * dhdp void bcmsdh_set_irq(int flag) { if (sdhcinfo->oob_irq_registered && sdhcinfo->oob_irq_enable_flag != flag) { - SDLX_MSG(("%s Flag = %d", __FUNCTION__, flag)); + SDLX_MSG(("%s Flag = %d\n", __FUNCTION__, flag)); sdhcinfo->oob_irq_enable_flag = flag; if (flag) { enable_irq(sdhcinfo->oob_irq); + +#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI) || defined(CONFIG_ARCH_SUN6I_BCMDHD) + if (device_may_wakeup(sdhcinfo->dev)) +#endif enable_irq_wake(sdhcinfo->oob_irq); } else { +#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI) || defined(CONFIG_ARCH_SUN6I_BCMDHD) + if (device_may_wakeup(sdhcinfo->dev)) +#endif disable_irq_wake(sdhcinfo->oob_irq); + + disable_irq(sdhcinfo->oob_irq); } } @@ -685,19 +702,15 @@ void bcmsdh_unregister_oob_intr(void) SDLX_MSG(("%s: Enter\n", __FUNCTION__)); if (sdhcinfo->oob_irq_registered == TRUE) { - bcmsdh_set_irq(FALSE); - free_irq(sdhcinfo->oob_irq, NULL); + + if(0 != wl_host_wake_irqno) { + pr_info("bcmdhd: free_irq %d\n", wl_host_wake_irqno); + free_irq(wl_host_wake_irqno, &wl_host_wake_irqno); + } + sdhcinfo->oob_irq_registered = FALSE; } } - -bool bcmsdh_is_oob_intr_registered(void) -{ - if (sdhcinfo) - return sdhcinfo->oob_irq_registered; - else - return FALSE; -} #endif #if defined(BCMLXSDMMC) @@ -735,10 +748,6 @@ module_param(sd_f2_blocksize, int, 0); #ifdef BCMSDIOH_STD extern int sd_uhsimode; module_param(sd_uhsimode, int, 0); -extern uint sd_tuning_period; -module_param(sd_tuning_period, uint, 0); -extern int sd_delay_value; -module_param(sd_delay_value, uint, 0); #endif #ifdef BCMSDIOH_TXGLOM diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c linux-sunxi-new/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c --- linux-sunxi/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c 2014-01-27 01:30:30.108433411 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c 2014-02-15 00:43:44.795014136 +0100 @@ -1,7 +1,7 @@ /* * BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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 418714 2013-08-16 13:21:09Z $ + * $Id: bcmsdh_sdmmc.c 362913 2012-10-15 11:26:11Z $ */ #include @@ -59,6 +59,7 @@ static void IRQHandlerF2(struct sdio_fun #endif /* !defined(OOB_INTR_ONLY) */ static int sdioh_sdmmc_get_cisaddr(sdioh_info_t *sd, uint32 regaddr); extern int sdio_reset_comm(struct mmc_card *card); +extern int sw_mci_check_r1_ready(struct mmc_host* mmc, unsigned ms); extern PBCMSDH_SDMMC_INSTANCE gInstance; @@ -76,18 +77,6 @@ uint sd_clock = 1; /* Default to SD Clo uint sd_hiok = FALSE; /* Don't use hi-speed mode by default */ uint sd_msglevel = 0x01; uint sd_use_dma = TRUE; - -#ifdef BCMSDIOH_TXGLOM -#ifndef CUSTOM_TXGLOM -#define CUSTOM_TXGLOM 0 -#endif -uint sd_txglom = CUSTOM_TXGLOM; -#endif /* BCMSDIOH_TXGLOM */ - -#ifndef CUSTOM_RXCHAIN -#define CUSTOM_RXCHAIN 0 -#endif - DHD_PM_RESUME_WAIT_INIT(sdioh_request_byte_wait); DHD_PM_RESUME_WAIT_INIT(sdioh_request_word_wait); DHD_PM_RESUME_WAIT_INIT(sdioh_request_packet_wait); @@ -166,7 +155,7 @@ sdioh_attach(osl_t *osh, void *bar0, uin sd->sd_blockmode = TRUE; sd->use_client_ints = TRUE; sd->client_block_size[0] = 64; - sd->use_rxchain = CUSTOM_RXCHAIN; + sd->use_rxchain = FALSE; gInstance->sd = sd; @@ -176,14 +165,12 @@ sdioh_attach(osl_t *osh, void *bar0, uin sd->client_block_size[1] = 64; err_ret = sdio_set_block_size(gInstance->func[1], 64); - /* Release host controller F1 */ - sdio_release_host(gInstance->func[1]); if (err_ret) { sd_err(("bcmsdh_sdmmc: Failed to set F1 blocksize\n")); - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - return NULL; } + /* Release host controller F1 */ + sdio_release_host(gInstance->func[1]); } else { sd_err(("%s:gInstance->func[1] is null\n", __FUNCTION__)); MFREE(sd->osh, sd, sizeof(sdioh_info_t)); @@ -196,15 +183,13 @@ sdioh_attach(osl_t *osh, void *bar0, uin sd->client_block_size[2] = sd_f2_blocksize; err_ret = sdio_set_block_size(gInstance->func[2], sd_f2_blocksize); - /* Release host controller F2 */ - sdio_release_host(gInstance->func[2]); if (err_ret) { sd_err(("bcmsdh_sdmmc: Failed to set F2 blocksize to %d\n", sd_f2_blocksize)); - MFREE(sd->osh, sd, sizeof(sdioh_info_t)); - return NULL; } + /* Release host controller F2 */ + sdio_release_host(gInstance->func[2]); } else { sd_err(("%s:gInstance->func[2] is null\n", __FUNCTION__)); MFREE(sd->osh, sd, sizeof(sdioh_info_t)); @@ -266,9 +251,9 @@ sdioh_enable_func_intr(void) return SDIOH_API_RC_FAIL; } - /* Enable F1 and F2 interrupts, clear master enable */ - reg &= ~INTR_CTL_MASTER_EN; - reg |= (INTR_CTL_FUNC1_EN | INTR_CTL_FUNC2_EN); + /* Enable F1 and F2 interrupts, set master enable */ + reg |= (INTR_CTL_FUNC1_EN | INTR_CTL_FUNC2_EN | INTR_CTL_MASTER_EN); + sdio_writeb(gInstance->func[0], reg, SDIOD_CCCR_INTEN, &err); sdio_release_host(gInstance->func[0]); @@ -795,10 +780,11 @@ sdioh_cis_read(sdioh_info_t *sd, uint fu extern SDIOH_API_RC sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, uint8 *byte) { - int err_ret = 0; + int err_ret; #if defined(MMC_SDIO_ABORT) int sdio_abort_retry = MMC_SDIO_ABORT_RETRY_LIMIT; #endif + int ret = 0; sd_info(("%s: rw=%d, func=%d, addr=0x%05x\n", __FUNCTION__, rw, func, regaddr)); @@ -833,14 +819,18 @@ sdioh_request_byte(sdioh_info_t *sd, uin #if defined(MMC_SDIO_ABORT) /* to allow abort command through F1 */ else if (regaddr == SDIOD_CCCR_IOABORT) { + /* Because of SDIO3.0 host issue on Manta, + * sometimes the abort fails. + * Retrying again will fix this issue. + */ while (sdio_abort_retry--) { if (gInstance->func[func]) { sdio_claim_host(gInstance->func[func]); /* - * this sdio_f0_writeb() can be replaced with - * another api depending upon MMC driver change. - * As of this time, this is temporaray one - */ + * this sdio_f0_writeb() can be replaced with + * another api depending upon MMC driver change. + * As of this time, this is temporaray one + */ sdio_writeb(gInstance->func[func], *byte, regaddr, &err_ret); sdio_release_host(gInstance->func[func]); @@ -882,12 +872,14 @@ sdioh_request_byte(sdioh_info_t *sd, uin } } + //AW judge sdio read write timeout, 1s + ret = sw_mci_check_r1_ready(gInstance->func[func]->card->host, 1000); + if (ret != 0) + printk(("%s data timeout.\n", __FUNCTION__)); + if (err_ret) { - if ((regaddr == 0x1001F) && (err_ret == -110)) { - } else { - sd_err(("bcmsdh_sdmmc: Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n", - rw ? "Write" : "Read", func, regaddr, *byte, err_ret)); - } + sd_err(("bcmsdh_sdmmc: Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n", + rw ? "Write" : "Read", func, regaddr, *byte, err_ret)); } return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL); @@ -901,6 +893,7 @@ sdioh_request_word(sdioh_info_t *sd, uin #if defined(MMC_SDIO_ABORT) int sdio_abort_retry = MMC_SDIO_ABORT_RETRY_LIMIT; #endif + int ret = 0; if (func == 0) { sd_err(("%s: Only CMD52 allowed to F0.\n", __FUNCTION__)); @@ -915,7 +908,7 @@ sdioh_request_word(sdioh_info_t *sd, uin /* Claim host controller */ sdio_claim_host(gInstance->func[func]); - if(rw) { /* CMD52 Write */ + if(rw) { /* CMD53 Write */ if (nbytes == 4) { sdio_writel(gInstance->func[func], *word, addr, &err_ret); } else if (nbytes == 2) { @@ -933,6 +926,11 @@ sdioh_request_word(sdioh_info_t *sd, uin } } + //AW judge sdio read write timeout, 1s + ret = sw_mci_check_r1_ready(gInstance->func[func]->card->host, 1000); + if (ret != 0) + printk(("%s data timeout.\n", __FUNCTION__)); + /* Release host controller */ sdio_release_host(gInstance->func[func]); @@ -943,10 +941,10 @@ sdioh_request_word(sdioh_info_t *sd, uin if (gInstance->func[0]) { sdio_claim_host(gInstance->func[0]); /* - * this sdio_f0_writeb() can be replaced with another api - * depending upon MMC driver change. - * As of this time, this is temporaray one - */ + * this sdio_f0_writeb() can be replaced with another api + * depending upon MMC driver change. + * As of this time, this is temporaray one + */ sdio_writeb(gInstance->func[0], func, SDIOD_CCCR_IOABORT, &err_ret); sdio_release_host(gInstance->func[0]); @@ -957,103 +955,14 @@ sdioh_request_word(sdioh_info_t *sd, uin if (err_ret) #endif /* MMC_SDIO_ABORT */ { - sd_err(("bcmsdh_sdmmc: Failed to %s word, Err: 0x%08x", - rw ? "Write" : "Read", err_ret)); + sd_err(("bcmsdh_sdmmc: Failed to %s word, Err: 0x%08x\n", + rw ? "Write" : "Read", err_ret)); } } return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL); } -#ifdef BCMSDIOH_TXGLOM -void -sdioh_glom_post(sdioh_info_t *sd, uint8 *frame, void *pkt, uint len) -{ - void *phead = sd->glom_info.glom_pkt_head; - void *ptail = sd->glom_info.glom_pkt_tail; - - BCM_REFERENCE(frame); - - ASSERT(!PKTLINK(pkt)); - if (!phead) { - ASSERT(!phead); - sd->glom_info.glom_pkt_head = sd->glom_info.glom_pkt_tail = pkt; - } - else { - ASSERT(ptail); - PKTSETNEXT(sd->osh, ptail, pkt); - sd->glom_info.glom_pkt_tail = pkt; - } - sd->glom_info.count++; -} - -void -sdioh_glom_clear(sdioh_info_t *sd) -{ - void *pnow, *pnext; - - pnext = sd->glom_info.glom_pkt_head; - - if (!pnext) { - sd_err(("sdioh_glom_clear: no first packet to clear!\n")); - return; - } - - while (pnext) { - pnow = pnext; - pnext = PKTNEXT(sd->osh, pnow); - PKTSETNEXT(sd->osh, pnow, NULL); - sd->glom_info.count--; - } - - sd->glom_info.glom_pkt_head = NULL; - sd->glom_info.glom_pkt_tail = NULL; - if (sd->glom_info.count != 0) { - sd_err(("sdioh_glom_clear: glom count mismatch!\n")); - sd->glom_info.count = 0; - } -} - -uint -sdioh_set_mode(sdioh_info_t *sd, uint mode) -{ - if (mode == SDPCM_TXGLOM_CPY) - sd->txglom_mode = mode; - else if (mode == SDPCM_TXGLOM_MDESC) - sd->txglom_mode = mode; - - return (sd->txglom_mode); -} - -bool -sdioh_glom_enabled(void) -{ - return sd_txglom; -} -#endif /* BCMSDIOH_TXGLOM */ - -static INLINE int sdioh_request_packet_align(uint pkt_len, uint write, uint func, int blk_size) -{ - /* Align Patch */ - if (!write || pkt_len < 32) - pkt_len = (pkt_len + 3) & 0xFFFFFFFC; - else if ((pkt_len > blk_size) && (pkt_len % blk_size)) { - if (func == SDIO_FUNC_2) { - sd_err(("%s: [%s] dhd_sdio must align %d bytes" - " packet larger than a %d bytes blk size by a blk size\n", - __FUNCTION__, write ? "W" : "R", pkt_len, blk_size)); - } - pkt_len += blk_size - (pkt_len % blk_size); - } -#ifdef CONFIG_MMC_MSM7X00A - if ((pkt_len % 64) == 32) { - sd_err(("%s: Rounding up TX packet +=32\n", __FUNCTION__)); - pkt_len += 32; - } -#endif /* CONFIG_MMC_MSM7X00A */ - return pkt_len; -} - static SDIOH_API_RC sdioh_request_packet(sdioh_info_t *sd, uint fix_inc, uint write, uint func, uint addr, void *pkt) @@ -1061,20 +970,14 @@ sdioh_request_packet(sdioh_info_t *sd, u bool fifo = (fix_inc == SDIOH_DATA_FIX); uint32 SGCount = 0; int err_ret = 0; - void *pnext; + void *pnext, *pprev; uint ttl_len, dma_len, lft_len, xfred_len, pkt_len; uint blk_num; int blk_size; struct mmc_request mmc_req; struct mmc_command mmc_cmd; struct mmc_data mmc_dat; -#ifdef BCMSDIOH_TXGLOM - uint8 *localbuf = NULL; - uint local_plen = 0; - bool need_txglom = write && sdioh_glom_enabled() && - (pkt == sd->glom_info.glom_pkt_tail) && - (sd->glom_info.glom_pkt_head != sd->glom_info.glom_pkt_tail); -#endif /* BCMSDIOH_TXGLOM */ + int ret = 0; sd_trace(("%s: Enter\n", __FUNCTION__)); @@ -1083,29 +986,18 @@ sdioh_request_packet(sdioh_info_t *sd, u DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL); ttl_len = xfred_len = 0; -#ifdef BCMSDIOH_TXGLOM - if (need_txglom) { - pkt = sd->glom_info.glom_pkt_head; - } -#endif /* BCMSDIOH_TXGLOM */ - /* at least 4 bytes alignment of skb buff is guaranteed */ for (pnext = pkt; pnext; pnext = PKTNEXT(sd->osh, pnext)) ttl_len += PKTLEN(sd->osh, pnext); blk_size = sd->client_block_size[func]; - if (((!write && sd->use_rxchain) || -#ifdef BCMSDIOH_TXGLOM - (need_txglom && sd->txglom_mode == SDPCM_TXGLOM_MDESC) || -#endif - 0) && (ttl_len >= blk_size)) { - blk_num = ttl_len / blk_size; - dma_len = blk_num * blk_size; - } else { + if (!sd->use_rxchain || ttl_len <= blk_size) { blk_num = 0; dma_len = 0; + } else { + blk_num = ttl_len / blk_size; + dma_len = blk_num * blk_size; } - lft_len = ttl_len - dma_len; sd_trace(("%s: %s %dB to func%d:%08x, %d blks with DMA, %dB leftover\n", @@ -1118,6 +1010,7 @@ sdioh_request_packet(sdioh_info_t *sd, u memset(&mmc_dat, 0, sizeof(struct mmc_data)); /* Set up DMA descriptors */ + pprev = pkt; for (pnext = pkt; pnext && dma_len; pnext = PKTNEXT(sd->osh, pnext)) { @@ -1171,8 +1064,12 @@ sdioh_request_packet(sdioh_info_t *sd, u __FUNCTION__, write ? "write" : "read", err_ret)); - } - if (!fifo) { + sd_err(("%s:Disabling rxchain and fire it with PIO\n", + __FUNCTION__)); + sd->use_rxchain = FALSE; + pkt = pprev; + lft_len = ttl_len; + } else if (!fifo) { addr = addr + ttl_len - lft_len - dma_len; } } @@ -1184,79 +1081,27 @@ sdioh_request_packet(sdioh_info_t *sd, u for (pnext = pkt; pnext; pnext = PKTNEXT(sd->osh, pnext)) { uint8 *buf = (uint8*)PKTDATA(sd->osh, pnext) + xfred_len; - int pad = 0; pkt_len = PKTLEN(sd->osh, pnext); if (0 != xfred_len) { pkt_len -= xfred_len; xfred_len = 0; } -#ifdef BCMSDIOH_TXGLOM - if (need_txglom) { - if (!localbuf) { - uint prev_lft_len = lft_len; - lft_len = sdioh_request_packet_align(lft_len, write, - func, blk_size); - - if (lft_len > prev_lft_len) { - sd_err(("%s: padding is unexpected! lft_len %d," - " prev_lft_len %d %s\n", - __FUNCTION__, lft_len, prev_lft_len, - write ? "Write" : "Read")); - } - - localbuf = (uint8 *)MALLOC(sd->osh, lft_len); - if (localbuf == NULL) { - sd_err(("%s: %s TXGLOM: localbuf malloc FAILED\n", - __FUNCTION__, (write) ? "TX" : "RX")); - need_txglom = FALSE; - goto txglomfail; - } - } - bcopy(buf, (localbuf + local_plen), pkt_len); - local_plen += pkt_len; - if (PKTNEXT(sd->osh, pnext)) { - continue; - } - - buf = localbuf; - pkt_len = local_plen; - } - -txglomfail: -#endif /* BCMSDIOH_TXGLOM */ + /* Align Patch + * read or small packet(ex:BDC header) skip 32 byte align + * otherwise, padding DHD_SDALIGN for performance + */ + if (write == 0 || pkt_len < 32) + pkt_len = (pkt_len + 3) & 0xFFFFFFFC; + else if (pkt_len % blk_size) + pkt_len += blk_size - (pkt_len % blk_size); - if ( -#ifdef BCMSDIOH_TXGLOM - !need_txglom && -#endif - TRUE) { - int align_pkt_len = 0; - align_pkt_len = sdioh_request_packet_align(pkt_len, write, - func, blk_size); - - pad = align_pkt_len - pkt_len; - if (pad > 0) { - if (func == SDIO_FUNC_2) { - sd_err(("%s: padding is unexpected! pkt_len %d," - " PKTLEN %d lft_len %d %s\n", - __FUNCTION__, pkt_len, PKTLEN(sd->osh, pnext), - lft_len, write ? "Write" : "Read")); - } - if (PKTTAILROOM(sd->osh, pkt) < pad) { - sd_info(("%s: insufficient tailroom %d, pad %d," - " lft_len %d pktlen %d, func %d %s\n", - __FUNCTION__, (int)PKTTAILROOM(sd->osh, pkt), - pad, lft_len, PKTLEN(sd->osh, pnext), func, - write ? "W" : "R")); - if (PKTPADTAILROOM(sd->osh, pkt, pad)) { - sd_err(("%s: padding error size %d.\n", - __FUNCTION__, pad)); - return SDIOH_API_RC_FAIL; - } - } - } +#ifdef CONFIG_MMC_MSM7X00A + if ((pkt_len % 64) == 32) { + sd_trace(("%s: Rounding up TX packet +=32\n", __FUNCTION__)); + pkt_len += 32; } +#endif /* CONFIG_MMC_MSM7X00A */ if ((write) && (!fifo)) err_ret = sdio_memcpy_toio( @@ -1275,6 +1120,11 @@ txglomfail: gInstance->func[func], buf, addr, pkt_len); + //AW judge sdio read write timeout, 1s + ret = sw_mci_check_r1_ready(gInstance->func[func]->card->host, 1000); + if (ret != 0) + printk(("%s data timeout.\n", __FUNCTION__)); + if (err_ret) sd_err(("%s: %s FAILED %p[%d], addr=0x%05x, pkt_len=%d, ERR=%d\n", __FUNCTION__, @@ -1292,10 +1142,6 @@ txglomfail: } sdio_release_host(gInstance->func[func]); } -#ifdef BCMSDIOH_TXGLOM - if (localbuf) - MFREE(sd->osh, localbuf, lft_len); -#endif /* BCMSDIOH_TXGLOM */ sd_trace(("%s: Exit\n", __FUNCTION__)); return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL); @@ -1315,51 +1161,89 @@ txglomfail: */ extern SDIOH_API_RC sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, uint func, - uint addr, uint reg_width, uint buflen_u, uint8 *buffer, void *pkt) + uint addr, uint reg_width, uint buflen_u, uint8 *buffer, void *pkt) { SDIOH_API_RC Status; - void *tmppkt; - void *orig_buf = NULL; - uint copylen = 0; + void *mypkt = NULL; sd_trace(("%s: Enter\n", __FUNCTION__)); DHD_PM_RESUME_WAIT(sdioh_request_buffer_wait); DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL); - + /* Case 1: we don't have a packet. */ if (pkt == NULL) { - /* Case 1: we don't have a packet. */ - orig_buf = buffer; - copylen = buflen_u; - } else if ((ulong)PKTDATA(sd->osh, pkt) & DMA_ALIGN_MASK) { - /* Case 2: We have a packet, but it is unaligned. - * in this case, we cannot have a chain. - */ - ASSERT(PKTNEXT(sd->osh, pkt) == NULL); + sd_data(("%s: Creating new %s Packet, len=%d\n", + __FUNCTION__, write ? "TX" : "RX", buflen_u)); +#ifdef CONFIG_DHD_USE_STATIC_BUF + if (!(mypkt = PKTGET_STATIC(sd->osh, buflen_u, write ? TRUE : FALSE))) +#else + if (!(mypkt = PKTGET(sd->osh, buflen_u, write ? TRUE : FALSE))) +#endif /* CONFIG_DHD_USE_STATIC_BUF */ + { + sd_err(("%s: PKTGET failed: len %d\n", + __FUNCTION__, buflen_u)); + return SDIOH_API_RC_FAIL; + } - orig_buf = PKTDATA(sd->osh, pkt); - copylen = PKTLEN(sd->osh, pkt); - } + /* For a write, copy the buffer data into the packet. */ + if (write) { + bcopy(buffer, PKTDATA(sd->osh, mypkt), buflen_u); + } + + Status = sdioh_request_packet(sd, fix_inc, write, func, addr, mypkt); + + /* For a read, copy the packet data back to the buffer. */ + if (!write) { + bcopy(PKTDATA(sd->osh, mypkt), buffer, buflen_u); + } +#ifdef CONFIG_DHD_USE_STATIC_BUF + PKTFREE_STATIC(sd->osh, mypkt, write ? TRUE : FALSE); +#else + PKTFREE(sd->osh, mypkt, write ? TRUE : FALSE); +#endif /* CONFIG_DHD_USE_STATIC_BUF */ + } else if (((uint32)(PKTDATA(sd->osh, pkt)) & DMA_ALIGN_MASK) != 0) { + /* Case 2: We have a packet, but it is unaligned. */ + + /* In this case, we cannot have a chain. */ + ASSERT(PKTNEXT(sd->osh, pkt) == NULL); - tmppkt = pkt; - if (copylen) { - tmppkt = PKTGET_STATIC(sd->osh, copylen, write ? TRUE : FALSE); - if (tmppkt == NULL) { - sd_err(("%s: PKTGET failed: len %d\n", __FUNCTION__, copylen)); + sd_data(("%s: Creating aligned %s Packet, len=%d\n", + __FUNCTION__, write ? "TX" : "RX", PKTLEN(sd->osh, pkt))); +#ifdef CONFIG_DHD_USE_STATIC_BUF + if (!(mypkt = PKTGET_STATIC(sd->osh, PKTLEN(sd->osh, pkt), write ? TRUE : FALSE))) +#else + if (!(mypkt = PKTGET(sd->osh, PKTLEN(sd->osh, pkt), write ? TRUE : FALSE))) +#endif /* CONFIG_DHD_USE_STATIC_BUF */ + { + sd_err(("%s: PKTGET failed: len %d\n", + __FUNCTION__, PKTLEN(sd->osh, pkt))); return SDIOH_API_RC_FAIL; } + /* For a write, copy the buffer data into the packet. */ - if (write) - bcopy(orig_buf, PKTDATA(sd->osh, tmppkt), copylen); - } + if (write) { + bcopy(PKTDATA(sd->osh, pkt), + PKTDATA(sd->osh, mypkt), + PKTLEN(sd->osh, pkt)); + } - Status = sdioh_request_packet(sd, fix_inc, write, func, addr, tmppkt); + Status = sdioh_request_packet(sd, fix_inc, write, func, addr, mypkt); - if (copylen) { /* For a read, copy the packet data back to the buffer. */ - if (!write) - bcopy(PKTDATA(sd->osh, tmppkt), orig_buf, PKTLEN(sd->osh, tmppkt)); - PKTFREE_STATIC(sd->osh, tmppkt, write ? TRUE : FALSE); + if (!write) { + bcopy(PKTDATA(sd->osh, mypkt), + PKTDATA(sd->osh, pkt), + PKTLEN(sd->osh, mypkt)); + } +#ifdef CONFIG_DHD_USE_STATIC_BUF + PKTFREE_STATIC(sd->osh, mypkt, write ? TRUE : FALSE); +#else + PKTFREE(sd->osh, mypkt, write ? TRUE : FALSE); +#endif /* CONFIG_DHD_USE_STATIC_BUF */ + } else { /* case 3: We have a packet and it is aligned. */ + sd_data(("%s: Aligned %s Packet, direct DMA\n", + __FUNCTION__, write ? "Tx" : "Rx")); + Status = sdioh_request_packet(sd, fix_inc, write, func, addr, pkt); } return (Status); @@ -1506,10 +1390,7 @@ sdioh_start(sdioh_info_t *si, int stage) int ret; sdioh_info_t *sd = gInstance->sd; - if (!sd) { - sd_err(("%s Failed, sd is NULL\n", __FUNCTION__)); - return (0); - } + if (!sd) return (0); /* Need to do this stages as we can't enable the interrupt till downloading of the firmware is complete, other wise polling diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c linux-sunxi-new/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c --- linux-sunxi/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c 2014-01-27 01:30:30.100433249 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c 2014-02-15 00:43:44.791014047 +0100 @@ -1,7 +1,7 @@ /* * BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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 404103 2013-05-23 20:07:27Z $ + * $Id: bcmsdh_sdmmc_linux.c 363783 2012-10-19 06:27:14Z $ */ #include @@ -110,9 +110,6 @@ static int bcmsdh_sdmmc_probe(struct sdi int ret = 0; static struct sdio_func sdio_func_0; - if (!gInstance) - return -EINVAL; - if (func) { sd_trace(("bcmsdh_sdmmc: %s Enter\n", __FUNCTION__)); sd_trace(("sdio_bcmsdh: func->class=%x\n", func->class)); @@ -139,8 +136,6 @@ static int bcmsdh_sdmmc_probe(struct sdi #endif sd_trace(("F2 found, calling bcmsdh_probe...\n")); ret = bcmsdh_probe(&func->dev); - if (ret < 0) - gInstance->func[2] = NULL; } } else { ret = -ENODEV; @@ -199,9 +194,11 @@ static int bcmsdh_sdmmc_suspend(struct d if (func->num != 2) return 0; - sd_trace(("%s Enter\n", __FUNCTION__)); + sd_trace_hw4(("%s Enter\n", __FUNCTION__)); + if (dhd_os_check_wakelock(bcmsdh_get_drvdata())) return -EBUSY; + sdio_flags = sdio_get_host_pm_caps(func); if (!(sdio_flags & MMC_PM_KEEP_POWER)) { @@ -215,9 +212,10 @@ static int bcmsdh_sdmmc_suspend(struct d sd_err(("%s: error while trying to keep power\n", __FUNCTION__)); return ret; } + #if defined(OOB_INTR_ONLY) bcmsdh_oob_intr_set(0); -#endif +#endif /* defined(OOB_INTR_ONLY) */ dhd_mmc_suspend = TRUE; smp_mb(); @@ -228,14 +226,14 @@ static int bcmsdh_sdmmc_resume(struct de { #if defined(OOB_INTR_ONLY) struct sdio_func *func = dev_to_sdio_func(pdev); -#endif - sd_trace(("%s Enter\n", __FUNCTION__)); +#endif /* defined(OOB_INTR_ONLY) */ + sd_trace_hw4(("%s Enter\n", __FUNCTION__)); + dhd_mmc_suspend = FALSE; #if defined(OOB_INTR_ONLY) if ((func->num == 2) && dhd_os_check_if_up(bcmsdh_get_drvdata())) bcmsdh_oob_intr_set(1); -#endif - +#endif /* (OOB_INTR_ONLY) */ smp_mb(); return 0; } @@ -286,11 +284,13 @@ static struct sdio_driver bcmsdh_sdmmc_d .remove = bcmsdh_sdmmc_remove, .name = "bcmsdh_sdmmc", .id_table = bcmsdh_sdmmc_ids, +#if !defined(CONFIG_ARCH_RHEA) || !defined(CONFIG_ARCH_CAPRI) #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM) .drv = { .pm = &bcmsdh_sdmmc_pm_ops, }, #endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM) */ +#endif /* !defined(CONFIG_ARCH_RHEA) || !defined(CONFIG_ARCH_CAPRI) */ }; struct sdos_info { @@ -401,9 +401,9 @@ int sdio_function_init(void) return -ENOMEM; error = sdio_register_driver(&bcmsdh_sdmmc_driver); - if (error) { + if (error && gInstance) { kfree(gInstance); - gInstance = NULL; + gInstance = 0; } return error; @@ -420,8 +420,6 @@ void sdio_function_cleanup(void) sdio_unregister_driver(&bcmsdh_sdmmc_driver); - if (gInstance) { + if (gInstance) kfree(gInstance); - gInstance = NULL; - } } diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/bcmutils.c linux-sunxi-new/drivers/net/wireless/bcmdhd/bcmutils.c --- linux-sunxi/drivers/net/wireless/bcmdhd/bcmutils.c 2014-01-27 01:30:30.101433269 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/bcmutils.c 2014-02-15 00:43:44.792014069 +0100 @@ -1,7 +1,7 @@ /* * Driver O/S-independent utility routines * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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: bcmutils.c 412804 2013-07-16 16:26:39Z $ + * $Id: bcmutils.c 312855 2012-02-04 02:01:18Z $ */ #include @@ -192,7 +192,7 @@ pktsegcnt_war(osl_t *osh, void *p) } uint8 * BCMFASTPATH -pktdataoffset(osl_t *osh, void *p, uint offset) +pktoffset(osl_t *osh, void *p, uint offset) { uint total = pkttotlen(osh, p); uint pkt_off = 0, len = 0; @@ -211,25 +211,6 @@ pktdataoffset(osl_t *osh, void *p, uint return (uint8*) (pdata+pkt_off); } - -/* given a offset in pdata, find the pkt seg hdr */ -void * -pktoffset(osl_t *osh, void *p, uint offset) -{ - uint total = pkttotlen(osh, p); - uint len = 0; - - if (offset > total) - return NULL; - - for (; p; p = PKTNEXT(osh, p)) { - len += PKTLEN(osh, p); - if (len > offset) - break; - } - return p; -} - /* * osl multiple-precedence packet queue * hi_prec is always >= the number of the highest non-empty precedence @@ -343,44 +324,6 @@ pktq_pdeq_prev(struct pktq *pq, int prec } void * BCMFASTPATH -pktq_pdeq_with_fn(struct pktq *pq, int prec, ifpkt_cb_t fn, int arg) -{ - struct pktq_prec *q; - void *p, *prev = NULL; - - ASSERT(prec >= 0 && prec < pq->num_prec); - - q = &pq->q[prec]; - p = q->head; - - while (p) { - if (fn == NULL || (*fn)(p, arg)) { - break; - } else { - prev = p; - p = PKTLINK(p); - } - } - if (p == NULL) - return NULL; - - if (prev == NULL) { - if ((q->head = PKTLINK(p)) == NULL) - q->tail = NULL; - } else { - PKTSETLINK(prev, PKTLINK(p)); - } - - q->len--; - - pq->len--; - - PKTSETLINK(p, NULL); - - return p; -} - -void * BCMFASTPATH pktq_pdeq_tail(struct pktq *pq, int prec) { struct pktq_prec *q; @@ -711,7 +654,6 @@ pktq_mdeq(struct pktq *pq, uint prec_bmp #endif /* BCMDRIVER */ -#if !defined(BCMROMOFFLOAD_EXCLUDE_BCMUTILS_FUNCS) const unsigned char bcm_ctype[] = { _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 0-7 */ @@ -1025,7 +967,6 @@ bcm_ether_atoe(const char *p, struct eth return (i == 6); } -#endif /* !BCMROMOFFLOAD_EXCLUDE_BCMUTILS_FUNCS */ #if defined(CONFIG_USBRNDIS_RETAIL) || defined(NDIS_MINIPORT_DRIVER) @@ -1137,7 +1078,7 @@ pktsetprio(void *pkt, bool update_vtag) eh = (struct ether_header *) pktdata; - if (eh->ether_type == hton16(ETHER_TYPE_8021Q)) { + if (ntoh16(eh->ether_type) == ETHER_TYPE_8021Q) { uint16 vlan_tag; int vlan_prio, dscp_prio = 0; @@ -1146,7 +1087,7 @@ pktsetprio(void *pkt, bool update_vtag) vlan_tag = ntoh16(evh->vlan_tag); vlan_prio = (int) (vlan_tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK; - if (evh->ether_type == hton16(ETHER_TYPE_IP)) { + if (ntoh16(evh->ether_type) == ETHER_TYPE_IP) { uint8 *ip_body = pktdata + sizeof(struct ethervlan_header); uint8 tos_tc = IP_TOS46(ip_body); dscp_prio = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT); @@ -1173,32 +1114,10 @@ pktsetprio(void *pkt, bool update_vtag) evh->vlan_tag = hton16(vlan_tag); rc |= PKTPRIO_UPD; } - } else if (eh->ether_type == hton16(ETHER_TYPE_IP)) { + } else if (ntoh16(eh->ether_type) == ETHER_TYPE_IP) { uint8 *ip_body = pktdata + sizeof(struct ether_header); uint8 tos_tc = IP_TOS46(ip_body); - uint8 dscp = tos_tc >> IPV4_TOS_DSCP_SHIFT; - switch (dscp) { - case DSCP_EF: - priority = PRIO_8021D_VO; - break; - case DSCP_AF31: - case DSCP_AF32: - case DSCP_AF33: - priority = PRIO_8021D_CL; - break; - case DSCP_AF21: - case DSCP_AF22: - case DSCP_AF23: - case DSCP_AF11: - case DSCP_AF12: - case DSCP_AF13: - priority = PRIO_8021D_EE; - break; - default: - priority = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT); - break; - } - + priority = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT); rc |= PKTPRIO_DSCP; } @@ -1304,7 +1223,6 @@ bcm_iovar_lencheck(const bcm_iovar_t *vi #endif /* BCMDRIVER */ -#if !defined(BCMROMOFFLOAD_EXCLUDE_BCMUTILS_FUNCS) /******************************************************************************* * crc8 * @@ -1661,36 +1579,10 @@ bcm_parse_ordered_tlvs(void *buf, int bu } return NULL; } -#endif /* !BCMROMOFFLOAD_EXCLUDE_BCMUTILS_FUNCS */ #if defined(WLMSG_PRHDRS) || defined(WLMSG_PRPKT) || defined(WLMSG_ASSOC) || \ defined(DHD_DEBUG) int -bcm_format_field(const bcm_bit_desc_ex_t *bd, uint32 flags, char* buf, int len) -{ - int i, slen = 0; - uint32 bit, mask; - const char *name; - mask = bd->mask; - if (len < 2 || !buf) - return 0; - - buf[0] = '\0'; - - for (i = 0; (name = bd->bitfield[i].name) != NULL; i++) { - bit = bd->bitfield[i].bit; - if ((flags & mask) == bit) { - if (len > (int)strlen(name)) { - slen = strlen(name); - strncpy(buf, name, slen+1); - } - break; - } - } - return slen; -} - -int bcm_format_flags(const bcm_bit_desc_t *bd, uint32 flags, char* buf, int len) { int i; @@ -1807,6 +1699,9 @@ static const char *crypto_algo_names[] = "UNDEF", "UNDEF", "UNDEF", +#ifdef BCMWAPI_WPI + "WAPI", +#endif /* BCMWAPI_WPI */ "UNDEF" }; @@ -2109,39 +2004,6 @@ bcm_print_bytes(const char *name, const } printf("\n"); } - -/* Look for vendor-specific IE with specified OUI and optional type */ -bcm_tlv_t * -find_vendor_ie(void *tlvs, int tlvs_len, const char *voui, uint8 *type, int type_len) -{ - bcm_tlv_t *ie; - uint8 ie_len; - - ie = (bcm_tlv_t*)tlvs; - - /* make sure we are looking at a valid IE */ - if (ie == NULL || - !bcm_valid_tlv(ie, tlvs_len)) - return NULL; - - /* Walk through the IEs looking for an OUI match */ - do { - ie_len = ie->len; - if ((ie->id == DOT11_MNG_PROPR_ID) && - (ie_len >= (DOT11_OUI_LEN + type_len)) && - !bcmp(ie->data, voui, DOT11_OUI_LEN)) - { - /* compare optional type */ - if (type_len == 0 || - !bcmp(&ie->data[DOT11_OUI_LEN], type, type_len)) { - return (ie); /* a match */ - } - } - } while ((ie = bcm_next_tlv(ie, &tlvs_len)) != NULL); - - return NULL; -} - #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) @@ -2229,93 +2091,3 @@ process_nvram_vars(char *varbuf, unsigne return buf_len; } - -/* calculate a * b + c */ -void -bcm_uint64_multiple_add(uint32* r_high, uint32* r_low, uint32 a, uint32 b, uint32 c) -{ -#define FORMALIZE(var) {cc += (var & 0x80000000) ? 1 : 0; var &= 0x7fffffff;} - uint32 r1, r0; - uint32 a1, a0, b1, b0, t, cc = 0; - - a1 = a >> 16; - a0 = a & 0xffff; - b1 = b >> 16; - b0 = b & 0xffff; - - r0 = a0 * b0; - FORMALIZE(r0); - - t = (a1 * b0) << 16; - FORMALIZE(t); - - r0 += t; - FORMALIZE(r0); - - t = (a0 * b1) << 16; - FORMALIZE(t); - - r0 += t; - FORMALIZE(r0); - - FORMALIZE(c); - - r0 += c; - FORMALIZE(r0); - - r0 |= (cc % 2) ? 0x80000000 : 0; - r1 = a1 * b1 + ((a1 * b0) >> 16) + ((b1 * a0) >> 16) + (cc / 2); - - *r_high = r1; - *r_low = r0; -} - -/* calculate a / b */ -void -bcm_uint64_divide(uint32* r, uint32 a_high, uint32 a_low, uint32 b) -{ - uint32 a1 = a_high, a0 = a_low, r0 = 0; - - if (b < 2) - return; - - while (a1 != 0) { - r0 += (0xffffffff / b) * a1; - bcm_uint64_multiple_add(&a1, &a0, ((0xffffffff % b) + 1) % b, a1, a0); - } - - r0 += a0 / b; - *r = r0; -} - -#ifndef setbit /* As in the header file */ -#ifdef BCMUTILS_BIT_MACROS_USE_FUNCS -/* Set bit in byte array. */ -void -setbit(void *array, uint bit) -{ - ((uint8 *)array)[bit / NBBY] |= 1 << (bit % NBBY); -} - -/* Clear bit in byte array. */ -void -clrbit(void *array, uint bit) -{ - ((uint8 *)array)[bit / NBBY] &= ~(1 << (bit % NBBY)); -} - -/* Test if bit is set in byte array. */ -bool -isset(const void *array, uint bit) -{ - return (((const uint8 *)array)[bit / NBBY] & (1 << (bit % NBBY))); -} - -/* Test if bit is clear in byte array. */ -bool -isclr(const void *array, uint bit) -{ - return ((((const uint8 *)array)[bit / NBBY] & (1 << (bit % NBBY))) == 0); -} -#endif /* BCMUTILS_BIT_MACROS_USE_FUNCS */ -#endif /* setbit */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/bcmwifi_channels.c linux-sunxi-new/drivers/net/wireless/bcmdhd/bcmwifi_channels.c --- linux-sunxi/drivers/net/wireless/bcmdhd/bcmwifi_channels.c 2014-01-27 01:30:30.108433411 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/bcmwifi_channels.c 2014-02-15 00:43:44.795014136 +0100 @@ -3,7 +3,7 @@ * Contents are wifi-specific, used by any kernel or app-level * software that might want wifi things as it grows. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -27,10 +27,10 @@ #include #include -#include #ifdef BCMDRIVER #include +#include #define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base)) #define tolower(c) (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c)) #else @@ -560,7 +560,7 @@ wf_chspec_aton(const char *a) return 0; /* if we are looking at a 'g', then the first number was a band */ - c = tolower((int)a[0]); + c = tolower(a[0]); if (c == 'g') { a ++; /* consume the char */ @@ -576,7 +576,7 @@ wf_chspec_aton(const char *a) if (!read_uint(&a, &ctl_ch)) return 0; - c = tolower((int)a[0]); + c = tolower(a[0]); } else { /* first number is channel, use default for band */ @@ -626,7 +626,7 @@ wf_chspec_aton(const char *a) * or '+80' if bw = 80, to make '80+80' bw. */ - c = tolower((int)a[0]); + c = tolower(a[0]); /* if we have a 2g/40 channel, we should have a l/u spec now */ if (chspec_band == WL_CHANSPEC_BAND_2G && bw == 40) { @@ -911,12 +911,6 @@ wf_chspec_valid(chanspec_t chanspec) } if (i == num_ch) { - /* check for channel 165 which is not the side band - * of 40MHz 5G channel - */ - if (chspec_ch == 165) - i = 0; - /* check for legacy JP channels on failure */ if (chspec_ch == 34 || chspec_ch == 38 || chspec_ch == 42 || chspec_ch == 46) @@ -1054,7 +1048,6 @@ wf_channel2chspec(uint ctl_ch, uint bw) return chspec; } - #endif /* D11AC_IOTYPES */ /* @@ -1184,106 +1177,3 @@ wf_channel2mhz(uint ch, uint start_facto return freq; } - -/* These chan_info[] & lookup routines replicate those from wlc_phy.c because of BMAC split */ -static const struct chan_info { - uint16 chan; /* channel number */ - uint16 freq; /* in MHz */ -} chan_info[] = { - /* 11b/11g */ -/* 0 */ {1, 2412}, -/* 1 */ {2, 2417}, -/* 2 */ {3, 2422}, -/* 3 */ {4, 2427}, -/* 4 */ {5, 2432}, -/* 5 */ {6, 2437}, -/* 6 */ {7, 2442}, -/* 7 */ {8, 2447}, -/* 8 */ {9, 2452}, -/* 9 */ {10, 2457}, -/* 10 */ {11, 2462}, -/* 11 */ {12, 2467}, -/* 12 */ {13, 2472}, -/* 13 */ {14, 2484}, - -#ifdef BAND5G -/* 11a japan high */ -/* 14 */ {34, 5170}, -/* 15 */ {38, 5190}, -/* 16 */ {42, 5210}, -/* 17 */ {46, 5230}, - -/* 11a usa low */ -/* 18 */ {36, 5180}, -/* 19 */ {40, 5200}, -/* 20 */ {44, 5220}, -/* 21 */ {48, 5240}, -/* 22 */ {52, 5260}, -/* 23 */ {56, 5280}, -/* 24 */ {60, 5300}, -/* 25 */ {64, 5320}, - -/* 11a Europe */ -/* 26 */ {100, 5500}, -/* 27 */ {104, 5520}, -/* 28 */ {108, 5540}, -/* 29 */ {112, 5560}, -/* 30 */ {116, 5580}, -/* 31 */ {120, 5600}, -/* 32 */ {124, 5620}, -/* 33 */ {128, 5640}, -/* 34 */ {132, 5660}, -/* 35 */ {136, 5680}, -/* 36 */ {140, 5700}, - -/* 11a usa high, ref5 only */ -/* 37 */ {149, 5745}, -/* 38 */ {153, 5765}, -/* 39 */ {157, 5785}, -/* 40 */ {161, 5805}, -/* 41 */ {165, 5825}, - -/* 11a japan */ -/* 42 */ {184, 4920}, -/* 43 */ {188, 4940}, -/* 44 */ {192, 4960}, -/* 45 */ {196, 4980}, -/* 46 */ {200, 5000}, -/* 47 */ {204, 5020}, -/* 48 */ {208, 5040}, -/* 49 */ {212, 5060}, -/* 50 */ {216, 5080} -#endif /* BAND5G */ -}; - -/* - * Converts channel frequency to channel number. - * Returns 0 if the frequency does not match any channel definition. - */ -uint -wf_freq2channel(uint freq) -{ - uint i; - - for (i = 0; i < ARRAYSIZE(chan_info); i++) { - if (chan_info[i].freq == freq) - return (chan_info[i].chan); - } - return (0); -} - -/* - * Converts channel number to channel frequency. - * Returns 0 if the channel is out of range. - * Also used by some code in wlc_iw.c - */ -uint -wf_channel2freq(uint channel) -{ - uint i; - - for (i = 0; i < ARRAYSIZE(chan_info); i++) - if (chan_info[i].chan == channel) - return (chan_info[i].freq); - return (0); -} diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/common/include/proto/802.3.h linux-sunxi-new/drivers/net/wireless/bcmdhd/common/include/proto/802.3.h --- linux-sunxi/drivers/net/wireless/bcmdhd/common/include/proto/802.3.h 2014-01-27 01:30:30.100433249 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/common/include/proto/802.3.h 2014-02-15 00:43:44.792014069 +0100 @@ -1,27 +1,15 @@ /* - * Copyright (C) 1999-2013, 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: + * Copyright (C) 2013, Broadcom Corporation + * All Rights Reserved. * - * 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. + * 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. * * Fundamental constants relating to 802.3 * - * $Id: 802.3.h 417942 2013-08-13 07:53:57Z $ + * $Id: 802.3.h 382882 2013-02-04 23:24:31Z $ */ #ifndef _802_3_h_ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/dhd_bta.c linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_bta.c --- linux-sunxi/drivers/net/wireless/bcmdhd/dhd_bta.c 2014-01-27 01:30:30.109433432 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_bta.c 2014-02-15 00:43:44.796014158 +0100 @@ -1,7 +1,7 @@ /* * BT-AMP support routines * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -21,9 +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: dhd_bta.c 379512 2013-01-17 22:49:08Z $ + * $Id: dhd_bta.c 303834 2011-12-20 06:17:39Z $ */ +#ifndef WLBTAMP #error "WLBTAMP is not defined" +#endif /* WLBTAMP */ #include #include @@ -311,9 +313,6 @@ dhd_bta_doevt(dhd_pub_t *dhdp, void *dat { amp_hci_event_t *evt = (amp_hci_event_t *)data_buf; - ASSERT(dhdp); - ASSERT(evt); - switch (evt->ecode) { case HCI_Command_Complete: { cmd_complete_parms_t *parms = (cmd_complete_parms_t *)evt->parms; diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/dhd_bta.h linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_bta.h --- linux-sunxi/drivers/net/wireless/bcmdhd/dhd_bta.h 2014-01-27 01:30:30.100433249 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_bta.h 2014-02-15 00:43:44.792014069 +0100 @@ -1,7 +1,7 @@ /* * BT-AMP support routines * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/dhd_bus.h linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_bus.h --- linux-sunxi/drivers/net/wireless/bcmdhd/dhd_bus.h 2014-01-27 01:30:30.101433269 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_bus.h 2014-02-15 00:43:44.792014069 +0100 @@ -4,7 +4,7 @@ * Provides type definitions and function prototypes used to link the * DHD OS, bus, and protocol modules. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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 335569 2012-05-29 12:04:43Z $ + * $Id: dhd_bus.h 347614 2012-07-27 10:24:51Z $ */ #ifndef _dhd_bus_h_ @@ -55,7 +55,7 @@ extern void dhd_bus_getidletime(dhd_pub_ 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); +extern int dhd_bus_txdata(struct dhd_bus *bus, void *txp, bool wlfc_locked); /* Send/receive a control message to/from the dongle. * Expects caller to enforce a single outstanding transaction. diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/dhd_cdc.c linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_cdc.c --- linux-sunxi/drivers/net/wireless/bcmdhd/dhd_cdc.c 2014-01-27 01:30:30.100433249 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_cdc.c 2014-02-15 00:43:44.791014047 +0100 @@ -1,7 +1,7 @@ /* * DHD Protocol Module for CDC and BDC. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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 416698 2013-08-06 07:53:34Z $ + * $Id: dhd_cdc.c 368762 2012-11-14 21:59:17Z $ * * 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 @@ -57,6 +57,19 @@ * round off at the end of buffer */ +#define BUS_RETRIES 1 /* # of retries before aborting a bus tx operation */ + +#ifdef PROP_TXSTATUS +typedef struct dhd_wlfc_commit_info { + uint8 needs_hdr; + uint8 ac_fifo_credit_spent; + ewlfc_packet_state_t pkt_type; + wlfc_mac_descriptor_t* mac_entry; + void* p; +} dhd_wlfc_commit_info_t; +#endif /* PROP_TXSTATUS */ + + typedef struct dhd_prot { uint16 reqid; uint8 pending; @@ -101,14 +114,12 @@ dhdcdc_cmplt(dhd_pub_t *dhd, uint32 id, DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - do { ret = dhd_bus_rxctl(dhd->bus, (uchar*)&prot->msg, cdc_len); if (ret < 0) break; } while (CDC_IOC_ID(ltoh32(prot->msg.flags)) != id); - return ret; } @@ -117,6 +128,7 @@ dhdcdc_query_ioctl(dhd_pub_t *dhd, int i { dhd_prot_t *prot = dhd->prot; cdc_ioctl_t *msg = &prot->msg; + void *info; int ret = 0, retries = 0; uint32 id, flags = 0; @@ -176,12 +188,15 @@ retry: goto done; } + /* Check info buffer */ + info = (void*)&msg[1]; + /* Copy info buffer */ if (buf) { if (ret < (int)len) len = ret; - memcpy(buf, (void*) prot->buf, len); + memcpy(buf, info, len); } /* Check the ERROR flag */ @@ -196,7 +211,6 @@ done: return ret; } - static int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len, uint8 action) { @@ -220,7 +234,6 @@ dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifi return -EIO; } - memset(msg, 0, sizeof(cdc_ioctl_t)); msg->cmd = htol32(cmd); @@ -272,11 +285,26 @@ dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx dhd_prot_t *prot = dhd->prot; int ret = -1; uint8 action; +#if defined(NDIS630) + bool acquired = FALSE; +#endif if ((dhd->busstate == DHD_BUS_DOWN) || dhd->hang_was_sent) { DHD_ERROR(("%s : bus is down. we have nothing to do\n", __FUNCTION__)); goto done; } +#if defined(NDIS630) + if (dhd_os_proto_block(dhd)) + { + acquired = TRUE; + } + else + { + /* attempt to acquire protocol mutex timed out. */ + ret = -1; + return ret; + } +#endif /* NDIS630 */ DHD_TRACE(("%s: Enter\n", __FUNCTION__)); @@ -327,7 +355,10 @@ dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx prot->pending = FALSE; done: - +#if defined(NDIS630) + if (acquired) + dhd_os_proto_unblock(dhd); +#endif return ret; } @@ -338,207 +369,2531 @@ dhd_prot_iovar_op(dhd_pub_t *dhdp, const return BCME_UNSUPPORTED; } +#ifdef PROP_TXSTATUS void -dhd_prot_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf) +dhd_wlfc_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf) { - bcm_bprintf(strbuf, "Protocol CDC: reqid %d\n", dhdp->prot->reqid); -#ifdef PROP_TXSTATUS - if (dhdp->wlfc_state) - dhd_wlfc_dump(dhdp, strbuf); + int i; + uint8* ea; + athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) + dhdp->wlfc_state; + wlfc_hanger_t* h; + wlfc_mac_descriptor_t* mac_table; + wlfc_mac_descriptor_t* interfaces; + char* iftypes[] = {"STA", "AP", "WDS", "p2pGO", "p2pCL"}; + + if (wlfc == NULL) { + bcm_bprintf(strbuf, "wlfc not initialized yet\n"); + return; + } + h = (wlfc_hanger_t*)wlfc->hanger; + if (h == NULL) { + bcm_bprintf(strbuf, "wlfc-hanger not initialized yet\n"); + } + + mac_table = wlfc->destination_entries.nodes; + interfaces = wlfc->destination_entries.interfaces; + bcm_bprintf(strbuf, "---- wlfc stats ----\n"); + if (h) { + bcm_bprintf(strbuf, "wlfc hanger (pushed,popped,f_push," + "f_pop,f_slot, pending) = (%d,%d,%d,%d,%d,%d)\n", + h->pushed, + h->popped, + h->failed_to_push, + h->failed_to_pop, + h->failed_slotfind, + (h->pushed - h->popped)); + } + + bcm_bprintf(strbuf, "wlfc fail(tlv,credit_rqst,mac_update,psmode_update), " + "(dq_full,sendq_full, rollback_fail) = (%d,%d,%d,%d), (%d,%d,%d)\n", + wlfc->stats.tlv_parse_failed, + wlfc->stats.credit_request_failed, + wlfc->stats.mac_update_failed, + wlfc->stats.psmode_update_failed, + wlfc->stats.delayq_full_error, + wlfc->stats.sendq_full_error, + wlfc->stats.rollback_failed); + + bcm_bprintf(strbuf, "SENDQ (len,credit,sent) " + "(AC0[%d,%d,%d],AC1[%d,%d,%d],AC2[%d,%d,%d],AC3[%d,%d,%d],BC_MC[%d,%d,%d])\n", + wlfc->SENDQ.q[0].len, wlfc->FIFO_credit[0], wlfc->stats.sendq_pkts[0], + wlfc->SENDQ.q[1].len, wlfc->FIFO_credit[1], wlfc->stats.sendq_pkts[1], + wlfc->SENDQ.q[2].len, wlfc->FIFO_credit[2], wlfc->stats.sendq_pkts[2], + wlfc->SENDQ.q[3].len, wlfc->FIFO_credit[3], wlfc->stats.sendq_pkts[3], + wlfc->SENDQ.q[4].len, wlfc->FIFO_credit[4], wlfc->stats.sendq_pkts[4]); + +#ifdef PROP_TXSTATUS_DEBUG + bcm_bprintf(strbuf, "SENDQ dropped: AC[0-3]:(%d,%d,%d,%d), (bcmc,atim):(%d,%d)\n", + wlfc->stats.dropped_qfull[0], wlfc->stats.dropped_qfull[1], + wlfc->stats.dropped_qfull[2], wlfc->stats.dropped_qfull[3], + wlfc->stats.dropped_qfull[4], wlfc->stats.dropped_qfull[5]); +#endif + + bcm_bprintf(strbuf, "\n"); + for (i = 0; i < WLFC_MAX_IFNUM; i++) { + if (interfaces[i].occupied) { + char* iftype_desc; + + if (interfaces[i].iftype > WLC_E_IF_ROLE_P2P_CLIENT) + iftype_desc = "hostif_flow_state[i] == OFF) + ? " OFF":" ON")); + + bcm_bprintf(strbuf, "INTERFACE[%d].DELAYQ(len,state,credit)" + "= (%d,%s,%d)\n", + i, + interfaces[i].psq.len, + ((interfaces[i].state == + WLFC_STATE_OPEN) ? " OPEN":"CLOSE"), + interfaces[i].requested_credit); + + bcm_bprintf(strbuf, "INTERFACE[%d].DELAYQ" + "(sup,ac0),(sup,ac1),(sup,ac2),(sup,ac3) = " + "(%d,%d),(%d,%d),(%d,%d),(%d,%d)\n", + i, + interfaces[i].psq.q[0].len, + interfaces[i].psq.q[1].len, + interfaces[i].psq.q[2].len, + interfaces[i].psq.q[3].len, + interfaces[i].psq.q[4].len, + interfaces[i].psq.q[5].len, + interfaces[i].psq.q[6].len, + interfaces[i].psq.q[7].len); + } + } + + bcm_bprintf(strbuf, "\n"); + for (i = 0; i < WLFC_MAC_DESC_TABLE_SIZE; i++) { + if (mac_table[i].occupied) { + ea = mac_table[i].ea; + bcm_bprintf(strbuf, "MAC_table[%d].ea = " + "[%02x:%02x:%02x:%02x:%02x:%02x], if:%d \n", i, + ea[0], ea[1], ea[2], ea[3], ea[4], ea[5], + mac_table[i].interface_id); + + bcm_bprintf(strbuf, "MAC_table[%d].DELAYQ(len,state,credit)" + "= (%d,%s,%d)\n", + i, + mac_table[i].psq.len, + ((mac_table[i].state == + WLFC_STATE_OPEN) ? " OPEN":"CLOSE"), + mac_table[i].requested_credit); +#ifdef PROP_TXSTATUS_DEBUG + bcm_bprintf(strbuf, "MAC_table[%d]: (opened, closed) = (%d, %d)\n", + i, mac_table[i].opened_ct, mac_table[i].closed_ct); #endif + bcm_bprintf(strbuf, "MAC_table[%d].DELAYQ" + "(sup,ac0),(sup,ac1),(sup,ac2),(sup,ac3) = " + "(%d,%d),(%d,%d),(%d,%d),(%d,%d)\n", + i, + mac_table[i].psq.q[0].len, + mac_table[i].psq.q[1].len, + mac_table[i].psq.q[2].len, + mac_table[i].psq.q[3].len, + mac_table[i].psq.q[4].len, + mac_table[i].psq.q[5].len, + mac_table[i].psq.q[6].len, + mac_table[i].psq.q[7].len); + } + } + +#ifdef PROP_TXSTATUS_DEBUG + { + int avg; + int moving_avg = 0; + int moving_samples; + + if (wlfc->stats.latency_sample_count) { + moving_samples = sizeof(wlfc->stats.deltas)/sizeof(uint32); + + for (i = 0; i < moving_samples; i++) + moving_avg += wlfc->stats.deltas[i]; + moving_avg /= moving_samples; + + avg = (100 * wlfc->stats.total_status_latency) / + wlfc->stats.latency_sample_count; + bcm_bprintf(strbuf, "txstatus latency (average, last, moving[%d]) = " + "(%d.%d, %03d, %03d)\n", + moving_samples, avg/100, (avg - (avg/100)*100), + wlfc->stats.latency_most_recent, + moving_avg); + } + } + + bcm_bprintf(strbuf, "wlfc- fifo[0-5] credit stats: sent = (%d,%d,%d,%d,%d,%d), " + "back = (%d,%d,%d,%d,%d,%d)\n", + wlfc->stats.fifo_credits_sent[0], + wlfc->stats.fifo_credits_sent[1], + wlfc->stats.fifo_credits_sent[2], + wlfc->stats.fifo_credits_sent[3], + wlfc->stats.fifo_credits_sent[4], + wlfc->stats.fifo_credits_sent[5], + + wlfc->stats.fifo_credits_back[0], + wlfc->stats.fifo_credits_back[1], + wlfc->stats.fifo_credits_back[2], + wlfc->stats.fifo_credits_back[3], + wlfc->stats.fifo_credits_back[4], + wlfc->stats.fifo_credits_back[5]); + { + uint32 fifo_cr_sent = 0; + uint32 fifo_cr_acked = 0; + uint32 request_cr_sent = 0; + uint32 request_cr_ack = 0; + uint32 bc_mc_cr_ack = 0; + + for (i = 0; i < sizeof(wlfc->stats.fifo_credits_sent)/sizeof(uint32); i++) { + fifo_cr_sent += wlfc->stats.fifo_credits_sent[i]; + } + + for (i = 0; i < sizeof(wlfc->stats.fifo_credits_back)/sizeof(uint32); i++) { + fifo_cr_acked += wlfc->stats.fifo_credits_back[i]; + } + + for (i = 0; i < WLFC_MAC_DESC_TABLE_SIZE; i++) { + if (wlfc->destination_entries.nodes[i].occupied) { + request_cr_sent += + wlfc->destination_entries.nodes[i].dstncredit_sent_packets; + } + } + for (i = 0; i < WLFC_MAX_IFNUM; i++) { + if (wlfc->destination_entries.interfaces[i].occupied) { + request_cr_sent += + wlfc->destination_entries.interfaces[i].dstncredit_sent_packets; + } + } + for (i = 0; i < WLFC_MAC_DESC_TABLE_SIZE; i++) { + if (wlfc->destination_entries.nodes[i].occupied) { + request_cr_ack += + wlfc->destination_entries.nodes[i].dstncredit_acks; + } + } + for (i = 0; i < WLFC_MAX_IFNUM; i++) { + if (wlfc->destination_entries.interfaces[i].occupied) { + request_cr_ack += + wlfc->destination_entries.interfaces[i].dstncredit_acks; + } + } + bcm_bprintf(strbuf, "wlfc- (sent, status) => pq(%d,%d), vq(%d,%d)," + "other:%d, bc_mc:%d, signal-only, (sent,freed): (%d,%d)", + fifo_cr_sent, fifo_cr_acked, + request_cr_sent, request_cr_ack, + wlfc->destination_entries.other.dstncredit_acks, + bc_mc_cr_ack, + wlfc->stats.signal_only_pkts_sent, wlfc->stats.signal_only_pkts_freed); + } +#endif /* PROP_TXSTATUS_DEBUG */ + bcm_bprintf(strbuf, "\n"); + bcm_bprintf(strbuf, "wlfc- pkt((in,2bus,txstats,hdrpull),(dropped,hdr_only,wlc_tossed)" + "(freed,free_err,rollback)) = " + "((%d,%d,%d,%d),(%d,%d,%d),(%d,%d,%d))\n", + wlfc->stats.pktin, + wlfc->stats.pkt2bus, + wlfc->stats.txstatus_in, + wlfc->stats.dhd_hdrpulls, + + wlfc->stats.pktdropped, + wlfc->stats.wlfc_header_only_pkt, + wlfc->stats.wlc_tossed_pkts, + + wlfc->stats.pkt_freed, + wlfc->stats.pkt_free_err, wlfc->stats.rollback); + + bcm_bprintf(strbuf, "wlfc- suppress((d11,wlc,err),enq(d11,wl,hq,mac?),retx(d11,wlc,hq)) = " + "((%d,%d,%d),(%d,%d,%d,%d),(%d,%d,%d))\n", + + wlfc->stats.d11_suppress, + wlfc->stats.wl_suppress, + wlfc->stats.bad_suppress, + + wlfc->stats.psq_d11sup_enq, + wlfc->stats.psq_wlsup_enq, + wlfc->stats.psq_hostq_enq, + wlfc->stats.mac_handle_notfound, + + wlfc->stats.psq_d11sup_retx, + wlfc->stats.psq_wlsup_retx, + wlfc->stats.psq_hostq_retx); + return; } -/* The FreeBSD PKTPUSH could change the packet buf pinter - so we need to make it changable +/* Create a place to store all packet pointers submitted to the firmware until + a status comes back, suppress or otherwise. + + hang-er: noun, a contrivance on which things are hung, as a hook. */ -#define PKTBUF pktbuf -void -dhd_prot_hdrpush(dhd_pub_t *dhd, int ifidx, void *PKTBUF) +static void* +dhd_wlfc_hanger_create(osl_t *osh, int max_items) { -#ifdef BDC - struct bdc_header *h; -#endif /* BDC */ - - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); + int i; + wlfc_hanger_t* hanger; -#ifdef BDC - /* Push BDC header used to convey priority for buses that don't */ + /* allow only up to a specific size for now */ + ASSERT(max_items == WLFC_HANGER_MAXITEMS); - PKTPUSH(dhd->osh, PKTBUF, BDC_HEADER_LEN); + if ((hanger = (wlfc_hanger_t*)MALLOC(osh, WLFC_HANGER_SIZE(max_items))) == NULL) + return NULL; - h = (struct bdc_header *)PKTDATA(dhd->osh, PKTBUF); + memset(hanger, 0, WLFC_HANGER_SIZE(max_items)); + hanger->max_items = max_items; - h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT); - if (PKTSUMNEEDED(PKTBUF)) - h->flags |= BDC_FLAG_SUM_NEEDED; + for (i = 0; i < hanger->max_items; i++) { + hanger->items[i].state = WLFC_HANGER_ITEM_STATE_FREE; + } + return hanger; +} +static int +dhd_wlfc_hanger_delete(osl_t *osh, void* hanger) +{ + wlfc_hanger_t* h = (wlfc_hanger_t*)hanger; - h->priority = (PKTPRIO(PKTBUF) & BDC_PRIORITY_MASK); - h->flags2 = 0; - h->dataOffset = 0; -#endif /* BDC */ - BDC_SET_IF_IDX(h, ifidx); + if (h) { + MFREE(osh, h, WLFC_HANGER_SIZE(h->max_items)); + return BCME_OK; + } + return BCME_BADARG; } -#undef PKTBUF /* Only defined in the above routine */ -int -dhd_prot_hdrpull(dhd_pub_t *dhd, int *ifidx, void *pktbuf, uchar *reorder_buf_info, - uint *reorder_info_len) +static uint16 +dhd_wlfc_hanger_get_free_slot(void* hanger) { -#ifdef BDC - struct bdc_header *h; -#endif - uint8 data_offset = 0; + uint32 i; + wlfc_hanger_t* h = (wlfc_hanger_t*)hanger; - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); + if (h) { + for (i = (h->slot_pos + 1); i != h->slot_pos;) { + if (h->items[i].state == WLFC_HANGER_ITEM_STATE_FREE) { + h->slot_pos = i; + return (uint16)i; + } + (i == h->max_items)? i = 0 : i++; + } + h->failed_slotfind++; + } + return WLFC_HANGER_MAXITEMS; +} -#ifdef BDC - if (reorder_info_len) - *reorder_info_len = 0; - /* Pop BDC header used to convey priority for buses that don't */ +static int +dhd_wlfc_hanger_get_genbit(void* hanger, void* pkt, uint32 slot_id, int* gen) +{ + int rc = BCME_OK; + wlfc_hanger_t* h = (wlfc_hanger_t*)hanger; - if (PKTLEN(dhd->osh, pktbuf) < BDC_HEADER_LEN) { - DHD_ERROR(("%s: rx data too short (%d < %d)\n", __FUNCTION__, - PKTLEN(dhd->osh, pktbuf), BDC_HEADER_LEN)); - return BCME_ERROR; + *gen = 0xff; + + /* this packet was not pushed at the time it went to the firmware */ + if (slot_id == WLFC_HANGER_MAXITEMS) + return BCME_NOTFOUND; + + if (h) { + if ((h->items[slot_id].state == WLFC_HANGER_ITEM_STATE_INUSE) || + (h->items[slot_id].state == WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED)) { + *gen = h->items[slot_id].gen; + } + else { + rc = BCME_NOTFOUND; + } } + else + rc = BCME_BADARG; + return rc; +} - h = (struct bdc_header *)PKTDATA(dhd->osh, pktbuf); +static int +dhd_wlfc_hanger_pushpkt(void* hanger, void* pkt, uint32 slot_id) +{ + int rc = BCME_OK; + wlfc_hanger_t* h = (wlfc_hanger_t*)hanger; - if (!ifidx) { - /* for tx packet, skip the analysis */ - data_offset = h->dataOffset; - PKTPULL(dhd->osh, pktbuf, BDC_HEADER_LEN); - goto exit; + if (h && (slot_id < WLFC_HANGER_MAXITEMS)) { + if (h->items[slot_id].state == WLFC_HANGER_ITEM_STATE_FREE) { + h->items[slot_id].state = WLFC_HANGER_ITEM_STATE_INUSE; + h->items[slot_id].pkt = pkt; + h->items[slot_id].identifier = slot_id; + h->pushed++; + } + else { + h->failed_to_push++; + rc = BCME_NOTFOUND; + } } + else + rc = BCME_BADARG; + return rc; +} - if ((*ifidx = BDC_GET_IF_IDX(h)) >= DHD_MAX_IFS) { - DHD_ERROR(("%s: rx data ifnum out of range (%d)\n", - __FUNCTION__, *ifidx)); - return BCME_ERROR; +static int +dhd_wlfc_hanger_poppkt(void* hanger, uint32 slot_id, void** pktout, int remove_from_hanger) +{ + int rc = BCME_OK; + wlfc_hanger_t* h = (wlfc_hanger_t*)hanger; + + /* this packet was not pushed at the time it went to the firmware */ + if (slot_id == WLFC_HANGER_MAXITEMS) + return BCME_NOTFOUND; + + if (h) { + if (h->items[slot_id].state != WLFC_HANGER_ITEM_STATE_FREE) { + *pktout = h->items[slot_id].pkt; + if (remove_from_hanger) { + h->items[slot_id].state = + WLFC_HANGER_ITEM_STATE_FREE; + h->items[slot_id].pkt = NULL; + h->items[slot_id].identifier = 0; + h->items[slot_id].gen = 0xff; + h->popped++; + } + } + else { + h->failed_to_pop++; + rc = BCME_NOTFOUND; + } } + else + rc = BCME_BADARG; + return rc; +} - if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) != BDC_PROTO_VER) { - DHD_ERROR(("%s: non-BDC packet received, flags = 0x%x\n", - dhd_ifname(dhd, *ifidx), h->flags)); - if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) == BDC_PROTO_VER_1) - h->dataOffset = 0; +static int +dhd_wlfc_hanger_mark_suppressed(void* hanger, uint32 slot_id, uint8 gen) +{ + int rc = BCME_OK; + wlfc_hanger_t* h = (wlfc_hanger_t*)hanger; + + /* this packet was not pushed at the time it went to the firmware */ + if (slot_id == WLFC_HANGER_MAXITEMS) + return BCME_NOTFOUND; + if (h) { + h->items[slot_id].gen = gen; + if (h->items[slot_id].state == WLFC_HANGER_ITEM_STATE_INUSE) { + h->items[slot_id].state = WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED; + } else - return BCME_ERROR; + rc = BCME_BADARG; } + else + rc = BCME_BADARG; - if (h->flags & BDC_FLAG_SUM_GOOD) { - DHD_INFO(("%s: BDC packet received with good rx-csum, flags 0x%x\n", - dhd_ifname(dhd, *ifidx), h->flags)); - PKTSETSUMGOOD(pktbuf, TRUE); + return rc; +} + +static int +_dhd_wlfc_pushheader(athost_wl_status_info_t* ctx, void* p, bool tim_signal, + uint8 tim_bmp, uint8 mac_handle, uint32 htodtag) +{ + uint32 wl_pktinfo = 0; + uint8* wlh; + uint8 dataOffset; + uint8 fillers; + uint8 tim_signal_len = 0; + + struct bdc_header *h; + + if (tim_signal) { + tim_signal_len = 1 + 1 + WLFC_CTL_VALUE_LEN_PENDING_TRAFFIC_BMP; } - PKTSETPRIO(pktbuf, (h->priority & BDC_PRIORITY_MASK)); - data_offset = h->dataOffset; - PKTPULL(dhd->osh, pktbuf, BDC_HEADER_LEN); -#endif /* BDC */ + /* +2 is for Type[1] and Len[1] in TLV, plus TIM signal */ + dataOffset = WLFC_CTL_VALUE_LEN_PKTTAG + 2 + tim_signal_len; + fillers = ROUNDUP(dataOffset, 4) - dataOffset; + dataOffset += fillers; -#ifdef PROP_TXSTATUS - dhd_os_wlfc_block(dhd); - if (dhd->wlfc_state && - ((athost_wl_status_info_t*)dhd->wlfc_state)->proptxstatus_mode - != WLFC_FCMODE_NONE && - (!DHD_PKTTAG_PKTDIR(PKTTAG(pktbuf)))) { - /* - - parse txstatus only for packets that came from the firmware - */ - dhd_wlfc_parse_header_info(dhd, pktbuf, (data_offset << 2), - reorder_buf_info, reorder_info_len); - ((athost_wl_status_info_t*)dhd->wlfc_state)->stats.dhd_hdrpulls++; + PKTPUSH(ctx->osh, p, dataOffset); + wlh = (uint8*) PKTDATA(ctx->osh, p); + + wl_pktinfo = htol32(htodtag); + wlh[0] = WLFC_CTL_TYPE_PKTTAG; + wlh[1] = WLFC_CTL_VALUE_LEN_PKTTAG; + memcpy(&wlh[2], &wl_pktinfo, sizeof(uint32)); + + if (tim_signal_len) { + wlh[dataOffset - fillers - tim_signal_len ] = + WLFC_CTL_TYPE_PENDING_TRAFFIC_BMP; + wlh[dataOffset - fillers - tim_signal_len + 1] = + WLFC_CTL_VALUE_LEN_PENDING_TRAFFIC_BMP; + wlh[dataOffset - fillers - tim_signal_len + 2] = mac_handle; + wlh[dataOffset - fillers - tim_signal_len + 3] = tim_bmp; } - dhd_os_wlfc_unblock(dhd); -#endif /* PROP_TXSTATUS */ + if (fillers) + memset(&wlh[dataOffset - fillers], WLFC_CTL_TYPE_FILLER, fillers); -exit: - PKTPULL(dhd->osh, pktbuf, (data_offset << 2)); - return 0; + PKTPUSH(ctx->osh, p, BDC_HEADER_LEN); + h = (struct bdc_header *)PKTDATA(ctx->osh, p); + h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT); + if (PKTSUMNEEDED(p)) + h->flags |= BDC_FLAG_SUM_NEEDED; + + + h->priority = (PKTPRIO(p) & BDC_PRIORITY_MASK); + h->flags2 = 0; + h->dataOffset = dataOffset >> 2; + BDC_SET_IF_IDX(h, DHD_PKTTAG_IF(PKTTAG(p))); + return BCME_OK; } -#if defined(PROP_TXSTATUS) -void -dhd_wlfc_trigger_pktcommit(dhd_pub_t *dhd) +static int +_dhd_wlfc_pullheader(athost_wl_status_info_t* ctx, void* pktbuf) { - dhd_os_wlfc_block(dhd); - if (dhd->wlfc_state && - (((athost_wl_status_info_t*)dhd->wlfc_state)->proptxstatus_mode - != WLFC_FCMODE_NONE)) { - dhd_wlfc_commit_packets(dhd->wlfc_state, (f_commitpkt_t)dhd_bus_txdata, - (void *)dhd->bus, NULL); + struct bdc_header *h; + + if (PKTLEN(ctx->osh, pktbuf) < BDC_HEADER_LEN) { + WLFC_DBGMESG(("%s: rx data too short (%d < %d)\n", __FUNCTION__, + PKTLEN(ctx->osh, pktbuf), BDC_HEADER_LEN)); + return BCME_ERROR; } - dhd_os_wlfc_unblock(dhd); + h = (struct bdc_header *)PKTDATA(ctx->osh, pktbuf); + + /* pull BDC header */ + PKTPULL(ctx->osh, pktbuf, BDC_HEADER_LEN); + + if (PKTLEN(ctx->osh, pktbuf) < (h->dataOffset << 2)) { + WLFC_DBGMESG(("%s: rx data too short (%d < %d)\n", __FUNCTION__, + PKTLEN(ctx->osh, pktbuf), (h->dataOffset << 2))); + return BCME_ERROR; + } + /* pull wl-header */ + PKTPULL(ctx->osh, pktbuf, (h->dataOffset << 2)); + return BCME_OK; } -#endif +static wlfc_mac_descriptor_t* +_dhd_wlfc_find_table_entry(athost_wl_status_info_t* ctx, void* p) +{ + int i; + wlfc_mac_descriptor_t* table = ctx->destination_entries.nodes; + uint8 ifid = DHD_PKTTAG_IF(PKTTAG(p)); + uint8* dstn = DHD_PKTTAG_DSTN(PKTTAG(p)); + + if (((ctx->destination_entries.interfaces[ifid].iftype == WLC_E_IF_ROLE_STA) || + ETHER_ISMULTI(dstn) || + (ctx->destination_entries.interfaces[ifid].iftype == WLC_E_IF_ROLE_P2P_CLIENT)) && + (ctx->destination_entries.interfaces[ifid].occupied)) { + return &ctx->destination_entries.interfaces[ifid]; + } + + for (i = 0; i < WLFC_MAC_DESC_TABLE_SIZE; i++) { + if (table[i].occupied) { + if (table[i].interface_id == ifid) { + if (!memcmp(table[i].ea, dstn, ETHER_ADDR_LEN)) + return &table[i]; + } + } + } + return &ctx->destination_entries.other; +} -int -dhd_prot_attach(dhd_pub_t *dhd) +static int +_dhd_wlfc_rollback_packet_toq(athost_wl_status_info_t* ctx, + void* p, ewlfc_packet_state_t pkt_type, uint32 hslot) { - dhd_prot_t *cdc; + /* + put the packet back to the head of queue - 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; + - a packet from send-q will need to go back to send-q and not delay-q + since that will change the order of packets. + - suppressed packet goes back to suppress sub-queue + - pull out the header, if new or delayed packet + + Note: hslot is used only when header removal is done. + */ + wlfc_mac_descriptor_t* entry; + void* pktout; + int rc = BCME_OK; + int prec; + + entry = _dhd_wlfc_find_table_entry(ctx, p); + prec = DHD_PKTTAG_FIFO(PKTTAG(p)); + if (entry != NULL) { + if (pkt_type == eWLFC_PKTTYPE_SUPPRESSED) { + /* wl-header is saved for suppressed packets */ + if (WLFC_PKTQ_PENQ_HEAD(&entry->psq, ((prec << 1) + 1), p) == NULL) { + WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); + rc = BCME_ERROR; + } } - memset(cdc, 0, sizeof(dhd_prot_t)); + else { + /* remove header first */ + rc = _dhd_wlfc_pullheader(ctx, p); + if (rc != BCME_OK) { + WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); + /* free the hanger slot */ + dhd_wlfc_hanger_poppkt(ctx->hanger, hslot, &pktout, 1); + PKTFREE(ctx->osh, p, TRUE); + rc = BCME_ERROR; + return rc; + } + + if (pkt_type == eWLFC_PKTTYPE_DELAYED) { + /* delay-q packets are going to delay-q */ + if (WLFC_PKTQ_PENQ_HEAD(&entry->psq, (prec << 1), p) == NULL) { + WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); + rc = BCME_ERROR; + } + } + else { + /* these are going to SENDQ */ + if (WLFC_PKTQ_PENQ_HEAD(&ctx->SENDQ, prec, p) == NULL) { + WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); + rc = BCME_ERROR; + } + } + /* free the hanger slot */ + dhd_wlfc_hanger_poppkt(ctx->hanger, hslot, &pktout, 1); - /* ensure that the msg buf directly follows the cdc msg struct */ - if ((uintptr)(&cdc->msg + 1) != (uintptr)cdc->buf) { - DHD_ERROR(("dhd_prot_t is not correctly defined\n")); - goto fail; + /* decrement sequence count */ + WLFC_DECR_SEQCOUNT(entry, prec); + } + /* + if this packet did not count against FIFO credit, it must have + taken a requested_credit from the firmware (for pspoll etc.) + */ + if (!DHD_PKTTAG_CREDITCHECK(PKTTAG(p))) { + entry->requested_credit++; + } } + else { + WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); + rc = BCME_ERROR; + } + if (rc != BCME_OK) + ctx->stats.rollback_failed++; + else + ctx->stats.rollback++; - dhd->prot = cdc; -#ifdef BDC - dhd->hdrlen += BDC_HEADER_LEN; -#endif - dhd->maxctl = WLC_IOCTL_MAXLEN + sizeof(cdc_ioctl_t) + ROUND_UP_MARGIN; - return 0; - -fail: -#ifndef CONFIG_DHD_USE_STATIC_BUF - if (cdc != NULL) - MFREE(dhd->osh, cdc, sizeof(dhd_prot_t)); -#endif /* CONFIG_DHD_USE_STATIC_BUF */ - return BCME_NOMEM; + return rc; } -/* ~NOTE~ What if another thread is waiting on the semaphore? Holding it? */ -void -dhd_prot_detach(dhd_pub_t *dhd) +static void +_dhd_wlfc_flow_control_check(athost_wl_status_info_t* ctx, struct pktq* pq, uint8 if_id) { -#ifdef PROP_TXSTATUS - dhd_wlfc_deinit(dhd); - if (dhd->plat_deinit) - dhd->plat_deinit((void *)dhd); -#endif -#ifndef CONFIG_DHD_USE_STATIC_BUF - MFREE(dhd->osh, dhd->prot, sizeof(dhd_prot_t)); -#endif /* CONFIG_DHD_USE_STATIC_BUF */ - dhd->prot = NULL; + if ((pq->len <= WLFC_FLOWCONTROL_LOWATER) && (ctx->hostif_flow_state[if_id] == ON)) { + /* start traffic */ + ctx->hostif_flow_state[if_id] = OFF; + /* + WLFC_DBGMESG(("qlen:%02d, if:%02d, ->OFF, start traffic %s()\n", + pq->len, if_id, __FUNCTION__)); + */ + WLFC_DBGMESG(("F")); + dhd_txflowcontrol(ctx->dhdp, if_id, OFF); + ctx->toggle_host_if = 0; + } + if ((pq->len >= WLFC_FLOWCONTROL_HIWATER) && (ctx->hostif_flow_state[if_id] == OFF)) { + /* stop traffic */ + ctx->hostif_flow_state[if_id] = ON; + /* + WLFC_DBGMESG(("qlen:%02d, if:%02d, ->ON, stop traffic %s()\n", + pq->len, if_id, __FUNCTION__)); + */ + WLFC_DBGMESG(("N")); + dhd_txflowcontrol(ctx->dhdp, if_id, ON); + ctx->host_ifidx = if_id; + ctx->toggle_host_if = 1; + } + return; } -void -dhd_prot_dstats(dhd_pub_t *dhd) +static int +_dhd_wlfc_send_signalonly_packet(athost_wl_status_info_t* ctx, wlfc_mac_descriptor_t* entry, + uint8 ta_bmp) { - /* No stats from dongle added yet, copy bus stats */ - dhd->dstats.tx_packets = dhd->tx_packets; - dhd->dstats.tx_errors = dhd->tx_errors; - dhd->dstats.rx_packets = dhd->rx_packets; - dhd->dstats.rx_errors = dhd->rx_errors; - dhd->dstats.rx_dropped = dhd->rx_dropped; - dhd->dstats.multicast = dhd->rx_multicast; - return; + int rc = BCME_OK; + void* p = NULL; + int dummylen = ((dhd_pub_t *)ctx->dhdp)->hdrlen+ 12; + + /* allocate a dummy packet */ + p = PKTGET(ctx->osh, dummylen, TRUE); + if (p) { + PKTPULL(ctx->osh, p, dummylen); + DHD_PKTTAG_SET_H2DTAG(PKTTAG(p), 0); + _dhd_wlfc_pushheader(ctx, p, TRUE, ta_bmp, entry->mac_handle, 0); + DHD_PKTTAG_SETSIGNALONLY(PKTTAG(p), 1); +#ifdef PROP_TXSTATUS_DEBUG + ctx->stats.signal_only_pkts_sent++; +#endif + rc = dhd_bus_txdata(((dhd_pub_t *)ctx->dhdp)->bus, p, FALSE); + if (rc != BCME_OK) { + PKTFREE(ctx->osh, p, TRUE); + } + } + else { + DHD_ERROR(("%s: couldn't allocate new %d-byte packet\n", + __FUNCTION__, dummylen)); + rc = BCME_NOMEM; + } + return rc; } -int -dhd_prot_init(dhd_pub_t *dhd) +/* Return TRUE if traffic availability changed */ +static bool +_dhd_wlfc_traffic_pending_check(athost_wl_status_info_t* ctx, wlfc_mac_descriptor_t* entry, + int prec) +{ + bool rc = FALSE; + + if (entry->state == WLFC_STATE_CLOSE) { + if ((pktq_plen(&entry->psq, (prec << 1)) == 0) && + (pktq_plen(&entry->psq, ((prec << 1) + 1)) == 0)) { + + if (entry->traffic_pending_bmp & NBITVAL(prec)) { + rc = TRUE; + entry->traffic_pending_bmp = + entry->traffic_pending_bmp & ~ NBITVAL(prec); + } + } + else { + if (!(entry->traffic_pending_bmp & NBITVAL(prec))) { + rc = TRUE; + entry->traffic_pending_bmp = + entry->traffic_pending_bmp | NBITVAL(prec); + } + } + } + if (rc) { + /* request a TIM update to firmware at the next piggyback opportunity */ + if (entry->traffic_lastreported_bmp != entry->traffic_pending_bmp) { + entry->send_tim_signal = 1; + _dhd_wlfc_send_signalonly_packet(ctx, entry, entry->traffic_pending_bmp); + entry->traffic_lastreported_bmp = entry->traffic_pending_bmp; + entry->send_tim_signal = 0; + } + else { + rc = FALSE; + } + } + return rc; +} + +static int +_dhd_wlfc_enque_suppressed(athost_wl_status_info_t* ctx, int prec, void* p) +{ + wlfc_mac_descriptor_t* entry; + + entry = _dhd_wlfc_find_table_entry(ctx, p); + if (entry == NULL) { + WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); + return BCME_NOTFOUND; + } + /* + - suppressed packets go to sub_queue[2*prec + 1] AND + - delayed packets go to sub_queue[2*prec + 0] to ensure + order of delivery. + */ + if (WLFC_PKTQ_PENQ(&entry->psq, ((prec << 1) + 1), p) == NULL) { + ctx->stats.delayq_full_error++; + /* WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); */ + WLFC_DBGMESG(("s")); + return BCME_ERROR; + } + /* A packet has been pushed, update traffic availability bitmap, if applicable */ + _dhd_wlfc_traffic_pending_check(ctx, entry, prec); + _dhd_wlfc_flow_control_check(ctx, &entry->psq, DHD_PKTTAG_IF(PKTTAG(p))); + return BCME_OK; +} + +static int +_dhd_wlfc_pretx_pktprocess(athost_wl_status_info_t* ctx, + wlfc_mac_descriptor_t* entry, void* p, int header_needed, uint32* slot) +{ + int rc = BCME_OK; + int hslot = WLFC_HANGER_MAXITEMS; + bool send_tim_update = FALSE; + uint32 htod = 0; + uint8 free_ctr; + + *slot = hslot; + + if (entry == NULL) { + entry = _dhd_wlfc_find_table_entry(ctx, p); + } + + if (entry == NULL) { + WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); + return BCME_ERROR; + } + if (entry->send_tim_signal) { + send_tim_update = TRUE; + entry->send_tim_signal = 0; + entry->traffic_lastreported_bmp = entry->traffic_pending_bmp; + } + if (header_needed) { + hslot = dhd_wlfc_hanger_get_free_slot(ctx->hanger); + free_ctr = WLFC_SEQCOUNT(entry, DHD_PKTTAG_FIFO(PKTTAG(p))); + DHD_PKTTAG_SET_H2DTAG(PKTTAG(p), htod); + WLFC_PKTFLAG_SET_GENERATION(htod, entry->generation); + entry->transit_count++; + } + else { + hslot = WLFC_PKTID_HSLOT_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p))); + free_ctr = WLFC_PKTID_FREERUNCTR_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p))); + } + WLFC_PKTID_HSLOT_SET(htod, hslot); + WLFC_PKTID_FREERUNCTR_SET(htod, free_ctr); + DHD_PKTTAG_SETPKTDIR(PKTTAG(p), 1); + WL_TXSTATUS_SET_FLAGS(htod, WLFC_PKTFLAG_PKTFROMHOST); + WL_TXSTATUS_SET_FIFO(htod, DHD_PKTTAG_FIFO(PKTTAG(p))); + + if (!DHD_PKTTAG_CREDITCHECK(PKTTAG(p))) { + /* + Indicate that this packet is being sent in response to an + explicit request from the firmware side. + */ + WLFC_PKTFLAG_SET_PKTREQUESTED(htod); + } + else { + WLFC_PKTFLAG_CLR_PKTREQUESTED(htod); + } + if (header_needed) { + rc = _dhd_wlfc_pushheader(ctx, p, send_tim_update, + entry->traffic_lastreported_bmp, entry->mac_handle, htod); + if (rc == BCME_OK) { + DHD_PKTTAG_SET_H2DTAG(PKTTAG(p), htod); + /* + a new header was created for this packet. + push to hanger slot and scrub q. Since bus + send succeeded, increment seq number as well. + */ + rc = dhd_wlfc_hanger_pushpkt(ctx->hanger, p, hslot); + if (rc == BCME_OK) { + /* increment free running sequence count */ + WLFC_INCR_SEQCOUNT(entry, DHD_PKTTAG_FIFO(PKTTAG(p))); +#ifdef PROP_TXSTATUS_DEBUG + ((wlfc_hanger_t*)(ctx->hanger))->items[hslot].push_time = + OSL_SYSUPTIME(); +#endif + } + else { + WLFC_DBGMESG(("%s() hanger_pushpkt() failed, rc: %d\n", + __FUNCTION__, rc)); + } + } + } + else { + int gen; + + /* remove old header */ + rc = _dhd_wlfc_pullheader(ctx, p); + if (rc == BCME_OK) { + hslot = WLFC_PKTID_HSLOT_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p))); + dhd_wlfc_hanger_get_genbit(ctx->hanger, p, hslot, &gen); + + WLFC_PKTFLAG_SET_GENERATION(htod, gen); + free_ctr = WLFC_PKTID_FREERUNCTR_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p))); + /* push new header */ + _dhd_wlfc_pushheader(ctx, p, send_tim_update, + entry->traffic_lastreported_bmp, entry->mac_handle, htod); + } + } + *slot = hslot; + return rc; +} + +static int +_dhd_wlfc_is_destination_closed(athost_wl_status_info_t* ctx, + wlfc_mac_descriptor_t* entry, int prec) +{ + if (ctx->destination_entries.interfaces[entry->interface_id].iftype == + WLC_E_IF_ROLE_P2P_GO) { + /* - destination interface is of type p2p GO. + For a p2pGO interface, if the destination is OPEN but the interface is + CLOSEd, do not send traffic. But if the dstn is CLOSEd while there is + destination-specific-credit left send packets. This is because the + firmware storing the destination-specific-requested packet in queue. + */ + if ((entry->state == WLFC_STATE_CLOSE) && (entry->requested_credit == 0) && + (entry->requested_packet == 0)) + return 1; + } + /* AP, p2p_go -> unicast desc entry, STA/p2p_cl -> interface desc. entry */ + if (((entry->state == WLFC_STATE_CLOSE) && (entry->requested_credit == 0) && + (entry->requested_packet == 0)) || + (!(entry->ac_bitmap & (1 << prec)))) + return 1; + + return 0; +} + +static void* +_dhd_wlfc_deque_delayedq(athost_wl_status_info_t* ctx, + int prec, uint8* ac_credit_spent, uint8* needs_hdr, wlfc_mac_descriptor_t** entry_out) +{ + wlfc_mac_descriptor_t* entry; + wlfc_mac_descriptor_t* table; + uint8 token_pos; + int total_entries; + void* p = NULL; + int pout; + int i; + + *entry_out = NULL; + token_pos = ctx->token_pos[prec]; + /* most cases a packet will count against FIFO credit */ + *ac_credit_spent = 1; + *needs_hdr = 1; + + /* search all entries, include nodes as well as interfaces */ + table = (wlfc_mac_descriptor_t*)&ctx->destination_entries; + total_entries = sizeof(ctx->destination_entries)/sizeof(wlfc_mac_descriptor_t); + + for (i = 0; i < total_entries; i++) { + entry = &table[(token_pos + i) % total_entries]; + if (entry->occupied) { + if (!_dhd_wlfc_is_destination_closed(ctx, entry, prec)) { + p = pktq_mdeq(&entry->psq, + /* higher precedence will be picked up first, + * i.e. suppressed packets before delayed ones + */ + NBITVAL((prec << 1) + 1), &pout); + *needs_hdr = 0; + + if (p == NULL) { + if (entry->suppressed == TRUE) { + if ((entry->suppr_transit_count <= + entry->suppress_count)) { + entry->suppressed = FALSE; + } else { + return NULL; + } + } + /* De-Q from delay Q */ + p = pktq_mdeq(&entry->psq, + NBITVAL((prec << 1)), + &pout); + *needs_hdr = 1; + } + + if (p != NULL) { + /* did the packet come from suppress sub-queue? */ + if (entry->requested_credit > 0) { + entry->requested_credit--; +#ifdef PROP_TXSTATUS_DEBUG + entry->dstncredit_sent_packets++; +#endif + /* + if the packet was pulled out while destination is in + closed state but had a non-zero packets requested, + then this should not count against the FIFO credit. + That is due to the fact that the firmware will + most likely hold onto this packet until a suitable + time later to push it to the appropriate AC FIFO. + */ + if (entry->state == WLFC_STATE_CLOSE) + *ac_credit_spent = 0; + } + else if (entry->requested_packet > 0) { + entry->requested_packet--; + DHD_PKTTAG_SETONETIMEPKTRQST(PKTTAG(p)); + if (entry->state == WLFC_STATE_CLOSE) + *ac_credit_spent = 0; + } + /* move token to ensure fair round-robin */ + ctx->token_pos[prec] = + (token_pos + i + 1) % total_entries; + *entry_out = entry; + _dhd_wlfc_flow_control_check(ctx, &entry->psq, + DHD_PKTTAG_IF(PKTTAG(p))); + /* + A packet has been picked up, update traffic + availability bitmap, if applicable + */ + _dhd_wlfc_traffic_pending_check(ctx, entry, prec); + return p; + } + } + } + } + return NULL; +} + +static void* +_dhd_wlfc_deque_sendq(athost_wl_status_info_t* ctx, int prec) +{ + wlfc_mac_descriptor_t* entry; + void* p; + + + p = pktq_pdeq(&ctx->SENDQ, prec); + if (p != NULL) { + if (ETHER_ISMULTI(DHD_PKTTAG_DSTN(PKTTAG(p)))) + /* bc/mc packets do not have a delay queue */ + return p; + + entry = _dhd_wlfc_find_table_entry(ctx, p); + + if (entry == NULL) { + WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); + return p; + } + + while ((p != NULL)) { + /* + - suppressed packets go to sub_queue[2*prec + 1] AND + - delayed packets go to sub_queue[2*prec + 0] to ensure + order of delivery. + */ + if (WLFC_PKTQ_PENQ(&entry->psq, (prec << 1), p) == NULL) { + WLFC_DBGMESG(("D")); + /* dhd_txcomplete(ctx->dhdp, p, FALSE); */ + PKTFREE(ctx->osh, p, TRUE); + ctx->stats.delayq_full_error++; + } + /* + A packet has been pushed, update traffic availability bitmap, + if applicable + */ + _dhd_wlfc_traffic_pending_check(ctx, entry, prec); + + p = pktq_pdeq(&ctx->SENDQ, prec); + if (p == NULL) + break; + + entry = _dhd_wlfc_find_table_entry(ctx, p); + + if ((entry == NULL) || (ETHER_ISMULTI(DHD_PKTTAG_DSTN(PKTTAG(p))))) { + return p; + } + } + } + return p; +} + +static int +_dhd_wlfc_mac_entry_update(athost_wl_status_info_t* ctx, wlfc_mac_descriptor_t* entry, + ewlfc_mac_entry_action_t action, uint8 ifid, uint8 iftype, uint8* ea) +{ + int rc = BCME_OK; + + if (action == eWLFC_MAC_ENTRY_ACTION_ADD) { + entry->occupied = 1; + entry->state = WLFC_STATE_OPEN; + entry->requested_credit = 0; + entry->interface_id = ifid; + entry->iftype = iftype; + entry->ac_bitmap = 0xff; /* update this when handling APSD */ + /* for an interface entry we may not care about the MAC address */ + if (ea != NULL) + memcpy(&entry->ea[0], ea, ETHER_ADDR_LEN); + pktq_init(&entry->psq, WLFC_PSQ_PREC_COUNT, WLFC_PSQ_LEN); + } + else if (action == eWLFC_MAC_ENTRY_ACTION_UPDATE) { + entry->occupied = 1; + entry->state = WLFC_STATE_OPEN; + entry->requested_credit = 0; + entry->interface_id = ifid; + entry->iftype = iftype; + entry->ac_bitmap = 0xff; /* update this when handling APSD */ + /* for an interface entry we may not care about the MAC address */ + if (ea != NULL) + memcpy(&entry->ea[0], ea, ETHER_ADDR_LEN); + } + else if (action == eWLFC_MAC_ENTRY_ACTION_DEL) { + entry->occupied = 0; + entry->state = WLFC_STATE_CLOSE; + entry->requested_credit = 0; + /* enable after packets are queued-deqeued properly. + pktq_flush(dhd->osh, &entry->psq, FALSE, NULL, 0); + */ + } + return rc; +} + +int +_dhd_wlfc_borrow_credit(athost_wl_status_info_t* ctx, uint8 available_credit_map, int borrower_ac) +{ + int lender_ac; + int rc = BCME_ERROR; + + if (ctx == NULL || available_credit_map == 0) { + WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); + return BCME_BADARG; + } + + /* Borrow from lowest priority available AC (including BC/MC credits) */ + for (lender_ac = 0; lender_ac <= AC_COUNT; lender_ac++) { + if ((available_credit_map && (1 << lender_ac)) && + (ctx->FIFO_credit[lender_ac] > 0)) { + ctx->credits_borrowed[borrower_ac][lender_ac]++; + ctx->FIFO_credit[lender_ac]--; + rc = BCME_OK; + break; + } + } + + return rc; +} + +int +dhd_wlfc_interface_entry_update(void* state, + ewlfc_mac_entry_action_t action, uint8 ifid, uint8 iftype, uint8* ea) +{ + athost_wl_status_info_t* ctx = (athost_wl_status_info_t*)state; + wlfc_mac_descriptor_t* entry; + + if (ifid >= WLFC_MAX_IFNUM) + return BCME_BADARG; + + entry = &ctx->destination_entries.interfaces[ifid]; + return _dhd_wlfc_mac_entry_update(ctx, entry, action, ifid, iftype, ea); +} + +int +dhd_wlfc_FIFOcreditmap_update(void* state, uint8* credits) +{ + athost_wl_status_info_t* ctx = (athost_wl_status_info_t*)state; + + /* update the AC FIFO credit map */ + ctx->FIFO_credit[0] = credits[0]; + ctx->FIFO_credit[1] = credits[1]; + ctx->FIFO_credit[2] = credits[2]; + ctx->FIFO_credit[3] = credits[3]; + /* credit for bc/mc packets */ + ctx->FIFO_credit[4] = credits[4]; + /* credit for ATIM FIFO is not used yet. */ + ctx->FIFO_credit[5] = 0; + return BCME_OK; +} + +int +dhd_wlfc_enque_sendq(void* state, int prec, void* p) +{ + athost_wl_status_info_t* ctx = (athost_wl_status_info_t*)state; + + if ((state == NULL) || + /* prec = AC_COUNT is used for bc/mc queue */ + (prec > AC_COUNT) || + (p == NULL)) { + WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); + return BCME_BADARG; + } + if (FALSE == dhd_prec_enq(ctx->dhdp, &ctx->SENDQ, p, prec)) { + ctx->stats.sendq_full_error++; + /* + WLFC_DBGMESG(("Error: %s():%d, qlen:%d\n", + __FUNCTION__, __LINE__, ctx->SENDQ.len)); + */ + WLFC_HOST_FIFO_DROPPEDCTR_INC(ctx, prec); + WLFC_DBGMESG(("Q")); + PKTFREE(ctx->osh, p, TRUE); + return BCME_ERROR; + } + ctx->stats.pktin++; + /* _dhd_wlfc_flow_control_check(ctx, &ctx->SENDQ, DHD_PKTTAG_IF(PKTTAG(p))); */ + return BCME_OK; +} + +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) +{ + uint32 hslot; + int rc; + + /* + if ac_fifo_credit_spent = 0 + + This packet will not count against the FIFO credit. + To ensure the txstatus corresponding to this packet + does not provide an implied credit (default behavior) + mark the packet accordingly. + + if ac_fifo_credit_spent = 1 + + 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); + + if (rc == BCME_OK) + rc = fcommit(commit_ctx, commit_info->p, TRUE); + else + ctx->stats.generic_error++; + + if (rc == BCME_OK) { + ctx->stats.pkt2bus++; + if (commit_info->ac_fifo_credit_spent) { + ctx->stats.sendq_pkts[ac]++; + WLFC_HOST_FIFO_CREDIT_INC_SENTCTRS(ctx, ac); + } + } else if (rc == BCME_NORESOURCE) + rc = BCME_ERROR; + else { + /* + 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); + 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]; + + /* 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; + + do { + commit_info.p = _dhd_wlfc_deque_sendq(ctx, ac); + if (commit_info.p == NULL) + break; + else if (ETHER_ISMULTI(DHD_PKTTAG_DSTN(PKTTAG(commit_info.p)))) { + ASSERT(ac == AC_COUNT); + + if (ctx->FIFO_credit[ac]) { + 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((" %s: bus error\n", + __FUNCTION__)); + return rc; + } + } + } + } + + } while (commit_info.p); + + 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; + + + /* 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; + } + } + } + + return BCME_OK; +} + +static uint8 +dhd_wlfc_find_mac_desc_id_from_mac(dhd_pub_t *dhdp, uint8* ea) +{ + wlfc_mac_descriptor_t* table = + ((athost_wl_status_info_t*)dhdp->wlfc_state)->destination_entries.nodes; + uint8 table_index; + + if (ea != NULL) { + for (table_index = 0; table_index < WLFC_MAC_DESC_TABLE_SIZE; table_index++) { + if ((memcmp(ea, &table[table_index].ea[0], ETHER_ADDR_LEN) == 0) && + table[table_index].occupied) + return table_index; + } + } + return WLFC_MAC_DESC_ID_INVALID; +} + +void +dhd_wlfc_txcomplete(dhd_pub_t *dhd, void *txp, bool success, bool wake_locked) +{ + athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) + dhd->wlfc_state; + void* p; + int fifo_id; + + if (!wake_locked) + dhd_os_wlfc_block(dhd); + + if (DHD_PKTTAG_SIGNALONLY(PKTTAG(txp))) { +#ifdef PROP_TXSTATUS_DEBUG + wlfc->stats.signal_only_pkts_freed++; +#endif + if (success) + /* is this a signal-only packet? */ + PKTFREE(wlfc->osh, txp, TRUE); + if (!wake_locked) + dhd_os_wlfc_unblock(dhd); + return; + } + if (!success) { + WLFC_DBGMESG(("At: %s():%d, bus_complete() failure for %p, htod_tag:0x%08x\n", + __FUNCTION__, __LINE__, txp, DHD_PKTTAG_H2DTAG(PKTTAG(txp)))); + dhd_wlfc_hanger_poppkt(wlfc->hanger, WLFC_PKTID_HSLOT_GET(DHD_PKTTAG_H2DTAG + (PKTTAG(txp))), &p, 1); + + /* indicate failure and free the packet */ + dhd_txcomplete(dhd, txp, FALSE); + + /* return the credit, if necessary */ + if (DHD_PKTTAG_CREDITCHECK(PKTTAG(txp))) { + int lender, credit_returned = 0; /* Note that borrower is fifo_id */ + + fifo_id = DHD_PKTTAG_FIFO(PKTTAG(txp)); + + /* Return credits to highest priority lender first */ + for (lender = AC_COUNT; lender >= 0; lender--) { + if (wlfc->credits_borrowed[fifo_id][lender] > 0) { + wlfc->FIFO_credit[lender]++; + wlfc->credits_borrowed[fifo_id][lender]--; + credit_returned = 1; + break; + } + } + + if (!credit_returned) { + wlfc->FIFO_credit[fifo_id]++; + } + } + + PKTFREE(wlfc->osh, txp, TRUE); + } + if (!wake_locked) + dhd_os_wlfc_unblock(dhd); + return; +} + +static int +dhd_wlfc_compressed_txstatus_update(dhd_pub_t *dhd, uint8* pkt_info, uint8 len) +{ + uint8 status_flag; + uint32 status; + int ret; + int remove_from_hanger = 1; + void* pktbuf; + uint8 fifo_id; + uint8 count = 0; + uint32 status_g; + uint32 hslot, hcnt; + wlfc_mac_descriptor_t* entry = NULL; + athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) + dhd->wlfc_state; + + memcpy(&status, pkt_info, sizeof(uint32)); + status_flag = WL_TXSTATUS_GET_FLAGS(status); + status_g = status & 0xff000000; + hslot = (status & 0x00ffff00) >> 8; + hcnt = status & 0xff; + len = pkt_info[4]; + + wlfc->stats.txstatus_in++; + + if (status_flag == WLFC_CTL_PKTFLAG_DISCARD) { + wlfc->stats.pkt_freed++; + } + + else if (status_flag == WLFC_CTL_PKTFLAG_D11SUPPRESS) { + wlfc->stats.d11_suppress++; + remove_from_hanger = 0; + } + + else if (status_flag == WLFC_CTL_PKTFLAG_WLSUPPRESS) { + wlfc->stats.wl_suppress++; + remove_from_hanger = 0; + } + + else if (status_flag == WLFC_CTL_PKTFLAG_TOSSED_BYWLC) { + wlfc->stats.wlc_tossed_pkts++; + } + while (count < len) { + status = (status_g << 24) | (hslot << 8) | (hcnt); + count++; + hslot++; + hcnt++; + + ret = dhd_wlfc_hanger_poppkt(wlfc->hanger, + WLFC_PKTID_HSLOT_GET(status), &pktbuf, remove_from_hanger); + if (ret != BCME_OK) { + /* do something */ + continue; + } + + entry = _dhd_wlfc_find_table_entry(wlfc, pktbuf); + + if (!remove_from_hanger) { + /* this packet was suppressed */ + if (!entry->suppressed || entry->generation != WLFC_PKTID_GEN(status)) { + entry->suppressed = TRUE; + entry->suppress_count = pktq_mlen(&entry->psq, + NBITVAL((WL_TXSTATUS_GET_FIFO(status) << 1) + 1)); + entry->suppr_transit_count = entry->transit_count; + } + entry->generation = WLFC_PKTID_GEN(status); + } + +#ifdef PROP_TXSTATUS_DEBUG + { + uint32 new_t = OSL_SYSUPTIME(); + uint32 old_t; + uint32 delta; + old_t = ((wlfc_hanger_t*)(wlfc->hanger))->items[ + WLFC_PKTID_HSLOT_GET(status)].push_time; + + + wlfc->stats.latency_sample_count++; + if (new_t > old_t) + delta = new_t - old_t; + else + delta = 0xffffffff + new_t - old_t; + wlfc->stats.total_status_latency += delta; + wlfc->stats.latency_most_recent = delta; + + wlfc->stats.deltas[wlfc->stats.idx_delta++] = delta; + if (wlfc->stats.idx_delta == sizeof(wlfc->stats.deltas)/sizeof(uint32)) + wlfc->stats.idx_delta = 0; + } +#endif /* PROP_TXSTATUS_DEBUG */ + + fifo_id = DHD_PKTTAG_FIFO(PKTTAG(pktbuf)); + + /* pick up the implicit credit from this packet */ + if (DHD_PKTTAG_CREDITCHECK(PKTTAG(pktbuf))) { + if (wlfc->proptxstatus_mode == WLFC_FCMODE_IMPLIED_CREDIT) { + + int lender, credit_returned = 0; /* Note that borrower is fifo_id */ + + /* Return credits to highest priority lender first */ + for (lender = AC_COUNT; lender >= 0; lender--) { + if (wlfc->credits_borrowed[fifo_id][lender] > 0) { + wlfc->FIFO_credit[lender]++; + wlfc->credits_borrowed[fifo_id][lender]--; + credit_returned = 1; + break; + } + } + + if (!credit_returned) { + wlfc->FIFO_credit[fifo_id]++; + } + } + } + else { + /* + if this packet did not count against FIFO credit, it must have + taken a requested_credit from the destination entry (for pspoll etc.) + */ + if (!entry) { + + entry = _dhd_wlfc_find_table_entry(wlfc, pktbuf); + } + if (!DHD_PKTTAG_ONETIMEPKTRQST(PKTTAG(pktbuf))) + entry->requested_credit++; +#ifdef PROP_TXSTATUS_DEBUG + entry->dstncredit_acks++; +#endif + } + if ((status_flag == WLFC_CTL_PKTFLAG_D11SUPPRESS) || + (status_flag == WLFC_CTL_PKTFLAG_WLSUPPRESS)) { + + ret = _dhd_wlfc_enque_suppressed(wlfc, fifo_id, pktbuf); + if (ret != BCME_OK) { + /* delay q is full, drop this packet */ + dhd_wlfc_hanger_poppkt(wlfc->hanger, WLFC_PKTID_HSLOT_GET(status), + &pktbuf, 1); + + /* indicate failure and free the packet */ + dhd_txcomplete(dhd, pktbuf, FALSE); + entry->transit_count--; + /* packet is transmitted Successfully by dongle + * after first suppress. + */ + if (entry->suppressed) { + entry->suppr_transit_count--; + } + PKTFREE(wlfc->osh, pktbuf, TRUE); + } else { + /* Mark suppressed to avoid a double free during wlfc cleanup */ + + dhd_wlfc_hanger_mark_suppressed(wlfc->hanger, + WLFC_PKTID_HSLOT_GET(status), WLFC_PKTID_GEN(status)); + entry->suppress_count++; + } + } + else { + dhd_txcomplete(dhd, pktbuf, TRUE); + entry->transit_count--; + + /* This packet is transmitted Successfully by dongle + * even after first suppress. + */ + if (entry->suppressed) { + entry->suppr_transit_count--; + } + /* free the packet */ + PKTFREE(wlfc->osh, pktbuf, TRUE); + } + } + return BCME_OK; +} + +/* Handle discard or suppress indication */ +static int +dhd_wlfc_txstatus_update(dhd_pub_t *dhd, uint8* pkt_info) +{ + uint8 status_flag; + uint32 status; + int ret; + int remove_from_hanger = 1; + void* pktbuf; + uint8 fifo_id; + wlfc_mac_descriptor_t* entry = NULL; + athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) + dhd->wlfc_state; + + memcpy(&status, pkt_info, sizeof(uint32)); + status_flag = WL_TXSTATUS_GET_FLAGS(status); + wlfc->stats.txstatus_in++; + + if (status_flag == WLFC_CTL_PKTFLAG_DISCARD) { + wlfc->stats.pkt_freed++; + } + + else if (status_flag == WLFC_CTL_PKTFLAG_D11SUPPRESS) { + wlfc->stats.d11_suppress++; + remove_from_hanger = 0; + } + + else if (status_flag == WLFC_CTL_PKTFLAG_WLSUPPRESS) { + wlfc->stats.wl_suppress++; + remove_from_hanger = 0; + } + + else if (status_flag == WLFC_CTL_PKTFLAG_TOSSED_BYWLC) { + wlfc->stats.wlc_tossed_pkts++; + } + + ret = dhd_wlfc_hanger_poppkt(wlfc->hanger, + WLFC_PKTID_HSLOT_GET(status), &pktbuf, remove_from_hanger); + if (ret != BCME_OK) { + /* do something */ + return ret; + } + + entry = _dhd_wlfc_find_table_entry(wlfc, pktbuf); + + if (!remove_from_hanger) { + /* this packet was suppressed */ + if (!entry->suppressed || entry->generation != WLFC_PKTID_GEN(status)) { + entry->suppressed = TRUE; + entry->suppress_count = pktq_mlen(&entry->psq, + NBITVAL((WL_TXSTATUS_GET_FIFO(status) << 1) + 1)); + entry->suppr_transit_count = entry->transit_count; + } + entry->generation = WLFC_PKTID_GEN(status); + } + +#ifdef PROP_TXSTATUS_DEBUG + { + uint32 new_t = OSL_SYSUPTIME(); + uint32 old_t; + uint32 delta; + old_t = ((wlfc_hanger_t*)(wlfc->hanger))->items[ + WLFC_PKTID_HSLOT_GET(status)].push_time; + + + wlfc->stats.latency_sample_count++; + if (new_t > old_t) + delta = new_t - old_t; + else + delta = 0xffffffff + new_t - old_t; + wlfc->stats.total_status_latency += delta; + wlfc->stats.latency_most_recent = delta; + + wlfc->stats.deltas[wlfc->stats.idx_delta++] = delta; + if (wlfc->stats.idx_delta == sizeof(wlfc->stats.deltas)/sizeof(uint32)) + wlfc->stats.idx_delta = 0; + } +#endif /* PROP_TXSTATUS_DEBUG */ + + fifo_id = DHD_PKTTAG_FIFO(PKTTAG(pktbuf)); + + /* pick up the implicit credit from this packet */ + if (DHD_PKTTAG_CREDITCHECK(PKTTAG(pktbuf))) { + if (wlfc->proptxstatus_mode == WLFC_FCMODE_IMPLIED_CREDIT) { + + int lender, credit_returned = 0; /* Note that borrower is fifo_id */ + + /* Return credits to highest priority lender first */ + for (lender = AC_COUNT; lender >= 0; lender--) { + if (wlfc->credits_borrowed[fifo_id][lender] > 0) { + wlfc->FIFO_credit[lender]++; + wlfc->credits_borrowed[fifo_id][lender]--; + credit_returned = 1; + break; + } + } + + if (!credit_returned) { + wlfc->FIFO_credit[fifo_id]++; + } + } + } + else { + /* + if this packet did not count against FIFO credit, it must have + taken a requested_credit from the destination entry (for pspoll etc.) + */ + if (!entry) { + + entry = _dhd_wlfc_find_table_entry(wlfc, pktbuf); + } + if (!DHD_PKTTAG_ONETIMEPKTRQST(PKTTAG(pktbuf))) + entry->requested_credit++; +#ifdef PROP_TXSTATUS_DEBUG + entry->dstncredit_acks++; +#endif + } + if ((status_flag == WLFC_CTL_PKTFLAG_D11SUPPRESS) || + (status_flag == WLFC_CTL_PKTFLAG_WLSUPPRESS)) { + + ret = _dhd_wlfc_enque_suppressed(wlfc, fifo_id, pktbuf); + if (ret != BCME_OK) { + /* delay q is full, drop this packet */ + dhd_wlfc_hanger_poppkt(wlfc->hanger, WLFC_PKTID_HSLOT_GET(status), + &pktbuf, 1); + + /* indicate failure and free the packet */ + dhd_txcomplete(dhd, pktbuf, FALSE); + entry->transit_count--; + /* This packet is transmitted Successfully by + * dongle even after first suppress. + */ + if (entry->suppressed) { + entry->suppr_transit_count--; + } + PKTFREE(wlfc->osh, pktbuf, TRUE); + } else { + /* Mark suppressed to avoid a double free during wlfc cleanup */ + dhd_wlfc_hanger_mark_suppressed(wlfc->hanger, + WLFC_PKTID_HSLOT_GET(status), WLFC_PKTID_GEN(status)); + entry->suppress_count++; + } + } + else { + dhd_txcomplete(dhd, pktbuf, TRUE); + entry->transit_count--; + + /* This packet is transmitted Successfully by dongle even after first suppress. */ + if (entry->suppressed) { + entry->suppr_transit_count--; + } + /* free the packet */ + PKTFREE(wlfc->osh, pktbuf, TRUE); + } + return BCME_OK; +} + +static int +dhd_wlfc_fifocreditback_indicate(dhd_pub_t *dhd, uint8* credits) +{ + int i; + athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) + dhd->wlfc_state; + for (i = 0; i < WLFC_CTL_VALUE_LEN_FIFO_CREDITBACK; i++) { +#ifdef PROP_TXSTATUS_DEBUG + wlfc->stats.fifo_credits_back[i] += credits[i]; +#endif + /* update FIFO credits */ + if (wlfc->proptxstatus_mode == WLFC_FCMODE_EXPLICIT_CREDIT) + { + int lender; /* Note that borrower is i */ + + /* Return credits to highest priority lender first */ + for (lender = AC_COUNT; (lender >= 0) && (credits[i] > 0); lender--) { + if (wlfc->credits_borrowed[i][lender] > 0) { + if (credits[i] >= wlfc->credits_borrowed[i][lender]) { + credits[i] -= wlfc->credits_borrowed[i][lender]; + wlfc->FIFO_credit[lender] += + wlfc->credits_borrowed[i][lender]; + wlfc->credits_borrowed[i][lender] = 0; + } + else { + wlfc->credits_borrowed[i][lender] -= credits[i]; + wlfc->FIFO_credit[lender] += credits[i]; + credits[i] = 0; + } + } + } + + /* If we have more credits left over, these must belong to the AC */ + if (credits[i] > 0) { + wlfc->FIFO_credit[i] += credits[i]; + } + } + } + + return BCME_OK; +} + +static int +dhd_wlfc_dbg_senum_check(dhd_pub_t *dhd, uint8 *value) +{ + uint32 timestamp; + + (void)dhd; + + bcopy(&value[2], ×tamp, sizeof(uint32)); + DHD_INFO(("RXPKT: SEQ: %d, timestamp %d\n", value[1], timestamp)); + return BCME_OK; +} + + +static int +dhd_wlfc_rssi_indicate(dhd_pub_t *dhd, uint8* rssi) +{ + (void)dhd; + (void)rssi; + return BCME_OK; +} + +static int +dhd_wlfc_mac_table_update(dhd_pub_t *dhd, uint8* value, uint8 type) +{ + int rc; + athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) + dhd->wlfc_state; + wlfc_mac_descriptor_t* table; + uint8 existing_index; + uint8 table_index; + uint8 ifid; + uint8* ea; + + WLFC_DBGMESG(("%s(), mac [%02x:%02x:%02x:%02x:%02x:%02x],%s,idx:%d,id:0x%02x\n", + __FUNCTION__, value[2], value[3], value[4], value[5], value[6], value[7], + ((type == WLFC_CTL_TYPE_MACDESC_ADD) ? "ADD":"DEL"), + WLFC_MAC_DESC_GET_LOOKUP_INDEX(value[0]), value[0])); + + table = wlfc->destination_entries.nodes; + table_index = WLFC_MAC_DESC_GET_LOOKUP_INDEX(value[0]); + ifid = value[1]; + ea = &value[2]; + + if (type == WLFC_CTL_TYPE_MACDESC_ADD) { + existing_index = dhd_wlfc_find_mac_desc_id_from_mac(dhd, &value[2]); + if (existing_index == WLFC_MAC_DESC_ID_INVALID) { + /* this MAC entry does not exist, create one */ + if (!table[table_index].occupied) { + table[table_index].mac_handle = value[0]; + rc = _dhd_wlfc_mac_entry_update(wlfc, &table[table_index], + eWLFC_MAC_ENTRY_ACTION_ADD, ifid, + wlfc->destination_entries.interfaces[ifid].iftype, + ea); + } + else { + /* the space should have been empty, but it's not */ + wlfc->stats.mac_update_failed++; + } + } + else { + /* + there is an existing entry, move it to new index + if necessary. + */ + if (existing_index != table_index) { + /* if we already have an entry, free the old one */ + table[existing_index].occupied = 0; + 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); + */ + } + } + } + if (type == WLFC_CTL_TYPE_MACDESC_DEL) { + if (table[table_index].occupied) { + rc = _dhd_wlfc_mac_entry_update(wlfc, &table[table_index], + eWLFC_MAC_ENTRY_ACTION_DEL, ifid, + wlfc->destination_entries.interfaces[ifid].iftype, + ea); + } + else { + /* the space should have been occupied, but it's not */ + wlfc->stats.mac_update_failed++; + } + } + BCM_REFERENCE(rc); + return BCME_OK; +} + +static int +dhd_wlfc_psmode_update(dhd_pub_t *dhd, uint8* value, uint8 type) +{ + /* Handle PS on/off indication */ + athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) + dhd->wlfc_state; + wlfc_mac_descriptor_t* table; + wlfc_mac_descriptor_t* desc; + uint8 mac_handle = value[0]; + int i; + + table = wlfc->destination_entries.nodes; + desc = &table[WLFC_MAC_DESC_GET_LOOKUP_INDEX(mac_handle)]; + if (desc->occupied) { + /* a fresh PS mode should wipe old ps credits? */ + desc->requested_credit = 0; + if (type == WLFC_CTL_TYPE_MAC_OPEN) { + desc->state = WLFC_STATE_OPEN; + DHD_WLFC_CTRINC_MAC_OPEN(desc); + } + else { + desc->state = WLFC_STATE_CLOSE; + DHD_WLFC_CTRINC_MAC_CLOSE(desc); + /* + Indicate to firmware if there is any traffic pending. + */ + for (i = AC_BE; i < AC_COUNT; i++) { + _dhd_wlfc_traffic_pending_check(wlfc, desc, i); + } + } + } + else { + wlfc->stats.psmode_update_failed++; + } + return BCME_OK; +} + +static int +dhd_wlfc_interface_update(dhd_pub_t *dhd, uint8* value, uint8 type) +{ + /* Handle PS on/off indication */ + athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) + dhd->wlfc_state; + wlfc_mac_descriptor_t* table; + uint8 if_id = value[0]; + + if (if_id < WLFC_MAX_IFNUM) { + table = wlfc->destination_entries.interfaces; + if (table[if_id].occupied) { + if (type == WLFC_CTL_TYPE_INTERFACE_OPEN) { + table[if_id].state = WLFC_STATE_OPEN; + /* WLFC_DBGMESG(("INTERFACE[%d] OPEN\n", if_id)); */ + } + else { + table[if_id].state = WLFC_STATE_CLOSE; + /* WLFC_DBGMESG(("INTERFACE[%d] CLOSE\n", if_id)); */ + } + return BCME_OK; + } + } + wlfc->stats.interface_update_failed++; + + return BCME_OK; +} + +static int +dhd_wlfc_credit_request(dhd_pub_t *dhd, uint8* value) +{ + athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) + dhd->wlfc_state; + wlfc_mac_descriptor_t* table; + wlfc_mac_descriptor_t* desc; + uint8 mac_handle; + uint8 credit; + + table = wlfc->destination_entries.nodes; + mac_handle = value[1]; + credit = value[0]; + + desc = &table[WLFC_MAC_DESC_GET_LOOKUP_INDEX(mac_handle)]; + if (desc->occupied) { + desc->requested_credit = credit; + + desc->ac_bitmap = value[2]; + } + else { + wlfc->stats.credit_request_failed++; + } + return BCME_OK; +} + +static int +dhd_wlfc_packet_request(dhd_pub_t *dhd, uint8* value) +{ + athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) + dhd->wlfc_state; + wlfc_mac_descriptor_t* table; + wlfc_mac_descriptor_t* desc; + uint8 mac_handle; + uint8 packet_count; + + table = wlfc->destination_entries.nodes; + mac_handle = value[1]; + packet_count = value[0]; + + desc = &table[WLFC_MAC_DESC_GET_LOOKUP_INDEX(mac_handle)]; + if (desc->occupied) { + desc->requested_packet = packet_count; + + desc->ac_bitmap = value[2]; + } + else { + wlfc->stats.packet_request_failed++; + } + 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, uchar *reorder_info_buf, + uint *reorder_info_len) +{ + uint8 type, len; + uint8* value; + uint8* tmpbuf; + uint16 remainder = tlv_hdr_len; + uint16 processed = 0; + athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) + dhd->wlfc_state; + tmpbuf = (uint8*)PKTDATA(dhd->osh, pktbuf); + if (remainder) { + while ((processed < (WLFC_MAX_PENDING_DATALEN * 2)) && (remainder > 0)) { + type = tmpbuf[processed]; + if (type == WLFC_CTL_TYPE_FILLER) { + remainder -= 1; + processed += 1; + continue; + } + + len = tmpbuf[processed + 1]; + value = &tmpbuf[processed + 2]; + + if (remainder < (2 + len)) + break; + + remainder -= 2 + len; + processed += 2 + len; + if (type == WLFC_CTL_TYPE_TXSTATUS) + dhd_wlfc_txstatus_update(dhd, value); + if (type == WLFC_CTL_TYPE_COMP_TXSTATUS) + dhd_wlfc_compressed_txstatus_update(dhd, value, len); + + 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); + + else if (type == WLFC_CTL_TYPE_RSSI) + dhd_wlfc_rssi_indicate(dhd, value); + + else if (type == WLFC_CTL_TYPE_MAC_REQUEST_CREDIT) + dhd_wlfc_credit_request(dhd, value); + + else if (type == WLFC_CTL_TYPE_MAC_REQUEST_PACKET) + dhd_wlfc_packet_request(dhd, value); + + else if ((type == WLFC_CTL_TYPE_MAC_OPEN) || + (type == WLFC_CTL_TYPE_MAC_CLOSE)) + dhd_wlfc_psmode_update(dhd, value, type); + + else if ((type == WLFC_CTL_TYPE_MACDESC_ADD) || + (type == WLFC_CTL_TYPE_MACDESC_DEL)) + dhd_wlfc_mac_table_update(dhd, value, type); + + else if (type == WLFC_CTL_TYPE_TRANS_ID) + dhd_wlfc_dbg_senum_check(dhd, value); + + else if ((type == WLFC_CTL_TYPE_INTERFACE_OPEN) || + (type == WLFC_CTL_TYPE_INTERFACE_CLOSE)) { + dhd_wlfc_interface_update(dhd, value, type); + } + } + if (remainder != 0) { + /* trouble..., something is not right */ + wlfc->stats.tlv_parse_failed++; + } + } + return BCME_OK; +} + +int +dhd_wlfc_init(dhd_pub_t *dhd) +{ + char iovbuf[12]; /* Room for "tlv" + '\0' + parameter */ + /* enable all signals & indicate host proptxstatus logic is active */ + uint32 tlv = dhd->wlfc_enabled? + WLFC_FLAGS_RSSI_SIGNALS | + WLFC_FLAGS_XONXOFF_SIGNALS | + WLFC_FLAGS_CREDIT_STATUS_SIGNALS | + WLFC_FLAGS_HOST_PROPTXSTATUS_ACTIVE | + WLFC_FLAGS_HOST_RXRERODER_ACTIVE : 0; + /* WLFC_FLAGS_HOST_PROPTXSTATUS_ACTIVE | WLFC_FLAGS_HOST_RXRERODER_ACTIVE : 0; */ + + + /* + try to enable/disable signaling by sending "tlv" iovar. if that fails, + fallback to no flow control? Print a message for now. + */ + + /* enable proptxtstatus signaling by default */ + bcm_mkiovar("tlv", (char *)&tlv, 4, iovbuf, sizeof(iovbuf)); + if (dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0) < 0) { + DHD_ERROR(("dhd_wlfc_init(): failed to enable/disable bdcv2 tlv signaling\n")); + } + else { + /* + Leaving the message for now, it should be removed after a while; once + the tlv situation is stable. + */ + DHD_ERROR(("dhd_wlfc_init(): successfully %s bdcv2 tlv signaling, %d\n", + dhd->wlfc_enabled?"enabled":"disabled", tlv)); + } + return BCME_OK; +} + +int +dhd_wlfc_enable(dhd_pub_t *dhd) +{ + int i; + athost_wl_status_info_t* wlfc; + + DHD_TRACE(("Enter %s\n", __FUNCTION__)); + + if (!dhd->wlfc_enabled || dhd->wlfc_state) + return BCME_OK; + + /* allocate space to track txstatus propagated from firmware */ + dhd->wlfc_state = MALLOC(dhd->osh, sizeof(athost_wl_status_info_t)); + if (dhd->wlfc_state == NULL) + return BCME_NOMEM; + + /* initialize state space */ + wlfc = (athost_wl_status_info_t*)dhd->wlfc_state; + memset(wlfc, 0, sizeof(athost_wl_status_info_t)); + + /* remember osh & dhdp */ + wlfc->osh = dhd->osh; + wlfc->dhdp = dhd; + + wlfc->hanger = + dhd_wlfc_hanger_create(dhd->osh, WLFC_HANGER_MAXITEMS); + if (wlfc->hanger == NULL) { + MFREE(dhd->osh, dhd->wlfc_state, sizeof(athost_wl_status_info_t)); + dhd->wlfc_state = NULL; + return BCME_NOMEM; + } + + /* initialize all interfaces to accept traffic */ + for (i = 0; i < WLFC_MAX_IFNUM; i++) { + wlfc->hostif_flow_state[i] = OFF; + } + + /* + create the SENDQ containing + sub-queues for all AC precedences + 1 for bc/mc traffic + */ + pktq_init(&wlfc->SENDQ, (AC_COUNT + 1), WLFC_SENDQ_LEN); + + wlfc->destination_entries.other.state = WLFC_STATE_OPEN; + /* bc/mc FIFO is always open [credit aside], i.e. b[5] */ + wlfc->destination_entries.other.ac_bitmap = 0x1f; + wlfc->destination_entries.other.interface_id = 0; + + wlfc->proptxstatus_mode = WLFC_FCMODE_EXPLICIT_CREDIT; + + wlfc->allow_credit_borrow = TRUE; + wlfc->borrow_defer_timestamp = 0; + + return BCME_OK; +} + +/* release all packet resources */ +void +dhd_wlfc_cleanup(dhd_pub_t *dhd) +{ + int i; + int total_entries; + athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) + dhd->wlfc_state; + wlfc_mac_descriptor_t* table; + wlfc_hanger_t* h; + int prec; + void *pkt = NULL; + struct pktq *txq = NULL; + + DHD_TRACE(("Enter %s\n", __FUNCTION__)); + if (dhd->wlfc_state == NULL) + return; + /* flush bus->txq */ + txq = dhd_bus_txq(dhd->bus); + + /* any in the hanger? */ + h = (wlfc_hanger_t*)wlfc->hanger; + total_entries = sizeof(wlfc->destination_entries)/sizeof(wlfc_mac_descriptor_t); + /* search all entries, include nodes as well as interfaces */ + table = (wlfc_mac_descriptor_t*)&wlfc->destination_entries; + + for (i = 0; i < total_entries; i++) { + if (table[i].occupied) { + if (table[i].psq.len) { + WLFC_DBGMESG(("%s(): DELAYQ[%d].len = %d\n", + __FUNCTION__, i, table[i].psq.len)); + /* release packets held in DELAYQ */ + pktq_flush(wlfc->osh, &table[i].psq, TRUE, NULL, 0); + } + table[i].occupied = 0; + } + } + /* release packets held in SENDQ */ + if (wlfc->SENDQ.len) + pktq_flush(wlfc->osh, &wlfc->SENDQ, TRUE, NULL, 0); + for (prec = 0; prec < txq->num_prec; prec++) { + pkt = pktq_pdeq(txq, prec); + while (pkt) { + for (i = 0; i < h->max_items; i++) { + if (pkt == h->items[i].pkt) { + if (h->items[i].state == WLFC_HANGER_ITEM_STATE_INUSE) { + PKTFREE(wlfc->osh, h->items[i].pkt, TRUE); + h->items[i].state = WLFC_HANGER_ITEM_STATE_FREE; + h->items[i].pkt = NULL; + h->items[i].identifier = 0; + } else if (h->items[i].state == + WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED) { + /* These are already freed from the psq */ + h->items[i].state = WLFC_HANGER_ITEM_STATE_FREE; + } + break; + } + } + pkt = pktq_pdeq(txq, prec); + } + } + /* flush remained pkt in hanger queue, not in bus->txq */ + for (i = 0; i < h->max_items; i++) { + if (h->items[i].state == WLFC_HANGER_ITEM_STATE_INUSE) { + PKTFREE(wlfc->osh, h->items[i].pkt, TRUE); + h->items[i].state = WLFC_HANGER_ITEM_STATE_FREE; + } else if (h->items[i].state == WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED) { + /* These are freed from the psq so no need to free again */ + h->items[i].state = WLFC_HANGER_ITEM_STATE_FREE; + } + } + + return; +} + +void +dhd_wlfc_deinit(dhd_pub_t *dhd) +{ + /* cleanup all psq related resources */ + athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) + dhd->wlfc_state; + + DHD_TRACE(("Enter %s\n", __FUNCTION__)); + + dhd_os_wlfc_block(dhd); + if (dhd->wlfc_state == NULL) { + dhd_os_wlfc_unblock(dhd); + return; + } + +#ifdef PROP_TXSTATUS_DEBUG + { + int i; + wlfc_hanger_t* h = (wlfc_hanger_t*)wlfc->hanger; + for (i = 0; i < h->max_items; i++) { + if (h->items[i].state != WLFC_HANGER_ITEM_STATE_FREE) { + WLFC_DBGMESG(("%s() pkt[%d] = 0x%p, FIFO_credit_used:%d\n", + __FUNCTION__, i, h->items[i].pkt, + DHD_PKTTAG_CREDITCHECK(PKTTAG(h->items[i].pkt)))); + } + } + } +#endif + /* delete hanger */ + dhd_wlfc_hanger_delete(dhd->osh, wlfc->hanger); + + /* free top structure */ + MFREE(dhd->osh, dhd->wlfc_state, sizeof(athost_wl_status_info_t)); + dhd->wlfc_state = NULL; + dhd_os_wlfc_unblock(dhd); + + return; +} +#endif /* PROP_TXSTATUS */ + +void +dhd_prot_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf) +{ + bcm_bprintf(strbuf, "Protocol CDC: reqid %d\n", dhdp->prot->reqid); +#ifdef PROP_TXSTATUS + dhd_os_wlfc_block(dhdp); + if (dhdp->wlfc_state) + dhd_wlfc_dump(dhdp, strbuf); + dhd_os_wlfc_unblock(dhdp); +#endif +} + +void +dhd_prot_hdrpush(dhd_pub_t *dhd, int ifidx, void *pktbuf) +{ +#ifdef BDC + struct bdc_header *h; +#endif /* BDC */ + + DHD_TRACE(("%s: Enter\n", __FUNCTION__)); + +#ifdef BDC + /* Push BDC header used to convey priority for buses that don't */ + + PKTPUSH(dhd->osh, pktbuf, BDC_HEADER_LEN); + + h = (struct bdc_header *)PKTDATA(dhd->osh, pktbuf); + + h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT); + if (PKTSUMNEEDED(pktbuf)) + h->flags |= BDC_FLAG_SUM_NEEDED; + + + h->priority = (PKTPRIO(pktbuf) & BDC_PRIORITY_MASK); + h->flags2 = 0; + h->dataOffset = 0; +#endif /* BDC */ + BDC_SET_IF_IDX(h, ifidx); +} + +int +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; +#endif + uint8 data_offset = 0; + + 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) { + DHD_ERROR(("%s: rx data too short (%d < %d)\n", __FUNCTION__, + PKTLEN(dhd->osh, pktbuf), BDC_HEADER_LEN)); + return BCME_ERROR; + } + + h = (struct bdc_header *)PKTDATA(dhd->osh, pktbuf); + +#if defined(NDIS630) + h->dataOffset = 0; +#endif + + if (!ifidx) { + /* for tx packet, skip the analysis */ + data_offset = h->dataOffset; + PKTPULL(dhd->osh, pktbuf, BDC_HEADER_LEN); + goto exit; + } + + if ((*ifidx = BDC_GET_IF_IDX(h)) >= DHD_MAX_IFS) { + DHD_ERROR(("%s: rx data ifnum out of range (%d)\n", + __FUNCTION__, *ifidx)); + return BCME_ERROR; + } + + if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) != BDC_PROTO_VER) { + DHD_ERROR(("%s: non-BDC packet received, flags = 0x%x\n", + dhd_ifname(dhd, *ifidx), h->flags)); + if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) == BDC_PROTO_VER_1) + h->dataOffset = 0; + else + return BCME_ERROR; + } + + if (h->flags & BDC_FLAG_SUM_GOOD) { + DHD_INFO(("%s: BDC packet received with good rx-csum, flags 0x%x\n", + dhd_ifname(dhd, *ifidx), h->flags)); + PKTSETSUMGOOD(pktbuf, TRUE); + } + + PKTSETPRIO(pktbuf, (h->priority & BDC_PRIORITY_MASK)); + data_offset = h->dataOffset; + PKTPULL(dhd->osh, pktbuf, BDC_HEADER_LEN); +#endif /* BDC */ + +#if !defined(NDIS630) + if (PKTLEN(dhd->osh, pktbuf) < (uint32) (data_offset << 2)) { + DHD_ERROR(("%s: rx data too short (%d < %d)\n", __FUNCTION__, + PKTLEN(dhd->osh, pktbuf), (data_offset * 4))); + return BCME_ERROR; + } +#endif +#ifdef PROP_TXSTATUS + if (dhd->wlfc_state && + ((athost_wl_status_info_t*)dhd->wlfc_state)->proptxstatus_mode + != WLFC_FCMODE_NONE && + (!DHD_PKTTAG_PKTDIR(PKTTAG(pktbuf)))) { + /* + - parse txstatus only for packets that came from the firmware + */ + dhd_os_wlfc_block(dhd); + dhd_wlfc_parse_header_info(dhd, pktbuf, (data_offset << 2), + reorder_buf_info, reorder_info_len); + ((athost_wl_status_info_t*)dhd->wlfc_state)->stats.dhd_hdrpulls++; + dhd_os_wlfc_unblock(dhd); + } +#endif /* PROP_TXSTATUS */ + +exit: +#if !defined(NDIS630) + PKTPULL(dhd->osh, pktbuf, (data_offset << 2)); +#endif + return 0; +} + +#if defined(PROP_TXSTATUS) +void +dhd_wlfc_trigger_pktcommit(dhd_pub_t *dhd) +{ + if (dhd->wlfc_state && + (((athost_wl_status_info_t*)dhd->wlfc_state)->proptxstatus_mode + != WLFC_FCMODE_NONE)) { + dhd_os_wlfc_block(dhd); + dhd_wlfc_commit_packets(dhd->wlfc_state, (f_commitpkt_t)dhd_bus_txdata, + (void *)dhd->bus); + dhd_os_wlfc_unblock(dhd); + } +} +#endif + +int +dhd_prot_attach(dhd_pub_t *dhd) +{ + dhd_prot_t *cdc; + + 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; + } + memset(cdc, 0, sizeof(dhd_prot_t)); + + /* ensure that the msg buf directly follows the cdc msg struct */ + if ((uintptr)(&cdc->msg + 1) != (uintptr)cdc->buf) { + DHD_ERROR(("dhd_prot_t is not correctly defined\n")); + goto fail; + } + + dhd->prot = cdc; +#ifdef BDC + dhd->hdrlen += BDC_HEADER_LEN; +#endif + dhd->maxctl = WLC_IOCTL_MAXLEN + sizeof(cdc_ioctl_t) + ROUND_UP_MARGIN; + return 0; + +fail: +#ifndef CONFIG_DHD_USE_STATIC_BUF + if (cdc != NULL) + MFREE(dhd->osh, cdc, sizeof(dhd_prot_t)); +#endif /* CONFIG_DHD_USE_STATIC_BUF */ + return BCME_NOMEM; +} + +/* ~NOTE~ What if another thread is waiting on the semaphore? Holding it? */ +void +dhd_prot_detach(dhd_pub_t *dhd) +{ +#ifdef PROP_TXSTATUS + dhd_wlfc_deinit(dhd); +#endif +#ifndef CONFIG_DHD_USE_STATIC_BUF + MFREE(dhd->osh, dhd->prot, sizeof(dhd_prot_t)); +#endif /* CONFIG_DHD_USE_STATIC_BUF */ + dhd->prot = NULL; +} + +void +dhd_prot_dstats(dhd_pub_t *dhd) +{ + /* No stats from dongle added yet, copy bus stats */ + dhd->dstats.tx_packets = dhd->tx_packets; + dhd->dstats.tx_errors = dhd->tx_errors; + dhd->dstats.rx_packets = dhd->rx_packets; + dhd->dstats.rx_errors = dhd->rx_errors; + dhd->dstats.rx_dropped = dhd->rx_dropped; + dhd->dstats.multicast = dhd->rx_multicast; + return; +} + +int +dhd_prot_init(dhd_pub_t *dhd) { int ret = 0; wlc_rev_info_t revinfo; @@ -556,6 +2911,11 @@ dhd_prot_init(dhd_pub_t *dhd) if (dhd_download_fw_on_driverload) #endif /* defined(WL_CFG80211) */ ret = dhd_preinit_ioctls(dhd); + +#ifdef PROP_TXSTATUS + ret = dhd_wlfc_init(dhd); +#endif + /* Always assumes wl for now */ dhd->iswl = TRUE; @@ -656,7 +3016,7 @@ dhd_process_pkt_reorder_info(dhd_pub_t * __FUNCTION__, flow_id)); if (ptr == NULL) { - DHD_REORDER(("%s: received flags to cleanup, but no flow (%d) yet\n", + DHD_ERROR(("%s: received flags to cleanup, but no flow (%d) yet\n", __FUNCTION__, flow_id)); *pkt_count = 1; *pkt = cur_pkt; diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/dhd_cfg80211.c linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_cfg80211.c --- linux-sunxi/drivers/net/wireless/bcmdhd/dhd_cfg80211.c 2014-01-27 01:30:30.108433411 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_cfg80211.c 2014-02-15 00:43:44.795014136 +0100 @@ -1,7 +1,7 @@ /* * Linux cfg80211 driver - Dongle Host Driver (DHD) related * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -152,43 +152,6 @@ default_conf_out: } -#ifdef CONFIG_NL80211_TESTMODE -int dhd_cfg80211_testmode_cmd(struct wiphy *wiphy, void *data, int len) -{ - struct sk_buff *reply; - struct wl_priv *wl; - dhd_pub_t *dhd; - dhd_ioctl_t *ioc = data; - int err = 0; - - WL_TRACE(("entry: cmd = %d\n", ioc->cmd)); - wl = wiphy_priv(wiphy); - dhd = wl->pub; - - DHD_OS_WAKE_LOCK(dhd); - - /* send to dongle only if we are not waiting for reload already */ - if (dhd->hang_was_sent) { - WL_ERR(("HANG was sent up earlier\n")); - DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE(dhd, DHD_EVENT_TIMEOUT_MS); - DHD_OS_WAKE_UNLOCK(dhd); - return OSL_ERROR(BCME_DONGLE_DOWN); - } - - /* currently there is only one wiphy for ifidx 0 */ - err = dhd_ioctl_process(dhd, 0, ioc); - if (err) - goto done; - - /* response data is in ioc->buf so return ioc here */ - reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*ioc)); - nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*ioc), ioc); - err = cfg80211_testmode_reply(reply); -done: - DHD_OS_WAKE_UNLOCK(dhd); - return err; -} -#endif /* CONFIG_NL80211_TESTMODE */ /* TODO: clean up the BT-Coex code, it still have some legacy ioctl/iovar functions */ #define COEX_DHCP @@ -274,10 +237,11 @@ static bool btcoex_is_sco_active(struct ioc_res = dev_wlc_intvar_get_reg(dev, "btc_params", 27, ¶m27); - WL_TRACE(("sample[%d], btc params: 27:%x\n", i, param27)); + WL_TRACE(("%s, sample[%d], btc params: 27:%x\n", + __FUNCTION__, i, param27)); if (ioc_res < 0) { - WL_ERR(("ioc read btc params error\n")); + WL_ERR(("%s ioc read btc params error\n", __FUNCTION__)); break; } @@ -286,13 +250,13 @@ static bool btcoex_is_sco_active(struct } if (sco_id_cnt > 2) { - WL_TRACE(("sco/esco detected, pkt id_cnt:%d samples:%d\n", - sco_id_cnt, i)); + WL_TRACE(("%s, sco/esco detected, pkt id_cnt:%d samples:%d\n", + __FUNCTION__, sco_id_cnt, i)); res = TRUE; break; } - OSL_SLEEP(5); + msleep(5); } return res; @@ -335,9 +299,9 @@ static int set_btc_esco_params(struct ne (!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(("saved bt_params[50,51,64,65,71]:" + WL_TRACE(("%s saved bt_params[50,51,64,65,71]:" "0x%x 0x%x 0x%x 0x%x 0x%x\n", - saved_reg50, saved_reg51, + __FUNCTION__, saved_reg50, saved_reg51, saved_reg64, saved_reg65, saved_reg71)); } else { WL_ERR((":%s: save btc_params failed\n", @@ -434,7 +398,7 @@ wl_cfg80211_bt_setflag(struct net_device static void wl_cfg80211_bt_timerfunc(ulong data) { struct btcoex_info *bt_local = (struct btcoex_info *)data; - WL_TRACE(("Enter\n")); + WL_TRACE(("%s\n", __FUNCTION__)); bt_local->timer_on = 0; schedule_work(&bt_local->work); } @@ -455,8 +419,8 @@ static void wl_cfg80211_bt_handler(struc /* DHCP started * provide OPPORTUNITY window to get DHCP address */ - WL_TRACE(("bt_dhcp stm: started \n")); - + WL_TRACE(("%s bt_dhcp stm: started \n", + __FUNCTION__)); btcx_inf->bt_state = BT_DHCP_OPPR_WIN; mod_timer(&btcx_inf->timer, jiffies + msecs_to_jiffies(BT_DHCP_OPPR_WIN_TIME)); @@ -465,14 +429,16 @@ static void wl_cfg80211_bt_handler(struc case BT_DHCP_OPPR_WIN: if (btcx_inf->dhcp_done) { - WL_TRACE(("DHCP Done before T1 expiration\n")); + WL_TRACE(("%s DHCP Done before T1 expiration\n", + __FUNCTION__)); goto btc_coex_idle; } /* DHCP is not over yet, start lowering BT priority * enforce btc_params + flags if necessary */ - WL_TRACE(("DHCP T1:%d expired\n", BT_DHCP_OPPR_WIN_TIME)); + WL_TRACE(("%s DHCP T1:%d expired\n", __FUNCTION__, + BT_DHCP_OPPR_WIN_TIME)); if (btcx_inf->dev) wl_cfg80211_bt_setflag(btcx_inf->dev, TRUE); btcx_inf->bt_state = BT_DHCP_FLAG_FORCE_TIMEOUT; @@ -483,11 +449,13 @@ static void wl_cfg80211_bt_handler(struc case BT_DHCP_FLAG_FORCE_TIMEOUT: if (btcx_inf->dhcp_done) { - WL_TRACE(("DHCP Done before T2 expiration\n")); + WL_TRACE(("%s DHCP Done before T2 expiration\n", + __FUNCTION__)); } else { /* Noo dhcp during T1+T2, restore BT priority */ - WL_TRACE(("DHCP wait interval T2:%d msec expired\n", - BT_DHCP_FLAG_FORCE_TIME)); + WL_TRACE(("%s DHCP wait interval T2:%d" + "msec expired\n", __FUNCTION__, + BT_DHCP_FLAG_FORCE_TIME)); } /* Restoring default bt priority */ @@ -499,7 +467,8 @@ btc_coex_idle: break; default: - WL_ERR(("error g_status=%d !!!\n", btcx_inf->bt_state)); + WL_ERR(("%s error g_status=%d !!!\n", __FUNCTION__, + btcx_inf->bt_state)); if (btcx_inf->dev) wl_cfg80211_bt_setflag(btcx_inf->dev, FALSE); btcx_inf->bt_state = BT_DHCP_IDLE; @@ -550,6 +519,7 @@ void wl_cfg80211_btcoex_deinit(struct wl kfree(wl->btcoex_info); wl->btcoex_info = NULL; } +#endif int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, char *command) { @@ -579,8 +549,12 @@ int wl_cfg80211_set_btcoex_dhcp(struct n strncpy((char *)&powermode_val, command + strlen("BTCOEXMODE") +1, 1); if (strnicmp((char *)&powermode_val, "1", strlen("1")) == 0) { - WL_TRACE_HW4(("DHCP session starts\n")); + WL_TRACE_HW4(("%s: DHCP session starts\n", __FUNCTION__)); +#if defined(DHCP_SCAN_SUPPRESS) + /* Suppress scan during the DHCP */ + wl_cfg80211_scan_suppress(dev, 1); +#endif /* OEM_ANDROID */ #ifdef PKT_FILTER_SUPPORT dhd->dhcp_in_progress = 1; @@ -623,21 +597,26 @@ int wl_cfg80211_set_btcoex_dhcp(struct n btco_inf->bt_state = BT_DHCP_START; btco_inf->timer_on = 1; mod_timer(&btco_inf->timer, btco_inf->timer.expires); - WL_TRACE(("enable BT DHCP Timer\n")); + WL_TRACE(("%s enable BT DHCP Timer\n", + __FUNCTION__)); } #endif /* COEX_DHCP */ } else if (saved_status == TRUE) { - WL_ERR(("was called w/o DHCP OFF. Continue\n")); + WL_ERR(("%s was called w/o DHCP OFF. Continue\n", __FUNCTION__)); } } else if (strnicmp((char *)&powermode_val, "2", strlen("2")) == 0) { - #ifdef PKT_FILTER_SUPPORT dhd->dhcp_in_progress = 0; - WL_TRACE_HW4(("DHCP is complete \n")); + WL_TRACE_HW4(("%s: DHCP is complete \n", __FUNCTION__)); + +#if defined(DHCP_SCAN_SUPPRESS) + /* Since DHCP is complete, enable the scan back */ + wl_cfg80211_scan_suppress(dev, 0); +#endif /* OEM_ANDROID */ /* Enable packet filtering */ if (dhd->early_suspended) { @@ -650,14 +629,15 @@ int wl_cfg80211_set_btcoex_dhcp(struct n #ifdef COEX_DHCP /* Stop any bt timer because DHCP session is done */ - WL_TRACE(("disable BT DHCP Timer\n")); + WL_TRACE(("%s disable BT DHCP Timer\n", __FUNCTION__)); if (btco_inf->timer_on) { btco_inf->timer_on = 0; del_timer_sync(&btco_inf->timer); if (btco_inf->bt_state != BT_DHCP_IDLE) { /* need to restore original btc flags & extra btc params */ - WL_TRACE(("bt->bt_state:%d\n", btco_inf->bt_state)); + WL_TRACE(("%s bt->bt_state:%d\n", + __FUNCTION__, btco_inf->bt_state)); /* wake up btcoex thread to restore btlags+params */ schedule_work(&btco_inf->work); } @@ -688,11 +668,11 @@ int wl_cfg80211_set_btcoex_dhcp(struct n } else { - WL_ERR(("Unkwown yet power setting, ignored\n")); + WL_ERR(("%s Unkwown yet power setting, ignored\n", + __FUNCTION__)); } snprintf(command, 3, "OK"); return (strlen("OK")); } -#endif diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/dhd_cfg80211.h linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_cfg80211.h --- linux-sunxi/drivers/net/wireless/bcmdhd/dhd_cfg80211.h 2014-01-27 01:30:30.108433411 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_cfg80211.h 2014-02-15 00:43:44.795014136 +0100 @@ -1,7 +1,7 @@ /* * Linux cfg80211 driver - Dongle Host Driver (DHD) related * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -38,15 +38,6 @@ s32 dhd_cfg80211_set_p2p_info(struct wl_ s32 dhd_cfg80211_clean_p2p_info(struct wl_priv *wl); s32 dhd_config_dongle(struct wl_priv *wl, bool need_lock); -#ifdef CONFIG_NL80211_TESTMODE -int dhd_cfg80211_testmode_cmd(struct wiphy *wiphy, void *data, int len); -#else -static inline int dhd_cfg80211_testmode_cmd(struct wiphy *wiphy, void *data, int len) -{ - return 0; -} -#endif - int wl_cfg80211_btcoex_init(struct wl_priv *wl); void wl_cfg80211_btcoex_deinit(struct wl_priv *wl); diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/dhd_common.c linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_common.c --- linux-sunxi/drivers/net/wireless/bcmdhd/dhd_common.c 2014-01-27 01:30:30.109433432 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_common.c 2014-02-15 00:43:44.796014158 +0100 @@ -1,7 +1,7 @@ /* * Broadcom Dongle Host Driver (DHD), common DHD core. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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 419132 2013-08-19 21:33:05Z $ + * $Id: dhd_common.c 373873 2012-12-10 20:45:58Z $ */ #include #include @@ -33,10 +33,8 @@ #include #include #include -#include #include -#include #include #include @@ -46,26 +44,29 @@ #ifdef WL_CFG80211 #include #endif -#ifdef PNO_SUPPORT -#include +#ifdef WLBTAMP +#include +#include #endif #ifdef SET_RANDOM_MAC_SOFTAP #include #include #endif -#define htod32(i) (i) -#define htod16(i) (i) -#define dtoh32(i) (i) -#define dtoh16(i) (i) -#define htodchanspec(i) (i) -#define dtohchanspec(i) (i) +#define htod32(i) i +#define htod16(i) i +#define dtoh32(i) i +#define dtoh16(i) i +#define htodchanspec(i) i +#define dtohchanspec(i) i #ifdef PROP_TXSTATUS #include #include #endif +extern int wifi_pm_get_mod_type(void); + #ifdef WLMEDIA_HTSF extern void htsf_update(struct dhd_info *dhd, void *data); #endif @@ -112,6 +113,7 @@ void dhd_set_timer(void *bus, uint wdtic /* IOVar table */ enum { IOV_VERSION = 1, + IOV_WLMSGLEVEL, IOV_MSGLEVEL, IOV_BCMERRORSTR, IOV_BCMERROR, @@ -123,6 +125,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,8 +136,7 @@ enum { #ifdef PROP_TXSTATUS IOV_PROPTXSTATUS_ENABLE, IOV_PROPTXSTATUS_MODE, - IOV_PROPTXSTATUS_OPT, -#endif /* PROP_TXSTATUS */ +#endif IOV_BUS_TYPE, #ifdef WLMEDIA_HTSF IOV_WLPKTDLYSTAT_SZ, @@ -143,6 +148,7 @@ enum { const bcm_iovar_t dhd_iovars[] = { {"version", IOV_VERSION, 0, IOVT_BUFFER, sizeof(dhd_version) }, + {"wlmsglevel", IOV_WLMSGLEVEL, 0, IOVT_UINT32, 0 }, #ifdef DHD_DEBUG {"msglevel", IOV_MSGLEVEL, 0, IOVT_UINT32, 0 }, #endif /* DHD_DEBUG */ @@ -157,6 +163,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,8 +176,7 @@ const bcm_iovar_t dhd_iovars[] = { 2 - Use explicit credit */ {"ptxmode", IOV_PROPTXSTATUS_MODE, 0, IOVT_UINT32, 0 }, - {"proptx_opt", IOV_PROPTXSTATUS_OPT, 0, IOVT_UINT32, 0 }, -#endif /* PROP_TXSTATUS */ +#endif {"bustype", IOV_BUS_TYPE, 0, IOVT_UINT32, 0}, #ifdef WLMEDIA_HTSF {"pktdlystatsz", IOV_WLPKTDLYSTAT_SZ, 0, IOVT_UINT8, 0 }, @@ -177,18 +186,53 @@ const bcm_iovar_t dhd_iovars[] = { (WLHOST_REORDERDATA_MAXFLOWS + 1) }, {NULL, 0, 0, 0, 0 } }; -#define DHD_IOVAR_BUF_SIZE 128 void dhd_common_init(osl_t *osh) { + int select_type = 0; + //aw checkout which wifi had select + select_type = wifi_pm_get_mod_type(); + #ifdef CONFIG_BCMDHD_FW_PATH - bcm_strncpy_s(fw_path, sizeof(fw_path), CONFIG_BCMDHD_FW_PATH, MOD_PARAM_PATHLEN-1); + //select bcm40181/ap6181/ap6210 + if (select_type == 1 || select_type == 7 || select_type == 9) { + bcm_strncpy_s(fw_path, sizeof(fw_path), "/lib/firmware/ap6210/fw_bcm40181a2.bin", MOD_PARAM_PATHLEN-1); + } + //select bcm40183 + if (select_type == 2) { + bcm_strncpy_s(fw_path, sizeof(fw_path), "/lib/firmware/ap6210/fw_bcm40183b2.bin", MOD_PARAM_PATHLEN-1); + } + //select ap6330 + if (select_type == 8) { + bcm_strncpy_s(fw_path, sizeof(fw_path), "/lib/firmware/ap6210/fw_bcm40183b2_ag.bin", MOD_PARAM_PATHLEN-1); + } + #else /* CONFIG_BCMDHD_FW_PATH */ fw_path[0] = '\0'; #endif /* CONFIG_BCMDHD_FW_PATH */ #ifdef CONFIG_BCMDHD_NVRAM_PATH - bcm_strncpy_s(nv_path, sizeof(nv_path), CONFIG_BCMDHD_NVRAM_PATH, MOD_PARAM_PATHLEN-1); + //select bcm40181 + if (select_type == 1) { + bcm_strncpy_s(nv_path, sizeof(nv_path), "/lib/firmware/ap6210/nvram_bcm40181.txt", MOD_PARAM_PATHLEN-1); + } + //select bcm40183 + if (select_type == 2) { + bcm_strncpy_s(nv_path, sizeof(nv_path), "/lib/firmware/ap6210/nvram_bcm40183.txt", MOD_PARAM_PATHLEN-1); + } + //select ap6210 + if (select_type == 7) { + bcm_strncpy_s(nv_path, sizeof(nv_path), "/lib/firmware/ap6210/nvram_ap6210.txt", MOD_PARAM_PATHLEN-1); + } + + //select ap6330 + if (select_type == 8) { + bcm_strncpy_s(nv_path, sizeof(nv_path), "/lib/firmware/ap6210/nvram_ap6330.txt", MOD_PARAM_PATHLEN-1); + } + //select ap6181 + if (select_type == 9) { + bcm_strncpy_s(nv_path, sizeof(nv_path), "/lib/firmware/ap6210/nvram_ap6181.txt", MOD_PARAM_PATHLEN-1); + } #else /* CONFIG_BCMDHD_NVRAM_PATH */ nv_path[0] = '\0'; #endif /* CONFIG_BCMDHD_NVRAM_PATH */ @@ -197,28 +241,6 @@ dhd_common_init(osl_t *osh) #endif } -void -dhd_common_deinit(dhd_pub_t *dhd_pub, dhd_cmn_t *sa_cmn) -{ - osl_t *osh; - dhd_cmn_t *cmn; - - if (dhd_pub != NULL) - cmn = dhd_pub->cmn; - else - cmn = sa_cmn; - - if (!cmn) - return; - - osh = cmn->osh; - - if (dhd_pub != NULL) - dhd_pub->cmn = NULL; - - MFREE(osh, cmn, sizeof(dhd_cmn_t)); -} - static int dhd_dump(dhd_pub_t *dhdp, char *buf, int buflen) { @@ -234,31 +256,31 @@ dhd_dump(dhd_pub_t *dhdp, char *buf, int bcm_bprintf(strbuf, "\n"); bcm_bprintf(strbuf, "pub.up %d pub.txoff %d pub.busstate %d\n", dhdp->up, dhdp->txoff, dhdp->busstate); - bcm_bprintf(strbuf, "pub.hdrlen %u pub.maxctl %u pub.rxsz %u\n", + bcm_bprintf(strbuf, "pub.hdrlen %d pub.maxctl %d pub.rxsz %d\n", dhdp->hdrlen, dhdp->maxctl, dhdp->rxsz); bcm_bprintf(strbuf, "pub.iswl %d pub.drv_version %ld pub.mac %s\n", dhdp->iswl, dhdp->drv_version, bcm_ether_ntoa(&dhdp->mac, eabuf)); - bcm_bprintf(strbuf, "pub.bcmerror %d tickcnt %u\n", dhdp->bcmerror, dhdp->tickcnt); + bcm_bprintf(strbuf, "pub.bcmerror %d tickcnt %d\n", dhdp->bcmerror, dhdp->tickcnt); bcm_bprintf(strbuf, "dongle stats:\n"); - bcm_bprintf(strbuf, "tx_packets %lu tx_bytes %lu tx_errors %lu tx_dropped %lu\n", + bcm_bprintf(strbuf, "tx_packets %ld tx_bytes %ld tx_errors %ld tx_dropped %ld\n", dhdp->dstats.tx_packets, dhdp->dstats.tx_bytes, dhdp->dstats.tx_errors, dhdp->dstats.tx_dropped); - bcm_bprintf(strbuf, "rx_packets %lu rx_bytes %lu rx_errors %lu rx_dropped %lu\n", + bcm_bprintf(strbuf, "rx_packets %ld rx_bytes %ld rx_errors %ld rx_dropped %ld\n", dhdp->dstats.rx_packets, dhdp->dstats.rx_bytes, dhdp->dstats.rx_errors, dhdp->dstats.rx_dropped); - bcm_bprintf(strbuf, "multicast %lu\n", dhdp->dstats.multicast); + bcm_bprintf(strbuf, "multicast %ld\n", dhdp->dstats.multicast); bcm_bprintf(strbuf, "bus stats:\n"); - bcm_bprintf(strbuf, "tx_packets %lu tx_multicast %lu tx_errors %lu\n", + bcm_bprintf(strbuf, "tx_packets %ld tx_multicast %ld tx_errors %ld\n", dhdp->tx_packets, dhdp->tx_multicast, dhdp->tx_errors); - bcm_bprintf(strbuf, "tx_ctlpkts %lu tx_ctlerrs %lu\n", + bcm_bprintf(strbuf, "tx_ctlpkts %ld tx_ctlerrs %ld\n", dhdp->tx_ctlpkts, dhdp->tx_ctlerrs); - bcm_bprintf(strbuf, "rx_packets %lu rx_multicast %lu rx_errors %lu \n", + bcm_bprintf(strbuf, "rx_packets %ld rx_multicast %ld rx_errors %ld \n", dhdp->rx_packets, dhdp->rx_multicast, dhdp->rx_errors); - bcm_bprintf(strbuf, "rx_ctlpkts %lu rx_ctlerrs %lu rx_dropped %lu\n", + bcm_bprintf(strbuf, "rx_ctlpkts %ld rx_ctlerrs %ld rx_dropped %ld\n", dhdp->rx_ctlpkts, dhdp->rx_ctlerrs, dhdp->rx_dropped); - bcm_bprintf(strbuf, "rx_readahead_cnt %lu tx_realloc %lu\n", + bcm_bprintf(strbuf, "rx_readahead_cnt %ld tx_realloc %ld\n", dhdp->rx_readahead_cnt, dhdp->tx_realloc); bcm_bprintf(strbuf, "\n"); @@ -289,27 +311,17 @@ dhd_wl_ioctl_cmd(dhd_pub_t *dhd_pub, int int dhd_wl_ioctl(dhd_pub_t *dhd_pub, int ifindex, wl_ioctl_t *ioc, void *buf, int len) { - int ret = 0; - - if (dhd_os_proto_block(dhd_pub)) - { + int ret; - ret = dhd_prot_ioctl(dhd_pub, ifindex, ioc, buf, len); - if ((ret) && (dhd_pub->up)) - /* Send hang event only if dhd_open() was success */ - dhd_os_check_hang(dhd_pub, ifindex, ret); - - if (ret == -ETIMEDOUT && !dhd_pub->up) { - DHD_ERROR(("%s: 'resumed on timeout' error is " - "occurred before the interface does not" - " bring up\n", __FUNCTION__)); - dhd_pub->busstate = DHD_BUS_DOWN; - } + dhd_os_proto_block(dhd_pub); - dhd_os_proto_unblock(dhd_pub); + ret = dhd_prot_ioctl(dhd_pub, ifindex, ioc, buf, len); + if ((ret) && (dhd_pub->up)) + /* Send hang event only if dhd_open() was success */ + dhd_os_check_hang(dhd_pub, ifindex, ret); + dhd_os_proto_unblock(dhd_pub); - } return ret; } @@ -335,22 +347,47 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bc bcm_strncpy_s((char*)arg, len, dhd_version, len); break; + case IOV_GVAL(IOV_WLMSGLEVEL): + printk("android_msg_level=0x%x\n", android_msg_level); +#if defined(CONFIG_WIRELESS_EXT) + int_val = (int32)iw_msg_level; + bcopy(&int_val, arg, val_size); + printk("iw_msg_level=0x%x\n", iw_msg_level); +#endif +#ifdef WL_CFG80211 + int_val = (int32)wl_dbg_level; + bcopy(&int_val, arg, val_size); + printk("cfg_msg_level=0x%x\n", wl_dbg_level); +#endif + break; + + case IOV_SVAL(IOV_WLMSGLEVEL): +#if defined(CONFIG_WIRELESS_EXT) + if (int_val & DHD_IW_VAL) { + iw_msg_level = (uint)(int_val & 0xFFFF); + printk("iw_msg_level=0x%x\n", iw_msg_level); + } else +#endif +#ifdef WL_CFG80211 + if (int_val & DHD_CFG_VAL) { + wl_cfg80211_enable_trace((u32)(int_val & 0xFFFF)); + } else +#endif + { + android_msg_level = (uint)int_val; + printk("android_msg_level=0x%x\n", android_msg_level); + } + break; + case IOV_GVAL(IOV_MSGLEVEL): int_val = (int32)dhd_msg_level; bcopy(&int_val, arg, val_size); break; case IOV_SVAL(IOV_MSGLEVEL): -#ifdef WL_CFG80211 - /* Enable DHD and WL logs in oneshot */ - if (int_val & DHD_WL_VAL2) - wl_cfg80211_enable_trace(TRUE, int_val & (~DHD_WL_VAL2)); - else if (int_val & DHD_WL_VAL) - wl_cfg80211_enable_trace(FALSE, WL_DBG_DBG); - if (!(int_val & DHD_WL_VAL2)) -#endif /* WL_CFG80211 */ dhd_msg_level = int_val; break; + case IOV_GVAL(IOV_BCMERRORSTR): bcm_strncpy_s((char *)arg, len, bcmerrorstr(dhd_pub->bcmerror), BCME_STRLEN); ((char *)arg)[BCME_STRLEN - 1] = 0x00; @@ -439,6 +476,37 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bc break; } +#ifdef WLBTAMP + case IOV_SVAL(IOV_HCI_CMD): { + amp_hci_cmd_t *cmd = (amp_hci_cmd_t *)arg; + + /* sanity check: command preamble present */ + if (len < HCI_CMD_PREAMBLE_SIZE) + return BCME_BUFTOOSHORT; + + /* sanity check: command parameters are present */ + if (len < (int)(HCI_CMD_PREAMBLE_SIZE + cmd->plen)) + return BCME_BUFTOOSHORT; + + dhd_bta_docmd(dhd_pub, cmd, len); + break; + } + + case IOV_SVAL(IOV_HCI_ACL_DATA): { + amp_hci_ACL_data_t *ACL_data = (amp_hci_ACL_data_t *)arg; + + /* sanity check: HCI header present */ + if (len < HCI_ACL_DATA_PREAMBLE_SIZE) + return BCME_BUFTOOSHORT; + + /* sanity check: ACL data is present */ + if (len < (int)(HCI_ACL_DATA_PREAMBLE_SIZE + ACL_data->dlen)) + return BCME_BUFTOOSHORT; + + dhd_bta_tx_hcidata(dhd_pub, ACL_data, len); + break; + } +#endif /* WLBTAMP */ #ifdef PROP_TXSTATUS case IOV_GVAL(IOV_PROPTXSTATUS_ENABLE): @@ -557,8 +625,7 @@ dhd_prec_enq(dhd_pub_t *dhdp, struct pkt if (pktq_pfull(q, prec)) eprec = prec; else if (pktq_full(q)) { - p = pktq_peek_tail(q, &eprec); - ASSERT(p); + pktq_peek_tail(q, &eprec); if (eprec > prec || eprec < 0) return FALSE; } @@ -578,91 +645,7 @@ dhd_prec_enq(dhd_pub_t *dhdp, struct pkt } /* Enqueue */ - p = pktq_penq(q, prec, pkt); - ASSERT(p); - - return TRUE; -} - -/* - * Functions to drop proper pkts from queue: - * If one pkt in queue is non-fragmented, drop first non-fragmented pkt only - * If all pkts in queue are all fragmented, find and drop one whole set fragmented pkts - * If can't find pkts matching upper 2 cases, drop first pkt anyway - */ -bool -dhd_prec_drop_pkts(osl_t *osh, struct pktq *pq, int prec) -{ - struct pktq_prec *q = NULL; - void *p, *prev = NULL, *next = NULL, *first = NULL, *last = NULL, *prev_first = NULL; - pkt_frag_t frag_info; - - ASSERT(osh && pq); - ASSERT(prec >= 0 && prec < pq->num_prec); - - q = &pq->q[prec]; - p = q->head; - - if (p == NULL) - return FALSE; - - while (p) { - frag_info = pkt_frag_info(osh, p); - if (frag_info == DHD_PKT_FRAG_NONE) { - break; - } else if (frag_info == DHD_PKT_FRAG_FIRST) { - if (first) { - /* No last frag pkt, use prev as last */ - last = prev; - } else { - first = p; - prev_first = prev; - } - } else if (frag_info == DHD_PKT_FRAG_LAST) { - if (first) { - last = p; - break; - } - } - - prev = p; - p = PKTLINK(p); - } - - if ((p == NULL) || ((frag_info != DHD_PKT_FRAG_NONE) && !(first && last))) { - /* Not found matching pkts, use oldest */ - prev = NULL; - p = q->head; - frag_info = 0; - } - - if (frag_info == DHD_PKT_FRAG_NONE) { - first = last = p; - prev_first = prev; - } - - p = first; - while (p) { - next = PKTLINK(p); - q->len--; - pq->len--; - - PKTSETLINK(p, NULL); - - PKTFREE(osh, p, TRUE); - - if (p == last) - break; - - p = next; - } - - if (prev_first == NULL) { - if ((q->head = next) == NULL) - q->tail = NULL; - } else { - PKTSETLINK(prev_first, next); - } + pktq_penq(q, prec, pkt); return TRUE; } @@ -740,7 +723,7 @@ dhd_ioctl(dhd_pub_t * dhd_pub, dhd_ioctl case DHD_GET_VERSION: if (buflen < sizeof(int)) - bcmerror = BCME_BUFTOOSHORT; + bcmerror = -BCME_BUFTOOSHORT; else *(int*)buf = DHD_IOCTL_VERSION; break; @@ -977,7 +960,6 @@ wl_show_host_event(wl_event_msg_t *event case WLC_E_TRACE: { static uint32 seqnum_prev = 0; - static uint32 logtrace_seqnum_prev = 0; msgtrace_hdr_t hdr; uint32 nblost; char *s, *p; @@ -994,72 +976,35 @@ wl_show_host_event(wl_event_msg_t *event break; } - if (hdr.trace_type == MSGTRACE_HDR_TYPE_MSG) { - /* There are 2 bytes available at the end of data */ - buf[MSGTRACE_HDRLEN + ntoh16(hdr.len)] = '\0'; - - if (ntoh32(hdr.discarded_bytes) || ntoh32(hdr.discarded_printf)) { - printf("\nWLC_E_TRACE: [Discarded traces in dongle -->" - "discarded_bytes %d discarded_printf %d]\n", - ntoh32(hdr.discarded_bytes), ntoh32(hdr.discarded_printf)); - } + /* There are 2 bytes available at the end of data */ + buf[MSGTRACE_HDRLEN + ntoh16(hdr.len)] = '\0'; - nblost = ntoh32(hdr.seqnum) - seqnum_prev - 1; - if (nblost > 0) { - printf("\nWLC_E_TRACE: [Event lost (msg) --> seqnum %d nblost %d\n", - ntoh32(hdr.seqnum), nblost); - } - seqnum_prev = ntoh32(hdr.seqnum); - - /* Display the trace buffer. Advance from \n to \n to avoid display big - * printf (issue with Linux printk ) - */ - p = (char *)&buf[MSGTRACE_HDRLEN]; - while (*p != '\0' && (s = strstr(p, "\n")) != NULL) { - *s = '\0'; - printf("%s\n", p); - p = s+1; - } - if (*p) printf("%s", p); - - /* Reset datalen to avoid display below */ - datalen = 0; - - } else if (hdr.trace_type == MSGTRACE_HDR_TYPE_LOG) { - /* Let the standard event printing work for now */ - uint32 timestamp, w; - if (ntoh32(hdr.seqnum) == logtrace_seqnum_prev) { - printf("\nWLC_E_TRACE: [Event duplicate (log) %d", - logtrace_seqnum_prev); - } else { - nblost = ntoh32(hdr.seqnum) - logtrace_seqnum_prev - 1; - if (nblost > 0) { - printf("\nWLC_E_TRACE: [Event lost (log)" - " --> seqnum %d nblost %d\n", - ntoh32(hdr.seqnum), nblost); - } - logtrace_seqnum_prev = ntoh32(hdr.seqnum); - - p = (char *)&buf[MSGTRACE_HDRLEN]; - datalen -= MSGTRACE_HDRLEN; - w = ntoh32((uint32) *p); - p += 4; - datalen -= 4; - timestamp = ntoh32((uint32) *p); - printf("Logtrace %x timestamp %x %x", - logtrace_seqnum_prev, timestamp, w); - - while (datalen > 4) { - p += 4; - datalen -= 4; - /* Print each word. DO NOT ntoh it. */ - printf(" %8.8x", *((uint32 *) p)); - } - printf("\n"); - } - datalen = 0; + if (ntoh32(hdr.discarded_bytes) || ntoh32(hdr.discarded_printf)) { + printf("\nWLC_E_TRACE: [Discarded traces in dongle -->" + "discarded_bytes %d discarded_printf %d]\n", + ntoh32(hdr.discarded_bytes), ntoh32(hdr.discarded_printf)); + } + + nblost = ntoh32(hdr.seqnum) - seqnum_prev - 1; + if (nblost > 0) { + printf("\nWLC_E_TRACE: [Event lost --> seqnum %d nblost %d\n", + ntoh32(hdr.seqnum), nblost); + } + seqnum_prev = ntoh32(hdr.seqnum); + + /* Display the trace buffer. Advance from \n to \n to avoid display big + * printf (issue with Linux printk ) + */ + p = (char *)&buf[MSGTRACE_HDRLEN]; + while ((s = strstr(p, "\n")) != NULL) { + *s = '\0'; + printf("%s\n", p); + p = s+1; } + printf("%s\n", p); + /* Reset datalen to avoid display below */ + datalen = 0; break; } @@ -1071,7 +1016,7 @@ wl_show_host_event(wl_event_msg_t *event case WLC_E_SERVICE_FOUND: case WLC_E_P2PO_ADD_DEVICE: case WLC_E_P2PO_DEL_DEVICE: - DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf)); + DHD_EVENT(("MACEVENT: %s, MAC: %s\n", event_name, eabuf)); break; default: @@ -1082,7 +1027,7 @@ wl_show_host_event(wl_event_msg_t *event } /* show any appended data */ - if (DHD_BYTES_ON() && DHD_EVENT_ON() && datalen) { + if (datalen) { buf = (uchar *) event_data; DHD_EVENT((" data (%d) : ", datalen)); for (i = 0; i < datalen; i++) @@ -1129,10 +1074,8 @@ wl_host_event(dhd_pub_t *dhd_pub, int *i switch (type) { #ifdef PROP_TXSTATUS case WLC_E_FIFO_CREDIT_MAP: - dhd_os_wlfc_block(dhd_pub); dhd_wlfc_event(dhd_pub->info); dhd_wlfc_FIFOcreditmap_event(dhd_pub->info, event_data); - dhd_os_wlfc_unblock(dhd_pub); WLFC_DBGMESG(("WLC_E_FIFO_CREDIT_MAP:(AC0,AC1,AC2,AC3),(BC_MC),(OTHER): " "(%d,%d,%d,%d),(%d),(%d)\n", event_data[0], event_data[1], event_data[2], @@ -1143,13 +1086,6 @@ wl_host_event(dhd_pub_t *dhd_pub, int *i case WLC_E_IF: { dhd_if_event_t *ifevent = (dhd_if_event_t *)event_data; - - /* Ignore the event if NOIF is set */ - if (ifevent->flags & WLC_E_IF_FLAGS_BSSCFG_NOIF) { - WLFC_DBGMESG(("WLC_E_IF: NO_IF set, event Ignored\r\n")); - return (BCME_OK); - } - #ifdef PROP_TXSTATUS { uint8* ea = pvt_data->eth.ether_dhost; @@ -1160,8 +1096,6 @@ wl_host_event(dhd_pub_t *dhd_pub, int *i ((ifevent->is_AP == 0) ? "STA":"AP "), ea[0], ea[1], ea[2], ea[3], ea[4], ea[5])); (void)ea; - - dhd_os_wlfc_block(dhd_pub); if (ifevent->action == WLC_E_IF_CHANGE) dhd_wlfc_interface_event(dhd_pub->info, eWLFC_MAC_ENTRY_ACTION_UPDATE, @@ -1171,7 +1105,7 @@ wl_host_event(dhd_pub_t *dhd_pub, int *i ((ifevent->action == WLC_E_IF_ADD) ? eWLFC_MAC_ENTRY_ACTION_ADD : eWLFC_MAC_ENTRY_ACTION_DEL), ifevent->ifidx, ifevent->is_AP, ea); - dhd_os_wlfc_unblock(dhd_pub); + /* dhd already has created an interface by default, for 0 */ if (ifevent->ifidx == 0) @@ -1225,22 +1159,17 @@ wl_host_event(dhd_pub_t *dhd_pub, int *i htsf_update(dhd_pub->info, event_data); break; #endif /* WLMEDIA_HTSF */ +#if defined(NDIS630) + case WLC_E_NDIS_LINK: + break; +#else /* defined(NDIS630) && defined(BCMDONGLEHOST) */ case WLC_E_NDIS_LINK: { uint32 temp = hton32(WLC_E_LINK); memcpy((void *)(&pvt_data->event.event_type), &temp, sizeof(pvt_data->event.event_type)); } - case WLC_E_PFN_NET_FOUND: - case WLC_E_PFN_NET_LOST: - break; - case WLC_E_PFN_BSSID_NET_FOUND: - case WLC_E_PFN_BSSID_NET_LOST: - case WLC_E_PFN_BEST_BATCHING: -#ifdef PNO_SUPPORT - dhd_pno_event_handler(dhd_pub, event, (void *)event_data); -#endif - break; +#endif /* These are what external supplicant/authenticator wants */ /* fall through */ case WLC_E_LINK: @@ -1561,19 +1490,6 @@ fail: if (buf) MFREE(dhd->osh, buf, BUF_SIZE); } - -void dhd_pktfilter_offload_delete(dhd_pub_t *dhd, int id) -{ - char iovbuf[32]; - int ret; - - bcm_mkiovar("pkt_filter_delete", (char *)&id, 4, iovbuf, sizeof(iovbuf)); - ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); - if (ret < 0) { - DHD_ERROR(("%s: Failed to delete filter ID:%d, ret=%d\n", - __FUNCTION__, id, ret)); - } -} #endif /* PKT_FILTER_SUPPORT */ /* ========================== */ @@ -1634,14 +1550,14 @@ dhd_aoe_arp_clr(dhd_pub_t *dhd, int idx) { int ret = 0; int iov_len = 0; - char iovbuf[DHD_IOVAR_BUF_SIZE]; + char iovbuf[128]; if (dhd == NULL) return; if (dhd->arp_version == 1) idx = 0; iov_len = bcm_mkiovar("arp_table_clear", 0, 0, iovbuf, sizeof(iovbuf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, iov_len, TRUE, idx)) < 0) + if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, iov_len, TRUE, idx) < 0)) DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret)); } @@ -1650,7 +1566,7 @@ dhd_aoe_hostip_clr(dhd_pub_t *dhd, int i { int ret = 0; int iov_len = 0; - char iovbuf[DHD_IOVAR_BUF_SIZE]; + char iovbuf[128]; if (dhd == NULL) return; if (dhd->arp_version == 1) @@ -1665,7 +1581,7 @@ void dhd_arp_offload_add_ip(dhd_pub_t *dhd, uint32 ipaddr, int idx) { int iov_len = 0; - char iovbuf[DHD_IOVAR_BUF_SIZE]; + char iovbuf[32]; int retcode; @@ -1724,91 +1640,15 @@ dhd_arp_get_arp_hostip_table(dhd_pub_t * } #endif /* ARP_OFFLOAD_SUPPORT */ -/* - * Neighbor Discovery Offload: enable NDO feature - * Called by ipv6 event handler when interface comes up/goes down - */ -int -dhd_ndo_enable(dhd_pub_t *dhd, int ndo_enable) -{ - char iovbuf[DHD_IOVAR_BUF_SIZE]; - int retcode; - - if (dhd == NULL) - return -1; - - bcm_mkiovar("ndoe", (char *)&ndo_enable, 4, iovbuf, sizeof(iovbuf)); - retcode = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); - if (retcode) - DHD_ERROR(("%s: failed to enabe ndo to %d, retcode = %d\n", - __FUNCTION__, ndo_enable, retcode)); - else - DHD_TRACE(("%s: successfully enabed ndo offload to %d\n", - __FUNCTION__, ndo_enable)); - - return retcode; -} - -/* - * Neighbor Discover Offload: add host ipv6 ip into firmware - * Called by ipv6 event handler when interface comes up - */ -int -dhd_ndo_add_ip(dhd_pub_t *dhd, char *ipv6addr, int idx) -{ - int iov_len = 0; - char iovbuf[DHD_IOVAR_BUF_SIZE]; - int retcode; - - if (dhd == NULL || ipv6addr == NULL) - return -1; - - iov_len = bcm_mkiovar("nd_hostip", ipv6addr, - IPV6_ADDR_LEN, iovbuf, sizeof(iovbuf)); - retcode = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, iov_len, TRUE, idx); - - if (retcode) - DHD_ERROR(("%s: ndo ip addr add failed, retcode = %d\n", - __FUNCTION__, retcode)); - else - DHD_ERROR(("%s: ndo ipaddr entry added \n", - __FUNCTION__)); - return retcode; -} - -/* - * Neighbor Discover Offload: disable NDO feature - * Called by ipv6 event handler when interface goes down - */ -int -dhd_ndo_remove_ip(dhd_pub_t *dhd, int idx) -{ - int iov_len = 0; - char iovbuf[DHD_IOVAR_BUF_SIZE]; - int retcode; - - if (dhd == NULL) - return -1; - - iov_len = bcm_mkiovar("nd_hostip_clear", (char *)NULL, - 0, iovbuf, sizeof(iovbuf)); - retcode = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, iov_len, TRUE, idx); - - if (retcode) - DHD_ERROR(("%s: ndo ip addr remove failed, retcode = %d\n", - __FUNCTION__, retcode)); - else - DHD_TRACE(("%s: ndo ipaddr entry removed \n", - __FUNCTION__)); - - return retcode; -} - /* send up locally generated event */ 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; } @@ -1861,68 +1701,48 @@ bool dhd_is_associated(dhd_pub_t *dhd, v int dhd_get_suspend_bcn_li_dtim(dhd_pub_t *dhd) { - int bcn_li_dtim = 1; /* deafult no dtim skip setting */ + int bcn_li_dtim; int ret = -1; - int dtim_period = 0; - int ap_beacon = 0; - int allowed_skip_dtim_cnt = 0; + int dtim_assoc = 0; + + bcn_li_dtim = dhd->suspend_bcn_li_dtim; + /* Check if associated */ if (dhd_is_associated(dhd, NULL, NULL) == FALSE) { DHD_TRACE(("%s NOT assoc ret %d\n", __FUNCTION__, ret)); goto exit; } - /* read associated AP beacon interval */ - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_BCNPRD, - &ap_beacon, sizeof(ap_beacon), FALSE, 0)) < 0) { - DHD_ERROR(("%s get beacon failed code %d\n", __FUNCTION__, ret)); - goto exit; - } - - /* if associated APs Beacon more that 100msec do no dtim skip */ - if (ap_beacon > MAX_DTIM_SKIP_BEACON_INTERVAL) { - DHD_ERROR(("%s NO dtim skip for AP with beacon %d ms\n", __FUNCTION__, ap_beacon)); - goto exit; - } - - /* read associated ap's dtim setup */ + /* if assoc grab ap's dtim value */ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_DTIMPRD, - &dtim_period, sizeof(dtim_period), FALSE, 0)) < 0) { + &dtim_assoc, sizeof(dtim_assoc), FALSE, 0)) < 0) { DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret)); goto exit; } + DHD_ERROR(("%s bcn_li_dtim=%d DTIM=%d Listen=%d\n", + __FUNCTION__, bcn_li_dtim, dtim_assoc, LISTEN_INTERVAL)); + /* if not assocated just eixt */ - if (dtim_period == 0) { + if (dtim_assoc == 0) { goto exit; } - /* attemp to use platform defined dtim skip interval */ - bcn_li_dtim = dhd->suspend_bcn_li_dtim; - /* check if sta listen interval fits into AP dtim */ - if (dtim_period > CUSTOM_LISTEN_INTERVAL) { + if (dtim_assoc > LISTEN_INTERVAL) { /* AP DTIM to big for our Listen Interval : no dtim skiping */ - bcn_li_dtim = NO_DTIM_SKIP; + bcn_li_dtim = 1; DHD_ERROR(("%s DTIM=%d > Listen=%d : too big ...\n", - __FUNCTION__, dtim_period, CUSTOM_LISTEN_INTERVAL)); + __FUNCTION__, dtim_assoc, LISTEN_INTERVAL)); goto exit; } - if ((dtim_period * ap_beacon * bcn_li_dtim) > MAX_DTIM_ALLOWED_INTERVAL) { - allowed_skip_dtim_cnt = MAX_DTIM_ALLOWED_INTERVAL / (dtim_period * ap_beacon); - bcn_li_dtim = (allowed_skip_dtim_cnt != 0) ? allowed_skip_dtim_cnt : NO_DTIM_SKIP; - } - - if ((bcn_li_dtim * dtim_period) > CUSTOM_LISTEN_INTERVAL) { + if ((bcn_li_dtim * dtim_assoc) > LISTEN_INTERVAL) { /* Round up dtim_skip to fit into STAs Listen Interval */ - bcn_li_dtim = (int)(CUSTOM_LISTEN_INTERVAL / dtim_period); + bcn_li_dtim = (int)(LISTEN_INTERVAL / dtim_assoc); DHD_TRACE(("%s agjust dtim_skip as %d\n", __FUNCTION__, bcn_li_dtim)); } - DHD_ERROR(("%s beacon=%d bcn_li_dtim=%d DTIM=%d Listen=%d\n", - __FUNCTION__, ap_beacon, bcn_li_dtim, dtim_period, CUSTOM_LISTEN_INTERVAL)); - exit: return bcn_li_dtim; } @@ -1939,12 +1759,213 @@ bool dhd_support_sta_mode(dhd_pub_t *dhd return TRUE; } +#if defined(PNO_SUPPORT) +int +dhd_pno_clean(dhd_pub_t *dhd) +{ + char iovbuf[128]; + int pfn_enabled = 0; + int iov_len = 0; + int ret; + + /* Disable pfn */ + iov_len = bcm_mkiovar("pfn", (char *)&pfn_enabled, 4, iovbuf, sizeof(iovbuf)); + if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) >= 0) { + /* clear pfn */ + iov_len = bcm_mkiovar("pfnclear", 0, 0, iovbuf, sizeof(iovbuf)); + if (iov_len) { + if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, + iov_len, TRUE, 0)) < 0) { + DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret)); + } + } + else { + ret = -1; + DHD_ERROR(("%s failed code %d\n", __FUNCTION__, iov_len)); + } + } + else + DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret)); + + return ret; +} + +int +dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled) +{ + char iovbuf[128]; + int ret = -1; + + if ((!dhd) && ((pfn_enabled != 0) || (pfn_enabled != 1))) { + DHD_ERROR(("%s error exit\n", __FUNCTION__)); + return ret; + } + +#ifndef WL_SCHED_SCAN + if (!dhd_support_sta_mode(dhd)) + return (ret); + + memset(iovbuf, 0, sizeof(iovbuf)); + + if ((pfn_enabled) && (dhd_is_associated(dhd, NULL, NULL) == TRUE)) { + DHD_ERROR(("%s pno is NOT enable : called in assoc mode , ignore\n", __FUNCTION__)); + return ret; + } +#endif /* !WL_SCHED_SCAN */ + + /* Enable/disable PNO */ + if ((ret = bcm_mkiovar("pfn", (char *)&pfn_enabled, 4, iovbuf, sizeof(iovbuf))) > 0) { + if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, + iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) { + DHD_ERROR(("%s failed for error=%d\n", __FUNCTION__, ret)); + return ret; + } + else { + dhd->pno_enable = pfn_enabled; + DHD_TRACE(("%s set pno as %s\n", + __FUNCTION__, dhd->pno_enable ? "Enable" : "Disable")); + } + } + else DHD_ERROR(("%s failed err=%d\n", __FUNCTION__, ret)); + + return ret; +} + +/* Function to execute combined scan */ +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) +{ + int err = -1; + char iovbuf[128]; + int k, i; + wl_pfn_param_t pfn_param; + wl_pfn_t pfn_element; + uint len = 0; + + DHD_TRACE(("%s nssid=%d nchan=%d\n", __FUNCTION__, nssid, scan_fr)); + + if ((!dhd) || (!ssids_local)) { + DHD_ERROR(("%s error exit(%s %s)\n", __FUNCTION__, + (!dhd)?"dhd is null":"", (!ssids_local)?"ssid is null":"")); + err = -1; + return err; + } +#ifndef WL_SCHED_SCAN + if (!dhd_support_sta_mode(dhd)) + return err; +#endif /* !WL_SCHED_SCAN */ + + /* Check for broadcast ssid */ + for (k = 0; k < nssid; k++) { + if (!ssids_local[k].SSID_len) { + DHD_ERROR(("%d: Broadcast SSID is ilegal for PNO setting\n", k)); + return err; + } + } +/* #define PNO_DUMP 1 */ +#ifdef PNO_DUMP + { + int j; + for (j = 0; j < nssid; j++) { + DHD_ERROR(("%d: scan for %s size =%d\n", j, + ssids_local[j].SSID, ssids_local[j].SSID_len)); + } + } +#endif /* PNO_DUMP */ + + /* clean up everything */ + if ((err = dhd_pno_clean(dhd)) < 0) { + DHD_ERROR(("%s failed error=%d\n", __FUNCTION__, err)); + return err; + } + memset(iovbuf, 0, sizeof(iovbuf)); + memset(&pfn_param, 0, sizeof(pfn_param)); + memset(&pfn_element, 0, sizeof(pfn_element)); + + /* set pfn parameters */ + pfn_param.version = htod32(PFN_VERSION); + pfn_param.flags = htod16((PFN_LIST_ORDER << SORT_CRITERIA_BIT)); + + /* check and set extra pno params */ + if ((pno_repeat != 0) || (pno_freq_expo_max != 0)) { + pfn_param.flags |= htod16(ENABLE << ENABLE_ADAPTSCAN_BIT); + pfn_param.repeat = (uchar) (pno_repeat); + pfn_param.exp = (uchar) (pno_freq_expo_max); + } + /* set up pno scan fr */ + if (scan_fr != 0) + pfn_param.scan_freq = htod32(scan_fr); + + if (pfn_param.scan_freq > PNO_SCAN_MAX_FW_SEC) { + DHD_ERROR(("%s pno freq above %d sec\n", __FUNCTION__, PNO_SCAN_MAX_FW_SEC)); + return err; + } + if (pfn_param.scan_freq < PNO_SCAN_MIN_FW_SEC) { + DHD_ERROR(("%s pno freq less %d sec\n", __FUNCTION__, PNO_SCAN_MIN_FW_SEC)); + return err; + } + + len = bcm_mkiovar("pfn_set", (char *)&pfn_param, sizeof(pfn_param), iovbuf, sizeof(iovbuf)); + if ((err = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, len, TRUE, 0)) < 0) { + DHD_ERROR(("%s pfn_set failed for error=%d\n", + __FUNCTION__, err)); + return err; + } + + /* set all pfn ssid */ + for (i = 0; i < nssid; i++) { + + pfn_element.infra = htod32(DOT11_BSSTYPE_INFRASTRUCTURE); + pfn_element.auth = (DOT11_OPEN_SYSTEM); + pfn_element.wpa_auth = htod32(WPA_AUTH_PFN_ANY); + pfn_element.wsec = htod32(0); + pfn_element.infra = htod32(1); + pfn_element.flags = htod32(ENABLE << WL_PFN_HIDDEN_BIT); + memcpy((char *)pfn_element.ssid.SSID, ssids_local[i].SSID, ssids_local[i].SSID_len); + pfn_element.ssid.SSID_len = ssids_local[i].SSID_len; + + if ((len = + bcm_mkiovar("pfn_add", (char *)&pfn_element, + sizeof(pfn_element), iovbuf, sizeof(iovbuf))) > 0) { + if ((err = + dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, len, TRUE, 0)) < 0) { + DHD_ERROR(("%s failed for i=%d error=%d\n", + __FUNCTION__, i, err)); + return err; + } + else + DHD_TRACE(("%s set OK with PNO time=%d repeat=%d max_adjust=%d\n", + __FUNCTION__, pfn_param.scan_freq, + pfn_param.repeat, pfn_param.exp)); + } + else DHD_ERROR(("%s failed err=%d\n", __FUNCTION__, err)); + } + + /* Enable PNO */ + /* dhd_pno_enable(dhd, 1); */ + return err; +} + +int +dhd_pno_get_status(dhd_pub_t *dhd) +{ + int ret = -1; + + if (!dhd) + return ret; + else + return (dhd->pno_enable); +} + +#endif /* OEM_ANDROID && PNO_SUPPORT */ + #if defined(KEEP_ALIVE) int dhd_keep_alive_onoff(dhd_pub_t *dhd) { char buf[256]; const char *str; - wl_mkeep_alive_pkt_t mkeep_alive_pkt = {0}; + wl_mkeep_alive_pkt_t mkeep_alive_pkt; wl_mkeep_alive_pkt_t *mkeep_alive_pktp; int buf_len; int str_len; diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/dhd_custom_gpio.c linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_custom_gpio.c --- linux-sunxi/drivers/net/wireless/bcmdhd/dhd_custom_gpio.c 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_custom_gpio.c 2014-02-15 00:43:44.795014136 +0100 @@ -1,6 +1,6 @@ /* * Customer code to add GPIO control during WLAN start/stop -* Copyright (C) 1999-2013, Broadcom Corporation +* 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 @@ -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 417465 2013-08-09 11:47:27Z $ +* $Id: dhd_custom_gpio.c 353167 2012-08-24 22:11:30Z $ */ #include @@ -34,16 +34,24 @@ #include #include +#include +#include + #define WL_ERROR(x) printf x -#define WL_TRACE(x) +#define WL_TRACE(x) printf x + +extern void sunximmc_rescan_card(unsigned id, unsigned insert); +extern void wifi_pm_power(int on); #ifdef CUSTOMER_HW +#include +#if defined(CUSTOMER_OOB) +extern int bcm_wlan_get_oob_irq(void); +#endif extern void bcm_wlan_power_off(int); extern void bcm_wlan_power_on(int); #endif /* CUSTOMER_HW */ #if defined(CUSTOMER_HW2) - - #ifdef CONFIG_WIFI_CONTROL_FUNC int wifi_set_power(int on, unsigned long msec); int wifi_get_irq_number(unsigned long *irq_flags_ptr); @@ -63,12 +71,12 @@ void *wifi_get_country_code(char *ccode) extern int sdioh_mmc_irq(int irq); #endif /* (BCMLXSDMMC) */ -#if defined(CUSTOMER_HW3) +#ifdef CUSTOMER_HW3 #include #endif /* Customer specific Host GPIO defintion */ -static int dhd_oob_gpio_num = -1; +static int dhd_oob_gpio_num = 2; module_param(dhd_oob_gpio_num, int, 0644); MODULE_PARM_DESC(dhd_oob_gpio_num, "DHD oob gpio number"); @@ -86,11 +94,14 @@ MODULE_PARM_DESC(dhd_oob_gpio_num, "DHD */ int dhd_customer_oob_irq_map(unsigned long *irq_flags_ptr) { - int host_oob_irq = 0; + int host_oob_irq = -1; #if defined(CUSTOMER_HW2) host_oob_irq = wifi_get_irq_number(irq_flags_ptr); +#elif defined(CUSTOMER_OOB) + host_oob_irq = bcm_wlan_get_oob_irq(); + pr_info("bcmdhd: irq=%d, flags=0x%08lx\n", host_oob_irq, *irq_flags_ptr); #else #if defined(CUSTOM_OOB_GPIO_NUM) if (dhd_oob_gpio_num < 0) { @@ -108,7 +119,7 @@ int dhd_customer_oob_irq_map(unsigned lo __FUNCTION__, dhd_oob_gpio_num)); #if defined CUSTOMER_HW - host_oob_irq = MSM_GPIO_TO_INT(dhd_oob_gpio_num); + pr_err("%s: should not be here!\n", __FUNCTION__); #elif defined CUSTOMER_HW3 gpio_request(dhd_oob_gpio_num, "oob irq"); host_oob_irq = gpio_to_irq(dhd_oob_gpio_num); @@ -124,16 +135,19 @@ int dhd_customer_oob_irq_map(unsigned lo void dhd_customer_gpio_wlan_ctrl(int onoff) { + static int sdc_id = 3; + switch (onoff) { case WLAN_RESET_OFF: WL_TRACE(("%s: call customer specific GPIO to insert WLAN RESET\n", __FUNCTION__)); #ifdef CUSTOMER_HW - bcm_wlan_power_off(2); + wifi_pm_power(0); #endif /* CUSTOMER_HW */ #if defined(CUSTOMER_HW2) - wifi_set_power(0, WIFI_TURNOFF_DELAY); + wifi_set_power(0, 0); #endif + mdelay(100); WL_ERROR(("=========== WLAN placed in RESET ========\n")); break; @@ -141,11 +155,12 @@ dhd_customer_gpio_wlan_ctrl(int onoff) WL_TRACE(("%s: callc customer specific GPIO to remove WLAN RESET\n", __FUNCTION__)); #ifdef CUSTOMER_HW - bcm_wlan_power_on(2); + wifi_pm_power(1); #endif /* CUSTOMER_HW */ #if defined(CUSTOMER_HW2) wifi_set_power(1, 0); #endif + mdelay(100); WL_ERROR(("=========== WLAN going back to live ========\n")); break; @@ -153,18 +168,22 @@ dhd_customer_gpio_wlan_ctrl(int onoff) WL_TRACE(("%s: call customer specific GPIO to turn off WL_REG_ON\n", __FUNCTION__)); #ifdef CUSTOMER_HW - bcm_wlan_power_off(1); + wifi_pm_power(0); + sunximmc_rescan_card(sdc_id, 0); #endif /* CUSTOMER_HW */ + WL_ERROR(("=========== WLAN placed in POWER OFF ========\n")); break; case WLAN_POWER_ON: WL_TRACE(("%s: call customer specific GPIO to turn on WL_REG_ON\n", __FUNCTION__)); #ifdef CUSTOMER_HW - bcm_wlan_power_on(1); + wifi_pm_power(1); + sunximmc_rescan_card(sdc_id, 1); /* Lets customer power to get stable */ - OSL_DELAY(200); #endif /* CUSTOMER_HW */ + mdelay(100); + WL_ERROR(("=========== WLAN placed in POWER ON ========\n")); break; } } diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/dhd_dbg.h linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_dbg.h --- linux-sunxi/drivers/net/wireless/bcmdhd/dhd_dbg.h 2014-01-27 01:30:30.108433411 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_dbg.h 2014-02-15 00:43:44.795014136 +0100 @@ -1,7 +1,7 @@ /* * Debug/trace/assert driver definitions for Dongle Host Driver. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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 419132 2013-08-19 21:33:05Z $ + * $Id: dhd_dbg.h 353490 2012-08-27 21:10:02Z $ */ #ifndef _dhd_dbg_ @@ -47,7 +47,6 @@ #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_PNO(args) do {if (dhd_msg_level & DHD_PNO_VAL) printf args;} while (0) #define DHD_TRACE_HW4 DHD_TRACE @@ -66,8 +65,6 @@ #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) -#define DHD_NOCHECKDIED_ON() (dhd_msg_level & DHD_NOCHECKDIED_VAL) -#define DHD_PNO_ON() (dhd_msg_level & DHD_PNO_VAL) #else /* defined(BCMDBG) || defined(DHD_DEBUG) */ @@ -86,7 +83,6 @@ #define DHD_ISCAN(args) #define DHD_ARPOE(args) #define DHD_REORDER(args) -#define DHD_PNO(args) #define DHD_TRACE_HW4 DHD_TRACE @@ -105,9 +101,6 @@ #define DHD_ISCAN_ON() 0 #define DHD_ARPOE_ON() 0 #define DHD_REORDER_ON() 0 -#define DHD_NOCHECKDIED_ON() 0 -#define DHD_PNO_ON() 0 - #endif #define DHD_LOG(args) diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/dhd_gpio.c linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_gpio.c --- linux-sunxi/drivers/net/wireless/bcmdhd/dhd_gpio.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_gpio.c 2014-02-15 00:43:44.795014136 +0100 @@ -0,0 +1,47 @@ +/* +* Customer code to add GPIO control during WLAN start/stop +* Copyright (C) 1999-2011, 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: dhd_custom_gpio.c,v 1.2.42.1 2010-10-19 00:41:09 Exp $ +*/ + +#include + +#include +#include + +#ifdef CUSTOMER_HW + +extern int __gpio_to_irq(unsigned gpio); +extern int gpio_direction_input(unsigned gpio); +extern int gpio_request(unsigned gpio, const char *label); +extern void gpio_free(unsigned gpio); + +#ifdef CUSTOMER_OOB +extern int wl_host_wake_irqno; +int bcm_wlan_get_oob_irq(void) +{ + return wl_host_wake_irqno; +} +#endif + + +#endif /* CUSTOMER_HW */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/dhd.h linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd.h --- linux-sunxi/drivers/net/wireless/bcmdhd/dhd.h 2014-01-27 01:30:30.108433411 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd.h 2014-02-15 00:43:44.795014136 +0100 @@ -4,7 +4,7 @@ * Provides type definitions and function prototypes used to link the * DHD OS, bus, and protocol modules. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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 419132 2013-08-19 21:33:05Z $ + * $Id: dhd.h 373887 2012-12-10 21:58:02Z $ */ /**************** @@ -43,7 +43,6 @@ #include #include #include -#include #include #include #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_HAS_WAKELOCK) @@ -59,22 +58,11 @@ int setScheduler(struct task_struct *p, #include #include -#if 0 && (0>= 0x0600) -#include -#include -#endif -#if defined(KEEP_ALIVE) -/* Default KEEP_ALIVE Period is 55 sec to prevent AP from sending Keep Alive probe frame */ -#define KEEP_ALIVE_PERIOD 55000 -#define NULL_PKT_STR "null_pkt" -#endif /* KEEP_ALIVE */ /* Forward decls */ struct dhd_bus; struct dhd_prot; struct dhd_info; -struct dhd_ioctl; -struct dhd_cmn; /* The level of bus communication with the dongle */ enum dhd_bus_state { @@ -83,41 +71,26 @@ enum dhd_bus_state { DHD_BUS_DATA /* Ready for frame transfers */ }; -#if 0 && (0>= 0x0600) -/* Firmware requested operation mode */ -#define STA_MASK 0x0001 -#define HOSTAPD_MASK 0x0002 -#define WFD_MASK 0x0004 -#define SOFTAP_FW_MASK 0x0008 -#define P2P_GO_ENABLED 0x0010 -#define P2P_GC_ENABLED 0x0020 -#define CONCURENT_MASK 0x00F0 -#endif - enum dhd_op_flags { /* Firmware requested operation mode */ - DHD_FLAG_STA_MODE = (1 << (0)), /* STA only */ - DHD_FLAG_HOSTAP_MODE = (1 << (1)), /* SOFTAP only */ - DHD_FLAG_P2P_MODE = (1 << (2)), /* P2P Only */ + DHD_FLAG_STA_MODE = BIT(0), /* STA only */ + DHD_FLAG_HOSTAP_MODE = BIT(1), /* SOFTAP only */ + DHD_FLAG_P2P_MODE = BIT(2), /* P2P Only */ /* STA + P2P */ DHD_FLAG_CONCURR_SINGLE_CHAN_MODE = (DHD_FLAG_STA_MODE | DHD_FLAG_P2P_MODE), - DHD_FLAG_CONCURR_MULTI_CHAN_MODE = (1 << (4)), /* STA + P2P */ + DHD_FLAG_CONCURR_MULTI_CHAN_MODE = BIT(4), /* STA + P2P */ /* Current P2P mode for P2P connection */ - DHD_FLAG_P2P_GC_MODE = (1 << (5)), - DHD_FLAG_P2P_GO_MODE = (1 << (6)), - DHD_FLAG_MBSS_MODE = (1 << (7)), /* MBSS in future */ - DHD_FLAG_IBSS_MODE = (1 << (8)) + DHD_FLAG_P2P_GC_MODE = BIT(5), + DHD_FLAG_P2P_GO_MODE = BIT(6), + DHD_FLAG_MBSS_MODE = BIT(7) /* MBSS in future */ }; #define MANUFACTRING_FW "WLTEST" -/* Max sequential TX/RX Control timeouts to set HANG event */ -#ifndef MAX_CNTL_TX_TIMEOUT -#define MAX_CNTL_TX_TIMEOUT 2 -#endif /* MAX_CNTL_TX_TIMEOUT */ -#ifndef MAX_CNTL_RX_TIMEOUT -#define MAX_CNTL_RX_TIMEOUT 1 -#endif /* MAX_CNTL_RX_TIMEOUT */ +/* max sequential rxcntl timeouts to set HANG event */ +#ifndef MAX_CNTL_TIMEOUT +#define MAX_CNTL_TIMEOUT 2 +#endif #define DHD_SCAN_ASSOC_ACTIVE_TIME 40 /* ms: Embedded default Active setting from DHD */ #define DHD_SCAN_UNASSOC_ACTIVE_TIME 80 /* ms: Embedded def. Unassoc Active setting from DHD */ @@ -127,7 +100,7 @@ enum dhd_op_flags { #define POWERUP_MAX_RETRY 3 /* 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 */ +#define POWERUP_WAIT_MS 2000 /* ms: time out in waiting wifi to come up */ #endif enum dhd_bus_wake_state { @@ -143,18 +116,20 @@ enum dhd_bus_wake_state { WAKE_LOCK_SOFTAP_SET, WAKE_LOCK_SOFTAP_STOP, WAKE_LOCK_SOFTAP_START, - WAKE_LOCK_SOFTAP_THREAD + WAKE_LOCK_SOFTAP_THREAD, + WAKE_LOCK_MAX }; enum dhd_prealloc_index { DHD_PREALLOC_PROT = 0, DHD_PREALLOC_RXBUF, DHD_PREALLOC_DATABUF, - DHD_PREALLOC_OSL_BUF, #if defined(STATIC_WL_PRIV_STRUCT) + DHD_PREALLOC_OSL_BUF, DHD_PREALLOC_WIPHY_ESCAN0 = 5, +#else + DHD_PREALLOC_OSL_BUF #endif /* STATIC_WL_PRIV_STRUCT */ - DHD_PREALLOC_DHD_INFO = 7 }; typedef enum { @@ -166,13 +141,6 @@ typedef enum { } dhd_if_state_t; -typedef enum { - DHD_IPV6_ADDR_NONE = 0, - DHD_IPV6_ADDR_ADD, - DHD_IPV6_ADDR_DELETE -} dhd_ipv6_op_t; - - #if defined(CONFIG_DHD_USE_STATIC_BUF) uint8* dhd_os_prealloc(void *osh, int section, uint size); @@ -203,19 +171,6 @@ typedef struct reorder_info { uint8 pend_pkts; } reorder_info_t; -#ifdef DHDTCPACK_SUPPRESS -#define MAXTCPSTREAMS 4 /* Keep this to be power of 2 */ -typedef struct tcp_ack_info { - void *p_tcpackinqueue; - uint32 tcpack_number; - uint ip_tcp_ttllen; - uint8 ipaddrs[8]; /* Each 4bytes src and dst IP addrs */ - uint8 tcpports[4]; /* Each 2bytes src and dst port number */ -} tcp_ack_info_t; - -void dhd_onoff_tcpack_sup(void *pub, bool on); -#endif /* DHDTCPACK_SUPPRESS */ - /* Common structure for module and instance linkage */ typedef struct dhd_pub { /* Linkage ponters */ @@ -223,7 +178,6 @@ typedef struct dhd_pub { struct dhd_bus *bus; /* Bus module handle */ struct dhd_prot *prot; /* Protocol module handle */ struct dhd_info *info; /* Info module handle */ - struct dhd_cmn *cmn; /* dhd_common module handle */ /* Internal dhd items */ bool up; /* Driver up/down (to OS) */ @@ -272,6 +226,10 @@ typedef struct dhd_pub { /* 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 */ +#ifdef PNO_SUPPORT + int pno_enable; /* pno status : "1" is pno enable */ + int pno_suspend; /* pno suspend status : "1" is pno suspended */ +#endif /* PNO_SUPPORT */ /* DTIM skip value, default 0(or 1) means wake each DTIM * 3 means skip 2 DTIMs and wake up 3rd DTIM(9th beacon when AP DTIM is 3) */ @@ -293,64 +251,34 @@ typedef struct dhd_pub { * For ICS MR1 releases it should be disable to be compatable with ICS MR1 Framework * see target dhd-cdc-sdmmc-panda-cfg80211-icsmr1-gpl-debug in Makefile */ +/* #define WL_ENABLE_P2P_IF 1 */ #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; - int ptx_opt_enabled; - bool pending_tx_pkts; - - /* - * implement below functions in each platform if needed. - */ - /* platform specific function whether to skip flow control */ - bool (*skip_fc)(void); - /* platform specific function for wlfc_enable and wlfc_deinit */ - void (*plat_enable)(void *dhd); - void (*plat_deinit)(void *dhd); -#endif -#ifdef PNO_SUPPORT - void *pno_state; -#endif -#ifdef ROAM_AP_ENV_DETECTION - bool roam_env_detection; + int wlfc_enabled; + void* wlfc_state; #endif bool dongle_isolation; bool dongle_trap_occured; /* flag for sending HANG event to upper layer */ int hang_was_sent; int rxcnt_timeout; /* counter rxcnt timeout to send HANG */ int txcnt_timeout; /* counter txcnt timeout to send HANG */ - bool hang_report; /* enable hang report by default */ #ifdef WLMEDIA_HTSF uint8 htsfdlystat_sz; /* Size of delay stats, max 255B */ #endif -#ifdef WLTDLS - bool tdls_enable; -#endif struct reorder_info *reorder_bufs[WLHOST_REORDERDATA_MAXFLOWS]; - char fw_capabilities[WLC_IOCTL_SMLEN]; -#ifdef RXFRAME_THREAD -#define MAXSKBPEND 1024 - void *skbbuf[MAXSKBPEND]; - uint32 store_idx; - uint32 sent_idx; -#endif /* RXFRAME_THREAD */ -#ifdef DHDTCPACK_SUPPRESS - int tcp_ack_info_cnt; - tcp_ack_info_t tcp_ack_info_tbl[MAXTCPSTREAMS]; -#endif /* DHDTCPACK_SUPPRESS */ +#if defined(ARP_OFFLOAD_SUPPORT) uint32 arp_version; +#endif } dhd_pub_t; -typedef struct dhd_cmn { - osl_t *osh; /* OSL handle */ - dhd_pub_t *dhd; -} dhd_cmn_t; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) @@ -399,11 +327,6 @@ typedef struct dhd_cmn { #undef SPINWAIT_SLEEP #define SPINWAIT_SLEEP(a, exp, us) SPINWAIT(exp, us) #endif /* DHDTHREAD */ - -#ifndef OSL_SLEEP -#define OSL_SLEEP(ms) OSL_DELAY(ms*1000) -#endif /* OSL_SLEEP */ - #define DHD_IF_VIF 0x01 /* Virtual IF (Hidden from user) */ unsigned long dhd_os_spin_lock(dhd_pub_t *pub); @@ -415,7 +338,6 @@ extern int dhd_os_wake_unlock(dhd_pub_t extern int dhd_os_wake_lock_timeout(dhd_pub_t *pub); extern int dhd_os_wake_lock_rx_timeout_enable(dhd_pub_t *pub, int val); extern int dhd_os_wake_lock_ctrl_timeout_enable(dhd_pub_t *pub, int val); -extern int dhd_os_wake_lock_ctrl_timeout_cancel(dhd_pub_t *pub); extern int dhd_os_wd_wake_lock(dhd_pub_t *pub); extern int dhd_os_wd_wake_unlock(dhd_pub_t *pub); @@ -441,7 +363,7 @@ inline static void MUTEX_UNLOCK_SOFTAP_S } #define DHD_OS_WAKE_LOCK(pub) dhd_os_wake_lock(pub) -#define DHD_OS_WAKE_UNLOCK(pub) dhd_os_wake_unlock(pub) +#define DHD_OS_WAKE_UNLOCK(pub) dhd_os_wake_unlock(pub) #define DHD_OS_WD_WAKE_LOCK(pub) dhd_os_wd_wake_lock(pub) #define DHD_OS_WD_WAKE_UNLOCK(pub) dhd_os_wd_wake_unlock(pub) #define DHD_OS_WAKE_LOCK_TIMEOUT(pub) dhd_os_wake_lock_timeout(pub) @@ -449,9 +371,7 @@ inline static void MUTEX_UNLOCK_SOFTAP_S dhd_os_wake_lock_rx_timeout_enable(pub, val) #define DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE(pub, val) \ dhd_os_wake_lock_ctrl_timeout_enable(pub, val) -#define DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_CANCEL(pub) \ - dhd_os_wake_lock_ctrl_timeout_cancel(pub) -#define DHD_PACKET_TIMEOUT_MS 500 +#define DHD_PACKET_TIMEOUT_MS 1000 #define DHD_EVENT_TIMEOUT_MS 1500 /* interface operations (register, remove) should be atomic, use this lock to prevent race @@ -460,6 +380,10 @@ inline static void MUTEX_UNLOCK_SOFTAP_S void dhd_net_if_lock(struct net_device *dev); void dhd_net_if_unlock(struct net_device *dev); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 +extern struct mutex _dhd_sdio_mutex_lock_; +#endif + typedef struct dhd_if_event { uint8 ifidx; uint8 action; @@ -516,9 +440,6 @@ extern void dhd_free(dhd_pub_t *dhdp); /* Indication from bus module to change flow-control state */ extern void dhd_txflowcontrol(dhd_pub_t *dhdp, int ifidx, bool on); -/* Store the status of a connection attempt for later retrieval by an iovar */ -extern void dhd_store_conn_status(uint32 event, uint32 status, uint32 reason); - extern bool dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, void *pkt, int prec); /* Receive frame for delivery to OS. Callee disposes of rxp. */ @@ -551,11 +472,6 @@ extern void dhd_os_sdunlock_txq(dhd_pub_ extern void dhd_os_sdlock_rxq(dhd_pub_t * pub); extern void dhd_os_sdunlock_rxq(dhd_pub_t * pub); extern void dhd_os_sdlock_sndup_rxq(dhd_pub_t * pub); -#ifdef DHDTCPACK_SUPPRESS -extern void dhd_os_tcpacklock(dhd_pub_t *pub); -extern void dhd_os_tcpackunlock(dhd_pub_t *pub); -#endif /* DHDTCPACK_SUPPRESS */ - extern void dhd_customer_gpio_wlan_ctrl(int onoff); extern int dhd_custom_get_mac_address(unsigned char *buf); extern void dhd_os_sdunlock_sndup_rxq(dhd_pub_t * pub); @@ -565,22 +481,29 @@ extern bool dhd_os_check_hang(dhd_pub_t extern int dhd_os_send_hang_message(dhd_pub_t *dhdp); extern void dhd_set_version_info(dhd_pub_t *pub, char *fw); -#if defined(KEEP_ALIVE) -extern int dhd_keep_alive_onoff(dhd_pub_t *dhd); -#endif /* KEEP_ALIVE */ - +#ifdef PNO_SUPPORT +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); +#endif /* PNO_SUPPORT */ #ifdef PKT_FILTER_SUPPORT #define DHD_UNICAST_FILTER_NUM 0 #define DHD_BROADCAST_FILTER_NUM 1 #define DHD_MULTICAST4_FILTER_NUM 2 #define DHD_MULTICAST6_FILTER_NUM 3 -#define DHD_MDNS_FILTER_NUM 4 -#define DHD_ARP_FILTER_NUM 5 +#define DHD_MDNS_FILTER_NUM 4 extern int dhd_os_enable_packet_filter(dhd_pub_t *dhdp, int val); -extern void dhd_enable_packet_filter(int value, dhd_pub_t *dhd); -extern int net_os_enable_packet_filter(struct net_device *dev, int val); -extern int net_os_rxfilter_add_remove(struct net_device *dev, int val, int num); +extern void dhd_enable_packet_filter(int value, dhd_pub_t *dhd); +extern int net_os_enable_packet_filter(struct net_device *dev, int val); +extern int net_os_rxfilter_add_remove(struct net_device *dev, int val, int num); #endif /* PKT_FILTER_SUPPORT */ extern int dhd_get_suspend_bcn_li_dtim(dhd_pub_t *dhd); @@ -616,8 +539,8 @@ extern void wl_event_to_host_order(wl_ev extern int dhd_wl_ioctl(dhd_pub_t *dhd_pub, int ifindex, wl_ioctl_t *ioc, void *buf, int len); extern int dhd_wl_ioctl_cmd(dhd_pub_t *dhd_pub, int cmd, void *arg, int len, uint8 set, int ifindex); + extern void 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, @@ -653,7 +576,7 @@ extern int dhd_keep_alive_onoff(dhd_pub_ #endif /* KEEP_ALIVE */ extern bool dhd_is_concurrent_mode(dhd_pub_t *dhd); -extern int dhd_iovar(dhd_pub_t *pub, int ifidx, char *name, char *cmd_buf, uint cmd_len, int set); + typedef enum cust_gpio_modes { WLAN_RESET_ON, WLAN_RESET_OFF, @@ -673,9 +596,14 @@ extern uint dhd_watchdog_ms; #if defined(DHD_DEBUG) /* Console output poll interval */ extern uint dhd_console_ms; -extern uint wl_msg_level; #endif /* defined(DHD_DEBUG) */ - +extern uint android_msg_level; +#ifdef CONFIG_WIRELESS_EXT +extern uint iw_msg_level; +#endif +#ifdef WL_CFG80211 +extern uint wl_dbg_level; +#endif extern uint dhd_slpauto; /* Use interrupts */ @@ -731,7 +659,7 @@ extern uint dhd_force_tx_queueing; #ifndef CUSTOM_GLOM_SETTING #define CUSTOM_GLOM_SETTING DEFAULT_GLOM_VALUE #endif -#define WL_AUTO_ROAM_TRIGGER -75 + /* hooks for custom Roaming Trigger setting via Makefile */ #define DEFAULT_ROAM_TRIGGER_VALUE -75 /* dBm default roam trigger all band */ #define DEFAULT_ROAM_TRIGGER_SETTING -1 @@ -753,46 +681,18 @@ extern uint dhd_force_tx_queueing; #ifndef CUSTOM_PNO_EVENT_LOCK_xTIME #define CUSTOM_PNO_EVENT_LOCK_xTIME DEFAULT_PNO_EVENT_LOCK_xTIME #endif + /* hooks for custom dhd_dpc_prio setting option via Makefile */ #define DEFAULT_DHP_DPC_PRIO 1 #ifndef CUSTOM_DPC_PRIO_SETTING #define CUSTOM_DPC_PRIO_SETTING DEFAULT_DHP_DPC_PRIO #endif -#ifndef CUSTOM_LISTEN_INTERVAL -#define CUSTOM_LISTEN_INTERVAL LISTEN_INTERVAL -#endif /* CUSTOM_LISTEN_INTERVAL */ - #define DEFAULT_SUSPEND_BCN_LI_DTIM 3 #ifndef CUSTOM_SUSPEND_BCN_LI_DTIM #define CUSTOM_SUSPEND_BCN_LI_DTIM DEFAULT_SUSPEND_BCN_LI_DTIM #endif -#define DEFAULT_WIFI_TURNOFF_DELAY 0 -#define WIFI_TURNOFF_DELAY DEFAULT_WIFI_TURNOFF_DELAY - -#ifdef RXFRAME_THREAD -#ifndef CUSTOM_RXF_PRIO_SETTING -#define CUSTOM_RXF_PRIO_SETTING MAX((CUSTOM_DPC_PRIO_SETTING - 1), 1) -#endif -#endif /* RXFRAME_THREAD */ - -#ifdef WLTDLS -#ifndef CUSTOM_TDLS_IDLE_MODE_SETTING -#define CUSTOM_TDLS_IDLE_MODE_SETTING 60000 /* 60sec to tear down TDLS of not active */ -#endif -#ifndef CUSTOM_TDLS_RSSI_THRESHOLD_HIGH -#define CUSTOM_TDLS_RSSI_THRESHOLD_HIGH -70 /* rssi threshold for establishing TDLS link */ -#endif -#ifndef CUSTOM_TDLS_RSSI_THRESHOLD_LOW -#define CUSTOM_TDLS_RSSI_THRESHOLD_LOW -80 /* rssi threshold for tearing down TDLS link */ -#endif -#endif /* WLTDLS */ - -#define MAX_DTIM_SKIP_BEACON_INTERVAL 100 /* max allowed associated AP beacon for DTIM skip */ -#define MAX_DTIM_ALLOWED_INTERVAL 600 /* max allowed total beacon interval for DTIM skip */ -#define NO_DTIM_SKIP 1 - #ifdef SDTEST /* Echo packet generator (SDIO), pkts/s */ extern uint dhd_pktgen; @@ -809,10 +709,16 @@ extern char fw_path[MOD_PARAM_PATHLEN]; extern char nv_path[MOD_PARAM_PATHLEN]; #define MOD_PARAM_INFOLEN 512 + #ifdef SOFTAP extern char fw_path2[MOD_PARAM_PATHLEN]; #endif +#define FW_PATH_AUTO_SELECT 1 +extern char firmware_path[MOD_PARAM_PATHLEN]; +extern void dhd_bus_select_firmware_name_by_chip(struct dhd_bus *bus, char *dst, char *src); +#define COPY_FW_PATH_BY_CHIP(bus, dst, src) dhd_bus_select_firmware_name_by_chip(bus, dst, src); + /* Flag to indicate if we should download firmware on driver load */ extern uint dhd_download_fw_on_driverload; @@ -821,13 +727,12 @@ extern uint dhd_download_fw_on_driverloa #define DHD_MAX_IFS 16 #define DHD_DEL_IF -0xe #define DHD_BAD_IF -0xf +#define WL_AUTO_ROAM_TRIGGER -75 #ifdef PROP_TXSTATUS /* Please be mindful that total pkttag space is 32 octets only */ typedef struct dhd_pkttag { /* - b[14:13] - encryption exemption - b[12 ] - 1 = event channel b[11 ] - 1 = this packet was sent in response to one time packet request, do not increment credit on status for this one. [WLFC_CTL_TYPE_MAC_REQUEST_PACKET]. b[10 ] - 1 = signal-only-packet to firmware [i.e. nothing to piggyback on] @@ -878,12 +783,6 @@ typedef struct dhd_pkttag { #define DHD_PKTTAG_ONETIMEPKTRQST_MASK 0x1 #define DHD_PKTTAG_ONETIMEPKTRQST_SHIFT 11 -#define DHD_PKTTAG_EVENT_MASK 0x1 -#define DHD_PKTTAG_EVENT_SHIFT 12 - -#define DHD_PKTTAG_EXEMPT_MASK 0x3 -#define DHD_PKTTAG_EXEMPT_SHIFT 13 - #define DHD_PKTTAG_PKTDIR_MASK 0x1 #define DHD_PKTTAG_PKTDIR_SHIFT 9 @@ -937,28 +836,11 @@ typedef struct dhd_pkttag { #define DHD_PKTTAG_ONETIMEPKTRQST(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \ DHD_PKTTAG_ONETIMEPKTRQST_SHIFT) & DHD_PKTTAG_ONETIMEPKTRQST_MASK) -#define DHD_PKTTAG_SETEVENT(tag, event) ((dhd_pkttag_t*)(tag))->if_flags = \ - (((dhd_pkttag_t*)(tag))->if_flags & \ - ~(DHD_PKTTAG_EVENT_MASK << DHD_PKTTAG_EVENT_SHIFT)) | \ - (((event) & DHD_PKTTAG_EVENT_MASK) << DHD_PKTTAG_EVENT_SHIFT) -#define DHD_PKTTAG_EVENT(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \ - DHD_PKTTAG_EVENT_SHIFT) & DHD_PKTTAG_EVENT_MASK) - -#define DHD_PKTTAG_EXEMPT_SET(tag, value) ((dhd_pkttag_t*)(tag))->if_flags = \ - (((dhd_pkttag_t*)(tag))->if_flags & \ - ~(DHD_PKTTAG_EXEMPT_MASK << DHD_PKTTAG_EXEMPT_SHIFT)) | \ - (((value) & DHD_PKTTAG_EXEMPT_MASK) << DHD_PKTTAG_EXEMPT_SHIFT) -#define DHD_PKTTAG_EXEMPT(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \ - DHD_PKTTAG_EXEMPT_SHIFT) & DHD_PKTTAG_EXEMPT_MASK) - #define DHD_PKTTAG_SETDSTN(tag, dstn_MAC_ea) memcpy(((dhd_pkttag_t*)((tag)))->dstn_ether, \ (dstn_MAC_ea), ETHER_ADDR_LEN) #define DHD_PKTTAG_DSTN(tag) ((dhd_pkttag_t*)(tag))->dstn_ether -typedef int (*f_commitpkt_t)(void* ctx, void* p); -int dhd_os_wlfc_block(dhd_pub_t *pub); -int dhd_os_wlfc_unblock(dhd_pub_t *pub); -void dhd_schedule_tx(struct dhd_info *dhd); +typedef int (*f_commitpkt_t)(void* ctx, void* p, bool wlfc_locked); #ifdef PROP_TXSTATUS_DEBUG #define DHD_WLFC_CTRINC_MAC_CLOSE(entry) do { (entry)->closed_ct++; } while (0) @@ -978,7 +860,19 @@ extern void dhd_wait_event_wakeup(dhd_pu NdisStallExecution(1); #define IFUNLOCK(lock) InterlockedExchange((lock), 0) #define IFLOCK_FREE(lock) -#define FW_SUPPORTED(dhd, capa) ((strstr(dhd->fw_capabilities, #capa) != NULL)) + +#ifdef PNO_SUPPORT +extern int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled); +extern int dhd_pnoenable(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_pno_set_add(dhd_pub_t *dhd, wl_pfn_t *netinfo, int nssid, ushort scan_fr, + ushort slowscan_fr, uint8 pno_repeat, uint8 pno_freq_expo_max, int16 flags); +extern int dhd_pno_cfg(dhd_pub_t *dhd, wl_pfn_cfg_t *pcfg); +extern int dhd_pno_suspend(dhd_pub_t *dhd, int pfn_suspend); +#endif /* PNO_SUPPORT */ #ifdef ARP_OFFLOAD_SUPPORT #define MAX_IPV4_ENTRIES 8 void dhd_arp_offload_set(dhd_pub_t * dhd, int arp_mode); @@ -991,19 +885,4 @@ int dhd_arp_get_arp_hostip_table(dhd_pub void dhd_arp_offload_add_ip(dhd_pub_t *dhd, uint32 ipaddr, int idx); #endif /* ARP_OFFLOAD_SUPPORT */ -#ifdef WLTDLS -int dhd_tdls_enable(struct net_device *dev, bool tdls_on, bool auto_on, struct ether_addr *mac); -#endif - -/* Neighbor Discovery Offload Support */ -int dhd_ndo_enable(dhd_pub_t *dhd, int ndo_enable); -int dhd_ndo_add_ip(dhd_pub_t *dhd, char *ipaddr, int idx); -int dhd_ndo_remove_ip(dhd_pub_t *dhd, int idx); -/* ioctl processing for nl80211 */ -int dhd_ioctl_process(dhd_pub_t *pub, int ifidx, struct dhd_ioctl *ioc); - -void dhd_set_bus_state(void *bus, uint32 state); - -/* Remove proper pkts(either one no-frag pkt or whole fragmented pkts) */ -extern bool dhd_prec_drop_pkts(osl_t *osh, struct pktq *pq, int prec); #endif /* _dhd_h_ */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/dhd_ip.c linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_ip.c --- linux-sunxi/drivers/net/wireless/bcmdhd/dhd_ip.c 2014-01-27 01:30:30.101433269 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_ip.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,111 +0,0 @@ -/* - * IP Packet Parser Module. - * - * Copyright (C) 1999-2013, 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$ - */ -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include - -/* special values */ -/* 802.3 llc/snap header */ -static const uint8 llc_snap_hdr[SNAP_HDR_LEN] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00}; - -pkt_frag_t pkt_frag_info(osl_t *osh, void *p) -{ - uint8 *frame; - int length; - uint8 *pt; /* Pointer to type field */ - uint16 ethertype; - struct ipv4_hdr *iph; /* IP frame pointer */ - int ipl; /* IP frame length */ - uint16 iph_frag; - - ASSERT(osh && p); - - frame = PKTDATA(osh, p); - length = PKTLEN(osh, p); - - /* Process Ethernet II or SNAP-encapsulated 802.3 frames */ - if (length < ETHER_HDR_LEN) { - DHD_INFO(("%s: short eth frame (%d)\n", __FUNCTION__, length)); - return DHD_PKT_FRAG_NONE; - } else if (ntoh16(*(uint16 *)(frame + ETHER_TYPE_OFFSET)) >= ETHER_TYPE_MIN) { - /* Frame is Ethernet II */ - pt = frame + ETHER_TYPE_OFFSET; - } else if (length >= ETHER_HDR_LEN + SNAP_HDR_LEN + ETHER_TYPE_LEN && - !bcmp(llc_snap_hdr, frame + ETHER_HDR_LEN, SNAP_HDR_LEN)) { - pt = frame + ETHER_HDR_LEN + SNAP_HDR_LEN; - } else { - DHD_INFO(("%s: non-SNAP 802.3 frame\n", __FUNCTION__)); - return DHD_PKT_FRAG_NONE; - } - - ethertype = ntoh16(*(uint16 *)pt); - - /* Skip VLAN tag, if any */ - if (ethertype == ETHER_TYPE_8021Q) { - pt += VLAN_TAG_LEN; - - if (pt + ETHER_TYPE_LEN > frame + length) { - DHD_INFO(("%s: short VLAN frame (%d)\n", __FUNCTION__, length)); - return DHD_PKT_FRAG_NONE; - } - - ethertype = ntoh16(*(uint16 *)pt); - } - - if (ethertype != ETHER_TYPE_IP) { - DHD_INFO(("%s: non-IP frame (ethertype 0x%x, length %d)\n", - __FUNCTION__, ethertype, length)); - return DHD_PKT_FRAG_NONE; - } - - iph = (struct ipv4_hdr *)(pt + ETHER_TYPE_LEN); - ipl = length - (pt + ETHER_TYPE_LEN - frame); - - /* We support IPv4 only */ - if ((ipl < IPV4_OPTIONS_OFFSET) || (IP_VER(iph) != IP_VER_4)) { - DHD_INFO(("%s: short frame (%d) or non-IPv4\n", __FUNCTION__, ipl)); - return DHD_PKT_FRAG_NONE; - } - - iph_frag = ntoh16(iph->frag); - - if (iph_frag & IPV4_FRAG_DONT) { - return DHD_PKT_FRAG_NONE; - } else if ((iph_frag & IPV4_FRAG_MORE) == 0) { - return DHD_PKT_FRAG_LAST; - } else { - return (iph_frag & IPV4_FRAG_OFFSET_MASK)? DHD_PKT_FRAG_CONT : DHD_PKT_FRAG_FIRST; - } -} diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/dhd_ip.h linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_ip.h --- linux-sunxi/drivers/net/wireless/bcmdhd/dhd_ip.h 2014-01-27 01:30:30.109433432 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_ip.h 1970-01-01 01:00:00.000000000 +0100 @@ -1,42 +0,0 @@ -/* - * Header file describing the common ip parser function. - * - * Provides type definitions and function prototypes used to parse ip packet. - * - * Copyright (C) 1999-2013, 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 _dhd_ip_h_ -#define _dhd_ip_h_ - -typedef enum pkt_frag -{ - DHD_PKT_FRAG_NONE = 0, - DHD_PKT_FRAG_FIRST, - DHD_PKT_FRAG_CONT, - DHD_PKT_FRAG_LAST -} pkt_frag_t; - -extern pkt_frag_t pkt_frag_info(osl_t *osh, void *p); - -#endif /* _dhd_ip_h_ */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/dhd_linux.c linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_linux.c --- linux-sunxi/drivers/net/wireless/bcmdhd/dhd_linux.c 2014-02-10 11:51:00.408495958 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_linux.c 2014-02-15 00:43:44.792014069 +0100 @@ -2,7 +2,7 @@ * Broadcom Dongle Host Driver (DHD), Linux-specific network interface * Basically selected code segments from usb-cdc.c and usb-rndis.c * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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 419821 2013-08-22 21:43:26Z $ + * $Id: dhd_linux.c 374275 2012-12-12 11:44:18Z $ */ #include @@ -42,8 +42,7 @@ #include #include #include -#include -#include +#include #include #include @@ -54,7 +53,6 @@ #include #include -#include #include #include #include @@ -66,8 +64,11 @@ #ifdef WL_CFG80211 #include #endif -#ifdef PNO_SUPPORT -#include + +#ifdef WLBTAMP +#include +#include +#include #endif #ifdef WLMEDIA_HTSF @@ -78,7 +79,6 @@ #define HTSF_BUS_DELAY 150 /* assume a fix propagation in us */ #define TSMAX 1000 /* max no. of timing record kept */ #define NUMBIN 34 - static uint32 tsidx = 0; static uint32 htsf_seqnum = 0; uint32 tsfsync; @@ -96,6 +96,8 @@ typedef struct histo_ { static histo_t vi_d1, vi_d2, vi_d3, vi_d4; #endif /* WLMEDIA_HTSF */ +#if defined(PKT_FILTER_SUPPORT) +#endif /* PKT_FILTER_SUPPORT */ #if defined(SOFTAP) extern bool ap_cfg_running; @@ -126,13 +128,6 @@ static struct notifier_block dhd_notifie .notifier_call = dhd_device_event }; #endif /* ARP_OFFLOAD_SUPPORT */ -static int dhd_device_ipv6_event(struct notifier_block *this, - unsigned long event, - void *ptr); - -static struct notifier_block dhd_notifier_ipv6 = { - .notifier_call = dhd_device_ipv6_event -}; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) #include @@ -143,7 +138,7 @@ DECLARE_WAIT_QUEUE_HEAD(dhd_dpc_wait); #if defined(OOB_INTR_ONLY) extern void dhd_enable_oob_intr(struct dhd_bus *bus, bool enable); #endif -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && (1) static void dhd_hang_process(struct work_struct *work); #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) @@ -162,12 +157,6 @@ MODULE_LICENSE("GPL v2"); #endif #endif /* BCM_FD_AGGR */ -#ifdef PROP_TXSTATUS -extern bool dhd_wlfc_skip_fc(void); -extern void dhd_wlfc_plat_enable(void *dhd); -extern void dhd_wlfc_plat_deinit(void *dhd); -#endif /* PROP_TXSTATUS */ - #if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 15) const char * print_tainted() @@ -177,10 +166,10 @@ print_tainted() #endif /* LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 15) */ /* Linux wireless extension support */ -#if defined(WL_WIRELESS_EXT) +#if defined(CONFIG_WIRELESS_EXT) #include extern wl_iw_extra_params_t g_wl_iw_params; -#endif /* defined(WL_WIRELESS_EXT) */ +#endif /* defined(CONFIG_WIRELESS_EXT) */ #if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND) #include @@ -191,25 +180,28 @@ extern int dhd_get_suspend_bcn_li_dtim(d #ifdef PKT_FILTER_SUPPORT extern void dhd_pktfilter_offload_set(dhd_pub_t * dhd, char *arg); extern void dhd_pktfilter_offload_enable(dhd_pub_t * dhd, char *arg, int enable, int master_mode); -extern void dhd_pktfilter_offload_delete(dhd_pub_t *dhd, int id); #endif - #ifdef READ_MACADDR -extern int dhd_read_macaddr(struct dhd_info *dhd); -#else -static inline int dhd_read_macaddr(struct dhd_info *dhd) { return 0; } +extern int dhd_read_macaddr(struct dhd_info *dhd, struct ether_addr *mac); +#endif +#ifdef RDWR_MACADDR +extern int dhd_check_rdwr_macaddr(struct dhd_info *dhd, dhd_pub_t *dhdp, struct ether_addr *mac); +extern int dhd_write_rdwr_macaddr(struct ether_addr *mac); #endif #ifdef WRITE_MACADDR extern int dhd_write_macaddr(struct ether_addr *mac); -#else -static inline int dhd_write_macaddr(struct ether_addr *mac) { return 0; } #endif -struct ipv6_addr { - char ipv6_addr[IPV6_ADDR_LEN]; - dhd_ipv6_op_t ipv6_oper; - struct list_head list; -}; +#ifdef GET_MAC_FROM_OTP +extern int dhd_check_module_mac(dhd_pub_t *dhd, struct ether_addr *mac); +#endif +#ifdef MIMO_ANT_SETTING +extern int dhd_sel_ant_from_file(dhd_pub_t *dhd); +#endif + +#ifdef GLOBALCONFIG_WLAN_COUNTRY_CODE +int dhd_customer_set_country(dhd_pub_t *dhd); +#endif /* Interface control information */ typedef struct dhd_if { @@ -226,8 +218,6 @@ typedef struct dhd_if { char name[IFNAMSIZ+1]; /* linux interface name */ uint8 bssidx; /* bsscfg index for the interface */ bool set_multicast; - struct list_head ipv6_list; - spinlock_t ipv6_lock; bool event2cfg80211; /* To determine if pass event to cfg80211 */ } dhd_if_t; @@ -261,9 +251,9 @@ static uint32 maxdelay = 0, tspktcnt = 0 /* Local private structure (extension of pub) */ typedef struct dhd_info { -#if defined(WL_WIRELESS_EXT) +#if defined(CONFIG_WIRELESS_EXT) wl_iw_t iw; /* wireless extensions state (must be first) */ -#endif /* defined(WL_WIRELESS_EXT) */ +#endif /* defined(CONFIG_WIRELESS_EXT) */ dhd_pub_t pub; @@ -278,8 +268,6 @@ typedef struct dhd_info { htsf_t htsf; #endif wait_queue_head_t ioctl_resp_wait; - uint32 default_wd_interval; - struct timer_list timer; bool wd_timer_valid; struct tasklet_struct tasklet; @@ -293,10 +281,6 @@ typedef struct dhd_info { tsk_ctl_t thr_dpc_ctl; tsk_ctl_t thr_wdt_ctl; -#ifdef RXFRAME_THREAD - tsk_ctl_t thr_rxf_ctl; - spinlock_t rxf_lock; -#endif /* RXFRAME_THREAD */ #endif /* DHDTHREAD */ bool dhd_tasklet_create; tsk_ctl_t thr_sysioc_ctl; @@ -306,13 +290,13 @@ typedef struct dhd_info { /* Wakelocks */ #if defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - struct wake_lock wl_wifi; /* Wifi wakelock */ - struct wake_lock wl_rxwake; /* Wifi rx wakelock */ - struct wake_lock wl_ctrlwake; /* Wifi ctrl wakelock */ - struct wake_lock wl_wdwake; /* Wifi wd wakelock */ + struct wake_lock *wl_wifi; /* Wifi wakelock */ + struct wake_lock *wl_rxwake; /* Wifi rx wakelock */ + struct wake_lock *wl_ctrlwake; /* Wifi ctrl wakelock */ + struct wake_lock *wl_wdwake; /* Wifi wd 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 */ @@ -334,7 +318,7 @@ typedef struct dhd_info { #if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND) struct early_suspend early_suspend; -#endif /* CONFIG_HAS_EARLYSUSPEND && DHD_USE_EARLYSUSPEND */ +#endif /* CONFIG_HAS_EARLYSUSPEND && defined(DHD_USE_EARLYSUSPEND) */ #ifdef ARP_OFFLOAD_SUPPORT u32 pend_ipaddr; @@ -346,9 +330,6 @@ typedef struct dhd_info { bool rpcth_timer_active; bool fdaggr; #endif -#ifdef DHDTCPACK_SUPPRESS - spinlock_t tcpack_lock; -#endif /* DHDTCPACK_SUPPRESS */ } dhd_info_t; /* Flag to indicate if we should download firmware on driver load */ @@ -363,6 +344,7 @@ char nvram_path[MOD_PARAM_PATHLEN]; /* information string to keep firmware, chio, cheip version info visiable from log */ char info_string[MOD_PARAM_INFOLEN]; module_param_string(info_string, info_string, MOD_PARAM_INFOLEN, 0444); + int op_mode = 0; int disable_proptx = 0; module_param(op_mode, int, 0644); @@ -381,32 +363,22 @@ module_param(dhd_sysioc, uint, 0); /* Error bits */ module_param(dhd_msg_level, int, 0); - -#ifdef ARP_OFFLOAD_SUPPORT -/* ARP offload enable */ -uint dhd_arp_enable = TRUE; -module_param(dhd_arp_enable, uint, 0); - -/* ARP offload agent mode : Enable ARP Host Auto-Reply and ARP Peer Auto-Reply */ - -uint dhd_arp_mode = ARP_OL_AGENT | ARP_OL_PEER_AUTO_REPLY; - -module_param(dhd_arp_mode, uint, 0); -#endif /* ARP_OFFLOAD_SUPPORT */ - - +#if defined(CONFIG_WIRELESS_EXT) +module_param(iw_msg_level, int, 0); +#endif +#ifdef WL_CFG80211 +module_param(wl_dbg_level, int, 0); +#endif +module_param(android_msg_level, int, 0); /* Disable Prop tx */ module_param(disable_proptx, int, 0644); + /* load firmware and/or nvram values from the filesystem */ module_param_string(firmware_path, firmware_path, MOD_PARAM_PATHLEN, 0660); module_param_string(nvram_path, nvram_path, MOD_PARAM_PATHLEN, 0); /* Watchdog interval */ - -/* extend watchdog expiration to 2 seconds when DPC is running */ -#define WATCHDOG_EXTEND_INTERVAL (2000) - uint dhd_watchdog_ms = 10; module_param(dhd_watchdog_ms, uint, 0); @@ -419,6 +391,14 @@ module_param(dhd_console_ms, uint, 0644) uint dhd_slpauto = TRUE; module_param(dhd_slpauto, uint, 0); +/* ARP offload agent mode : Enable ARP Host Auto-Reply and ARP Peer Auto-Reply */ +uint dhd_arp_mode = ARP_OL_AGENT | ARP_OL_PEER_AUTO_REPLY; +module_param(dhd_arp_mode, uint, 0); + +/* ARP offload enable */ +uint dhd_arp_enable = TRUE; +module_param(dhd_arp_enable, uint, 0); + #ifdef PKT_FILTER_SUPPORT /* Global Pkt filter enable control */ uint dhd_pkt_filter_enable = TRUE; @@ -430,7 +410,11 @@ uint dhd_pkt_filter_init = 0; module_param(dhd_pkt_filter_init, uint, 0); /* Pkt filter mode control */ +#ifdef GAN_LITE_NAT_KEEPALIVE_FILTER +uint dhd_master_mode = FALSE; +#else uint dhd_master_mode = TRUE; +#endif /* GAL_LITE_NAT_KEEPALIVE_FILTER */ module_param(dhd_master_mode, uint, 0); #ifdef DHDTHREAD @@ -441,15 +425,9 @@ module_param(dhd_watchdog_prio, int, 0); int dhd_dpc_prio = CUSTOM_DPC_PRIO_SETTING; module_param(dhd_dpc_prio, int, 0); -#ifdef RXFRAME_THREAD -/* RX frame thread priority */ -int dhd_rxf_prio = CUSTOM_RXF_PRIO_SETTING; -module_param(dhd_rxf_prio, int, 0); -#endif /* RXFRAME_THREAD */ - /* DPC thread priority, -1 to use tasklet */ -extern int dhd_dongle_ramsize; -module_param(dhd_dongle_ramsize, int, 0); +extern int dhd_dongle_memsize; +module_param(dhd_dongle_memsize, int, 0); #endif /* DHDTHREAD */ /* Control fw roaming */ uint dhd_roam_disable = 0; @@ -497,6 +475,13 @@ extern void dhd_dbg_init(dhd_pub_t *dhdp extern void dhd_dbg_remove(void); #endif /* BCMDBGFS */ +/* + * the the 2 vars init at init time + *benn@cubietech.com + */ +#define WL_HOST_WAKE_DEF_GPIO 2 +int wl_host_wake_irqno = -1; +int wl_host_wake = -1; #ifdef SDTEST @@ -546,15 +531,13 @@ int dhd_monitor_init(void *dhd_pub); int dhd_monitor_uninit(void); - -#if defined(WL_WIRELESS_EXT) +#if defined(CONFIG_WIRELESS_EXT) struct iw_statistics *dhd_get_wireless_stats(struct net_device *dev); -#endif /* defined(WL_WIRELESS_EXT) */ +#endif /* defined(CONFIG_WIRELESS_EXT) */ static void dhd_dpc(ulong data); /* forward decl */ extern int dhd_wait_pend8021x(struct net_device *dev); -void dhd_os_wd_timer_extend(void *bus, bool extend); #ifdef TOE #ifndef BDC @@ -567,12 +550,13 @@ static int dhd_toe_set(dhd_info_t *dhd, static int dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata, wl_event_msg_t *event_ptr, void **data_ptr); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && (LINUX_VERSION_CODE <= \ - KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM_SLEEP) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) static int dhd_sleep_pm_callback(struct notifier_block *nfb, unsigned long action, void *ignored) { int ret = NOTIFY_DONE; +#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI) || (LINUX_VERSION_CODE <= \ + KERNEL_VERSION(2, 6, 39)) switch (action) { case PM_HIBERNATION_PREPARE: case PM_SUSPEND_PREPARE: @@ -586,6 +570,7 @@ static int dhd_sleep_pm_callback(struct break; } smp_mb(); +#endif return ret; } @@ -595,109 +580,7 @@ static struct notifier_block dhd_sleep_p }; extern int register_pm_notifier(struct notifier_block *nb); extern int unregister_pm_notifier(struct notifier_block *nb); -#endif /* (LINUX_VERSION >= 2.6.27 && LINUX_VERSION <= 2.6.39 && CONFIG_PM_SLEEP */ - -#if defined(DHDTHREAD) && defined(RXFRAME_THREAD) -/* Request scheduling of the bus rx frame */ -static void dhd_sched_rxf(dhd_pub_t *dhdp, void *skb); -static void dhd_os_rxflock(dhd_pub_t *pub); -static void dhd_os_rxfunlock(dhd_pub_t *pub); - -static inline int dhd_rxf_enqueue(dhd_pub_t *dhdp, void* skb) -{ - uint32 store_idx; - uint32 sent_idx; - - if (!skb) { - DHD_ERROR(("dhd_rxf_enqueue: NULL skb!!!\n")); - return BCME_ERROR; - } - - dhd_os_rxflock(dhdp); - store_idx = dhdp->store_idx; - sent_idx = dhdp->sent_idx; - if (dhdp->skbbuf[store_idx] != NULL) { - /* Make sure the previous packets are processed */ - /* Do I need to make this context sleep here? Definitely in Single processor case */ - dhd_os_rxfunlock(dhdp); - DHD_ERROR(("dhd_rxf_enqueue: pktbuf not consumed %p, store idx %d sent idx %d\n", - skb, store_idx, sent_idx)); - msleep(1); - return BCME_ERROR; - } - DHD_TRACE(("dhd_rxf_enqueue: Store SKB %p. idx %d -> %d\n", - skb, store_idx, (store_idx + 1) & (MAXSKBPEND - 1))); - dhdp->skbbuf[store_idx] = skb; - dhdp->store_idx = (store_idx + 1) & (MAXSKBPEND - 1); - dhd_os_rxfunlock(dhdp); - - return BCME_OK; -} - -static inline void* dhd_rxf_dequeue(dhd_pub_t *dhdp) -{ - uint32 store_idx; - uint32 sent_idx; - void *skb; - - dhd_os_rxflock(dhdp); - - store_idx = dhdp->store_idx; - sent_idx = dhdp->sent_idx; - skb = dhdp->skbbuf[sent_idx]; - - if (skb == NULL) { - dhd_os_rxfunlock(dhdp); - DHD_ERROR(("dhd_rxf_dequeue: Dequeued packet is NULL, store idx %d sent idx %d\n", - store_idx, sent_idx)); - return NULL; - } - - dhdp->skbbuf[sent_idx] = NULL; - dhdp->sent_idx = (sent_idx + 1) & (MAXSKBPEND - 1); - - DHD_TRACE(("dhd_rxf_dequeue: netif_rx_ni(%p), sent idx %d\n", - skb, sent_idx)); - - dhd_os_rxfunlock(dhdp); - - return skb; -} -#endif /* defined(DHDTHREAD) && defined(RXFRAME_THREAD) */ - -static int dhd_process_cid_mac(dhd_pub_t *dhdp, bool prepost) -{ - dhd_info_t *dhd = (dhd_info_t *)dhdp->info; - - if (prepost) { /* pre process */ - dhd_read_macaddr(dhd); - } else { /* post process */ - dhd_write_macaddr(&dhd->pub.mac); - } - - return 0; -} - -#ifdef PKT_FILTER_SUPPORT -static bool -_turn_on_arp_filter(dhd_pub_t *dhd, int op_mode) -{ - bool _apply = FALSE; - /* In case of IBSS mode, apply arp pkt filter */ - if (op_mode & DHD_FLAG_IBSS_MODE) { - _apply = TRUE; - goto exit; - } - /* In case of P2P GO or GC, apply pkt filter to pass arp pkt to host */ - if ((dhd->arp_version == 1) && - (op_mode & (DHD_FLAG_P2P_GC_MODE | DHD_FLAG_P2P_GO_MODE))) { - _apply = TRUE; - goto exit; - } -exit: - return _apply; -} -#endif /* PKT_FILTER_SUPPORT */ +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */ void dhd_set_packet_filter(dhd_pub_t *dhd) { @@ -722,16 +605,17 @@ void dhd_enable_packet_filter(int value, /* 1 - Enable packet filter, only allow unicast packet to send up */ /* 0 - Disable packet filter */ if (dhd_pkt_filter_enable && (!value || - (dhd_support_sta_mode(dhd) && !dhd->dhcp_in_progress))) - { + (dhd_support_sta_mode(dhd) && !dhd->dhcp_in_progress))) { for (i = 0; i < dhd->pktfilter_count; i++) { - if (value && (i == DHD_ARP_FILTER_NUM) && - !_turn_on_arp_filter(dhd, dhd->op_mode)) { - DHD_TRACE(("Do not turn on ARP white list pkt filter:" +#ifdef PASS_ARP_PACKET + if (value && (i == dhd->pktfilter_count -1) && + !(dhd->op_mode & (DHD_FLAG_P2P_GC_MODE | DHD_FLAG_P2P_GO_MODE))) { + DHD_TRACE_HW4(("Do not turn on ARP white list pkt filter:" "val %d, cnt %d, op_mode 0x%x\n", - value, i, dhd->op_mode)); + value, i, dhd->op_mode)); continue; } +#endif dhd_pktfilter_offload_enable(dhd, dhd->pktfilter[i], value, dhd_master_mode); } @@ -741,41 +625,52 @@ void dhd_enable_packet_filter(int value, static int dhd_set_suspend(int value, dhd_pub_t *dhd) { -#ifndef SUPPORT_PM2_ONLY +#if !defined(SUPPORT_PM2_ONLY) int power_mode = PM_MAX; -#endif /* SUPPORT_PM2_ONLY */ +#endif /* wl_pkt_filter_enable_t enable_parm; */ char iovbuf[32]; int bcn_li_dtim = 0; /* Default bcn_li_dtim in resume mode is 0 */ -#ifndef ENABLE_FW_ROAM_SUSPEND +#ifndef DISABLE_FW_ROAM_SUSPEND uint roamvar = 1; -#endif /* ENABLE_FW_ROAM_SUSPEND */ - uint nd_ra_filter = 0; - int ret = 0; - - if (!dhd) - return -ENODEV; +#endif +#ifdef ENABLE_BCN_LI_BCN_WAKEUP + int bcn_li_bcn; +#endif /* ENABLE_BCN_LI_BCN_WAKEUP */ +#ifdef PASS_ALL_MCAST_PKTS + struct dhd_info *dhdinfo = dhd->info; + uint32 allmulti; + uint i; +#endif /* PASS_ALL_MCAST_PKTS */ DHD_TRACE(("%s: enter, value = %d in_suspend=%d\n", __FUNCTION__, value, dhd->in_suspend)); dhd_suspend_lock(dhd); - if (dhd->up) { + if (dhd && dhd->up) { if (value && dhd->in_suspend) { #ifdef PKT_FILTER_SUPPORT dhd->early_suspended = 1; #endif /* Kernel suspended */ - DHD_ERROR(("%s: force extra Suspend setting \n", __FUNCTION__)); + DHD_ERROR(("%s: force extra Suspend setting\n", __FUNCTION__)); -#ifndef SUPPORT_PM2_ONLY +#if !defined(SUPPORT_PM2_ONLY) dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode, sizeof(power_mode), TRUE, 0); -#endif /* SUPPORT_PM2_ONLY */ - +#endif /* Enable packet filter, only allow unicast packet to send up */ dhd_enable_packet_filter(1, dhd); - +#ifdef PASS_ALL_MCAST_PKTS + allmulti = 0; + bcm_mkiovar("allmulti", (char *)&allmulti, + 4, iovbuf, sizeof(iovbuf)); + for (i = 0; i < DHD_MAX_IFS; i++) { + if (dhdinfo->iflist[i] && dhdinfo->iflist[i]->net) + dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, + sizeof(iovbuf), TRUE, i); + } +#endif /* PASS_ALL_MCAST_PKTS */ /* If DTIM skip is set up as default, force it to wake * each third DTIM for better power savings. Note that @@ -784,65 +679,68 @@ static int dhd_set_suspend(int value, dh bcn_li_dtim = dhd_get_suspend_bcn_li_dtim(dhd); bcm_mkiovar("bcn_li_dtim", (char *)&bcn_li_dtim, 4, iovbuf, sizeof(iovbuf)); - if (dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), - TRUE, 0) < 0) - DHD_ERROR(("%s: set dtim failed\n", __FUNCTION__)); + dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); -#ifndef ENABLE_FW_ROAM_SUSPEND +#ifndef DISABLE_FW_ROAM_SUSPEND /* Disable firmware roaming during suspend */ bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf)); dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); -#endif /* ENABLE_FW_ROAM_SUSPEND */ - if (FW_SUPPORTED(dhd, ndoe)) { - /* enable IPv6 RA filter in firmware during suspend */ - nd_ra_filter = 1; - bcm_mkiovar("nd_ra_filter_enable", (char *)&nd_ra_filter, 4, - iovbuf, sizeof(iovbuf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) - DHD_ERROR(("failed to set nd_ra_filter (%d)\n", ret)); - } +#endif +#ifdef ENABLE_BCN_LI_BCN_WAKEUP + bcn_li_bcn = 0; + bcm_mkiovar("bcn_li_bcn", (char *)&bcn_li_bcn, + 4, iovbuf, sizeof(iovbuf)); + dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); +#endif /* ENABLE_BCN_LI_BCN_WAKEUP */ + } else { #ifdef PKT_FILTER_SUPPORT dhd->early_suspended = 0; #endif /* Kernel resumed */ - DHD_ERROR(("%s: Remove extra suspend setting \n", __FUNCTION__)); + DHD_ERROR(("%s: Remove extra suspend setting\n", __FUNCTION__)); -#ifndef SUPPORT_PM2_ONLY +#if !defined(SUPPORT_PM2_ONLY) power_mode = PM_FAST; dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode, sizeof(power_mode), TRUE, 0); -#endif /* SUPPORT_PM2_ONLY */ -#ifdef PKT_FILTER_SUPPORT +#endif /* disable pkt filter */ dhd_enable_packet_filter(0, dhd); -#endif /* PKT_FILTER_SUPPORT */ +#ifdef PASS_ALL_MCAST_PKTS + allmulti = 1; + bcm_mkiovar("allmulti", (char *)&allmulti, + 4, iovbuf, sizeof(iovbuf)); + for (i = 0; i < DHD_MAX_IFS; i++) { + if (dhdinfo->iflist[i] && dhdinfo->iflist[i]->net) + dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, + sizeof(iovbuf), TRUE, i); + } +#endif /* PASS_ALL_MCAST_PKTS */ /* restore pre-suspend setting for dtim_skip */ bcm_mkiovar("bcn_li_dtim", (char *)&bcn_li_dtim, 4, iovbuf, sizeof(iovbuf)); dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); -#ifndef ENABLE_FW_ROAM_SUSPEND +#ifndef DISABLE_FW_ROAM_SUSPEND roamvar = dhd_roam_disable; bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf)); dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); -#endif /* ENABLE_FW_ROAM_SUSPEND */ - if (FW_SUPPORTED(dhd, ndoe)) { - /* disable IPv6 RA filter in firmware during suspend */ - nd_ra_filter = 0; - bcm_mkiovar("nd_ra_filter_enable", (char *)&nd_ra_filter, 4, - iovbuf, sizeof(iovbuf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) - DHD_ERROR(("failed to set nd_ra_filter (%d)\n", ret)); - } +#endif +#ifdef ENABLE_BCN_LI_BCN_WAKEUP + bcn_li_bcn = 1; + bcm_mkiovar("bcn_li_bcn", (char *)&bcn_li_bcn, + 4, iovbuf, sizeof(iovbuf)); + dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); +#endif /* ENABLE_BCN_LI_BCN_WAKEUP */ } } - dhd_suspend_unlock(dhd); + dhd_suspend_unlock(dhd); return 0; } @@ -882,7 +780,7 @@ static void dhd_late_resume(struct early if (dhd) dhd_suspend_resume_helper(dhd, 0, 0); } -#endif /* CONFIG_HAS_EARLYSUSPEND && DHD_USE_EARLYSUSPEND */ +#endif /* defined(CONFIG_HAS_EARLYSUSPEND) */ /* * Generalized timeout mechanism. Uses spin sleep with exponential back-off until @@ -1040,25 +938,31 @@ _dhd_set_multicast_list(dhd_info_t *dhd, uint buflen; int ret; - ASSERT(dhd && dhd->iflist[ifidx]); - dev = dhd->iflist[ifidx]->net; - if (!dev) - return; + ASSERT(dhd && dhd->iflist[ifidx]); + dev = dhd->iflist[ifidx]->net; + if (!dev) + return; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) - netif_addr_lock_bh(dev); + netif_addr_lock_bh(dev); #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) - cnt = netdev_mc_count(dev); + cnt = netdev_mc_count(dev); #else - cnt = dev->mc_count; + cnt = dev->mc_count; #endif /* LINUX_VERSION_CODE */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) - netif_addr_unlock_bh(dev); + netif_addr_unlock_bh(dev); #endif - /* Determine initial value of allmulti flag */ + /* Determine initial value of allmulti flag */ allmulti = (dev->flags & IFF_ALLMULTI) ? TRUE : FALSE; +#ifdef PASS_ALL_MCAST_PKTS +#ifdef PKT_FILTER_SUPPORT + if (!dhd->pub.early_suspended) +#endif /* PKT_FILTER_SUPPORT */ + allmulti = TRUE; +#endif /* PASS_ALL_MCAST_PKTS */ /* Send down the multicast list first. */ @@ -1078,28 +982,27 @@ _dhd_set_multicast_list(dhd_info_t *dhd, memcpy(bufp, &cnt, sizeof(cnt)); bufp += sizeof(cnt); - #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) - netif_addr_lock_bh(dev); + netif_addr_lock_bh(dev); #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) - netdev_for_each_mc_addr(ha, dev) { - if (!cnt) - break; - memcpy(bufp, ha->addr, ETHER_ADDR_LEN); - bufp += ETHER_ADDR_LEN; - cnt--; + netdev_for_each_mc_addr(ha, dev) { + if (!cnt) + break; + memcpy(bufp, ha->addr, ETHER_ADDR_LEN); + bufp += ETHER_ADDR_LEN; + cnt--; } #else for (mclist = dev->mc_list; (mclist && (cnt > 0)); cnt--, mclist = mclist->next) { - memcpy(bufp, (void *)mclist->dmi_addr, ETHER_ADDR_LEN); - bufp += ETHER_ADDR_LEN; - } + memcpy(bufp, (void *)mclist->dmi_addr, ETHER_ADDR_LEN); + bufp += ETHER_ADDR_LEN; + } #endif /* LINUX_VERSION_CODE */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) - netif_addr_unlock_bh(dev); + netif_addr_unlock_bh(dev); #endif memset(&ioc, 0, sizeof(ioc)); @@ -1154,7 +1057,6 @@ _dhd_set_multicast_list(dhd_info_t *dhd, /* Finally, pick up the PROMISC flag as well, like the NIC driver does */ allmulti = (dev->flags & IFF_PROMISC) ? TRUE : FALSE; - allmulti = htol32(allmulti); memset(&ioc, 0, sizeof(ioc)); @@ -1239,7 +1141,7 @@ dhd_op_if(dhd_if_t *ifp) } /* Allocate etherdev, including space for private structure */ if (!(ifp->net = alloc_etherdev(sizeof(dhd)))) { - DHD_ERROR(("%s: OOM - alloc_etherdev(%d)\n", __FUNCTION__, sizeof(dhd))); + DHD_ERROR(("%s: OOM - alloc_etherdev\n", __FUNCTION__)); ret = -ENOMEM; } if (ret == 0) { @@ -1324,23 +1226,23 @@ dhd_op_if(dhd_if_t *ifp) } } -#ifdef DHDTCPACK_SUPPRESS -uint dhd_use_tcpack_suppress = TRUE; -module_param(dhd_use_tcpack_suppress, uint, FALSE); -extern bool dhd_tcpack_suppress(dhd_pub_t *dhdp, void *pkt); -#endif /* DHDTCPACK_SUPPRESS */ - static int _dhd_sysioc_thread(void *data) { tsk_ctl_t *tsk = (tsk_ctl_t *)data; dhd_info_t *dhd = (dhd_info_t *)tsk->parent; - struct ipv6_addr *iter, *next; - int i, ret; + + + int i; #ifdef SOFTAP bool in_ap = FALSE; unsigned long flags; #endif +#ifndef USE_KTHREAD_API + DAEMONIZE("dhd_sysioc"); + + complete(&tsk->completed); +#endif while (down_interruptible(&tsk->sema) == 0) { @@ -1388,47 +1290,15 @@ _dhd_sysioc_thread(void *data) if (dhd->iflist[i]->set_multicast) { dhd->iflist[i]->set_multicast = FALSE; _dhd_set_multicast_list(dhd, i); - - } - list_for_each_entry_safe(iter, next, - &dhd->iflist[i]->ipv6_list, list) { - spin_lock_bh(&dhd->iflist[i]->ipv6_lock); - list_del(&iter->list); - spin_unlock_bh(&dhd->iflist[i]->ipv6_lock); - if (iter->ipv6_oper == DHD_IPV6_ADDR_ADD) { - ret = dhd_ndo_enable(&dhd->pub, TRUE); - if (ret < 0) { - DHD_ERROR(("%s: Enabling NDO Failed %d\n", - __FUNCTION__, ret)); - continue; - } - ret = dhd_ndo_add_ip(&dhd->pub, - (char *)&iter->ipv6_addr[0], i); - if (ret < 0) { - DHD_ERROR(("%s: Adding host ip fail %d\n", - __FUNCTION__, ret)); - continue; - } - } else { - ret = dhd_ndo_remove_ip(&dhd->pub, i); - if (ret < 0) { - DHD_ERROR(("%s: Removing host ip fail %d\n", - __FUNCTION__, ret)); - continue; - } - } - NATIVE_MFREE(dhd->pub.osh, iter, sizeof(struct ipv6_addr)); } if (dhd->set_macaddress == i+1) { dhd->set_macaddress = 0; if (_dhd_set_mac_address(dhd, i, &dhd->macvalue) == 0) { DHD_INFO(( - "%s: MACID is overwritten\n", - __FUNCTION__)); + "dhd_sysioc_thread: MACID is overwritten\n")); } else { DHD_ERROR(( - "%s: _dhd_set_mac_address() failed\n", - __FUNCTION__)); + "dhd_sysioc_thread: _dhd_set_mac_address() failed\n")); } } } @@ -1505,7 +1375,7 @@ uint8 prio2fifo[8] = { 1, 0, 0, 1, 2, 2, int dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, void *pktbuf) { - int ret = BCME_OK; + int ret; dhd_info_t *dhd = (dhd_info_t *)(dhdp->info); struct ether_header *eh = NULL; @@ -1559,17 +1429,14 @@ dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, #ifdef WLMEDIA_HTSF dhd_htsf_addtxts(dhdp, pktbuf); #endif -#ifdef DHDTCPACK_SUPPRESS - if (dhd_use_tcpack_suppress && dhd_tcpack_suppress(dhdp, pktbuf)) - ret = BCME_OK; - else -#endif /* DHDTCPACK_SUPPRESS */ #ifdef PROP_TXSTATUS dhd_os_wlfc_block(dhdp); if (dhdp->wlfc_state && ((athost_wl_status_info_t*)dhdp->wlfc_state)->proptxstatus_mode != WLFC_FCMODE_NONE) { + ret = dhd_wlfc_enque_sendq(dhdp->wlfc_state, DHD_PKTTAG_FIFO(PKTTAG(pktbuf)), + pktbuf); dhd_wlfc_commit_packets(dhdp->wlfc_state, (f_commitpkt_t)dhd_bus_txdata, - dhdp->bus, pktbuf); + dhdp->bus); if (((athost_wl_status_info_t*)dhdp->wlfc_state)->toggle_host_if) { ((athost_wl_status_info_t*)dhdp->wlfc_state)->toggle_host_if = 0; } @@ -1578,10 +1445,10 @@ dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, else { dhd_os_wlfc_unblock(dhdp); /* non-proptxstatus way */ - ret = dhd_bus_txdata(dhdp->bus, pktbuf); + ret = dhd_bus_txdata(dhdp->bus, pktbuf, FALSE); } #else - ret = dhd_bus_txdata(dhdp->bus, pktbuf); + ret = dhd_bus_txdata(dhdp->bus, pktbuf, FALSE); #endif /* PROP_TXSTATUS */ return ret; @@ -1591,10 +1458,8 @@ int dhd_start_xmit(struct sk_buff *skb, struct net_device *net) { int ret; - uint datalen; void *pktbuf; - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net); - dhd_if_t *ifp = NULL; + dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net); int ifidx; #ifdef WLMEDIA_HTSF uint8 htsfdlystat_sz = dhd->pub.htsfdlystat_sz; @@ -1636,9 +1501,6 @@ dhd_start_xmit(struct sk_buff *skb, stru #endif } - ifp = dhd->iflist[ifidx]; - datalen = PKTLEN(dhdp->osh, skb); - /* Make sure there's enough room for any header */ if (skb_headroom(skb) < dhd->pub.hdrlen + htsfdlystat_sz) { @@ -1681,15 +1543,12 @@ dhd_start_xmit(struct sk_buff *skb, stru ret = dhd_sendpkt(&dhd->pub, ifidx, pktbuf); + done: - if (ret) { - ifp->stats.tx_dropped++; - } - else { - dhd->pub.tx_packets++; - ifp->stats.tx_packets++; - ifp->stats.tx_bytes += datalen; - } + if (ret) + dhd->pub.dstats.tx_dropped++; + else + dhd->pub.tx_packets++; DHD_OS_WAKE_UNLOCK(&dhd->pub); @@ -1779,10 +1638,7 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, wl_event_msg_t event; int tout_rx = 0; int tout_ctrl = 0; -#if defined(DHDTHREAD) && defined(RXFRAME_THREAD) - void *skbhead = NULL; - void *skbprev = NULL; -#endif /* defined(DHDTHREAD) && defined(RXFRAME_THREAD) */ + #ifdef DHD_RX_DUMP #ifdef DHD_RX_FULL_DUMP int k; @@ -1794,9 +1650,10 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, DHD_TRACE(("%s: Enter\n", __FUNCTION__)); for (i = 0; pktbuf && i < numpkt; i++, pktbuf = pnext) { - - pnext = PKTNEXT(dhdp->osh, pktbuf); - PKTSETNEXT(wl->sh.osh, pktbuf, NULL); +#ifdef WLBTAMP + struct ether_header *eh; + struct dot11_llc_snap_header *lsh; +#endif ifp = dhd->iflist[ifidx]; if (ifp == NULL) { @@ -1819,6 +1676,22 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, } #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) */ + 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]; + + if ((ntoh16(eh->ether_type) < ETHER_TYPE_MIN) && + (PKTLEN(wl->sh.osh, pktbuf) >= RFC1042_HDR_LEN) && + bcmp(lsh, BT_SIG_SNAP_MPROT, DOT11_LLC_SNAP_HDR_LEN - 2) == 0 && + lsh->type == HTON16(BTA_PROT_L2CAP)) { + amp_hci_ACL_data_t *ACL_data = (amp_hci_ACL_data_t *) + ((uint8 *)eh + RFC1042_HDR_LEN); + ACL_data = NULL; + } +#endif /* WLBTAMP */ #ifdef PROP_TXSTATUS if (dhdp->wlfc_state && PKTLEN(wl->sh.osh, pktbuf) == 0) { @@ -1908,11 +1781,10 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, skb_pull(skb, ETH_HLEN); /* Process special event packets and then discard them */ - memset(&event, 0, sizeof(event)); if (ntoh16(skb->protocol) == ETHER_TYPE_BRCM) { dhd_wl_host_event(dhd, &ifidx, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) - skb_mac_header(skb), + skb->mac_header, #else skb->mac.raw, #endif @@ -1922,6 +1794,11 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, wl_event_to_host_order(&event); if (!tout_ctrl) tout_ctrl = DHD_PACKET_TIMEOUT_MS; +#ifdef WLBTAMP + if (event.event_type == WLC_E_BTA_HCI_EVENT) { + dhd_bta_doevt(dhdp, data, event.datalen); + } +#endif /* WLBTAMP */ #if defined(PNO_SUPPORT) if (event.event_type == WLC_E_PFN_NET_FOUND) { @@ -1947,8 +1824,6 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, dhdp->dstats.rx_bytes += skb->len; dhdp->rx_packets++; /* Local count */ - ifp->stats.rx_bytes += skb->len; - ifp->stats.rx_packets++; if (in_interrupt()) { netif_rx(skb); @@ -1959,13 +1834,6 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, * by netif_rx_ni(), but in earlier kernels, we need * to do it manually. */ -#if defined(DHDTHREAD) && defined(RXFRAME_THREAD) - if (!skbhead) - skbhead = skb; - else - PKTSETNEXT(wl->sh.osh, skbprev, skb); - skbprev = skb; -#else #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) netif_rx_ni(skb); #else @@ -1975,13 +1843,9 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, RAISE_RX_SOFTIRQ(); local_irq_restore(flags); #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) */ -#endif /* defined(DHDTHREAD) && defined(RXFRAME_THREAD) */ } } -#if defined(DHDTHREAD) && defined(RXFRAME_THREAD) - if (skbhead) - dhd_sched_rxf(dhdp, skbhead); -#endif + DHD_OS_WAKE_LOCK_RX_TIMEOUT_ENABLE(dhdp, tout_rx); DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE(dhdp, tout_ctrl); } @@ -1999,6 +1863,9 @@ dhd_txcomplete(dhd_pub_t *dhdp, void *tx dhd_info_t *dhd = (dhd_info_t *)(dhdp->info); struct ether_header *eh; uint16 type; +#ifdef WLBTAMP + uint len; +#endif dhd_prot_hdrpull(dhdp, NULL, txp, NULL, NULL); @@ -2008,6 +1875,23 @@ dhd_txcomplete(dhd_pub_t *dhdp, void *tx 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. + */ + len = PKTLEN(dhdp->osh, txp); + + /* Generate ACL data tx completion event locally to avoid SDIO bus transaction */ + if ((type < ETHER_TYPE_MIN) && (len >= RFC1042_HDR_LEN)) { + struct dot11_llc_snap_header *lsh = (struct dot11_llc_snap_header *)&eh[1]; + + if (bcmp(lsh, BT_SIG_SNAP_MPROT, DOT11_LLC_SNAP_HDR_LEN - 2) == 0 && + ntoh16(lsh->type) == BTA_PROT_L2CAP) { + + dhd_bta_tx_hcidata_complete(dhdp, txp, success); + } + } +#endif /* WLBTAMP */ } static struct net_device_stats * @@ -2062,6 +1946,12 @@ dhd_watchdog_thread(void *data) dhd_watchdog_prio:(MAX_RT_PRIO-1); setScheduler(current, SCHED_FIFO, ¶m); } +#ifndef USE_KTHREAD_API + DAEMONIZE("dhd_watchdog"); + + /* Run until signal received */ + complete(&tsk->completed); +#endif while (1) if (down_interruptible (&tsk->sema) == 0) { @@ -2089,9 +1979,9 @@ dhd_watchdog_thread(void *data) /* Reschedule the watchdog */ if (dhd->wd_timer_valid) mod_timer(&dhd->timer, - jiffies + - msecs_to_jiffies(dhd_watchdog_ms) - - min(msecs_to_jiffies(dhd_watchdog_ms), time_lapse)); + jiffies + + msecs_to_jiffies(dhd_watchdog_ms) - + min(msecs_to_jiffies(dhd_watchdog_ms), time_lapse)); dhd_os_spin_unlock(&dhd->pub, flags); } dhd_os_sdunlock(&dhd->pub); @@ -2150,14 +2040,17 @@ dhd_dpc_thread(void *data) param.sched_priority = (dhd_dpc_prio < MAX_RT_PRIO)?dhd_dpc_prio:(MAX_RT_PRIO-1); setScheduler(current, SCHED_FIFO, ¶m); } +#ifndef USE_KTHREAD_API + DAEMONIZE("dhd_dpc"); + /* DHD_OS_WAKE_LOCK is called in dhd_sched_dpc[dhd_linux.c] down below */ -#ifdef CUSTOM_DPC_CPUCORE - set_cpus_allowed_ptr(current, cpumask_of(CUSTOM_DPC_CPUCORE)); -#endif /* CUSTOM_DPC_CPUCORE */ + /* signal: thread has started */ + complete(&tsk->completed); +#endif /* Run until signal received */ while (1) { - if (!binary_sema_down(tsk)) { + if (down_interruptible(&tsk->sema) == 0) { SMP_RD_BARRIER_DEPENDS(); if (tsk->terminated) { @@ -2166,12 +2059,12 @@ dhd_dpc_thread(void *data) /* Call bus dpc unless it indicated down (then clean stop) */ if (dhd->pub.busstate != DHD_BUS_DOWN) { - dhd_os_wd_timer_extend(&dhd->pub, TRUE); - while (dhd_bus_dpc(dhd->pub.bus)) { - /* process all data */ + if (dhd_bus_dpc(dhd->pub.bus)) { + up(&tsk->sema); + } + else { + DHD_OS_WAKE_UNLOCK(&dhd->pub); } - dhd_os_wd_timer_extend(&dhd->pub, FALSE); - DHD_OS_WAKE_UNLOCK(&dhd->pub); } else { if (dhd->pub.up) dhd_bus_stop(dhd->pub.bus, TRUE); @@ -2184,74 +2077,6 @@ dhd_dpc_thread(void *data) complete_and_exit(&tsk->completed, 0); } - -#ifdef RXFRAME_THREAD -static int -dhd_rxf_thread(void *data) -{ - tsk_ctl_t *tsk = (tsk_ctl_t *)data; - dhd_info_t *dhd = (dhd_info_t *)tsk->parent; - dhd_pub_t *pub = &dhd->pub; - - /* This thread doesn't need any user-level access, - * so get rid of all our resources - */ - if (dhd_rxf_prio > 0) - { - struct sched_param param; - param.sched_priority = (dhd_rxf_prio < MAX_RT_PRIO)?dhd_rxf_prio:(MAX_RT_PRIO-1); - setScheduler(current, SCHED_FIFO, ¶m); - } - - DAEMONIZE("dhd_rxf"); - /* DHD_OS_WAKE_LOCK is called in dhd_sched_dpc[dhd_linux.c] down below */ - - /* signal: thread has started */ - complete(&tsk->completed); - - /* Run until signal received */ - while (1) { - if (down_interruptible(&tsk->sema) == 0) { - void *skb; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) - ulong flags; -#endif - - SMP_RD_BARRIER_DEPENDS(); - - if (tsk->terminated) { - break; - } - skb = dhd_rxf_dequeue(pub); - - if (skb == NULL) { - continue; - } - while (skb) { - void *skbnext = PKTNEXT(pub->osh, skb); - PKTSETNEXT(pub->osh, skb, NULL); - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) - netif_rx_ni(skb); -#else - netif_rx(skb); - local_irq_save(flags); - RAISE_RX_SOFTIRQ(); - local_irq_restore(flags); - -#endif - skb = skbnext; - } - - DHD_OS_WAKE_UNLOCK(pub); - } - else - break; - } - - complete_and_exit(&tsk->completed, 0); -} -#endif /* RXFRAME_THREAD */ #endif /* DHDTHREAD */ static void @@ -2285,8 +2110,7 @@ dhd_sched_dpc(dhd_pub_t *dhdp) DHD_OS_WAKE_LOCK(dhdp); #ifdef DHDTHREAD if (dhd->thr_dpc_ctl.thr_pid >= 0) { - if (!binary_sema_up(&dhd->thr_dpc_ctl)) - DHD_OS_WAKE_UNLOCK(dhdp); + up(&dhd->thr_dpc_ctl.sema); return; } #endif /* DHDTHREAD */ @@ -2295,35 +2119,14 @@ dhd_sched_dpc(dhd_pub_t *dhdp) tasklet_schedule(&dhd->tasklet); } -#if defined(DHDTHREAD) && defined(RXFRAME_THREAD) -static void -dhd_sched_rxf(dhd_pub_t *dhdp, void *skb) +#ifdef TOE +/* Retrieve current toe component enables, which are kept as a bitmap in toe_ol iovar */ +static int +dhd_toe_get(dhd_info_t *dhd, int ifidx, uint32 *toe_ol) { - dhd_info_t *dhd = (dhd_info_t *)dhdp->info; - - DHD_OS_WAKE_LOCK(dhdp); - - DHD_TRACE(("dhd_sched_rxf: Enter\n")); - - do { - if (dhd_rxf_enqueue(dhdp, skb) == BCME_OK) - break; - } while (1); - if (dhd->thr_rxf_ctl.thr_pid >= 0) { - up(&dhd->thr_rxf_ctl.sema); - } - return; -} -#endif /* defined(DHDTHREAD) && defined(RXFRAME_THREAD) */ - -#ifdef TOE -/* Retrieve current toe component enables, which are kept as a bitmap in toe_ol iovar */ -static int -dhd_toe_get(dhd_info_t *dhd, int ifidx, uint32 *toe_ol) -{ - wl_ioctl_t ioc; - char buf[32]; - int ret; + wl_ioctl_t ioc; + char buf[32]; + int ret; memset(&ioc, 0, sizeof(ioc)); @@ -2523,14 +2326,9 @@ dhd_ethtool(dhd_info_t *dhd, void *uaddr static bool dhd_check_hang(struct net_device *net, dhd_pub_t *dhdp, int error) { - dhd_info_t *dhd; - - if (!dhdp) { - DHD_ERROR(("%s: dhdp is NULL\n", __FUNCTION__)); - return FALSE; - } + dhd_info_t * dhd; - if (!dhdp->up) + if (!dhdp) return FALSE; dhd = (dhd_info_t *)dhdp->info; @@ -2549,61 +2347,128 @@ static bool dhd_check_hang(struct net_de return FALSE; } -int dhd_ioctl_process(dhd_pub_t *pub, int ifidx, dhd_ioctl_t *ioc) +static int +dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd) { - int bcmerror = BCME_OK; + dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net); + dhd_ioctl_t ioc; + int bcmerror = 0; int buflen = 0; void *buf = NULL; - struct net_device *net; + uint driver = 0; + int ifidx; + int ret; - net = dhd_idx2net(pub, ifidx); - if (!net) { - bcmerror = BCME_BADARG; + DHD_OS_WAKE_LOCK(&dhd->pub); + + /* send to dongle only if we are not waiting for reload already */ + if (dhd->pub.hang_was_sent) { + DHD_ERROR(("%s: HANG was sent up earlier\n", __FUNCTION__)); + DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE(&dhd->pub, DHD_EVENT_TIMEOUT_MS); + DHD_OS_WAKE_UNLOCK(&dhd->pub); + return OSL_ERROR(BCME_DONGLE_DOWN); + } + + ifidx = dhd_net2idx(dhd, net); + DHD_TRACE(("%s: ifidx %d, cmd 0x%04x\n", __FUNCTION__, ifidx, cmd)); + + if (ifidx == DHD_BAD_IF) { + DHD_ERROR(("%s: BAD IF\n", __FUNCTION__)); + DHD_OS_WAKE_UNLOCK(&dhd->pub); + return -1; + } + +#if defined(CONFIG_WIRELESS_EXT) + /* linux wireless extensions */ + if ((cmd >= SIOCIWFIRST) && (cmd <= SIOCIWLAST)) { + /* may recurse, do NOT lock */ + ret = wl_iw_ioctl(net, ifr, cmd); + DHD_OS_WAKE_UNLOCK(&dhd->pub); + return ret; + } +#endif /* defined(CONFIG_WIRELESS_EXT) */ + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 2) + if (cmd == SIOCETHTOOL) { + ret = dhd_ethtool(dhd, (void*)ifr->ifr_data); + DHD_OS_WAKE_UNLOCK(&dhd->pub); + return ret; + } +#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 2) */ + + if (cmd == SIOCDEVPRIVATE+1) { + ret = wl_android_priv_cmd(net, ifr, cmd); + dhd_check_hang(net, &dhd->pub, ret); + DHD_OS_WAKE_UNLOCK(&dhd->pub); + return ret; + } + + if (cmd != SIOCDEVPRIVATE) { + DHD_OS_WAKE_UNLOCK(&dhd->pub); + return -EOPNOTSUPP; + } + + memset(&ioc, 0, sizeof(ioc)); + + /* Copy the ioc control structure part of ioctl request */ + if (copy_from_user(&ioc, ifr->ifr_data, sizeof(wl_ioctl_t))) { + bcmerror = BCME_BADADDR; goto done; } /* Copy out any buffer passed */ - if (ioc->buf) { - if (ioc->len == 0) { - DHD_TRACE(("%s: ioc->len=0, returns BCME_BADARG \n", __FUNCTION__)); + 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); + buflen = MIN(ioc.len, DHD_IOCTL_MAXLEN); /* optimization for direct ioctl calls from kernel */ /* if (segment_eq(get_fs(), KERNEL_DS)) { - buf = ioc->buf; + buf = ioc.buf; } else { */ { - if (!(buf = MALLOC(pub->osh, buflen + 1))) { + if (!(buf = (char*)MALLOC(dhd->pub.osh, buflen))) { bcmerror = BCME_NOMEM; goto done; } - if (copy_from_user(buf, ioc->buf, buflen)) { + if (copy_from_user(buf, ioc.buf, buflen)) { bcmerror = BCME_BADADDR; goto done; } - *(char *)(buf + buflen) = '\0'; } } + /* To differentiate between wl and dhd read 4 more byes */ + if ((copy_from_user(&driver, (char *)ifr->ifr_data + sizeof(wl_ioctl_t), + sizeof(uint)) != 0)) { + bcmerror = BCME_BADADDR; + goto done; + } + + if (!capable(CAP_NET_ADMIN)) { + bcmerror = BCME_EPERM; + goto done; + } + /* check for local dhd ioctl and handle it */ - if (ioc->driver == DHD_IOCTL_MAGIC) { - bcmerror = dhd_ioctl((void *)pub, ioc, buf, buflen); + if (driver == DHD_IOCTL_MAGIC) { + bcmerror = dhd_ioctl((void *)&dhd->pub, &ioc, buf, buflen); if (bcmerror) - pub->bcmerror = bcmerror; + dhd->pub.bcmerror = bcmerror; goto done; } /* send to dongle (must be up, and wl). */ - if (pub->busstate != DHD_BUS_DATA) { + if (dhd->pub.busstate != DHD_BUS_DATA) { bcmerror = BCME_DONGLE_DOWN; goto done; } - if (!pub->iswl) { + if (!dhd->pub.iswl) { bcmerror = BCME_DONGLE_DOWN; goto done; } @@ -2615,24 +2480,24 @@ int dhd_ioctl_process(dhd_pub_t *pub, in * intercept WLC_DISASSOC IOCTL - serialize WPS-DONE and WLC_DISASSOC IOCTL to * prevent disassoc frame being sent before WPS-DONE frame. */ - if (ioc->cmd == WLC_SET_KEY || - (ioc->cmd == WLC_SET_VAR && ioc->buf != NULL && - strncmp("wsec_key", ioc->buf, 9) == 0) || - (ioc->cmd == WLC_SET_VAR && ioc->buf != NULL && - strncmp("bsscfg:wsec_key", ioc->buf, 15) == 0) || - ioc->cmd == WLC_DISASSOC) + if (ioc.cmd == WLC_SET_KEY || + (ioc.cmd == WLC_SET_VAR && ioc.buf != NULL && + strncmp("wsec_key", ioc.buf, 9) == 0) || + (ioc.cmd == WLC_SET_VAR && ioc.buf != NULL && + strncmp("bsscfg:wsec_key", ioc.buf, 15) == 0) || + ioc.cmd == WLC_DISASSOC) dhd_wait_pend8021x(net); #ifdef WLMEDIA_HTSF - if (ioc->buf) { + if (ioc.buf) { /* short cut wl ioctl calls here */ - if (strcmp("htsf", ioc->buf) == 0) { + if (strcmp("htsf", ioc.buf) == 0) { dhd_ioctl_htsf_get(dhd, 0); return BCME_OK; } - if (strcmp("htsflate", ioc->buf) == 0) { - if (ioc->set) { + if (strcmp("htsflate", ioc.buf) == 0) { + if (ioc.set) { memset(ts, 0, sizeof(tstamp_t)*TSMAX); memset(&maxdelayts, 0, sizeof(tstamp_t)); maxdelay = 0; @@ -2647,7 +2512,7 @@ int dhd_ioctl_process(dhd_pub_t *pub, in } return BCME_OK; } - if (strcmp("htsfclear", ioc->buf) == 0) { + if (strcmp("htsfclear", ioc.buf) == 0) { memset(&vi_d1.bin, 0, sizeof(uint32)*NUMBIN); memset(&vi_d2.bin, 0, sizeof(uint32)*NUMBIN); memset(&vi_d3.bin, 0, sizeof(uint32)*NUMBIN); @@ -2655,16 +2520,16 @@ int dhd_ioctl_process(dhd_pub_t *pub, in htsf_seqnum = 0; return BCME_OK; } - if (strcmp("htsfhis", ioc->buf) == 0) { + if (strcmp("htsfhis", ioc.buf) == 0) { dhd_dump_htsfhisto(&vi_d1, "H to D"); dhd_dump_htsfhisto(&vi_d2, "D to D"); dhd_dump_htsfhisto(&vi_d3, "D to H"); dhd_dump_htsfhisto(&vi_d4, "H to H"); return BCME_OK; } - if (strcmp("tsport", ioc->buf) == 0) { - if (ioc->set) { - memcpy(&tsport, ioc->buf + 7, 4); + if (strcmp("tsport", ioc.buf) == 0) { + if (ioc.set) { + memcpy(&tsport, ioc.buf + 7, 4); } else { DHD_ERROR(("current timestamp port: %d \n", tsport)); } @@ -2673,112 +2538,28 @@ int dhd_ioctl_process(dhd_pub_t *pub, in } #endif /* WLMEDIA_HTSF */ - if ((ioc->cmd == WLC_SET_VAR || ioc->cmd == WLC_GET_VAR) && - ioc->buf != NULL && strncmp("rpc_", ioc->buf, 4) == 0) { + if ((ioc.cmd == WLC_SET_VAR || ioc.cmd == WLC_GET_VAR) && + ioc.buf != NULL && strncmp("rpc_", ioc.buf, 4) == 0) { #ifdef BCM_FD_AGGR - bcmerror = dhd_fdaggr_ioctl(pub, ifidx, (wl_ioctl_t *)ioc, buf, buflen); + bcmerror = dhd_fdaggr_ioctl(&dhd->pub, ifidx, (wl_ioctl_t *)&ioc, buf, buflen); #else bcmerror = BCME_UNSUPPORTED; #endif goto done; } - bcmerror = dhd_wl_ioctl(pub, ifidx, (wl_ioctl_t *)ioc, buf, buflen); + bcmerror = dhd_wl_ioctl(&dhd->pub, ifidx, (wl_ioctl_t *)&ioc, buf, buflen); done: - dhd_check_hang(net, pub, bcmerror); + dhd_check_hang(net, &dhd->pub, bcmerror); - if (!bcmerror && buf && ioc->buf) { - if (copy_to_user(ioc->buf, buf, buflen)) + if (!bcmerror && buf && ioc.buf) { + if (copy_to_user(ioc.buf, buf, buflen)) bcmerror = -EFAULT; } if (buf) - MFREE(pub->osh, buf, buflen + 1); - - return bcmerror; -} - -static int -dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net); - dhd_ioctl_t ioc; - int bcmerror = 0; - int ifidx; - int ret; - - DHD_OS_WAKE_LOCK(&dhd->pub); - - /* send to dongle only if we are not waiting for reload already */ - if (dhd->pub.hang_was_sent) { - DHD_ERROR(("%s: HANG was sent up earlier\n", __FUNCTION__)); - DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE(&dhd->pub, DHD_EVENT_TIMEOUT_MS); - DHD_OS_WAKE_UNLOCK(&dhd->pub); - return OSL_ERROR(BCME_DONGLE_DOWN); - } - - ifidx = dhd_net2idx(dhd, net); - DHD_TRACE(("%s: ifidx %d, cmd 0x%04x\n", __FUNCTION__, ifidx, cmd)); - - if (ifidx == DHD_BAD_IF) { - DHD_ERROR(("%s: BAD IF\n", __FUNCTION__)); - DHD_OS_WAKE_UNLOCK(&dhd->pub); - return -1; - } - -#if defined(WL_WIRELESS_EXT) - /* linux wireless extensions */ - if ((cmd >= SIOCIWFIRST) && (cmd <= SIOCIWLAST)) { - /* may recurse, do NOT lock */ - ret = wl_iw_ioctl(net, ifr, cmd); - DHD_OS_WAKE_UNLOCK(&dhd->pub); - return ret; - } -#endif /* defined(WL_WIRELESS_EXT) */ - -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 2) - if (cmd == SIOCETHTOOL) { - ret = dhd_ethtool(dhd, (void*)ifr->ifr_data); - DHD_OS_WAKE_UNLOCK(&dhd->pub); - return ret; - } -#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 2) */ - - if (cmd == SIOCDEVPRIVATE+1) { - ret = wl_android_priv_cmd(net, ifr, cmd); - dhd_check_hang(net, &dhd->pub, ret); - DHD_OS_WAKE_UNLOCK(&dhd->pub); - return ret; - } - - if (cmd != SIOCDEVPRIVATE) { - DHD_OS_WAKE_UNLOCK(&dhd->pub); - return -EOPNOTSUPP; - } - - memset(&ioc, 0, sizeof(ioc)); - - /* Copy the ioc control structure part of ioctl request */ - if (copy_from_user(&ioc, ifr->ifr_data, sizeof(wl_ioctl_t))) { - bcmerror = BCME_BADADDR; - goto done; - } - - /* To differentiate between wl and dhd read 4 more byes */ - if ((copy_from_user(&ioc.driver, (char *)ifr->ifr_data + sizeof(wl_ioctl_t), - sizeof(uint)) != 0)) { - bcmerror = BCME_BADADDR; - goto done; - } - - if (!capable(CAP_NET_ADMIN)) { - bcmerror = BCME_EPERM; - goto done; - } - - bcmerror = dhd_ioctl_process(&dhd->pub, ifidx, &ioc); + MFREE(dhd->pub.osh, buf, buflen); -done: DHD_OS_WAKE_UNLOCK(&dhd->pub); return OSL_ERROR(bcmerror); @@ -2834,7 +2615,6 @@ dhd_stop(struct net_device *net) dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net); DHD_OS_WAKE_LOCK(&dhd->pub); DHD_TRACE(("%s: Enter %p\n", __FUNCTION__, net)); - if (dhd->pub.up == 0) { goto exit; } @@ -2853,18 +2633,16 @@ dhd_stop(struct net_device *net) * For CFG80211: Clean up all the left over virtual interfaces * when the primary Interface is brought down. [ifconfig wlan0 down] */ - if (!dhd_download_fw_on_driverload) { - if ((dhd->dhd_state & DHD_ATTACH_STATE_ADD_IF) && - (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211)) { - dhd_cleanup_virt_ifaces(dhd); - } + if ((dhd->dhd_state & DHD_ATTACH_STATE_ADD_IF) && + (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211)) { + dhd_cleanup_virt_ifaces(dhd); } } #endif #ifdef PROP_TXSTATUS dhd_os_wlfc_block(&dhd->pub); - dhd_wlfc_cleanup(&dhd->pub, NULL, 0); + dhd_wlfc_cleanup(&dhd->pub); dhd_os_wlfc_unblock(&dhd->pub); #endif /* Stop the protocol module */ @@ -2873,8 +2651,10 @@ dhd_stop(struct net_device *net) OLD_MOD_DEC_USE_COUNT; exit: #if defined(WL_CFG80211) - if (ifidx == 0 && !dhd_download_fw_on_driverload) - wl_android_wifi_off(net); + if (ifidx == 0) { + if (!dhd_download_fw_on_driverload) + wl_android_wifi_off(net); + } #endif dhd->pub.rxcnt_timeout = 0; dhd->pub.txcnt_timeout = 0; @@ -2893,18 +2673,24 @@ dhd_open(struct net_device *net) int ifidx; int32 ret = 0; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 + if (mutex_is_locked(&_dhd_sdio_mutex_lock_) != 0) { + DHD_ERROR(("%s : dhd_open: call dev open before insmod complete!\n", __FUNCTION__)); + } + mutex_lock(&_dhd_sdio_mutex_lock_); +#endif + + printk("%s, firmware path %s\n", __func__, firmware_path); + DHD_OS_WAKE_LOCK(&dhd->pub); /* Update FW path if it was changed */ if (strlen(firmware_path) != 0) { if (firmware_path[strlen(firmware_path)-1] == '\n') firmware_path[strlen(firmware_path)-1] = '\0'; - bzero(fw_path, MOD_PARAM_PATHLEN); - strncpy(fw_path, firmware_path, sizeof(fw_path)-1); - firmware_path[0] = '\0'; + COPY_FW_PATH_BY_CHIP( dhd->pub.bus, fw_path, firmware_path); } - dhd->pub.dongle_trap_occured = 0; dhd->pub.hang_was_sent = 0; #if !defined(WL_CFG80211) @@ -2919,8 +2705,7 @@ dhd_open(struct net_device *net) ret = -1; goto exit; } - -#endif +#endif ifidx = dhd_net2idx(dhd, net); DHD_TRACE(("%s: ifidx %d\n", __FUNCTION__, ifidx)); @@ -2944,11 +2729,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 : wl_android_wifi_on failed (%d)\n", - __FUNCTION__, ret)); + DHD_ERROR(("%s: failed with code %d\n", __FUNCTION__, ret)); ret = -1; goto exit; } + } else { } #endif @@ -2997,6 +2782,10 @@ exit: dhd_stop(net); DHD_OS_WAKE_UNLOCK(&dhd->pub); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 + mutex_unlock(&_dhd_sdio_mutex_lock_); +#endif return ret; } @@ -3009,6 +2798,15 @@ int dhd_do_driver_init(struct net_device return -EINVAL; } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 +#ifdef MULTIPLE_SUPPLICANT + if (mutex_is_locked(&_dhd_sdio_mutex_lock_) != 0) { + DHD_ERROR(("%s : dhdsdio_probe is already running!\n", __FUNCTION__)); + return 0; + } +#endif /* MULTIPLE_SUPPLICANT */ +#endif + dhd = *(dhd_info_t **)netdev_priv(net); /* If driver is already initialized, do nothing @@ -3039,7 +2837,7 @@ 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)) dhd_registration_check = FALSE; up(&dhd_registration_sem); #if defined(BCMLXSDMMC) @@ -3067,7 +2865,7 @@ dhd_add_if(dhd_info_t *dhd, int ifidx, v } } else if ((ifp = MALLOC(dhd->pub.osh, sizeof(dhd_if_t))) == NULL) { - DHD_ERROR(("%s: OOM - dhd_if_t(%d)\n", __FUNCTION__, sizeof(dhd_if_t))); + DHD_ERROR(("%s: OOM - dhd_if_t\n", __FUNCTION__)); return -ENOMEM; } @@ -3077,8 +2875,6 @@ dhd_add_if(dhd_info_t *dhd, int ifidx, v dhd->iflist[ifidx] = ifp; strncpy(ifp->name, name, IFNAMSIZ); ifp->name[IFNAMSIZ] = '\0'; - INIT_LIST_HEAD(&ifp->ipv6_list); - spin_lock_init(&ifp->ipv6_lock); if (mac_addr != NULL) memcpy(&ifp->mac_addr, mac_addr, ETHER_ADDR_LEN); @@ -3155,14 +2951,14 @@ dhd_attach(osl_t *osh, struct dhd_bus *b dhd_attach_states_t dhd_state = DHD_ATTACH_STATE_INIT; DHD_TRACE(("%s: Enter\n", __FUNCTION__)); + printk("%s, firmware path %s\n", __func__, firmware_path); + /* updates firmware nvram path if it was provided as module parameters */ - if (strlen(firmware_path) != 0) { - bzero(fw_path, MOD_PARAM_PATHLEN); - strncpy(fw_path, firmware_path, sizeof(fw_path) - 1); - } + if ((firmware_path != NULL) && (firmware_path[0] != '\0')) + COPY_FW_PATH_BY_CHIP(bus, fw_path, firmware_path); if (strlen(nvram_path) != 0) { - bzero(nv_path, MOD_PARAM_PATHLEN); strncpy(nv_path, nvram_path, sizeof(nv_path) -1); + nv_path[sizeof(nv_path) -1] = '\0'; } /* Allocate etherdev, including space for private structure */ @@ -3173,18 +2969,10 @@ dhd_attach(osl_t *osh, struct dhd_bus *b dhd_state |= DHD_ATTACH_STATE_NET_ALLOC; /* Allocate primary dhd_info */ -#if defined(CONFIG_DHD_USE_STATIC_BUF) - dhd = (void *)dhd_os_prealloc(osh, DHD_PREALLOC_DHD_INFO, sizeof(dhd_info_t)); - if (!dhd) { - DHD_INFO(("%s: OOM - Pre-alloc dhd_info\n", __FUNCTION__)); -#endif /* CONFIG_DHD_USE_STATIC_BUF */ if (!(dhd = MALLOC(osh, sizeof(dhd_info_t)))) { DHD_ERROR(("%s: OOM - alloc dhd_info\n", __FUNCTION__)); goto fail; } -#if defined(CONFIG_DHD_USE_STATIC_BUF) - } -#endif /* CONFIG_DHD_USE_STATIC_BUF */ memset(dhd, 0, sizeof(dhd_info_t)); #ifdef DHDTHREAD @@ -3236,15 +3024,8 @@ dhd_attach(osl_t *osh, struct dhd_bus *b #ifdef PROP_TXSTATUS_VSDB dhd->pub.wlfc_enabled = FALSE; #else - if (!disable_proptx) - dhd->pub.wlfc_enabled = TRUE; - else - dhd->pub.wlfc_enabled = FALSE; + dhd->pub.wlfc_enabled = TRUE; #endif /* PROP_TXSTATUS_VSDB */ - dhd->pub.ptx_opt_enabled = FALSE; - dhd->pub.skip_fc = dhd_wlfc_skip_fc; - dhd->pub.plat_enable = dhd_wlfc_plat_enable; - dhd->pub.plat_deinit = dhd_wlfc_plat_deinit; #endif /* PROP_TXSTATUS */ /* Initialize other structure content */ @@ -3255,12 +3036,6 @@ dhd_attach(osl_t *osh, struct dhd_bus *b spin_lock_init(&dhd->sdlock); spin_lock_init(&dhd->txqlock); spin_lock_init(&dhd->dhd_lock); -#if defined(DHDTHREAD) && defined(RXFRAME_THREAD) - spin_lock_init(&dhd->rxf_lock); -#endif /* defined(DHDTHREAD) && defined(RXFRAME_THREAD) */ -#ifdef DHDTCPACK_SUPPRESS - spin_lock_init(&dhd->tcpack_lock); -#endif /* DHDTCPACK_SUPPRESS */ /* Initialize Wakelock stuff */ spin_lock_init(&dhd->wakelock_spinlock); @@ -3269,12 +3044,20 @@ dhd_attach(osl_t *osh, struct dhd_bus *b dhd->wakelock_rx_timeout_enable = 0; dhd->wakelock_ctrl_timeout_enable = 0; #ifdef CONFIG_HAS_WAKELOCK - wake_lock_init(&dhd->wl_wifi, WAKE_LOCK_SUSPEND, "wlan_wake"); - wake_lock_init(&dhd->wl_rxwake, WAKE_LOCK_SUSPEND, "wlan_rx_wake"); - wake_lock_init(&dhd->wl_ctrlwake, WAKE_LOCK_SUSPEND, "wlan_ctrl_wake"); - wake_lock_init(&dhd->wl_wdwake, WAKE_LOCK_SUSPEND, "wlan_wd_wake"); + dhd->wl_wifi = MALLOC(osh, sizeof(struct wake_lock)); + dhd->wl_rxwake = MALLOC(osh, sizeof(struct wake_lock)); + dhd->wl_ctrlwake = MALLOC(osh, sizeof(struct wake_lock)); + dhd->wl_wdwake = MALLOC(osh, sizeof(struct wake_lock)); + if (!dhd->wl_wifi || !dhd->wl_rxwake || !dhd->wl_ctrlwake || !dhd->wl_wdwake) { + DHD_ERROR(("%s: mem alloc for wake lock failed\n", __FUNCTION__)); + goto fail; + } + wake_lock_init(dhd->wl_wifi, WAKE_LOCK_SUSPEND, "wlan_wake"); + wake_lock_init(dhd->wl_rxwake, WAKE_LOCK_SUSPEND, "wlan_rx_wake"); + wake_lock_init(dhd->wl_ctrlwake, WAKE_LOCK_SUSPEND, "wlan_ctrl_wake"); + wake_lock_init(dhd->wl_wdwake, WAKE_LOCK_SUSPEND, "wlan_wd_wake"); #endif /* CONFIG_HAS_WAKELOCK */ -#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); mutex_init(&dhd->dhd_suspend_mutex); #endif @@ -3297,23 +3080,22 @@ dhd_attach(osl_t *osh, struct dhd_bus *b dhd_monitor_init(&dhd->pub); dhd_state |= DHD_ATTACH_STATE_CFG80211; #endif -#if defined(WL_WIRELESS_EXT) +#if defined(CONFIG_WIRELESS_EXT) /* 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(WL_WIRELESS_EXT) */ +#endif /* defined(CONFIG_WIRELESS_EXT) */ /* Set up the watchdog timer */ init_timer(&dhd->timer); dhd->timer.data = (ulong)dhd; dhd->timer.function = dhd_watchdog; - dhd->default_wd_interval = dhd_watchdog_ms; #ifdef DHDTHREAD /* Initialize thread based operation and lock */ @@ -3327,8 +3109,11 @@ dhd_attach(osl_t *osh, struct dhd_bus *b if (dhd_watchdog_prio >= 0) { /* Initialize watchdog thread */ - PROC_START(dhd_watchdog_thread, dhd, &dhd->thr_wdt_ctl, 0, "dhd_watchdog_thread"); - +#ifdef USE_KTHREAD_API + PROC_START2(dhd_watchdog_thread, dhd, &dhd->thr_wdt_ctl, 0, "dhd_watchdog_thread"); +#else + PROC_START(dhd_watchdog_thread, dhd, &dhd->thr_wdt_ctl, 0); +#endif } else { dhd->thr_wdt_ctl.thr_pid = -1; } @@ -3336,17 +3121,16 @@ dhd_attach(osl_t *osh, struct dhd_bus *b /* Set up the bottom half handler */ if (dhd_dpc_prio >= 0) { /* Initialize DPC thread */ - PROC_START(dhd_dpc_thread, dhd, &dhd->thr_dpc_ctl, 0, "dhd_dpc"); +#ifdef USE_KTHREAD_API + PROC_START2(dhd_dpc_thread, dhd, &dhd->thr_dpc_ctl, 0, "dhd_dpc"); +#else + PROC_START(dhd_dpc_thread, dhd, &dhd->thr_dpc_ctl, 0); +#endif } else { /* use tasklet for dpc */ tasklet_init(&dhd->tasklet, dhd_dpc, (ulong)dhd); dhd->thr_dpc_ctl.thr_pid = -1; } -#ifdef RXFRAME_THREAD - bzero(&dhd->pub.skbbuf[0], sizeof(void *) * MAXSKBPEND); - /* Initialize RXF thread */ - PROC_START(dhd_rxf_thread, dhd, &dhd->thr_rxf_ctl, 0, "dhd_rxf"); -#endif #else /* Set up the bottom half handler */ tasklet_init(&dhd->tasklet, dhd_dpc, (ulong)dhd); @@ -3354,25 +3138,26 @@ dhd_attach(osl_t *osh, struct dhd_bus *b #endif /* DHDTHREAD */ if (dhd_sysioc) { - PROC_START(_dhd_sysioc_thread, dhd, &dhd->thr_sysioc_ctl, 0, "dhd_sysioc"); +#ifdef USE_KTHREAD_API + PROC_START2(_dhd_sysioc_thread, dhd, &dhd->thr_sysioc_ctl, 0, "dhd_sysioc"); +#else + PROC_START(_dhd_sysioc_thread, dhd, &dhd->thr_sysioc_ctl, 0); +#endif } else { dhd->thr_sysioc_ctl.thr_pid = -1; } dhd_state |= DHD_ATTACH_STATE_THREADS_CREATED; - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && (1) INIT_WORK(&dhd->work_hang, dhd_hang_process); #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ - /* * Save the dhd_info into the priv */ memcpy(netdev_priv(net), &dhd, sizeof(dhd)); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && (LINUX_VERSION_CODE <= \ - KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM_SLEEP) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) register_pm_notifier(&dhd_sleep_pm_notifier); -#endif /* (LINUX_VERSION >= 2.6.27 && LINUX_VERSION <= 2.6.39 && CONFIG_PM_SLEEP */ +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */ #if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND) dhd->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 20; @@ -3380,20 +3165,12 @@ dhd_attach(osl_t *osh, struct dhd_bus *b dhd->early_suspend.resume = dhd_late_resume; register_early_suspend(&dhd->early_suspend); dhd_state |= DHD_ATTACH_STATE_EARLYSUSPEND_DONE; -#endif /* CONFIG_HAS_EARLYSUSPEND && DHD_USE_EARLYSUSPEND */ +#endif #ifdef ARP_OFFLOAD_SUPPORT dhd->pend_ipaddr = 0; register_inetaddr_notifier(&dhd_notifier); #endif /* ARP_OFFLOAD_SUPPORT */ -#ifdef IPV6 - register_inet6addr_notifier(&dhd_notifier_ipv6); -#endif - -#ifdef DHDTCPACK_SUPPRESS - dhd->pub.tcp_ack_info_cnt = 0; - bzero(dhd->pub.tcp_ack_info_tbl, sizeof(struct tcp_ack_info)*MAXTCPSTREAMS); -#endif /* DHDTCPACK_SUPPRESS */ dhd_state |= DHD_ATTACH_STATE_DONE; dhd->dhd_state = dhd_state; @@ -3432,19 +3209,8 @@ dhd_bus_start(dhd_pub_t *dhdp) /* try to download image and nvram to the dongle */ if ((dhd->pub.busstate == DHD_BUS_DOWN) && - (fw_path[0] != '\0') && (nv_path[0] != '\0')) { -#ifdef SHOW_NVRAM_TYPE - { /* Show nvram type in the kernel log */ - int i; - for (i = 0; nv_path[i] != '\0'; ++i) { - if (nv_path[i] == '.') { - ++i; - break; - } - } - DHD_ERROR(("%s: nvram_type = [%s]\n", __FUNCTION__, &nv_path[i])); - } -#endif /* SHOW_NVRAM_TYPE */ + (fw_path != NULL) && (fw_path[0] != '\0') && + (nv_path != NULL) && (nv_path[0] != '\0')) { /* wake lock moved to dhdsdio_download_firmware */ if (!(dhd_bus_download_firmware(dhd->pub.bus, dhd->pub.osh, fw_path, nv_path))) { @@ -3479,6 +3245,7 @@ dhd_bus_start(dhd_pub_t *dhdp) #endif /* DHDTHREAD */ return ret; } + bcmsdh_set_drvdata(dhdp); #if defined(OOB_INTR_ONLY) /* Host registration for OOB interrupt */ if (bcmsdh_register_oob_intr(dhdp)) { @@ -3488,7 +3255,6 @@ dhd_bus_start(dhd_pub_t *dhdp) dhd->wd_timer_valid = FALSE; dhd_os_spin_unlock(&dhd->pub, flags); del_timer_sync(&dhd->timer); - DHD_ERROR(("%s Host failed to register for OOB\n", __FUNCTION__)); #ifdef DHDTHREAD if (dhd->threads_only) @@ -3522,13 +3288,23 @@ dhd_bus_start(dhd_pub_t *dhdp) dhd_os_sdunlock(dhdp); #endif /* DHDTHREAD */ - dhd_process_cid_mac(dhdp, TRUE); +#ifdef BCMSDIOH_TXGLOM + if ((dhd->pub.busstate == DHD_BUS_DATA) && bcmsdh_glom_enabled()) { + dhd_txglom_enable(dhdp, TRUE); + } +#endif + +#ifdef READ_MACADDR + dhd_read_macaddr(dhd); +#endif /* Bus is ready, do any protocol initialization */ if ((ret = dhd_prot_init(&dhd->pub)) < 0) return ret; - dhd_process_cid_mac(dhdp, FALSE); +#ifdef WRITE_MACADDR + dhd_write_macaddr(dhd->pub.mac.octet); +#endif #ifdef ARP_OFFLOAD_SUPPORT if (dhd->pend_ipaddr) { @@ -3542,73 +3318,6 @@ dhd_bus_start(dhd_pub_t *dhdp) return 0; } -#ifdef WLTDLS -int _dhd_tdls_enable(dhd_pub_t *dhd, bool tdls_on, bool auto_on, struct ether_addr *mac) -{ - char iovbuf[WLC_IOCTL_SMLEN]; - uint32 tdls = tdls_on; - int ret = 0; - uint32 tdls_auto_op = 0; - uint32 tdls_idle_time = CUSTOM_TDLS_IDLE_MODE_SETTING; - int32 tdls_rssi_high = CUSTOM_TDLS_RSSI_THRESHOLD_HIGH; - int32 tdls_rssi_low = CUSTOM_TDLS_RSSI_THRESHOLD_LOW; - if (!FW_SUPPORTED(dhd, tdls)) - return BCME_ERROR; - - if (dhd->tdls_enable == tdls_on) - goto auto_mode; - bcm_mkiovar("tdls_enable", (char *)&tdls, sizeof(tdls), iovbuf, sizeof(iovbuf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) { - DHD_ERROR(("%s: tdls %d failed %d\n", __FUNCTION__, tdls, ret)); - goto exit; - } - dhd->tdls_enable = tdls_on; -auto_mode: - if (mac) { - tdls_auto_op = auto_on; - bcm_mkiovar("tdls_auto_op", (char *)&tdls_auto_op, sizeof(tdls_auto_op), - iovbuf, sizeof(iovbuf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, - sizeof(iovbuf), TRUE, 0)) < 0) { - DHD_ERROR(("%s: tdls_auto_op failed %d\n", __FUNCTION__, ret)); - goto exit; - } - - if (tdls_auto_op) { - bcm_mkiovar("tdls_idle_time", (char *)&tdls_idle_time, - sizeof(tdls_idle_time), iovbuf, sizeof(iovbuf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, - sizeof(iovbuf), TRUE, 0)) < 0) { - DHD_ERROR(("%s: tdls_idle_time failed %d\n", __FUNCTION__, ret)); - goto exit; - } - bcm_mkiovar("tdls_rssi_high", (char *)&tdls_rssi_high, 4, iovbuf, sizeof(iovbuf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) { - DHD_ERROR(("%s: tdls_rssi_high failed %d\n", __FUNCTION__, ret)); - goto exit; - } - bcm_mkiovar("tdls_rssi_low", (char *)&tdls_rssi_low, 4, iovbuf, sizeof(iovbuf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) { - DHD_ERROR(("%s: tdls_rssi_low failed %d\n", __FUNCTION__, ret)); - goto exit; - } - } - } -exit: - return ret; -} -int dhd_tdls_enable(struct net_device *dev, bool tdls_on, bool auto_on, struct ether_addr *mac) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - int ret = 0; - if (dhd) - ret = _dhd_tdls_enable(&dhd->pub, tdls_on, auto_on, mac); - else - ret = BCME_ERROR; - return ret; -} -#endif /* WLTDLS */ - bool dhd_is_concurrent_mode(dhd_pub_t *dhd) { if (!dhd) @@ -3640,10 +3349,18 @@ dhd_get_concurrent_capabilites(dhd_pub_t */ if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) return 0; - if (FW_SUPPORTED(dhd, vsdb)) { + memset(buf, 0, sizeof(buf)); + bcm_mkiovar("cap", 0, 0, buf, sizeof(buf)); + if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, sizeof(buf), + FALSE, 0)) < 0) { + DHD_ERROR(("%s: Get Capability failed (error=%d)\n", + __FUNCTION__, ret)); + return 0; + } + if (strstr(buf, "vsdb")) { mchan_supported = TRUE; } - if (!FW_SUPPORTED(dhd, p2p)) { + if (strstr(buf, "p2p") == NULL) { DHD_TRACE(("Chip does not support p2p\n")); return 0; } @@ -3664,7 +3381,7 @@ dhd_get_concurrent_capabilites(dhd_pub_t ret = DHD_FLAG_CONCURR_SINGLE_CHAN_MODE; if (mchan_supported) ret |= DHD_FLAG_CONCURR_MULTI_CHAN_MODE; -#if defined(WL_ENABLE_P2P_IF) || defined(WL_CFG80211_P2P_DEV_IF) +#if defined(WL_ENABLE_P2P_IF) /* For customer_hw4, although ICS, * we still support concurrent mode */ @@ -3677,21 +3394,28 @@ dhd_get_concurrent_capabilites(dhd_pub_t } return 0; } -#endif +#endif int dhd_preinit_ioctls(dhd_pub_t *dhd) { int ret = 0; char eventmask[WL_EVENTING_MASK_LEN]; char iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + '\0' + bitvec */ - uint32 buf_key_b4_m4 = 1; -#ifdef CUSTOM_AMPDU_BA_WSIZE - uint32 ampdu_ba_wsize = CUSTOM_AMPDU_BA_WSIZE; -#endif /* CUSTOM_AMPDU_BA_WSIZE */ + +#if !defined(WL_CFG80211) + uint up = 0; +#endif /* !defined(WL_CFG80211) */ uint power_mode = PM_FAST; uint32 dongle_align = DHD_SDALIGN; uint32 glom = CUSTOM_GLOM_SETTING; +#if defined(VSDB) || defined(ROAM_ENABLE) + uint bcn_timeout = 8; +#else uint bcn_timeout = 4; +#endif +#ifdef ENABLE_BCN_LI_BCN_WAKEUP + uint32 bcn_li_bcn = 1; +#endif /* ENABLE_BCN_LI_BCN_WAKEUP */ uint retry_max = 3; #if defined(ARP_OFFLOAD_SUPPORT) int arpoe = 1; @@ -3701,15 +3425,12 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) int scan_passive_time = DHD_SCAN_PASSIVE_TIME; char buf[WLC_IOCTL_SMLEN]; char *ptr; - uint32 listen_interval = CUSTOM_LISTEN_INTERVAL; /* Default Listen Interval in Beacons */ + uint32 listen_interval = LISTEN_INTERVAL; /* Default Listen Interval in Beacons */ #ifdef ROAM_ENABLE uint roamvar = 0; int roam_trigger[2] = {CUSTOM_ROAM_TRIGGER_SETTING, WLC_BAND_ALL}; int roam_scan_period[2] = {10, WLC_BAND_ALL}; int roam_delta[2] = {CUSTOM_ROAM_DELTA_SETTING, WLC_BAND_ALL}; -#ifdef ROAM_AP_ENV_DETECTION - int roam_env_mode = AP_ENV_INDETERMINATE; -#endif /* ROAM_AP_ENV_DETECTION */ #ifdef FULL_ROAMING_SCAN_PERIOD_60_SEC int roam_fullscan_period = 60; #else /* FULL_ROAMING_SCAN_PERIOD_60_SEC */ @@ -3728,6 +3449,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) uint32 mpc = 0; /* Turn MPC off for AP/APSTA mode */ struct ether_addr p2p_ea; #endif + uint32 mimo_bw_cap = 1; /* Turn HT40 on in 2.4 GHz */ #if defined(AP) || defined(WLP2P) uint32 apsta = 1; /* Enable APSTA mode */ @@ -3735,36 +3457,22 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) #ifdef GET_CUSTOM_MAC_ENABLE struct ether_addr ea_addr; #endif /* GET_CUSTOM_MAC_ENABLE */ - #ifdef DISABLE_11N uint32 nmode = 0; +#else +#ifdef AMPDU_HOSTREORDER + uint32 hostreorder = 1; +#endif #endif /* DISABLE_11N */ -#ifdef USE_WL_TXBF - uint32 txbf = 1; -#endif /* USE_WL_TXBF */ -#ifdef USE_WL_FRAMEBURST - uint32 frameburst = 1; -#endif /* USE_WL_FRAMEBURST */ -#ifdef SUPPORT_2G_VHT - uint32 vht_features = 0x3; /* 2G enable | rates all */ -#endif /* SUPPORT_2G_VHT */ + dhd->suspend_bcn_li_dtim = CUSTOM_SUSPEND_BCN_LI_DTIM; #ifdef PROP_TXSTATUS #ifdef PROP_TXSTATUS_VSDB - /* In case the host does not support proptxstatus, hostreorder in dongle should be off */ - uint32 hostreorder = 0; dhd->wlfc_enabled = FALSE; /* enable WLFC only if the firmware is VSDB */ #else - if (!disable_proptx) - dhd->wlfc_enabled = TRUE; - else - dhd->wlfc_enabled = FALSE; + dhd->wlfc_enabled = TRUE; #endif /* PROP_TXSTATUS_VSDB */ #endif /* PROP_TXSTATUS */ -#ifdef WLTDLS - dhd->tdls_enable = FALSE; -#endif /* WLTDLS */ - dhd->suspend_bcn_li_dtim = CUSTOM_SUSPEND_BCN_LI_DTIM; DHD_TRACE(("Enter %s\n", __FUNCTION__)); dhd->op_mode = 0; #ifdef GET_CUSTOM_MAC_ENABLE @@ -3796,16 +3504,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) #endif /* GET_CUSTOM_MAC_ENABLE */ DHD_TRACE(("Firmware = %s\n", fw_path)); - /* get a capabilities from firmware */ - memset(dhd->fw_capabilities, 0, sizeof(dhd->fw_capabilities)); - bcm_mkiovar("cap", 0, 0, dhd->fw_capabilities, sizeof(dhd->fw_capabilities)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, dhd->fw_capabilities, - sizeof(dhd->fw_capabilities), FALSE, 0)) < 0) { - DHD_ERROR(("%s: Get Capability failed (error=%d)\n", - __FUNCTION__, ret)); - return 0; - } - DHD_TRACE(("Firmare Capabilities: %s\n", dhd->fw_capabilities)); + if ((!op_mode && strstr(fw_path, "_apsta") != NULL) || (op_mode == DHD_FLAG_HOSTAP_MODE)) { #ifdef SET_RANDOM_MAC_SOFTAP @@ -3819,8 +3518,8 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) dhd_pkt_filter_enable = FALSE; #endif #ifdef SET_RANDOM_MAC_SOFTAP - SRANDOM32((uint)jiffies); - rand_mac = RANDOM32(); + srandom32((uint)jiffies); + rand_mac = random32(); iovbuf[0] = 0x02; /* locally administered bit */ iovbuf[1] = 0x1A; iovbuf[2] = 0x11; @@ -3843,6 +3542,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) DHD_ERROR(("%s mpc for HostAPD failed %d\n", __FUNCTION__, ret)); } #endif + } else { uint32 concurrent_mode = 0; @@ -3855,15 +3555,11 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) dhd_pkt_filter_enable = FALSE; #endif dhd->op_mode = DHD_FLAG_P2P_MODE; - } else if (op_mode == DHD_FLAG_IBSS_MODE || - (!op_mode && strstr(fw_path, "_ibss") != NULL)) { - dhd->op_mode = DHD_FLAG_IBSS_MODE; - } else { - dhd->op_mode = DHD_FLAG_STA_MODE; } + else + dhd->op_mode = DHD_FLAG_STA_MODE; #if !defined(AP) && defined(WLP2P) - if (dhd->op_mode != DHD_FLAG_IBSS_MODE && - (concurrent_mode = dhd_get_concurrent_capabilites(dhd))) { + if ((concurrent_mode = dhd_get_concurrent_capabilites(dhd))) { #if defined(ARP_OFFLOAD_SUPPORT) arpoe = 1; #endif @@ -3916,7 +3612,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf)); dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); #endif /* ROAM_ENABLE || DISABLE_BUILTIN_ROAM */ -#if defined(ROAM_ENABLE) +#ifdef ROAM_ENABLE if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_ROAM_TRIGGER, roam_trigger, sizeof(roam_trigger), TRUE, 0)) < 0) DHD_ERROR(("%s: roam trigger set failed %d\n", __FUNCTION__, ret)); @@ -3929,24 +3625,8 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) bcm_mkiovar("fullroamperiod", (char *)&roam_fullscan_period, 4, iovbuf, sizeof(iovbuf)); if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) DHD_ERROR(("%s: roam fullscan period set failed %d\n", __FUNCTION__, ret)); -#ifdef ROAM_AP_ENV_DETECTION - if (roam_trigger[0] == WL_AUTO_ROAM_TRIGGER) { - bcm_mkiovar("roam_env_detection", (char *)&roam_env_mode, - 4, iovbuf, sizeof(iovbuf)); - if (dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0) == BCME_OK) - dhd->roam_env_detection = TRUE; - else { - dhd->roam_env_detection = FALSE; - } - } -#endif /* ROAM_AP_ENV_DETECTION */ #endif /* ROAM_ENABLE */ -#ifdef WLTDLS - /* by default TDLS on and auto mode off */ - _dhd_tdls_enable(dhd, true, false, NULL); -#endif /* WLTDLS */ - /* Set PowerSave mode */ dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode, sizeof(power_mode), TRUE, 0); @@ -3974,6 +3654,11 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); #endif /* defined(AP) && !defined(WLP2P) */ + if (dhd_bus_chip_id(dhd) == BCM43341_CHIP_ID || dhd_bus_chip_id(dhd) == BCM4324_CHIP_ID) { + /* Turn on HT40 in 2.4 GHz */ + bcm_mkiovar("mimo_bw_cap", (char *)&mimo_bw_cap, 4, iovbuf, sizeof(iovbuf)); + dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); + } #if defined(SOFTAP) if (ap_fw_loaded == TRUE) { @@ -3996,41 +3681,6 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) } } #endif /* defined(KEEP_ALIVE) */ -#ifdef USE_WL_TXBF - bcm_mkiovar("txbf", (char *)&txbf, 4, iovbuf, sizeof(iovbuf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, - sizeof(iovbuf), TRUE, 0)) < 0) { - DHD_ERROR(("%s Set txbf failed %d\n", __FUNCTION__, ret)); - } -#endif /* USE_WL_TXBF */ -#ifdef USE_WL_FRAMEBURST - /* Set frameburst to value */ - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_FAKEFRAG, (char *)&frameburst, - sizeof(frameburst), TRUE, 0)) < 0) { - DHD_ERROR(("%s Set frameburst failed %d\n", __FUNCTION__, ret)); - } -#endif /* USE_WL_FRAMEBURST */ -#ifdef CUSTOM_AMPDU_BA_WSIZE - /* Set ampdu ba wsize to 64 */ - bcm_mkiovar("ampdu_ba_wsize", (char *)&du_ba_wsize, 4, iovbuf, sizeof(iovbuf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, - sizeof(iovbuf), TRUE, 0)) < 0) { - DHD_ERROR(("%s Set ampdu_ba_wsize to %d failed %d\n", - __FUNCTION__, CUSTOM_AMPDU_BA_WSIZE, ret)); - } -#endif /* CUSTOM_AMPDU_BA_WSIZE */ -#ifdef SUPPORT_2G_VHT - bcm_mkiovar("vht_features", (char *)&vht_features, 4, iovbuf, sizeof(iovbuf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) { - DHD_ERROR(("%s vht_features set failed %d\n", __FUNCTION__, ret)); - } -#endif /* SUPPORT_2G_VHT */ - - bcm_mkiovar("buf_key_b4_m4", (char *)&buf_key_b4_m4, 4, iovbuf, sizeof(iovbuf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, - sizeof(iovbuf), TRUE, 0)) < 0) { - DHD_ERROR(("%s buf_key_b4_m4 set failed %d\n", __FUNCTION__, ret)); - } /* Read event_msgs mask */ bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf, sizeof(iovbuf)); @@ -4052,7 +3702,6 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) setbit(eventmask, WLC_E_DISASSOC_IND); setbit(eventmask, WLC_E_DISASSOC); setbit(eventmask, WLC_E_JOIN); - setbit(eventmask, WLC_E_START); setbit(eventmask, WLC_E_ASSOC_IND); setbit(eventmask, WLC_E_PSK_SUP); setbit(eventmask, WLC_E_LINK); @@ -4071,15 +3720,9 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) #endif /* WLMEDIA_HTSF */ #ifdef PNO_SUPPORT setbit(eventmask, WLC_E_PFN_NET_FOUND); - setbit(eventmask, WLC_E_PFN_BEST_BATCHING); - setbit(eventmask, WLC_E_PFN_BSSID_NET_FOUND); - setbit(eventmask, WLC_E_PFN_BSSID_NET_LOST); #endif /* PNO_SUPPORT */ /* enable dongle roaming event */ setbit(eventmask, WLC_E_ROAM); -#ifdef WLTDLS - setbit(eventmask, WLC_E_TDLS_PEER_EVENT); -#endif /* WLTDLS */ #ifdef WL_CFG80211 setbit(eventmask, WLC_E_ESCAN_RESULT); if (dhd->op_mode & DHD_FLAG_P2P_MODE) { @@ -4120,36 +3763,46 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) #ifdef PKT_FILTER_SUPPORT /* Setup default defintions for pktfilter , enable in suspend */ - dhd->pktfilter_count = 6; + dhd->pktfilter_count = 5; /* Setup filter to allow only unicast */ - dhd->pktfilter[DHD_UNICAST_FILTER_NUM] = "100 0 0 0 0x01 0x00"; - dhd->pktfilter[DHD_BROADCAST_FILTER_NUM] = NULL; - dhd->pktfilter[DHD_MULTICAST4_FILTER_NUM] = NULL; - dhd->pktfilter[DHD_MULTICAST6_FILTER_NUM] = NULL; + dhd->pktfilter[0] = "100 0 0 0 0x01 0x00"; + dhd->pktfilter[1] = NULL; + dhd->pktfilter[2] = NULL; + dhd->pktfilter[3] = NULL; /* Add filter to pass multicastDNS packet and NOT filter out as Broadcast */ - dhd->pktfilter[DHD_MDNS_FILTER_NUM] = "104 0 0 0 0xFFFFFFFFFFFF 0x01005E0000FB"; - /* apply APP pktfilter */ - dhd->pktfilter[DHD_ARP_FILTER_NUM] = "105 0 0 12 0xFFFF 0x0806"; + dhd->pktfilter[4] = "104 0 0 0 0xFFFFFFFFFFFF 0x01005E0000FB"; + dhd_set_packet_filter(dhd); #if defined(SOFTAP) if (ap_fw_loaded) { dhd_enable_packet_filter(0, dhd); } #endif /* defined(SOFTAP) */ - dhd_set_packet_filter(dhd); + #endif /* PKT_FILTER_SUPPORT */ #ifdef DISABLE_11N bcm_mkiovar("nmode", (char *)&nmode, 4, iovbuf, sizeof(iovbuf)); if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) DHD_ERROR(("%s wl nmode 0 failed %d\n", __FUNCTION__, ret)); #else -#if defined(PROP_TXSTATUS) && defined(PROP_TXSTATUS_VSDB) +#ifdef AMPDU_HOSTREORDER bcm_mkiovar("ampdu_hostreorder", (char *)&hostreorder, 4, buf, sizeof(buf)); dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, sizeof(buf), TRUE, 0); -#endif +#endif /* AMPDU_HOSTREORDER */ #endif /* DISABLE_11N */ +#if !defined(WL_CFG80211) + /* Force STA UP */ + if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_UP, (char *)&up, sizeof(up), TRUE, 0)) < 0) { + DHD_ERROR(("%s Setting WL UP failed %d\n", __FUNCTION__, ret)); + goto done; + } +#endif +#ifdef ENABLE_BCN_LI_BCN_WAKEUP + bcm_mkiovar("bcn_li_bcn", (char *)&bcn_li_bcn, 4, iovbuf, sizeof(iovbuf)); + dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); +#endif /* ENABLE_BCN_LI_BCN_WAKEUP */ /* query for 'ver' to get version info from firmware */ memset(buf, 0, sizeof(buf)); @@ -4161,8 +3814,12 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) bcmstrtok(&ptr, "\n", 0); /* Print fw version info */ DHD_ERROR(("Firmware version = %s\n", buf)); + dhd_set_version_info(dhd, buf); + DHD_BLOG(buf, strlen(buf) + 1); + DHD_BLOG(dhd_version, strlen(dhd_version) + 1); + /* Check and adjust IOCTL response timeout for Manufactring firmware */ if (strstr(buf, MANUFACTRING_FW) != NULL) { dhd_os_set_ioctl_resp_timeout(20000); @@ -4171,21 +3828,6 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) } } -#ifdef BCMSDIOH_TXGLOM - if (bcmsdh_glom_enabled()) { - dhd_txglom_enable(dhd, TRUE); - } -#endif /* BCMSDIOH_TXGLOM */ - -#if defined(PROP_TXSTATUS) && !defined(PROP_TXSTATUS_VSDB) - dhd_wlfc_init(dhd); -#endif /* PROP_TXSTATUS && !PROP_TXSTATUS_VSDB */ -#ifdef PNO_SUPPORT - if (!dhd->pno_state) { - dhd_pno_init(dhd); - } -#endif - done: return ret; } @@ -4206,7 +3848,7 @@ dhd_iovar(dhd_pub_t *pub, int ifidx, cha ioc.cmd = set? WLC_SET_VAR : WLC_GET_VAR; ioc.buf = buf; ioc.len = len; - ioc.set = set; + ioc.set = TRUE; ret = dhd_wl_ioctl(pub, ifidx, &ioc, ioc.buf, ioc.len); if (!set && ret >= 0) @@ -4317,9 +3959,9 @@ static int dhd_device_event(struct notif /* Filter notifications meant for non Broadcom devices */ if ((ifa->ifa_dev->dev->netdev_ops != &dhd_ops_pri) && (ifa->ifa_dev->dev->netdev_ops != &dhd_ops_virt)) { -#if defined(WL_ENABLE_P2P_IF) +#ifdef WLP2P if (!wl_cfgp2p_is_ifops(ifa->ifa_dev->dev->netdev_ops)) -#endif /* WL_ENABLE_P2P_IF */ +#endif return NOTIFY_DONE; } #endif /* LINUX_VERSION_CODE */ @@ -4362,99 +4004,35 @@ static int dhd_device_event(struct notif break; } -#ifdef AOE_IP_ALIAS_SUPPORT - DHD_ARPOE(("%s:add aliased IP to AOE hostip cache\n", - __FUNCTION__)); - aoe_update_host_ipv4_table(dhd_pub, ifa->ifa_address, TRUE, idx); -#endif /* AOE_IP_ALIAS_SUPPORT */ - break; - - case NETDEV_DOWN: - DHD_ARPOE(("%s: [%s] Down IP: 0x%x\n", - __FUNCTION__, ifa->ifa_label, ifa->ifa_address)); - dhd->pend_ipaddr = 0; -#ifdef AOE_IP_ALIAS_SUPPORT - DHD_ARPOE(("%s:interface is down, AOE clr all for this if\n", - __FUNCTION__)); - aoe_update_host_ipv4_table(dhd_pub, ifa->ifa_address, FALSE, idx); -#else - dhd_aoe_hostip_clr(&dhd->pub, idx); - dhd_aoe_arp_clr(&dhd->pub, idx); -#endif /* AOE_IP_ALIAS_SUPPORT */ - break; - - default: - DHD_ARPOE(("%s: do noting for [%s] Event: %lu\n", - __func__, ifa->ifa_label, event)); - break; - } - return NOTIFY_DONE; -} -#endif /* ARP_OFFLOAD_SUPPORT */ - -/* - * Neighbor Discovery Offload: Called when an interface - * is assigned with ipv6 address. - * Handles only primary interface - */ -static int dhd_device_ipv6_event(struct notifier_block *this, - unsigned long event, - void *ptr) -{ - dhd_info_t *dhd; - dhd_pub_t *dhd_pub; - struct ipv6_addr *_ipv6_addr = NULL; - struct inet6_ifaddr *inet6_ifa = ptr; - int idx = 0; - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)) - /* Filter notifications meant for non Broadcom devices */ - if (inet6_ifa->idev->dev->netdev_ops != &dhd_ops_pri) { - goto exit; - } -#endif /* LINUX_VERSION_CODE */ - - dhd = *(dhd_info_t **)netdev_priv(inet6_ifa->idev->dev); - if (!dhd) - goto exit; - - idx = dhd_net2idx(dhd, inet6_ifa->idev->dev); - if (idx == DHD_BAD_IF) { - DHD_ERROR(("Cannot find ifidx")); - goto exit; - } - dhd_pub = &dhd->pub; - if (!FW_SUPPORTED(dhd_pub, ndoe)) - goto exit; - if (event == NETDEV_UP || event == NETDEV_DOWN) { - _ipv6_addr = NATIVE_MALLOC(dhd_pub->osh, sizeof(struct ipv6_addr)); - if (_ipv6_addr == NULL) { - DHD_ERROR(("Failed to allocate ipv6\n")); - goto exit; - } - memcpy(&_ipv6_addr->ipv6_addr[0], &inet6_ifa->addr, IPV6_ADDR_LEN); - DHD_TRACE(("IPV6 address : %pI6\n", &inet6_ifa->addr)); - } - switch (event) { - case NETDEV_UP: - DHD_TRACE(("%s: Enable NDO and add ipv6 into table \n ", __FUNCTION__)); - _ipv6_addr->ipv6_oper = DHD_IPV6_ADDR_ADD; +#ifdef AOE_IP_ALIAS_SUPPORT + DHD_ARPOE(("%s:add aliased IP to AOE hostip cache\n", + __FUNCTION__)); + aoe_update_host_ipv4_table(dhd_pub, ifa->ifa_address, TRUE, idx); +#endif break; + case NETDEV_DOWN: - DHD_TRACE(("%s: clear ipv6 table \n", __FUNCTION__)); - _ipv6_addr->ipv6_oper = DHD_IPV6_ADDR_DELETE; + DHD_ARPOE(("%s: [%s] Down IP: 0x%x\n", + __FUNCTION__, ifa->ifa_label, ifa->ifa_address)); + dhd->pend_ipaddr = 0; +#ifdef AOE_IP_ALIAS_SUPPORT + DHD_ARPOE(("%s:interface is down, AOE clr all for this if\n", + __FUNCTION__)); + aoe_update_host_ipv4_table(dhd_pub, ifa->ifa_address, FALSE, idx); +#else + dhd_aoe_hostip_clr(&dhd->pub, idx); + dhd_aoe_arp_clr(&dhd->pub, idx); +#endif /* AOE_IP_ALIAS_SUPPORT */ break; + default: - DHD_ERROR(("%s: unknown notifier event \n", __FUNCTION__)); - goto exit; + DHD_ARPOE(("%s: do noting for [%s] Event: %lu\n", + __func__, ifa->ifa_label, event)); + break; } - spin_lock_bh(&dhd->iflist[idx]->ipv6_lock); - list_add_tail(&_ipv6_addr->list, &dhd->iflist[idx]->ipv6_list); - spin_unlock_bh(&dhd->iflist[idx]->ipv6_lock); - up(&dhd->thr_sysioc_ctl.sema); -exit: return NOTIFY_DONE; } +#endif /* ARP_OFFLOAD_SUPPORT */ int dhd_net_attach(dhd_pub_t *dhdp, int ifidx) @@ -4520,20 +4098,19 @@ dhd_net_attach(dhd_pub_t *dhdp, int ifid net->ethtool_ops = &dhd_ethtool_ops; #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) */ -#if defined(WL_WIRELESS_EXT) +#if defined(CONFIG_WIRELESS_EXT) #if WIRELESS_EXT < 19 net->get_wireless_stats = dhd_get_wireless_stats; #endif /* WIRELESS_EXT < 19 */ #if WIRELESS_EXT > 12 net->wireless_handlers = (struct iw_handler_def *)&wl_iw_handler_def; #endif /* WIRELESS_EXT > 12 */ -#endif /* defined(WL_WIRELESS_EXT) */ +#endif /* defined(CONFIG_WIRELESS_EXT) */ dhd->pub.rxsz = DBUS_RX_BUFFER_SIZE_DHD(net); memcpy(net->dev_addr, temp_addr, ETHER_ADDR_LEN); - net->ifindex = 0; if ((err = register_netdev(net)) != 0) { DHD_ERROR(("couldn't register the net device, err %d\n", err)); goto fail; @@ -4543,11 +4120,11 @@ dhd_net_attach(dhd_pub_t *dhdp, int ifid net->name, MAC2STRDBG(net->dev_addr)); -#if defined(SOFTAP) && defined(WL_WIRELESS_EXT) && !defined(WL_CFG80211) +#if defined(SOFTAP) && defined(CONFIG_WIRELESS_EXT) && !defined(WL_CFG80211) 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) { dhd_registration_check = TRUE; up(&dhd_registration_sem); @@ -4609,19 +4186,13 @@ void dhd_detach(dhd_pub_t *dhdp) return; DHD_TRACE(("%s: Enter state 0x%x\n", __FUNCTION__, dhd->dhd_state)); -#ifdef ARP_OFFLOAD_SUPPORT - unregister_inetaddr_notifier(&dhd_notifier); -#endif /* ARP_OFFLOAD_SUPPORT */ -#ifdef IPV6 - unregister_inet6addr_notifier(&dhd_notifier_ipv6); -#endif dhd->pub.up = 0; if (!(dhd->dhd_state & DHD_ATTACH_STATE_DONE)) { /* Give sufficient time for threads to start running in case * dhd_attach() has failed */ - OSL_SLEEP(100); + osl_delay(1000*100); } if (dhd->dhd_state & DHD_ATTACH_STATE_PROT_ATTACH) { @@ -4630,23 +4201,28 @@ void dhd_detach(dhd_pub_t *dhdp) if (dhdp->prot) dhd_prot_detach(dhdp); } + +#ifdef ARP_OFFLOAD_SUPPORT + unregister_inetaddr_notifier(&dhd_notifier); +#endif /* ARP_OFFLOAD_SUPPORT */ + #if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND) if (dhd->dhd_state & DHD_ATTACH_STATE_EARLYSUSPEND_DONE) { if (dhd->early_suspend.suspend) unregister_early_suspend(&dhd->early_suspend); } -#endif /* CONFIG_HAS_EARLYSUSPEND && DHD_USE_EARLYSUSPEND */ +#endif /* defined(CONFIG_HAS_EARLYSUSPEND) */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) cancel_work_sync(&dhd->work_hang); #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ -#if defined(WL_WIRELESS_EXT) +#if defined(CONFIG_WIRELESS_EXT) if (dhd->dhd_state & DHD_ATTACH_STATE_WL_ATTACH) { /* Detatch and unlink in the iw */ wl_iw_detach(); } -#endif /* defined(WL_WIRELESS_EXT) */ +#endif /* defined(CONFIG_WIRELESS_EXT) */ if (dhd->thr_sysioc_ctl.thr_pid >= 0) { PROC_STOP(&dhd->thr_sysioc_ctl); @@ -4705,15 +4281,11 @@ void dhd_detach(dhd_pub_t *dhdp) if (dhd->thr_dpc_ctl.thr_pid >= 0) { PROC_STOP(&dhd->thr_dpc_ctl); } -#ifdef RXFRAME_THREAD - if (dhd->thr_rxf_ctl.thr_pid >= 0) { - PROC_STOP(&dhd->thr_rxf_ctl); - } -#endif else #endif /* DHDTHREAD */ tasklet_kill(&dhd->tasklet); } + #ifdef WL_CFG80211 if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211) { wl_cfg80211_detach(NULL); @@ -4721,26 +4293,38 @@ void dhd_detach(dhd_pub_t *dhdp) } #endif -#ifdef PNO_SUPPORT - if (dhdp->pno_state) - dhd_pno_deinit(dhdp); -#endif -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && (LINUX_VERSION_CODE <= \ - KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM_SLEEP) + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) unregister_pm_notifier(&dhd_sleep_pm_notifier); -#endif /* (LINUX_VERSION >= 2.6.27 && LINUX_VERSION <= 2.6.39 && CONFIG_PM_SLEEP */ +#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) { - DHD_TRACE(("wd wakelock count:%d\n", dhd->wakelock_wd_counter)); #ifdef CONFIG_HAS_WAKELOCK dhd->wakelock_counter = 0; dhd->wakelock_wd_counter = 0; dhd->wakelock_rx_timeout_enable = 0; dhd->wakelock_ctrl_timeout_enable = 0; - wake_lock_destroy(&dhd->wl_wifi); - wake_lock_destroy(&dhd->wl_rxwake); - wake_lock_destroy(&dhd->wl_ctrlwake); - wake_lock_destroy(&dhd->wl_wdwake); + if (dhd->wl_wifi) { + wake_lock_destroy(dhd->wl_wifi); + MFREE(dhd->pub.osh, dhd->wl_wifi, sizeof(struct wake_lock)); + dhd->wl_wifi = NULL; + } + if (dhd->wl_rxwake) { + wake_lock_destroy(dhd->wl_rxwake); + MFREE(dhd->pub.osh, dhd->wl_rxwake, sizeof(struct wake_lock)); + dhd->wl_rxwake = NULL; + } + if (dhd->wl_ctrlwake) { + wake_lock_destroy(dhd->wl_ctrlwake); + MFREE(dhd->pub.osh, dhd->wl_ctrlwake, sizeof(struct wake_lock)); + dhd->wl_ctrlwake = NULL; + } + if (dhd->wl_wdwake) { + wake_lock_destroy(dhd->wl_wdwake); + MFREE(dhd->pub.osh, dhd->wl_wdwake, sizeof(struct wake_lock)); + dhd->wl_wdwake = NULL; + } #endif /* CONFIG_HAS_WAKELOCK */ } } @@ -4770,19 +4354,8 @@ dhd_free(dhd_pub_t *dhdp) } } dhd = (dhd_info_t *)dhdp->info; -#if defined(CONFIG_DHD_USE_STATIC_BUF) - /* If pointer is allocated by dhd_os_prealloc then avoid MFREE */ - if (dhd != (dhd_info_t *)dhd_os_prealloc(NULL, DHD_PREALLOC_DHD_INFO, 0)) { -#endif /* CONFIG_DHD_USE_STATIC_BUF */ - if (dhd) - MFREE(dhd->pub.osh, dhd, sizeof(*dhd)); -#if defined(CONFIG_DHD_USE_STATIC_BUF) - } - else { - if (dhd) - dhd = NULL; - } -#endif /* CONFIG_DHD_USE_STATIC_BUF */ + if (dhd) + MFREE(dhd->pub.osh, dhd, sizeof(*dhd)); } } @@ -4800,25 +4373,35 @@ dhd_module_cleanup(void) /* Call customer gpio to turn off power with WL_REG_ON signal */ dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF); -} + if (wl_host_wake > 0) + gpio_free(wl_host_wake); + wl_host_wake = -1; +} -#if defined(CONFIG_WIFI_CONTROL_FUNC) -extern bool g_wifi_poweron; -#endif /* CONFIG_WIFI_CONTROL_FUNC */ static int __init dhd_module_init(void) { int error = 0; -#if defined(BCMLXSDMMC) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) +#if 1 && defined(BCMLXSDMMC) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) int retry = POWERUP_MAX_RETRY; int chip_up = 0; #endif DHD_TRACE(("%s: Enter\n", __FUNCTION__)); + if (gpio_request(WL_HOST_WAKE_DEF_GPIO, "wl_host_wake")) { + pr_warning("[%s] get wl_host_wake gpio failed\n", __FUNCTION__); + wl_host_wake = -1; + return -1; + } + wl_host_wake = WL_HOST_WAKE_DEF_GPIO; + gpio_direction_input(wl_host_wake); + wl_host_wake_irqno = gpio_to_irq(wl_host_wake); + pr_info("bcmdhd: got gpio%d, mapped to irqno%d\n", wl_host_wake, wl_host_wake_irqno); + wl_android_init(); #if defined(DHDTHREAD) @@ -4833,13 +4416,11 @@ dhd_module_init(void) break; DHD_ERROR(("Invalid module parameters.\n")); - error = -EINVAL; + return -EINVAL; } while (0); #endif - if (error) - goto fail_0; -#if defined(BCMLXSDMMC) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) +#if 1 && defined(BCMLXSDMMC) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) do { sema_init(&dhd_chipup_sem, 0); dhd_bus_reg_sdio_notify(&dhd_chipup_sem); @@ -4867,8 +4448,7 @@ dhd_module_init(void) if (!chip_up) { DHD_ERROR(("\nfailed to power up wifi chip, max retry reached, exits **\n\n")); - error = -ENODEV; - goto fail_0; + return -ENODEV; } #else dhd_customer_gpio_wlan_ctrl(WLAN_POWER_ON); @@ -4879,18 +4459,7 @@ dhd_module_init(void) #endif -#if defined(CONFIG_WIFI_CONTROL_FUNC) && defined(BCMLXSDMMC) - /* If the wifi_set_power() is failed, - * we need to jump error handling routines. - */ - if (!g_wifi_poweron) { - printk("%s: wifi_set_power() failed\n", __FUNCTION__); - error = -ENODEV; - goto fail_1; - } -#endif /* defined(CONFIG_WIFI_CONTROL_FUNC) */ - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) +#if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) sema_init(&dhd_registration_sem, 0); #endif @@ -4904,7 +4473,7 @@ dhd_module_init(void) goto fail_1; } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(BCMLXSDMMC) +#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 @@ -4924,7 +4493,7 @@ dhd_module_init(void) return error; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(BCMLXSDMMC) +#if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) fail_2: dhd_bus_unregister(); #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ @@ -4938,21 +4507,14 @@ fail_1: /* Call customer gpio to turn off power with WL_REG_ON signal */ dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF); -fail_0: - wl_android_exit(); - return error; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) -#ifdef USE_LATE_INITCALL_SYNC -late_initcall_sync(dhd_module_init); -#else late_initcall(dhd_module_init); -#endif /* USE_LATE_INITCALL_SYNC */ #else module_init(dhd_module_init); -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) */ +#endif module_exit(dhd_module_cleanup); @@ -5027,19 +4589,6 @@ dhd_os_ioctl_resp_wake(dhd_pub_t *pub) } void -dhd_os_wd_timer_extend(void *bus, bool extend) -{ - dhd_pub_t *pub = bus; - dhd_info_t *dhd = (dhd_info_t *)pub->info; - - if (extend) - dhd_os_wd_timer(bus, WATCHDOG_EXTEND_INTERVAL); - else - dhd_os_wd_timer(bus, dhd->default_wd_interval); -} - - -void dhd_os_wd_timer(void *bus, uint wdtick) { dhd_pub_t *pub = bus; @@ -5048,22 +4597,21 @@ dhd_os_wd_timer(void *bus, uint wdtick) DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - if (!dhd) { - DHD_ERROR(("%s: dhd NULL\n", __FUNCTION__)); + if (!dhd) return; - } + if (wdtick) + DHD_OS_WD_WAKE_LOCK(pub); flags = dhd_os_spin_lock(pub); /* don't start the wd until fw is loaded */ if (pub->busstate == DHD_BUS_DOWN) { dhd_os_spin_unlock(pub, flags); - if (!wdtick) - DHD_OS_WD_WAKE_UNLOCK(pub); + DHD_OS_WD_WAKE_UNLOCK(pub); return; } - /* Totally stop the timer */ + /* totally stop the timer */ if (!wdtick && dhd->wd_timer_valid == TRUE) { dhd->wd_timer_valid = FALSE; dhd_os_spin_unlock(pub, flags); @@ -5072,12 +4620,12 @@ dhd_os_wd_timer(void *bus, uint wdtick) #else del_timer(&dhd->timer); #endif /* DHDTHREAD */ + /* Unlock when timer deleted */ DHD_OS_WD_WAKE_UNLOCK(pub); return; } if (wdtick) { - DHD_OS_WD_WAKE_LOCK(pub); dhd_watchdog_ms = (uint)wdtick; /* Re arm the timer, at last watchdog period */ mod_timer(&dhd->timer, jiffies + msecs_to_jiffies(dhd_watchdog_ms)); @@ -5198,48 +4746,6 @@ dhd_os_sdtxunlock(dhd_pub_t *pub) dhd_os_sdunlock(pub); } -#if defined(DHDTHREAD) && defined(RXFRAME_THREAD) -static void -dhd_os_rxflock(dhd_pub_t *pub) -{ - dhd_info_t *dhd; - - dhd = (dhd_info_t *)(pub->info); - spin_lock_bh(&dhd->rxf_lock); - -} - -static void -dhd_os_rxfunlock(dhd_pub_t *pub) -{ - dhd_info_t *dhd; - - dhd = (dhd_info_t *)(pub->info); - spin_unlock_bh(&dhd->rxf_lock); -} -#endif /* defined(DHDTHREAD) && defined(RXFRAME_THREAD) */ - -#ifdef DHDTCPACK_SUPPRESS -void -dhd_os_tcpacklock(dhd_pub_t *pub) -{ - dhd_info_t *dhd; - - dhd = (dhd_info_t *)(pub->info); - spin_lock_bh(&dhd->tcpack_lock); - -} - -void -dhd_os_tcpackunlock(dhd_pub_t *pub) -{ - dhd_info_t *dhd; - - dhd = (dhd_info_t *)(pub->info); - spin_unlock_bh(&dhd->tcpack_lock); -} -#endif /* DHDTCPACK_SUPPRESS */ - #if defined(CONFIG_DHD_USE_STATIC_BUF) uint8* dhd_os_prealloc(void *osh, int section, uint size) { @@ -5251,7 +4757,7 @@ void dhd_os_prefree(void *osh, void *add } #endif /* defined(CONFIG_WIFI_CONTROL_FUNC) */ -#if defined(WL_WIRELESS_EXT) +#if defined(CONFIG_WIRELESS_EXT) struct iw_statistics * dhd_get_wireless_stats(struct net_device *dev) { @@ -5269,7 +4775,7 @@ dhd_get_wireless_stats(struct net_device else return NULL; } -#endif /* defined(WL_WIRELESS_EXT) */ +#endif /* defined(CONFIG_WIRELESS_EXT) */ static int dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata, @@ -5282,7 +4788,7 @@ dhd_wl_host_event(dhd_info_t *dhd, int * if (bcmerror != BCME_OK) return (bcmerror); -#if defined(WL_WIRELESS_EXT) +#if defined(CONFIG_WIRELESS_EXT) if (event->bsscfgidx == 0) { /* * Wireless ext is on primary interface only @@ -5295,7 +4801,7 @@ dhd_wl_host_event(dhd_info_t *dhd, int * wl_iw_event(dhd->iflist[*ifidx]->net, event, *data); } } -#endif /* defined(WL_WIRELESS_EXT) */ +#endif /* defined(CONFIG_WIRELESS_EXT) */ #ifdef WL_CFG80211 if ((ntoh32(event->event_type) == WLC_E_IF) && @@ -5329,6 +4835,103 @@ 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; + bcm_event_t *msg; + wl_event_msg_t *p_bcm_event; + char *ptr; + uint32 len; + uint32 pktlen; + dhd_if_t *ifp; + dhd_info_t *dhd; + uchar *eth; + int ifidx; + + len = ntoh32(event->datalen); + pktlen = sizeof(bcm_event_t) + len + 2; + dhd = dhdp->info; + ifidx = dhd_ifname2idx(dhd, event->ifname); + + if ((p = PKTGET(dhdp->osh, pktlen, FALSE))) { + ASSERT(ISALIGNED((uintptr)PKTDATA(dhdp->osh, p), sizeof(uint32))); + + msg = (bcm_event_t *) PKTDATA(dhdp->osh, p); + + bcopy(&dhdp->mac, &msg->eth.ether_dhost, ETHER_ADDR_LEN); + bcopy(&dhdp->mac, &msg->eth.ether_shost, ETHER_ADDR_LEN); + ETHER_TOGGLE_LOCALADDR(&msg->eth.ether_shost); + + msg->eth.ether_type = hton16(ETHER_TYPE_BRCM); + + /* BCM Vendor specific header... */ + msg->bcm_hdr.subtype = hton16(BCMILCP_SUBTYPE_VENDOR_LONG); + msg->bcm_hdr.version = BCMILCP_BCM_SUBTYPEHDR_VERSION; + bcopy(BRCM_OUI, &msg->bcm_hdr.oui[0], DOT11_OUI_LEN); + + /* vendor spec header length + pvt data length (private indication + * hdr + actual message itself) + */ + msg->bcm_hdr.length = hton16(BCMILCP_BCM_SUBTYPEHDR_MINLENGTH + + BCM_MSG_LEN + sizeof(wl_event_msg_t) + (uint16)len); + msg->bcm_hdr.usr_subtype = hton16(BCMILCP_BCM_SUBTYPE_EVENT); + + PKTSETLEN(dhdp->osh, p, (sizeof(bcm_event_t) + len + 2)); + + /* copy wl_event_msg_t into sk_buf */ + + /* pointer to wl_event_msg_t in sk_buf */ + p_bcm_event = &msg->event; + bcopy(event, p_bcm_event, sizeof(wl_event_msg_t)); + + /* copy hci event into sk_buf */ + bcopy(data, (p_bcm_event + 1), len); + + msg->bcm_hdr.length = hton16(sizeof(wl_event_msg_t) + + ntoh16(msg->bcm_hdr.length)); + PKTSETLEN(dhdp->osh, p, (sizeof(bcm_event_t) + len + 2)); + + ptr = (char *)(msg + 1); + /* Last 2 bytes of the message are 0x00 0x00 to signal that there + * are no ethertypes which are following this + */ + ptr[len+0] = 0x00; + ptr[len+1] = 0x00; + + skb = PKTTONATIVE(dhdp->osh, p); + eth = skb->data; + len = skb->len; + + ifp = dhd->iflist[ifidx]; + if (ifp == NULL) + ifp = dhd->iflist[0]; + + ASSERT(ifp); + skb->dev = ifp->net; + skb->protocol = eth_type_trans(skb, skb->dev); + + skb->data = eth; + skb->len = len; + + /* Strip header, count, deliver upward */ + skb_pull(skb, ETH_HLEN); + + /* Send the packet */ + if (in_interrupt()) { + netif_rx(skb); + } else { + netif_rx_ni(skb); + } + } + 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; } @@ -5336,7 +4939,7 @@ dhd_sendup_event(dhd_pub_t *dhdp, wl_eve 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; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) @@ -5348,13 +4951,13 @@ void dhd_wait_for_event(dhd_pub_t *dhd, dhd_os_sdunlock(dhd); wait_event_timeout(dhdinfo->ctrl_wait, (*lockvar == FALSE), timeout); dhd_os_sdlock(dhd); -#endif +#endif return; } 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(&dhdinfo->ctrl_wait); @@ -5374,15 +4977,6 @@ dhd_dev_reset(struct net_device *dev, ui if (dhd_wl_ioctl_cmd(&dhd->pub, WLC_DOWN, NULL, 0, TRUE, 0) < 0) { DHD_TRACE(("%s: wl down failed\n", __FUNCTION__)); } -#if defined(PROP_TXSTATUS) && !defined(PROP_TXSTATUS_VSDB) - dhd_wlfc_deinit(&dhd->pub); - if (dhd->pub.plat_deinit) - dhd->pub.plat_deinit((void *)&dhd->pub); -#endif /* PROP_TXSTATUS && !PROP_TXSTATUS_VSDB */ -#ifdef PNO_SUPPORT - if (dhd->pub.pno_state) - dhd_pno_deinit(&dhd->pub); -#endif } ret = dhd_bus_devreset(&dhd->pub, flag); @@ -5437,9 +5031,9 @@ int net_os_set_suspend_bcn_li_dtim(struc #ifdef PKT_FILTER_SUPPORT int net_os_rxfilter_add_remove(struct net_device *dev, int add_remove, int num) { +#ifndef GAN_LITE_NAT_KEEPALIVE_FILTER dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); char *filterp = NULL; - int filter_id = 0; int ret = 0; if (!dhd || (num == DHD_UNICAST_FILTER_NUM) || @@ -5447,32 +5041,27 @@ int net_os_rxfilter_add_remove(struct ne return ret; if (num >= dhd->pub.pktfilter_count) return -EINVAL; - switch (num) { + if (add_remove) { + switch (num) { case DHD_BROADCAST_FILTER_NUM: filterp = "101 0 0 0 0xFFFFFFFFFFFF 0xFFFFFFFFFFFF"; - filter_id = 101; break; case DHD_MULTICAST4_FILTER_NUM: filterp = "102 0 0 0 0xFFFFFF 0x01005E"; - filter_id = 102; break; case DHD_MULTICAST6_FILTER_NUM: filterp = "103 0 0 0 0xFFFF 0x3333"; - filter_id = 103; break; default: return -EINVAL; + } } - - /* Add filter */ - if (add_remove) { - dhd->pub.pktfilter[num] = filterp; - dhd_pktfilter_offload_set(&dhd->pub, dhd->pub.pktfilter[num]); - } else { /* Delete filter */ - dhd->pub.pktfilter[num] = NULL; - /* dhd_pktfilter_offload_delete(&dhd->pub, filter_id); */ - } + dhd->pub.pktfilter[num] = filterp; + dhd_pktfilter_offload_set(&dhd->pub, dhd->pub.pktfilter[num]); return ret; +#else + return 0; +#endif /* GAN_LITE_NAT_KEEPALIVE_FILTER */ } int dhd_os_enable_packet_filter(dhd_pub_t *dhdp, int val) @@ -5506,84 +5095,52 @@ int dhd_dev_init_ioctl(struct net_device *dev) { dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - int ret; - - dhd_process_cid_mac(&dhd->pub, TRUE); - - if ((ret = dhd_preinit_ioctls(&dhd->pub)) < 0) - goto done; - - dhd_process_cid_mac(&dhd->pub, FALSE); - -done: - return ret; + return dhd_preinit_ioctls(&dhd->pub); } #ifdef PNO_SUPPORT -/* Linux wrapper to call common dhd_pno_stop_for_ssid */ +/* Linux wrapper to call common dhd_pno_clean */ int -dhd_dev_pno_stop_for_ssid(struct net_device *dev) +dhd_dev_pno_reset(struct net_device *dev) { dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - return (dhd_pno_stop_for_ssid(&dhd->pub)); + return (dhd_pno_clean(&dhd->pub)); } -/* Linux wrapper to call common dhd_pno_set_for_ssid */ -int -dhd_dev_pno_set_for_ssid(struct net_device *dev, wlc_ssid_t* ssids_local, int nssid, - uint16 scan_fr, int pno_repeat, int pno_freq_expo_max, uint16 *channel_list, int nchan) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - return (dhd_pno_set_for_ssid(&dhd->pub, ssids_local, nssid, scan_fr, - pno_repeat, pno_freq_expo_max, channel_list, nchan)); -} /* Linux wrapper to call common dhd_pno_enable */ int -dhd_dev_pno_enable(struct net_device *dev, int enable) +dhd_dev_pno_enable(struct net_device *dev, int pfn_enabled) { dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - return (dhd_pno_enable(&dhd->pub, enable)); + return (dhd_pno_enable(&dhd->pub, pfn_enabled)); } -/* Linux wrapper to call common dhd_pno_set_for_hotlist */ -int -dhd_dev_pno_set_for_hotlist(struct net_device *dev, wl_pfn_bssid_t *p_pfn_bssid, - struct dhd_pno_hotlist_params *hotlist_params) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - return (dhd_pno_set_for_hotlist(&dhd->pub, p_pfn_bssid, hotlist_params)); -} -/* Linux wrapper to call common dhd_dev_pno_stop_for_batch */ +/* Linux wrapper to call common dhd_pno_set */ int -dhd_dev_pno_stop_for_batch(struct net_device *dev) +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) { dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - return (dhd_pno_stop_for_batch(&dhd->pub)); -} -/* Linux wrapper to call common dhd_dev_pno_set_for_batch */ -int -dhd_dev_pno_set_for_batch(struct net_device *dev, struct dhd_pno_batch_params *batch_params) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - return (dhd_pno_set_for_batch(&dhd->pub, batch_params)); + return (dhd_pno_set(&dhd->pub, ssids_local, nssid, scan_fr, pno_repeat, pno_freq_expo_max)); } -/* Linux wrapper to call common dhd_dev_pno_get_for_batch */ +/* Linux wrapper to get pno status */ int -dhd_dev_pno_get_for_batch(struct net_device *dev, char *buf, int bufsize) +dhd_dev_get_pno_status(struct net_device *dev) { dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - return (dhd_pno_get_for_batch(&dhd->pub, buf, bufsize, PNO_STATUS_NORMAL)); + + return (dhd_pno_get_status(&dhd->pub)); } + #endif /* PNO_SUPPORT */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && (1) static void dhd_hang_process(struct work_struct *work) { dhd_info_t *dhd; @@ -5622,32 +5179,24 @@ int net_os_send_hang_message(struct net_ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); int ret = 0; - if (dhd) { - /* Report FW problem when enabled */ - if (dhd->pub.hang_report) { + if (dhd) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) - ret = dhd_os_send_hang_message(&dhd->pub); + ret = dhd_os_send_hang_message(&dhd->pub); #else - ret = wl_cfg80211_hang(dev, WLAN_REASON_UNSPECIFIED); + ret = wl_cfg80211_hang(dev, WLAN_REASON_UNSPECIFIED); #endif - } else { - DHD_ERROR(("%s: FW HANG ignored (for testing purpose) and not sent up\n", - __FUNCTION__)); - /* Enforce bus down to stop any future traffic */ - dhd->pub.busstate = DHD_BUS_DOWN; - } - } return ret; } -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) && OEM_ANDROID */ +#endif /* (OEM_ANDROID) */ -void dhd_bus_country_set(struct net_device *dev, wl_country_t *cspec, bool notify) +void dhd_bus_country_set(struct net_device *dev, wl_country_t *cspec) { dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); + if (dhd && dhd->pub.up) { memcpy(&dhd->pub.dhd_cspec, cspec, sizeof(wl_country_t)); #ifdef WL_CFG80211 - wl_update_wiphybands(NULL, notify); + wl_update_wiphybands(NULL, true); #endif } } @@ -5676,7 +5225,7 @@ void dhd_net_if_unlock(struct net_device 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 @@ -5684,7 +5233,7 @@ static void dhd_net_if_lock_local(dhd_in 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 @@ -5692,7 +5241,7 @@ static void dhd_net_if_unlock_local(dhd_ static void dhd_suspend_lock(dhd_pub_t *pub) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 dhd_info_t *dhd = (dhd_info_t *)(pub->info); if (dhd) mutex_lock(&dhd->dhd_suspend_mutex); @@ -5701,7 +5250,7 @@ static void dhd_suspend_lock(dhd_pub_t * static void dhd_suspend_unlock(dhd_pub_t *pub) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 dhd_info_t *dhd = (dhd_info_t *)(pub->info); if (dhd) mutex_unlock(&dhd->dhd_suspend_mutex); @@ -5733,7 +5282,7 @@ dhd_get_pend_8021x_cnt(dhd_info_t *dhd) return (atomic_read(&dhd->pend_8021x_cnt)); } -#define MAX_WAIT_FOR_8021X_TX 50 +#define MAX_WAIT_FOR_8021X_TX 25 int dhd_wait_pend8021x(struct net_device *dev) @@ -5753,10 +5302,7 @@ dhd_wait_pend8021x(struct net_device *de pend = dhd_get_pend_8021x_cnt(dhd); } if (ntimes == 0) - { - atomic_set(&dhd->pend_8021x_cnt, 0); DHD_ERROR(("%s: TIMEOUT\n", __FUNCTION__)); - } return pend; } @@ -5809,10 +5355,10 @@ int dhd_os_wake_lock_timeout(dhd_pub_t * dhd->wakelock_rx_timeout_enable : dhd->wakelock_ctrl_timeout_enable; #ifdef CONFIG_HAS_WAKELOCK if (dhd->wakelock_rx_timeout_enable) - wake_lock_timeout(&dhd->wl_rxwake, + wake_lock_timeout(dhd->wl_rxwake, msecs_to_jiffies(dhd->wakelock_rx_timeout_enable)); if (dhd->wakelock_ctrl_timeout_enable) - wake_lock_timeout(&dhd->wl_ctrlwake, + wake_lock_timeout(dhd->wl_ctrlwake, msecs_to_jiffies(dhd->wakelock_ctrl_timeout_enable)); #endif dhd->wakelock_rx_timeout_enable = 0; @@ -5860,23 +5406,6 @@ int dhd_os_wake_lock_ctrl_timeout_enable return 0; } -int dhd_os_wake_lock_ctrl_timeout_cancel(dhd_pub_t *pub) -{ - dhd_info_t *dhd = (dhd_info_t *)(pub->info); - unsigned long flags; - - if (dhd) { - spin_lock_irqsave(&dhd->wakelock_spinlock, flags); - dhd->wakelock_ctrl_timeout_enable = 0; -#ifdef CONFIG_HAS_WAKELOCK - if (wake_lock_active(&dhd->wl_ctrlwake)) - wake_unlock(&dhd->wl_ctrlwake); -#endif - spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags); - } - return 0; -} - int net_os_wake_lock_rx_timeout_enable(struct net_device *dev, int val) { dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); @@ -5907,10 +5436,7 @@ int dhd_os_wake_lock(dhd_pub_t *pub) spin_lock_irqsave(&dhd->wakelock_spinlock, flags); #ifdef CONFIG_HAS_WAKELOCK if (!dhd->wakelock_counter) - wake_lock(&dhd->wl_wifi); -#elif 1 && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) - if (pm_dev) - pm_stay_awake(pm_dev); + wake_lock(dhd->wl_wifi); #endif dhd->wakelock_counter++; ret = dhd->wakelock_counter; @@ -5942,10 +5468,7 @@ int dhd_os_wake_unlock(dhd_pub_t *pub) dhd->wakelock_counter--; #ifdef CONFIG_HAS_WAKELOCK if (!dhd->wakelock_counter) - wake_unlock(&dhd->wl_wifi); -#elif 1 && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) - if (pm_dev) - pm_relax(pm_dev); + wake_unlock(dhd->wl_wifi); #endif ret = dhd->wakelock_counter; } @@ -5956,23 +5479,17 @@ int dhd_os_wake_unlock(dhd_pub_t *pub) int dhd_os_check_wakelock(void *dhdp) { -#if defined(CONFIG_HAS_WAKELOCK) || (1 && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, \ - 36))) +#ifdef CONFIG_HAS_WAKELOCK dhd_pub_t *pub = (dhd_pub_t *)dhdp; dhd_info_t *dhd; if (!pub) return 0; dhd = (dhd_info_t *)(pub->info); -#endif /* CONFIG_HAS_WAKELOCK || BCMSDIO */ -#ifdef CONFIG_HAS_WAKELOCK /* Indicate to the SD Host to avoid going to suspend if internal locks are up */ - if (dhd && (wake_lock_active(&dhd->wl_wifi) || - (wake_lock_active(&dhd->wl_wdwake)))) - return 1; -#elif 1 && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) - if (dhd && (dhd->wakelock_counter > 0) && pm_dev) + if (dhd && (wake_lock_active(dhd->wl_wifi) || + (wake_lock_active(dhd->wl_wdwake)))) return 1; #endif return 0; @@ -5998,8 +5515,14 @@ int dhd_os_wd_wake_lock(dhd_pub_t *pub) spin_lock_irqsave(&dhd->wakelock_spinlock, flags); #ifdef CONFIG_HAS_WAKELOCK /* if wakelock_wd_counter was never used : lock it at once */ - if (!dhd->wakelock_wd_counter) - wake_lock(&dhd->wl_wdwake); + if (!dhd->wakelock_wd_counter) { + if (dhd->wl_wdwake) + wake_lock(dhd->wl_wdwake); + else { + spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags); + return 0; + } + } #endif dhd->wakelock_wd_counter++; ret = dhd->wakelock_wd_counter; @@ -6019,7 +5542,7 @@ int dhd_os_wd_wake_unlock(dhd_pub_t *pub if (dhd->wakelock_wd_counter) { dhd->wakelock_wd_counter = 0; #ifdef CONFIG_HAS_WAKELOCK - wake_unlock(&dhd->wl_wdwake); + wake_unlock(dhd->wl_wdwake); #endif } spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags); @@ -6043,6 +5566,7 @@ void dhd_set_version_info(dhd_pub_t *dhd i = snprintf(info_string, sizeof(info_string), " Driver: %s\n Firmware: %s ", EPI_VERSION_STR, fw); + printf("%s\n", info_string); if (!dhdp) return; @@ -6064,9 +5588,6 @@ int dhd_ioctl_entry_local(struct net_dev } dhd = *(dhd_info_t **)netdev_priv(net); - if (!dhd) - return -EINVAL; - ifidx = dhd_net2idx(dhd, net); if (ifidx == DHD_BAD_IF) { DHD_ERROR(("%s bad ifidx\n", __FUNCTION__)); @@ -6098,45 +5619,42 @@ extern int dhd_wlfc_FIFOcreditmap_update int dhd_wlfc_interface_event(struct dhd_info *dhd, ewlfc_mac_entry_action_t action, uint8 ifid, uint8 iftype, uint8* ea) { - if (dhd->pub.wlfc_state == NULL) + int status; + + dhd_os_wlfc_block(&dhd->pub); + if (dhd->pub.wlfc_state == NULL) { + dhd_os_wlfc_unblock(&dhd->pub); return BCME_OK; + } - return dhd_wlfc_interface_entry_update(dhd->pub.wlfc_state, action, ifid, iftype, ea); + status = dhd_wlfc_interface_entry_update(dhd->pub.wlfc_state, action, ifid, iftype, ea); + dhd_os_wlfc_unblock(&dhd->pub); + return status; } int dhd_wlfc_FIFOcreditmap_event(struct dhd_info *dhd, uint8* event_data) { - if (dhd->pub.wlfc_state == NULL) + int status; + + dhd_os_wlfc_block(&dhd->pub); + if (dhd->pub.wlfc_state == NULL) { + dhd_os_wlfc_unblock(&dhd->pub); return BCME_OK; + } - return dhd_wlfc_FIFOcreditmap_update(dhd->pub.wlfc_state, event_data); + status = dhd_wlfc_FIFOcreditmap_update(dhd->pub.wlfc_state, event_data); + dhd_os_wlfc_unblock(&dhd->pub); + return status; } int dhd_wlfc_event(struct dhd_info *dhd) { - return dhd_wlfc_enable(&dhd->pub); -} - -void dhd_wlfc_plat_enable(void *dhd) -{ - return; -} - -void dhd_wlfc_plat_deinit(void *dhd) -{ - return; -} - -bool dhd_wlfc_skip_fc(void) -{ -#ifdef WL_CFG80211 - extern struct wl_priv *wlcfg_drv_priv; + int status; - /* enable flow control in vsdb mode */ - return !(wlcfg_drv_priv && wlcfg_drv_priv->vsdb_mode); -#else - return TRUE; /* skip flow control */ -#endif /* WL_CFG80211 */ + dhd_os_wlfc_block(&dhd->pub); + status = dhd_wlfc_enable(&dhd->pub); + dhd_os_wlfc_unblock(&dhd->pub); + return status; } #endif /* PROP_TXSTATUS */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/dhd_linux_sched.c linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_linux_sched.c --- linux-sunxi/drivers/net/wireless/bcmdhd/dhd_linux_sched.c 2014-01-27 01:30:30.101433269 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_linux_sched.c 2014-02-15 00:43:44.792014069 +0100 @@ -1,7 +1,7 @@ /* * Expose some of the kernel scheduler routines * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/dhd_pno.c linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_pno.c --- linux-sunxi/drivers/net/wireless/bcmdhd/dhd_pno.c 2014-01-27 01:30:30.109433432 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_pno.c 2014-02-15 00:43:44.795014136 +0100 @@ -53,12 +53,12 @@ #define htodchanspec(i) htod16(i) #define dtohchanspec(i) dtoh16(i) #else -#define htod32(i) (i) -#define htod16(i) (i) -#define dtoh32(i) (i) -#define dtoh16(i) (i) -#define htodchanspec(i) (i) -#define dtohchanspec(i) (i) +#define htod32(i) i +#define htod16(i) i +#define dtoh32(i) i +#define dtoh16(i) i +#define htodchanspec(i) i +#define dtohchanspec(i) i #endif /* IL_BIGENDINA */ #define NULL_CHECK(p, s, err) \ @@ -91,9 +91,8 @@ is_dfs(uint16 channel) else return FALSE; } - -int -dhd_pno_clean(dhd_pub_t *dhd) +static int +_dhd_pno_clean(dhd_pub_t *dhd) { int pfn = 0; int err; @@ -127,9 +126,7 @@ _dhd_pno_suspend(dhd_pub_t *dhd) dhd_pno_status_info_t *_pno_state; NULL_CHECK(dhd, "dhd is NULL", err); NULL_CHECK(dhd->pno_state, "pno_state is NULL", err); - DHD_PNO(("%s enter\n", __FUNCTION__)); - _pno_state = PNO_GET_PNOSTATE(dhd); err = dhd_iovar(dhd, 0, "pfn_suspend", (char *)&suspend, sizeof(suspend), 1); if (err < 0) { DHD_ERROR(("%s : failed to suspend pfn(error :%d)\n", __FUNCTION__, err)); @@ -302,13 +299,13 @@ _dhd_pno_set(dhd_pub_t *dhd, const dhd_p /* set bestn to calculate the max mscan which firmware supports */ err = dhd_iovar(dhd, 0, "pfnmem", (char *)&_tmp, sizeof(_tmp), 1); if (err < 0) { - DHD_ERROR(("%s : failed to set pfnmem\n", __FUNCTION__)); + DHD_ERROR(("%s : failed to set pfnmscan\n", __FUNCTION__)); goto exit; } /* get max mscan which the firmware supports */ err = dhd_iovar(dhd, 0, "pfnmem", (char *)&_tmp, sizeof(_tmp), 0); if (err < 0) { - DHD_ERROR(("%s : failed to get pfnmem\n", __FUNCTION__)); + DHD_ERROR(("%s : failed to get pfnmscan\n", __FUNCTION__)); goto exit; } DHD_PNO((" returned mscan : %d, set bestn : %d\n", _tmp, pfn_param.bestn)); @@ -767,7 +764,7 @@ dhd_pno_stop_for_ssid(dhd_pub_t *dhd) dhd_pno_get_for_batch(dhd, NULL, 0, PNO_STATUS_DISABLE); /* save current pno_mode before calling dhd_pno_clean */ mode = _pno_state->pno_mode; - dhd_pno_clean(dhd); + _dhd_pno_clean(dhd); /* restore previous pno_mode */ _pno_state->pno_mode = mode; if (_pno_state->pno_mode & DHD_PNO_BATCH_MODE) { @@ -811,9 +808,9 @@ dhd_pno_stop_for_ssid(dhd_pub_t *dhd) } } } else { - err = dhd_pno_clean(dhd); + err = _dhd_pno_clean(dhd); if (err < 0) { - DHD_ERROR(("%s : failed to call dhd_pno_clean (err: %d)\n", + DHD_ERROR(("%s : failed to call _dhd_pno_clean (err: %d)\n", __FUNCTION__, err)); goto exit; } @@ -857,23 +854,15 @@ dhd_pno_set_for_ssid(dhd_pub_t *dhd, wlc scan_fr, pno_repeat, pno_freq_expo_max, nchan)); _params = &(_pno_state->pno_params_arr[INDEX_OF_LEGACY_PARAMS]); - if (_pno_state->pno_mode & DHD_PNO_LEGACY_MODE) { - DHD_ERROR(("%s : Legacy PNO mode was already started, " - "will disable previous one to start new one\n", __FUNCTION__)); - err = dhd_pno_stop_for_ssid(dhd); + if (!(_pno_state->pno_mode & DHD_PNO_LEGACY_MODE)) { + _pno_state->pno_mode |= DHD_PNO_LEGACY_MODE; + err = _dhd_pno_reinitialize_prof(dhd, _params, DHD_PNO_LEGACY_MODE); if (err < 0) { - DHD_ERROR(("%s : failed to stop legacy PNO (err %d)\n", + DHD_ERROR(("%s : failed to reinitialize profile (err %d)\n", __FUNCTION__, err)); goto exit; } } - _pno_state->pno_mode |= DHD_PNO_LEGACY_MODE; - err = _dhd_pno_reinitialize_prof(dhd, _params, DHD_PNO_LEGACY_MODE); - if (err < 0) { - DHD_ERROR(("%s : failed to reinitialize profile (err %d)\n", - __FUNCTION__, err)); - goto exit; - } memset(_chan_list, 0, sizeof(_chan_list)); tot_nchan = nchan; if (tot_nchan > 0 && channel_list) { @@ -938,7 +927,7 @@ dhd_pno_set_for_ssid(dhd_pub_t *dhd, wlc goto exit; } if ((err = _dhd_pno_add_ssid(dhd, ssid_list, nssid)) < 0) { - DHD_ERROR(("failed to add ssid list(err %d), %d in firmware\n", err, nssid)); + DHD_ERROR(("failed to add ssid list (err %d) in firmware\n", err)); goto exit; } for (i = 0; i < nssid; i++) { @@ -1005,9 +994,6 @@ dhd_pno_set_for_batch(dhd_pub_t *dhd, st __FUNCTION__)); goto exit; } - } else { - /* batch mode is already started */ - return -EBUSY; } _params->params_batch.scan_fr = batch_params->scan_fr; _params->params_batch.bestn = batch_params->bestn; @@ -1249,7 +1235,6 @@ _dhd_pno_get_for_batch(dhd_pub_t *dhd, c DHD_ERROR(("failed to allocate dhd_pno_bestnet_entry\n")); goto exit; } - memset(pbestnet_entry, 0, BESTNET_ENTRY_SIZE); pbestnet_entry->recorded_time = jiffies; /* record the current time */ /* create header for the first entry */ allocate_header = (i == 0)? TRUE : FALSE; @@ -1328,15 +1313,6 @@ _dhd_pno_get_for_batch(dhd_pub_t *dhd, c plnetinfo++; } } - if (pscan_results->cnt_header == 0) { - /* In case that we didn't get any data from the firmware - * Remove the current scan_result list from get_bach.scan_results_list. - */ - DHD_PNO(("NO BATCH DATA from Firmware, Delete current SCAN RESULT LIST\n")); - list_del(&pscan_results->list); - MFREE(dhd->osh, pscan_results, SCAN_RESULTS_SIZE); - _params->params_batch.get_batch.top_node_cnt--; - } /* increase total scan count using current scan count */ _params->params_batch.get_batch.tot_scan_cnt += pscan_results->cnt_header; @@ -1365,14 +1341,10 @@ convert_format: exit: if (plbestnet) MFREE(dhd->osh, plbestnet, PNO_BESTNET_LEN); - if (_params) { - _params->params_batch.get_batch.buf = NULL; - _params->params_batch.get_batch.bufsize = 0; - _params->params_batch.get_batch.bytes_written = err; - } + _params->params_batch.get_batch.buf = NULL; + _params->params_batch.get_batch.bufsize = 0; mutex_unlock(&_pno_state->pno_mutex); - if (waitqueue_active(&_pno_state->get_batch_done.wait)) - complete(&_pno_state->get_batch_done); + complete(&_pno_state->get_batch_done); return err; } static void @@ -1398,7 +1370,6 @@ int dhd_pno_get_for_batch(dhd_pub_t *dhd, char *buf, int bufsize, int reason) { int err = BCME_OK; - char *pbuf = buf; dhd_pno_status_info_t *_pno_state; struct dhd_pno_batch_params *params_batch; NULL_CHECK(dhd, "dhd is NULL", err); @@ -1418,19 +1389,13 @@ dhd_pno_get_for_batch(dhd_pub_t *dhd, ch params_batch = &_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS].params_batch; if (!(_pno_state->pno_mode & DHD_PNO_BATCH_MODE)) { DHD_ERROR(("%s: Batching SCAN mode is not enabled\n", __FUNCTION__)); - memset(pbuf, 0, bufsize); - pbuf += sprintf(pbuf, "scancount=%d\n", 0); - sprintf(pbuf, "%s", RESULTS_END_MARKER); - err = strlen(buf); goto exit; } params_batch->get_batch.buf = buf; params_batch->get_batch.bufsize = bufsize; params_batch->get_batch.reason = reason; - params_batch->get_batch.bytes_written = 0; schedule_work(&_pno_state->work); wait_for_completion(&_pno_state->get_batch_done); - err = params_batch->get_batch.bytes_written; exit: return err; } @@ -1466,7 +1431,7 @@ dhd_pno_stop_for_batch(dhd_pub_t *dhd) _pno_state->pno_mode &= ~DHD_PNO_BATCH_MODE; if (_pno_state->pno_mode & (DHD_PNO_LEGACY_MODE | DHD_PNO_HOTLIST_MODE)) { mode = _pno_state->pno_mode; - dhd_pno_clean(dhd); + _dhd_pno_clean(dhd); _pno_state->pno_mode = mode; /* restart Legacy PNO if the Legacy PNO is on */ if (_pno_state->pno_mode & DHD_PNO_LEGACY_MODE) { @@ -1530,9 +1495,9 @@ dhd_pno_stop_for_batch(dhd_pub_t *dhd) } } } else { - err = dhd_pno_clean(dhd); + err = _dhd_pno_clean(dhd); if (err < 0) { - DHD_ERROR(("%s : failed to call dhd_pno_clean (err: %d)\n", + DHD_ERROR(("%s : failed to call _dhd_pno_clean (err: %d)\n", __FUNCTION__, err)); goto exit; } @@ -1725,9 +1690,9 @@ dhd_pno_stop_for_hotlist(dhd_pub_t *dhd) dhd_pno_get_for_batch(dhd, NULL, 0, PNO_STATUS_DISABLE); /* save current pno_mode before calling dhd_pno_clean */ mode = _pno_state->pno_mode; - err = dhd_pno_clean(dhd); + err = _dhd_pno_clean(dhd); if (err < 0) { - DHD_ERROR(("%s : failed to call dhd_pno_clean (err: %d)\n", + DHD_ERROR(("%s : failed to call _dhd_pno_clean (err: %d)\n", __FUNCTION__, err)); goto exit; } @@ -1777,9 +1742,9 @@ dhd_pno_stop_for_hotlist(dhd_pub_t *dhd) } } } else { - err = dhd_pno_clean(dhd); + err = _dhd_pno_clean(dhd); if (err < 0) { - DHD_ERROR(("%s : failed to call dhd_pno_clean (err: %d)\n", + DHD_ERROR(("%s : failed to call _dhd_pno_clean (err: %d)\n", __FUNCTION__, err)); goto exit; } @@ -1817,15 +1782,11 @@ dhd_pno_event_handler(dhd_pub_t *dhd, wl { struct dhd_pno_batch_params *params_batch; params_batch = &_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS].params_batch; - if (!waitqueue_active(&_pno_state->get_batch_done.wait)) { - DHD_PNO(("%s : WLC_E_PFN_BEST_BATCHING\n", __FUNCTION__)); - params_batch->get_batch.buf = NULL; - params_batch->get_batch.bufsize = 0; - params_batch->get_batch.reason = PNO_STATUS_EVENT; - schedule_work(&_pno_state->work); - } else - DHD_PNO(("%s : WLC_E_PFN_BEST_BATCHING" - "will skip this event\n", __FUNCTION__)); + DHD_PNO(("%s : WLC_E_PFN_BEST_BATCHING\n", __FUNCTION__)); + params_batch->get_batch.buf = NULL; + params_batch->get_batch.bufsize = 0; + params_batch->get_batch.reason = PNO_STATUS_EVENT; + schedule_work(&_pno_state->work); break; } default: @@ -1845,8 +1806,8 @@ int dhd_pno_init(dhd_pub_t *dhd) if (dhd->pno_state) goto exit; dhd->pno_state = MALLOC(dhd->osh, sizeof(dhd_pno_status_info_t)); - NULL_CHECK(dhd->pno_state, "failed to create dhd_pno_state", err); memset(dhd->pno_state, 0, sizeof(dhd_pno_status_info_t)); + NULL_CHECK(dhd, "failed to create dhd_pno_state", err); /* need to check whether current firmware support batching and hotlist scan */ _pno_state = PNO_GET_PNOSTATE(dhd); _pno_state->wls_supported = TRUE; @@ -1866,20 +1827,12 @@ exit: int dhd_pno_deinit(dhd_pub_t *dhd) { int err = BCME_OK; - dhd_pno_status_info_t *_pno_state; - dhd_pno_params_t *_params; + dhd_pno_status_info_t *_pno_state = PNO_GET_PNOSTATE(dhd); NULL_CHECK(dhd, "dhd is NULL", err); - DHD_PNO(("%s enter\n", __FUNCTION__)); - _pno_state = PNO_GET_PNOSTATE(dhd); - NULL_CHECK(_pno_state, "pno_state is NULL", err); - if (_pno_state->pno_mode & DHD_PNO_BATCH_MODE) { - _params = &_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS]; - /* clear resource if the BATCH MODE is on */ - _dhd_pno_reinitialize_prof(dhd, _params, DHD_PNO_BATCH_MODE); - } cancel_work_sync(&_pno_state->work); - MFREE(dhd->osh, _pno_state, sizeof(dhd_pno_status_info_t)); + if (dhd->pno_state) + MFREE(dhd->osh, dhd->pno_state, sizeof(dhd_pno_status_info_t)); dhd->pno_state = NULL; return err; } diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/dhd_pno.h linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_pno.h --- linux-sunxi/drivers/net/wireless/bcmdhd/dhd_pno.h 2014-01-27 01:30:30.109433432 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_pno.h 2014-02-15 00:43:44.796014158 +0100 @@ -152,7 +152,6 @@ struct dhd_pno_get_batch_info { uint32 expired_tot_scan_cnt; uint32 top_node_cnt; uint32 bufsize; - uint32 bytes_written; int reason; struct list_head scan_results_list; struct list_head expired_scan_results_list; diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/dhd_proto.h linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_proto.h --- linux-sunxi/drivers/net/wireless/bcmdhd/dhd_proto.h 2014-01-27 01:30:30.100433249 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_proto.h 2014-02-15 00:43:44.791014047 +0100 @@ -4,7 +4,7 @@ * Provides type definitions and function prototypes used to link the * DHD OS, bus, and protocol modules. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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 390836 2013-03-13 23:43:53Z $ + * $Id: dhd_proto.h 343390 2012-07-06 22:34:19Z $ */ #ifndef _dhd_proto_h_ @@ -54,6 +54,10 @@ extern int dhd_prot_init(dhd_pub_t *dhdp /* Stop protocol: sync w/dongle state. */ extern void dhd_prot_stop(dhd_pub_t *dhdp); +#ifdef PROP_TXSTATUS +extern int dhd_wlfc_init(dhd_pub_t *dhd); +extern void dhd_wlfc_deinit(dhd_pub_t *dhd); +#endif /* PROP_TXSTATUS */ /* Add any protocol-specific data header. * Caller must reserve prot_hdrlen prepend space. @@ -83,6 +87,12 @@ extern int dhd_ioctl(dhd_pub_t * dhd_pub extern int dhd_preinit_ioctls(dhd_pub_t *dhd); +#ifdef PROP_TXSTATUS +extern int dhd_wlfc_enque_sendq(void* state, int prec, void* p); +extern int dhd_wlfc_commit_packets(void* state, f_commitpkt_t fcommit, void* commit_ctx); +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); @@ -94,6 +104,8 @@ extern int dhd_process_pkt_reorder_info( #define DHD_PROTOCOL "bdc" #elif defined(CDC) #define DHD_PROTOCOL "cdc" +#elif defined(RNDIS) +#define DHD_PROTOCOL "rndis" #else #define DHD_PROTOCOL "unknown" #endif /* proto */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/dhd_sdio.c linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_sdio.c --- linux-sunxi/drivers/net/wireless/bcmdhd/dhd_sdio.c 2014-01-27 01:30:30.109433432 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_sdio.c 2014-02-15 00:43:44.796014158 +0100 @@ -1,7 +1,7 @@ /* * DHD Bus Module for SDIO * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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 419981 2013-08-23 19:49:45Z $ + * $Id: dhd_sdio.c 373330 2012-12-07 04:46:17Z $ */ #include @@ -66,11 +66,6 @@ #include #include -bool dhd_mp_halting(dhd_pub_t *dhdp); -extern void bcmsdh_waitfor_iodrain(void *sdh); -extern void bcmsdh_reject_ioreqs(void *sdh, bool reject); -extern bool bcmsdh_fatal_error(void *sdh); - #ifndef DHDSDIO_MEM_DUMP_FNAME #define DHDSDIO_MEM_DUMP_FNAME "mem_dump" #endif @@ -81,13 +76,10 @@ extern bool bcmsdh_fatal_error(void *sd #define PRIOMASK 7 #define TXRETRIES 2 /* # of retries for tx frames */ -#ifndef DHD_RXBOUND + #define DHD_RXBOUND 50 /* Default for max rx frames in one scheduling */ -#endif -#ifndef DHD_TXBOUND #define DHD_TXBOUND 20 /* Default for max tx frames in one scheduling */ -#endif #define DHD_TXMINMAX 1 /* Max tx frames if rx still pending */ @@ -159,10 +151,12 @@ DHD_SPINWAIT_SLEEP_INIT(sdioh_spinwait_s extern void bcmsdh_set_irq(int flag); #endif #ifdef PROP_TXSTATUS -extern void dhd_wlfc_txcomplete(dhd_pub_t *dhd, void *txp, bool success); +extern void dhd_wlfc_txcomplete(dhd_pub_t *dhd, void *txp, bool success, bool wlfc_locked); extern void dhd_wlfc_trigger_pktcommit(dhd_pub_t *dhd); #endif - +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) +DEFINE_MUTEX(_dhd_sdio_mutex_lock_); +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) */ #ifdef DHD_DEBUG /* Device console log buffer state */ @@ -187,17 +181,14 @@ typedef struct dhd_console { #define MIN_RSRC_SR 0x3 #define CORE_CAPEXT_ADDR (SI_ENUM_BASE + 0x64c) #define CORE_CAPEXT_SR_SUPPORTED_MASK (1 << 1) -#define RCTL_MACPHY_DISABLE_MASK (1 << 26) -#define RCTL_LOGIC_DISABLE_MASK (1 << 27) +#define RCTL_MACPHY_DISABLE_MASK (1 << 26) +#define RCTL_LOGIC_DISABLE_MASK (1 << 27) #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) -#define CC_CHIPCTRL3_SR_ENG_ENABLE (1 << 2) -#define OVERFLOW_BLKSZ512_WM 48 -#define OVERFLOW_BLKSZ512_MES 80 #define CC_PMUCC3 (0x3) /* Private data for SDIO bus interaction */ @@ -389,7 +380,6 @@ static int tx_packets[NUMPRIO]; const uint dhd_deferred_tx = 1; extern uint dhd_watchdog_ms; - extern void dhd_os_wd_timer(void *bus, uint wdtick); /* Tx/Rx bounds */ @@ -398,15 +388,10 @@ uint dhd_rxbound; uint dhd_txminmax = DHD_TXMINMAX; /* override the RAM size if possible */ -#define DONGLE_MIN_RAMSIZE (128 *1024) -int dhd_dongle_ramsize; - -uint dhd_doflow = TRUE; -uint dhd_dpcpoll = FALSE; - -module_param(dhd_doflow, uint, 0644); -module_param(dhd_dpcpoll, uint, 0644); +#define DONGLE_MIN_MEMSIZE (128 *1024) +int dhd_dongle_memsize; +static bool dhd_doflow; static bool dhd_alignctl; static bool sd1idle; @@ -420,7 +405,7 @@ static uint mesbusyctrl = 80; #else static const uint watermark = 8; static const uint mesbusyctrl = 0; -#endif +#endif static const uint firstread = DHD_FIRSTREAD; #define HDATLEN (firstread - (SDPCM_HDRLEN)) @@ -431,6 +416,61 @@ static const uint retry_limit = 2; /* Force even SD lengths (some host controllers mess up on odd bytes) */ static bool forcealign; +#define FW_TYPE_STA 0 +#define FW_TYPE_APSTA 1 +#define FW_TYPE_P2P 2 +#define FW_TYPE_MFG 3 +#define FW_TYPE_G 0 +#define FW_TYPE_AG 1 + +const static char *bcm40183b2_fw_name[] = { + "fw_bcm40183b2.bin", + "fw_bcm40183b2_apsta.bin", + "fw_bcm40183b2_p2p.bin", + "fw_bcm40183b2_mfg.bin" +}; + +const static char *bcm40183b2ag_fw_name[] = { + "fw_bcm40183b2_ag.bin", + "fw_bcm40183b2_ag_apsta.bin", + "fw_bcm40183b2_ag_p2p.bin", + "fw_bcm40183b2_ag_mfg.bin" +}; + +const static char *bcm40181a0_fw_name[] = { + "fw_bcm40181a0.bin", + "fw_bcm40181a0_apsta.bin", + "fw_bcm40181a0_p2p.bin", + "fw_bcm40181a0_mfg.bin" +}; + +const static char *bcm40181a2_fw_name[] = { + "fw_bcm40181a2.bin", + "fw_bcm40181a2_apsta.bin", + "fw_bcm40181a2_p2p.bin", + "fw_bcm40181a2_mfg.bin" +}; + +const static char *bcm43341b0ag_fw_name[] = { + "fw_bcm43341b0_ag.bin", + "fw_bcm43341b0_ag_apsta.bin", + "fw_bcm43341b0_ag_p2p.bin", + "fw_bcm43341b0_ag_mfg.bin" +}; + +const static char *bcm43241b4ag_fw_name[] = { + "fw_bcm43241b4_ag.bin", + "fw_bcm43241b4_ag_apsta.bin", + "fw_bcm43241b4_ag_p2p.bin", + "fw_bcm43241b4_ag_mfg.bin" +}; + +#define BCM4330B2_CHIP_REV 4 +#define BCM43362A0_CHIP_REV 0 +#define BCM43362A2_CHIP_REV 1 +#define BCM43341B0_CHIP_REV 2 +#define BCM43241B4_CHIP_REV 5 + #define ALIGNMENT 4 #if defined(OOB_INTR_ONLY) && defined(HW_OOB) @@ -458,6 +498,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) && \ @@ -568,7 +609,7 @@ static bool dhdsdio_probe_init(dhd_bus_t static void dhdsdio_release_dongle(dhd_bus_t *bus, osl_t *osh, bool dongle_isolation, bool reset_flag); -static void dhd_dongle_setramsize(struct dhd_bus *bus, int mem_size); +static void dhd_dongle_setmemsize(struct dhd_bus *bus, int mem_size); static int dhd_bcmsdh_recv_buf(dhd_bus_t *bus, uint32 addr, uint fn, uint flags, uint8 *buf, uint nbytes, void *pkt, bcmsdh_cmplt_fn_t complete, void *handle); @@ -576,7 +617,7 @@ static int dhd_bcmsdh_send_buf(dhd_bus_t uint8 *buf, uint nbytes, void *pkt, bcmsdh_cmplt_fn_t complete, void *handle); #ifdef BCMSDIOH_TXGLOM -static void dhd_bcmsdh_glom_post(dhd_bus_t *bus, uint8 *frame, void *pkt, uint len); +static void dhd_bcmsdh_glom_post(dhd_bus_t *bus, uint8 *frame, uint len); static void dhd_bcmsdh_glom_clear(dhd_bus_t *bus); #endif @@ -598,48 +639,15 @@ extern uint32 dhd_get_htsf(void *dhd, in #endif /* WLMEDIA_HTSF */ static void -dhd_overflow_war(struct dhd_bus *bus) -{ - int err; - uint8 devctl, wm, mes; - - /* See .ppt in PR for these recommended values */ - if (bus->blocksize == 512) { - wm = OVERFLOW_BLKSZ512_WM; - mes = OVERFLOW_BLKSZ512_MES; - } else { - mes = bus->blocksize/4; - wm = bus->blocksize/4; - } - - - /* Update watermark */ - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_WATERMARK, wm, &err); - - devctl = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); - devctl |= SBSDIO_DEVCTL_F2WM_ENAB; - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, devctl, &err); - - /* Update MES */ - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_MESBUSYCTRL, - (mes | SBSDIO_MESBUSYCTRL_ENAB), &err); - - DHD_INFO(("Apply overflow WAR: 0x%02x 0x%02x 0x%02x\n", - bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err), - bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_WATERMARK, &err), - bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_MESBUSYCTRL, &err))); -} - -static void -dhd_dongle_setramsize(struct dhd_bus *bus, int mem_size) +dhd_dongle_setmemsize(struct dhd_bus *bus, int mem_size) { - int32 min_size = DONGLE_MIN_RAMSIZE; - /* Restrict the ramsize to user specified limit */ + int32 min_size = DONGLE_MIN_MEMSIZE; + /* Restrict the memsize to user specified limit */ DHD_ERROR(("user: Restrict the dongle ram size to %d, min accepted %d\n", - dhd_dongle_ramsize, min_size)); - if ((dhd_dongle_ramsize > min_size) && - (dhd_dongle_ramsize < (int32)bus->orig_ramsize)) - bus->ramsize = dhd_dongle_ramsize; + dhd_dongle_memsize, min_size)); + if ((dhd_dongle_memsize > min_size) && + (dhd_dongle_memsize < (int32)bus->orig_ramsize)) + bus->ramsize = dhd_dongle_memsize; } static int @@ -688,17 +696,15 @@ static bool dhdsdio_sr_cap(dhd_bus_t *bus) { bool cap = FALSE; - uint32 core_capext, addr, data; + uint32 min = 0, core_capext, addr, data; if (bus->sih->chip == BCM4324_CHIP_ID) { addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, chipcontrol_addr); data = SI_ENUM_BASE + OFFSETOF(chipcregs_t, chipcontrol_data); bcmsdh_reg_write(bus->sdh, addr, 4, 3); core_capext = bcmsdh_reg_read(bus->sdh, data, 4); - } else if (bus->sih->chip == BCM4330_CHIP_ID) { + } else if (bus->sih->chip == BCM4330_CHIP_ID || bus->sih->chip == BCM43362_CHIP_ID) { core_capext = FALSE; - } else if ((bus->sih->chip == BCM4335_CHIP_ID) || - (bus->sih->chip == BCM4339_CHIP_ID) || - (bus->sih->chip == BCM4350_CHIP_ID)) { + } else if (bus->sih->chip == BCM4335_CHIP_ID) { core_capext = TRUE; } else { core_capext = bcmsdh_reg_read(bus->sdh, CORE_CAPEXT_ADDR, 4); @@ -709,20 +715,16 @@ dhdsdio_sr_cap(dhd_bus_t *bus) if (bus->sih->chip == BCM4324_CHIP_ID) { /* FIX: Should change to query SR control register instead */ - cap = TRUE; - } else if ((bus->sih->chip == BCM4335_CHIP_ID) || - (bus->sih->chip == BCM4339_CHIP_ID)) { + min = bcmsdh_reg_read(bus->sdh, MIN_RSRC_ADDR, 4); + if (min == MIN_RSRC_SR) + cap = TRUE; + } else if (bus->sih->chip == BCM4335_CHIP_ID) { uint32 enabval = 0; addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, chipcontrol_addr); data = SI_ENUM_BASE + OFFSETOF(chipcregs_t, chipcontrol_data); bcmsdh_reg_write(bus->sdh, addr, 4, CC_PMUCC3); enabval = bcmsdh_reg_read(bus->sdh, data, 4); - if ((bus->sih->chip == BCM4350_CHIP_ID) || - 0) - enabval &= CC_CHIPCTRL3_SR_ENG_ENABLE; - - if (enabval) cap = TRUE; } else { @@ -738,6 +740,7 @@ dhdsdio_sr_cap(dhd_bus_t *bus) static int dhdsdio_srwar_init(dhd_bus_t *bus) { + bcmsdh_gpio_init(bus->sdh); #ifdef USE_OOB_GPIO1 @@ -806,8 +809,7 @@ dhdsdio_clk_kso_init(dhd_bus_t *bus) } #define KSO_DBG(x) -#define KSO_WAIT_US 50 -#define MAX_KSO_ATTEMPTS (PMU_MAX_TRANSITION_DLY/KSO_WAIT_US) +#define MAX_KSO_ATTEMPTS 64 static int dhdsdio_clk_kso_enab(dhd_bus_t *bus, bool on) { @@ -825,9 +827,10 @@ dhdsdio_clk_kso_enab(dhd_bus_t *bus, boo cmp_val = SBSDIO_FUNC1_SLEEPCSR_KSO_MASK | SBSDIO_FUNC1_SLEEPCSR_DEVON_MASK; bmask = cmp_val; - OSL_SLEEP(3); + msleep(3); + } else { - /* Put device to sleep, turn off KSO */ + /* Put device to sleep, turn off KSO */ cmp_val = 0; bmask = SBSDIO_FUNC1_SLEEPCSR_KSO_MASK; } @@ -838,15 +841,17 @@ dhdsdio_clk_kso_enab(dhd_bus_t *bus, boo break; KSO_DBG(("%s> KSO wr/rd retry:%d, ERR:%x \n", __FUNCTION__, try_cnt, err)); - OSL_DELAY(KSO_WAIT_US); + OSL_DELAY(50); bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SLEEPCSR, wr_val, &err); + } while (try_cnt++ < MAX_KSO_ATTEMPTS); - if (try_cnt > 2) + if (try_cnt > 1) { KSO_DBG(("%s> op:%s, try_cnt:%d, rd_val:%x, ERR:%x \n", __FUNCTION__, (on ? "KSO_SET" : "KSO_CLR"), try_cnt, rd_val, err)); + } if (try_cnt > MAX_KSO_ATTEMPTS) { DHD_ERROR(("%s> op:%s, ERROR: try_cnt:%d, rd_val:%x, ERR:%x \n", @@ -878,7 +883,16 @@ dhdsdio_clk_kso_iovar(dhd_bus_t *bus, bo 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))); @@ -960,10 +974,8 @@ dhdsdio_clk_devsleep_iovar(dhd_bus_t *bu #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 /* USE_CMD14 */ +#endif } else { /* Exit Sleep */ /* Make sure we have SD bus access */ @@ -973,8 +985,7 @@ dhdsdio_clk_devsleep_iovar(dhd_bus_t *bu } if ((bus->sih->chip == BCM4334_CHIP_ID) && (bus->sih->chiprev == 2)) { - SPINWAIT_SLEEP(sdioh_spinwait_sleep, - (bcmsdh_gpioin(bus->sdh, GPIO_DEV_SRSTATE) != TRUE), + SPINWAIT((bcmsdh_gpioin(bus->sdh, GPIO_DEV_SRSTATE) != TRUE), GPIO_DEV_SRSTATE_TIMEOUT); if (bcmsdh_gpioin(bus->sdh, GPIO_DEV_SRSTATE) == FALSE) { @@ -1010,13 +1021,12 @@ dhdsdio_clk_devsleep_iovar(dhd_bus_t *bu } #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); if (err) - OSL_SLEEP(10); + OSL_DELAY(10000); } while ((err != 0) && (++retry < 3)); if (err != 0) { @@ -1029,8 +1039,7 @@ dhdsdio_clk_devsleep_iovar(dhd_bus_t *bu uint8 csr; /* Wait for device ready during transition to wake-up */ - SPINWAIT_SLEEP(sdioh_spinwait_sleep, - (((csr = dhdsdio_sleepcsr_get(bus)) & + SPINWAIT((((csr = dhdsdio_sleepcsr_get(bus)) & SBSDIO_FUNC1_SLEEPCSR_DEVON_MASK) != (SBSDIO_FUNC1_SLEEPCSR_DEVON_MASK)), (20000)); @@ -1042,8 +1051,7 @@ dhdsdio_clk_devsleep_iovar(dhd_bus_t *bu err = BCME_NODEVICE; } - SPINWAIT_SLEEP(sdioh_spinwait_sleep, - (((csr = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, + SPINWAIT((((csr = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err)) & SBSDIO_HT_AVAIL) != (SBSDIO_HT_AVAIL)), (10000)); @@ -1074,6 +1082,9 @@ dhdsdio_htclk(dhd_bus_t *bus, bool on, b DHD_TRACE(("%s: Enter\n", __FUNCTION__)); +#if defined(OOB_INTR_ONLY) + pendok = FALSE; +#endif clkctl = 0; sdh = bus->sdh; @@ -1109,6 +1120,12 @@ dhdsdio_htclk(dhd_bus_t *bus, bool on, b ht_avail_error = 0; } + if (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 */ clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err); @@ -1117,7 +1134,6 @@ dhdsdio_htclk(dhd_bus_t *bus, bool on, b return BCME_ERROR; } -#if !defined(OOB_INTR_ONLY) /* Go to pending and await interrupt if appropriate */ if (!SBSDIO_CLKAV(clkctl, bus->alp_only) && pendok) { /* Allow only clock-available interrupt */ @@ -1133,15 +1149,11 @@ dhdsdio_htclk(dhd_bus_t *bus, bool on, b DHD_INFO(("CLKCTL: set PENDING\n")); bus->clkstate = CLK_PENDING; return BCME_OK; - } else -#endif /* !defined (OOB_INTR_ONLY) */ - { - if (bus->clkstate == CLK_PENDING) { - /* Cancel CA-only interrupt filter */ - devctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); - devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, devctl, &err); - } + } else if (bus->clkstate == CLK_PENDING) { + /* Cancel CA-only interrupt filter */ + devctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); + devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; + bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, devctl, &err); } /* Otherwise, wait here (polling) for HT Avail */ @@ -1185,7 +1197,6 @@ dhdsdio_htclk(dhd_bus_t *bus, bool on, b #endif /* DHD_USE_IDLECOUNT */ } 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); @@ -1465,7 +1476,6 @@ dhdsdio_bussleep(dhd_bus_t *bus, bool sl return err; } - #if defined(OOB_INTR_ONLY) void dhd_enable_oob_intr(struct dhd_bus *bus, bool enable) @@ -1497,234 +1507,6 @@ dhd_enable_oob_intr(struct dhd_bus *bus, } #endif -#ifdef DHDTCPACK_SUPPRESS -extern bool dhd_use_tcpack_suppress; - -/* Please be sure this function is called under dhd_os_tcpacklock() */ -void dhd_onoff_tcpack_sup(void *pub, bool on) -{ - dhd_pub_t *dhdp = (dhd_pub_t *)pub; - - if (dhd_use_tcpack_suppress != on) { - - DHD_ERROR(("dhd_onoff_tcpack_sup: %d -> %d\n", dhd_use_tcpack_suppress, on)); - dhd_use_tcpack_suppress = on; - dhdp->tcp_ack_info_cnt = 0; - bzero(dhdp->tcp_ack_info_tbl, sizeof(struct tcp_ack_info)*MAXTCPSTREAMS); - - } else - DHD_ERROR(("dhd_onoff_tcpack_sup: alread %d\n", on)); - - return; -} - -inline void dhd_tcpack_check_xmit(dhd_pub_t *dhdp, void *pkt) -{ - uint8 i; - tcp_ack_info_t *tcp_ack_info = NULL; - int tbl_cnt; - - dhd_os_tcpacklock(dhdp); - tbl_cnt = dhdp->tcp_ack_info_cnt; - for (i = 0; i < tbl_cnt; i++) { - tcp_ack_info = &dhdp->tcp_ack_info_tbl[i]; - if (tcp_ack_info->p_tcpackinqueue == pkt) { - /* This pkt is being transmitted so remove the tcp_ack_info of it. - * compact the array unless the last element, - * then the pkt's array is removed. - */ - if (i < tbl_cnt-1) { - memmove(&dhdp->tcp_ack_info_tbl[i], - &dhdp->tcp_ack_info_tbl[i+1], - sizeof(struct tcp_ack_info)*(tbl_cnt - (i+1))); - } - bzero(&dhdp->tcp_ack_info_tbl[tbl_cnt-1], sizeof(struct tcp_ack_info)); - if (--dhdp->tcp_ack_info_cnt < 0) { - DHD_ERROR(("dhdsdio_sendfromq:(ERROR) tcp_ack_info_cnt %d" - " Stop using tcpack_suppress\n", dhdp->tcp_ack_info_cnt)); - dhd_onoff_tcpack_sup(dhdp, FALSE); - } - break; - } - } - dhd_os_tcpackunlock(dhdp); -} - -bool -dhd_tcpack_suppress(dhd_pub_t *dhdp, void *pkt) -{ - uint8 *eh_header; - uint16 eh_type; - uint8 *ip_header; - uint8 *tcp_header; - uint32 ip_hdr_len; - uint32 cur_framelen; - uint8 bdc_hdr_len = BDC_HEADER_LEN; - uint8 wlfc_hdr_len = 0; - uint8 *data = PKTDATA(dhdp->osh, pkt); - cur_framelen = PKTLEN(dhdp->osh, pkt); - -#ifdef PROP_TXSTATUS - /* In this case, BDC header is not pushed in dhd_sendpkt() */ - if (dhdp->wlfc_state) { - bdc_hdr_len = 0; - wlfc_hdr_len = 8; - } -#endif - if (cur_framelen < bdc_hdr_len + ETHER_HDR_LEN) { - DHD_TRACE(("dhd_tcpack_suppress: Too short packet length %d\n", cur_framelen)); - return FALSE; - } - - /* Get rid of BDC header */ - eh_header = data + bdc_hdr_len; - cur_framelen -= bdc_hdr_len; - eh_type = eh_header[12] << 8 | eh_header[13]; - - if (eh_type != ETHER_TYPE_IP) { - DHD_TRACE(("dhd_tcpack_suppress: Not a IP packet 0x%x\n", eh_type)); - return FALSE; - } - - DHD_TRACE(("dhd_tcpack_suppress: IP pkt! 0x%x\n", eh_type)); - - ip_header = eh_header + ETHER_HDR_LEN; - cur_framelen -= ETHER_HDR_LEN; - ip_hdr_len = 4 * (ip_header[0] & 0x0f); - - if ((ip_header[0] & 0xf0) != 0x40) { - DHD_TRACE(("dhd_tcpack_suppress: Not IPv4!\n")); - return FALSE; - } - - if (cur_framelen < ip_hdr_len) { - DHD_ERROR(("dhd_tcpack_suppress: IP packet length %d wrong!\n", cur_framelen)); - return FALSE; - } - - /* not tcp */ - if (ip_header[9] != 0x06) { - DHD_TRACE(("dhd_tcpack_suppress: Not a TCP packet 0x%x\n", ip_header[9])); - return FALSE; - } - - DHD_TRACE(("dhd_tcpack_suppress: TCP pkt!\n")); - - tcp_header = ip_header + ip_hdr_len; - - /* is it an ack ? */ - if (tcp_header[13] == 0x10) { -#if defined(DHD_DEBUG) - uint32 tcp_seq_num = tcp_header[4] << 24 | tcp_header[5] << 16 | - tcp_header[6] << 8 | tcp_header[7]; -#endif - uint32 tcp_ack_num = tcp_header[8] << 24 | tcp_header[9] << 16 | - tcp_header[10] << 8 | tcp_header[11]; - uint16 ip_tcp_ttllen = (ip_header[3] & 0xff) + (ip_header[2] << 8); - uint32 tcp_hdr_len = 4*((tcp_header[12] & 0xf0) >> 4); - DHD_TRACE(("dhd_tcpack_suppress: TCP ACK seq %ud ack %ud\n", - tcp_seq_num, tcp_ack_num)); - - - /* zero length ? */ - if (ip_tcp_ttllen == ip_hdr_len + tcp_hdr_len) { - int i; - tcp_ack_info_t *tcp_ack_info = NULL; - DHD_TRACE(("dhd_tcpack_suppress: TCP ACK zero length\n")); - /* Look for tcp_ack_info that has the same - * ip src/dst addrs and tcp src/dst ports - */ - dhd_os_tcpacklock(dhdp); - for (i = 0; i < dhdp->tcp_ack_info_cnt; i++) { - if (dhdp->tcp_ack_info_tbl[i].p_tcpackinqueue && - !memcmp(&ip_header[12], dhdp->tcp_ack_info_tbl[i].ipaddrs, 8) && - !memcmp(tcp_header, dhdp->tcp_ack_info_tbl[i].tcpports, 4)) { - tcp_ack_info = &dhdp->tcp_ack_info_tbl[i]; - break; - } - } - - if (i == dhdp->tcp_ack_info_cnt && i < MAXTCPSTREAMS) - tcp_ack_info = &dhdp->tcp_ack_info_tbl[dhdp->tcp_ack_info_cnt++]; - - if (!tcp_ack_info) { - DHD_TRACE(("dhd_tcpack_suppress: No empty tcp ack info" - "%d %d %d %d, %d %d %d %d\n", - tcp_header[0], tcp_header[1], tcp_header[2], tcp_header[3], - dhdp->tcp_ack_info_tbl[i].tcpports[0], - dhdp->tcp_ack_info_tbl[i].tcpports[1], - dhdp->tcp_ack_info_tbl[i].tcpports[2], - dhdp->tcp_ack_info_tbl[i].tcpports[3])); - dhd_os_tcpackunlock(dhdp); - return FALSE; - } - - if (tcp_ack_info->p_tcpackinqueue) { - if (tcp_ack_num > tcp_ack_info->tcpack_number) { - void *prevpkt = tcp_ack_info->p_tcpackinqueue; - uint8 pushed_len = SDPCM_HDRLEN + - (BDC_HEADER_LEN - bdc_hdr_len) + wlfc_hdr_len; -#ifdef PROP_TXSTATUS - /* In case the prev pkt is delayenqueued - * but not delayedequeued yet, it may not have - * any additional header yet. - */ - if (dhdp->wlfc_state && (PKTLEN(dhdp->osh, prevpkt) == - tcp_ack_info->ip_tcp_ttllen + ETHER_HDR_LEN)) - pushed_len = 0; -#endif - if ((ip_tcp_ttllen == tcp_ack_info->ip_tcp_ttllen) && - (PKTLEN(dhdp->osh, pkt) == - PKTLEN(dhdp->osh, prevpkt) - pushed_len)) { - bcopy(PKTDATA(dhdp->osh, pkt), - PKTDATA(dhdp->osh, prevpkt) + pushed_len, - PKTLEN(dhdp->osh, pkt)); - PKTFREE(dhdp->osh, pkt, FALSE); - DHD_TRACE(("dhd_tcpack_suppress: pkt 0x%p" - " TCP ACK replace %ud -> %ud\n", prevpkt, - tcp_ack_info->tcpack_number, tcp_ack_num)); - tcp_ack_info->tcpack_number = tcp_ack_num; - dhd_os_tcpackunlock(dhdp); - return TRUE; - } else - DHD_TRACE(("dhd_tcpack_suppress: len mismatch" - " %d(%d) %d(%d)\n", - PKTLEN(dhdp->osh, pkt), ip_tcp_ttllen, - PKTLEN(dhdp->osh, prevpkt), - tcp_ack_info->ip_tcp_ttllen)); - } else { -#ifdef TCPACK_TEST - void *prevpkt = tcp_ack_info->p_tcpackinqueue; -#endif - DHD_TRACE(("dhd_tcpack_suppress: TCP ACK number reverse" - " prev %ud (0x%p) new %ud (0x%p)\n", - tcp_ack_info->tcpack_number, - tcp_ack_info->p_tcpackinqueue, - tcp_ack_num, pkt)); -#ifdef TCPACK_TEST - if (PKTLEN(dhdp->osh, pkt) == PKTLEN(dhdp->osh, prevpkt)) { - PKTFREE(dhdp->osh, pkt, FALSE); - dhd_os_tcpackunlock(dhdp); - return TRUE; - } -#endif - } - } else { - tcp_ack_info->p_tcpackinqueue = pkt; - tcp_ack_info->tcpack_number = tcp_ack_num; - tcp_ack_info->ip_tcp_ttllen = ip_tcp_ttllen; - bcopy(&ip_header[12], tcp_ack_info->ipaddrs, 8); - bcopy(tcp_header, tcp_ack_info->tcpports, 4); - } - dhd_os_tcpackunlock(dhdp); - } else - DHD_TRACE(("dhd_tcpack_suppress: TCP ACK with DATA len %d\n", - ip_tcp_ttllen - ip_hdr_len - tcp_hdr_len)); - } - return FALSE; -} -#endif /* DHDTCPACK_SUPPRESS */ - /* Writes a HW/SW header into the packet and sends it. */ /* Assumes: (a) header space already there, (b) caller holds lock */ static int @@ -1733,10 +1515,9 @@ dhdsdio_txpkt(dhd_bus_t *bus, void *pkt, int ret; osl_t *osh; uint8 *frame; - uint16 len, pad1 = 0, act_len = 0; + uint16 len, pad1 = 0; uint32 swheader; uint retries = 0; - uint32 real_pad = 0; bcmsdh_info_t *sdh; void *new; int i; @@ -1749,17 +1530,12 @@ dhdsdio_txpkt(dhd_bus_t *bus, void *pkt, htsfts_t *htsf_ts; #endif + DHD_TRACE(("%s: Enter\n", __FUNCTION__)); sdh = bus->sdh; osh = bus->dhd->osh; -#ifdef DHDTCPACK_SUPPRESS - if (dhd_use_tcpack_suppress) { - dhd_tcpack_check_xmit(bus->dhd, pkt); - } -#endif /* DHDTCPACK_SUPPRESS */ - if (bus->dhd->dongle_reset) { ret = BCME_NOTREADY; goto done; @@ -1779,7 +1555,7 @@ dhdsdio_txpkt(dhd_bus_t *bus, void *pkt, #endif /* WLMEDIA_HTSF */ /* Add alignment padding, allocate new packet if needed */ - if ((pad1 = ((uintptr)frame % DHD_SDALIGN))) { + if (!((uintptr)frame & 1) && (pad1 = ((uintptr)frame % DHD_SDALIGN))) { if (PKTHEADROOM(osh, pkt) < pad1) { DHD_INFO(("%s: insufficient headroom %d for %d pad1\n", __FUNCTION__, (int)PKTHEADROOM(osh, pkt), pad1)); @@ -1819,8 +1595,7 @@ dhdsdio_txpkt(dhd_bus_t *bus, void *pkt, #ifdef BCMSDIOH_TXGLOM if (bus->glom_enable) { - uint32 hwheader1 = 0, hwheader2 = 0; - act_len = len; + uint32 hwheader1 = 0, hwheader2 = 0, act_len = len; /* Software tag: channel, sequence number, data offset */ swheader = ((chan << SDPCM_CHANNEL_SHIFT) & SDPCM_CHANNEL_MASK) | @@ -1830,9 +1605,8 @@ dhdsdio_txpkt(dhd_bus_t *bus, void *pkt, htol32_ua_store(0, frame + SDPCM_FRAMETAG_LEN + SDPCM_HWEXT_LEN + sizeof(swheader)); if (queue_only) { - uint8 alignment = ALIGNMENT; - if (forcealign && (len & (alignment - 1))) - len = ROUNDUP(len, alignment); + if (forcealign && (len & (ALIGNMENT - 1))) + len = ROUNDUP(len, ALIGNMENT); /* Hardware extention tag */ /* 2byte frame length, 1byte-, 1byte frame flag, * 2byte-hdrlength, 2byte padlenght @@ -1841,25 +1615,8 @@ dhdsdio_txpkt(dhd_bus_t *bus, void *pkt, hwheader2 = (len - act_len) << 16; htol32_ua_store(hwheader1, frame + SDPCM_FRAMETAG_LEN); htol32_ua_store(hwheader2, frame + SDPCM_FRAMETAG_LEN + 4); - real_pad = len - act_len; - if (PKTTAILROOM(osh, pkt) < real_pad) { - DHD_INFO(("%s 1: insufficient tailroom %d for %d real_pad\n", - __FUNCTION__, (int)PKTTAILROOM(osh, pkt), real_pad)); - if (PKTPADTAILROOM(osh, pkt, real_pad)) { - DHD_ERROR(("CHK1: padding error size %d\n", real_pad)); - ret = BCME_NOMEM; - goto done; - } -#ifndef BCMLXSDMMC - else - PKTSETLEN(osh, pkt, act_len); -#endif - } -#ifdef BCMLXSDMMC - PKTSETLEN(osh, pkt, len); -#endif /* BCMLXSDMMC */ /* Post the frame pointer to sdio glom array */ - dhd_bcmsdh_glom_post(bus, frame, pkt, len); + dhd_bcmsdh_glom_post(bus, frame, len); /* Save the pkt pointer in bus glom array */ bus->glom_pkt_arr[bus->glom_cnt] = pkt; bus->glom_total_len += len; @@ -1891,36 +1648,9 @@ dhdsdio_txpkt(dhd_bus_t *bus, void *pkt, hwheader2 = (len - act_len) << 16; htol32_ua_store(hwheader1, frame + SDPCM_FRAMETAG_LEN); htol32_ua_store(hwheader2, frame + SDPCM_FRAMETAG_LEN + 4); - real_pad = len - act_len; - if (PKTTAILROOM(osh, pkt) < real_pad) { - DHD_INFO(("%s 2: insufficient tailroom %d" - " for %d real_pad\n", - __FUNCTION__, (int)PKTTAILROOM(osh, pkt), real_pad)); - if (PKTPADTAILROOM(osh, pkt, real_pad)) { - DHD_ERROR(("CHK2: padding error size %d." - " %d more pkts are discarded together.\n", - real_pad, bus->glom_cnt)); - /* Save the pkt pointer in bus glom array - * Otherwise, this last pkt will not be - * cleaned under "goto done" - */ - bus->glom_pkt_arr[bus->glom_cnt] = pkt; - bus->glom_cnt++; - bus->glom_total_len += len; - ret = BCME_NOMEM; - goto done; - } -#ifndef BCMLXSDMMC - else - PKTSETLEN(osh, pkt, act_len); -#endif - } -#ifdef BCMLXSDMMC - PKTSETLEN(osh, pkt, len); -#endif /* BCMLXSDMMC */ /* Post the frame pointer to sdio glom array */ - dhd_bcmsdh_glom_post(bus, frame, pkt, len); + dhd_bcmsdh_glom_post(bus, frame, len); /* Save the pkt pointer in bus glom array */ bus->glom_pkt_arr[bus->glom_cnt] = pkt; bus->glom_cnt++; @@ -1934,7 +1664,6 @@ dhdsdio_txpkt(dhd_bus_t *bus, void *pkt, } else #endif /* BCMSDIOH_TXGLOM */ { - act_len = len; /* Software tag: channel, sequence number, data offset */ swheader = ((chan << SDPCM_CHANNEL_SHIFT) & SDPCM_CHANNEL_MASK) | bus->tx_seq | (((pad1 + SDPCM_HDRLEN) << SDPCM_DOFFSET_SHIFT) & SDPCM_DOFFSET_MASK); @@ -1977,24 +1706,8 @@ dhdsdio_txpkt(dhd_bus_t *bus, void *pkt, DHD_ERROR(("%s: sending unrounded %d-byte packet\n", __FUNCTION__, len)); #endif } - real_pad = len - act_len; - if (PKTTAILROOM(osh, pkt) < real_pad) { - DHD_INFO(("%s 3: insufficient tailroom %d for %d real_pad\n", - __FUNCTION__, (int)PKTTAILROOM(osh, pkt), real_pad)); - if (PKTPADTAILROOM(osh, pkt, real_pad)) { - DHD_ERROR(("CHK3: padding error size %d\n", real_pad)); - ret = BCME_NOMEM; - goto done; - } -#ifndef BCMLXSDMMC - else - PKTSETLEN(osh, pkt, act_len); -#endif - } -#ifdef BCMLXSDMMC - PKTSETLEN(osh, pkt, len); -#endif /* BCMLXSDMMC */ } + do { ret = dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, frame, len, pkt, NULL, NULL); @@ -2040,7 +1753,7 @@ dhdsdio_txpkt(dhd_bus_t *bus, void *pkt, done: #ifdef BCMSDIOH_TXGLOM - if (bus->glom_enable && !queue_only) { + if (bus->glom_enable) { dhd_bcmsdh_glom_clear(bus); pkt_cnt = bus->glom_cnt; } else @@ -2053,33 +1766,20 @@ done: #ifdef BCMSDIOH_TXGLOM uint32 doff; if (bus->glom_enable) { -#ifdef BCMLXSDMMC - uint32 pad2 = 0; -#endif /* BCMLXSDMMC */ - if (!queue_only) - pkt = bus->glom_pkt_arr[bus->glom_cnt - pkt_cnt]; - + pkt = bus->glom_pkt_arr[bus->glom_cnt - pkt_cnt]; frame = (uint8*)PKTDATA(osh, pkt); doff = ltoh32_ua(frame + SDPCM_FRAMETAG_LEN + SDPCM_HWEXT_LEN); doff = (doff & SDPCM_DOFFSET_MASK) >> SDPCM_DOFFSET_SHIFT; -#ifdef BCMLXSDMMC - pad2 = ltoh32_ua(frame + SDPCM_FRAMETAG_LEN + 4) >> 16; - PKTSETLEN(osh, pkt, PKTLEN(osh, pkt) - pad2); -#endif /* BCMLXSDMMC */ PKTPULL(osh, pkt, doff); } else -#endif /* BCMSDIOH_TXGLOM */ +#endif { -#ifdef BCMLXSDMMC - if (act_len > 0) - PKTSETLEN(osh, pkt, act_len); -#endif /* BCMLXSDMMC */ - PKTPULL(osh, pkt, SDPCM_HDRLEN + pad1); + PKTPULL(osh, pkt, SDPCM_HDRLEN + pad1); } #ifdef PROP_TXSTATUS if (bus->dhd->wlfc_state) { dhd_os_sdunlock(bus->dhd); - dhd_wlfc_txcomplete(bus->dhd, pkt, ret == 0); + dhd_wlfc_txcomplete(bus->dhd, pkt, ret == 0, FALSE); dhd_os_sdlock(bus->dhd); } else { #endif /* PROP_TXSTATUS */ @@ -2101,7 +1801,7 @@ done: #ifdef BCMSDIOH_TXGLOM /* Reset the glom array */ - if (bus->glom_enable && !queue_only) { + if (bus->glom_enable) { bus->glom_cnt = 0; bus->glom_total_len = 0; } @@ -2110,7 +1810,7 @@ done: } int -dhd_bus_txdata(struct dhd_bus *bus, void *pkt) +dhd_bus_txdata(struct dhd_bus *bus, void *pkt, bool wlfc_locked) { int ret = BCME_ERROR; osl_t *osh; @@ -2195,7 +1895,7 @@ dhd_bus_txdata(struct dhd_bus *bus, void #endif #ifdef PROP_TXSTATUS if (bus->dhd->wlfc_state) - dhd_wlfc_txcomplete(bus->dhd, pkt, FALSE); + dhd_wlfc_txcomplete(bus->dhd, pkt, FALSE, wlfc_locked); else #endif dhd_txcomplete(bus->dhd, pkt, FALSE); @@ -2212,6 +1912,7 @@ dhd_bus_txdata(struct dhd_bus *bus, void } else ret = BCME_OK; + dhd_os_sdunlock_txq(bus->dhd); if ((pktq_len(&bus->txq) >= FCHI) && dhd_doflow) dhd_txflowcontrol(bus->dhd, ALL_INTERFACES, ON); @@ -2220,8 +1921,6 @@ dhd_bus_txdata(struct dhd_bus *bus, void if (pktq_plen(&bus->txq, prec) > qcount[prec]) qcount[prec] = pktq_plen(&bus->txq, prec); #endif - dhd_os_sdunlock_txq(bus->dhd); - /* Schedule DPC if needed to send queued packet(s) */ if (dhd_deferred_tx && !bus->dpc_sched) { bus->dpc_sched = TRUE; @@ -2275,7 +1974,6 @@ dhdsdio_sendfromq(dhd_bus_t *bus, uint m uint cnt = 0; uint datalen; uint8 tx_prec_map; - uint16 txpktqlen = 0; #ifdef BCMSDIOH_TXGLOM uint i; uint8 glom_cnt; @@ -2297,36 +1995,28 @@ dhdsdio_sendfromq(dhd_bus_t *bus, uint m for (cnt = 0; (cnt < maxframes) && DATAOK(bus); cnt++) { #ifdef BCMSDIOH_TXGLOM if (bus->glom_enable) { - void *pkttable[SDPCM_MAXGLOM_SIZE]; - dhd_os_sdlock_txq(bus->dhd); glom_cnt = MIN(DATABUFCNT(bus), bus->glomsize); glom_cnt = MIN(glom_cnt, pktq_mlen(&bus->txq, tx_prec_map)); glom_cnt = MIN(glom_cnt, maxframes-cnt); /* Limiting the size to 2pkts in case of copy */ if (bus->glom_mode == SDPCM_TXGLOM_CPY) - glom_cnt = MIN(glom_cnt, 10); - - for (i = 0; i < glom_cnt; i++) - pkttable[i] = pktq_mdeq(&bus->txq, tx_prec_map, &prec_out); - - txpktqlen = pktq_len(&bus->txq); - dhd_os_sdunlock_txq(bus->dhd); + glom_cnt = MIN(glom_cnt, 5); if (glom_cnt == 0) break; datalen = 0; for (i = 0; i < glom_cnt; i++) { - uint datalen_tmp = 0; - - if ((pkt = pkttable[i]) == NULL) { + dhd_os_sdlock_txq(bus->dhd); + if ((pkt = pktq_mdeq(&bus->txq, tx_prec_map, &prec_out)) == NULL) { /* This case should not happen */ DHD_ERROR(("No pkts in the queue for glomming\n")); + dhd_os_sdunlock_txq(bus->dhd); break; } + dhd_os_sdunlock_txq(bus->dhd); - datalen_tmp = (PKTLEN(bus->dhd->osh, pkt) - SDPCM_HDRLEN); - + datalen += (PKTLEN(bus->dhd->osh, pkt) - SDPCM_HDRLEN); #ifndef SDTEST ret = dhdsdio_txpkt(bus, pkt, @@ -2340,8 +2030,6 @@ dhdsdio_sendfromq(dhd_bus_t *bus, uint m TRUE, (i == (glom_cnt-1))? FALSE: TRUE); #endif - if (ret == BCME_OK) - datalen += datalen_tmp; } cnt += i-1; } else @@ -2349,11 +2037,9 @@ dhdsdio_sendfromq(dhd_bus_t *bus, uint m { dhd_os_sdlock_txq(bus->dhd); if ((pkt = pktq_mdeq(&bus->txq, tx_prec_map, &prec_out)) == NULL) { - txpktqlen = pktq_len(&bus->txq); dhd_os_sdunlock_txq(bus->dhd); break; } - txpktqlen = pktq_len(&bus->txq); dhd_os_sdunlock_txq(bus->dhd); datalen = PKTLEN(bus->dhd->osh, pkt) - SDPCM_HDRLEN; @@ -2388,68 +2074,12 @@ dhdsdio_sendfromq(dhd_bus_t *bus, uint m /* Deflow-control stack if needed */ if (dhd_doflow && dhd->up && (dhd->busstate == DHD_BUS_DATA) && - dhd->txoff && (txpktqlen < FCLOW)) + dhd->txoff && (pktq_len(&bus->txq) < FCLOW)) dhd_txflowcontrol(dhd, ALL_INTERFACES, OFF); return cnt; } -static void -dhdsdio_sendpendctl(dhd_bus_t *bus) -{ - bcmsdh_info_t *sdh = bus->sdh; - int ret, i; - uint8* frame_seq = bus->ctrl_frame_buf + SDPCM_FRAMETAG_LEN; - -#ifdef BCMSDIOH_TXGLOM - if (bus->glom_enable) - frame_seq += SDPCM_HWEXT_LEN; -#endif - - if (*frame_seq != bus->tx_seq) { - DHD_INFO(("%s IOCTL frame seq lag detected!" - " frm_seq:%d != bus->tx_seq:%d, corrected\n", - __FUNCTION__, *frame_seq, bus->tx_seq)); - *frame_seq = bus->tx_seq; - } - - ret = dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, - (uint8 *)bus->ctrl_frame_buf, (uint32)bus->ctrl_frame_len, - NULL, NULL, NULL); - ASSERT(ret != BCME_PENDING); - 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)); - bus->tx_sderrs++; - - bcmsdh_abort(sdh, SDIO_FUNC_2); - - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL, - SFC_WF_TERM, NULL); - bus->f1regdata++; - - for (i = 0; i < 3; i++) { - uint8 hi, lo; - hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_WFRAMEBCHI, NULL); - lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_WFRAMEBCLO, NULL); - bus->f1regdata += 2; - if ((hi == 0) && (lo == 0)) - break; - } - } - if (ret == 0) { - bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; - } - - bus->ctrl_frame_stat = FALSE; - dhd_wait_event_wakeup(bus->dhd); -} - int dhd_bus_txctl(struct dhd_bus *bus, uchar *msg, uint msglen) { @@ -2629,7 +2259,7 @@ done: else bus->dhd->tx_ctlpkts++; - if (bus->dhd->txcnt_timeout >= MAX_CNTL_TX_TIMEOUT) + if (bus->dhd->txcnt_timeout >= MAX_CNTL_TIMEOUT) return -ETIMEDOUT; return ret ? -EIO : 0; @@ -2658,7 +2288,7 @@ dhd_bus_rxctl(struct dhd_bus *bus, uchar if (rxlen) { DHD_CTL(("%s: resumed on rxctl frame, got %d expected %d\n", - __FUNCTION__, rxlen, msglen)); + __FUNCTION__, rxlen, msglen)); } else if (timeleft == 0) { #ifdef DHD_DEBUG uint32 status, retry = 0; @@ -2669,15 +2299,14 @@ dhd_bus_rxctl(struct dhd_bus *bus, uchar DHD_ERROR(("%s: resumed on timeout\n", __FUNCTION__)); #endif /* DHD_DEBUG */ #ifdef DHD_DEBUG - dhd_os_sdlock(bus->dhd); - dhdsdio_checkdied(bus, NULL, 0); - dhd_os_sdunlock(bus->dhd); + dhd_os_sdlock(bus->dhd); + dhdsdio_checkdied(bus, NULL, 0); + dhd_os_sdunlock(bus->dhd); #endif /* DHD_DEBUG */ } else if (pending == TRUE) { /* signal pending */ DHD_ERROR(("%s: signal pending\n", __FUNCTION__)); return -EINTR; - } else { DHD_CTL(("%s: resumed for unknown reason?\n", __FUNCTION__)); #ifdef DHD_DEBUG @@ -2687,10 +2316,8 @@ dhd_bus_rxctl(struct dhd_bus *bus, uchar #endif /* DHD_DEBUG */ } if (timeleft == 0) { - if (rxlen == 0) - bus->dhd->rxcnt_timeout++; - DHD_ERROR(("%s: rxcnt_timeout=%d, rxlen=%d\n", __FUNCTION__, - bus->dhd->rxcnt_timeout, rxlen)); + bus->dhd->rxcnt_timeout++; + DHD_ERROR(("%s: rxcnt_timeout=%d\n", __FUNCTION__, bus->dhd->rxcnt_timeout)); } else bus->dhd->rxcnt_timeout = 0; @@ -2700,7 +2327,7 @@ dhd_bus_rxctl(struct dhd_bus *bus, uchar else bus->dhd->rx_ctlerrs++; - if (bus->dhd->rxcnt_timeout >= MAX_CNTL_RX_TIMEOUT) + if (bus->dhd->rxcnt_timeout >= MAX_CNTL_TIMEOUT) return -ETIMEDOUT; if (bus->dhd->dongle_trap_occured) @@ -2717,8 +2344,7 @@ enum { IOV_SBREG, IOV_SDCIS, IOV_MEMBYTES, - IOV_RAMSIZE, - IOV_RAMSTART, + IOV_MEMSIZE, #ifdef DHD_DEBUG IOV_CHECKDIED, IOV_SERIALCONS, @@ -2758,8 +2384,7 @@ enum { IOV_FWPATH, #endif IOV_TXGLOMSIZE, - IOV_TXGLOMMODE, - IOV_HANGREPORT + IOV_TXGLOMMODE }; const bcm_iovar_t dhdsdio_iovars[] = { @@ -2770,8 +2395,7 @@ const bcm_iovar_t dhdsdio_iovars[] = { {"idleclock", IOV_IDLECLOCK, 0, IOVT_INT32, 0 }, {"sd1idle", IOV_SD1IDLE, 0, IOVT_BOOL, 0 }, {"membytes", IOV_MEMBYTES, 0, IOVT_BUFFER, 2 * sizeof(int) }, - {"ramsize", IOV_RAMSIZE, 0, IOVT_UINT32, 0 }, - {"ramstart", IOV_RAMSTART, 0, IOVT_UINT32, 0 }, + {"memsize", IOV_MEMSIZE, 0, IOVT_UINT32, 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 }, @@ -2812,7 +2436,6 @@ const bcm_iovar_t dhdsdio_iovars[] = { #endif {"txglomsize", IOV_TXGLOMSIZE, 0, IOVT_UINT32, 0 }, {"txglommode", IOV_TXGLOMMODE, 0, IOVT_UINT32, 0 }, - {"fw_hang_report", IOV_HANGREPORT, 0, IOVT_BOOL, 0 }, {NULL, 0, 0, 0, 0 } }; @@ -2838,25 +2461,25 @@ dhd_bus_dump(dhd_pub_t *dhdp, struct bcm bcm_bprintf(strbuf, "Bus SDIO structure:\n"); bcm_bprintf(strbuf, "hostintmask 0x%08x intstatus 0x%08x sdpcm_ver %d\n", bus->hostintmask, bus->intstatus, bus->sdpcm_ver); - bcm_bprintf(strbuf, "fcstate %d qlen %u tx_seq %d, max %d, rxskip %d rxlen %u rx_seq %d\n", + bcm_bprintf(strbuf, "fcstate %d qlen %d tx_seq %d, max %d, rxskip %d rxlen %d rx_seq %d\n", bus->fcstate, pktq_len(&bus->txq), bus->tx_seq, bus->tx_max, bus->rxskip, bus->rxlen, bus->rx_seq); - bcm_bprintf(strbuf, "intr %d intrcount %u lastintrs %u spurious %u\n", + bcm_bprintf(strbuf, "intr %d intrcount %d lastintrs %d spurious %d\n", bus->intr, bus->intrcount, bus->lastintrs, bus->spurious); - bcm_bprintf(strbuf, "pollrate %u pollcnt %u regfails %u\n", + bcm_bprintf(strbuf, "pollrate %d pollcnt %d regfails %d\n", bus->pollrate, bus->pollcnt, bus->regfails); bcm_bprintf(strbuf, "\nAdditional counters:\n"); - bcm_bprintf(strbuf, "tx_sderrs %u fcqueued %u rxrtx %u rx_toolong %u rxc_errors %u\n", + bcm_bprintf(strbuf, "tx_sderrs %d fcqueued %d rxrtx %d rx_toolong %d rxc_errors %d\n", bus->tx_sderrs, bus->fcqueued, bus->rxrtx, bus->rx_toolong, bus->rxc_errors); - bcm_bprintf(strbuf, "rx_hdrfail %u badhdr %u badseq %u\n", + bcm_bprintf(strbuf, "rx_hdrfail %d badhdr %d badseq %d\n", bus->rx_hdrfail, bus->rx_badhdr, bus->rx_badseq); - bcm_bprintf(strbuf, "fc_rcvd %u, fc_xoff %u, fc_xon %u\n", + bcm_bprintf(strbuf, "fc_rcvd %d, fc_xoff %d, fc_xon %d\n", bus->fc_rcvd, bus->fc_xoff, bus->fc_xon); - bcm_bprintf(strbuf, "rxglomfail %u, rxglomframes %u, rxglompkts %u\n", + bcm_bprintf(strbuf, "rxglomfail %d, rxglomframes %d, rxglompkts %d\n", bus->rxglomfail, bus->rxglomframes, bus->rxglompkts); - bcm_bprintf(strbuf, "f2rx (hdrs/data) %u (%u/%u), f2tx %u f1regs %u\n", + bcm_bprintf(strbuf, "f2rx (hdrs/data) %d (%d/%d), f2tx %d f1regs %d\n", (bus->f2rxhdrs + bus->f2rxdata), bus->f2rxhdrs, bus->f2rxdata, bus->f2txdata, bus->f1regdata); { @@ -2896,17 +2519,17 @@ dhd_bus_dump(dhd_pub_t *dhdp, struct bcm #ifdef SDTEST if (bus->pktgen_count) { bcm_bprintf(strbuf, "pktgen config and count:\n"); - bcm_bprintf(strbuf, "freq %u count %u print %u total %u min %u len %u\n", + bcm_bprintf(strbuf, "freq %d count %d print %d total %d min %d len %d\n", bus->pktgen_freq, bus->pktgen_count, bus->pktgen_print, bus->pktgen_total, bus->pktgen_minlen, bus->pktgen_maxlen); - bcm_bprintf(strbuf, "send attempts %u rcvd %u fail %u\n", + bcm_bprintf(strbuf, "send attempts %d rcvd %d fail %d\n", bus->pktgen_sent, bus->pktgen_rcvd, bus->pktgen_fail); } #endif /* SDTEST */ #ifdef DHD_DEBUG bcm_bprintf(strbuf, "dpc_sched %d host interrupt%spending\n", bus->dpc_sched, (bcmsdh_intr_pending(bus->sdh) ? " " : " not ")); - bcm_bprintf(strbuf, "blocksize %u roundup %u\n", bus->blocksize, bus->roundup); + bcm_bprintf(strbuf, "blocksize %d roundup %d\n", bus->blocksize, bus->roundup); #endif /* DHD_DEBUG */ bcm_bprintf(strbuf, "clkstate %d activity %d idletime %d idlecount %d sleeping %d\n", bus->clkstate, bus->activity, bus->idletime, bus->idlecount, bus->sleeping); @@ -3215,9 +2838,6 @@ dhdsdio_checkdied(dhd_bus_t *bus, char * DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - if (DHD_NOCHECKDIED_ON()) - return 0; - if (data == NULL) { /* * Called after a rx ctrl timeout. "data" is NULL. @@ -3445,7 +3065,6 @@ dhd_serialconsole(dhd_bus_t *bus, bool s uart_enab = CC_PLL_CHIPCTRL_SERIAL_ENAB; } else if (bus->sih->chip == BCM4334_CHIP_ID || - bus->sih->chip == BCM43340_CHIP_ID || bus->sih->chip == BCM43341_CHIP_ID) { if (enable) { /* Moved to PMU chipcontrol 1 from 4330 */ @@ -3642,16 +3261,6 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bc DHD_INFO(("%s: Request to %s %d bytes at address 0x%08x\n", __FUNCTION__, (set ? "write" : "read"), size, address)); - /* check if CR4 */ - if (si_setcore(bus->sih, ARMCR4_CORE_ID, 0)) { - /* - * If address is start of RAM (i.e. a downloaded image), - * store the reset instruction to be written in 0 - */ - if (address == bus->dongle_ram_base) { - bus->resetinstr = *(((uint32*)params) + 2); - } - } else { /* If we know about SOCRAM, check for a fit */ if ((bus->orig_ramsize) && ((address > bus->orig_ramsize) || (address + size > bus->orig_ramsize))) @@ -3693,7 +3302,6 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bc break; } } - } /* Generate the actual data pointer */ data = set ? (uint8*)params + 2 * sizeof(int): (uint8*)arg; @@ -3704,16 +3312,11 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bc break; } - case IOV_GVAL(IOV_RAMSIZE): + case IOV_GVAL(IOV_MEMSIZE): int_val = (int32)bus->ramsize; bcopy(&int_val, arg, val_size); break; - case IOV_GVAL(IOV_RAMSTART): - int_val = (int32)bus->dongle_ram_base; - bcopy(&int_val, arg, val_size); - break; - case IOV_GVAL(IOV_SDIOD_DRIVE): int_val = (int32)dhd_sdiod_drive_strength; bcopy(&int_val, arg, val_size); @@ -3951,14 +3554,13 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bc case IOV_SVAL(IOV_MESBUSYCTRL): mesbusyctrl = (uint)int_val; mesbusyctrl = (mesbusyctrl > SBSDIO_MESBUSYCTRL_MASK) - ? SBSDIO_MESBUSYCTRL_MASK : mesbusyctrl; + ? SBSDIO_MESBUSYCTRL_MASK : mesbusyctrl; DHD_ERROR(("Setting mesbusyctrl as 0x%x.\n", mesbusyctrl)); bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_MESBUSYCTRL, ((uint8)mesbusyctrl | 0x80), NULL); break; #endif /* SDIO_CRC_ERROR_FIX */ - case IOV_GVAL(IOV_DONGLEISOLATION): int_val = bus->dhd->dongle_isolation; bcopy(&int_val, arg, val_size); @@ -4068,16 +3670,6 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bc } break; #endif /* BCMSDIOH_TXGLOM */ - - case IOV_SVAL(IOV_HANGREPORT): - bus->dhd->hang_report = bool_val; - DHD_ERROR(("%s: Set hang_report as %d\n", __FUNCTION__, bus->dhd->hang_report)); - break; - - case IOV_GVAL(IOV_HANGREPORT): - int_val = (int32)bus->dhd->hang_report; - bcopy(&int_val, arg, val_size); - break; default: bcmerror = BCME_UNSUPPORTED; break; @@ -4198,8 +3790,6 @@ dhdsdio_download_state(dhd_bus_t *bus, b int bcmerror = 0; int foundcr4 = 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). */ @@ -4211,47 +3801,45 @@ dhdsdio_download_state(dhd_bus_t *bus, b if (si_setcore(bus->sih, ARMCR4_CORE_ID, 0)) { foundcr4 = 1; } else { - DHD_ERROR(("%s: Failed to find ARM core!\n", __FUNCTION__)); - bcmerror = BCME_ERROR; - goto fail; - } + DHD_ERROR(("%s: Failed to find ARM core!\n", __FUNCTION__)); + bcmerror = BCME_ERROR; + goto fail; + } } if (!foundcr4) { - si_core_disable(bus->sih, 0); - if (bcmsdh_regfail(bus->sdh)) { - bcmerror = BCME_SDIO_ERROR; - goto fail; - } + si_core_disable(bus->sih, 0); + if (bcmsdh_regfail(bus->sdh)) { + bcmerror = BCME_SDIO_ERROR; + goto fail; + } - if (!(si_setcore(bus->sih, SOCRAM_CORE_ID, 0))) { - DHD_ERROR(("%s: Failed to find SOCRAM core!\n", __FUNCTION__)); - bcmerror = BCME_ERROR; - goto fail; - } + if (!(si_setcore(bus->sih, SOCRAM_CORE_ID, 0))) { + DHD_ERROR(("%s: Failed to find SOCRAM core!\n", __FUNCTION__)); + bcmerror = BCME_ERROR; + goto fail; + } - si_core_reset(bus->sih, 0, 0); - if (bcmsdh_regfail(bus->sdh)) { - DHD_ERROR(("%s: Failure trying reset SOCRAM core?\n", - __FUNCTION__)); + si_core_reset(bus->sih, 0, 0); + if (bcmsdh_regfail(bus->sdh)) { + DHD_ERROR(("%s: Failure trying reset SOCRAM core?\n", __FUNCTION__)); + bcmerror = BCME_SDIO_ERROR; + 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; + if (dhdsdio_membytes(bus, TRUE, bus->ramsize - 4, (uint8*)&zeros, 4) < 0) { bcmerror = BCME_SDIO_ERROR; 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; - if (dhdsdio_membytes(bus, TRUE, bus->ramsize - 4, - (uint8*)&zeros, 4) < 0) { - bcmerror = BCME_SDIO_ERROR; - goto fail; - } - } - } else { + } + } else { /* For CR4, * Halt ARM * Remove ARM reset @@ -4265,44 +3853,44 @@ dhdsdio_download_state(dhd_bus_t *bus, b } } else { if (!si_setcore(bus->sih, ARMCR4_CORE_ID, 0)) { - if (!(si_setcore(bus->sih, SOCRAM_CORE_ID, 0))) { - DHD_ERROR(("%s: Failed to find SOCRAM core!\n", __FUNCTION__)); - bcmerror = BCME_ERROR; - goto fail; - } + if (!(si_setcore(bus->sih, SOCRAM_CORE_ID, 0))) { + DHD_ERROR(("%s: Failed to find SOCRAM core!\n", __FUNCTION__)); + bcmerror = BCME_ERROR; + goto fail; + } - if (!si_iscoreup(bus->sih)) { - DHD_ERROR(("%s: SOCRAM core is down after reset?\n", __FUNCTION__)); - bcmerror = BCME_ERROR; - goto fail; - } + if (!si_iscoreup(bus->sih)) { + DHD_ERROR(("%s: SOCRAM core is down after reset?\n", __FUNCTION__)); + bcmerror = BCME_ERROR; + goto fail; + } - if ((bcmerror = dhdsdio_write_vars(bus))) { - DHD_ERROR(("%s: could not write vars to RAM\n", __FUNCTION__)); - goto fail; - } + if ((bcmerror = dhdsdio_write_vars(bus))) { + DHD_ERROR(("%s: could not write vars to RAM\n", __FUNCTION__)); + 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); + /* 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__)); - bcmerror = BCME_ERROR; - goto fail; - } - W_SDREG(0xFFFFFFFF, &bus->regs->intstatus, retries); + 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__)); + bcmerror = BCME_ERROR; + goto fail; + } + W_SDREG(0xFFFFFFFF, &bus->regs->intstatus, retries); - if (!(si_setcore(bus->sih, ARM7S_CORE_ID, 0)) && - !(si_setcore(bus->sih, ARMCM3_CORE_ID, 0))) { - DHD_ERROR(("%s: Failed to find ARM core!\n", __FUNCTION__)); - bcmerror = BCME_ERROR; - goto fail; - } + if (!(si_setcore(bus->sih, ARM7S_CORE_ID, 0)) && + !(si_setcore(bus->sih, ARMCM3_CORE_ID, 0))) { + DHD_ERROR(("%s: Failed to find ARM core!\n", __FUNCTION__)); + bcmerror = BCME_ERROR; + goto fail; + } } else { /* cr4 has no socram, but tcm's */ /* write vars */ @@ -4419,10 +4007,6 @@ dhd_bus_iovar_op(dhd_pub_t *dhdp, const } else { DHD_INFO(("%s: noted %s update, value now %d\n", __FUNCTION__, "sd_blocksize", bus->blocksize)); - - if ((bus->sih->chip == BCM4335_CHIP_ID) || - (bus->sih->chip == BCM4339_CHIP_ID)) - dhd_overflow_war(bus); } } bus->roundup = MIN(max_roundup, bus->blocksize); @@ -4467,7 +4051,7 @@ dhd_bus_stop(struct dhd_bus *bus, bool e { osl_t *osh; uint32 local_hostintmask; - uint8 saveclk; + uint8 saveclk, dat; uint retries; int err; if (!bus->dhd) @@ -4487,40 +4071,45 @@ dhd_bus_stop(struct dhd_bus *bus, bool e bus->hostintmask = 0; bcmsdh_intr_disable(bus->sdh); } else { - BUS_WAKE(bus); + if (KSO_ENAB(bus)) { + /* Mask the interrupt */ + dat = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_INTEN, NULL); + dat &= ~(INTR_CTL_FUNC1_EN | INTR_CTL_FUNC2_EN); + bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_INTEN, dat, NULL); + } + /* 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); - - /* Disable and clear interrupts at the chip level also */ - W_SDREG(0, &bus->regs->hostintmask, retries); - local_hostintmask = bus->hostintmask; - bus->hostintmask = 0; + /* Enable clock for device interrupts */ + dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); - /* Force clocks on backplane to be sure F2 interrupt propagates */ - saveclk = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err); - if (!err) { - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - (saveclk | SBSDIO_FORCE_HT), &err); - } - if (err) { - DHD_ERROR(("%s: Failed to force clock for F2: err %d\n", - __FUNCTION__, err)); - } + /* Disable and clear interrupts at the chip level also */ + W_SDREG(0, &bus->regs->hostintmask, retries); + local_hostintmask = bus->hostintmask; + bus->hostintmask = 0; + + /* Force clocks on backplane to be sure F2 interrupt propagates */ + saveclk = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err); + if (!err) { + bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, + (saveclk | SBSDIO_FORCE_HT), &err); + } + if (err) { + DHD_ERROR(("%s: Failed to force clock for F2: err %d\n", __FUNCTION__, err)); + } - /* Turn off the bus (F2), free any pending packets */ - DHD_INTR(("%s: disable SDIO interrupts\n", __FUNCTION__)); - bcmsdh_intr_disable(bus->sdh); - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, SDIO_FUNC_ENABLE_1, NULL); + /* Turn off the bus (F2), free any pending packets */ + DHD_INTR(("%s: disable SDIO interrupts\n", __FUNCTION__)); + bcmsdh_intr_disable(bus->sdh); + bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, SDIO_FUNC_ENABLE_1, NULL); - /* Clear any pending interrupts now that F2 is disabled */ - W_SDREG(local_hostintmask, &bus->regs->intstatus, retries); + /* Clear any pending interrupts now that F2 is disabled */ + W_SDREG(local_hostintmask, &bus->regs->intstatus, retries); } /* Turn off the backplane clock (only) */ @@ -4547,8 +4136,6 @@ dhd_bus_stop(struct dhd_bus *bus, bool e bus->rxskip = FALSE; bus->tx_seq = bus->rx_seq = 0; - bus->tx_max = 4; - if (enforce_mutex) dhd_os_sdunlock(bus->dhd); } @@ -4563,8 +4150,6 @@ dhd_txglom_enable(dhd_pub_t *dhdp, bool uint32 rxglom; int32 ret; - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); - if (enable) { rxglom = 1; memset(buf, 0, sizeof(buf)); @@ -4662,11 +4247,8 @@ dhd_bus_init(dhd_pub_t *dhdp, bool enfor mesbusyctrl = watermark = bus->blocksize / 4; } #endif /* SDIO_CRC_ERROR_FIX */ - if (!((bus->sih->chip == BCM4335_CHIP_ID) || - (bus->sih->chip == BCM4339_CHIP_ID))) { - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_WATERMARK, - (uint8)watermark, &err); - } + + bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_WATERMARK, (uint8)watermark, &err); #ifdef SDIO_CRC_ERROR_FIX bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_MESBUSYCTRL, (uint8)mesbusyctrl|0x80, &err); @@ -4697,14 +4279,8 @@ dhd_bus_init(dhd_pub_t *dhdp, bool enfor bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, enable, NULL); } - if (dhdsdio_sr_cap(bus)) { + if (dhdsdio_sr_cap(bus)) dhdsdio_sr_init(bus); - /* Masking the chip active interrupt permanantly */ - bus->hostintmask &= ~I_CHIPACTIVE; - W_SDREG(bus->hostintmask, &bus->regs->hostintmask, retries); - DHD_INFO(("%s: disable I_CHIPACTIVE in hostintmask[0x%08x]\n", - __FUNCTION__, bus->hostintmask)); - } else bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err); @@ -4743,21 +4319,12 @@ dhdsdio_rxfail(dhd_bus_t *bus, bool abor } bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL, SFC_RF_TERM, &err); - if (err) { - DHD_ERROR(("%s: SBSDIO_FUNC1_FRAMECTRL cmd err\n", __FUNCTION__)); - goto fail; - } bus->f1regdata++; /* Wait until the packet has been flushed (device/FIFO stable) */ for (lastrbc = retries = 0xffff; retries > 0; retries--) { hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_RFRAMEBCHI, NULL); - lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_RFRAMEBCLO, &err); - if (err) { - DHD_ERROR(("%s: SBSDIO_FUNC1_RFAMEBCLO cmd err\n", __FUNCTION__)); - goto fail; - } - + lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_RFRAMEBCLO, NULL); bus->f1regdata += 2; if ((hi == 0) && (lo == 0)) @@ -4788,7 +4355,6 @@ dhdsdio_rxfail(dhd_bus_t *bus, bool abor /* Clear partial in any case */ bus->nextlen = 0; -fail: /* If we can't reach the device, signal failure */ if (err || bcmsdh_regfail(sdh)) bus->dhd->busstate = DHD_BUS_DOWN; @@ -4893,9 +4459,6 @@ done: /* Awake any waiters */ dhd_os_ioctl_resp_wake(bus->dhd); } -int -dhd_process_pkt_reorder_info(dhd_pub_t *dhd, uchar *reorder_info_buf, uint reorder_info_len, - void **pkt, uint32 *pkt_count); static uint8 dhdsdio_rxglom(dhd_bus_t *bus, uint8 rxseq) @@ -5266,11 +4829,14 @@ dhdsdio_rxglom(dhd_bus_t *bus, uint8 rxs temp = PKTNEXT(osh, temp); } pfirst = temp; - if (list_tail[ifidx] == NULL) + if (list_tail[ifidx] == NULL) { list_head[ifidx] = ppfirst; - else + list_tail[ifidx] = pfirst; + } + else { PKTSETNEXT(osh, list_tail[ifidx], ppfirst); - list_tail[ifidx] = pfirst; + list_tail[ifidx] = pfirst; + } } num += (uint8)free_buf_count; @@ -5383,13 +4949,14 @@ dhdsdio_readframes(dhd_bus_t *bus, uint rxseq++, rxleft--) { #ifdef DHDTHREAD - /* tx more to improve rx performance */ - if (TXCTLOK(bus) && bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL)) { - dhdsdio_sendpendctl(bus); - } else if ((bus->clkstate == CLK_AVAIL) && !bus->fcstate && - pktq_mlen(&bus->txq, ~bus->flowcontrol) && DATAOK(bus)) { - dhdsdio_sendfromq(bus, dhd_txbound); - } + /* terence: fix got unlikely tx max for 43362a0*/ + if (bus->sih->chip!=BCM43362_CHIP_ID && bus->sih->chiprev!=BCM43362A0_CHIP_REV) { + /* tx more to improve rx performance */ + if ((bus->clkstate == CLK_AVAIL) && !bus->fcstate && + pktq_mlen(&bus->txq, ~bus->flowcontrol) && DATAOK(bus)) { + dhdsdio_sendfromq(bus, dhd_txbound); + } + } #endif /* DHDTHREAD */ /* Handle glomming separately */ @@ -5912,6 +5479,7 @@ deliver: else pkt_count = 1; + /* Unlock during rx call */ dhd_os_sdunlock(bus->dhd); dhd_rx_frame(bus->dhd, ifidx, pkt, pkt_count, chan); @@ -6239,14 +5807,57 @@ clkwait: resched = TRUE; } #endif /* defined(OOB_INTR_ONLY) && !defined(HW_OOB) */ - #ifdef PROP_TXSTATUS dhd_wlfc_trigger_pktcommit(bus->dhd); #endif + if (TXCTLOK(bus) && bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL)) { + int ret, i; + + uint8* frame_seq = bus->ctrl_frame_buf + SDPCM_FRAMETAG_LEN; + + if (*frame_seq != bus->tx_seq) { + DHD_INFO(("%s IOCTL frame seq lag detected!" + " frm_seq:%d != bus->tx_seq:%d, corrected\n", + __FUNCTION__, *frame_seq, bus->tx_seq)); + *frame_seq = bus->tx_seq; + } + + ret = dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, + (uint8 *)bus->ctrl_frame_buf, (uint32)bus->ctrl_frame_len, + NULL, NULL, NULL); + ASSERT(ret != BCME_PENDING); + 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)); + bus->tx_sderrs++; + + bcmsdh_abort(sdh, SDIO_FUNC_2); - if (TXCTLOK(bus) && bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL)) - dhdsdio_sendpendctl(bus); + bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL, + SFC_WF_TERM, NULL); + bus->f1regdata++; + for (i = 0; i < 3; i++) { + uint8 hi, lo; + hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, + SBSDIO_FUNC1_WFRAMEBCHI, NULL); + lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, + SBSDIO_FUNC1_WFRAMEBCLO, NULL); + bus->f1regdata += 2; + if ((hi == 0) && (lo == 0)) + break; + } + } + if (ret == 0) { + bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; + } + + bus->ctrl_frame_stat = FALSE; + dhd_wait_event_wakeup(bus->dhd); + } /* Send queued frames (limit 1 if rx may still be pending) */ else if ((bus->clkstate == CLK_AVAIL) && !bus->fcstate && pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit && DATAOK(bus)) { @@ -6289,13 +5900,6 @@ clkwait: } exit: - - if (!resched && dhd_dpcpoll) { - if (dhdsdio_readframes(bus, dhd_rxbound, &rxdone) != 0) { - resched = TRUE; - } - } - dhd_os_sdunlock(bus->dhd); return resched; } @@ -6360,13 +5964,11 @@ dhdsdio_isr(void *arg) #if defined(SDIO_ISR_THREAD) DHD_TRACE(("Calling dhdsdio_dpc() from %s\n", __FUNCTION__)); DHD_OS_WAKE_LOCK(bus->dhd); - dhdsdio_dpc(bus); + while (dhdsdio_dpc(bus)); DHD_OS_WAKE_UNLOCK(bus->dhd); #else - bus->dpc_sched = TRUE; dhd_sched_dpc(bus->dhd); - #endif } @@ -6387,7 +5989,7 @@ dhdsdio_pktgen_init(dhd_bus_t *bus) /* Default to per-watchdog burst with 10s print time */ bus->pktgen_freq = 1; - bus->pktgen_print = dhd_watchdog_ms ? (10000 / dhd_watchdog_ms) : 0; + bus->pktgen_print = dhd_watchdog_ms ? (10000/dhd_watchdog_ms):0; bus->pktgen_count = (dhd_pktgen * dhd_watchdog_ms + 999) / 1000; /* Default to echo mode */ @@ -6772,8 +6374,9 @@ dhd_bus_watchdog(dhd_pub_t *dhdp) else { bus->idlecount++; - if ((bus->idletime > 0) && (bus->idlecount >= bus->idletime)) { + if (bus->idlecount >= bus->idletime) { DHD_TIMER(("%s: DHD Idle state!!\n", __FUNCTION__)); + if (SLPAUTO_ENAB(bus)) { if (dhdsdio_bussleep(bus, TRUE) != BCME_BUSY) dhd_os_wd_timer(bus->dhd, 0); @@ -6918,28 +6521,16 @@ dhdsdio_chipmatch(uint16 chipid) return TRUE; if (chipid == BCM4314_CHIP_ID) return TRUE; - if (chipid == BCM43242_CHIP_ID) - return TRUE; - if (chipid == BCM43340_CHIP_ID) + if (chipid == BCM4334_CHIP_ID) return TRUE; if (chipid == BCM43341_CHIP_ID) return TRUE; - if (chipid == BCM43143_CHIP_ID) - return TRUE; - if (chipid == BCM43342_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; if (chipid == BCM4335_CHIP_ID) return TRUE; - if (chipid == BCM4339_CHIP_ID) - return TRUE; - if (chipid == BCM4350_CHIP_ID) - return TRUE; return FALSE; } @@ -6953,6 +6544,16 @@ dhdsdio_probe(uint16 venid, uint16 devid struct ether_addr ea_addr; #endif /* GET_CUSTOM_MAC_ENABLE */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) + + if (mutex_is_locked(&_dhd_sdio_mutex_lock_) == 0) { + DHD_ERROR(("%s : no mutex held. set lock\n", __FUNCTION__)); + } + else { + DHD_ERROR(("%s : mutex is locked!. wait for unlocking\n", __FUNCTION__)); + } + mutex_lock(&_dhd_sdio_mutex_lock_); +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) */ /* Init global variables at run-time, not as part of the declaration. * This is required to support init/de-init of the driver. Initialization @@ -6966,8 +6567,8 @@ dhdsdio_probe(uint16 venid, uint16 devid sd1idle = TRUE; dhd_readahead = TRUE; retrydata = FALSE; - dhd_doflow = TRUE; - dhd_dongle_ramsize = 0; + dhd_doflow = FALSE; + dhd_dongle_memsize = 0; dhd_txminmax = DHD_TXMINMAX; forcealign = TRUE; @@ -7100,11 +6701,10 @@ dhdsdio_probe(uint16 venid, uint16 devid #endif /* GET_CUSTOM_MAC_ENABLE */ /* if firmware path present try to download and bring up bus */ - bus->dhd->hang_report = TRUE; if (dhd_download_fw_on_driverload) { if ((ret = dhd_bus_start(bus->dhd)) != 0) { DHD_ERROR(("%s: dhd_bus_start failed\n", __FUNCTION__)); - goto fail; + goto fail; } } /* Ok, have the per-port tell the stack we're open for business */ @@ -7113,7 +6713,10 @@ dhdsdio_probe(uint16 venid, uint16 devid goto fail; } - +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) + mutex_unlock(&_dhd_sdio_mutex_lock_); + DHD_ERROR(("%s : the lock is released.\n", __FUNCTION__)); +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ return bus; @@ -7121,6 +6724,10 @@ fail: dhdsdio_release(bus, osh); forcereturn: +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) + mutex_unlock(&_dhd_sdio_mutex_lock_); + DHD_ERROR(("%s : the lock is released.\n", __FUNCTION__)); +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ return NULL; } @@ -7140,6 +6747,12 @@ dhdsdio_probe_attach(struct dhd_bus *bus DHD_ERROR(("%s: FAILED to return to SI_ENUM_BASE\n", __FUNCTION__)); } +#ifdef DHD_DEBUG + DHD_ERROR(("F1 signature read @0x18000000=0x%4x\n", + bcmsdh_reg_read(bus->sdh, SI_ENUM_BASE, 4))); + +#endif /* DHD_DEBUG */ + /* Force PLL off until si_attach() programs PLL control regs */ @@ -7208,14 +6821,6 @@ dhdsdio_probe_attach(struct dhd_bus *bus goto fail; } - -#ifdef DHD_DEBUG - DHD_ERROR(("F1 signature OK, socitype:0x%x chip:0x%4x rev:0x%x pkg:0x%x\n", - bus->sih->socitype, bus->sih->chip, bus->sih->chiprev, - bus->sih->chippkg)); -#endif /* DHD_DEBUG */ - - bcmsdh_chipinfo(sdh, bus->sih->chip, bus->sih->chiprev); if (!dhdsdio_chipmatch((uint16)bus->sih->chip)) { @@ -7247,10 +6852,10 @@ dhdsdio_probe_attach(struct dhd_bus *bus } if (!si_setcore(bus->sih, ARMCR4_CORE_ID, 0)) { - if (!(bus->orig_ramsize = si_socram_size(bus->sih))) { - DHD_ERROR(("%s: failed to find SOCRAM memory!\n", __FUNCTION__)); - goto fail; - } + if (!(bus->orig_ramsize = si_socram_size(bus->sih))) { + DHD_ERROR(("%s: failed to find SOCRAM memory!\n", __FUNCTION__)); + goto fail; + } } else { /* cr4 has a different way to find the RAM size from TCM's */ if (!(bus->orig_ramsize = si_tcm_size(bus->sih))) { @@ -7258,29 +6863,14 @@ dhdsdio_probe_attach(struct dhd_bus *bus goto fail; } /* also populate base address */ - switch ((uint16)bus->sih->chip) { - case BCM4335_CHIP_ID: - case BCM4339_CHIP_ID: - bus->dongle_ram_base = CR4_4335_RAM_BASE; - break; - case BCM4350_CHIP_ID: - bus->dongle_ram_base = CR4_4350_RAM_BASE; - break; - case BCM4360_CHIP_ID: - bus->dongle_ram_base = CR4_4360_RAM_BASE; - break; - default: - bus->dongle_ram_base = 0; - DHD_ERROR(("%s: WARNING: Using default ram base at 0x%x\n", - __FUNCTION__, bus->dongle_ram_base)); - } + bus->dongle_ram_base = CR4_RAM_BASE; } bus->ramsize = bus->orig_ramsize; - if (dhd_dongle_ramsize) - dhd_dongle_setramsize(bus, dhd_dongle_ramsize); + if (dhd_dongle_memsize) + dhd_dongle_setmemsize(bus, dhd_dongle_memsize); - DHD_ERROR(("DHD: dongle ram size is set to %d(orig %d) at 0x%x\n", - bus->ramsize, bus->orig_ramsize, bus->dongle_ram_base)); + DHD_ERROR(("DHD: dongle ram size is set to %d(orig %d)\n", + bus->ramsize, bus->orig_ramsize)); bus->srmemsize = si_socram_srmem_size(bus->sih); } @@ -7321,7 +6911,7 @@ dhdsdio_probe_attach(struct dhd_bus *bus #ifdef BCMSDIOH_TXGLOM /* Setting default Glom mode */ - bus->glom_mode = bcmsdh_set_mode(bus->sdh, SDPCM_DEFGLOM_MODE); + bus->glom_mode = SDPCM_TXGLOM_CPY; /* Setting default Glom size */ bus->glomsize = SDPCM_DEFGLOM_SIZE; #endif @@ -7427,10 +7017,6 @@ dhdsdio_probe_init(dhd_bus_t *bus, osl_t } else { DHD_INFO(("%s: Initial value for %s is %d\n", __FUNCTION__, "sd_blocksize", bus->blocksize)); - - if ((bus->sih->chip == BCM4335_CHIP_ID) || - (bus->sih->chip == BCM4339_CHIP_ID)) - dhd_overflow_war(bus); } bus->roundup = MIN(max_roundup, bus->blocksize); @@ -7447,6 +7033,81 @@ dhdsdio_probe_init(dhd_bus_t *bus, osl_t return TRUE; } +void +dhd_bus_select_firmware_name_by_chip(struct dhd_bus *bus, char *dst, char *src) +{ + int fw_type, ag_type; + static uint chip, chiprev, first=1; + int i; + + if (first) { + chip = bus->sih->chip; + chiprev = bus->sih->chiprev; + first = 0; + } + if (src[0] == '\0') { +#ifdef CONFIG_BCMDHD_FW_PATH + bcm_strncpy_s(src, sizeof(fw_path), CONFIG_BCMDHD_FW_PATH, MOD_PARAM_PATHLEN-1); + if (src[0] == '\0') +#endif + { + printf("src firmware path is null\n"); + return; + } + } + + strcpy(dst, src); +#ifndef FW_PATH_AUTO_SELECT + return; +#endif + + /* find out the last '/' */ + i = strlen(dst); + while (i>0){ + if (dst[i] == '/') break; + i--; + } +#ifdef BAND_AG + ag_type = FW_TYPE_AG; +#else + ag_type = strstr(&dst[i], "_ag") ? FW_TYPE_AG : FW_TYPE_G; +#endif + fw_type = (strstr(&dst[i], "_mfg") ? + FW_TYPE_MFG : (strstr(&dst[i], "_apsta") ? + FW_TYPE_APSTA : (strstr(&dst[i], "_p2p") ? + FW_TYPE_P2P : FW_TYPE_STA))); + + + switch (chip) { + case BCM4330_CHIP_ID: + if (ag_type == FW_TYPE_G) { + if (chiprev == BCM4330B2_CHIP_REV) + strcpy(&dst[i+1], bcm40183b2_fw_name[fw_type]); + break; + } else { + if (chiprev == BCM4330B2_CHIP_REV) + strcpy(&dst[i+1], bcm40183b2ag_fw_name[fw_type]); + break; + } + case BCM43362_CHIP_ID: + if (chiprev == BCM43362A0_CHIP_REV) + strcpy(&dst[i+1], bcm40181a0_fw_name[fw_type]); + else + strcpy(&dst[i+1], bcm40181a2_fw_name[fw_type]); + break; + case BCM43341_CHIP_ID: + if (chiprev == BCM43341B0_CHIP_REV) + strcpy(&dst[i+1], bcm43341b0ag_fw_name[fw_type]); + break; + case BCM4324_CHIP_ID: + if (chiprev == BCM43241B4_CHIP_REV) + strcpy(&dst[i+1], bcm43241b4ag_fw_name[fw_type]); + break; + } + + printf("%s: firmware_path=%s\n", __FUNCTION__, dst); +} + bool dhd_bus_download_firmware(struct dhd_bus *bus, osl_t *osh, char *pfw_path, char *pnv_path) @@ -7471,6 +7132,8 @@ dhdsdio_download_firmware(struct dhd_bus /* Download the firmware */ dhdsdio_clkctl(bus, CLK_AVAIL, FALSE); + printk("Final fw_path=%s\n", bus->fw_path); + printk("Final nv_path=%s\n", bus->nv_path); ret = _dhdsdio_download_firmware(bus) == 0; dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); @@ -7586,16 +7249,28 @@ dhdsdio_disconnect(void *ptr) { dhd_bus_t *bus = (dhd_bus_t *)ptr; - DHD_TRACE(("%s: Enter\n", __FUNCTION__)); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) + if (mutex_is_locked(&_dhd_sdio_mutex_lock_) == 0) { + DHD_ERROR(("%s : no mutex held. set lock\n", __FUNCTION__)); + } + else { + DHD_ERROR(("%s : mutex is locked!. wait for unlocking\n", __FUNCTION__)); + } + mutex_lock(&_dhd_sdio_mutex_lock_); +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) */ + DHD_TRACE(("%s: Enter\n", __FUNCTION__)); if (bus) { ASSERT(bus->dhd); dhdsdio_release(bus, bus->dhd->osh); } - +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) + mutex_unlock(&_dhd_sdio_mutex_lock_); + DHD_ERROR(("%s : the lock is released.\n", __FUNCTION__)); +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) */ DHD_TRACE(("%s: Disconnected\n", __FUNCTION__)); } @@ -7652,17 +7327,6 @@ dhdsdio_download_code_array(struct dhd_b /* Download image */ while ((offset + MEMBLOCK) < sizeof(dlarray)) { - /* check if CR4 */ - if (si_setcore(bus->sih, ARMCR4_CORE_ID, 0)) { - /* if address is 0, store the reset instruction to be written in 0 */ - - if (offset == 0) { - bus->resetinstr = *(((uint32*)dlarray)); - /* Add start of RAM address to the address given by user */ - offset += bus->dongle_ram_base; - } - } - bcmerror = dhdsdio_membytes(bus, TRUE, offset, (uint8 *) (dlarray + offset), MEMBLOCK); if (bcmerror) { @@ -7738,6 +7402,7 @@ dhdsdio_download_code_file(struct dhd_bu int len; void *image = NULL; uint8 *memblock = NULL, *memptr; + uint8 *memptr_tmp = NULL; // terence: check downloaded firmware is correct DHD_INFO(("%s: download firmware %s\n", __FUNCTION__, pfw_path)); @@ -7750,6 +7415,13 @@ dhdsdio_download_code_file(struct dhd_bu DHD_ERROR(("%s: Failed to allocate memory %d bytes\n", __FUNCTION__, MEMBLOCK)); goto err; } + if (dhd_msg_level & DHD_TRACE_VAL) { + memptr_tmp = MALLOC(bus->dhd->osh, MEMBLOCK + DHD_SDALIGN); + if (memptr_tmp == NULL) { + DHD_ERROR(("%s: Failed to allocate memory %d bytes\n", __FUNCTION__, MEMBLOCK)); + goto err; + } + } if ((uint32)(uintptr)memblock % DHD_SDALIGN) memptr += (DHD_SDALIGN - ((uint32)(uintptr)memblock % DHD_SDALIGN)); @@ -7760,17 +7432,6 @@ dhdsdio_download_code_file(struct dhd_bu bcmerror = BCME_ERROR; goto err; } - /* check if CR4 */ - if (si_setcore(bus->sih, ARMCR4_CORE_ID, 0)) { - /* if address is 0, store the reset instruction to be written in 0 */ - - if (offset == 0) { - bus->resetinstr = *(((uint32*)memptr)); - /* Add start of RAM address to the address given by user */ - offset += bus->dongle_ram_base; - } - } - bcmerror = dhdsdio_membytes(bus, TRUE, offset, memptr, len); if (bcmerror) { DHD_ERROR(("%s: error %d on writing %d membytes at 0x%08x\n", @@ -7778,12 +7439,29 @@ dhdsdio_download_code_file(struct dhd_bu goto err; } + if (dhd_msg_level & DHD_TRACE_VAL) { + bcmerror = dhdsdio_membytes(bus, FALSE, offset, memptr_tmp, len); + if (bcmerror) { + DHD_ERROR(("%s: error %d on reading %d membytes at 0x%08x\n", + __FUNCTION__, bcmerror, MEMBLOCK, offset)); + goto err; + } + if (memcmp(memptr_tmp, memptr, len)) { + DHD_ERROR(("%s: Downloaded image is corrupted.\n", __FUNCTION__)); + goto err; + } else + DHD_INFO(("%s: Download, Upload and compare succeeded.\n", __FUNCTION__)); + } offset += MEMBLOCK; } err: if (memblock) MFREE(bus->dhd->osh, memblock, MEMBLOCK + DHD_SDALIGN); + if (dhd_msg_level & DHD_TRACE_VAL) { + if (memptr_tmp) + MFREE(bus->dhd->osh, memptr_tmp, MEMBLOCK + DHD_SDALIGN); + } if (image) dhd_os_close_image(image); @@ -7920,7 +7598,6 @@ _dhdsdio_download_firmware(struct dhd_bu dlok = TRUE; } } - #ifdef BCMEMBEDIMAGE if (embed) { if (dhdsdio_download_code_array(bus)) { @@ -7991,9 +7668,9 @@ dhd_bcmsdh_send_buf(dhd_bus_t *bus, uint #ifdef BCMSDIOH_TXGLOM static void -dhd_bcmsdh_glom_post(dhd_bus_t *bus, uint8 *frame, void *pkt, uint len) +dhd_bcmsdh_glom_post(dhd_bus_t *bus, uint8 *frame, uint len) { - bcmsdh_glom_post(bus->sdh, frame, pkt, len); + bcmsdh_glom_post(bus->sdh, frame, len); } static void @@ -8063,14 +7740,14 @@ dhd_bus_devreset(dhd_pub_t *dhdp, uint8 #endif dhd_os_sdunlock(dhdp); - DHD_TRACE(("%s: WLAN OFF DONE\n", __FUNCTION__)); + DHD_ERROR(("%s: WLAN OFF DONE\n", __FUNCTION__)); /* App can now remove power from device */ } else bcmerror = BCME_SDIO_ERROR; } else { /* App must have restored power to device before calling */ - DHD_TRACE(("\n\n%s: == WLAN ON ==\n", __FUNCTION__)); + DHD_ERROR(("\n\n%s: == WLAN ON ==\n", __FUNCTION__)); if (bus->dhd->dongle_reset) { /* Turn on WLAN */ @@ -8085,6 +7762,7 @@ dhd_bus_devreset(dhd_pub_t *dhdp, uint8 (uint32 *)SI_ENUM_BASE, bus->cl_devid)) { /* Attempt to download binary to the dongle */ + COPY_FW_PATH_BY_CHIP(bus, fw_path, firmware_path); // terence if (dhdsdio_probe_init(bus, bus->dhd->osh, bus->sdh) && dhdsdio_download_firmware(bus, bus->dhd->osh, bus->sdh)) { @@ -8092,13 +7770,6 @@ dhd_bus_devreset(dhd_pub_t *dhdp, uint8 bcmerror = dhd_bus_init((dhd_pub_t *) bus->dhd, FALSE); if (bcmerror == BCME_OK) { #if defined(OOB_INTR_ONLY) - /* make sure oob intr get registered */ - if (!bcmsdh_is_oob_intr_registered()) { - sdioh_start(NULL, 1); - bcmsdh_register_oob_intr(dhdp); - dhdp->iswl = TRUE; - } - bcmsdh_set_irq(TRUE); dhd_enable_oob_intr(bus, TRUE); #endif @@ -8111,7 +7782,13 @@ dhd_bus_devreset(dhd_pub_t *dhdp, uint8 dhd_txflowcontrol(bus->dhd, ALL_INTERFACES, OFF); #endif dhd_os_wd_timer(dhdp, dhd_watchdog_ms); - DHD_TRACE(("%s: WLAN ON DONE\n", __FUNCTION__)); +#ifdef BCMSDIOH_TXGLOM + if ((dhdp->busstate == DHD_BUS_DATA) && + bcmsdh_glom_enabled()) { + dhd_txglom_enable(dhdp, TRUE); + } +#endif /* BCMSDIOH_TXGLOM */ + DHD_ERROR(("%s: WLAN ON DONE\n", __FUNCTION__)); } else { dhd_bus_stop(bus, FALSE); dhdsdio_release_dongle(bus, bus->dhd->osh, @@ -8123,14 +7800,18 @@ dhd_bus_devreset(dhd_pub_t *dhdp, uint8 bcmerror = BCME_SDIO_ERROR; #ifdef DHDTHREAD - dhd_os_sdunlock(dhdp); + dhd_os_sdunlock(dhdp); #endif /* DHDTHREAD */ } else { bcmerror = BCME_SDIO_ERROR; - DHD_INFO(("%s called when dongle is not in reset\n", + DHD_ERROR(("%s called when dongle is not in reset\n", __FUNCTION__)); - DHD_INFO(("Will call dhd_bus_start instead\n")); + DHD_ERROR(("Will call dhd_bus_start instead\n")); sdioh_start(NULL, 1); +#if defined(HW_OOB) + bcmsdh_config_hw_oob_intr(bus->sdh, bus->sih->chip); // terence 20120615: fix for OOB initial issue +#endif + COPY_FW_PATH_BY_CHIP(bus, fw_path, firmware_path); if ((bcmerror = dhd_bus_start(dhdp)) != 0) DHD_ERROR(("%s: dhd_bus_start fail with %d\n", __FUNCTION__, bcmerror)); @@ -8171,68 +7852,3 @@ dhd_bus_membytes(dhd_pub_t *dhdp, bool s bus = dhdp->bus; return dhdsdio_membytes(bus, set, address, data, size); } - -int -dhd_enableOOB(dhd_pub_t *dhd, bool sleep) -{ - dhd_bus_t *bus = dhd->bus; - sdpcmd_regs_t *regs = bus->regs; - uint retries = 0; - - if (sleep) { - 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")); - return BCME_BUSY; - } - /* Turn off our contribution to the HT clock request */ - dhdsdio_clkctl(bus, CLK_SDONLY, FALSE); - } else { - /* 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); - - 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); - } - return BCME_OK; -} - -void -dhd_bus_pktq_flush(dhd_pub_t *dhdp) -{ - dhd_bus_t *bus = dhdp->bus; - /* Clear the data packet queues */ - pktq_flush(dhdp->osh, &bus->txq, TRUE, NULL, 0); -} - -int -dhd_sr_config(dhd_pub_t *dhd, bool on) -{ - dhd_bus_t *bus = dhd->bus; - - if (!bus->_srenab) - return -1; - - return dhdsdio_clk_devsleep_iovar(bus, on); -} - -uint16 -dhd_get_chipid(dhd_pub_t *dhd) -{ - dhd_bus_t *bus = dhd->bus; - - if (bus && bus->sih) - return (uint16)bus->sih->chip; - else - return 0; -} diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/dhd_wlfc.c linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_wlfc.c --- linux-sunxi/drivers/net/wireless/bcmdhd/dhd_wlfc.c 2014-01-27 01:30:30.108433411 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_wlfc.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,2441 +0,0 @@ -/* - * DHD PROP_TXSTATUS Module. - * - * Copyright (C) 1999-2013, 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: dhd_wlfc.c 412994 2013-07-17 12:38:03Z $ - * - */ - -#include -#include - -#include -#include - -#include -#include - -#include -#include - -#ifdef PROP_TXSTATUS -#include -#include -#endif - - - - -#define BUS_RETRIES 1 /* # of retries before aborting a bus tx operation */ - -#ifdef PROP_TXSTATUS -typedef struct dhd_wlfc_commit_info { - uint8 needs_hdr; - uint8 ac_fifo_credit_spent; - ewlfc_packet_state_t pkt_type; - wlfc_mac_descriptor_t* mac_entry; - void* p; -} dhd_wlfc_commit_info_t; -#endif /* PROP_TXSTATUS */ - - -#ifdef PROP_TXSTATUS - -#define DHD_WLFC_QMON_COMPLETE(entry) - -void -dhd_wlfc_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf) -{ - int i; - uint8* ea; - athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) - dhdp->wlfc_state; - wlfc_hanger_t* h; - wlfc_mac_descriptor_t* mac_table; - wlfc_mac_descriptor_t* interfaces; - char* iftypes[] = {"STA", "AP", "WDS", "p2pGO", "p2pCL"}; - - if (wlfc == NULL) { - bcm_bprintf(strbuf, "wlfc not initialized yet\n"); - return; - } - h = (wlfc_hanger_t*)wlfc->hanger; - if (h == NULL) { - bcm_bprintf(strbuf, "wlfc-hanger not initialized yet\n"); - } - - mac_table = wlfc->destination_entries.nodes; - interfaces = wlfc->destination_entries.interfaces; - bcm_bprintf(strbuf, "---- wlfc stats ----\n"); - if (h) { - bcm_bprintf(strbuf, "wlfc hanger (pushed,popped,f_push," - "f_pop,f_slot, pending) = (%d,%d,%d,%d,%d,%d)\n", - h->pushed, - h->popped, - h->failed_to_push, - h->failed_to_pop, - h->failed_slotfind, - (h->pushed - h->popped)); - } - - bcm_bprintf(strbuf, "wlfc fail(tlv,credit_rqst,mac_update,psmode_update), " - "(dq_full,rollback_fail) = (%d,%d,%d,%d), (%d,%d)\n", - wlfc->stats.tlv_parse_failed, - wlfc->stats.credit_request_failed, - wlfc->stats.mac_update_failed, - wlfc->stats.psmode_update_failed, - wlfc->stats.delayq_full_error, - wlfc->stats.rollback_failed); - - bcm_bprintf(strbuf, "PKTS (credit,sent) " - "(AC0[%d,%d],AC1[%d,%d],AC2[%d,%d],AC3[%d,%d],BC_MC[%d,%d])\n", - wlfc->FIFO_credit[0], wlfc->stats.send_pkts[0], - wlfc->FIFO_credit[1], wlfc->stats.send_pkts[1], - wlfc->FIFO_credit[2], wlfc->stats.send_pkts[2], - wlfc->FIFO_credit[3], wlfc->stats.send_pkts[3], - wlfc->FIFO_credit[4], wlfc->stats.send_pkts[4]); - - bcm_bprintf(strbuf, "\n"); - for (i = 0; i < WLFC_MAX_IFNUM; i++) { - if (interfaces[i].occupied) { - char* iftype_desc; - - if (interfaces[i].iftype > WLC_E_IF_ROLE_P2P_CLIENT) - iftype_desc = "hostif_flow_state[i] == OFF) - ? " OFF":" ON")); - - bcm_bprintf(strbuf, "INTERFACE[%d].DELAYQ(len,state,credit)" - "= (%d,%s,%d)\n", - i, - interfaces[i].psq.len, - ((interfaces[i].state == - WLFC_STATE_OPEN) ? " OPEN":"CLOSE"), - interfaces[i].requested_credit); - - bcm_bprintf(strbuf, "INTERFACE[%d].DELAYQ" - "(sup,ac0),(sup,ac1),(sup,ac2),(sup,ac3) = " - "(%d,%d),(%d,%d),(%d,%d),(%d,%d)\n", - i, - interfaces[i].psq.q[0].len, - interfaces[i].psq.q[1].len, - interfaces[i].psq.q[2].len, - interfaces[i].psq.q[3].len, - interfaces[i].psq.q[4].len, - interfaces[i].psq.q[5].len, - interfaces[i].psq.q[6].len, - interfaces[i].psq.q[7].len); - } - } - - bcm_bprintf(strbuf, "\n"); - for (i = 0; i < WLFC_MAC_DESC_TABLE_SIZE; i++) { - if (mac_table[i].occupied) { - ea = mac_table[i].ea; - bcm_bprintf(strbuf, "MAC_table[%d].ea = " - "[%02x:%02x:%02x:%02x:%02x:%02x], if:%d \n", i, - ea[0], ea[1], ea[2], ea[3], ea[4], ea[5], - mac_table[i].interface_id); - - bcm_bprintf(strbuf, "MAC_table[%d].DELAYQ(len,state,credit)" - "= (%d,%s,%d)\n", - i, - mac_table[i].psq.len, - ((mac_table[i].state == - WLFC_STATE_OPEN) ? " OPEN":"CLOSE"), - mac_table[i].requested_credit); -#ifdef PROP_TXSTATUS_DEBUG - bcm_bprintf(strbuf, "MAC_table[%d]: (opened, closed) = (%d, %d)\n", - i, mac_table[i].opened_ct, mac_table[i].closed_ct); -#endif - bcm_bprintf(strbuf, "MAC_table[%d].DELAYQ" - "(sup,ac0),(sup,ac1),(sup,ac2),(sup,ac3) = " - "(%d,%d),(%d,%d),(%d,%d),(%d,%d)\n", - i, - mac_table[i].psq.q[0].len, - mac_table[i].psq.q[1].len, - mac_table[i].psq.q[2].len, - mac_table[i].psq.q[3].len, - mac_table[i].psq.q[4].len, - mac_table[i].psq.q[5].len, - mac_table[i].psq.q[6].len, - mac_table[i].psq.q[7].len); - } - } - -#ifdef PROP_TXSTATUS_DEBUG - { - int avg; - int moving_avg = 0; - int moving_samples; - - if (wlfc->stats.latency_sample_count) { - moving_samples = sizeof(wlfc->stats.deltas)/sizeof(uint32); - - for (i = 0; i < moving_samples; i++) - moving_avg += wlfc->stats.deltas[i]; - moving_avg /= moving_samples; - - avg = (100 * wlfc->stats.total_status_latency) / - wlfc->stats.latency_sample_count; - bcm_bprintf(strbuf, "txstatus latency (average, last, moving[%d]) = " - "(%d.%d, %03d, %03d)\n", - moving_samples, avg/100, (avg - (avg/100)*100), - wlfc->stats.latency_most_recent, - moving_avg); - } - } - - bcm_bprintf(strbuf, "wlfc- fifo[0-5] credit stats: sent = (%d,%d,%d,%d,%d,%d), " - "back = (%d,%d,%d,%d,%d,%d)\n", - wlfc->stats.fifo_credits_sent[0], - wlfc->stats.fifo_credits_sent[1], - wlfc->stats.fifo_credits_sent[2], - wlfc->stats.fifo_credits_sent[3], - wlfc->stats.fifo_credits_sent[4], - wlfc->stats.fifo_credits_sent[5], - - wlfc->stats.fifo_credits_back[0], - wlfc->stats.fifo_credits_back[1], - wlfc->stats.fifo_credits_back[2], - wlfc->stats.fifo_credits_back[3], - wlfc->stats.fifo_credits_back[4], - wlfc->stats.fifo_credits_back[5]); - { - uint32 fifo_cr_sent = 0; - uint32 fifo_cr_acked = 0; - uint32 request_cr_sent = 0; - uint32 request_cr_ack = 0; - uint32 bc_mc_cr_ack = 0; - - for (i = 0; i < sizeof(wlfc->stats.fifo_credits_sent)/sizeof(uint32); i++) { - fifo_cr_sent += wlfc->stats.fifo_credits_sent[i]; - } - - for (i = 0; i < sizeof(wlfc->stats.fifo_credits_back)/sizeof(uint32); i++) { - fifo_cr_acked += wlfc->stats.fifo_credits_back[i]; - } - - for (i = 0; i < WLFC_MAC_DESC_TABLE_SIZE; i++) { - if (wlfc->destination_entries.nodes[i].occupied) { - request_cr_sent += - wlfc->destination_entries.nodes[i].dstncredit_sent_packets; - } - } - for (i = 0; i < WLFC_MAX_IFNUM; i++) { - if (wlfc->destination_entries.interfaces[i].occupied) { - request_cr_sent += - wlfc->destination_entries.interfaces[i].dstncredit_sent_packets; - } - } - for (i = 0; i < WLFC_MAC_DESC_TABLE_SIZE; i++) { - if (wlfc->destination_entries.nodes[i].occupied) { - request_cr_ack += - wlfc->destination_entries.nodes[i].dstncredit_acks; - } - } - for (i = 0; i < WLFC_MAX_IFNUM; i++) { - if (wlfc->destination_entries.interfaces[i].occupied) { - request_cr_ack += - wlfc->destination_entries.interfaces[i].dstncredit_acks; - } - } - bcm_bprintf(strbuf, "wlfc- (sent, status) => pq(%d,%d), vq(%d,%d)," - "other:%d, bc_mc:%d, signal-only, (sent,freed): (%d,%d)", - fifo_cr_sent, fifo_cr_acked, - request_cr_sent, request_cr_ack, - wlfc->destination_entries.other.dstncredit_acks, - bc_mc_cr_ack, - wlfc->stats.signal_only_pkts_sent, wlfc->stats.signal_only_pkts_freed); - } -#endif /* PROP_TXSTATUS_DEBUG */ - bcm_bprintf(strbuf, "\n"); - bcm_bprintf(strbuf, "wlfc- pkt((in,2bus,txstats,hdrpull),(dropped,hdr_only,wlc_tossed)" - "(freed,free_err,rollback)) = " - "((%d,%d,%d,%d),(%d,%d,%d),(%d,%d,%d))\n", - wlfc->stats.pktin, - wlfc->stats.pkt2bus, - wlfc->stats.txstatus_in, - wlfc->stats.dhd_hdrpulls, - - wlfc->stats.pktdropped, - wlfc->stats.wlfc_header_only_pkt, - wlfc->stats.wlc_tossed_pkts, - - wlfc->stats.pkt_freed, - wlfc->stats.pkt_free_err, wlfc->stats.rollback); - - bcm_bprintf(strbuf, "wlfc- suppress((d11,wlc,err),enq(d11,wl,hq,mac?),retx(d11,wlc,hq)) = " - "((%d,%d,%d),(%d,%d,%d,%d),(%d,%d,%d))\n", - - wlfc->stats.d11_suppress, - wlfc->stats.wl_suppress, - wlfc->stats.bad_suppress, - - wlfc->stats.psq_d11sup_enq, - wlfc->stats.psq_wlsup_enq, - wlfc->stats.psq_hostq_enq, - wlfc->stats.mac_handle_notfound, - - wlfc->stats.psq_d11sup_retx, - wlfc->stats.psq_wlsup_retx, - wlfc->stats.psq_hostq_retx); - bcm_bprintf(strbuf, "wlfc- generic error: %d", wlfc->stats.generic_error); - - return; -} - -/* Create a place to store all packet pointers submitted to the firmware until - a status comes back, suppress or otherwise. - - hang-er: noun, a contrivance on which things are hung, as a hook. -*/ -static void* -dhd_wlfc_hanger_create(osl_t *osh, int max_items) -{ - int i; - wlfc_hanger_t* hanger; - - /* allow only up to a specific size for now */ - ASSERT(max_items == WLFC_HANGER_MAXITEMS); - - if ((hanger = (wlfc_hanger_t*)MALLOC(osh, WLFC_HANGER_SIZE(max_items))) == NULL) - return NULL; - - memset(hanger, 0, WLFC_HANGER_SIZE(max_items)); - hanger->max_items = max_items; - - for (i = 0; i < hanger->max_items; i++) { - hanger->items[i].state = WLFC_HANGER_ITEM_STATE_FREE; - } - return hanger; -} - -static int -dhd_wlfc_hanger_delete(osl_t *osh, void* hanger) -{ - wlfc_hanger_t* h = (wlfc_hanger_t*)hanger; - - if (h) { - MFREE(osh, h, WLFC_HANGER_SIZE(h->max_items)); - return BCME_OK; - } - return BCME_BADARG; -} - -static uint16 -dhd_wlfc_hanger_get_free_slot(void* hanger) -{ - uint32 i; - wlfc_hanger_t* h = (wlfc_hanger_t*)hanger; - - if (h) { - i = h->slot_pos + 1; - if (i == h->max_items) { - i = 0; - } - while (i != h->slot_pos) { - if (h->items[i].state == WLFC_HANGER_ITEM_STATE_FREE) { - h->slot_pos = i; - return (uint16)i; - } - i++; - if (i == h->max_items) - i = 0; - } - h->failed_slotfind++; - } - return WLFC_HANGER_MAXITEMS; -} - -static int -dhd_wlfc_hanger_get_genbit(void* hanger, void* pkt, uint32 slot_id, int* gen) -{ - int rc = BCME_OK; - wlfc_hanger_t* h = (wlfc_hanger_t*)hanger; - - *gen = 0xff; - - /* this packet was not pushed at the time it went to the firmware */ - if (slot_id == WLFC_HANGER_MAXITEMS) - return BCME_NOTFOUND; - - if (h) { - if ((h->items[slot_id].state == WLFC_HANGER_ITEM_STATE_INUSE) || - (h->items[slot_id].state == WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED)) { - *gen = h->items[slot_id].gen; - } - else { - rc = BCME_NOTFOUND; - } - } - else - rc = BCME_BADARG; - return rc; -} - -static int -dhd_wlfc_hanger_pushpkt(void* hanger, void* pkt, uint32 slot_id) -{ - int rc = BCME_OK; - wlfc_hanger_t* h = (wlfc_hanger_t*)hanger; - - if (h && (slot_id < WLFC_HANGER_MAXITEMS)) { - if (h->items[slot_id].state == WLFC_HANGER_ITEM_STATE_FREE) { - h->items[slot_id].state = WLFC_HANGER_ITEM_STATE_INUSE; - h->items[slot_id].pkt = pkt; - h->items[slot_id].identifier = slot_id; - h->pushed++; - } - else { - h->failed_to_push++; - rc = BCME_NOTFOUND; - } - } - else - rc = BCME_BADARG; - return rc; -} - -static int -dhd_wlfc_hanger_poppkt(void* hanger, uint32 slot_id, void** pktout, int remove_from_hanger) -{ - int rc = BCME_OK; - wlfc_hanger_t* h = (wlfc_hanger_t*)hanger; - - /* this packet was not pushed at the time it went to the firmware */ - if (slot_id == WLFC_HANGER_MAXITEMS) - return BCME_NOTFOUND; - - if (h) { - if (h->items[slot_id].state != WLFC_HANGER_ITEM_STATE_FREE) { - *pktout = h->items[slot_id].pkt; - if (remove_from_hanger) { - h->items[slot_id].state = - WLFC_HANGER_ITEM_STATE_FREE; - h->items[slot_id].pkt = NULL; - h->items[slot_id].identifier = 0; - h->items[slot_id].gen = 0xff; - h->popped++; - } - } - else { - h->failed_to_pop++; - rc = BCME_NOTFOUND; - } - } - else - rc = BCME_BADARG; - return rc; -} - -static int -dhd_wlfc_hanger_mark_suppressed(void* hanger, uint32 slot_id, uint8 gen) -{ - int rc = BCME_OK; - wlfc_hanger_t* h = (wlfc_hanger_t*)hanger; - - /* this packet was not pushed at the time it went to the firmware */ - if (slot_id == WLFC_HANGER_MAXITEMS) - return BCME_NOTFOUND; - if (h) { - h->items[slot_id].gen = gen; - if (h->items[slot_id].state == WLFC_HANGER_ITEM_STATE_INUSE) { - h->items[slot_id].state = WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED; - } - else - rc = BCME_BADARG; - } - else - rc = BCME_BADARG; - - return rc; -} - -static int -_dhd_wlfc_pushheader(athost_wl_status_info_t* ctx, void* p, bool tim_signal, - uint8 tim_bmp, uint8 mac_handle, uint32 htodtag) -{ - uint32 wl_pktinfo = 0; - uint8* wlh; - uint8 dataOffset; - uint8 fillers; - uint8 tim_signal_len = 0; - - struct bdc_header *h; - - if (tim_signal) { - tim_signal_len = 1 + 1 + WLFC_CTL_VALUE_LEN_PENDING_TRAFFIC_BMP; - } - - /* +2 is for Type[1] and Len[1] in TLV, plus TIM signal */ - dataOffset = WLFC_CTL_VALUE_LEN_PKTTAG + 2 + tim_signal_len; - fillers = ROUNDUP(dataOffset, 4) - dataOffset; - dataOffset += fillers; - - PKTPUSH(ctx->osh, p, dataOffset); - wlh = (uint8*) PKTDATA(ctx->osh, p); - - wl_pktinfo = htol32(htodtag); - - wlh[0] = WLFC_CTL_TYPE_PKTTAG; - wlh[1] = WLFC_CTL_VALUE_LEN_PKTTAG; - memcpy(&wlh[2], &wl_pktinfo, sizeof(uint32)); - - if (tim_signal_len) { - wlh[dataOffset - fillers - tim_signal_len ] = - WLFC_CTL_TYPE_PENDING_TRAFFIC_BMP; - wlh[dataOffset - fillers - tim_signal_len + 1] = - WLFC_CTL_VALUE_LEN_PENDING_TRAFFIC_BMP; - wlh[dataOffset - fillers - tim_signal_len + 2] = mac_handle; - wlh[dataOffset - fillers - tim_signal_len + 3] = tim_bmp; - } - if (fillers) - memset(&wlh[dataOffset - fillers], WLFC_CTL_TYPE_FILLER, fillers); - - PKTPUSH(ctx->osh, p, BDC_HEADER_LEN); - h = (struct bdc_header *)PKTDATA(ctx->osh, p); - h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT); - if (PKTSUMNEEDED(p)) - h->flags |= BDC_FLAG_SUM_NEEDED; - - - h->priority = (PKTPRIO(p) & BDC_PRIORITY_MASK); - h->flags2 = 0; - h->dataOffset = dataOffset >> 2; - BDC_SET_IF_IDX(h, DHD_PKTTAG_IF(PKTTAG(p))); - return BCME_OK; -} - -static int -_dhd_wlfc_pullheader(athost_wl_status_info_t* ctx, void* pktbuf) -{ - struct bdc_header *h; - - if (PKTLEN(ctx->osh, pktbuf) < BDC_HEADER_LEN) { - WLFC_DBGMESG(("%s: rx data too short (%d < %d)\n", __FUNCTION__, - PKTLEN(ctx->osh, pktbuf), BDC_HEADER_LEN)); - return BCME_ERROR; - } - h = (struct bdc_header *)PKTDATA(ctx->osh, pktbuf); - - /* pull BDC header */ - PKTPULL(ctx->osh, pktbuf, BDC_HEADER_LEN); - - if (PKTLEN(ctx->osh, pktbuf) < (h->dataOffset << 2)) { - WLFC_DBGMESG(("%s: rx data too short (%d < %d)\n", __FUNCTION__, - PKTLEN(ctx->osh, pktbuf), (h->dataOffset << 2))); - return BCME_ERROR; - } - - /* pull wl-header */ - PKTPULL(ctx->osh, pktbuf, (h->dataOffset << 2)); - return BCME_OK; -} - -static wlfc_mac_descriptor_t* -_dhd_wlfc_find_table_entry(athost_wl_status_info_t* ctx, void* p) -{ - int i; - wlfc_mac_descriptor_t* table = ctx->destination_entries.nodes; - uint8 ifid = DHD_PKTTAG_IF(PKTTAG(p)); - uint8* dstn = DHD_PKTTAG_DSTN(PKTTAG(p)); - wlfc_mac_descriptor_t* entry = NULL; - int iftype = ctx->destination_entries.interfaces[ifid].iftype; - - /* Multicast destination and P2P clients get the interface entry. - * STA gets the interface entry if there is no exact match. For - * example, TDLS destinations have their own entry. - */ - if ((iftype == WLC_E_IF_ROLE_STA || ETHER_ISMULTI(dstn) || - iftype == WLC_E_IF_ROLE_P2P_CLIENT) && - (ctx->destination_entries.interfaces[ifid].occupied)) { - entry = &ctx->destination_entries.interfaces[ifid]; - } - - if (entry != NULL && ETHER_ISMULTI(dstn)) - return entry; - - for (i = 0; i < WLFC_MAC_DESC_TABLE_SIZE; i++) { - if (table[i].occupied) { - if (table[i].interface_id == ifid) { - if (!memcmp(table[i].ea, dstn, ETHER_ADDR_LEN)) { - entry = &table[i]; - break; - } - } - } - } - - return entry != NULL ? entry : &ctx->destination_entries.other; -} - -static int -_dhd_wlfc_rollback_packet_toq(athost_wl_status_info_t* ctx, - void* p, ewlfc_packet_state_t pkt_type, uint32 hslot) -{ - /* - put the packet back to the head of queue - - - suppressed packet goes back to suppress sub-queue - - pull out the header, if new or delayed packet - - Note: hslot is used only when header removal is done. - */ - wlfc_mac_descriptor_t* entry; - void* pktout; - int rc = BCME_OK; - int prec; - - entry = _dhd_wlfc_find_table_entry(ctx, p); - prec = DHD_PKTTAG_FIFO(PKTTAG(p)); - if (entry != NULL) { - if (pkt_type == eWLFC_PKTTYPE_SUPPRESSED) { - /* wl-header is saved for suppressed packets */ - if (WLFC_PKTQ_PENQ_HEAD(&entry->psq, ((prec << 1) + 1), p) == NULL) { - WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); - rc = BCME_ERROR; - } - } - else { - /* remove header first */ - rc = _dhd_wlfc_pullheader(ctx, p); - if (rc != BCME_OK) { - WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); - /* free the hanger slot */ - dhd_wlfc_hanger_poppkt(ctx->hanger, hslot, &pktout, 1); - PKTFREE(ctx->osh, p, TRUE); - ctx->stats.rollback_failed++; - return BCME_ERROR; - } - - if (pkt_type == eWLFC_PKTTYPE_DELAYED) { - /* delay-q packets are going to delay-q */ - if (WLFC_PKTQ_PENQ_HEAD(&entry->psq, (prec << 1), p) == NULL) { - WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); - rc = BCME_ERROR; - } - } - - /* free the hanger slot */ - dhd_wlfc_hanger_poppkt(ctx->hanger, hslot, &pktout, 1); - - /* decrement sequence count */ - WLFC_DECR_SEQCOUNT(entry, prec); - } - /* - if this packet did not count against FIFO credit, it must have - taken a requested_credit from the firmware (for pspoll etc.) - */ - if (!DHD_PKTTAG_CREDITCHECK(PKTTAG(p))) { - entry->requested_credit++; - } - } - else { - WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); - rc = BCME_ERROR; - } - if (rc != BCME_OK) - ctx->stats.rollback_failed++; - else - ctx->stats.rollback++; - - return rc; -} - -static void -_dhd_wlfc_flow_control_check(athost_wl_status_info_t* ctx, struct pktq* pq, uint8 if_id) -{ - dhd_pub_t *dhdp; - - ASSERT(ctx); - - dhdp = (dhd_pub_t *)ctx->dhdp; - - if (dhdp && dhdp->skip_fc && dhdp->skip_fc()) - return; - - if ((pq->len <= WLFC_FLOWCONTROL_LOWATER) && (ctx->hostif_flow_state[if_id] == ON)) { - /* start traffic */ - ctx->hostif_flow_state[if_id] = OFF; - /* - WLFC_DBGMESG(("qlen:%02d, if:%02d, ->OFF, start traffic %s()\n", - pq->len, if_id, __FUNCTION__)); - */ - WLFC_DBGMESG(("F")); - - dhd_txflowcontrol(ctx->dhdp, if_id, OFF); - - ctx->toggle_host_if = 0; - } - if ((pq->len >= WLFC_FLOWCONTROL_HIWATER) && (ctx->hostif_flow_state[if_id] == OFF)) { - /* stop traffic */ - ctx->hostif_flow_state[if_id] = ON; - /* - WLFC_DBGMESG(("qlen:%02d, if:%02d, ->ON, stop traffic %s()\n", - pq->len, if_id, __FUNCTION__)); - */ - WLFC_DBGMESG(("N")); - - dhd_txflowcontrol(ctx->dhdp, if_id, ON); - - ctx->host_ifidx = if_id; - ctx->toggle_host_if = 1; - } - - return; -} - -static int -_dhd_wlfc_send_signalonly_packet(athost_wl_status_info_t* ctx, wlfc_mac_descriptor_t* entry, - uint8 ta_bmp) -{ - int rc = BCME_OK; - void* p = NULL; - int dummylen = ((dhd_pub_t *)ctx->dhdp)->hdrlen+ 12; - - /* allocate a dummy packet */ - p = PKTGET(ctx->osh, dummylen, TRUE); - if (p) { - PKTPULL(ctx->osh, p, dummylen); - DHD_PKTTAG_SET_H2DTAG(PKTTAG(p), 0); - _dhd_wlfc_pushheader(ctx, p, TRUE, ta_bmp, entry->mac_handle, 0); - DHD_PKTTAG_SETSIGNALONLY(PKTTAG(p), 1); -#ifdef PROP_TXSTATUS_DEBUG - ctx->stats.signal_only_pkts_sent++; -#endif - rc = dhd_bus_txdata(((dhd_pub_t *)ctx->dhdp)->bus, p); - if (rc != BCME_OK) { - PKTFREE(ctx->osh, p, TRUE); - } - } - else { - DHD_ERROR(("%s: couldn't allocate new %d-byte packet\n", - __FUNCTION__, dummylen)); - rc = BCME_NOMEM; - } - return rc; -} - -/* Return TRUE if traffic availability changed */ -static bool -_dhd_wlfc_traffic_pending_check(athost_wl_status_info_t* ctx, wlfc_mac_descriptor_t* entry, - int prec) -{ - bool rc = FALSE; - - if (entry->state == WLFC_STATE_CLOSE) { - if ((pktq_plen(&entry->psq, (prec << 1)) == 0) && - (pktq_plen(&entry->psq, ((prec << 1) + 1)) == 0)) { - - if (entry->traffic_pending_bmp & NBITVAL(prec)) { - rc = TRUE; - entry->traffic_pending_bmp = - entry->traffic_pending_bmp & ~ NBITVAL(prec); - } - } - else { - if (!(entry->traffic_pending_bmp & NBITVAL(prec))) { - rc = TRUE; - entry->traffic_pending_bmp = - entry->traffic_pending_bmp | NBITVAL(prec); - } - } - } - if (rc) { - /* request a TIM update to firmware at the next piggyback opportunity */ - if (entry->traffic_lastreported_bmp != entry->traffic_pending_bmp) { - entry->send_tim_signal = 1; - _dhd_wlfc_send_signalonly_packet(ctx, entry, entry->traffic_pending_bmp); - entry->traffic_lastreported_bmp = entry->traffic_pending_bmp; - entry->send_tim_signal = 0; - } - else { - rc = FALSE; - } - } - return rc; -} - -static int -_dhd_wlfc_enque_suppressed(athost_wl_status_info_t* ctx, int prec, void* p) -{ - wlfc_mac_descriptor_t* entry; - - entry = _dhd_wlfc_find_table_entry(ctx, p); - if (entry == NULL) { - WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); - return BCME_NOTFOUND; - } - /* - - suppressed packets go to sub_queue[2*prec + 1] AND - - delayed packets go to sub_queue[2*prec + 0] to ensure - order of delivery. - */ - if (WLFC_PKTQ_PENQ(&entry->psq, ((prec << 1) + 1), p) == NULL) { - ctx->stats.delayq_full_error++; - /* WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); */ - WLFC_DBGMESG(("s")); - return BCME_ERROR; - } - /* A packet has been pushed, update traffic availability bitmap, if applicable */ - _dhd_wlfc_traffic_pending_check(ctx, entry, prec); - _dhd_wlfc_flow_control_check(ctx, &entry->psq, DHD_PKTTAG_IF(PKTTAG(p))); - return BCME_OK; -} - -static int -_dhd_wlfc_pretx_pktprocess(athost_wl_status_info_t* ctx, - wlfc_mac_descriptor_t* entry, void* p, int header_needed, uint32* slot) -{ - int rc = BCME_OK; - int hslot = WLFC_HANGER_MAXITEMS; - bool send_tim_update = FALSE; - uint32 htod = 0; - uint8 free_ctr; - - *slot = hslot; - - if (entry == NULL) { - entry = _dhd_wlfc_find_table_entry(ctx, p); - } - - if (entry == NULL) { - WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); - return BCME_ERROR; - } - if (entry->send_tim_signal) { - send_tim_update = TRUE; - entry->send_tim_signal = 0; - entry->traffic_lastreported_bmp = entry->traffic_pending_bmp; - } - if (header_needed) { - hslot = dhd_wlfc_hanger_get_free_slot(ctx->hanger); - free_ctr = WLFC_SEQCOUNT(entry, DHD_PKTTAG_FIFO(PKTTAG(p))); - DHD_PKTTAG_SET_H2DTAG(PKTTAG(p), htod); - WLFC_PKTFLAG_SET_GENERATION(htod, entry->generation); - entry->transit_count++; - } - else { - hslot = WLFC_PKTID_HSLOT_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p))); - free_ctr = WLFC_PKTID_FREERUNCTR_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p))); - } - WLFC_PKTID_HSLOT_SET(htod, hslot); - WLFC_PKTID_FREERUNCTR_SET(htod, free_ctr); - DHD_PKTTAG_SETPKTDIR(PKTTAG(p), 1); - WL_TXSTATUS_SET_FLAGS(htod, WLFC_PKTFLAG_PKTFROMHOST); - WL_TXSTATUS_SET_FIFO(htod, DHD_PKTTAG_FIFO(PKTTAG(p))); - - - if (!DHD_PKTTAG_CREDITCHECK(PKTTAG(p))) { - /* - Indicate that this packet is being sent in response to an - explicit request from the firmware side. - */ - WLFC_PKTFLAG_SET_PKTREQUESTED(htod); - } - else { - WLFC_PKTFLAG_CLR_PKTREQUESTED(htod); - } - if (header_needed) { - rc = _dhd_wlfc_pushheader(ctx, p, send_tim_update, - entry->traffic_lastreported_bmp, entry->mac_handle, htod); - if (rc == BCME_OK) { - DHD_PKTTAG_SET_H2DTAG(PKTTAG(p), htod); - /* - a new header was created for this packet. - push to hanger slot and scrub q. Since bus - send succeeded, increment seq number as well. - */ - rc = dhd_wlfc_hanger_pushpkt(ctx->hanger, p, hslot); - if (rc == BCME_OK) { - /* increment free running sequence count */ - WLFC_INCR_SEQCOUNT(entry, DHD_PKTTAG_FIFO(PKTTAG(p))); -#ifdef PROP_TXSTATUS_DEBUG - ((wlfc_hanger_t*)(ctx->hanger))->items[hslot].push_time = - OSL_SYSUPTIME(); -#endif - } - else { - WLFC_DBGMESG(("%s() hanger_pushpkt() failed, rc: %d\n", - __FUNCTION__, rc)); - } - } - } - else { - int gen; - - /* remove old header */ - rc = _dhd_wlfc_pullheader(ctx, p); - if (rc == BCME_OK) { - hslot = WLFC_PKTID_HSLOT_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p))); - dhd_wlfc_hanger_get_genbit(ctx->hanger, p, hslot, &gen); - - WLFC_PKTFLAG_SET_GENERATION(htod, gen); - free_ctr = WLFC_PKTID_FREERUNCTR_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p))); - /* push new header */ - _dhd_wlfc_pushheader(ctx, p, send_tim_update, - entry->traffic_lastreported_bmp, entry->mac_handle, htod); - } - } - *slot = hslot; - return rc; -} - -static int -_dhd_wlfc_is_destination_closed(athost_wl_status_info_t* ctx, - wlfc_mac_descriptor_t* entry, int prec) -{ - if (ctx->destination_entries.interfaces[entry->interface_id].iftype == - WLC_E_IF_ROLE_P2P_GO) { - /* - destination interface is of type p2p GO. - For a p2pGO interface, if the destination is OPEN but the interface is - CLOSEd, do not send traffic. But if the dstn is CLOSEd while there is - destination-specific-credit left send packets. This is because the - firmware storing the destination-specific-requested packet in queue. - */ - if ((entry->state == WLFC_STATE_CLOSE) && (entry->requested_credit == 0) && - (entry->requested_packet == 0)) - return 1; - } - /* AP, p2p_go -> unicast desc entry, STA/p2p_cl -> interface desc. entry */ - if (((entry->state == WLFC_STATE_CLOSE) && (entry->requested_credit == 0) && - (entry->requested_packet == 0)) || - (!(entry->ac_bitmap & (1 << prec)))) - return 1; - - return 0; -} - -static void* -_dhd_wlfc_deque_delayedq(athost_wl_status_info_t* ctx, - int prec, uint8* ac_credit_spent, uint8* needs_hdr, wlfc_mac_descriptor_t** entry_out) -{ - wlfc_mac_descriptor_t* entry; - wlfc_mac_descriptor_t* table; - uint8 token_pos; - int total_entries; - void* p = NULL; - int pout; - int i; - - *entry_out = NULL; - token_pos = ctx->token_pos[prec]; - /* most cases a packet will count against FIFO credit */ - *ac_credit_spent = 1; - *needs_hdr = 1; - - /* search all entries, include nodes as well as interfaces */ - table = (wlfc_mac_descriptor_t*)&ctx->destination_entries; - total_entries = sizeof(ctx->destination_entries)/sizeof(wlfc_mac_descriptor_t); - - for (i = 0; i < total_entries; i++) { - entry = &table[(token_pos + i) % total_entries]; - if (entry->occupied && !entry->deleting) { - if (!_dhd_wlfc_is_destination_closed(ctx, entry, prec)) { - p = pktq_mdeq(&entry->psq, - /* higher precedence will be picked up first, - * i.e. suppressed packets before delayed ones - */ - NBITVAL((prec << 1) + 1), &pout); - *needs_hdr = 0; - - if (p == NULL) { - if (entry->suppressed == TRUE) { - if ((entry->suppr_transit_count <= - entry->suppress_count)) { - entry->suppressed = FALSE; - } else { - return NULL; - } - } - /* De-Q from delay Q */ - p = pktq_mdeq(&entry->psq, - NBITVAL((prec << 1)), - &pout); - *needs_hdr = 1; - } - - if (p != NULL) { - /* did the packet come from suppress sub-queue? */ - if (entry->requested_credit > 0) { - entry->requested_credit--; -#ifdef PROP_TXSTATUS_DEBUG - entry->dstncredit_sent_packets++; -#endif - /* - if the packet was pulled out while destination is in - closed state but had a non-zero packets requested, - then this should not count against the FIFO credit. - That is due to the fact that the firmware will - most likely hold onto this packet until a suitable - time later to push it to the appropriate AC FIFO. - */ - if (entry->state == WLFC_STATE_CLOSE) - *ac_credit_spent = 0; - } - else if (entry->requested_packet > 0) { - entry->requested_packet--; - DHD_PKTTAG_SETONETIMEPKTRQST(PKTTAG(p)); - if (entry->state == WLFC_STATE_CLOSE) - *ac_credit_spent = 0; - } - /* move token to ensure fair round-robin */ - ctx->token_pos[prec] = - (token_pos + i + 1) % total_entries; - *entry_out = entry; - _dhd_wlfc_flow_control_check(ctx, &entry->psq, - DHD_PKTTAG_IF(PKTTAG(p))); - /* - A packet has been picked up, update traffic - availability bitmap, if applicable - */ - _dhd_wlfc_traffic_pending_check(ctx, entry, prec); - return p; - } - } - } - } - return NULL; -} - -void * -_dhd_wlfc_pktq_peek_tail(struct pktq *pq, int *prec_out) -{ - int prec; - - ASSERT(pq); - - if (pq->len == 0) - return NULL; - - for (prec = 0; prec < pq->hi_prec; prec++) - /* only pick packets from dealyed-q */ - if (((prec & 1) == 0) && pq->q[prec].head) - break; - - if (prec_out) - *prec_out = prec; - - return (pq->q[prec].tail); -} - -bool -_dhd_wlfc_prec_enq_with_drop(dhd_pub_t *dhdp, struct pktq *pq, void *pkt, int prec) -{ - void *p = NULL; - int eprec = -1; /* precedence to evict from */ - - ASSERT(dhdp && pq && pkt); - ASSERT(prec >= 0 && prec < pq->num_prec); - - /* Fast case, precedence queue is not full and we are also not - * exceeding total queue length - */ - if (!pktq_pfull(pq, prec) && !pktq_full(pq)) { - pktq_penq(pq, prec, pkt); - return TRUE; - } - - /* Determine precedence from which to evict packet, if any */ - if (pktq_pfull(pq, prec)) - eprec = prec; - else if (pktq_full(pq)) { - p = _dhd_wlfc_pktq_peek_tail(pq, &eprec); - if (!p) { - WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); - return FALSE; - } - if ((eprec > prec) || (eprec < 0)) { - if (!pktq_pempty(pq, prec)) { - eprec = prec; - } else { - return FALSE; - } - } - } - - /* Evict if needed */ - if (eprec >= 0) { - /* Detect queueing to unconfigured precedence */ - ASSERT(!pktq_pempty(pq, eprec)); - /* Evict all fragmented frames */ - dhd_prec_drop_pkts(dhdp->osh, pq, eprec); - } - - /* Enqueue */ - p = pktq_penq(pq, prec, pkt); - if (!p) { - WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); - return FALSE; - } - - return TRUE; -} - -static int -_dhd_wlfc_enque_delayq(athost_wl_status_info_t* ctx, void* pktbuf, int prec) -{ - wlfc_mac_descriptor_t* entry; - - if (pktbuf != NULL) { - entry = _dhd_wlfc_find_table_entry(ctx, pktbuf); - - if (entry == NULL) { - WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); - return BCME_ERROR; - } - - /* - - suppressed packets go to sub_queue[2*prec + 1] AND - - delayed packets go to sub_queue[2*prec + 0] to ensure - order of delivery. - */ - if (_dhd_wlfc_prec_enq_with_drop(ctx->dhdp, &entry->psq, pktbuf, (prec << 1)) - == FALSE) { - WLFC_DBGMESG(("D")); - /* dhd_txcomplete(ctx->dhdp, pktbuf, FALSE); */ - PKTFREE(ctx->osh, pktbuf, TRUE); - ctx->stats.delayq_full_error++; - return BCME_ERROR; - } - - /* - A packet has been pushed, update traffic availability bitmap, - if applicable - */ - _dhd_wlfc_traffic_pending_check(ctx, entry, prec); - - } - return BCME_OK; -} - -bool ifpkt_fn(void* p, int ifid) -{ - return (ifid == DHD_PKTTAG_IF(PKTTAG(p))); -} - -static int -_dhd_wlfc_mac_entry_update(athost_wl_status_info_t* ctx, wlfc_mac_descriptor_t* entry, - ewlfc_mac_entry_action_t action, uint8 ifid, uint8 iftype, uint8* ea) -{ - int rc = BCME_OK; - - if (action == eWLFC_MAC_ENTRY_ACTION_ADD) { - entry->occupied = 1; - entry->state = WLFC_STATE_OPEN; - entry->requested_credit = 0; - entry->interface_id = ifid; - entry->iftype = iftype; - entry->ac_bitmap = 0xff; /* update this when handling APSD */ - /* for an interface entry we may not care about the MAC address */ - if (ea != NULL) - memcpy(&entry->ea[0], ea, ETHER_ADDR_LEN); - pktq_init(&entry->psq, WLFC_PSQ_PREC_COUNT, WLFC_PSQ_LEN); - } - else if (action == eWLFC_MAC_ENTRY_ACTION_UPDATE) { - entry->occupied = 1; - entry->state = WLFC_STATE_OPEN; - entry->requested_credit = 0; - entry->interface_id = ifid; - entry->iftype = iftype; - entry->ac_bitmap = 0xff; /* update this when handling APSD */ - /* for an interface entry we may not care about the MAC address */ - if (ea != NULL) - memcpy(&entry->ea[0], ea, ETHER_ADDR_LEN); - } - else if (action == eWLFC_MAC_ENTRY_ACTION_DEL) { - /* When the entry is deleted, the packets that are queued in the entry must be - cleanup. The cleanup action should be before the occupied is set as 0. The - flag deleting is set to avoid de-queue action when these queues are being - cleanup - */ - entry->deleting = 1; - dhd_wlfc_cleanup(ctx->dhdp, ifpkt_fn, ifid); - _dhd_wlfc_flow_control_check(ctx, &entry->psq, ifid); - entry->deleting = 0; - - entry->occupied = 0; - entry->suppressed = 0; - entry->state = WLFC_STATE_CLOSE; - entry->requested_credit = 0; - entry->transit_count = 0; - entry->suppr_transit_count = 0; - entry->suppress_count = 0; - memset(&entry->ea[0], 0, ETHER_ADDR_LEN); - - /* enable after packets are queued-deqeued properly. - pktq_flush(dhd->osh, &entry->psq, FALSE, NULL, 0); - */ - } - return rc; -} - -int -_dhd_wlfc_borrow_credit(athost_wl_status_info_t* ctx, uint8 available_credit_map, int borrower_ac) -{ - int lender_ac; - int rc = BCME_ERROR; - - if (ctx == NULL || available_credit_map == 0) { - WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); - return BCME_BADARG; - } - - /* Borrow from lowest priority available AC (including BC/MC credits) */ - for (lender_ac = 0; lender_ac <= AC_COUNT; lender_ac++) { - if ((available_credit_map && (1 << lender_ac)) && - (ctx->FIFO_credit[lender_ac] > 0)) { - ctx->credits_borrowed[borrower_ac][lender_ac]++; - ctx->FIFO_credit[lender_ac]--; - rc = BCME_OK; - break; - } - } - - return rc; -} - -int -dhd_wlfc_interface_entry_update(void* state, - ewlfc_mac_entry_action_t action, uint8 ifid, uint8 iftype, uint8* ea) -{ - athost_wl_status_info_t* ctx = (athost_wl_status_info_t*)state; - wlfc_mac_descriptor_t* entry; - int ret; - - if (ifid >= WLFC_MAX_IFNUM) - return BCME_BADARG; - - entry = &ctx->destination_entries.interfaces[ifid]; - ret = _dhd_wlfc_mac_entry_update(ctx, entry, action, ifid, iftype, ea); - return ret; -} - -int -dhd_wlfc_FIFOcreditmap_update(void* state, uint8* credits) -{ - athost_wl_status_info_t* ctx = (athost_wl_status_info_t*)state; - - /* update the AC FIFO credit map */ - ctx->FIFO_credit[0] = credits[0]; - ctx->FIFO_credit[1] = credits[1]; - ctx->FIFO_credit[2] = credits[2]; - ctx->FIFO_credit[3] = credits[3]; - /* credit for bc/mc packets */ - ctx->FIFO_credit[4] = credits[4]; - /* credit for ATIM FIFO is not used yet. */ - ctx->FIFO_credit[5] = 0; - return BCME_OK; -} - -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) -{ - uint32 hslot; - int rc; - - /* - if ac_fifo_credit_spent = 0 - - This packet will not count against the FIFO credit. - To ensure the txstatus corresponding to this packet - does not provide an implied credit (default behavior) - mark the packet accordingly. - - if ac_fifo_credit_spent = 1 - - 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); - - if (rc == BCME_OK) - rc = fcommit(commit_ctx, commit_info->p); - else - ctx->stats.generic_error++; - - if (rc == BCME_OK) { - ctx->stats.pkt2bus++; - if (commit_info->ac_fifo_credit_spent) { - ctx->stats.send_pkts[ac]++; - WLFC_HOST_FIFO_CREDIT_INC_SENTCTRS(ctx, ac); - } - } else if (rc == BCME_NORESOURCE) - rc = BCME_ERROR; - else { - /* - 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); - - rc = BCME_ERROR; - } - - return rc; -} - -int -dhd_wlfc_commit_packets(void* state, f_commitpkt_t fcommit, void* commit_ctx, void *pktbuf) -{ - 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. - */ - - if (pktbuf) { - ac = DHD_PKTTAG_FIFO(PKTTAG(pktbuf)); - if (ETHER_ISMULTI(DHD_PKTTAG_DSTN(PKTTAG(pktbuf)))) { - ASSERT(ac == AC_COUNT); - commit_info.needs_hdr = 1; - commit_info.mac_entry = NULL; - commit_info.pkt_type = eWLFC_PKTTYPE_NEW; - commit_info.p = pktbuf; - if (ctx->FIFO_credit[ac]) { - 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((" %s: bus error %d\n", - __FUNCTION__, rc)); - return rc; - } - } - } - } - else { - /* en-queue the packets to respective queue. */ - rc = _dhd_wlfc_enque_delayq(ctx, pktbuf, ac); - } - } - - for (ac = AC_COUNT; ac >= 0; ac--) { - - bool bQueueIdle = TRUE; - - /* packets from delayQ with less priority 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 = 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; - - bQueueIdle = FALSE; - - 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(("%s: bus error %d\n", __FUNCTION__, rc)); - ctx->FIFO_credit[ac] -= credit; - return rc; - } - } - } - - ctx->FIFO_credit[ac] -= credit; - - - /* If no pkts can be dequed, the credit can be borrowed */ - if (bQueueIdle) { - 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(("%s: bus error %d\n", __FUNCTION__, rc)); - return rc; - } - } - } - return BCME_OK; -} - -static uint8 -dhd_wlfc_find_mac_desc_id_from_mac(dhd_pub_t *dhdp, uint8* ea) -{ - wlfc_mac_descriptor_t* table = - ((athost_wl_status_info_t*)dhdp->wlfc_state)->destination_entries.nodes; - uint8 table_index; - - if (ea != NULL) { - for (table_index = 0; table_index < WLFC_MAC_DESC_TABLE_SIZE; table_index++) { - if ((memcmp(ea, &table[table_index].ea[0], ETHER_ADDR_LEN) == 0) && - table[table_index].occupied) - return table_index; - } - } - return WLFC_MAC_DESC_ID_INVALID; -} - -void -dhd_wlfc_txcomplete(dhd_pub_t *dhd, void *txp, bool success) -{ - athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) - dhd->wlfc_state; - void* p; - int fifo_id; - - if (DHD_PKTTAG_SIGNALONLY(PKTTAG(txp))) { -#ifdef PROP_TXSTATUS_DEBUG - wlfc->stats.signal_only_pkts_freed++; -#endif - /* is this a signal-only packet? */ - if (success) - PKTFREE(wlfc->osh, txp, TRUE); - return; - } - if (!success) { - WLFC_DBGMESG(("At: %s():%d, bus_complete() failure for %p, htod_tag:0x%08x\n", - __FUNCTION__, __LINE__, txp, DHD_PKTTAG_H2DTAG(PKTTAG(txp)))); - dhd_wlfc_hanger_poppkt(wlfc->hanger, WLFC_PKTID_HSLOT_GET(DHD_PKTTAG_H2DTAG - (PKTTAG(txp))), &p, 1); - - /* indicate failure and free the packet */ - dhd_txcomplete(dhd, txp, FALSE); - - /* return the credit, if necessary */ - if (DHD_PKTTAG_CREDITCHECK(PKTTAG(txp))) { - int lender, credit_returned = 0; /* Note that borrower is fifo_id */ - - fifo_id = DHD_PKTTAG_FIFO(PKTTAG(txp)); - - /* Return credits to highest priority lender first */ - for (lender = AC_COUNT; lender >= 0; lender--) { - if (wlfc->credits_borrowed[fifo_id][lender] > 0) { - wlfc->FIFO_credit[lender]++; - wlfc->credits_borrowed[fifo_id][lender]--; - credit_returned = 1; - break; - } - } - - if (!credit_returned) { - wlfc->FIFO_credit[fifo_id]++; - } - } - - PKTFREE(wlfc->osh, txp, TRUE); - } - return; -} - -static int -dhd_wlfc_compressed_txstatus_update(dhd_pub_t *dhd, uint8* pkt_info, uint8 len) -{ - uint8 status_flag; - uint32 status; - int ret; - int remove_from_hanger = 1; - void* pktbuf; - uint8 fifo_id; - uint8 count = 0; - uint32 status_g; - uint32 hslot, hcnt; - wlfc_mac_descriptor_t* entry = NULL; - athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) - dhd->wlfc_state; - - memcpy(&status, pkt_info, sizeof(uint32)); - status_flag = WL_TXSTATUS_GET_FLAGS(status); - status_g = status & 0xff000000; - hslot = (status & 0x00ffff00) >> 8; - hcnt = status & 0xff; - len = pkt_info[4]; - - wlfc->stats.txstatus_in++; - - if (status_flag == WLFC_CTL_PKTFLAG_DISCARD) { - wlfc->stats.pkt_freed++; - } - - else if (status_flag == WLFC_CTL_PKTFLAG_D11SUPPRESS) { - wlfc->stats.d11_suppress++; - remove_from_hanger = 0; - } - - else if (status_flag == WLFC_CTL_PKTFLAG_WLSUPPRESS) { - wlfc->stats.wl_suppress++; - remove_from_hanger = 0; - } - - else if (status_flag == WLFC_CTL_PKTFLAG_TOSSED_BYWLC) { - wlfc->stats.wlc_tossed_pkts++; - } - while (count < len) { - status = (status_g << 24) | (hslot << 8) | (hcnt); - count++; - hslot++; - hcnt++; - - ret = dhd_wlfc_hanger_poppkt(wlfc->hanger, - WLFC_PKTID_HSLOT_GET(status), &pktbuf, remove_from_hanger); - if (ret != BCME_OK) { - /* do something */ - continue; - } - - entry = _dhd_wlfc_find_table_entry(wlfc, pktbuf); - - if (!remove_from_hanger) { - /* this packet was suppressed */ - if (!entry->suppressed || entry->generation != WLFC_PKTID_GEN(status)) { - entry->suppressed = TRUE; - entry->suppress_count = pktq_mlen(&entry->psq, - NBITVAL((WL_TXSTATUS_GET_FIFO(status) << 1) + 1)); - entry->suppr_transit_count = entry->transit_count; - } - entry->generation = WLFC_PKTID_GEN(status); - } - -#ifdef PROP_TXSTATUS_DEBUG - { - uint32 new_t = OSL_SYSUPTIME(); - uint32 old_t; - uint32 delta; - old_t = ((wlfc_hanger_t*)(wlfc->hanger))->items[ - WLFC_PKTID_HSLOT_GET(status)].push_time; - - - wlfc->stats.latency_sample_count++; - if (new_t > old_t) - delta = new_t - old_t; - else - delta = 0xffffffff + new_t - old_t; - wlfc->stats.total_status_latency += delta; - wlfc->stats.latency_most_recent = delta; - - wlfc->stats.deltas[wlfc->stats.idx_delta++] = delta; - if (wlfc->stats.idx_delta == sizeof(wlfc->stats.deltas)/sizeof(uint32)) - wlfc->stats.idx_delta = 0; - } -#endif /* PROP_TXSTATUS_DEBUG */ - - fifo_id = DHD_PKTTAG_FIFO(PKTTAG(pktbuf)); - - /* pick up the implicit credit from this packet */ - if (DHD_PKTTAG_CREDITCHECK(PKTTAG(pktbuf))) { - if (wlfc->proptxstatus_mode == WLFC_FCMODE_IMPLIED_CREDIT) { - - int lender, credit_returned = 0; /* Note that borrower is fifo_id */ - - /* Return credits to highest priority lender first */ - for (lender = AC_COUNT; lender >= 0; lender--) { - if (wlfc->credits_borrowed[fifo_id][lender] > 0) { - wlfc->FIFO_credit[lender]++; - wlfc->credits_borrowed[fifo_id][lender]--; - credit_returned = 1; - break; - } - } - - if (!credit_returned) { - wlfc->FIFO_credit[fifo_id]++; - } - } - } - else { - /* - if this packet did not count against FIFO credit, it must have - taken a requested_credit from the destination entry (for pspoll etc.) - */ - if (!entry) { - - entry = _dhd_wlfc_find_table_entry(wlfc, pktbuf); - } - if (!DHD_PKTTAG_ONETIMEPKTRQST(PKTTAG(pktbuf))) - entry->requested_credit++; -#ifdef PROP_TXSTATUS_DEBUG - entry->dstncredit_acks++; -#endif - } - if ((status_flag == WLFC_CTL_PKTFLAG_D11SUPPRESS) || - (status_flag == WLFC_CTL_PKTFLAG_WLSUPPRESS)) { - - ret = _dhd_wlfc_enque_suppressed(wlfc, fifo_id, pktbuf); - if (ret != BCME_OK) { - /* delay q is full, drop this packet */ - dhd_wlfc_hanger_poppkt(wlfc->hanger, WLFC_PKTID_HSLOT_GET(status), - &pktbuf, 1); - - /* indicate failure and free the packet */ - dhd_txcomplete(dhd, pktbuf, FALSE); - entry->transit_count--; - DHD_WLFC_QMON_COMPLETE(entry); - /* packet is transmitted Successfully by dongle - * after first suppress. - */ - if (entry->suppressed) { - entry->suppr_transit_count--; - } - PKTFREE(wlfc->osh, pktbuf, TRUE); - } else { - /* Mark suppressed to avoid a double free during wlfc cleanup */ - - dhd_wlfc_hanger_mark_suppressed(wlfc->hanger, - WLFC_PKTID_HSLOT_GET(status), WLFC_PKTID_GEN(status)); - entry->suppress_count++; - } - } - else { - dhd_txcomplete(dhd, pktbuf, TRUE); - entry->transit_count--; - DHD_WLFC_QMON_COMPLETE(entry); - - /* This packet is transmitted Successfully by dongle - * even after first suppress. - */ - if (entry->suppressed) { - entry->suppr_transit_count--; - } - /* free the packet */ - PKTFREE(wlfc->osh, pktbuf, TRUE); - } - } - return BCME_OK; -} - -/* Handle discard or suppress indication */ -static int -dhd_wlfc_txstatus_update(dhd_pub_t *dhd, uint8* pkt_info) -{ - uint8 status_flag; - uint32 status; - int ret; - int remove_from_hanger = 1; - void* pktbuf; - uint8 fifo_id; - wlfc_mac_descriptor_t* entry = NULL; - athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) - dhd->wlfc_state; - - memcpy(&status, pkt_info, sizeof(uint32)); - status_flag = WL_TXSTATUS_GET_FLAGS(status); - wlfc->stats.txstatus_in++; - - if (status_flag == WLFC_CTL_PKTFLAG_DISCARD) { - wlfc->stats.pkt_freed++; - } - - else if (status_flag == WLFC_CTL_PKTFLAG_D11SUPPRESS) { - wlfc->stats.d11_suppress++; - remove_from_hanger = 0; - } - - else if (status_flag == WLFC_CTL_PKTFLAG_WLSUPPRESS) { - wlfc->stats.wl_suppress++; - remove_from_hanger = 0; - } - - else if (status_flag == WLFC_CTL_PKTFLAG_TOSSED_BYWLC) { - wlfc->stats.wlc_tossed_pkts++; - } - - ret = dhd_wlfc_hanger_poppkt(wlfc->hanger, - WLFC_PKTID_HSLOT_GET(status), &pktbuf, remove_from_hanger); - if (ret != BCME_OK) { - /* do something */ - return ret; - } - - entry = _dhd_wlfc_find_table_entry(wlfc, pktbuf); - - if (!remove_from_hanger) { - /* this packet was suppressed */ - if (!entry->suppressed || entry->generation != WLFC_PKTID_GEN(status)) { - entry->suppressed = TRUE; - entry->suppress_count = pktq_mlen(&entry->psq, - NBITVAL((WL_TXSTATUS_GET_FIFO(status) << 1) + 1)); - entry->suppr_transit_count = entry->transit_count; - } - entry->generation = WLFC_PKTID_GEN(status); - } - -#ifdef PROP_TXSTATUS_DEBUG - { - uint32 new_t = OSL_SYSUPTIME(); - uint32 old_t; - uint32 delta; - old_t = ((wlfc_hanger_t*)(wlfc->hanger))->items[ - WLFC_PKTID_HSLOT_GET(status)].push_time; - - - wlfc->stats.latency_sample_count++; - if (new_t > old_t) - delta = new_t - old_t; - else - delta = 0xffffffff + new_t - old_t; - wlfc->stats.total_status_latency += delta; - wlfc->stats.latency_most_recent = delta; - - wlfc->stats.deltas[wlfc->stats.idx_delta++] = delta; - if (wlfc->stats.idx_delta == sizeof(wlfc->stats.deltas)/sizeof(uint32)) - wlfc->stats.idx_delta = 0; - } -#endif /* PROP_TXSTATUS_DEBUG */ - - fifo_id = DHD_PKTTAG_FIFO(PKTTAG(pktbuf)); - - /* pick up the implicit credit from this packet */ - if (DHD_PKTTAG_CREDITCHECK(PKTTAG(pktbuf))) { - if (wlfc->proptxstatus_mode == WLFC_FCMODE_IMPLIED_CREDIT) { - - int lender, credit_returned = 0; /* Note that borrower is fifo_id */ - - /* Return credits to highest priority lender first */ - for (lender = AC_COUNT; lender >= 0; lender--) { - if (wlfc->credits_borrowed[fifo_id][lender] > 0) { - wlfc->FIFO_credit[lender]++; - wlfc->credits_borrowed[fifo_id][lender]--; - credit_returned = 1; - break; - } - } - - if (!credit_returned) { - wlfc->FIFO_credit[fifo_id]++; - } - } - } - else { - /* - if this packet did not count against FIFO credit, it must have - taken a requested_credit from the destination entry (for pspoll etc.) - */ - if (!entry) { - - entry = _dhd_wlfc_find_table_entry(wlfc, pktbuf); - } - if (!DHD_PKTTAG_ONETIMEPKTRQST(PKTTAG(pktbuf))) - entry->requested_credit++; -#ifdef PROP_TXSTATUS_DEBUG - entry->dstncredit_acks++; -#endif - } - if ((status_flag == WLFC_CTL_PKTFLAG_D11SUPPRESS) || - (status_flag == WLFC_CTL_PKTFLAG_WLSUPPRESS)) { - - ret = _dhd_wlfc_enque_suppressed(wlfc, fifo_id, pktbuf); - if (ret != BCME_OK) { - /* delay q is full, drop this packet */ - dhd_wlfc_hanger_poppkt(wlfc->hanger, WLFC_PKTID_HSLOT_GET(status), - &pktbuf, 1); - - /* indicate failure and free the packet */ - dhd_txcomplete(dhd, pktbuf, FALSE); - entry->transit_count--; - DHD_WLFC_QMON_COMPLETE(entry); - /* This packet is transmitted Successfully by - * dongle even after first suppress. - */ - if (entry->suppressed) { - entry->suppr_transit_count--; - } - PKTFREE(wlfc->osh, pktbuf, TRUE); - } else { - /* Mark suppressed to avoid a double free during wlfc cleanup */ - - dhd_wlfc_hanger_mark_suppressed(wlfc->hanger, - WLFC_PKTID_HSLOT_GET(status), WLFC_PKTID_GEN(status)); - entry->suppress_count++; - } - } - else { - dhd_txcomplete(dhd, pktbuf, TRUE); - entry->transit_count--; - DHD_WLFC_QMON_COMPLETE(entry); - - /* This packet is transmitted Successfully by dongle even after first suppress. */ - if (entry->suppressed) { - entry->suppr_transit_count--; - } - /* free the packet */ - PKTFREE(wlfc->osh, pktbuf, TRUE); - } - return BCME_OK; -} - -static int -dhd_wlfc_fifocreditback_indicate(dhd_pub_t *dhd, uint8* credits) -{ - int i; - athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) - dhd->wlfc_state; - for (i = 0; i < WLFC_CTL_VALUE_LEN_FIFO_CREDITBACK; i++) { -#ifdef PROP_TXSTATUS_DEBUG - wlfc->stats.fifo_credits_back[i] += credits[i]; -#endif - /* update FIFO credits */ - if (wlfc->proptxstatus_mode == WLFC_FCMODE_EXPLICIT_CREDIT) - { - int lender; /* Note that borrower is i */ - - /* Return credits to highest priority lender first */ - for (lender = AC_COUNT; (lender >= 0) && (credits[i] > 0); lender--) { - if (wlfc->credits_borrowed[i][lender] > 0) { - if (credits[i] >= wlfc->credits_borrowed[i][lender]) { - credits[i] -= wlfc->credits_borrowed[i][lender]; - wlfc->FIFO_credit[lender] += - wlfc->credits_borrowed[i][lender]; - wlfc->credits_borrowed[i][lender] = 0; - } - else { - wlfc->credits_borrowed[i][lender] -= credits[i]; - wlfc->FIFO_credit[lender] += credits[i]; - credits[i] = 0; - } - } - } - - /* If we have more credits left over, these must belong to the AC */ - if (credits[i] > 0) { - wlfc->FIFO_credit[i] += credits[i]; - } - } - } - - return BCME_OK; -} - -static int -dhd_wlfc_dbg_senum_check(dhd_pub_t *dhd, uint8 *value) -{ - uint32 timestamp; - - (void)dhd; - - bcopy(&value[2], ×tamp, sizeof(uint32)); - DHD_INFO(("RXPKT: SEQ: %d, timestamp %d\n", value[1], timestamp)); - return BCME_OK; -} - - -static int -dhd_wlfc_rssi_indicate(dhd_pub_t *dhd, uint8* rssi) -{ - (void)dhd; - (void)rssi; - return BCME_OK; -} - -static int -dhd_wlfc_mac_table_update(dhd_pub_t *dhd, uint8* value, uint8 type) -{ - int rc; - athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) - dhd->wlfc_state; - wlfc_mac_descriptor_t* table; - uint8 existing_index; - uint8 table_index; - uint8 ifid; - uint8* ea; - - WLFC_DBGMESG(("%s(), mac [%02x:%02x:%02x:%02x:%02x:%02x],%s,idx:%d,id:0x%02x\n", - __FUNCTION__, value[2], value[3], value[4], value[5], value[6], value[7], - ((type == WLFC_CTL_TYPE_MACDESC_ADD) ? "ADD":"DEL"), - WLFC_MAC_DESC_GET_LOOKUP_INDEX(value[0]), value[0])); - - table = wlfc->destination_entries.nodes; - table_index = WLFC_MAC_DESC_GET_LOOKUP_INDEX(value[0]); - ifid = value[1]; - ea = &value[2]; - - if (type == WLFC_CTL_TYPE_MACDESC_ADD) { - existing_index = dhd_wlfc_find_mac_desc_id_from_mac(dhd, &value[2]); - if (existing_index == WLFC_MAC_DESC_ID_INVALID) { - /* this MAC entry does not exist, create one */ - if (!table[table_index].occupied) { - table[table_index].mac_handle = value[0]; - rc = _dhd_wlfc_mac_entry_update(wlfc, &table[table_index], - eWLFC_MAC_ENTRY_ACTION_ADD, ifid, - wlfc->destination_entries.interfaces[ifid].iftype, - ea); - } - else { - /* the space should have been empty, but it's not */ - wlfc->stats.mac_update_failed++; - } - } - else { - /* - there is an existing entry, move it to new index - if necessary. - */ - if (existing_index != table_index) { - /* if we already have an entry, free the old one */ - table[existing_index].occupied = 0; - 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); - */ - } - } - } - if (type == WLFC_CTL_TYPE_MACDESC_DEL) { - if (table[table_index].occupied) { - rc = _dhd_wlfc_mac_entry_update(wlfc, &table[table_index], - eWLFC_MAC_ENTRY_ACTION_DEL, ifid, - wlfc->destination_entries.interfaces[ifid].iftype, - ea); - } - else { - /* the space should have been occupied, but it's not */ - wlfc->stats.mac_update_failed++; - } - } - BCM_REFERENCE(rc); - return BCME_OK; -} - -static int -dhd_wlfc_psmode_update(dhd_pub_t *dhd, uint8* value, uint8 type) -{ - /* Handle PS on/off indication */ - athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) - dhd->wlfc_state; - wlfc_mac_descriptor_t* table; - wlfc_mac_descriptor_t* desc; - uint8 mac_handle = value[0]; - int i; - - table = wlfc->destination_entries.nodes; - desc = &table[WLFC_MAC_DESC_GET_LOOKUP_INDEX(mac_handle)]; - if (desc->occupied) { - /* a fresh PS mode should wipe old ps credits? */ - desc->requested_credit = 0; - if (type == WLFC_CTL_TYPE_MAC_OPEN) { - desc->state = WLFC_STATE_OPEN; - DHD_WLFC_CTRINC_MAC_OPEN(desc); - } - else { - desc->state = WLFC_STATE_CLOSE; - DHD_WLFC_CTRINC_MAC_CLOSE(desc); - /* - Indicate to firmware if there is any traffic pending. - */ - for (i = AC_BE; i < AC_COUNT; i++) { - _dhd_wlfc_traffic_pending_check(wlfc, desc, i); - } - } - } - else { - wlfc->stats.psmode_update_failed++; - } - return BCME_OK; -} - -static int -dhd_wlfc_interface_update(dhd_pub_t *dhd, uint8* value, uint8 type) -{ - /* Handle PS on/off indication */ - athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) - dhd->wlfc_state; - wlfc_mac_descriptor_t* table; - uint8 if_id = value[0]; - - if (if_id < WLFC_MAX_IFNUM) { - table = wlfc->destination_entries.interfaces; - if (table[if_id].occupied) { - if (type == WLFC_CTL_TYPE_INTERFACE_OPEN) { - table[if_id].state = WLFC_STATE_OPEN; - /* WLFC_DBGMESG(("INTERFACE[%d] OPEN\n", if_id)); */ - } - else { - table[if_id].state = WLFC_STATE_CLOSE; - /* WLFC_DBGMESG(("INTERFACE[%d] CLOSE\n", if_id)); */ - } - return BCME_OK; - } - } - wlfc->stats.interface_update_failed++; - - return BCME_OK; -} - -static int -dhd_wlfc_credit_request(dhd_pub_t *dhd, uint8* value) -{ - athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) - dhd->wlfc_state; - wlfc_mac_descriptor_t* table; - wlfc_mac_descriptor_t* desc; - uint8 mac_handle; - uint8 credit; - - table = wlfc->destination_entries.nodes; - mac_handle = value[1]; - credit = value[0]; - - desc = &table[WLFC_MAC_DESC_GET_LOOKUP_INDEX(mac_handle)]; - if (desc->occupied) { - desc->requested_credit = credit; - - desc->ac_bitmap = value[2]; - } - else { - wlfc->stats.credit_request_failed++; - } - return BCME_OK; -} - -static int -dhd_wlfc_packet_request(dhd_pub_t *dhd, uint8* value) -{ - athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) - dhd->wlfc_state; - wlfc_mac_descriptor_t* table; - wlfc_mac_descriptor_t* desc; - uint8 mac_handle; - uint8 packet_count; - - table = wlfc->destination_entries.nodes; - mac_handle = value[1]; - packet_count = value[0]; - - desc = &table[WLFC_MAC_DESC_GET_LOOKUP_INDEX(mac_handle)]; - if (desc->occupied) { - desc->requested_packet = packet_count; - - desc->ac_bitmap = value[2]; - } - else { - wlfc->stats.packet_request_failed++; - } - 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; - } -} - -int -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; - uint8* tmpbuf; - uint16 remainder = tlv_hdr_len; - uint16 processed = 0; - athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) - dhd->wlfc_state; - tmpbuf = (uint8*)PKTDATA(dhd->osh, pktbuf); - if (remainder) { - while ((processed < (WLFC_MAX_PENDING_DATALEN * 2)) && (remainder > 0)) { - type = tmpbuf[processed]; - if (type == WLFC_CTL_TYPE_FILLER) { - remainder -= 1; - processed += 1; - continue; - } - - len = tmpbuf[processed + 1]; - value = &tmpbuf[processed + 2]; - - if (remainder < (2 + len)) - break; - - remainder -= 2 + len; - processed += 2 + len; - if (type == WLFC_CTL_TYPE_TXSTATUS) - dhd_wlfc_txstatus_update(dhd, value); - if (type == WLFC_CTL_TYPE_COMP_TXSTATUS) - dhd_wlfc_compressed_txstatus_update(dhd, value, len); - - 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); - - else if (type == WLFC_CTL_TYPE_RSSI) - dhd_wlfc_rssi_indicate(dhd, value); - - else if (type == WLFC_CTL_TYPE_MAC_REQUEST_CREDIT) - dhd_wlfc_credit_request(dhd, value); - - else if (type == WLFC_CTL_TYPE_MAC_REQUEST_PACKET) - dhd_wlfc_packet_request(dhd, value); - - else if ((type == WLFC_CTL_TYPE_MAC_OPEN) || - (type == WLFC_CTL_TYPE_MAC_CLOSE)) - dhd_wlfc_psmode_update(dhd, value, type); - - else if ((type == WLFC_CTL_TYPE_MACDESC_ADD) || - (type == WLFC_CTL_TYPE_MACDESC_DEL)) - dhd_wlfc_mac_table_update(dhd, value, type); - - else if (type == WLFC_CTL_TYPE_TRANS_ID) - dhd_wlfc_dbg_senum_check(dhd, value); - - else if ((type == WLFC_CTL_TYPE_INTERFACE_OPEN) || - (type == WLFC_CTL_TYPE_INTERFACE_CLOSE)) { - dhd_wlfc_interface_update(dhd, value, type); - } - } - if (remainder != 0) { - /* trouble..., something is not right */ - wlfc->stats.tlv_parse_failed++; - } - } - return BCME_OK; -} - -int -dhd_wlfc_init(dhd_pub_t *dhd) -{ - char iovbuf[12]; /* Room for "tlv" + '\0' + parameter */ - /* enable all signals & indicate host proptxstatus logic is active */ - uint32 tlv = dhd->wlfc_enabled? - WLFC_FLAGS_RSSI_SIGNALS | - WLFC_FLAGS_XONXOFF_SIGNALS | - WLFC_FLAGS_CREDIT_STATUS_SIGNALS | - WLFC_FLAGS_HOST_PROPTXSTATUS_ACTIVE | - WLFC_FLAGS_HOST_RXRERODER_ACTIVE : 0; - /* WLFC_FLAGS_HOST_PROPTXSTATUS_ACTIVE | WLFC_FLAGS_HOST_RXRERODER_ACTIVE : 0; */ - - - /* - try to enable/disable signaling by sending "tlv" iovar. if that fails, - fallback to no flow control? Print a message for now. - */ - - /* enable proptxtstatus signaling by default */ - bcm_mkiovar("tlv", (char *)&tlv, 4, iovbuf, sizeof(iovbuf)); - if (dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0) < 0) { - DHD_ERROR(("dhd_wlfc_init(): failed to enable/disable bdcv2 tlv signaling\n")); - } - else { - /* - Leaving the message for now, it should be removed after a while; once - the tlv situation is stable. - */ - DHD_ERROR(("dhd_wlfc_init(): successfully %s bdcv2 tlv signaling, %d\n", - dhd->wlfc_enabled?"enabled":"disabled", tlv)); - } - return BCME_OK; -} - -int -dhd_wlfc_enable(dhd_pub_t *dhd) -{ - int i; - athost_wl_status_info_t* wlfc; - - if (!dhd->wlfc_enabled || dhd->wlfc_state) - return BCME_OK; - - /* allocate space to track txstatus propagated from firmware */ - dhd->wlfc_state = MALLOC(dhd->osh, sizeof(athost_wl_status_info_t)); - if (dhd->wlfc_state == NULL) - return BCME_NOMEM; - - /* initialize state space */ - wlfc = (athost_wl_status_info_t*)dhd->wlfc_state; - memset(wlfc, 0, sizeof(athost_wl_status_info_t)); - - /* remember osh & dhdp */ - wlfc->osh = dhd->osh; - wlfc->dhdp = dhd; - - wlfc->hanger = - dhd_wlfc_hanger_create(dhd->osh, WLFC_HANGER_MAXITEMS); - if (wlfc->hanger == NULL) { - MFREE(dhd->osh, dhd->wlfc_state, sizeof(athost_wl_status_info_t)); - dhd->wlfc_state = NULL; - DHD_ERROR(("Failed to malloc dhd->wlfc_state\n")); - return BCME_NOMEM; - } - - /* initialize all interfaces to accept traffic */ - for (i = 0; i < WLFC_MAX_IFNUM; i++) { - wlfc->hostif_flow_state[i] = OFF; - } - - wlfc->destination_entries.other.state = WLFC_STATE_OPEN; - /* bc/mc FIFO is always open [credit aside], i.e. b[5] */ - wlfc->destination_entries.other.ac_bitmap = 0x1f; - wlfc->destination_entries.other.interface_id = 0; - - wlfc->proptxstatus_mode = WLFC_FCMODE_EXPLICIT_CREDIT; - - wlfc->allow_credit_borrow = TRUE; - wlfc->borrow_defer_timestamp = 0; - - return BCME_OK; -} - -/* release all packet resources */ -void -dhd_wlfc_cleanup(dhd_pub_t *dhd, ifpkt_cb_t fn, int arg) -{ - int i; - int total_entries; - athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) - dhd->wlfc_state; - wlfc_mac_descriptor_t* table; - wlfc_hanger_t* h; - int prec; - void *pkt = NULL; - struct pktq *txq = NULL; - if (dhd->wlfc_state == NULL) - return; - /* flush bus->txq */ - txq = dhd_bus_txq(dhd->bus); - /* any in the hanger? */ - h = (wlfc_hanger_t*)wlfc->hanger; - total_entries = sizeof(wlfc->destination_entries)/sizeof(wlfc_mac_descriptor_t); - /* search all entries, include nodes as well as interfaces */ - table = (wlfc_mac_descriptor_t*)&wlfc->destination_entries; - - for (i = 0; i < total_entries; i++) { - if (table[i].occupied && (fn == NULL || (arg == table[i].interface_id))) { - if (table[i].psq.len) { - WLFC_DBGMESG(("%s(): DELAYQ[%d].len = %d\n", - __FUNCTION__, i, table[i].psq.len)); - /* release packets held in DELAYQ */ - pktq_flush(wlfc->osh, &table[i].psq, TRUE, fn, arg); - } - if (fn == NULL) - table[i].occupied = 0; - } - } - for (prec = 0; prec < txq->num_prec; prec++) { - pkt = pktq_pdeq_with_fn(txq, prec, fn, arg); - while (pkt) { - for (i = 0; i < h->max_items; i++) { - if (pkt == h->items[i].pkt) { - if (h->items[i].state == WLFC_HANGER_ITEM_STATE_INUSE) { - PKTFREE(wlfc->osh, h->items[i].pkt, TRUE); - h->items[i].state = WLFC_HANGER_ITEM_STATE_FREE; - } else if (h->items[i].state == - WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED) { - /* These are already freed from the psq */ - h->items[i].state = WLFC_HANGER_ITEM_STATE_FREE; - } - break; - } - } - pkt = pktq_pdeq(txq, prec); - } - } - /* flush remained pkt in hanger queue, not in bus->txq */ - for (i = 0; i < h->max_items; i++) { - if (h->items[i].state == WLFC_HANGER_ITEM_STATE_INUSE) { - if (fn == NULL || (*fn)(h->items[i].pkt, arg)) { - PKTFREE(wlfc->osh, h->items[i].pkt, TRUE); - h->items[i].state = WLFC_HANGER_ITEM_STATE_FREE; - } - } else if (h->items[i].state == WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED) { - if (fn == NULL || (*fn)(h->items[i].pkt, arg)) { - /* These are freed from the psq so no need to free again */ - h->items[i].state = WLFC_HANGER_ITEM_STATE_FREE; - } - } - } - return; -} - -void -dhd_wlfc_deinit(dhd_pub_t *dhd) -{ - /* cleanup all psq related resources */ - athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*) - dhd->wlfc_state; - - dhd_os_wlfc_block(dhd); - if (dhd->wlfc_state == NULL) { - dhd_os_wlfc_unblock(dhd); - return; - } - -#ifdef PROP_TXSTATUS_DEBUG - { - int i; - wlfc_hanger_t* h = (wlfc_hanger_t*)wlfc->hanger; - for (i = 0; i < h->max_items; i++) { - if (h->items[i].state != WLFC_HANGER_ITEM_STATE_FREE) { - WLFC_DBGMESG(("%s() pkt[%d] = 0x%p, FIFO_credit_used:%d\n", - __FUNCTION__, i, h->items[i].pkt, - DHD_PKTTAG_CREDITCHECK(PKTTAG(h->items[i].pkt)))); - } - } - } -#endif - /* delete hanger */ - dhd_wlfc_hanger_delete(dhd->osh, wlfc->hanger); - - /* free top structure */ - MFREE(dhd->osh, dhd->wlfc_state, sizeof(athost_wl_status_info_t)); - dhd->wlfc_state = NULL; - dhd_os_wlfc_unblock(dhd); - - return; -} -#endif /* PROP_TXSTATUS */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/dhd_wlfc.h linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_wlfc.h --- linux-sunxi/drivers/net/wireless/bcmdhd/dhd_wlfc.h 2014-01-27 01:30:30.101433269 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/dhd_wlfc.h 2014-02-15 00:43:44.792014069 +0100 @@ -1,5 +1,5 @@ /* -* Copyright (C) 1999-2013, Broadcom Corporation +* 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 @@ -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 398418 2013-04-24 15:18:27Z $ +* $Id: dhd_wlfc.h 361006 2012-10-05 07:45:51Z $ * */ #ifndef __wlfc_host_driver_definitions_h__ @@ -27,10 +27,9 @@ /* 16 bits will provide an absolute max of 65536 slots */ #define WLFC_HANGER_MAXITEMS 1024 -#define WLFC_HANGER_ITEM_STATE_FREE 1 -#define WLFC_HANGER_ITEM_STATE_INUSE 2 +#define WLFC_HANGER_ITEM_STATE_FREE 1 +#define WLFC_HANGER_ITEM_STATE_INUSE 2 #define WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED 3 - #define WLFC_PKTID_HSLOT_MASK 0xffff /* allow 16 bits only */ #define WLFC_PKTID_HSLOT_SHIFT 8 @@ -85,8 +84,8 @@ typedef struct wlfc_hanger { uint32 failed_to_push; uint32 failed_to_pop; uint32 failed_slotfind; - uint32 slot_pos; wlfc_hanger_item_t items[1]; + uint32 slot_pos; } wlfc_hanger_t; #define WLFC_HANGER_SIZE(n) ((sizeof(wlfc_hanger_t) - \ @@ -99,9 +98,13 @@ typedef struct wlfc_hanger { #define WLFC_PSQ_LEN 2048 +#define WLFC_SENDQ_LEN 256 + + #define WLFC_FLOWCONTROL_HIWATER (2048 - 256) #define WLFC_FLOWCONTROL_LOWATER 256 + typedef struct wlfc_mac_descriptor { uint8 occupied; uint8 interface_id; @@ -125,17 +128,10 @@ typedef struct wlfc_mac_descriptor { /* 1= send on next opportunity */ uint8 send_tim_signal; uint8 mac_handle; - /* Number of packets in transit for this entry. */ uint transit_count; - /* Numbe of suppression to wait before evict from delayQ */ uint suppr_transit_count; - /* Used when a new suppress is detected to track the number of - * packets getting suppressed - */ uint suppress_count; - /* flag. TRUE when in suppress state */ - uint8 suppressed; - uint8 deleting; + uint8 suppressed; #ifdef PROP_TXSTATUS_DEBUG uint32 dstncredit_sent_packets; @@ -158,6 +154,7 @@ typedef struct athost_wl_stat_counters { uint32 tlv_parse_failed; uint32 rollback; uint32 rollback_failed; + uint32 sendq_full_error; uint32 delayq_full_error; uint32 credit_request_failed; uint32 packet_request_failed; @@ -182,7 +179,7 @@ typedef struct athost_wl_stat_counters { uint32 dhd_hdrpulls; uint32 generic_error; /* an extra one for bc/mc traffic */ - uint32 send_pkts[AC_COUNT + 1]; + uint32 sendq_pkts[AC_COUNT + 1]; #ifdef PROP_TXSTATUS_DEBUG /* all pkt2bus -> txstatus latency accumulated */ uint32 latency_sample_count; @@ -241,6 +238,8 @@ typedef struct athost_wl_status_info { /* Credit borrow counts for each FIFO from each of the other FIFOs */ int credits_borrowed[AC_COUNT + 2][AC_COUNT + 2]; + struct pktq SENDQ; + /* packet hanger and MAC->handle lookup table */ void* hanger; struct { @@ -275,6 +274,7 @@ typedef struct athost_wl_status_info { /* Timestamp to compute how long to defer borrowing for */ uint32 borrow_defer_timestamp; + bool wlfc_locked; } athost_wl_status_info_t; int dhd_wlfc_enable(dhd_pub_t *dhd); @@ -285,13 +285,4 @@ int dhd_wlfc_event(struct dhd_info *dhd) int dhd_os_wlfc_block(dhd_pub_t *pub); int dhd_os_wlfc_unblock(dhd_pub_t *pub); -void dhd_wlfc_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf); -int dhd_wlfc_init(dhd_pub_t *dhd); -void dhd_wlfc_deinit(dhd_pub_t *dhd); -int dhd_wlfc_parse_header_info(dhd_pub_t *dhd, void* pktbuf, int tlv_hdr_len, - uchar *reorder_info_buf, uint *reorder_info_len); -int dhd_wlfc_commit_packets(void* state, f_commitpkt_t fcommit, - void* commit_ctx, void *pktbuf); -void dhd_wlfc_cleanup(dhd_pub_t *dhd, ifpkt_cb_t fn, int arg); -bool ifpkt_fn(void* p, int ifid); #endif /* __wlfc_host_driver_definitions_h__ */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/dngl_stats.h linux-sunxi-new/drivers/net/wireless/bcmdhd/dngl_stats.h --- linux-sunxi/drivers/net/wireless/bcmdhd/dngl_stats.h 2014-01-27 01:30:30.108433411 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/dngl_stats.h 2014-02-15 00:43:44.795014136 +0100 @@ -2,7 +2,7 @@ * Common stats definitions for clients of dongle * ports * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/dngl_wlhdr.h linux-sunxi-new/drivers/net/wireless/bcmdhd/dngl_wlhdr.h --- linux-sunxi/drivers/net/wireless/bcmdhd/dngl_wlhdr.h 2014-01-27 01:30:30.100433249 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/dngl_wlhdr.h 2014-02-15 00:43:44.792014069 +0100 @@ -1,7 +1,7 @@ /* * Dongle WL Header definitions * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/hndpmu.c linux-sunxi-new/drivers/net/wireless/bcmdhd/hndpmu.c --- linux-sunxi/drivers/net/wireless/bcmdhd/hndpmu.c 2014-01-27 01:30:30.108433411 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/hndpmu.c 2014-02-15 00:43:44.795014136 +0100 @@ -2,7 +2,7 @@ * Misc utility routines for accessing PMU corerev specific features * of the SiliconBackplane-based Broadcom chips. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -22,16 +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: hndpmu.c 414368 2013-07-24 15:00:23Z $ - */ - -/* - * Note: this file contains PLL/FLL related functions. A chip can contain multiple PLLs/FLLs. - * However, in the context of this file the baseband ('BB') PLL/FLL is referred to. - * - * Throughout this code, the prefixes 'pmu0_', 'pmu1_' and 'pmu2_' are used. - * They refer to different revisions of the PMU (which is at revision 18 @ Apr 25, 2012) - * pmu2_ marks the transition from PLL to ADFLL (Digital Frequency Locked Loop) + * $Id: hndpmu.c 354194 2012-08-30 08:39:03Z $ */ #include @@ -125,54 +116,16 @@ static const sdiod_drive_str_t sdiod_dri {1, 0x1}, {0, 0x0} }; - -/* - * SDIO Drive Strength to sel value table for 43143 PMU Rev 17, see Confluence 43143 Toplevel - * architecture page, section 'PMU Chip Control 1 Register definition', click link to picture - * BCM43143_sel_sdio_signals.jpg. Valid after PMU Chip Control 0 Register, bit31 (override) has - * been written '1'. - */ -#if !defined(BCM_SDIO_VDDIO) || BCM_SDIO_VDDIO == 33 - -static const sdiod_drive_str_t sdiod_drive_strength_tab7_3v3[] = { - /* note: for 14, 10, 6 and 2mA hw timing is not met according to rtl team */ - {16, 0x7}, - {12, 0x5}, - {8, 0x3}, - {4, 0x1} }; /* note: 43143 does not support tristate */ - -#else - -static const sdiod_drive_str_t sdiod_drive_strength_tab7_1v8[] = { - /* note: for 7, 5, 3 and 1mA hw timing is not met according to rtl team */ - {8, 0x7}, - {6, 0x5}, - {4, 0x3}, - {2, 0x1} }; /* note: 43143 does not support tristate */ - -#endif /* BCM_SDIO_VDDIO */ - #define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu)) -/** - * Balance between stable SDIO operation and power consumption is achieved using this function. - * Note that each drive strength table is for a specific VDDIO of the SDIO pads, ideally this - * function should read the VDDIO itself to select the correct table. For now it has been solved - * with the 'BCM_SDIO_VDDIO' preprocessor constant. - * - * 'drivestrength': desired pad drive strength in mA. Drive strength of 0 requests tri-state (if - * hardware supports this), if no hw support drive strength is not programmed. - */ void si_sdiod_drive_strength_init(si_t *sih, osl_t *osh, uint32 drivestrength) { chipcregs_t *cc; uint origidx, intr_val = 0; sdiod_drive_str_t *str_tab = NULL; - uint32 str_mask = 0; /* only alter desired bits in PMU chipcontrol 1 register */ + uint32 str_mask = 0; uint32 str_shift = 0; - uint32 str_ovr_pmuctl = PMU_CHIPCTL0; /* PMU chipcontrol register containing override bit */ - uint32 str_ovr_pmuval = 0; /* position of bit within this register */ if (!(sih->cccaps & CC_CAP_PMU)) { return; @@ -220,22 +173,10 @@ si_sdiod_drive_strength_init(si_t *sih, str_mask = 0x00001800; str_shift = 11; break; - case SDIOD_DRVSTR_KEY(BCM43143_CHIP_ID, 17): -#if !defined(BCM_SDIO_VDDIO) || BCM_SDIO_VDDIO == 33 - if (drivestrength >= ARRAYLAST(sdiod_drive_strength_tab7_3v3)->strength) { - str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab7_3v3; - } -#else - if (drivestrength >= ARRAYLAST(sdiod_drive_strength_tab7_1v8)->strength) { - str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab7_1v8; - } -#endif /* BCM_SDIO_VDDIO */ - str_mask = 0x00000007; - str_ovr_pmuval = PMU43143_CC0_SDIO_DRSTR_OVR; - break; default: PMU_MSG(("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n", bcm_chipname(sih->chip, chn, 8), sih->chiprev, sih->pmurev)); + break; } @@ -252,19 +193,16 @@ si_sdiod_drive_strength_init(si_t *sih, if (i > 0 && drivestrength > str_tab[i].strength) i--; - W_REG(osh, &cc->chipcontrol_addr, PMU_CHIPCTL1); + W_REG(osh, &cc->chipcontrol_addr, 1); cc_data_temp = R_REG(osh, &cc->chipcontrol_data); cc_data_temp &= ~str_mask; cc_data_temp |= str_tab[i].sel << str_shift; W_REG(osh, &cc->chipcontrol_data, cc_data_temp); - if (str_ovr_pmuval) { /* enables the selected drive strength */ - W_REG(osh, &cc->chipcontrol_addr, str_ovr_pmuctl); - OR_REG(osh, &cc->chipcontrol_data, str_ovr_pmuval); - } + PMU_MSG(("SDIO: %dmA drive strength requested; set to %dmA\n", drivestrength, str_tab[i].strength)); } /* Return to original core */ si_restore_core(sih, origidx, intr_val); -} /* si_sdiod_drive_strength_init */ +} diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/aidmp.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/aidmp.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/aidmp.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/aidmp.h 2014-02-15 00:43:44.794014114 +0100 @@ -1,7 +1,7 @@ /* * Broadcom AMBA Interconnect definitions. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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: aidmp.h 385510 2013-02-15 21:02:07Z $ + * $Id: aidmp.h 241182 2011-02-17 21:50:03Z $ */ #ifndef _AIDMP_H @@ -372,15 +372,4 @@ typedef volatile struct _aidmp { #define OOB_SEL_OUTEN_B_5 15 #define OOB_SEL_OUTEN_B_6 23 -/* AI_OOBSEL for A/B/C/D, 0-7 */ -#define AI_OOBSEL_MASK 0x1F -#define AI_OOBSEL_0_SHIFT 0 -#define AI_OOBSEL_1_SHIFT 8 -#define AI_OOBSEL_2_SHIFT 16 -#define AI_OOBSEL_3_SHIFT 24 -#define AI_OOBSEL_4_SHIFT 0 -#define AI_OOBSEL_5_SHIFT 8 -#define AI_OOBSEL_6_SHIFT 16 -#define AI_OOBSEL_7_SHIFT 24 - #endif /* _AIDMP_H */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/bcmcdc.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcmcdc.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/bcmcdc.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcmcdc.h 2014-02-15 00:43:44.794014114 +0100 @@ -4,7 +4,7 @@ * * Definitions subject to change without notice. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/bcm_cfg.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcm_cfg.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/bcm_cfg.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcm_cfg.h 2014-02-15 00:43:44.794014114 +0100 @@ -1,7 +1,7 @@ /* * BCM common config options * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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: bcm_cfg.h 351867 2012-08-21 18:46:16Z $ + * $Id: bcm_cfg.h 294399 2011-11-07 03:31:22Z $ */ #ifndef _bcm_cfg_h_ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/bcmdefs.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcmdefs.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/bcmdefs.h 2014-01-27 01:30:30.101433269 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcmdefs.h 2014-02-15 00:43:44.793014092 +0100 @@ -1,7 +1,7 @@ /* * Misc system wide definitions * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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: bcmdefs.h 416231 2013-08-02 07:38:34Z $ + * $Id: bcmdefs.h 316830 2012-02-23 20:29:22Z $ */ #ifndef _bcmdefs_h_ @@ -65,22 +65,9 @@ #define BCMNMIATTACHFN(_fn) _fn #define BCMNMIATTACHDATA(_data) _data #define CONST const - -/* Do not put BCM47XX and __ARM_ARCH_7A__ to the same line. - * DHD build has problem because the BCM47XX will be excluded in DHD release. - */ -#undef BCM47XX_CA9 -#ifdef __ARM_ARCH_7A__ -#define BCM47XX_CA9 -#endif /* __ARM_ARCH_7A__ */ #ifndef BCMFASTPATH -#if defined(BCM47XX_CA9) -#define BCMFASTPATH __attribute__ ((__section__ (".text.fastpath"))) -#define BCMFASTPATH_HOST __attribute__ ((__section__ (".text.fastpath_host"))) -#else #define BCMFASTPATH #define BCMFASTPATH_HOST -#endif #endif /* BCMFASTPATH */ @@ -206,13 +193,9 @@ typedef struct { #if defined(BCM_RPC_NOCOPY) || defined(BCM_RCP_TXNOCOPY) /* add 40 bytes to allow for extra RPC header and info */ -#define BCMEXTRAHDROOM 260 +#define BCMEXTRAHDROOM 220 #else /* BCM_RPC_NOCOPY || BCM_RPC_TXNOCOPY */ -#if defined(BCM47XX_CA9) -#define BCMEXTRAHDROOM 224 -#else -#define BCMEXTRAHDROOM 204 -#endif /* linux && BCM47XX_CA9 */ +#define BCMEXTRAHDROOM 172 #endif /* BCM_RPC_NOCOPY || BCM_RPC_TXNOCOPY */ /* Packet alignment for most efficient SDIO (can change based on platform) */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/bcmdevs.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcmdevs.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/bcmdevs.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcmdevs.h 2014-02-15 00:43:44.794014114 +0100 @@ -1,7 +1,7 @@ /* * Broadcom device-specific manifest constants. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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: bcmdevs.h 414368 2013-07-24 15:00:23Z $ + * $Id: bcmdevs.h 329854 2012-04-27 01:42:28Z $ */ #ifndef _BCMDEVS_H @@ -63,12 +63,6 @@ #define BCM_DNGL_BL_PID_43239 0xbd1b #define BCM_DNGL_BL_PID_4324 0xbd1c #define BCM_DNGL_BL_PID_4360 0xbd1d -#define BCM_DNGL_BL_PID_43143 0xbd1e -#define BCM_DNGL_BL_PID_43242 0xbd1f -#define BCM_DNGL_BL_PID_43342 0xbd21 -#define BCM_DNGL_BL_PID_4335 0xbd20 -#define BCM_DNGL_BL_PID_4350 0xbd23 -#define BCM_DNGL_BL_PID_43341 0xbd22 #define BCM_DNGL_BDC_PID 0x0bdc #define BCM_DNGL_JTAG_PID 0x4a44 @@ -137,8 +131,6 @@ #define BCM4330_D11N5G_ID 0x4362 /* 4330 802.11n 5G device */ #define BCM4336_D11N_ID 0x4343 /* 4336 802.11n 2.4GHz device */ #define BCM6362_D11N_ID 0x435f /* 6362 802.11n dualband device */ -#define BCM6362_D11N2G_ID 0x433f /* 6362 802.11n 2.4Ghz band id */ -#define BCM6362_D11N5G_ID 0x434f /* 6362 802.11n 5Ghz band id */ #define BCM4331_D11N_ID 0x4331 /* 4331 802.11n dualband id */ #define BCM4331_D11N2G_ID 0x4332 /* 4331 802.11n 2.4Ghz band id */ #define BCM4331_D11N5G_ID 0x4333 /* 4331 802.11n 5Ghz band id */ @@ -154,42 +146,28 @@ #define BCM43131_D11N2G_ID 0x43aa /* 43131 802.11n 2.4GHz device */ #define BCM4314_D11N2G_ID 0x4364 /* 4314 802.11n 2.4G device */ #define BCM43142_D11N2G_ID 0x4365 /* 43142 802.11n 2.4G device */ -#define BCM43143_D11N2G_ID 0x4366 /* 43143 802.11n 2.4G device */ #define BCM4334_D11N_ID 0x4380 /* 4334 802.11n dualband device */ #define BCM4334_D11N2G_ID 0x4381 /* 4334 802.11n 2.4G device */ #define BCM4334_D11N5G_ID 0x4382 /* 4334 802.11n 5G device */ -#define BCM43342_D11N_ID 0x4383 /* 43342 802.11n dualband device */ -#define BCM43342_D11N2G_ID 0x4384 /* 43342 802.11n 2.4G device */ -#define BCM43342_D11N5G_ID 0x4385 /* 43342 802.11n 5G device */ #define BCM43341_D11N_ID 0x4386 /* 43341 802.11n dualband device */ #define BCM43341_D11N2G_ID 0x4387 /* 43341 802.11n 2.4G device */ #define BCM43341_D11N5G_ID 0x4388 /* 43341 802.11n 5G device */ #define BCM4360_D11AC_ID 0x43a0 #define BCM4360_D11AC2G_ID 0x43a1 #define BCM4360_D11AC5G_ID 0x43a2 -#define BCM4335_D11AC_ID 0x43ae -#define BCM4335_D11AC2G_ID 0x43af -#define BCM4335_D11AC5G_ID 0x43b0 -#define BCM4352_D11AC_ID 0x43b1 /* 4352 802.11ac dualband device */ -#define BCM4352_D11AC2G_ID 0x43b2 /* 4352 802.11ac 2.4G device */ -#define BCM4352_D11AC5G_ID 0x43b3 /* 4352 802.11ac 5G device */ /* PCI Subsystem ID */ #define BCM943228HMB_SSID_VEN1 0x0607 #define BCM94313HMGBL_SSID_VEN1 0x0608 #define BCM94313HMG_SSID_VEN1 0x0609 -#define BCM943142HM_SSID_VEN1 0x0611 - -#define BCM43143_D11N2G_ID 0x4366 /* 43143 802.11n 2.4G device */ - -#define BCM43242_D11N_ID 0x4367 /* 43242 802.11n dualband device */ -#define BCM43242_D11N2G_ID 0x4368 /* 43242 802.11n 2.4G device */ -#define BCM43242_D11N5G_ID 0x4369 /* 43242 802.11n 5G device */ -#define BCM4350_D11AC_ID 0x43a3 -#define BCM4350_D11AC2G_ID 0x43a4 -#define BCM4350_D11AC5G_ID 0x43a5 +#define BCM4335_D11AC_ID 0x43ae +#define BCM4335_D11AC2G_ID 0x43af +#define BCM4335_D11AC5G_ID 0x43b0 +#define BCM4352_D11AC_ID 0x43b1 /* 4352 802.11ac dualband device */ +#define BCM4352_D11AC2G_ID 0x43b2 /* 4352 802.11ac 2.4G device */ +#define BCM4352_D11AC5G_ID 0x43b3 /* 4352 802.11ac 5G device */ #define BCMGPRS_UART_ID 0x4333 /* Uart id used by 4306/gprs card */ #define BCMGPRS2_UART_ID 0x4344 /* Uart id used by 4306/gprs card */ @@ -227,8 +205,6 @@ #define BCM47XX_GIGETH_ID 0x471f /* 47xx GbE (5700) */ #define BCM4712_MIPS_ID 0x4720 /* 4712 base devid */ #define BCM4716_DEVICE_ID 0x4722 /* 4716 base devid */ -#define BCM47XX_USB30H_ID 0x472a /* 47xx usb 3.0 host */ -#define BCM47XX_USB30D_ID 0x472b /* 47xx usb 3.0 device */ #define BCM47XX_SMBUS_EMU_ID 0x47fe /* 47xx emulated SMBus device */ #define BCM47XX_XOR_EMU_ID 0x47ff /* 47xx emulated XOR engine */ #define EPI41210_DEVICE_ID 0xa0fa /* bcm4210 */ @@ -284,28 +260,21 @@ #define BCM6362_CHIP_ID 0x6362 /* 6362 chipcommon chipid */ #define BCM4314_CHIP_ID 0x4314 /* 4314 chipcommon chipid */ #define BCM43142_CHIP_ID 43142 /* 43142 chipcommon chipid */ -#define BCM43143_CHIP_ID 43143 /* 43143 chipcommon chipid */ #define BCM4324_CHIP_ID 0x4324 /* 4324 chipcommon chipid */ #define BCM43242_CHIP_ID 43242 /* 43242 chipcommon chipid */ -#define BCM43243_CHIP_ID 43243 /* 43243 chipcommon chipid */ #define BCM4334_CHIP_ID 0x4334 /* 4334 chipcommon chipid */ -#define BCM4335_CHIP_ID 0x4335 /* 4335 chipcommon chipid */ -#define BCM4339_CHIP_ID 0x4339 /* 4339 chipcommon chipid */ #define BCM4360_CHIP_ID 0x4360 /* 4360 chipcommon chipid */ #define BCM4352_CHIP_ID 0x4352 /* 4352 chipcommon chipid */ #define BCM43526_CHIP_ID 0xAA06 -#define BCM43340_CHIP_ID 43340 /* 43340 chipcommon chipid */ #define BCM43341_CHIP_ID 43341 /* 43341 chipcommon chipid */ #define BCM43342_CHIP_ID 43342 /* 43342 chipcommon chipid */ -#define BCM4350_CHIP_ID 0x4350 /* 4350 chipcommon chipid */ + +#define BCM4335_CHIP_ID 0x4335 #define BCM4342_CHIP_ID 4342 /* 4342 chipcommon chipid (OTP, RBBU) */ #define BCM4402_CHIP_ID 0x4402 /* 4402 chipid */ #define BCM4704_CHIP_ID 0x4704 /* 4704 chipcommon chipid */ #define BCM4706_CHIP_ID 0x5300 /* 4706 chipcommon chipid */ -#define BCM4707_CHIP_ID 53010 /* 4707 chipcommon chipid */ -#define BCM53018_CHIP_ID 53018 /* 53018 chipcommon chipid */ -#define BCM4707_CHIP(chipid) (((chipid) == BCM4707_CHIP_ID) || ((chipid) == BCM53018_CHIP_ID)) #define BCM4710_CHIP_ID 0x4710 /* 4710 chipid */ #define BCM4712_CHIP_ID 0x4712 /* 4712 chipcommon chipid */ #define BCM4716_CHIP_ID 0x4716 /* 4716 chipcommon chipid */ @@ -367,38 +336,27 @@ #define BCM4314SDIO_FPBGA_PKG_ID (8 | 4) /* 4314 FpBGA SDIO package id */ #define BCM4314DEV_PKG_ID (8 | 6) /* 4314 Developement package id */ -#define BCM4707_PKG_ID 1 /* 4707 package id */ -#define BCM4708_PKG_ID 2 /* 4708 package id */ -#define BCM4709_PKG_ID 0 /* 4709 package id */ - #define PCIXX21_FLASHMEDIA0_ID 0x8033 /* TI PCI xx21 Standard Host Controller */ #define PCIXX21_SDIOH0_ID 0x8034 /* TI PCI xx21 Standard Host Controller */ -#define BCM4335_WLCSP_PKG_ID (0x0) /* WLCSP Module/Mobile SDIO/HSIC. */ -#define BCM4335_FCBGA_PKG_ID (0x1) /* FCBGA PC/Embeded/Media PCIE/SDIO */ -#define BCM4335_WLBGA_PKG_ID (0x2) /* WLBGA COB/Mobile SDIO/HSIC. */ -#define BCM4335_FCBGAD_PKG_ID (0x3) /* FCBGA Debug Debug/Dev All if's. */ -#define BCM4335_PKG_MASK (0x3) - /* boardflags */ #define BFL_BTC2WIRE 0x00000001 /* old 2wire Bluetooth coexistence, OBSOLETE */ #define BFL_BTCOEX 0x00000001 /* Board supports BTCOEX */ #define BFL_PACTRL 0x00000002 /* Board has gpio 9 controlling the PA */ #define BFL_AIRLINEMODE 0x00000004 /* Board implements gpio 13 radio disable indication, UNUSED */ #define BFL_ADCDIV 0x00000008 /* Board has the rssi ADC divider */ -#define BFL_DIS_256QAM 0x00000008 +#define BFL_RFPLL 0x00000008 /* ACPHY: Changing RFPLL BW to be 150 MHz */ #define BFL_ENETROBO 0x00000010 /* Board has robo switch or core */ #define BFL_NOPLLDOWN 0x00000020 /* Not ok to power down the chip pll and oscillator */ #define BFL_CCKHIPWR 0x00000040 /* Can do high-power CCK transmission */ #define BFL_ENETADM 0x00000080 /* Board has ADMtek switch */ #define BFL_ENETVLAN 0x00000100 /* Board has VLAN capability */ -#define BFL_LTECOEX 0x00000200 /* Board has LTE coex capability */ +#define BFL_UNUSED 0x00000200 #define BFL_NOPCI 0x00000400 /* Board leaves PCI floating */ #define BFL_FEM 0x00000800 /* Board supports the Front End Module */ #define BFL_EXTLNA 0x00001000 /* Board has an external LNA in 2.4GHz band */ #define BFL_HGPA 0x00002000 /* Board has a high gain PA */ -#define BFL_BTC2WIRE_ALTGPIO 0x00004000 -/* Board's BTC 2wire is in the alternate gpios OBSLETE */ +#define BFL_BTC2WIRE_ALTGPIO 0x00004000 /* Board's BTC 2wire is in the alternate gpios */ #define BFL_ALTIQ 0x00008000 /* Alternate I/Q settings */ #define BFL_NOPA 0x00010000 /* Board has no PA */ #define BFL_RSSIINV 0x00020000 /* Board's RSSI uses positive slope(not TSSI) */ @@ -407,7 +365,6 @@ #define BFL_PHASESHIFT 0x00100000 /* Board can support phase shifter */ #define BFL_BUCKBOOST 0x00200000 /* Power topology uses BUCKBOOST */ #define BFL_FEM_BT 0x00400000 /* Board has FEM and switch to share antenna w/ BT */ -#define BFL_RXCHAIN_OFF_BT 0x00400000 /* one rxchain is to be shut off when BT is active */ #define BFL_NOCBUCK 0x00800000 /* Power topology doesn't use CBUCK */ #define BFL_CCKFAVOREVM 0x01000000 /* Favor CCK EVM over spectral mask */ #define BFL_PALDO 0x02000000 /* Power topology uses PALDO */ @@ -416,7 +373,6 @@ #define BFL_UCPWRCTL_MININDX 0x08000000 /* Enforce min power index to avoid FEM damage */ #define BFL_EXTLNA_5GHz 0x10000000 /* Board has an external LNA in 5GHz band */ #define BFL_TRSW_1by2 0x20000000 /* Board has 2 TRSW's in 1by2 designs */ -#define BFL_GAINBOOSTA01 0x20000000 /* 5g Gainboost for core0 and core1 */ #define BFL_LO_TRSW_R_5GHz 0x40000000 /* In 5G do not throw TRSW to T for clipLO gain */ #define BFL_ELNA_GAINDEF 0x80000000 /* Backoff InitGain based on elna_2g/5g field * when this flag is set @@ -453,8 +409,7 @@ #define BFL2_ANAPACTRL_2G 0x00100000 /* 2G ext PAs are controlled by analog PA ctrl lines */ #define BFL2_ANAPACTRL_5G 0x00200000 /* 5G ext PAs are controlled by analog PA ctrl lines */ #define BFL2_ELNACTRL_TRSW_2G 0x00400000 /* AZW4329: 2G gmode_elna_gain controls TR Switch */ -#define BFL2_BT_SHARE_ANT0 0x00800000 /* WLAN/BT share antenna 0 */ -#define BFL2_BT_SHARE_BM_BIT0 0x00800000 /* bit 0 of WLAN/BT shared core bitmap */ +#define BFL2_BT_SHARE_ANT0 0x00800000 /* share core0 antenna with BT */ #define BFL2_TEMPSENSE_HIGHER 0x01000000 /* The tempsense threshold can sustain higher value * than programmed. The exact delta is decided by * driver per chip/boardtype. This can be used @@ -466,46 +421,7 @@ /* ucode control of eLNA during Tx */ #define BFL2_4313_RADIOREG 0x10000000 /* board rework */ -#define BFL2_DYNAMIC_VMID 0x10000000 /* boardflag to enable dynamic Vmid idle TSSI CAL */ -#define BFL2_SDR_EN 0x20000000 /* SDR enabled or disabled */ -#define BFL2_LNA1BYPFORTR2G 0x40000000 /* acphy, enable lna1 bypass for clip gain, 2g */ -#define BFL2_LNA1BYPFORTR5G 0x80000000 /* acphy, enable lna1 bypass for clip gain, 5g */ - -/* SROM 11 - 11ac boardflag definitions */ -#define BFL_SROM11_BTCOEX 0x00000001 /* Board supports BTCOEX */ -#define BFL_SROM11_WLAN_BT_SH_XTL 0x00000002 /* bluetooth and wlan share same crystal */ -#define BFL_SROM11_EXTLNA 0x00001000 /* Board has an external LNA in 2.4GHz band */ -#define BFL_SROM11_EXTLNA_5GHz 0x10000000 /* Board has an external LNA in 5GHz band */ -#define BFL_SROM11_GAINBOOSTA01 0x20000000 /* 5g Gainboost for core0 and core1 */ -#define BFL2_SROM11_APLL_WAR 0x00000002 /* Flag to implement alternative A-band PLL settings */ -#define BFL2_SROM11_ANAPACTRL_2G 0x00100000 /* 2G ext PAs are ctrl-ed by analog PA ctrl lines */ -#define BFL2_SROM11_ANAPACTRL_5G 0x00200000 /* 5G ext PAs are ctrl-ed by analog PA ctrl lines */ - -/* boardflags3 */ -#define BFL3_FEMCTRL_SUB 0x00000007 /* acphy, subrevs of femctrl on top of srom_femctrl */ -#define BFL3_RCAL_WAR 0x00000008 /* acphy, rcal war active on this board (4335a0) */ -#define BFL3_TXGAINTBLID 0x00000070 /* acphy, txgain table id */ -#define BFL3_TXGAINTBLID_SHIFT 0x4 /* acphy, txgain table id shift bit */ -#define BFL3_TSSI_DIV_WAR 0x00000080 /* acphy, Seperate paparam for 20/40/80 */ -#define BFL3_TSSI_DIV_WAR_SHIFT 0x7 /* acphy, Seperate paparam for 20/40/80 shift bit */ -#define BFL3_FEMTBL_FROM_NVRAM 0x00000100 /* acphy, femctrl table is read from nvram */ -#define BFL3_FEMTBL_FROM_NVRAM_SHIFT 0x8 /* acphy, femctrl table is read from nvram */ -#define BFL3_AGC_CFG_2G 0x00000200 /* acphy, gain control configuration for 2G */ -#define BFL3_AGC_CFG_5G 0x00000400 /* acphy, gain control configuration for 5G */ -#define BFL3_PPR_BIT_EXT 0x00000800 /* acphy, bit position for 1bit extension for ppr */ -#define BFL3_PPR_BIT_EXT_SHIFT 11 /* acphy, bit shift for 1bit extension for ppr */ -#define BFL3_BBPLL_SPR_MODE_DIS 0x00001000 /* acphy, disables bbpll spur modes */ -#define BFL3_RCAL_OTP_VAL_EN 0x00002000 /* acphy, to read rcal_trim value from otp */ -#define BFL3_2GTXGAINTBL_BLANK 0x00004000 /* acphy, blank the first X ticks of 2g gaintbl */ -#define BFL3_2GTXGAINTBL_BLANK_SHIFT 14 /* acphy, blank the first X ticks of 2g gaintbl */ -#define BFL3_5GTXGAINTBL_BLANK 0x00008000 /* acphy, blank the first X ticks of 5g gaintbl */ -#define BFL3_5GTXGAINTBL_BLANK_SHIFT 15 /* acphy, blank the first X ticks of 5g gaintbl */ -#define BFL3_BT_SHARE_BM_BIT1 0x40000000 /* bit 1 of WLAN/BT shared core bitmap */ -#define BFL3_PHASETRACK_MAX_ALPHABETA 0x00010000 /* acphy, to max out alpha,beta to 511 */ -#define BFL3_PHASETRACK_MAX_ALPHABETA_SHIFT 16 /* acphy, to max out alpha,beta to 511 */ -#define BFL3_BT_SHARE_BM_BIT1 0x40000000 /* bit 1 of WLAN/BT shared core bitmap */ -#define BFL3_EN_NONBRCM_TXBF 0x10000000 /* acphy, enable non-brcm TXBF */ -#define BFL3_EN_P2PLINK_TXBF 0x20000000 /* acphy, enable TXBF in p2p links */ +#define BFL2_SDR_EN 0x20000000 /* SDR enabled or disabled */ /* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */ #define BOARD_GPIO_BTC3W_IN 0x850 /* bit 4 is RF_ACTIVE, bit 6 is STATUS, bit 11 is PRI */ @@ -548,9 +464,6 @@ /* 43341 Boards */ #define BCM943341WLABGS_SSID 0x062d -/* 43342 Boards */ -#define BCM943342FCAGBI_SSID 0x0641 - /* # of GPIO pins */ #define GPIO_NUMPINS 32 @@ -565,18 +478,8 @@ #define RDL_RAM_BASE_4328 0x80000000 #define RDL_RAM_SIZE_4322 0x60000 #define RDL_RAM_BASE_4322 0x60000000 -#define RDL_RAM_SIZE_4360 0xA0000 -#define RDL_RAM_BASE_4360 0x60000000 -#define RDL_RAM_SIZE_43242 0x90000 -#define RDL_RAM_BASE_43242 0x60000000 -#define RDL_RAM_SIZE_43143 0x70000 -#define RDL_RAM_BASE_43143 0x60000000 -#define RDL_RAM_SIZE_4350 0xC0000 -#define RDL_RAM_BASE_4350 0x180800 - -/* generic defs for nvram "muxenab" bits -* Note: these differ for 4335a0. refer bcmchipc.h for specific mux options. -*/ + +/* generic defs for nvram "muxenab" bits */ #define MUXENAB_UART 0x00000001 #define MUXENAB_GPIO 0x00000002 #define MUXENAB_ERCX 0x00000004 /* External Radio BT coex */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/bcmendian.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcmendian.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/bcmendian.h 2014-01-27 01:30:30.101433269 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcmendian.h 2014-02-15 00:43:44.793014092 +0100 @@ -1,7 +1,7 @@ /* * Byte order utilities * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/bcm_mpool_pub.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcm_mpool_pub.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/bcm_mpool_pub.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcm_mpool_pub.h 2014-02-15 00:43:44.795014136 +0100 @@ -35,7 +35,7 @@ * and instrumentation on top of the heap, without modifying the heap * allocation implementation. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/bcmpcispi.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcmpcispi.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/bcmpcispi.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcmpcispi.h 2014-02-15 00:43:44.793014092 +0100 @@ -0,0 +1,181 @@ +/* + * Broadcom PCI-SPI Host Controller Register 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: bcmpcispi.h 241182 2011-02-17 21:50:03Z $ + */ +#ifndef _BCM_PCI_SPI_H +#define _BCM_PCI_SPI_H + +/* cpp contortions to concatenate w/arg prescan */ +#ifndef PAD +#define _PADLINE(line) pad ## line +#define _XSTR(line) _PADLINE(line) +#define PAD _XSTR(__LINE__) +#endif /* PAD */ + + +typedef volatile struct { + uint32 spih_ctrl; /* 0x00 SPI Control Register */ + uint32 spih_stat; /* 0x04 SPI Status Register */ + uint32 spih_data; /* 0x08 SPI Data Register, 32-bits wide */ + uint32 spih_ext; /* 0x0C SPI Extension Register */ + uint32 PAD[4]; /* 0x10-0x1F PADDING */ + + uint32 spih_gpio_ctrl; /* 0x20 SPI GPIO Control Register */ + uint32 spih_gpio_data; /* 0x24 SPI GPIO Data Register */ + uint32 PAD[6]; /* 0x28-0x3F PADDING */ + + uint32 spih_int_edge; /* 0x40 SPI Interrupt Edge Register (0=Level, 1=Edge) */ + uint32 spih_int_pol; /* 0x44 SPI Interrupt Polarity Register (0=Active Low, */ + /* 1=Active High) */ + uint32 spih_int_mask; /* 0x48 SPI Interrupt Mask */ + uint32 spih_int_status; /* 0x4C SPI Interrupt Status */ + uint32 PAD[4]; /* 0x50-0x5F PADDING */ + + uint32 spih_hex_disp; /* 0x60 SPI 4-digit hex display value */ + uint32 spih_current_ma; /* 0x64 SPI SD card current consumption in mA */ + uint32 PAD[1]; /* 0x68 PADDING */ + uint32 spih_disp_sel; /* 0x6c SPI 4-digit hex display mode select (1=current) */ + uint32 PAD[4]; /* 0x70-0x7F PADDING */ + uint32 PAD[8]; /* 0x80-0x9F PADDING */ + uint32 PAD[8]; /* 0xA0-0xBF PADDING */ + uint32 spih_pll_ctrl; /* 0xC0 PLL Control Register */ + uint32 spih_pll_status; /* 0xC4 PLL Status Register */ + uint32 spih_xtal_freq; /* 0xC8 External Clock Frequency in units of 10000Hz */ + uint32 spih_clk_count; /* 0xCC External Clock Count Register */ + +} spih_regs_t; + +typedef volatile struct { + uint32 cfg_space[0x40]; /* 0x000-0x0FF PCI Configuration Space (Read Only) */ + uint32 P_IMG_CTRL0; /* 0x100 PCI Image0 Control Register */ + + uint32 P_BA0; /* 0x104 32 R/W PCI Image0 Base Address register */ + uint32 P_AM0; /* 0x108 32 R/W PCI Image0 Address Mask register */ + uint32 P_TA0; /* 0x10C 32 R/W PCI Image0 Translation Address register */ + uint32 P_IMG_CTRL1; /* 0x110 32 R/W PCI Image1 Control register */ + uint32 P_BA1; /* 0x114 32 R/W PCI Image1 Base Address register */ + uint32 P_AM1; /* 0x118 32 R/W PCI Image1 Address Mask register */ + uint32 P_TA1; /* 0x11C 32 R/W PCI Image1 Translation Address register */ + uint32 P_IMG_CTRL2; /* 0x120 32 R/W PCI Image2 Control register */ + uint32 P_BA2; /* 0x124 32 R/W PCI Image2 Base Address register */ + uint32 P_AM2; /* 0x128 32 R/W PCI Image2 Address Mask register */ + uint32 P_TA2; /* 0x12C 32 R/W PCI Image2 Translation Address register */ + uint32 P_IMG_CTRL3; /* 0x130 32 R/W PCI Image3 Control register */ + uint32 P_BA3; /* 0x134 32 R/W PCI Image3 Base Address register */ + uint32 P_AM3; /* 0x138 32 R/W PCI Image3 Address Mask register */ + uint32 P_TA3; /* 0x13C 32 R/W PCI Image3 Translation Address register */ + uint32 P_IMG_CTRL4; /* 0x140 32 R/W PCI Image4 Control register */ + uint32 P_BA4; /* 0x144 32 R/W PCI Image4 Base Address register */ + uint32 P_AM4; /* 0x148 32 R/W PCI Image4 Address Mask register */ + uint32 P_TA4; /* 0x14C 32 R/W PCI Image4 Translation Address register */ + uint32 P_IMG_CTRL5; /* 0x150 32 R/W PCI Image5 Control register */ + uint32 P_BA5; /* 0x154 32 R/W PCI Image5 Base Address register */ + uint32 P_AM5; /* 0x158 32 R/W PCI Image5 Address Mask register */ + uint32 P_TA5; /* 0x15C 32 R/W PCI Image5 Translation Address register */ + uint32 P_ERR_CS; /* 0x160 32 R/W PCI Error Control and Status register */ + uint32 P_ERR_ADDR; /* 0x164 32 R PCI Erroneous Address register */ + uint32 P_ERR_DATA; /* 0x168 32 R PCI Erroneous Data register */ + + uint32 PAD[5]; /* 0x16C-0x17F PADDING */ + + uint32 WB_CONF_SPC_BAR; /* 0x180 32 R WISHBONE Configuration Space Base Address */ + uint32 W_IMG_CTRL1; /* 0x184 32 R/W WISHBONE Image1 Control register */ + uint32 W_BA1; /* 0x188 32 R/W WISHBONE Image1 Base Address register */ + uint32 W_AM1; /* 0x18C 32 R/W WISHBONE Image1 Address Mask register */ + uint32 W_TA1; /* 0x190 32 R/W WISHBONE Image1 Translation Address reg */ + uint32 W_IMG_CTRL2; /* 0x194 32 R/W WISHBONE Image2 Control register */ + uint32 W_BA2; /* 0x198 32 R/W WISHBONE Image2 Base Address register */ + uint32 W_AM2; /* 0x19C 32 R/W WISHBONE Image2 Address Mask register */ + uint32 W_TA2; /* 0x1A0 32 R/W WISHBONE Image2 Translation Address reg */ + uint32 W_IMG_CTRL3; /* 0x1A4 32 R/W WISHBONE Image3 Control register */ + uint32 W_BA3; /* 0x1A8 32 R/W WISHBONE Image3 Base Address register */ + uint32 W_AM3; /* 0x1AC 32 R/W WISHBONE Image3 Address Mask register */ + uint32 W_TA3; /* 0x1B0 32 R/W WISHBONE Image3 Translation Address reg */ + uint32 W_IMG_CTRL4; /* 0x1B4 32 R/W WISHBONE Image4 Control register */ + uint32 W_BA4; /* 0x1B8 32 R/W WISHBONE Image4 Base Address register */ + uint32 W_AM4; /* 0x1BC 32 R/W WISHBONE Image4 Address Mask register */ + uint32 W_TA4; /* 0x1C0 32 R/W WISHBONE Image4 Translation Address reg */ + uint32 W_IMG_CTRL5; /* 0x1C4 32 R/W WISHBONE Image5 Control register */ + uint32 W_BA5; /* 0x1C8 32 R/W WISHBONE Image5 Base Address register */ + uint32 W_AM5; /* 0x1CC 32 R/W WISHBONE Image5 Address Mask register */ + uint32 W_TA5; /* 0x1D0 32 R/W WISHBONE Image5 Translation Address reg */ + uint32 W_ERR_CS; /* 0x1D4 32 R/W WISHBONE Error Control and Status reg */ + uint32 W_ERR_ADDR; /* 0x1D8 32 R WISHBONE Erroneous Address register */ + uint32 W_ERR_DATA; /* 0x1DC 32 R WISHBONE Erroneous Data register */ + uint32 CNF_ADDR; /* 0x1E0 32 R/W Configuration Cycle register */ + uint32 CNF_DATA; /* 0x1E4 32 R/W Configuration Cycle Generation Data reg */ + + uint32 INT_ACK; /* 0x1E8 32 R Interrupt Acknowledge register */ + uint32 ICR; /* 0x1EC 32 R/W Interrupt Control register */ + uint32 ISR; /* 0x1F0 32 R/W Interrupt Status register */ +} spih_pciregs_t; + +/* + * PCI Core interrupt enable and status bit definitions. + */ + +/* PCI Core ICR Register bit definitions */ +#define PCI_INT_PROP_EN (1 << 0) /* Interrupt Propagation Enable */ +#define PCI_WB_ERR_INT_EN (1 << 1) /* Wishbone Error Interrupt Enable */ +#define PCI_PCI_ERR_INT_EN (1 << 2) /* PCI Error Interrupt Enable */ +#define PCI_PAR_ERR_INT_EN (1 << 3) /* Parity Error Interrupt Enable */ +#define PCI_SYS_ERR_INT_EN (1 << 4) /* System Error Interrupt Enable */ +#define PCI_SOFTWARE_RESET (1U << 31) /* Software reset of the PCI Core. */ + + +/* PCI Core ISR Register bit definitions */ +#define PCI_INT_PROP_ST (1 << 0) /* Interrupt Propagation Status */ +#define PCI_WB_ERR_INT_ST (1 << 1) /* Wishbone Error Interrupt Status */ +#define PCI_PCI_ERR_INT_ST (1 << 2) /* PCI Error Interrupt Status */ +#define PCI_PAR_ERR_INT_ST (1 << 3) /* Parity Error Interrupt Status */ +#define PCI_SYS_ERR_INT_ST (1 << 4) /* System Error Interrupt Status */ + + +/* Registers on the Wishbone bus */ +#define SPIH_CTLR_INTR (1 << 0) /* SPI Host Controller Core Interrupt */ +#define SPIH_DEV_INTR (1 << 1) /* SPI Device Interrupt */ +#define SPIH_WFIFO_INTR (1 << 2) /* SPI Tx FIFO Empty Intr (FPGA Rev >= 8) */ + +/* GPIO Bit definitions */ +#define SPIH_CS (1 << 0) /* SPI Chip Select (active low) */ +#define SPIH_SLOT_POWER (1 << 1) /* SD Card Slot Power Enable */ +#define SPIH_CARD_DETECT (1 << 2) /* SD Card Detect */ + +/* SPI Status Register Bit definitions */ +#define SPIH_STATE_MASK 0x30 /* SPI Transfer State Machine state mask */ +#define SPIH_STATE_SHIFT 4 /* SPI Transfer State Machine state shift */ +#define SPIH_WFFULL (1 << 3) /* SPI Write FIFO Full */ +#define SPIH_WFEMPTY (1 << 2) /* SPI Write FIFO Empty */ +#define SPIH_RFFULL (1 << 1) /* SPI Read FIFO Full */ +#define SPIH_RFEMPTY (1 << 0) /* SPI Read FIFO Empty */ + +#define SPIH_EXT_CLK (1U << 31) /* Use External Clock as PLL Clock source. */ + +#define SPIH_PLL_NO_CLK (1 << 1) /* Set to 1 if the PLL's input clock is lost. */ +#define SPIH_PLL_LOCKED (1 << 3) /* Set to 1 when the PLL is locked. */ + +/* Spin bit loop bound check */ +#define SPI_SPIN_BOUND 0xf4240 /* 1 million */ + +#endif /* _BCM_PCI_SPI_H */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/bcmperf.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcmperf.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/bcmperf.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcmperf.h 2014-02-15 00:43:44.794014114 +0100 @@ -1,7 +1,7 @@ /* * Performance counters software interface. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/bcmsdbus.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcmsdbus.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/bcmsdbus.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcmsdbus.h 2014-02-15 00:43:44.794014114 +0100 @@ -2,7 +2,7 @@ * Definitions for API from sdio common code (bcmsdh) to individual * host controller drivers. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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 408155 2013-06-17 21:52:27Z $ + * $Id: bcmsdbus.h 347614 2012-07-27 10:24:51Z $ */ #ifndef _sdio_api_h_ @@ -48,33 +48,13 @@ #ifdef BCMSDIOH_TXGLOM /* Max number of glommed pkts */ -#ifdef CUSTOM_MAX_TXGLOM_SIZE -#define SDPCM_MAXGLOM_SIZE CUSTOM_MAX_TXGLOM_SIZE -#else #define SDPCM_MAXGLOM_SIZE 10 -#endif /* CUSTOM_MAX_TXGLOM_SIZE */ +#define SDPCM_DEFGLOM_SIZE 3 #define SDPCM_TXGLOM_CPY 0 /* SDIO 2.0 should use copy mode */ #define SDPCM_TXGLOM_MDESC 1 /* SDIO 3.0 should use multi-desc mode */ - -#ifdef BCMSDIOH_TXGLOM_HIGHSPEED -#define SDPCM_DEFGLOM_MODE SDPCM_TXGLOM_MDESC -#ifdef CUSTOM_DEF_TXGLOM_SIZE -#define SDPCM_DEFGLOM_SIZE CUSTOM_DEF_TXGLOM_SIZE -#else -#define SDPCM_DEFGLOM_SIZE 10 -#endif /* CUSTOM_DEF_TXGLOM_SIZE */ -#else -#define SDPCM_DEFGLOM_MODE SDPCM_TXGLOM_CPY -#define SDPCM_DEFGLOM_SIZE 3 -#endif /* BCMSDIOH_TXGLOM_HIGHSPEED */ - -#if SDPCM_DEFGLOM_SIZE > SDPCM_MAXGLOM_SIZE -#warning "SDPCM_DEFGLOM_SIZE cannot be higher than SDPCM_MAXGLOM_SIZE!!" -#undef SDPCM_DEFGLOM_SIZE -#define SDPCM_DEFGLOM_SIZE SDPCM_MAXGLOM_SIZE #endif -#endif /* BCMSDIOH_TXGLOM */ + typedef int SDIOH_API_RC; @@ -116,12 +96,12 @@ extern SDIOH_API_RC sdioh_request_buffer void *pkt); #ifdef BCMSDIOH_TXGLOM -extern void sdioh_glom_post(sdioh_info_t *sd, uint8 *frame, void *pkt, uint len); +extern void sdioh_glom_post(sdioh_info_t *sd, uint8 *frame, uint len); extern void sdioh_glom_clear(sdioh_info_t *sd); extern uint sdioh_set_mode(sdioh_info_t *sd, uint mode); extern bool sdioh_glom_enabled(void); #else -#define sdioh_glom_post(a, b, c, d) +#define sdioh_glom_post(a, b, c) #define sdioh_glom_clear(a) #define sdioh_set_mode(a) (0) #define sdioh_glom_enabled() (FALSE) diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/bcmsdh.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcmsdh.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/bcmsdh.h 2014-01-27 01:30:30.101433269 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcmsdh.h 2014-02-15 00:43:44.793014092 +0100 @@ -3,7 +3,7 @@ * export functions to client drivers * abstract OS and BUS specific details of SDIO * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -23,7 +23,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.h 414953 2013-07-26 17:36:27Z $ + * $Id: bcmsdh.h 347614 2012-07-27 10:24:51Z $ */ /** @@ -48,8 +48,6 @@ extern const uint bcmsdh_msglevel; typedef struct bcmsdh_info bcmsdh_info_t; typedef void (*bcmsdh_cb_fn_t)(void *); -extern struct device *pm_dev; - /* Attach and build an interface to the underlying SD host driver. * - Allocates resources (structs, arrays, mem, OS handles, etc) needed by bcmsdh. * - Returns the bcmsdh handle and virtual address base for register access. @@ -57,7 +55,13 @@ extern struct device *pm_dev; * implementation may maintain a single "default" handle (e.g. the first or * most recent one) to enable single-instance implementations to pass NULL. */ + +#if 0 && (NDISVER >= 0x0630) && 1 +extern bcmsdh_info_t *bcmsdh_attach(osl_t *osh, void *cfghdl, + void **regsva, uint irq, shared_info_t *sh); +#else extern bcmsdh_info_t *bcmsdh_attach(osl_t *osh, void *cfghdl, void **regsva, uint irq); +#endif /* Detach - freeup resources allocated in attach */ extern int bcmsdh_detach(osl_t *osh, void *sdh); @@ -141,7 +145,7 @@ extern int bcmsdh_recv_buf(void *sdh, ui uint8 *buf, uint nbytes, void *pkt, bcmsdh_cmplt_fn_t complete_fn, void *handle); -extern void bcmsdh_glom_post(void *sdh, uint8 *frame, void *pkt, uint len); +extern void bcmsdh_glom_post(void *sdh, uint8 *frame, uint len); extern void bcmsdh_glom_clear(void *sdh); extern uint bcmsdh_set_mode(void *sdh, uint mode); extern bool bcmsdh_glom_enabled(void); @@ -211,12 +215,16 @@ extern void bcmsdh_device_remove(void * extern int bcmsdh_reg_sdio_notify(void* semaphore); extern void bcmsdh_unreg_sdio_notify(void); +extern int bcmsdh_set_drvdata(void * dhdp); + #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); -extern bool bcmsdh_is_oob_intr_registered(void); -#endif +#endif +#if defined(HW_OOB) +void bcmsdh_config_hw_oob_intr(bcmsdh_info_t *sdh, uint chip); +#endif /* Function to pass device-status bits to DHD. */ extern uint32 bcmsdh_get_dstatus(void *sdh); diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/bcmsdh_sdmmc.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcmsdh_sdmmc.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/bcmsdh_sdmmc.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcmsdh_sdmmc.h 2014-02-15 00:43:44.794014114 +0100 @@ -1,7 +1,7 @@ /* * BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -21,19 +21,21 @@ * 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 396592 2013-04-13 16:14:38Z $ + * $Id: bcmsdh_sdmmc.h 366812 2012-11-05 13:49:32Z $ */ #ifndef __BCMSDH_SDMMC_H__ #define __BCMSDH_SDMMC_H__ -#define sd_err(x) +#define sd_err(x) printf x #define sd_trace(x) #define sd_info(x) #define sd_debug(x) #define sd_data(x) #define sd_ctrl(x) +#define sd_trace_hw4 sd_trace + #define sd_sync_dma(sd, read, nbytes) #define sd_init_dma(sd) #define sd_ack_intr(sd) @@ -59,19 +61,10 @@ extern void sdioh_sdmmc_osfree(sdioh_inf /* private bus modes */ #define SDIOH_MODE_SD4 2 -#define CLIENT_INTR 0x100 /* Get rid of this! */ - -#ifdef BCMSDIOH_TXGLOM - -typedef struct glom_buf { - void *glom_pkt_head; - void *glom_pkt_tail; - uint32 count; /* Total number of pkts queued */ -} glom_buf_t; -#endif /* BCMSDIOH_TXGLOM */ +#define CLIENT_INTR 0x100 /* Get rid of this! */ struct sdioh_info { - osl_t *osh; /* osh handler */ + osl_t *osh; /* osh handler */ 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 */ @@ -79,27 +72,22 @@ struct sdioh_info { uint16 intmask; /* Current active interrupts */ void *sdos_info; /* Pointer to per-OS private data */ - uint irq; /* Client irq */ - int intrcount; /* Client interrupts */ + uint irq; /* Client irq */ + int intrcount; /* Client interrupts */ bool sd_use_dma; /* DMA on CMD53 */ - bool sd_blockmode; /* sd_blockmode == FALSE => 64 Byte Cmd 53s. */ + 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 */ int sd_mode; /* SD1/SD4/SPI */ int client_block_size[SDIOD_MAX_IOFUNCS]; /* Blocksize */ uint8 num_funcs; /* Supported funcs on client */ uint32 com_cis_ptr; - uint32 func_cis_ptr[SDIOD_MAX_IOFUNCS]; + uint32 func_cis_ptr[SDIOD_MAX_IOFUNCS]; #define SDIOH_SDMMC_MAX_SG_ENTRIES 32 struct scatterlist sg_list[SDIOH_SDMMC_MAX_SG_ENTRIES]; bool use_rxchain; - -#ifdef BCMSDIOH_TXGLOM - glom_buf_t glom_info; /* pkt information used for glomming */ - uint txglom_mode; /* Txglom mode: 0 - copy, 1 - multi-descriptor */ -#endif }; /************************************************************ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/bcmsdpcm.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcmsdpcm.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/bcmsdpcm.h 2014-01-27 01:30:30.101433269 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcmsdpcm.h 2014-02-15 00:43:44.793014092 +0100 @@ -2,7 +2,7 @@ * Broadcom SDIO/PCMCIA * Software-specific definitions shared between device and host side * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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 364353 2012-10-23 20:31:46Z $ + * $Id: bcmsdpcm.h 362722 2012-10-12 23:55:55Z $ */ #ifndef _bcmsdpcm_h_ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/bcmsdspi.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcmsdspi.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/bcmsdspi.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcmsdspi.h 2014-02-15 00:43:44.794014114 +0100 @@ -1,7 +1,7 @@ /* * SD-SPI Protocol Conversion - BCMSDH->SPI Translation Layer * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/bcmsdstd.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcmsdstd.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/bcmsdstd.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcmsdstd.h 2014-02-15 00:43:44.794014114 +0100 @@ -1,7 +1,7 @@ /* * 'Standard' SDIO HOST CONTROLLER driver * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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 343301 2012-07-06 13:07:32Z $ + * $Id: bcmsdstd.h 347614 2012-07-27 10:24:51Z $ */ #ifndef _BCM_SD_STD_H #define _BCM_SD_STD_H diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/bcmspi.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcmspi.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/bcmspi.h 2014-01-27 01:30:30.101433269 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcmspi.h 2014-02-15 00:43:44.793014092 +0100 @@ -1,7 +1,7 @@ /* * Broadcom SPI Low-Level Hardware Driver API * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/bcmutils.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcmutils.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/bcmutils.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcmutils.h 2014-02-15 00:43:44.794014114 +0100 @@ -1,7 +1,7 @@ /* * Misc useful os-independent macros and functions. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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: bcmutils.h 412804 2013-07-16 16:26:39Z $ + * $Id: bcmutils.h 354837 2012-09-04 06:58:44Z $ */ #ifndef _bcmutils_h_ @@ -140,8 +140,6 @@ typedef struct { increases with use ('inverse' of max_avail) */ uint32 queue_capacity; /* the maximum capacity of the queue */ - uint32 rtsfail; /* count of rts attempts that failed to receive cts */ - uint32 acked; /* count of packets sent (acked) successfully */ } pktq_counters_t; #endif /* PKTQ_LOG */ @@ -158,9 +156,7 @@ struct pktq { /* q array must be last since # of elements can be either PKTQ_MAX_PREC or 1 */ struct pktq_prec q[PKTQ_MAX_PREC]; #ifdef PKTQ_LOG - pktq_counters_t _prec_cnt[PKTQ_MAX_PREC]; /* Counters per queue */ - pktq_counters_t _prec_bytes[PKTQ_MAX_PREC]; /* Byte count per queue */ - uint32 _logtime; /* timestamp of last counter clear */ + pktq_counters_t _prec_cnt[PKTQ_MAX_PREC]; /* Counters per queue */ #endif }; @@ -304,7 +300,6 @@ extern void *pktq_penq(struct pktq *pq, 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_with_fn(struct pktq *pq, int prec, ifpkt_cb_t fn, int arg); extern void *pktq_pdeq_tail(struct pktq *pq, int prec); /* Empty the queue at particular precedence level */ extern void pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir, @@ -351,8 +346,7 @@ extern uint pkttotlen(osl_t *osh, void * 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 *pktdataoffset(osl_t *osh, void *p, uint offset); -extern void *pktoffset(osl_t *osh, void *p, uint offset); +extern uint8 *pktoffset(osl_t *osh, void *p, uint offset); /* Get priority from a packet and pass it back in scb (or equiv) */ #define PKTPRIO_VDSCP 0x100 /* DSCP prio found after VLAN tag */ @@ -360,22 +354,6 @@ extern void *pktoffset(osl_t *osh, void #define PKTPRIO_UPD 0x400 /* DSCP used to update VLAN prio */ #define PKTPRIO_DSCP 0x800 /* DSCP prio found */ -/* DSCP type definitions (RFC4594) */ -/* AF1x: High-Throughput Data (RFC2597) */ -#define DSCP_AF11 0x0A -#define DSCP_AF12 0x0C -#define DSCP_AF13 0x0E -/* AF2x: Low-Latency Data (RFC2597) */ -#define DSCP_AF21 0x12 -#define DSCP_AF22 0x14 -#define DSCP_AF23 0x16 -/* AF3x: Multimedia Streaming (RFC2597) */ -#define DSCP_AF31 0x1A -#define DSCP_AF32 0x1C -#define DSCP_AF33 0x1E -/* EF: Telephony (RFC3246) */ -#define DSCP_EF 0x2E - extern uint pktsetprio(void *pkt, bool update_vtag); /* string */ @@ -551,11 +529,7 @@ extern int bcm_format_ssid(char* buf, co #define BCME_NODEVICE -40 /* Device not present */ #define BCME_NMODE_DISABLED -41 /* NMODE disabled */ #define BCME_NONRESIDENT -42 /* access to nonresident overlay */ -#define BCME_SCANREJECT -43 /* reject scan request */ -#define BCME_USAGE_ERROR -44 /* WLCMD usage error */ -#define BCME_IOCTL_ERROR -45 /* WLCMD ioctl error */ -#define BCME_SERIAL_PORT_ERR -46 /* RWL serial port error */ -#define BCME_LAST BCME_SERIAL_PORT_ERR +#define BCME_LAST BCME_NONRESIDENT /* These are collection of BCME Error strings */ #define BCMERRSTRINGTABLE { \ @@ -602,10 +576,6 @@ extern int bcm_format_ssid(char* buf, co "Device Not Present", \ "NMODE Disabled", \ "Nonresident overlay access", \ - "Scan Rejected", \ - "WLCMD usage error", \ - "WLCMD ioctl error", \ - "RWL serial port error", \ } #ifndef ABS @@ -620,24 +590,6 @@ extern int bcm_format_ssid(char* buf, co #define MAX(a, b) (((a) > (b)) ? (a) : (b)) #endif /* MAX */ -/* limit to [min, max] */ -#ifndef LIMIT_TO_RANGE -#define LIMIT_TO_RANGE(x, min, max) \ - ((x) < (min) ? (min) : ((x) > (max) ? (max) : (x))) -#endif /* LIMIT_TO_RANGE */ - -/* limit to max */ -#ifndef LIMIT_TO_MAX -#define LIMIT_TO_MAX(x, max) \ - (((x) > (max) ? (max) : (x))) -#endif /* LIMIT_TO_MAX */ - -/* limit to min */ -#ifndef LIMIT_TO_MIN -#define LIMIT_TO_MIN(x, min) \ - (((x) < (min) ? (min) : (x))) -#endif /* LIMIT_TO_MIN */ - #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) @@ -666,10 +618,6 @@ extern int bcm_format_ssid(char* buf, co #define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0])) #endif -#ifndef ARRAYLAST /* returns pointer to last array element */ -#define ARRAYLAST(a) (&a[ARRAYSIZE(a)-1]) -#endif - /* Reference a function; used to prevent a static function from being optimized out */ extern void *_bcmutils_dummy_fn; #define REFERENCE_FUNCTION(f) (_bcmutils_dummy_fn = (void *)(f)) @@ -679,21 +627,12 @@ extern void *_bcmutils_dummy_fn; #ifndef NBBY /* the BSD family defines NBBY */ #define NBBY 8 /* 8 bits per byte */ #endif /* #ifndef NBBY */ -#ifdef BCMUTILS_BIT_MACROS_USE_FUNCS -extern void setbit(void *array, uint bit); -extern void clrbit(void *array, uint bit); -extern bool isset(const void *array, uint bit); -extern bool isclr(const void *array, uint bit); -#else #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 #endif /* setbit */ -#define isbitset(a, i) (((a) & (1 << (i))) != 0) - #define NBITS(type) (sizeof(type) * 8) #define NBITVAL(nbits) (1 << (nbits)) #define MAXBITVAL(nbits) ((1 << (nbits)) - 1) @@ -758,13 +697,6 @@ typedef struct bcm_bit_desc { const char* name; } bcm_bit_desc_t; -/* bcm_format_field */ -typedef struct bcm_bit_desc_ex { - uint32 mask; - const bcm_bit_desc_t *bitfield; -} bcm_bit_desc_ex_t; - - /* tag_ID/length/value_buffer tuple */ typedef struct bcm_tlv { uint8 id; @@ -811,9 +743,6 @@ extern uint32 hndcrc32(uint8 *p, uint nb /* format/print */ #if defined(DHD_DEBUG) || defined(WLMSG_PRHDRS) || defined(WLMSG_PRPKT) || \ defined(WLMSG_ASSOC) -/* print out the value a field has: fields may have 1-32 bits and may hold any value */ -extern int bcm_format_field(const bcm_bit_desc_ex_t *bd, uint32 field, char* buf, int len); -/* print out which bits in flags are set */ extern int bcm_format_flags(const bcm_bit_desc_t *bd, uint32 flags, char* buf, int len); #endif @@ -835,7 +764,7 @@ extern bcm_tlv_t *bcm_parse_ordered_tlvs /* bcmerror */ extern const char *bcmerrorstr(int bcmerror); -/* extern bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen, uint key); */ +extern bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen, uint key); /* multi-bool data type: set of bools, mbool is true if any is set */ typedef uint32 mbool; @@ -871,13 +800,6 @@ 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); -extern bcm_tlv_t *find_vendor_ie(void *tlvs, int tlvs_len, - const char *voui, uint8 *type, int type_len); - -/* calculate a * b + c */ -extern void bcm_uint64_multiple_add(uint32* r_high, uint32* r_low, uint32 a, uint32 b, uint32 c); -/* calculate a / b */ -extern void bcm_uint64_divide(uint32* r, uint32 a_high, uint32 a_low, uint32 b); #ifdef __cplusplus } diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/bcmwifi_channels.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcmwifi_channels.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/bcmwifi_channels.h 2014-01-27 01:30:30.101433269 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcmwifi_channels.h 2014-02-15 00:43:44.793014092 +0100 @@ -3,7 +3,7 @@ * This header file housing the define and function prototype use by * both the wl driver, tools & Apps. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -47,8 +47,7 @@ typedef uint16 chanspec_t; * this is that + 1 rounded up to a multiple of NBBY (8). * DO NOT MAKE it > 255: channels are uint8's all over */ -#define CHSPEC_CTLOVLP(sp1, sp2, sep) (ABS(wf_chspec_ctlchan(sp1) - wf_chspec_ctlchan(sp2)) < \ - (sep)) +#define CHSPEC_CTLOVLP(sp1, sp2, sep) ABS(wf_chspec_ctlchan(sp1) - wf_chspec_ctlchan(sp2)) < (sep) /* All builds use the new 11ac ratespec/chanspec */ #undef D11AC_IOTYPES @@ -87,13 +86,6 @@ typedef uint16 chanspec_t; #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 LL_20_SB(channel) (((channel) > 3 * CH_10MHZ_APART) ? ((channel) - 3 * CH_10MHZ_APART) : 0) -#define UU_20_SB(channel) (((channel) < (MAXCHANNEL - 3 * CH_10MHZ_APART)) ? \ - ((channel) + 3 * CH_10MHZ_APART) : 0) -#define LU_20_SB(channel) LOWER_20_SB(channel) -#define UL_20_SB(channel) UPPER_20_SB(channel) - #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 | \ WL_CHANSPEC_CTL_SB_NONE | (((channel) <= CH_MAX_2G_CHANNEL) ? \ @@ -192,13 +184,6 @@ typedef uint16 chanspec_t; ((channel) - CH_10MHZ_APART) : 0) #define UPPER_20_SB(channel) (((channel) < (MAXCHANNEL - CH_10MHZ_APART)) ? \ ((channel) + CH_10MHZ_APART) : 0) - -#define LL_20_SB(channel) (((channel) > 3 * CH_10MHZ_APART) ? ((channel) - 3 * CH_10MHZ_APART) : 0) -#define UU_20_SB(channel) (((channel) < (MAXCHANNEL - 3 * CH_10MHZ_APART)) ? \ - ((channel) + 3 * CH_10MHZ_APART) : 0) -#define LU_20_SB(channel) LOWER_20_SB(channel) -#define UL_20_SB(channel) UPPER_20_SB(channel) - #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) @@ -313,11 +298,6 @@ typedef uint16 chanspec_t; #define LCHSPEC_CREATE(chan, band, bw, sb) ((uint16)((chan) | (sb) | (bw) | (band))) -#define CH20MHZ_LCHSPEC(channel) \ - (chanspec_t)((chanspec_t)(channel) | WL_LCHANSPEC_BW_20 | \ - WL_LCHANSPEC_CTL_SB_NONE | (((channel) <= CH_MAX_2G_CHANNEL) ? \ - WL_LCHANSPEC_BAND_2G : WL_LCHANSPEC_BAND_5G)) - #endif /* D11AC_IOTYPES */ /* @@ -344,6 +324,21 @@ typedef uint16 chanspec_t; */ #define WF_CHAN_FACTOR_4_G 8000 /* 4.9 GHz band for Japan */ +/* defined rate in 500kbps */ +#define WLC_MAXRATE 108 /* in 500kbps units */ +#define WLC_RATE_1M 2 /* in 500kbps units */ +#define WLC_RATE_2M 4 /* in 500kbps units */ +#define WLC_RATE_5M5 11 /* in 500kbps units */ +#define WLC_RATE_11M 22 /* in 500kbps units */ +#define WLC_RATE_6M 12 /* in 500kbps units */ +#define WLC_RATE_9M 18 /* in 500kbps units */ +#define WLC_RATE_12M 24 /* in 500kbps units */ +#define WLC_RATE_18M 36 /* in 500kbps units */ +#define WLC_RATE_24M 48 /* in 500kbps units */ +#define WLC_RATE_36M 72 /* in 500kbps units */ +#define WLC_RATE_48M 96 /* in 500kbps units */ +#define WLC_RATE_54M 108 /* in 500kbps units */ + #define WLC_2G_25MHZ_OFFSET 5 /* 2.4GHz band channel offset */ /** @@ -492,8 +487,4 @@ extern int wf_channel2mhz(uint channel, */ extern uint16 wf_channel2chspec(uint ctl_ch, uint bw); -extern uint wf_channel2freq(uint channel); -extern uint wf_freq2channel(uint freq); - - #endif /* _bcmwifi_channels_h_ */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/bcmwifi_rates.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcmwifi_rates.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/bcmwifi_rates.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/bcmwifi_rates.h 2014-02-15 00:43:44.794014114 +0100 @@ -1,7 +1,7 @@ /* * Indices for 802.11 a/b/g/n/ac 1-3 chain symmetric transmit rates * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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: bcmwifi_rates.h 5187 2012-06-29 06:17:50Z $ + * $Id: bcmwifi_rates.h 252708 2011-04-12 06:45:56Z $ */ #ifndef _bcmwifi_rates_h_ @@ -48,7 +48,8 @@ typedef enum wl_tx_bw { WL_TX_BW_80, WL_TX_BW_20IN40, WL_TX_BW_20IN80, - WL_TX_BW_40IN80 + WL_TX_BW_40IN80, + WL_TX_BW_ALL } wl_tx_bw_t; @@ -60,8 +61,7 @@ typedef enum wl_tx_mode { WL_TX_MODE_NONE, WL_TX_MODE_STBC, WL_TX_MODE_CDD, - WL_TX_MODE_TXBF, - WL_NUM_TX_MODES + WL_TX_MODE_SDM } wl_tx_mode_t; @@ -83,9 +83,9 @@ typedef enum wl_tx_nss { typedef enum clm_rates { /************ - * 1 chain * - ************ - */ + * 1 chain * + ************ + */ /* 1 Stream */ WL_RATE_1X1_DSSS_1 = 0, @@ -124,9 +124,9 @@ typedef enum clm_rates { /************ - * 2 chains * - ************ - */ + * 2 chains * + ************ + */ /* 1 Stream expanded + 1 */ WL_RATE_1X2_DSSS_1 = 22, @@ -204,10 +204,11 @@ typedef enum clm_rates { WL_RATE_2X2_VHT8SS2 = 62, WL_RATE_2X2_VHT9SS2 = 63, + /************ - * 3 chains * - ************ - */ + * 3 chains * + ************ + */ /* 1 Stream expanded + 2 */ WL_RATE_1X3_DSSS_1 = 64, @@ -306,146 +307,10 @@ typedef enum clm_rates { WL_RATE_3X3_VHT8SS3 = 114, WL_RATE_3X3_VHT9SS3 = 115, - - /**************************** - * TX Beamforming, 2 chains * - **************************** - */ - - /* 1 Stream expanded + 1 */ - - WL_RATE_1X2_TXBF_OFDM_6 = 116, - WL_RATE_1X2_TXBF_OFDM_9 = 117, - WL_RATE_1X2_TXBF_OFDM_12 = 118, - WL_RATE_1X2_TXBF_OFDM_18 = 119, - WL_RATE_1X2_TXBF_OFDM_24 = 120, - WL_RATE_1X2_TXBF_OFDM_36 = 121, - WL_RATE_1X2_TXBF_OFDM_48 = 122, - WL_RATE_1X2_TXBF_OFDM_54 = 123, - - WL_RATE_1X2_TXBF_MCS0 = 124, - WL_RATE_1X2_TXBF_MCS1 = 125, - WL_RATE_1X2_TXBF_MCS2 = 126, - WL_RATE_1X2_TXBF_MCS3 = 127, - WL_RATE_1X2_TXBF_MCS4 = 128, - WL_RATE_1X2_TXBF_MCS5 = 129, - WL_RATE_1X2_TXBF_MCS6 = 130, - WL_RATE_1X2_TXBF_MCS7 = 131, - - WL_RATE_1X2_TXBF_VHT0SS1 = 124, - WL_RATE_1X2_TXBF_VHT1SS1 = 125, - WL_RATE_1X2_TXBF_VHT2SS1 = 126, - WL_RATE_1X2_TXBF_VHT3SS1 = 127, - WL_RATE_1X2_TXBF_VHT4SS1 = 128, - WL_RATE_1X2_TXBF_VHT5SS1 = 129, - WL_RATE_1X2_TXBF_VHT6SS1 = 130, - WL_RATE_1X2_TXBF_VHT7SS1 = 131, - WL_RATE_1X2_TXBF_VHT8SS1 = 132, - WL_RATE_1X2_TXBF_VHT9SS1 = 133, - - /* 2 Streams */ - - WL_RATE_2X2_TXBF_SDM_MCS8 = 134, - WL_RATE_2X2_TXBF_SDM_MCS9 = 135, - WL_RATE_2X2_TXBF_SDM_MCS10 = 136, - WL_RATE_2X2_TXBF_SDM_MCS11 = 137, - WL_RATE_2X2_TXBF_SDM_MCS12 = 138, - WL_RATE_2X2_TXBF_SDM_MCS13 = 139, - WL_RATE_2X2_TXBF_SDM_MCS14 = 140, - WL_RATE_2X2_TXBF_SDM_MCS15 = 141, - - WL_RATE_2X2_TXBF_VHT0SS2 = 134, - WL_RATE_2X2_TXBF_VHT1SS2 = 135, - WL_RATE_2X2_TXBF_VHT2SS2 = 136, - WL_RATE_2X2_TXBF_VHT3SS2 = 137, - WL_RATE_2X2_TXBF_VHT4SS2 = 138, - WL_RATE_2X2_TXBF_VHT5SS2 = 139, - WL_RATE_2X2_TXBF_VHT6SS2 = 140, - WL_RATE_2X2_TXBF_VHT7SS2 = 141, - - - /**************************** - * TX Beamforming, 3 chains * - **************************** - */ - - /* 1 Stream expanded + 2 */ - - WL_RATE_1X3_TXBF_OFDM_6 = 142, - WL_RATE_1X3_TXBF_OFDM_9 = 143, - WL_RATE_1X3_TXBF_OFDM_12 = 144, - WL_RATE_1X3_TXBF_OFDM_18 = 145, - WL_RATE_1X3_TXBF_OFDM_24 = 146, - WL_RATE_1X3_TXBF_OFDM_36 = 147, - WL_RATE_1X3_TXBF_OFDM_48 = 148, - WL_RATE_1X3_TXBF_OFDM_54 = 149, - - WL_RATE_1X3_TXBF_MCS0 = 150, - WL_RATE_1X3_TXBF_MCS1 = 151, - WL_RATE_1X3_TXBF_MCS2 = 152, - WL_RATE_1X3_TXBF_MCS3 = 153, - WL_RATE_1X3_TXBF_MCS4 = 154, - WL_RATE_1X3_TXBF_MCS5 = 155, - WL_RATE_1X3_TXBF_MCS6 = 156, - WL_RATE_1X3_TXBF_MCS7 = 157, - - WL_RATE_1X3_TXBF_VHT0SS1 = 150, - WL_RATE_1X3_TXBF_VHT1SS1 = 151, - WL_RATE_1X3_TXBF_VHT2SS1 = 152, - WL_RATE_1X3_TXBF_VHT3SS1 = 153, - WL_RATE_1X3_TXBF_VHT4SS1 = 154, - WL_RATE_1X3_TXBF_VHT5SS1 = 155, - WL_RATE_1X3_TXBF_VHT6SS1 = 156, - WL_RATE_1X3_TXBF_VHT7SS1 = 157, - WL_RATE_1X3_TXBF_VHT8SS1 = 158, - WL_RATE_1X3_TXBF_VHT9SS1 = 159, - - /* 2 Streams expanded + 1 */ - - WL_RATE_2X3_TXBF_SDM_MCS8 = 160, - WL_RATE_2X3_TXBF_SDM_MCS9 = 161, - WL_RATE_2X3_TXBF_SDM_MCS10 = 162, - WL_RATE_2X3_TXBF_SDM_MCS11 = 163, - WL_RATE_2X3_TXBF_SDM_MCS12 = 164, - WL_RATE_2X3_TXBF_SDM_MCS13 = 165, - WL_RATE_2X3_TXBF_SDM_MCS14 = 166, - WL_RATE_2X3_TXBF_SDM_MCS15 = 167, - - WL_RATE_2X3_TXBF_VHT0SS2 = 160, - WL_RATE_2X3_TXBF_VHT1SS2 = 161, - WL_RATE_2X3_TXBF_VHT2SS2 = 162, - WL_RATE_2X3_TXBF_VHT3SS2 = 163, - WL_RATE_2X3_TXBF_VHT4SS2 = 164, - WL_RATE_2X3_TXBF_VHT5SS2 = 165, - WL_RATE_2X3_TXBF_VHT6SS2 = 166, - WL_RATE_2X3_TXBF_VHT7SS2 = 167, - WL_RATE_2X3_TXBF_VHT8SS2 = 168, - WL_RATE_2X3_TXBF_VHT9SS2 = 169, - - /* 3 Streams */ - - WL_RATE_3X3_TXBF_SDM_MCS16 = 170, - WL_RATE_3X3_TXBF_SDM_MCS17 = 171, - WL_RATE_3X3_TXBF_SDM_MCS18 = 172, - WL_RATE_3X3_TXBF_SDM_MCS19 = 173, - WL_RATE_3X3_TXBF_SDM_MCS20 = 174, - WL_RATE_3X3_TXBF_SDM_MCS21 = 175, - WL_RATE_3X3_TXBF_SDM_MCS22 = 176, - WL_RATE_3X3_TXBF_SDM_MCS23 = 177, - - WL_RATE_3X3_TXBF_VHT0SS3 = 170, - WL_RATE_3X3_TXBF_VHT1SS3 = 171, - WL_RATE_3X3_TXBF_VHT2SS3 = 172, - WL_RATE_3X3_TXBF_VHT3SS3 = 173, - WL_RATE_3X3_TXBF_VHT4SS3 = 174, - WL_RATE_3X3_TXBF_VHT5SS3 = 175, - WL_RATE_3X3_TXBF_VHT6SS3 = 176, - WL_RATE_3X3_TXBF_VHT7SS3 = 177 + /* Number of rate codes */ + WL_NUMRATES = 116 } clm_rates_t; -/* Number of rate codes */ -#define WL_NUMRATES 178 - #ifdef __cplusplus } #endif /* __cplusplus */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/dhdioctl.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/dhdioctl.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/dhdioctl.h 2014-01-27 01:30:30.101433269 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/dhdioctl.h 2014-02-15 00:43:44.793014092 +0100 @@ -5,7 +5,7 @@ * * Definitions subject to change without notice. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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 419132 2013-08-19 21:33:05Z $ + * $Id: dhdioctl.h 354894 2012-09-04 12:34:07Z $ */ #ifndef _dhdioctl_h_ @@ -85,13 +85,15 @@ enum { #define DHD_GLOM_VAL 0x0400 #define DHD_EVENT_VAL 0x0800 #define DHD_BTA_VAL 0x1000 +#if 0 && (NDISVER >= 0x0630) && 1 +#define DHD_SCAN_VAL 0x2000 +#else #define DHD_ISCAN_VAL 0x2000 +#endif #define DHD_ARPOE_VAL 0x4000 #define DHD_REORDER_VAL 0x8000 -#define DHD_WL_VAL 0x10000 -#define DHD_NOCHECKDIED_VAL 0x20000 /* UTF WAR */ -#define DHD_WL_VAL2 0x40000 -#define DHD_PNO_VAL 0x80000 +#define DHD_IW_VAL 0x10000 +#define DHD_CFG_VAL 0x20000 #ifdef SDTEST /* For pktgen iovar */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/epivers.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/epivers.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/epivers.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/epivers.h 2014-02-15 00:43:44.794014114 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -28,28 +28,28 @@ #define EPI_MAJOR_VERSION 1 -#define EPI_MINOR_VERSION 88 +#define EPI_MINOR_VERSION 28 -#define EPI_RC_NUMBER 45 +#define EPI_RC_NUMBER 23 #define EPI_INCREMENTAL_NUMBER 0 #define EPI_BUILD_NUMBER 0 -#define EPI_VERSION 1, 88, 45, 0 +#define EPI_VERSION 1, 28, 23, 0 -#define EPI_VERSION_NUM 0x01582d00 +#define EPI_VERSION_NUM 0x011c1700 -#define EPI_VERSION_DEV 1.88.45 +#define EPI_VERSION_DEV 1.28.23 /* Driver Version String, ASCII, 32 chars max */ #ifdef BCMINTERNAL -#define EPI_VERSION_STR "1.88.45 (r BCMINT)" +#define EPI_VERSION_STR "1.28.23.3 (r BCMINT)" #else #ifdef WLTEST -#define EPI_VERSION_STR "1.88.45 (r WLTEST)" +#define EPI_VERSION_STR "1.28.23.3 (r WLTEST)" #else -#define EPI_VERSION_STR "1.88.45 (r)" +#define EPI_VERSION_STR "1.28.23.3 (r)" #endif #endif /* BCMINTERNAL */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/hndpmu.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/hndpmu.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/hndpmu.h 2014-01-27 01:30:30.101433269 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/hndpmu.h 2014-02-15 00:43:44.793014092 +0100 @@ -1,7 +1,7 @@ /* * HND SiliconBackplane PMU support. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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 385540 2013-02-15 23:14:50Z $ + * $Id: hndpmu.h 241182 2011-02-17 21:50:03Z $ */ #ifndef _hndpmu_h_ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/hndrte_armtrap.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/hndrte_armtrap.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/hndrte_armtrap.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/hndrte_armtrap.h 2014-02-15 00:43:44.794014114 +0100 @@ -1,7 +1,7 @@ /* * HNDRTE arm trap handling. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/hndrte_cons.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/hndrte_cons.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/hndrte_cons.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/hndrte_cons.h 2014-02-15 00:43:44.794014114 +0100 @@ -1,7 +1,7 @@ /* * Console support for hndrte. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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_cons.h 383834 2013-02-07 23:21:51Z $ + * $Id: hndrte_cons.h 300516 2011-12-04 17:39:44Z $ */ #ifndef _HNDRTE_CONS_H #define _HNDRTE_CONS_H @@ -64,6 +64,4 @@ typedef struct { char cbuf[CBUF_LEN]; } hndrte_cons_t; -hndrte_cons_t *hndrte_get_active_cons_state(void); - #endif /* _HNDRTE_CONS_H */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/hndsoc.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/hndsoc.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/hndsoc.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/hndsoc.h 2014-02-15 00:43:44.794014114 +0100 @@ -1,7 +1,7 @@ /* * Broadcom HND chip & on-chip-interconnect-related definitions. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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 365041 2012-10-26 09:10:35Z $ + * $Id: hndsoc.h 309193 2012-01-19 00:03:57Z $ */ #ifndef _HNDSOC_H @@ -46,8 +46,10 @@ #define SI_WRAP_BASE 0x18100000 /* Wrapper space base */ #define SI_CORE_SIZE 0x1000 /* each core gets 4Kbytes for registers */ - -#define SI_MAXCORES 32 /* NorthStar has more cores */ +#define SI_MAXCORES 16 /* Max cores (this is arbitrary, for software + * convenience and could be changed if we + * make any larger chips + */ #define SI_FASTRAM 0x19000000 /* On-chip RAM on chips that also have DDR */ #define SI_FASTRAM_SWAPPED 0x19800000 @@ -57,13 +59,6 @@ #define SI_ARMCM3_ROM 0x1e000000 /* ARM Cortex-M3 ROM */ #define SI_FLASH1 0x1fc00000 /* MIPS Flash Region 1 */ #define SI_FLASH1_SZ 0x00400000 /* MIPS Size of Flash Region 1 */ -#define SI_FLASH_WINDOW 0x01000000 /* Flash XIP Window */ - -#define SI_NS_NANDFLASH 0x1c000000 /* NorthStar NAND flash base */ -#define SI_NS_NORFLASH 0x1e000000 /* NorthStar NOR flash base */ -#define SI_NS_ROM 0xfffd0000 /* NorthStar ROM */ -#define SI_NS_FLASH_WINDOW 0x02000000 /* Flash XIP Window */ - #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 */ @@ -152,21 +147,7 @@ */ #define CC_4706_CORE_ID 0x500 /* chipcommon core */ -#define NS_PCIEG2_CORE_ID 0x501 /* PCIE Gen 2 core */ -#define NS_DMA_CORE_ID 0x502 /* DMA core */ -#define NS_SDIO3_CORE_ID 0x503 /* SDIO3 core */ -#define NS_USB20_CORE_ID 0x504 /* USB2.0 core */ -#define NS_USB30_CORE_ID 0x505 /* USB3.0 core */ -#define NS_A9JTAG_CORE_ID 0x506 /* ARM Cortex A9 JTAG core */ -#define NS_DDR23_CORE_ID 0x507 /* Denali DDR2/DDR3 memory controller */ -#define NS_ROM_CORE_ID 0x508 /* ROM core */ -#define NS_NAND_CORE_ID 0x509 /* NAND flash controller core */ -#define NS_QSPI_CORE_ID 0x50a /* SPI flash controller core */ -#define NS_CCB_CORE_ID 0x50b /* ChipcommonB core */ #define SOCRAM_4706_CORE_ID 0x50e /* internal memory core */ -#define NS_SOCRAM_CORE_ID SOCRAM_4706_CORE_ID -#define ARMCA9_CORE_ID 0x510 /* ARM Cortex A9 core (ihost) */ -#define NS_IHOST_CORE_ID ARMCA9_CORE_ID /* ARM Cortex A9 core (ihost) */ #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 */ @@ -191,7 +172,6 @@ #define SOCI_SB 0 #define SOCI_AI 1 #define SOCI_UBUS 2 -#define SOCI_NAI 3 /* Common core control flags */ #define SICF_BIST_EN 0x8000 @@ -207,14 +187,6 @@ #define SISF_DMA64 0x1000 #define SISF_CORE_BITS 0x0fff -/* Norstar core status flags */ -#define SISF_NS_BOOTDEV_MASK 0x0003 /* ROM core */ -#define SISF_NS_BOOTDEV_NOR 0x0000 /* ROM core */ -#define SISF_NS_BOOTDEV_NAND 0x0001 /* ROM core */ -#define SISF_NS_BOOTDEV_ROM 0x0002 /* ROM core */ -#define SISF_NS_BOOTDEV_OFFLOAD 0x0003 /* ROM core */ -#define SISF_NS_SKUVEC_MASK 0x000c /* ROM core */ - /* A register that is common to all cores to * communicate w/PMU regarding clock control. */ @@ -260,18 +232,4 @@ #define BISZ_BSSEND_IDX 6 /* 6: bss end */ #define BISZ_SIZE 7 /* descriptor size in 32-bit integers */ -/* Boot/Kernel related defintion and functions */ -#define SOC_BOOTDEV_ROM 0x00000001 -#define SOC_BOOTDEV_PFLASH 0x00000002 -#define SOC_BOOTDEV_SFLASH 0x00000004 -#define SOC_BOOTDEV_NANDFLASH 0x00000008 - -#define SOC_KNLDEV_NORFLASH 0x00000002 -#define SOC_KNLDEV_NANDFLASH 0x00000004 - -#ifndef _LANGUAGE_ASSEMBLY -int soc_boot_dev(void *sih); -int soc_knl_dev(void *sih); -#endif /* _LANGUAGE_ASSEMBLY */ - #endif /* _HNDSOC_H */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/linux_osl.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/linux_osl.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/linux_osl.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/linux_osl.h 2014-02-15 00:43:44.794014114 +0100 @@ -1,7 +1,7 @@ /* * Linux OS Independent Layer * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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: linux_osl.h 411126 2013-07-05 01:22:09Z $ + * $Id: linux_osl.h 354452 2012-08-31 04:59:17Z $ */ #ifndef _linux_osl_h_ @@ -67,9 +67,6 @@ extern void osl_assert(const char *exp, #define OSL_DELAY(usec) osl_delay(usec) extern void osl_delay(uint usec); -#define OSL_SLEEP(ms) osl_sleep(ms) -extern void osl_sleep(uint ms); - #define OSL_PCMCIA_READ_ATTR(osh, offset, buf, size) \ osl_pcmcia_read_attr((osh), (offset), (buf), (size)) #define OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size) \ @@ -95,6 +92,7 @@ extern struct pci_dev *osl_pci_device(os /* Pkttag flag should be part of public information */ typedef struct { bool pkttag; + uint pktalloced; /* Number of allocated packet buffers */ bool mmbus; /* Bus supports memory-mapped register accesses */ pktfree_cb_fn_t tx_fn; /* Callback function for PKTFREE */ void *tx_ctx; /* Context to the callback function */ @@ -141,8 +139,7 @@ extern void osl_dma_free_consistent(osl_ /* map/unmap shared (dma-able) memory */ #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, void *p, - hnddma_seg_map_t *txp_dmah); +extern uint osl_dma_map(osl_t *osh, void *va, uint size, int direction); extern void osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction); /* API for DMA addressing capability */ @@ -227,9 +224,6 @@ extern int osl_error(int bcmerror); #define OSL_UNCACHED(va) ((void *)va) #define OSL_CACHED(va) ((void *)va) -/* ARM NorthStar */ -#define OSL_CACHE_FLUSH(va, len) - #define OSL_PREF_RANGE_LD(va, sz) #define OSL_PREF_RANGE_ST(va, sz) @@ -262,77 +256,30 @@ extern int osl_error(int bcmerror); #include /* use current 2.4.x calling conventions */ /* packet primitives */ -#ifdef BCMDBG_CTRACE -#define PKTGET(osh, len, send) osl_pktget((osh), (len), __LINE__, __FILE__) -#define PKTDUP(osh, skb) osl_pktdup((osh), (skb), __LINE__, __FILE__) -#else #define PKTGET(osh, len, send) osl_pktget((osh), (len)) #define PKTDUP(osh, skb) osl_pktdup((osh), (skb)) -#endif /* BCMDBG_CTRACE */ #define PKTLIST_DUMP(osh, buf) #define PKTDBG_TRACE(osh, pkt, bit) #define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb), (send)) #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)) -#else -#define PKTGET_STATIC PKTGET -#define PKTFREE_STATIC PKTFREE #endif /* CONFIG_DHD_USE_STATIC_BUF */ #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)) -#define PKTTAILROOM(osh, skb) skb_tailroom((struct sk_buff*)(skb)) -#define PKTPADTAILROOM(osh, skb, padlen) osh_pktpadtailroom((osh), (skb), (padlen)) +#define PKTTAILROOM(osh, skb) ((((struct sk_buff*)(skb))->end)-(((struct sk_buff*)(skb))->tail)) #define PKTNEXT(osh, skb) (((struct sk_buff*)(skb))->next) #define PKTSETNEXT(osh, skb, x) (((struct sk_buff*)(skb))->next = (struct sk_buff*)(x)) #define PKTSETLEN(osh, skb, len) __skb_trim((struct sk_buff*)(skb), (len)) #define PKTPUSH(osh, skb, bytes) skb_push((struct sk_buff*)(skb), (bytes)) #define PKTPULL(osh, skb, bytes) skb_pull((struct sk_buff*)(skb), (bytes)) #define PKTTAG(skb) ((void*)(((struct sk_buff*)(skb))->cb)) +#define PKTALLOCED(osh) ((osl_pubinfo_t *)(osh))->pktalloced #define PKTSETPOOL(osh, skb, x, y) do {} while (0) #define PKTPOOL(osh, skb) FALSE #define PKTSHRINK(osh, m) (m) -#ifdef BCMDBG_CTRACE -#define DEL_CTRACE(zosh, zskb) { \ - unsigned long zflags; \ - spin_lock_irqsave(&(zosh)->ctrace_lock, zflags); \ - list_del(&(zskb)->ctrace_list); \ - (zosh)->ctrace_num--; \ - (zskb)->ctrace_start = 0; \ - (zskb)->ctrace_count = 0; \ - spin_unlock_irqrestore(&(zosh)->ctrace_lock, zflags); \ -} - -#define UPDATE_CTRACE(zskb, zfile, zline) { \ - struct sk_buff *_zskb = (struct sk_buff *)(zskb); \ - if (_zskb->ctrace_count < CTRACE_NUM) { \ - _zskb->func[_zskb->ctrace_count] = zfile; \ - _zskb->line[_zskb->ctrace_count] = zline; \ - _zskb->ctrace_count++; \ - } \ - else { \ - _zskb->func[_zskb->ctrace_start] = zfile; \ - _zskb->line[_zskb->ctrace_start] = zline; \ - _zskb->ctrace_start++; \ - if (_zskb->ctrace_start >= CTRACE_NUM) \ - _zskb->ctrace_start = 0; \ - } \ -} - -#define ADD_CTRACE(zosh, zskb, zfile, zline) { \ - unsigned long zflags; \ - spin_lock_irqsave(&(zosh)->ctrace_lock, zflags); \ - list_add(&(zskb)->ctrace_list, &(zosh)->ctrace_list); \ - (zosh)->ctrace_num++; \ - UPDATE_CTRACE(zskb, zfile, zline); \ - spin_unlock_irqrestore(&(zosh)->ctrace_lock, zflags); \ -} - -#define PKTCALLER(zskb) UPDATE_CTRACE((struct sk_buff *)zskb, (char *)__FUNCTION__, __LINE__) -#endif /* BCMDBG_CTRACE */ - #ifdef CTFPOOL #define CTFPOOL_REFILL_THRESH 3 typedef struct ctfpool { @@ -346,117 +293,66 @@ typedef struct ctfpool { uint fast_frees; uint slow_allocs; } ctfpool_t; - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) -#define FASTBUF (1 << 0) -#define PKTSETFAST(osh, skb) ((((struct sk_buff*)(skb))->pktc_flags) |= FASTBUF) -#define PKTCLRFAST(osh, skb) ((((struct sk_buff*)(skb))->pktc_flags) &= (~FASTBUF)) -#define PKTISFAST(osh, skb) ((((struct sk_buff*)(skb))->pktc_flags) & FASTBUF) -#define PKTFAST(osh, skb) (((struct sk_buff*)(skb))->pktc_flags) -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) #define FASTBUF (1 << 16) +#define CTFBUF (1 << 17) #define PKTSETFAST(osh, skb) ((((struct sk_buff*)(skb))->mac_len) |= FASTBUF) #define PKTCLRFAST(osh, skb) ((((struct sk_buff*)(skb))->mac_len) &= (~FASTBUF)) +#define PKTSETCTF(osh, skb) ((((struct sk_buff*)(skb))->mac_len) |= CTFBUF) +#define PKTCLRCTF(osh, skb) ((((struct sk_buff*)(skb))->mac_len) &= (~CTFBUF)) #define PKTISFAST(osh, skb) ((((struct sk_buff*)(skb))->mac_len) & FASTBUF) +#define PKTISCTF(osh, skb) ((((struct sk_buff*)(skb))->mac_len) & CTFBUF) #define PKTFAST(osh, skb) (((struct sk_buff*)(skb))->mac_len) #else #define FASTBUF (1 << 0) +#define CTFBUF (1 << 1) #define PKTSETFAST(osh, skb) ((((struct sk_buff*)(skb))->__unused) |= FASTBUF) #define PKTCLRFAST(osh, skb) ((((struct sk_buff*)(skb))->__unused) &= (~FASTBUF)) +#define PKTSETCTF(osh, skb) ((((struct sk_buff*)(skb))->__unused) |= CTFBUF) +#define PKTCLRCTF(osh, skb) ((((struct sk_buff*)(skb))->__unused) &= (~CTFBUF)) #define PKTISFAST(osh, skb) ((((struct sk_buff*)(skb))->__unused) & FASTBUF) +#define PKTISCTF(osh, skb) ((((struct sk_buff*)(skb))->__unused) & CTFBUF) #define PKTFAST(osh, skb) (((struct sk_buff*)(skb))->__unused) #endif /* 2.6.22 */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) -#define CTFPOOLPTR(osh, skb) (((struct sk_buff*)(skb))->ctfpool) -#define CTFPOOLHEAD(osh, skb) (((ctfpool_t *)((struct sk_buff*)(skb))->ctfpool)->head) -#else #define CTFPOOLPTR(osh, skb) (((struct sk_buff*)(skb))->sk) #define CTFPOOLHEAD(osh, skb) (((ctfpool_t *)((struct sk_buff*)(skb))->sk)->head) -#endif extern void *osl_ctfpool_add(osl_t *osh); extern void osl_ctfpool_replenish(osl_t *osh, uint thresh); extern int32 osl_ctfpool_init(osl_t *osh, uint numobj, uint size); extern void osl_ctfpool_cleanup(osl_t *osh); extern void osl_ctfpool_stats(osl_t *osh, void *b); -#else /* CTFPOOL */ -#define PKTSETFAST(osh, skb) -#define PKTCLRFAST(osh, skb) -#define PKTISFAST(osh, skb) (FALSE) #endif /* CTFPOOL */ -#define PKTSETCTF(osh, skb) -#define PKTCLRCTF(osh, skb) -#define PKTISCTF(osh, skb) (FALSE) #ifdef HNDCTF - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) -#define SKIPCT (1 << 2) -#define CHAINED (1 << 3) -#define PKTSETSKIPCT(osh, skb) (((struct sk_buff*)(skb))->pktc_flags |= SKIPCT) -#define PKTCLRSKIPCT(osh, skb) (((struct sk_buff*)(skb))->pktc_flags &= (~SKIPCT)) -#define PKTSKIPCT(osh, skb) (((struct sk_buff*)(skb))->pktc_flags & SKIPCT) -#define PKTSETCHAINED(osh, skb) (((struct sk_buff*)(skb))->pktc_flags |= CHAINED) -#define PKTCLRCHAINED(osh, skb) (((struct sk_buff*)(skb))->pktc_flags &= (~CHAINED)) -#define PKTISCHAINED(skb) (((struct sk_buff*)(skb))->pktc_flags & CHAINED) -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) #define SKIPCT (1 << 18) -#define CHAINED (1 << 19) #define PKTSETSKIPCT(osh, skb) (((struct sk_buff*)(skb))->mac_len |= SKIPCT) #define PKTCLRSKIPCT(osh, skb) (((struct sk_buff*)(skb))->mac_len &= (~SKIPCT)) #define PKTSKIPCT(osh, skb) (((struct sk_buff*)(skb))->mac_len & SKIPCT) -#define PKTSETCHAINED(osh, skb) (((struct sk_buff*)(skb))->mac_len |= CHAINED) -#define PKTCLRCHAINED(osh, skb) (((struct sk_buff*)(skb))->mac_len &= (~CHAINED)) -#define PKTISCHAINED(skb) (((struct sk_buff*)(skb))->mac_len & CHAINED) #else /* 2.6.22 */ #define SKIPCT (1 << 2) -#define CHAINED (1 << 3) #define PKTSETSKIPCT(osh, skb) (((struct sk_buff*)(skb))->__unused |= SKIPCT) #define PKTCLRSKIPCT(osh, skb) (((struct sk_buff*)(skb))->__unused &= (~SKIPCT)) #define PKTSKIPCT(osh, skb) (((struct sk_buff*)(skb))->__unused & SKIPCT) -#define PKTSETCHAINED(osh, skb) (((struct sk_buff*)(skb))->__unused |= CHAINED) -#define PKTCLRCHAINED(osh, skb) (((struct sk_buff*)(skb))->__unused &= (~CHAINED)) -#define PKTISCHAINED(skb) (((struct sk_buff*)(skb))->__unused & CHAINED) #endif /* 2.6.22 */ -typedef struct ctf_mark { - uint32 value; -} ctf_mark_t; -#define CTF_MARK(m) (m.value) #else /* HNDCTF */ #define PKTSETSKIPCT(osh, skb) #define PKTCLRSKIPCT(osh, skb) #define PKTSKIPCT(osh, skb) -#define CTF_MARK(m) 0 #endif /* HNDCTF */ 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 int osh_pktpadtailroom(osl_t *osh, void* skb, int pad); -#ifdef BCMDBG_CTRACE -#define PKT_CTRACE_DUMP(osh, b) osl_ctrace_dump((osh), (b)) -extern void *osl_pktget(osl_t *osh, uint len, int line, char *file); -extern void *osl_pkt_frmnative(osl_t *osh, void *skb, int line, char *file); -extern int osl_pkt_is_frmnative(osl_t *osh, struct sk_buff *pkt); -extern void *osl_pktdup(osl_t *osh, void *skb, int line, char *file); -struct bcmstrbuf; -extern void osl_ctrace_dump(osl_t *osh, struct bcmstrbuf *b); -#else 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); -#endif /* BCMDBG_CTRACE */ extern struct sk_buff *osl_pkt_tonative(osl_t *osh, void *pkt); -#ifdef BCMDBG_CTRACE -#define PKTFRMNATIVE(osh, skb) osl_pkt_frmnative(((osl_t *)osh), \ - (struct sk_buff*)(skb), __LINE__, __FILE__) -#define PKTISFRMNATIVE(osh, skb) osl_pkt_is_frmnative((osl_t *)(osh), (struct sk_buff *)(skb)) -#else #define PKTFRMNATIVE(osh, skb) osl_pkt_frmnative(((osl_t *)osh), (struct sk_buff*)(skb)) -#endif /* BCMDBG_CTRACE */ #define PKTTONATIVE(osh, pkt) osl_pkt_tonative((osl_t *)(osh), (pkt)) #define PKTLINK(skb) (((struct sk_buff*)(skb))->prev) @@ -469,24 +365,8 @@ extern struct sk_buff *osl_pkt_tonative( /* PKTSETSUMNEEDED and PKTSUMGOOD are not possible because skb->ip_summed is overloaded */ #define PKTSHARED(skb) (((struct sk_buff*)(skb))->cloned) -#ifdef CONFIG_NF_CONNTRACK_MARK -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -#define PKTMARK(p) (((struct sk_buff *)(p))->mark) -#define PKTSETMARK(p, m) ((struct sk_buff *)(p))->mark = (m) -#else /* !2.6.0 */ -#define PKTMARK(p) (((struct sk_buff *)(p))->nfmark) -#define PKTSETMARK(p, m) ((struct sk_buff *)(p))->nfmark = (m) -#endif /* 2.6.0 */ -#else /* CONFIG_NF_CONNTRACK_MARK */ -#define PKTMARK(p) 0 -#define PKTSETMARK(p, m) -#endif /* CONFIG_NF_CONNTRACK_MARK */ - -#define PKTALLOCED(osh) osl_pktalloced(osh) -extern uint osl_pktalloced(osl_t *osh); - #define DMA_MAP(osh, va, size, direction, p, dmah) \ - osl_dma_map((osh), (va), (size), (direction), (p), (dmah)) + osl_dma_map((osh), (va), (size), (direction)) #ifdef PKTC /* Use 8 bytes of skb tstamp field to store below info */ @@ -495,52 +375,33 @@ struct chain_node { unsigned int flags:3, pkts:9, bytes:20; }; -#define CHAIN_NODE(skb) ((struct chain_node*)(((struct sk_buff*)skb)->pktc_cb)) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14) +#define CHAIN_NODE(skb) ((struct chain_node*)&(((struct sk_buff*)skb)->tstamp)) +#else +#define CHAIN_NODE(skb) ((struct chain_node*)&(((struct sk_buff*)skb)->stamp)) +#endif -#define PKTCSETATTR(s, f, p, b) ({CHAIN_NODE(s)->flags = (f); CHAIN_NODE(s)->pkts = (p); \ - CHAIN_NODE(s)->bytes = (b);}) -#define PKTCCLRATTR(s) ({CHAIN_NODE(s)->flags = CHAIN_NODE(s)->pkts = \ - CHAIN_NODE(s)->bytes = 0;}) -#define PKTCGETATTR(s) (CHAIN_NODE(s)->flags << 29 | CHAIN_NODE(s)->pkts << 20 | \ - CHAIN_NODE(s)->bytes) #define PKTCCNT(skb) (CHAIN_NODE(skb)->pkts) #define PKTCLEN(skb) (CHAIN_NODE(skb)->bytes) -#define PKTCGETFLAGS(skb) (CHAIN_NODE(skb)->flags) -#define PKTCSETFLAGS(skb, f) (CHAIN_NODE(skb)->flags = (f)) -#define PKTCCLRFLAGS(skb) (CHAIN_NODE(skb)->flags = 0) #define PKTCFLAGS(skb) (CHAIN_NODE(skb)->flags) -#define PKTCSETCNT(skb, c) (CHAIN_NODE(skb)->pkts = (c)) -#define PKTCINCRCNT(skb) (CHAIN_NODE(skb)->pkts++) -#define PKTCADDCNT(skb, c) (CHAIN_NODE(skb)->pkts += (c)) -#define PKTCSETLEN(skb, l) (CHAIN_NODE(skb)->bytes = (l)) -#define PKTCADDLEN(skb, l) (CHAIN_NODE(skb)->bytes += (l)) +#define PKTCSETCNT(skb, c) (CHAIN_NODE(skb)->pkts = (c) & ((1 << 9) - 1)) +#define PKTCSETLEN(skb, l) (CHAIN_NODE(skb)->bytes = (l) & ((1 << 20) - 1)) #define PKTCSETFLAG(skb, fb) (CHAIN_NODE(skb)->flags |= (fb)) #define PKTCCLRFLAG(skb, fb) (CHAIN_NODE(skb)->flags &= ~(fb)) #define PKTCLINK(skb) (CHAIN_NODE(skb)->link) #define PKTSETCLINK(skb, x) (CHAIN_NODE(skb)->link = (struct sk_buff*)(x)) +#define PKTISCHAINED(skb) (PKTCLINK(skb) != NULL) #define FOREACH_CHAINED_PKT(skb, nskb) \ for (; (skb) != NULL; (skb) = (nskb)) \ - if ((nskb) = (PKTISCHAINED(skb) ? PKTCLINK(skb) : NULL), \ - PKTSETCLINK((skb), NULL), 1) + if ((nskb) = PKTCLINK(skb), PKTSETCLINK((skb), NULL), 1) #define PKTCFREE(osh, skb, send) \ do { \ void *nskb; \ ASSERT((skb) != NULL); \ FOREACH_CHAINED_PKT((skb), nskb) { \ - PKTCLRCHAINED((osh), (skb)); \ - PKTCCLRFLAGS((skb)); \ PKTFREE((osh), (skb), (send)); \ } \ } while (0) -#define PKTCENQTAIL(h, t, p) \ -do { \ - if ((t) == NULL) { \ - (h) = (t) = (p); \ - } else { \ - PKTSETCLINK((t), (p)); \ - (t) = (p); \ - } \ -} while (0) #endif /* PKTC */ #else /* ! BCMDRIVER */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/linuxver.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/linuxver.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/linuxver.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/linuxver.h 2014-02-15 00:43:44.795014136 +0100 @@ -2,7 +2,7 @@ * 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-2013, Broadcom Corporation + * 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 @@ -22,13 +22,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: linuxver.h 417757 2013-08-12 12:24:45Z $ + * $Id: linuxver.h 366812 2012-11-05 13:49:32Z $ */ #ifndef _linuxver_h_ #define _linuxver_h_ -#include #include #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) #include @@ -69,7 +68,6 @@ #include #include #include -#include #include #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) #include @@ -99,10 +97,7 @@ #endif #endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 41) */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) -#define DAEMONIZE(a) -#elif ((LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)) && \ - (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) #define DAEMONIZE(a) daemonize(a); \ allow_signal(SIGKILL); \ allow_signal(SIGTERM); @@ -155,11 +150,7 @@ typedef irqreturn_t(*FN_ISR) (int irq, v #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) #include -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) */ - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)) -#include -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) */ +#endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) #include @@ -173,6 +164,7 @@ typedef irqreturn_t(*FN_ISR) (int irq, v #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30) */ + #ifndef __exit #define __exit #endif @@ -496,11 +488,9 @@ pci_restore_state(struct pci_dev *dev, u #define SET_NETDEV_DEV(net, pdev) do {} while (0) #endif -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0)) #ifndef HAVE_FREE_NETDEV #define free_netdev(dev) kfree(dev) #endif -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0) */ #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) /* struct packet_type redefined in 2.6.x */ @@ -519,16 +509,13 @@ pci_restore_state(struct pci_dev *dev, u #endif typedef struct { - void *parent; /* some external entity that the thread supposed to work for */ - char *proc_name; + void *parent; /* some external entity that the thread supposed to work for */ struct task_struct *p_task; - long thr_pid; - int prio; /* priority */ + long thr_pid; + int prio; /* priority */ struct semaphore sema; int terminated; struct completion completed; - spinlock_t spinlock; - int up_cnt; } tsk_ctl_t; @@ -540,63 +527,38 @@ typedef struct { #define DBG_THR(x) #endif -static inline bool binary_sema_down(tsk_ctl_t *tsk) -{ - if (down_interruptible(&tsk->sema) == 0) { - unsigned long flags = 0; - spin_lock_irqsave(&tsk->spinlock, flags); - if (tsk->up_cnt == 1) - tsk->up_cnt--; - else { - DBG_THR(("dhd_dpc_thread: Unexpected up_cnt %d\n", tsk->up_cnt)); - } - spin_unlock_irqrestore(&tsk->spinlock, flags); - return FALSE; - } else - return TRUE; -} - -static inline bool binary_sema_up(tsk_ctl_t *tsk) -{ - bool sem_up = FALSE; - unsigned long flags = 0; - - spin_lock_irqsave(&tsk->spinlock, flags); - if (tsk->up_cnt == 0) { - tsk->up_cnt++; - sem_up = TRUE; - } else if (tsk->up_cnt == 1) { - /* dhd_sched_dpc: dpc is alread up! */ - } else - DBG_THR(("dhd_sched_dpc: unexpected up cnt %d!\n", tsk->up_cnt)); - - spin_unlock_irqrestore(&tsk->spinlock, flags); - - if (sem_up) - up(&tsk->sema); - - return sem_up; -} - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) #define SMP_RD_BARRIER_DEPENDS(x) smp_read_barrier_depends(x) #else #define SMP_RD_BARRIER_DEPENDS(x) smp_rmb(x) #endif -#define PROC_START(thread_func, owner, tsk_ctl, flags, name) \ + +#define PROC_START(thread_func, owner, tsk_ctl, flags) \ +{ \ + sema_init(&((tsk_ctl)->sema), 0); \ + init_completion(&((tsk_ctl)->completed)); \ + (tsk_ctl)->parent = owner; \ + (tsk_ctl)->terminated = FALSE; \ + (tsk_ctl)->thr_pid = kernel_thread(thread_func, tsk_ctl, flags); \ + DBG_THR(("%s thr:%lx created\n", __FUNCTION__, (tsk_ctl)->thr_pid)); \ + if ((tsk_ctl)->thr_pid > 0) \ + wait_for_completion(&((tsk_ctl)->completed)); \ + DBG_THR(("%s thr:%lx started\n", __FUNCTION__, (tsk_ctl)->thr_pid)); \ +} + +#ifdef USE_KTHREAD_API +#define PROC_START2(thread_func, owner, tsk_ctl, flags, name) \ { \ sema_init(&((tsk_ctl)->sema), 0); \ init_completion(&((tsk_ctl)->completed)); \ (tsk_ctl)->parent = owner; \ - (tsk_ctl)->proc_name = name; \ (tsk_ctl)->terminated = FALSE; \ (tsk_ctl)->p_task = kthread_run(thread_func, tsk_ctl, (char*)name); \ (tsk_ctl)->thr_pid = (tsk_ctl)->p_task->pid; \ - spin_lock_init(&((tsk_ctl)->spinlock)); \ - DBG_THR(("%s(): thread:%s:%lx started\n", __FUNCTION__, \ - (tsk_ctl)->proc_name, (tsk_ctl)->thr_pid)); \ + DBG_THR(("%s thr:%lx created\n", __FUNCTION__, (tsk_ctl)->thr_pid)); \ } +#endif #define PROC_STOP(tsk_ctl) \ { \ @@ -604,8 +566,7 @@ static inline bool binary_sema_up(tsk_ct smp_wmb(); \ up(&((tsk_ctl)->sema)); \ wait_for_completion(&((tsk_ctl)->completed)); \ - DBG_THR(("%s(): thread:%s:%lx terminated OK\n", __FUNCTION__, \ - (tsk_ctl)->proc_name, (tsk_ctl)->thr_pid)); \ + DBG_THR(("%s thr:%lx terminated OK\n", __FUNCTION__, (tsk_ctl)->thr_pid)); \ (tsk_ctl)->thr_pid = -1; \ } @@ -698,16 +659,4 @@ not match our unaligned address for < 2. #define netdev_priv(dev) dev->priv #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) -#define RANDOM32 prandom_u32 -#else -#define RANDOM32 random32 -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) */ - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) -#define SRANDOM32(entropy) prandom_seed(entropy) -#else -#define SRANDOM32(entropy) srandom32(entropy) -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) */ - #endif /* _linuxver_h_ */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/Makefile linux-sunxi-new/drivers/net/wireless/bcmdhd/include/Makefile --- linux-sunxi/drivers/net/wireless/bcmdhd/include/Makefile 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/Makefile 2014-02-15 00:43:44.794014114 +0100 @@ -10,10 +10,10 @@ # # Copyright 2005, Broadcom, Inc. # -# $Id: Makefile 347587 2012-07-27 09:13:31Z prakashd $ +# $Id: Makefile 241686 2011-02-19 00:22:45Z prakashd $ # -export SRCBASE:=.. +SRCBASE := .. TARGETS := epivers.h @@ -23,11 +23,11 @@ endif all release: epivers compvers -# Generate epivers.h for native branch url +# Generate epivers.h for native branch version epivers: bash epivers.sh -# Generate component versions based on component url +# Generate epivers.h for native branch version compvers: @if [ -s "compvers.sh" ]; then \ echo "Generating component versions, if any"; \ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/miniopt.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/miniopt.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/miniopt.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/miniopt.h 2014-02-15 00:43:44.794014114 +0100 @@ -1,7 +1,7 @@ /* * Command line options parser. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/msgtrace.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/msgtrace.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/msgtrace.h 2014-01-27 01:30:30.101433269 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/msgtrace.h 2014-02-15 00:43:44.793014092 +0100 @@ -1,7 +1,7 @@ /* * Trace messages sent over HBUS * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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 369735 2012-11-19 22:50:22Z $ + * $Id: msgtrace.h 281527 2011-09-02 17:12:53Z $ */ #ifndef _MSGTRACE_H @@ -40,14 +40,11 @@ /* Message trace header */ typedef BWL_PRE_PACKED_STRUCT struct msgtrace_hdr { uint8 version; - uint8 trace_type; -#define MSGTRACE_HDR_TYPE_MSG 0 -#define MSGTRACE_HDR_TYPE_LOG 1 + uint8 spare; uint16 len; /* Len of the trace */ uint32 seqnum; /* Sequence number of message. Useful if the messsage has been lost * because of DMA error or a bus reset (ex: SDIO Func2) */ - /* Msgtrace type only */ uint32 discarded_bytes; /* Number of discarded bytes because of trace overflow */ uint32 discarded_printf; /* Number of discarded printf because of trace overflow */ } BWL_POST_PACKED_STRUCT msgtrace_hdr_t; @@ -66,7 +63,7 @@ typedef void (*msgtrace_func_send_t)(voi uint16 hdrlen, uint8 *buf, uint16 buflen); extern void msgtrace_start(void); extern void msgtrace_stop(void); -extern int msgtrace_sent(void); +extern void msgtrace_sent(void); extern void msgtrace_put(char *buf, int count); extern void msgtrace_init(void *hdl1, void *hdl2, msgtrace_func_send_t func_send); extern bool msgtrace_event_enabled(void); diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/osl.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/osl.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/osl.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/osl.h 2014-02-15 00:43:44.794014114 +0100 @@ -1,7 +1,7 @@ /* * OS Abstraction Layer * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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: osl.h 370064 2012-11-20 21:00:25Z $ + * $Id: osl.h 320905 2012-03-13 15:33:25Z $ */ #ifndef _osl_h_ @@ -71,33 +71,20 @@ typedef void (*osl_wreg_fn_t)(void *ctx #endif /* OSL_SYSUPTIME */ #if !defined(PKTC) -#define PKTCGETATTR(s) (0) -#define PKTCSETATTR(skb, f, p, b) -#define PKTCCLRATTR(skb) -#define PKTCCNT(skb) (1) -#define PKTCLEN(skb) PKTLEN(NULL, skb) -#define PKTCGETFLAGS(skb) (0) -#define PKTCSETFLAGS(skb, f) -#define PKTCCLRFLAGS(skb) +#define PKTCCNT(skb) (0) +#define PKTCLEN(skb) (0) #define PKTCFLAGS(skb) (0) #define PKTCSETCNT(skb, c) -#define PKTCINCRCNT(skb) -#define PKTCADDCNT(skb, c) #define PKTCSETLEN(skb, l) -#define PKTCADDLEN(skb, l) #define PKTCSETFLAG(skb, fb) #define PKTCCLRFLAG(skb, fb) -#define PKTCLINK(skb) NULL -#define PKTSETCLINK(skb, x) +#define PKTCLINK(skb) PKTLINK(skb) +#define PKTSETCLINK(skb, x) PKTSETLINK((skb), (x)) +#define PKTISCHAINED(skb) FALSE #define FOREACH_CHAINED_PKT(skb, nskb) \ for ((nskb) = NULL; (skb) != NULL; (skb) = (nskb)) #define PKTCFREE PKTFREE -#endif /* !linux || !PKTC */ - -#ifndef HNDCTF -#define PKTSETCHAINED(osh, skb) -#define PKTCLRCHAINED(osh, skb) -#define PKTISCHAINED(skb) (FALSE) #endif + #endif /* _osl_h_ */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/packed_section_end.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/packed_section_end.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/packed_section_end.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/packed_section_end.h 2014-02-15 00:43:44.794014114 +0100 @@ -15,7 +15,7 @@ * #include * * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/packed_section_start.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/packed_section_start.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/packed_section_start.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/packed_section_start.h 2014-02-15 00:43:44.794014114 +0100 @@ -15,7 +15,7 @@ * #include * * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/pcicfg.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/pcicfg.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/pcicfg.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/pcicfg.h 2014-02-15 00:43:44.794014114 +0100 @@ -1,7 +1,7 @@ /* * pcicfg.h: PCI configuration constants and structures. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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: pcicfg.h 346935 2012-07-25 00:24:55Z $ + * $Id: pcicfg.h 309193 2012-01-19 00:03:57Z $ */ #ifndef _h_pcicfg_ @@ -58,7 +58,6 @@ #define PCI_CFG_PIN 0x3d #define PCI_CFG_MINGNT 0x3e #define PCI_CFG_MAXLAT 0x3f -#define PCI_CFG_DEVCTRL 0xd8 #define PCI_BAR0_WIN 0x80 /* backplane addres space accessed by BAR0 */ #define PCI_BAR1_WIN 0x84 /* backplane addres space accessed by BAR1 */ #define PCI_SPROM_CONTROL 0x88 /* sprom property control */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/proto/802.11_bta.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/proto/802.11_bta.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/proto/802.11_bta.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/proto/802.11_bta.h 2014-02-15 00:43:44.793014092 +0100 @@ -0,0 +1,45 @@ +/* + * BT-AMP (BlueTooth Alternate Mac and Phy) 802.11 PAL (Protocol Adaptation Layer) + * + * 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: 802.11_bta.h 294267 2011-11-04 23:41:52Z $ +*/ + +#ifndef _802_11_BTA_H_ +#define _802_11_BTA_H_ + +#define BT_SIG_SNAP_MPROT "\xAA\xAA\x03\x00\x19\x58" + +/* BT-AMP 802.11 PAL Protocols */ +#define BTA_PROT_L2CAP 1 +#define BTA_PROT_ACTIVITY_REPORT 2 +#define BTA_PROT_SECURITY 3 +#define BTA_PROT_LINK_SUPERVISION_REQUEST 4 +#define BTA_PROT_LINK_SUPERVISION_REPLY 5 + +/* BT-AMP 802.11 PAL AMP_ASSOC Type IDs */ +#define BTA_TYPE_ID_MAC_ADDRESS 1 +#define BTA_TYPE_ID_PREFERRED_CHANNELS 2 +#define BTA_TYPE_ID_CONNECTED_CHANNELS 3 +#define BTA_TYPE_ID_CAPABILITIES 4 +#define BTA_TYPE_ID_VERSION 5 +#endif /* _802_11_bta_h_ */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/proto/802.11e.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/proto/802.11e.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/proto/802.11e.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/proto/802.11e.h 2014-02-15 00:43:44.793014092 +0100 @@ -0,0 +1,131 @@ +/* + * 802.11e protocol header file + * + * 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: 802.11e.h 241182 2011-02-17 21:50:03Z $ + */ + +#ifndef _802_11e_H_ +#define _802_11e_H_ + +#ifndef _TYPEDEFS_H_ +#include +#endif + +/* This marks the start of a packed structure section. */ +#include + + +/* WME Traffic Specification (TSPEC) element */ +#define WME_TSPEC_HDR_LEN 2 /* WME TSPEC header length */ +#define WME_TSPEC_BODY_OFF 2 /* WME TSPEC body offset */ + +#define WME_CATEGORY_CODE_OFFSET 0 /* WME Category code offset */ +#define WME_ACTION_CODE_OFFSET 1 /* WME Action code offset */ +#define WME_TOKEN_CODE_OFFSET 2 /* WME Token code offset */ +#define WME_STATUS_CODE_OFFSET 3 /* WME Status code offset */ + +BWL_PRE_PACKED_STRUCT struct tsinfo { + uint8 octets[3]; +} BWL_POST_PACKED_STRUCT; + +typedef struct tsinfo tsinfo_t; + +/* 802.11e TSPEC IE */ +typedef BWL_PRE_PACKED_STRUCT struct tspec { + uint8 oui[DOT11_OUI_LEN]; /* WME_OUI */ + uint8 type; /* WME_TYPE */ + uint8 subtype; /* WME_SUBTYPE_TSPEC */ + uint8 version; /* WME_VERSION */ + tsinfo_t tsinfo; /* TS Info bit field */ + uint16 nom_msdu_size; /* (Nominal or fixed) MSDU Size (bytes) */ + uint16 max_msdu_size; /* Maximum MSDU Size (bytes) */ + uint32 min_srv_interval; /* Minimum Service Interval (us) */ + uint32 max_srv_interval; /* Maximum Service Interval (us) */ + uint32 inactivity_interval; /* Inactivity Interval (us) */ + uint32 suspension_interval; /* Suspension Interval (us) */ + uint32 srv_start_time; /* Service Start Time (us) */ + uint32 min_data_rate; /* Minimum Data Rate (bps) */ + uint32 mean_data_rate; /* Mean Data Rate (bps) */ + uint32 peak_data_rate; /* Peak Data Rate (bps) */ + uint32 max_burst_size; /* Maximum Burst Size (bytes) */ + uint32 delay_bound; /* Delay Bound (us) */ + uint32 min_phy_rate; /* Minimum PHY Rate (bps) */ + uint16 surplus_bw; /* Surplus Bandwidth Allowance (range 1.0-8.0) */ + uint16 medium_time; /* Medium Time (32 us/s periods) */ +} BWL_POST_PACKED_STRUCT tspec_t; + +#define WME_TSPEC_LEN (sizeof(tspec_t)) /* not including 2-bytes of header */ + +/* ts_info */ +/* 802.1D priority is duplicated - bits 13-11 AND bits 3-1 */ +#define TS_INFO_TID_SHIFT 1 /* TS info. TID shift */ +#define TS_INFO_TID_MASK (0xf << TS_INFO_TID_SHIFT) /* TS info. TID mask */ +#define TS_INFO_CONTENTION_SHIFT 7 /* TS info. contention shift */ +#define TS_INFO_CONTENTION_MASK (0x1 << TS_INFO_CONTENTION_SHIFT) /* TS info. contention mask */ +#define TS_INFO_DIRECTION_SHIFT 5 /* TS info. direction shift */ +#define TS_INFO_DIRECTION_MASK (0x3 << TS_INFO_DIRECTION_SHIFT) /* TS info. direction mask */ +#define TS_INFO_PSB_SHIFT 2 /* TS info. PSB bit Shift */ +#define TS_INFO_PSB_MASK (1 << TS_INFO_PSB_SHIFT) /* TS info. PSB mask */ +#define TS_INFO_UPLINK (0 << TS_INFO_DIRECTION_SHIFT) /* TS info. uplink */ +#define TS_INFO_DOWNLINK (1 << TS_INFO_DIRECTION_SHIFT) /* TS info. downlink */ +#define TS_INFO_BIDIRECTIONAL (3 << TS_INFO_DIRECTION_SHIFT) /* TS info. bidirectional */ +#define TS_INFO_USER_PRIO_SHIFT 3 /* TS info. user priority shift */ +/* TS info. user priority mask */ +#define TS_INFO_USER_PRIO_MASK (0x7 << TS_INFO_USER_PRIO_SHIFT) + +/* Macro to get/set bit(s) field in TSINFO */ +#define WLC_CAC_GET_TID(pt) ((((pt).octets[0]) & TS_INFO_TID_MASK) >> TS_INFO_TID_SHIFT) +#define WLC_CAC_GET_DIR(pt) ((((pt).octets[0]) & \ + TS_INFO_DIRECTION_MASK) >> TS_INFO_DIRECTION_SHIFT) +#define WLC_CAC_GET_PSB(pt) ((((pt).octets[1]) & TS_INFO_PSB_MASK) >> TS_INFO_PSB_SHIFT) +#define WLC_CAC_GET_USER_PRIO(pt) ((((pt).octets[1]) & \ + TS_INFO_USER_PRIO_MASK) >> TS_INFO_USER_PRIO_SHIFT) + +#define WLC_CAC_SET_TID(pt, id) ((((pt).octets[0]) & (~TS_INFO_TID_MASK)) | \ + ((id) << TS_INFO_TID_SHIFT)) +#define WLC_CAC_SET_USER_PRIO(pt, prio) ((((pt).octets[0]) & (~TS_INFO_USER_PRIO_MASK)) | \ + ((prio) << TS_INFO_USER_PRIO_SHIFT)) + +/* 802.11e QBSS Load IE */ +#define QBSS_LOAD_IE_LEN 5 /* QBSS Load IE length */ +#define QBSS_LOAD_AAC_OFF 3 /* AAC offset in IE */ + +#define CAC_ADDTS_RESP_TIMEOUT 300 /* default ADDTS response timeout in ms */ + +/* 802.11e ADDTS status code */ +#define DOT11E_STATUS_ADMISSION_ACCEPTED 0 /* TSPEC Admission accepted status */ +#define DOT11E_STATUS_ADDTS_INVALID_PARAM 1 /* TSPEC invalid parameter status */ +#define DOT11E_STATUS_ADDTS_REFUSED_NSBW 3 /* ADDTS refused (non-sufficient BW) */ +#define DOT11E_STATUS_ADDTS_REFUSED_AWHILE 47 /* ADDTS refused but could retry later */ + +/* 802.11e DELTS status code */ +#define DOT11E_STATUS_QSTA_LEAVE_QBSS 36 /* STA leave QBSS */ +#define DOT11E_STATUS_END_TS 37 /* END TS */ +#define DOT11E_STATUS_UNKNOWN_TS 38 /* UNKNOWN TS */ +#define DOT11E_STATUS_QSTA_REQ_TIMEOUT 39 /* STA ADDTS request timeout */ + + +/* This marks the end of a packed structure section. */ +#include + +#endif /* _802_11e_CAC_H_ */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/proto/802.11.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/proto/802.11.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/proto/802.11.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/proto/802.11.h 2014-02-15 00:43:44.793014092 +0100 @@ -0,0 +1,2355 @@ +/* + * 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 types and constants relating to 802.11 + * + * $Id: 802.11.h 346820 2012-07-24 13:53:12Z $ + */ + +#ifndef _802_11_H_ +#define _802_11_H_ + +#ifndef _TYPEDEFS_H_ +#include +#endif + +#ifndef _NET_ETHERNET_H_ +#include +#endif + +#include + +/* This marks the start of a packed structure section. */ +#include + + +#define DOT11_TU_TO_US 1024 /* 802.11 Time Unit is 1024 microseconds */ + +/* Generic 802.11 frame constants */ +#define DOT11_A3_HDR_LEN 24 /* d11 header length with A3 */ +#define DOT11_A4_HDR_LEN 30 /* d11 header length with A4 */ +#define DOT11_MAC_HDR_LEN DOT11_A3_HDR_LEN /* MAC header length */ +#define DOT11_FCS_LEN 4 /* d11 FCS length */ +#define DOT11_ICV_LEN 4 /* d11 ICV length */ +#define DOT11_ICV_AES_LEN 8 /* d11 ICV/AES length */ +#define DOT11_QOS_LEN 2 /* d11 QoS length */ +#define DOT11_HTC_LEN 4 /* d11 HT Control field length */ + +#define DOT11_KEY_INDEX_SHIFT 6 /* d11 key index shift */ +#define DOT11_IV_LEN 4 /* d11 IV length */ +#define DOT11_IV_TKIP_LEN 8 /* d11 IV TKIP length */ +#define DOT11_IV_AES_OCB_LEN 4 /* d11 IV/AES/OCB length */ +#define DOT11_IV_AES_CCM_LEN 8 /* d11 IV/AES/CCM length */ +#define DOT11_IV_MAX_LEN 8 /* maximum iv len for any encryption */ + +/* Includes MIC */ +#define DOT11_MAX_MPDU_BODY_LEN 2304 /* max MPDU body length */ +/* A4 header + QoS + CCMP + PDU + ICV + FCS = 2352 */ +#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) /* d11 max MPDU length */ + +#define DOT11_MAX_SSID_LEN 32 /* d11 max ssid length */ + +/* dot11RTSThreshold */ +#define DOT11_DEFAULT_RTS_LEN 2347 /* d11 default RTS length */ +#define DOT11_MAX_RTS_LEN 2347 /* d11 max RTS length */ + +/* dot11FragmentationThreshold */ +#define DOT11_MIN_FRAG_LEN 256 /* d11 min fragmentation length */ +#define DOT11_MAX_FRAG_LEN 2346 /* Max frag is also limited by aMPDUMaxLength + * of the attached PHY + */ +#define DOT11_DEFAULT_FRAG_LEN 2346 /* d11 default fragmentation length */ + +/* dot11BeaconPeriod */ +#define DOT11_MIN_BEACON_PERIOD 1 /* d11 min beacon period */ +#define DOT11_MAX_BEACON_PERIOD 0xFFFF /* d11 max beacon period */ + +/* dot11DTIMPeriod */ +#define DOT11_MIN_DTIM_PERIOD 1 /* d11 min DTIM period */ +#define DOT11_MAX_DTIM_PERIOD 0xFF /* d11 max DTIM period */ + +/* 802.2 LLC/SNAP header used by 802.11 per 802.1H */ +#define DOT11_LLC_SNAP_HDR_LEN 8 /* d11 LLC/SNAP header length */ +#define DOT11_OUI_LEN 3 /* d11 OUI length */ +BWL_PRE_PACKED_STRUCT struct dot11_llc_snap_header { + uint8 dsap; /* always 0xAA */ + uint8 ssap; /* always 0xAA */ + uint8 ctl; /* always 0x03 */ + uint8 oui[DOT11_OUI_LEN]; /* RFC1042: 0x00 0x00 0x00 + * Bridge-Tunnel: 0x00 0x00 0xF8 + */ + uint16 type; /* ethertype */ +} BWL_POST_PACKED_STRUCT; + +/* RFC1042 header used by 802.11 per 802.1H */ +#define RFC1042_HDR_LEN (ETHER_HDR_LEN + DOT11_LLC_SNAP_HDR_LEN) /* RCF1042 header length */ + +/* Generic 802.11 MAC header */ +/* + * N.B.: This struct reflects the full 4 address 802.11 MAC header. + * The fields are defined such that the shorter 1, 2, and 3 + * address headers just use the first k fields. + */ +BWL_PRE_PACKED_STRUCT struct dot11_header { + uint16 fc; /* frame control */ + uint16 durid; /* duration/ID */ + struct ether_addr a1; /* address 1 */ + struct ether_addr a2; /* address 2 */ + struct ether_addr a3; /* address 3 */ + uint16 seq; /* sequence control */ + struct ether_addr a4; /* address 4 */ +} BWL_POST_PACKED_STRUCT; + +/* Control frames */ + +BWL_PRE_PACKED_STRUCT struct dot11_rts_frame { + uint16 fc; /* frame control */ + uint16 durid; /* duration/ID */ + struct ether_addr ra; /* receiver address */ + struct ether_addr ta; /* transmitter address */ +} BWL_POST_PACKED_STRUCT; +#define DOT11_RTS_LEN 16 /* d11 RTS frame length */ + +BWL_PRE_PACKED_STRUCT struct dot11_cts_frame { + uint16 fc; /* frame control */ + uint16 durid; /* duration/ID */ + struct ether_addr ra; /* receiver address */ +} BWL_POST_PACKED_STRUCT; +#define DOT11_CTS_LEN 10 /* d11 CTS frame length */ + +BWL_PRE_PACKED_STRUCT struct dot11_ack_frame { + uint16 fc; /* frame control */ + uint16 durid; /* duration/ID */ + struct ether_addr ra; /* receiver address */ +} BWL_POST_PACKED_STRUCT; +#define DOT11_ACK_LEN 10 /* d11 ACK frame length */ + +BWL_PRE_PACKED_STRUCT struct dot11_ps_poll_frame { + uint16 fc; /* frame control */ + uint16 durid; /* AID */ + struct ether_addr bssid; /* receiver address, STA in AP */ + struct ether_addr ta; /* transmitter address */ +} BWL_POST_PACKED_STRUCT; +#define DOT11_PS_POLL_LEN 16 /* d11 PS poll frame length */ + +BWL_PRE_PACKED_STRUCT struct dot11_cf_end_frame { + uint16 fc; /* frame control */ + uint16 durid; /* duration/ID */ + struct ether_addr ra; /* receiver address */ + struct ether_addr bssid; /* transmitter address, STA in AP */ +} BWL_POST_PACKED_STRUCT; +#define DOT11_CS_END_LEN 16 /* d11 CF-END frame length */ + +/* RWL wifi protocol: The Vendor Specific Action frame is defined for vendor-specific signaling +* category+OUI+vendor specific content ( this can be variable) +*/ +BWL_PRE_PACKED_STRUCT struct dot11_action_wifi_vendor_specific { + 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; + +/* generic vender specific action frame with variable length */ +BWL_PRE_PACKED_STRUCT struct dot11_action_vs_frmhdr { + 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 BCM_ACTION_OUI_BYTE0 0x00 +#define BCM_ACTION_OUI_BYTE1 0x90 +#define BCM_ACTION_OUI_BYTE2 0x4c + +/* BA/BAR Control parameters */ +#define DOT11_BA_CTL_POLICY_NORMAL 0x0000 /* normal ack */ +#define DOT11_BA_CTL_POLICY_NOACK 0x0001 /* no ack */ +#define DOT11_BA_CTL_POLICY_MASK 0x0001 /* ack policy mask */ + +#define DOT11_BA_CTL_MTID 0x0002 /* multi tid BA */ +#define DOT11_BA_CTL_COMPRESSED 0x0004 /* compressed bitmap */ + +#define DOT11_BA_CTL_NUMMSDU_MASK 0x0FC0 /* num msdu in bitmap mask */ +#define DOT11_BA_CTL_NUMMSDU_SHIFT 6 /* num msdu in bitmap shift */ + +#define DOT11_BA_CTL_TID_MASK 0xF000 /* tid mask */ +#define DOT11_BA_CTL_TID_SHIFT 12 /* tid shift */ + +/* control frame header (BA/BAR) */ +BWL_PRE_PACKED_STRUCT struct dot11_ctl_header { + uint16 fc; /* frame control */ + uint16 durid; /* duration/ID */ + struct ether_addr ra; /* receiver address */ + struct ether_addr ta; /* transmitter address */ +} BWL_POST_PACKED_STRUCT; +#define DOT11_CTL_HDR_LEN 16 /* control frame hdr len */ + +/* BAR frame payload */ +BWL_PRE_PACKED_STRUCT struct dot11_bar { + uint16 bar_control; /* BAR Control */ + uint16 seqnum; /* Starting Sequence control */ +} BWL_POST_PACKED_STRUCT; +#define DOT11_BAR_LEN 4 /* BAR frame payload length */ + +#define DOT11_BA_BITMAP_LEN 128 /* bitmap length */ +#define DOT11_BA_CMP_BITMAP_LEN 8 /* compressed bitmap length */ +/* BA frame payload */ +BWL_PRE_PACKED_STRUCT struct dot11_ba { + uint16 ba_control; /* BA Control */ + uint16 seqnum; /* Starting Sequence control */ + uint8 bitmap[DOT11_BA_BITMAP_LEN]; /* Block Ack Bitmap */ +} BWL_POST_PACKED_STRUCT; +#define DOT11_BA_LEN 4 /* BA frame payload len (wo bitmap) */ + +/* Management frame header */ +BWL_PRE_PACKED_STRUCT struct dot11_management_header { + uint16 fc; /* frame control */ + uint16 durid; /* duration/ID */ + struct ether_addr da; /* receiver address */ + struct ether_addr sa; /* transmitter address */ + struct ether_addr bssid; /* BSS ID */ + uint16 seq; /* sequence control */ +} BWL_POST_PACKED_STRUCT; +#define DOT11_MGMT_HDR_LEN 24 /* d11 management header length */ + +/* Management frame payloads */ + +BWL_PRE_PACKED_STRUCT struct dot11_bcn_prb { + uint32 timestamp[2]; + uint16 beacon_interval; + uint16 capability; +} BWL_POST_PACKED_STRUCT; +#define DOT11_BCN_PRB_LEN 12 /* 802.11 beacon/probe frame fixed length */ +#define DOT11_BCN_PRB_FIXED_LEN 12 /* 802.11 beacon/probe frame fixed length */ + +BWL_PRE_PACKED_STRUCT struct dot11_auth { + uint16 alg; /* algorithm */ + uint16 seq; /* sequence control */ + uint16 status; /* status code */ +} BWL_POST_PACKED_STRUCT; +#define DOT11_AUTH_FIXED_LEN 6 /* length of auth frame without challenge IE */ + +BWL_PRE_PACKED_STRUCT struct dot11_assoc_req { + uint16 capability; /* capability information */ + uint16 listen; /* listen interval */ +} BWL_POST_PACKED_STRUCT; +#define DOT11_ASSOC_REQ_FIXED_LEN 4 /* length of assoc frame without info elts */ + +BWL_PRE_PACKED_STRUCT struct dot11_reassoc_req { + uint16 capability; /* capability information */ + uint16 listen; /* listen interval */ + struct ether_addr ap; /* Current AP address */ +} BWL_POST_PACKED_STRUCT; +#define DOT11_REASSOC_REQ_FIXED_LEN 10 /* length of assoc frame without info elts */ + +BWL_PRE_PACKED_STRUCT struct dot11_assoc_resp { + uint16 capability; /* capability information */ + uint16 status; /* status code */ + uint16 aid; /* association ID */ +} BWL_POST_PACKED_STRUCT; +#define DOT11_ASSOC_RESP_FIXED_LEN 6 /* length of assoc resp frame without info elts */ + +BWL_PRE_PACKED_STRUCT struct dot11_action_measure { + uint8 category; + uint8 action; + uint8 token; + uint8 data[1]; +} BWL_POST_PACKED_STRUCT; +#define DOT11_ACTION_MEASURE_LEN 3 /* d11 action measurement header length */ + +BWL_PRE_PACKED_STRUCT struct dot11_action_ht_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; +} 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 + +/* ************* 802.11h related definitions. ************* */ +BWL_PRE_PACKED_STRUCT struct dot11_power_cnst { + uint8 id; + uint8 len; + uint8 power; +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_power_cnst dot11_power_cnst_t; + +BWL_PRE_PACKED_STRUCT struct dot11_power_cap { + uint8 min; + uint8 max; +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_power_cap dot11_power_cap_t; + +BWL_PRE_PACKED_STRUCT struct dot11_tpc_rep { + uint8 id; + uint8 len; + uint8 tx_pwr; + uint8 margin; +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_tpc_rep dot11_tpc_rep_t; +#define DOT11_MNG_IE_TPC_REPORT_LEN 2 /* length of IE data, not including 2 byte header */ + +BWL_PRE_PACKED_STRUCT struct dot11_supp_channels { + uint8 id; + uint8 len; + uint8 first_channel; + uint8 num_channels; +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_supp_channels dot11_supp_channels_t; + +/* Extension Channel Offset IE: 802.11n-D1.0 spec. added sideband + * offset for 40MHz operation. The possible 3 values are: + * 1 = above control channel + * 3 = below control channel + * 0 = no extension channel + */ +BWL_PRE_PACKED_STRUCT struct dot11_extch { + uint8 id; /* IE ID, 62, DOT11_MNG_EXT_CHANNEL_OFFSET */ + uint8 len; /* IE length */ + uint8 extch; +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_extch dot11_extch_ie_t; + +BWL_PRE_PACKED_STRUCT struct dot11_brcm_extch { + uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */ + uint8 len; /* IE length */ + uint8 oui[3]; /* Proprietary OUI, BRCM_PROP_OUI */ + uint8 type; /* type inidicates what follows */ + 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 /* 802.11n ID not yet assigned */ +#define DOT11_EXTCH_IE_LEN 1 +#define DOT11_EXT_CH_MASK 0x03 /* extension channel mask */ +#define DOT11_EXT_CH_UPPER 0x01 /* ext. ch. on upper sb */ +#define DOT11_EXT_CH_LOWER 0x03 /* ext. ch. on lower sb */ +#define DOT11_EXT_CH_NONE 0x00 /* no extension ch. */ + +BWL_PRE_PACKED_STRUCT struct dot11_action_frmhdr { + uint8 category; + uint8 action; + uint8 data[1]; +} BWL_POST_PACKED_STRUCT; +#define DOT11_ACTION_FRMHDR_LEN 2 + +/* CSA IE data structure */ +BWL_PRE_PACKED_STRUCT struct dot11_channel_switch { + uint8 id; /* id DOT11_MNG_CHANNEL_SWITCH_ID */ + uint8 len; /* length of IE */ + uint8 mode; /* mode 0 or 1 */ + uint8 channel; /* channel switch to */ + uint8 count; /* number of beacons before switching */ +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_channel_switch dot11_chan_switch_ie_t; + +#define DOT11_SWITCH_IE_LEN 3 /* length of IE data, not including 2 byte header */ +/* CSA mode - 802.11h-2003 $7.3.2.20 */ +#define DOT11_CSA_MODE_ADVISORY 0 /* no DOT11_CSA_MODE_NO_TX restriction imposed */ +#define DOT11_CSA_MODE_NO_TX 1 /* no transmission upon receiving CSA frame. */ + +BWL_PRE_PACKED_STRUCT struct dot11_action_switch_channel { + uint8 category; + uint8 action; + dot11_chan_switch_ie_t chan_switch_ie; /* for switch IE */ + dot11_brcm_extch_ie_t extch_ie; /* extension channel offset */ +} BWL_POST_PACKED_STRUCT; + +BWL_PRE_PACKED_STRUCT struct dot11_csa_body { + uint8 mode; /* mode 0 or 1 */ + uint8 reg; /* regulatory class */ + uint8 channel; /* channel switch to */ + uint8 count; /* number of beacons before switching */ +} BWL_POST_PACKED_STRUCT; + +/* 11n Extended Channel Switch IE data structure */ +BWL_PRE_PACKED_STRUCT struct dot11_ext_csa { + uint8 id; /* id DOT11_MNG_EXT_CHANNEL_SWITCH_ID */ + uint8 len; /* length of IE */ + struct dot11_csa_body b; /* body of the ie */ +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_ext_csa dot11_ext_csa_ie_t; +#define DOT11_EXT_CSA_IE_LEN 4 /* length of extended channel switch IE body */ + +BWL_PRE_PACKED_STRUCT struct dot11_action_ext_csa { + uint8 category; + uint8 action; + dot11_ext_csa_ie_t chan_switch_ie; /* for switch IE */ +} BWL_POST_PACKED_STRUCT; + +BWL_PRE_PACKED_STRUCT struct dot11y_action_ext_csa { + uint8 category; + uint8 action; + struct dot11_csa_body b; /* body of the ie */ +} BWL_POST_PACKED_STRUCT; + +BWL_PRE_PACKED_STRUCT struct dot11_obss_coex { + 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 /* length of OBSS Coexistence INFO IE */ + +#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]; +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_obss_chanlist dot11_obss_chanlist_t; +#define DOT11_OBSS_CHANLIST_FIXED_LEN 1 /* fixed length of regclass */ + +BWL_PRE_PACKED_STRUCT struct dot11_extcap_ie { + uint8 id; + uint8 len; + uint8 cap[1]; +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_extcap_ie dot11_extcap_ie_t; + +#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; +typedef struct dot11_extcap dot11_extcap_t; + +/* TDLS Capabilities */ +#define TDLS_CAP_TDLS 37 /* TDLS support */ +#define TDLS_CAP_PU_BUFFER_STA 28 /* TDLS Peer U-APSD buffer STA support */ +#define TDLS_CAP_PEER_PSM 20 /* TDLS Peer PSM support */ +#define TDLS_CAP_CH_SW 30 /* TDLS Channel switch */ +#define TDLS_CAP_PROH 38 /* TDLS prohibited */ +#define TDLS_CAP_CH_SW_PROH 39 /* TDLS Channel switch prohibited */ + +#define TDLS_CAP_MAX_BIT 39 /* TDLS max bit defined in ext cap */ + +/* 802.11h/802.11k Measurement Request/Report IEs */ +/* Measurement Type field */ +#define DOT11_MEASURE_TYPE_BASIC 0 /* d11 measurement basic type */ +#define DOT11_MEASURE_TYPE_CCA 1 /* d11 measurement CCA type */ +#define DOT11_MEASURE_TYPE_RPI 2 /* d11 measurement RPI type */ +#define DOT11_MEASURE_TYPE_CHLOAD 3 /* d11 measurement Channel Load type */ +#define DOT11_MEASURE_TYPE_NOISE 4 /* d11 measurement Noise Histogram type */ +#define DOT11_MEASURE_TYPE_BEACON 5 /* d11 measurement Beacon type */ +#define DOT11_MEASURE_TYPE_FRAME 6 /* d11 measurement Frame type */ +#define DOT11_MEASURE_TYPE_STATS 7 /* d11 measurement STA Statistics type */ +#define DOT11_MEASURE_TYPE_LCI 8 /* d11 measurement LCI type */ +#define DOT11_MEASURE_TYPE_TXSTREAM 9 /* d11 measurement TX Stream type */ +#define DOT11_MEASURE_TYPE_PAUSE 255 /* d11 measurement pause type */ + +/* Measurement Request Modes */ +#define DOT11_MEASURE_MODE_PARALLEL (1<<0) /* d11 measurement parallel */ +#define DOT11_MEASURE_MODE_ENABLE (1<<1) /* d11 measurement enable */ +#define DOT11_MEASURE_MODE_REQUEST (1<<2) /* d11 measurement request */ +#define DOT11_MEASURE_MODE_REPORT (1<<3) /* d11 measurement report */ +#define DOT11_MEASURE_MODE_DUR (1<<4) /* d11 measurement dur mandatory */ +/* Measurement Report Modes */ +#define DOT11_MEASURE_MODE_LATE (1<<0) /* d11 measurement late */ +#define DOT11_MEASURE_MODE_INCAPABLE (1<<1) /* d11 measurement incapable */ +#define DOT11_MEASURE_MODE_REFUSED (1<<2) /* d11 measurement refuse */ +/* Basic Measurement Map bits */ +#define DOT11_MEASURE_BASIC_MAP_BSS ((uint8)(1<<0)) /* d11 measurement basic map BSS */ +#define DOT11_MEASURE_BASIC_MAP_OFDM ((uint8)(1<<1)) /* d11 measurement map OFDM */ +#define DOT11_MEASURE_BASIC_MAP_UKNOWN ((uint8)(1<<2)) /* d11 measurement map unknown */ +#define DOT11_MEASURE_BASIC_MAP_RADAR ((uint8)(1<<3)) /* d11 measurement map radar */ +#define DOT11_MEASURE_BASIC_MAP_UNMEAS ((uint8)(1<<4)) /* d11 measurement map unmeasuremnt */ + +BWL_PRE_PACKED_STRUCT struct dot11_meas_req { + uint8 id; + uint8 len; + uint8 token; + uint8 mode; + uint8 type; + uint8 channel; + uint8 start_time[8]; + uint16 duration; +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_meas_req dot11_meas_req_t; +#define DOT11_MNG_IE_MREQ_LEN 14 /* d11 measurement request IE length */ +/* length of Measure Request IE data not including variable len */ +#define DOT11_MNG_IE_MREQ_FIXED_LEN 3 /* d11 measurement request IE fixed length */ + +BWL_PRE_PACKED_STRUCT struct dot11_meas_rep { + uint8 id; + uint8 len; + uint8 token; + uint8 mode; + uint8 type; + BWL_PRE_PACKED_STRUCT union + { + BWL_PRE_PACKED_STRUCT struct { + uint8 channel; + uint8 start_time[8]; + uint16 duration; + uint8 map; + } BWL_POST_PACKED_STRUCT basic; + uint8 data[1]; + } BWL_POST_PACKED_STRUCT rep; +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_meas_rep dot11_meas_rep_t; + +/* length of Measure Report IE data not including variable len */ +#define DOT11_MNG_IE_MREP_FIXED_LEN 3 /* d11 measurement response IE fixed length */ + +BWL_PRE_PACKED_STRUCT struct dot11_meas_rep_basic { + uint8 channel; + uint8 start_time[8]; + uint16 duration; + uint8 map; +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_meas_rep_basic dot11_meas_rep_basic_t; +#define DOT11_MEASURE_BASIC_REP_LEN 12 /* d11 measurement basic report length */ + +BWL_PRE_PACKED_STRUCT struct dot11_quiet { + uint8 id; + uint8 len; + uint8 count; /* TBTTs until beacon interval in quiet starts */ + uint8 period; /* Beacon intervals between periodic quiet periods ? */ + uint16 duration; /* Length of quiet period, in TU's */ + uint16 offset; /* TU's offset from TBTT in Count field */ +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_quiet dot11_quiet_t; + +BWL_PRE_PACKED_STRUCT struct chan_map_tuple { + uint8 channel; + uint8 map; +} BWL_POST_PACKED_STRUCT; +typedef struct chan_map_tuple chan_map_tuple_t; + +BWL_PRE_PACKED_STRUCT struct dot11_ibss_dfs { + uint8 id; + uint8 len; + uint8 eaddr[ETHER_ADDR_LEN]; + uint8 interval; + chan_map_tuple_t map[1]; +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_ibss_dfs dot11_ibss_dfs_t; + +/* WME Elements */ +#define WME_OUI "\x00\x50\xf2" /* WME OUI */ +#define WME_OUI_LEN 3 +#define WME_OUI_TYPE 2 /* WME type */ +#define WME_TYPE 2 /* WME type, deprecated */ +#define WME_SUBTYPE_IE 0 /* Information Element */ +#define WME_SUBTYPE_PARAM_IE 1 /* Parameter Element */ +#define WME_SUBTYPE_TSPEC 2 /* Traffic Specification */ +#define WME_VER 1 /* WME version */ + +/* WME Access Category Indices (ACIs) */ +#define AC_BE 0 /* Best Effort */ +#define AC_BK 1 /* Background */ +#define AC_VI 2 /* Video */ +#define AC_VO 3 /* Voice */ +#define AC_COUNT 4 /* number of ACs */ + +typedef uint8 ac_bitmap_t; /* AC bitmap of (1 << AC_xx) */ + +#define AC_BITMAP_NONE 0x0 /* No ACs */ +#define AC_BITMAP_ALL 0xf /* All ACs */ +#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)))) + +/* WME Information Element (IE) */ +BWL_PRE_PACKED_STRUCT struct wme_ie { + uint8 oui[3]; + uint8 type; + uint8 subtype; + uint8 version; + uint8 qosinfo; +} BWL_POST_PACKED_STRUCT; +typedef struct wme_ie wme_ie_t; +#define WME_IE_LEN 7 /* WME IE length */ + +BWL_PRE_PACKED_STRUCT struct edcf_acparam { + uint8 ACI; + uint8 ECW; + uint16 TXOP; /* stored in network order (ls octet first) */ +} BWL_POST_PACKED_STRUCT; +typedef struct edcf_acparam edcf_acparam_t; + +/* WME Parameter Element (PE) */ +BWL_PRE_PACKED_STRUCT struct wme_param_ie { + uint8 oui[3]; + uint8 type; + uint8 subtype; + uint8 version; + uint8 qosinfo; + uint8 rsvd; + edcf_acparam_t acparam[AC_COUNT]; +} BWL_POST_PACKED_STRUCT; +typedef struct wme_param_ie wme_param_ie_t; +#define WME_PARAM_IE_LEN 24 /* WME Parameter IE length */ + +/* QoS Info field for IE as sent from AP */ +#define WME_QI_AP_APSD_MASK 0x80 /* U-APSD Supported mask */ +#define WME_QI_AP_APSD_SHIFT 7 /* U-APSD Supported shift */ +#define WME_QI_AP_COUNT_MASK 0x0f /* Parameter set count mask */ +#define WME_QI_AP_COUNT_SHIFT 0 /* Parameter set count shift */ + +/* QoS Info field for IE as sent from STA */ +#define WME_QI_STA_MAXSPLEN_MASK 0x60 /* Max Service Period Length mask */ +#define WME_QI_STA_MAXSPLEN_SHIFT 5 /* Max Service Period Length shift */ +#define WME_QI_STA_APSD_ALL_MASK 0xf /* APSD all AC bits mask */ +#define WME_QI_STA_APSD_ALL_SHIFT 0 /* APSD all AC bits shift */ +#define WME_QI_STA_APSD_BE_MASK 0x8 /* APSD AC_BE mask */ +#define WME_QI_STA_APSD_BE_SHIFT 3 /* APSD AC_BE shift */ +#define WME_QI_STA_APSD_BK_MASK 0x4 /* APSD AC_BK mask */ +#define WME_QI_STA_APSD_BK_SHIFT 2 /* APSD AC_BK shift */ +#define WME_QI_STA_APSD_VI_MASK 0x2 /* APSD AC_VI mask */ +#define WME_QI_STA_APSD_VI_SHIFT 1 /* APSD AC_VI shift */ +#define WME_QI_STA_APSD_VO_MASK 0x1 /* APSD AC_VO mask */ +#define WME_QI_STA_APSD_VO_SHIFT 0 /* APSD AC_VO shift */ + +/* ACI */ +#define EDCF_AIFSN_MIN 1 /* AIFSN minimum value */ +#define EDCF_AIFSN_MAX 15 /* AIFSN maximum value */ +#define EDCF_AIFSN_MASK 0x0f /* AIFSN mask */ +#define EDCF_ACM_MASK 0x10 /* ACM mask */ +#define EDCF_ACI_MASK 0x60 /* ACI mask */ +#define EDCF_ACI_SHIFT 5 /* ACI shift */ +#define EDCF_AIFSN_SHIFT 12 /* 4 MSB(0xFFF) in ifs_ctl for AC idx */ + +/* ECW */ +#define EDCF_ECW_MIN 0 /* cwmin/cwmax exponent minimum value */ +#define EDCF_ECW_MAX 15 /* cwmin/cwmax exponent maximum value */ +#define EDCF_ECW2CW(exp) ((1 << (exp)) - 1) +#define EDCF_ECWMIN_MASK 0x0f /* cwmin exponent form mask */ +#define EDCF_ECWMAX_MASK 0xf0 /* cwmax exponent form mask */ +#define EDCF_ECWMAX_SHIFT 4 /* cwmax exponent form shift */ + +/* TXOP */ +#define EDCF_TXOP_MIN 0 /* TXOP minimum value */ +#define EDCF_TXOP_MAX 65535 /* TXOP maximum value */ +#define EDCF_TXOP2USEC(txop) ((txop) << 5) + +/* Default BE ACI value for non-WME connection STA */ +#define NON_EDCF_AC_BE_ACI_STA 0x02 + +/* Default EDCF parameters that AP advertises for STA to use; WMM draft Table 12 */ +#define EDCF_AC_BE_ACI_STA 0x03 /* STA ACI value for best effort AC */ +#define EDCF_AC_BE_ECW_STA 0xA4 /* STA ECW value for best effort AC */ +#define EDCF_AC_BE_TXOP_STA 0x0000 /* STA TXOP value for best effort AC */ +#define EDCF_AC_BK_ACI_STA 0x27 /* STA ACI value for background AC */ +#define EDCF_AC_BK_ECW_STA 0xA4 /* STA ECW value for background AC */ +#define EDCF_AC_BK_TXOP_STA 0x0000 /* STA TXOP value for background AC */ +#define EDCF_AC_VI_ACI_STA 0x42 /* STA ACI value for video AC */ +#define EDCF_AC_VI_ECW_STA 0x43 /* STA ECW value for video AC */ +#define EDCF_AC_VI_TXOP_STA 0x005e /* STA TXOP value for video AC */ +#define EDCF_AC_VO_ACI_STA 0x62 /* STA ACI value for audio AC */ +#define EDCF_AC_VO_ECW_STA 0x32 /* STA ECW value for audio AC */ +#define EDCF_AC_VO_TXOP_STA 0x002f /* STA TXOP value for audio AC */ + +/* Default EDCF parameters that AP uses; WMM draft Table 14 */ +#define EDCF_AC_BE_ACI_AP 0x03 /* AP ACI value for best effort AC */ +#define EDCF_AC_BE_ECW_AP 0x64 /* AP ECW value for best effort AC */ +#define EDCF_AC_BE_TXOP_AP 0x0000 /* AP TXOP value for best effort AC */ +#define EDCF_AC_BK_ACI_AP 0x27 /* AP ACI value for background AC */ +#define EDCF_AC_BK_ECW_AP 0xA4 /* AP ECW value for background AC */ +#define EDCF_AC_BK_TXOP_AP 0x0000 /* AP TXOP value for background AC */ +#define EDCF_AC_VI_ACI_AP 0x41 /* AP ACI value for video AC */ +#define EDCF_AC_VI_ECW_AP 0x43 /* AP ECW value for video AC */ +#define EDCF_AC_VI_TXOP_AP 0x005e /* AP TXOP value for video AC */ +#define EDCF_AC_VO_ACI_AP 0x61 /* AP ACI value for audio AC */ +#define EDCF_AC_VO_ECW_AP 0x32 /* AP ECW value for audio AC */ +#define EDCF_AC_VO_TXOP_AP 0x002f /* AP TXOP value for audio AC */ + +/* EDCA Parameter IE */ +BWL_PRE_PACKED_STRUCT struct edca_param_ie { + uint8 qosinfo; + uint8 rsvd; + edcf_acparam_t acparam[AC_COUNT]; +} BWL_POST_PACKED_STRUCT; +typedef struct edca_param_ie edca_param_ie_t; +#define EDCA_PARAM_IE_LEN 18 /* EDCA Parameter IE length */ + +/* QoS Capability IE */ +BWL_PRE_PACKED_STRUCT struct qos_cap_ie { + uint8 qosinfo; +} BWL_POST_PACKED_STRUCT; +typedef struct qos_cap_ie qos_cap_ie_t; + +BWL_PRE_PACKED_STRUCT struct dot11_qbss_load_ie { + uint8 id; /* 11, DOT11_MNG_QBSS_LOAD_ID */ + uint8 length; + uint16 station_count; /* total number of STAs associated */ + uint8 channel_utilization; /* % of time, normalized to 255, QAP sensed medium busy */ + uint16 aac; /* available admission capacity */ +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_qbss_load_ie dot11_qbss_load_ie_t; +#define BSS_LOAD_IE_SIZE 7 /* BSS load IE size */ + +/* nom_msdu_size */ +#define FIXED_MSDU_SIZE 0x8000 /* MSDU size is fixed */ +#define MSDU_SIZE_MASK 0x7fff /* (Nominal or fixed) MSDU size */ + +/* surplus_bandwidth */ +/* Represented as 3 bits of integer, binary point, 13 bits fraction */ +#define INTEGER_SHIFT 13 /* integer shift */ +#define FRACTION_MASK 0x1FFF /* fraction mask */ + +/* Management Notification Frame */ +BWL_PRE_PACKED_STRUCT struct dot11_management_notification { + uint8 category; /* DOT11_ACTION_NOTIFICATION */ + uint8 action; + uint8 token; + uint8 status; + uint8 data[1]; /* Elements */ +} BWL_POST_PACKED_STRUCT; +#define DOT11_MGMT_NOTIFICATION_LEN 4 /* Fixed length */ + +/* Timeout Interval IE */ +BWL_PRE_PACKED_STRUCT struct ti_ie { + uint8 ti_type; + uint32 ti_val; +} BWL_POST_PACKED_STRUCT; +typedef struct ti_ie ti_ie_t; +#define TI_TYPE_REASSOC_DEADLINE 1 +#define TI_TYPE_KEY_LIFETIME 2 + +/* WME Action Codes */ +#define WME_ADDTS_REQUEST 0 /* WME ADDTS request */ +#define WME_ADDTS_RESPONSE 1 /* WME ADDTS response */ +#define WME_DELTS_REQUEST 2 /* WME DELTS request */ + +/* WME Setup Response Status Codes */ +#define WME_ADMISSION_ACCEPTED 0 /* WME admission accepted */ +#define WME_INVALID_PARAMETERS 1 /* WME invalide parameters */ +#define WME_ADMISSION_REFUSED 3 /* WME admission refused */ + +/* Macro to take a pointer to a beacon or probe response + * body and return the char* pointer to the SSID info element + */ +#define BCN_PRB_SSID(body) ((char*)(body) + DOT11_BCN_PRB_LEN) + +/* Authentication frame payload constants */ +#define DOT11_OPEN_SYSTEM 0 /* d11 open authentication */ +#define DOT11_SHARED_KEY 1 /* d11 shared authentication */ +#define DOT11_FAST_BSS 2 /* d11 fast bss authentication */ +#define DOT11_CHALLENGE_LEN 128 /* d11 challenge text length */ + +/* Frame control macros */ +#define FC_PVER_MASK 0x3 /* PVER mask */ +#define FC_PVER_SHIFT 0 /* PVER shift */ +#define FC_TYPE_MASK 0xC /* type mask */ +#define FC_TYPE_SHIFT 2 /* type shift */ +#define FC_SUBTYPE_MASK 0xF0 /* subtype mask */ +#define FC_SUBTYPE_SHIFT 4 /* subtype shift */ +#define FC_TODS 0x100 /* to DS */ +#define FC_TODS_SHIFT 8 /* to DS shift */ +#define FC_FROMDS 0x200 /* from DS */ +#define FC_FROMDS_SHIFT 9 /* from DS shift */ +#define FC_MOREFRAG 0x400 /* more frag. */ +#define FC_MOREFRAG_SHIFT 10 /* more frag. shift */ +#define FC_RETRY 0x800 /* retry */ +#define FC_RETRY_SHIFT 11 /* retry shift */ +#define FC_PM 0x1000 /* PM */ +#define FC_PM_SHIFT 12 /* PM shift */ +#define FC_MOREDATA 0x2000 /* more data */ +#define FC_MOREDATA_SHIFT 13 /* more data shift */ +#define FC_WEP 0x4000 /* WEP */ +#define FC_WEP_SHIFT 14 /* WEP shift */ +#define FC_ORDER 0x8000 /* order */ +#define FC_ORDER_SHIFT 15 /* order shift */ + +/* sequence control macros */ +#define SEQNUM_SHIFT 4 /* seq. number shift */ +#define SEQNUM_MAX 0x1000 /* max seqnum + 1 */ +#define FRAGNUM_MASK 0xF /* frag. number mask */ + +/* Frame Control type/subtype defs */ + +/* FC Types */ +#define FC_TYPE_MNG 0 /* management type */ +#define FC_TYPE_CTL 1 /* control type */ +#define FC_TYPE_DATA 2 /* data type */ + +/* Management Subtypes */ +#define FC_SUBTYPE_ASSOC_REQ 0 /* assoc. request */ +#define FC_SUBTYPE_ASSOC_RESP 1 /* assoc. response */ +#define FC_SUBTYPE_REASSOC_REQ 2 /* reassoc. request */ +#define FC_SUBTYPE_REASSOC_RESP 3 /* reassoc. response */ +#define FC_SUBTYPE_PROBE_REQ 4 /* probe request */ +#define FC_SUBTYPE_PROBE_RESP 5 /* probe response */ +#define FC_SUBTYPE_BEACON 8 /* beacon */ +#define FC_SUBTYPE_ATIM 9 /* ATIM */ +#define FC_SUBTYPE_DISASSOC 10 /* disassoc. */ +#define FC_SUBTYPE_AUTH 11 /* authentication */ +#define FC_SUBTYPE_DEAUTH 12 /* de-authentication */ +#define FC_SUBTYPE_ACTION 13 /* action */ +#define FC_SUBTYPE_ACTION_NOACK 14 /* action no-ack */ + +/* Control Subtypes */ +#define FC_SUBTYPE_CTL_WRAPPER 7 /* Control Wrapper */ +#define FC_SUBTYPE_BLOCKACK_REQ 8 /* Block Ack Req */ +#define FC_SUBTYPE_BLOCKACK 9 /* Block Ack */ +#define FC_SUBTYPE_PS_POLL 10 /* PS poll */ +#define FC_SUBTYPE_RTS 11 /* RTS */ +#define FC_SUBTYPE_CTS 12 /* CTS */ +#define FC_SUBTYPE_ACK 13 /* ACK */ +#define FC_SUBTYPE_CF_END 14 /* CF-END */ +#define FC_SUBTYPE_CF_END_ACK 15 /* CF-END ACK */ + +/* Data Subtypes */ +#define FC_SUBTYPE_DATA 0 /* Data */ +#define FC_SUBTYPE_DATA_CF_ACK 1 /* Data + CF-ACK */ +#define FC_SUBTYPE_DATA_CF_POLL 2 /* Data + CF-Poll */ +#define FC_SUBTYPE_DATA_CF_ACK_POLL 3 /* Data + CF-Ack + CF-Poll */ +#define FC_SUBTYPE_NULL 4 /* Null */ +#define FC_SUBTYPE_CF_ACK 5 /* CF-Ack */ +#define FC_SUBTYPE_CF_POLL 6 /* CF-Poll */ +#define FC_SUBTYPE_CF_ACK_POLL 7 /* CF-Ack + CF-Poll */ +#define FC_SUBTYPE_QOS_DATA 8 /* QoS Data */ +#define FC_SUBTYPE_QOS_DATA_CF_ACK 9 /* QoS Data + CF-Ack */ +#define FC_SUBTYPE_QOS_DATA_CF_POLL 10 /* QoS Data + CF-Poll */ +#define FC_SUBTYPE_QOS_DATA_CF_ACK_POLL 11 /* QoS Data + CF-Ack + CF-Poll */ +#define FC_SUBTYPE_QOS_NULL 12 /* QoS Null */ +#define FC_SUBTYPE_QOS_CF_POLL 14 /* QoS CF-Poll */ +#define FC_SUBTYPE_QOS_CF_ACK_POLL 15 /* QoS CF-Ack + CF-Poll */ + +/* Data Subtype Groups */ +#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) + +/* Type/Subtype Combos */ +#define FC_KIND_MASK (FC_TYPE_MASK | FC_SUBTYPE_MASK) /* FC kind mask */ + +#define FC_KIND(t, s) (((t) << FC_TYPE_SHIFT) | ((s) << FC_SUBTYPE_SHIFT)) /* FC kind */ + +#define FC_SUBTYPE(fc) (((fc) & FC_SUBTYPE_MASK) >> FC_SUBTYPE_SHIFT) /* Subtype from FC */ +#define FC_TYPE(fc) (((fc) & FC_TYPE_MASK) >> FC_TYPE_SHIFT) /* Type from FC */ + +#define FC_ASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_REQ) /* assoc. request */ +#define FC_ASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_RESP) /* assoc. response */ +#define FC_REASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_REQ) /* reassoc. request */ +#define FC_REASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_RESP) /* reassoc. response */ +#define FC_PROBE_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_REQ) /* probe request */ +#define FC_PROBE_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_RESP) /* probe response */ +#define FC_BEACON FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_BEACON) /* beacon */ +#define FC_DISASSOC FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DISASSOC) /* disassoc */ +#define FC_AUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_AUTH) /* authentication */ +#define FC_DEAUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DEAUTH) /* deauthentication */ +#define FC_ACTION FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ACTION) /* action */ +#define FC_ACTION_NOACK FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ACTION_NOACK) /* action no-ack */ + +#define FC_CTL_WRAPPER FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CTL_WRAPPER) /* Control Wrapper */ +#define FC_BLOCKACK_REQ FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_BLOCKACK_REQ) /* Block Ack Req */ +#define FC_BLOCKACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_BLOCKACK) /* Block Ack */ +#define FC_PS_POLL FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_PS_POLL) /* PS poll */ +#define FC_RTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_RTS) /* RTS */ +#define FC_CTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CTS) /* CTS */ +#define FC_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_ACK) /* ACK */ +#define FC_CF_END FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END) /* CF-END */ +#define FC_CF_END_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END_ACK) /* CF-END ACK */ + +#define FC_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA) /* data */ +#define FC_NULL_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_NULL) /* null data */ +#define FC_DATA_CF_ACK FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA_CF_ACK) /* data CF ACK */ +#define FC_QOS_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_DATA) /* QoS data */ +#define FC_QOS_NULL FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_NULL) /* QoS null */ + +/* QoS Control Field */ + +/* 802.1D Priority */ +#define QOS_PRIO_SHIFT 0 /* QoS priority shift */ +#define QOS_PRIO_MASK 0x0007 /* QoS priority mask */ +#define QOS_PRIO(qos) (((qos) & QOS_PRIO_MASK) >> QOS_PRIO_SHIFT) /* QoS priority */ + +/* Traffic Identifier */ +#define QOS_TID_SHIFT 0 /* QoS TID shift */ +#define QOS_TID_MASK 0x000f /* QoS TID mask */ +#define QOS_TID(qos) (((qos) & QOS_TID_MASK) >> QOS_TID_SHIFT) /* QoS TID */ + +/* End of Service Period (U-APSD) */ +#define QOS_EOSP_SHIFT 4 /* QoS End of Service Period shift */ +#define QOS_EOSP_MASK 0x0010 /* QoS End of Service Period mask */ +#define QOS_EOSP(qos) (((qos) & QOS_EOSP_MASK) >> QOS_EOSP_SHIFT) /* Qos EOSP */ + +/* Ack Policy */ +#define QOS_ACK_NORMAL_ACK 0 /* Normal Ack */ +#define QOS_ACK_NO_ACK 1 /* No Ack (eg mcast) */ +#define QOS_ACK_NO_EXP_ACK 2 /* No Explicit Ack */ +#define QOS_ACK_BLOCK_ACK 3 /* Block Ack */ +#define QOS_ACK_SHIFT 5 /* QoS ACK shift */ +#define QOS_ACK_MASK 0x0060 /* QoS ACK mask */ +#define QOS_ACK(qos) (((qos) & QOS_ACK_MASK) >> QOS_ACK_SHIFT) /* QoS ACK */ + +/* A-MSDU flag */ +#define QOS_AMSDU_SHIFT 7 /* AMSDU shift */ +#define QOS_AMSDU_MASK 0x0080 /* AMSDU mask */ + +/* Management Frames */ + +/* Management Frame Constants */ + +/* Fixed fields */ +#define DOT11_MNG_AUTH_ALGO_LEN 2 /* d11 management auth. algo. length */ +#define DOT11_MNG_AUTH_SEQ_LEN 2 /* d11 management auth. seq. length */ +#define DOT11_MNG_BEACON_INT_LEN 2 /* d11 management beacon interval length */ +#define DOT11_MNG_CAP_LEN 2 /* d11 management cap. length */ +#define DOT11_MNG_AP_ADDR_LEN 6 /* d11 management AP address length */ +#define DOT11_MNG_LISTEN_INT_LEN 2 /* d11 management listen interval length */ +#define DOT11_MNG_REASON_LEN 2 /* d11 management reason length */ +#define DOT11_MNG_AID_LEN 2 /* d11 management AID length */ +#define DOT11_MNG_STATUS_LEN 2 /* d11 management status length */ +#define DOT11_MNG_TIMESTAMP_LEN 8 /* d11 management timestamp length */ + +/* DUR/ID field in assoc resp is 0xc000 | AID */ +#define DOT11_AID_MASK 0x3fff /* d11 AID mask */ + +/* Reason Codes */ +#define DOT11_RC_RESERVED 0 /* d11 RC reserved */ +#define DOT11_RC_UNSPECIFIED 1 /* Unspecified reason */ +#define DOT11_RC_AUTH_INVAL 2 /* Previous authentication no longer valid */ +#define DOT11_RC_DEAUTH_LEAVING 3 /* Deauthenticated because sending station + * is leaving (or has left) IBSS or ESS + */ +#define DOT11_RC_INACTIVITY 4 /* Disassociated due to inactivity */ +#define DOT11_RC_BUSY 5 /* Disassociated because AP is unable to handle + * all currently associated stations + */ +#define DOT11_RC_INVAL_CLASS_2 6 /* Class 2 frame received from + * nonauthenticated station + */ +#define DOT11_RC_INVAL_CLASS_3 7 /* Class 3 frame received from + * nonassociated station + */ +#define DOT11_RC_DISASSOC_LEAVING 8 /* Disassociated because sending station is + * leaving (or has left) BSS + */ +#define DOT11_RC_NOT_AUTH 9 /* Station requesting (re)association is not + * authenticated with responding station + */ +#define DOT11_RC_BAD_PC 10 /* Unacceptable power capability element */ +#define DOT11_RC_BAD_CHANNELS 11 /* Unacceptable supported channels element */ +/* 12 is unused */ + +/* 32-39 are QSTA specific reasons added in 11e */ +#define DOT11_RC_UNSPECIFIED_QOS 32 /* unspecified QoS-related reason */ +#define DOT11_RC_INSUFFCIENT_BW 33 /* QAP lacks sufficient bandwidth */ +#define DOT11_RC_EXCESSIVE_FRAMES 34 /* excessive number of frames need ack */ +#define DOT11_RC_TX_OUTSIDE_TXOP 35 /* transmitting outside the limits of txop */ +#define DOT11_RC_LEAVING_QBSS 36 /* QSTA is leaving the QBSS (or restting) */ +#define DOT11_RC_BAD_MECHANISM 37 /* does not want to use the mechanism */ +#define DOT11_RC_SETUP_NEEDED 38 /* mechanism needs a setup */ +#define DOT11_RC_TIMEOUT 39 /* timeout */ + +#define DOT11_RC_MAX 23 /* Reason codes > 23 are reserved */ + +#define DOT11_RC_TDLS_PEER_UNREACH 25 +#define DOT11_RC_TDLS_DOWN_UNSPECIFIED 26 + +/* Status Codes */ +#define DOT11_SC_SUCCESS 0 /* Successful */ +#define DOT11_SC_FAILURE 1 /* Unspecified failure */ +#define DOT11_SC_TDLS_WAKEUP_SCH_ALT 2 /* TDLS wakeup schedule rejected but alternative */ + /* schedule provided */ +#define DOT11_SC_TDLS_WAKEUP_SCH_REJ 3 /* TDLS wakeup schedule rejected */ +#define DOT11_SC_TDLS_SEC_DISABLED 5 /* TDLS Security disabled */ +#define DOT11_SC_LIFETIME_REJ 6 /* Unacceptable lifetime */ +#define DOT11_SC_NOT_SAME_BSS 7 /* Not in same BSS */ +#define DOT11_SC_CAP_MISMATCH 10 /* Cannot support all requested + * capabilities in the Capability + * Information field + */ +#define DOT11_SC_REASSOC_FAIL 11 /* Reassociation denied due to inability + * to confirm that association exists + */ +#define DOT11_SC_ASSOC_FAIL 12 /* Association denied due to reason + * outside the scope of this standard + */ +#define DOT11_SC_AUTH_MISMATCH 13 /* Responding station does not support + * the specified authentication + * algorithm + */ +#define DOT11_SC_AUTH_SEQ 14 /* Received an Authentication frame + * with authentication transaction + * sequence number out of expected + * sequence + */ +#define DOT11_SC_AUTH_CHALLENGE_FAIL 15 /* Authentication rejected because of + * challenge failure + */ +#define DOT11_SC_AUTH_TIMEOUT 16 /* Authentication rejected due to timeout + * waiting for next frame in sequence + */ +#define DOT11_SC_ASSOC_BUSY_FAIL 17 /* Association denied because AP is + * unable to handle additional + * associated stations + */ +#define DOT11_SC_ASSOC_RATE_MISMATCH 18 /* Association denied due to requesting + * station not supporting all of the + * data rates in the BSSBasicRateSet + * parameter + */ +#define DOT11_SC_ASSOC_SHORT_REQUIRED 19 /* Association denied due to requesting + * station not supporting the Short + * Preamble option + */ +#define DOT11_SC_ASSOC_PBCC_REQUIRED 20 /* Association denied due to requesting + * station not supporting the PBCC + * Modulation option + */ +#define DOT11_SC_ASSOC_AGILITY_REQUIRED 21 /* Association denied due to requesting + * station not supporting the Channel + * Agility option + */ +#define DOT11_SC_ASSOC_SPECTRUM_REQUIRED 22 /* Association denied because Spectrum + * Management capability is required. + */ +#define DOT11_SC_ASSOC_BAD_POWER_CAP 23 /* Association denied because the info + * in the Power Cap element is + * unacceptable. + */ +#define DOT11_SC_ASSOC_BAD_SUP_CHANNELS 24 /* Association denied because the info + * in the Supported Channel element is + * unacceptable + */ +#define DOT11_SC_ASSOC_SHORTSLOT_REQUIRED 25 /* Association denied due to requesting + * station not supporting the Short Slot + * Time option + */ +#define DOT11_SC_ASSOC_ERPBCC_REQUIRED 26 /* Association denied due to requesting + * station not supporting the ER-PBCC + * Modulation option + */ +#define DOT11_SC_ASSOC_DSSOFDM_REQUIRED 27 /* Association denied due to requesting + * station not supporting the DSS-OFDM + * option + */ +#define DOT11_SC_ASSOC_R0KH_UNREACHABLE 28 /* Association denied due to AP + * being unable to reach the R0 Key Holder + */ +#define DOT11_SC_ASSOC_TRY_LATER 30 /* Association denied temporarily, try again later + */ +#define DOT11_SC_ASSOC_MFP_VIOLATION 31 /* Association denied due to Robust Management + * frame policy violation + */ + +#define DOT11_SC_DECLINED 37 /* request declined */ +#define DOT11_SC_INVALID_PARAMS 38 /* One or more params have invalid values */ +#define DOT11_SC_INVALID_PAIRWISE_CIPHER 42 /* invalid pairwise cipher */ +#define DOT11_SC_INVALID_AKMP 43 /* Association denied due to invalid AKMP */ +#define DOT11_SC_INVALID_RSNIE_CAP 45 /* invalid RSN IE capabilities */ +#define DOT11_SC_DLS_NOT_ALLOWED 48 /* DLS is not allowed in the BSS by policy */ +#define DOT11_SC_INVALID_PMKID 53 /* Association denied due to invalid PMKID */ +#define DOT11_SC_INVALID_MDID 54 /* Association denied due to invalid MDID */ +#define DOT11_SC_INVALID_FTIE 55 /* Association denied due to invalid FTIE */ + +#define DOT11_SC_UNEXP_MSG 70 /* Unexpected message */ +#define DOT11_SC_INVALID_SNONCE 71 /* Invalid SNonce */ +#define DOT11_SC_INVALID_RSNIE 72 /* Invalid contents of RSNIE */ + +/* Info Elts, length of INFORMATION portion of Info Elts */ +#define DOT11_MNG_DS_PARAM_LEN 1 /* d11 management DS parameter length */ +#define DOT11_MNG_IBSS_PARAM_LEN 2 /* d11 management IBSS parameter length */ + +/* TIM Info element has 3 bytes fixed info in INFORMATION field, + * followed by 1 to 251 bytes of Partial Virtual Bitmap + */ +#define DOT11_MNG_TIM_FIXED_LEN 3 /* d11 management TIM fixed length */ +#define DOT11_MNG_TIM_DTIM_COUNT 0 /* d11 management DTIM count */ +#define DOT11_MNG_TIM_DTIM_PERIOD 1 /* d11 management DTIM period */ +#define DOT11_MNG_TIM_BITMAP_CTL 2 /* d11 management TIM BITMAP control */ +#define DOT11_MNG_TIM_PVB 3 /* d11 management TIM PVB */ + +/* TLV defines */ +#define TLV_TAG_OFF 0 /* tag offset */ +#define TLV_LEN_OFF 1 /* length offset */ +#define TLV_HDR_LEN 2 /* header length */ +#define TLV_BODY_OFF 2 /* body offset */ + +/* Management Frame Information Element IDs */ +#define DOT11_MNG_SSID_ID 0 /* d11 management SSID id */ +#define DOT11_MNG_RATES_ID 1 /* d11 management rates id */ +#define DOT11_MNG_FH_PARMS_ID 2 /* d11 management FH parameter id */ +#define DOT11_MNG_DS_PARMS_ID 3 /* d11 management DS parameter id */ +#define DOT11_MNG_CF_PARMS_ID 4 /* d11 management CF parameter id */ +#define DOT11_MNG_TIM_ID 5 /* d11 management TIM id */ +#define DOT11_MNG_IBSS_PARMS_ID 6 /* d11 management IBSS parameter id */ +#define DOT11_MNG_COUNTRY_ID 7 /* d11 management country id */ +#define DOT11_MNG_HOPPING_PARMS_ID 8 /* d11 management hopping parameter id */ +#define DOT11_MNG_HOPPING_TABLE_ID 9 /* d11 management hopping table id */ +#define DOT11_MNG_REQUEST_ID 10 /* d11 management request id */ +#define DOT11_MNG_QBSS_LOAD_ID 11 /* d11 management QBSS Load id */ +#define DOT11_MNG_EDCA_PARAM_ID 12 /* 11E EDCA Parameter id */ +#define DOT11_MNG_CHALLENGE_ID 16 /* d11 management chanllenge id */ +#define DOT11_MNG_PWR_CONSTRAINT_ID 32 /* 11H PowerConstraint */ +#define DOT11_MNG_PWR_CAP_ID 33 /* 11H PowerCapability */ +#define DOT11_MNG_TPC_REQUEST_ID 34 /* 11H TPC Request */ +#define DOT11_MNG_TPC_REPORT_ID 35 /* 11H TPC Report */ +#define DOT11_MNG_SUPP_CHANNELS_ID 36 /* 11H Supported Channels */ +#define DOT11_MNG_CHANNEL_SWITCH_ID 37 /* 11H ChannelSwitch Announcement */ +#define DOT11_MNG_MEASURE_REQUEST_ID 38 /* 11H MeasurementRequest */ +#define DOT11_MNG_MEASURE_REPORT_ID 39 /* 11H MeasurementReport */ +#define DOT11_MNG_QUIET_ID 40 /* 11H Quiet */ +#define DOT11_MNG_IBSS_DFS_ID 41 /* 11H IBSS_DFS */ +#define DOT11_MNG_ERP_ID 42 /* d11 management ERP id */ +#define DOT11_MNG_TS_DELAY_ID 43 /* d11 management TS Delay id */ +#define DOT11_MNG_HT_CAP 45 /* d11 mgmt HT cap id */ +#define DOT11_MNG_QOS_CAP_ID 46 /* 11E QoS Capability id */ +#define DOT11_MNG_NONERP_ID 47 /* d11 management NON-ERP id */ +#define DOT11_MNG_RSN_ID 48 /* d11 management RSN id */ +#define DOT11_MNG_EXT_RATES_ID 50 /* d11 management ext. rates id */ +#define DOT11_MNG_AP_CHREP_ID 51 /* 11k AP Channel report id */ +#define DOT11_MNG_NBR_REP_ID 52 /* 11k Neighbor report id */ +#define DOT11_MNG_MDIE_ID 54 /* 11r Mobility domain id */ +#define DOT11_MNG_FTIE_ID 55 /* 11r Fast Bss Transition id */ +#define DOT11_MNG_FT_TI_ID 56 /* 11r Timeout Interval id */ +#define DOT11_MNG_REGCLASS_ID 59 /* d11 management regulatory class id */ +#define DOT11_MNG_EXT_CSA_ID 60 /* d11 Extended CSA */ +#define DOT11_MNG_HT_ADD 61 /* d11 mgmt additional HT info */ +#define DOT11_MNG_EXT_CHANNEL_OFFSET 62 /* d11 mgmt ext channel offset */ +#ifdef BCMWAPI_WAI +#define DOT11_MNG_WAPI_ID 68 /* d11 management WAPI id */ +#endif +#define DOT11_MNG_WAPI_ID 68 /* d11 management WAPI id */ +#define DOT11_MNG_TIME_ADVERTISE_ID 69 /* 11p time advertisement */ +#define DOT11_MNG_RRM_CAP_ID 70 /* 11k radio measurement capability */ +#define DOT11_MNG_HT_BSS_COEXINFO_ID 72 /* d11 mgmt OBSS Coexistence INFO */ +#define DOT11_MNG_HT_BSS_CHANNEL_REPORT_ID 73 /* d11 mgmt OBSS Intolerant Channel list */ +#define DOT11_MNG_HT_OBSS_ID 74 /* d11 mgmt OBSS HT info */ +#define DOT11_MNG_CHANNEL_USAGE 97 /* 11v channel usage */ +#define DOT11_MNG_TIME_ZONE_ID 98 /* 11v time zone */ +#define DOT11_MNG_LINK_IDENTIFIER_ID 101 /* 11z TDLS Link Identifier IE */ +#define DOT11_MNG_WAKEUP_SCHEDULE_ID 102 /* 11z TDLS Wakeup Schedule IE */ +#define DOT11_MNG_CHANNEL_SWITCH_TIMING_ID 104 /* 11z TDLS Channel Switch Timing IE */ +#define DOT11_MNG_PTI_CONTROL_ID 105 /* 11z TDLS PTI Control IE */ +#define DOT11_MNG_PU_BUFFER_STATUS_ID 106 /* 11z TDLS PU Buffer Status IE */ +#define DOT11_MNG_INTERWORKING_ID 107 /* 11u interworking */ +#define DOT11_MNG_ADVERTISEMENT_ID 108 /* 11u advertisement protocol */ +#define DOT11_MNG_EXP_BW_REQ_ID 109 /* 11u expedited bandwith request */ +#define DOT11_MNG_QOS_MAP_ID 110 /* 11u QoS map set */ +#define DOT11_MNG_ROAM_CONSORT_ID 111 /* 11u roaming consortium */ +#define DOT11_MNG_EMERGCY_ALERT_ID 112 /* 11u emergency alert identifier */ +#define DOT11_MNG_EXT_CAP_ID 127 /* d11 mgmt ext capability */ +#define DOT11_MNG_VHT_CAP_ID 191 /* d11 mgmt VHT cap id */ +#define DOT11_MNG_VHT_OPERATION_ID 192 /* d11 mgmt VHT op id */ + +#define DOT11_MNG_WPA_ID 221 /* d11 management WPA id */ +#define DOT11_MNG_PROPR_ID 221 /* d11 management proprietary id */ +/* should start using this one instead of above two */ +#define DOT11_MNG_VS_ID 221 /* d11 management Vendor Specific IE */ + +/* Rate element Basic flag and rate mask */ +#define DOT11_RATE_BASIC 0x80 /* flag for a Basic Rate */ +#define DOT11_RATE_MASK 0x7F /* mask for numeric part of rate */ + +/* ERP info element bit values */ +#define DOT11_MNG_ERP_LEN 1 /* ERP is currently 1 byte long */ +#define DOT11_MNG_NONERP_PRESENT 0x01 /* NonERP (802.11b) STAs are present + *in the BSS + */ +#define DOT11_MNG_USE_PROTECTION 0x02 /* Use protection mechanisms for + *ERP-OFDM frames + */ +#define DOT11_MNG_BARKER_PREAMBLE 0x04 /* Short Preambles: 0 == allowed, + * 1 == not allowed + */ +/* TS Delay element offset & size */ +#define DOT11_MGN_TS_DELAY_LEN 4 /* length of TS DELAY IE */ +#define TS_DELAY_FIELD_SIZE 4 /* TS DELAY field size */ + +/* Capability Information Field */ +#define DOT11_CAP_ESS 0x0001 /* d11 cap. ESS */ +#define DOT11_CAP_IBSS 0x0002 /* d11 cap. IBSS */ +#define DOT11_CAP_POLLABLE 0x0004 /* d11 cap. pollable */ +#define DOT11_CAP_POLL_RQ 0x0008 /* d11 cap. poll request */ +#define DOT11_CAP_PRIVACY 0x0010 /* d11 cap. privacy */ +#define DOT11_CAP_SHORT 0x0020 /* d11 cap. short */ +#define DOT11_CAP_PBCC 0x0040 /* d11 cap. PBCC */ +#define DOT11_CAP_AGILITY 0x0080 /* d11 cap. agility */ +#define DOT11_CAP_SPECTRUM 0x0100 /* d11 cap. spectrum */ +#define DOT11_CAP_SHORTSLOT 0x0400 /* d11 cap. shortslot */ +#define DOT11_CAP_RRM 0x1000 /* d11 cap. 11k radio measurement */ +#define DOT11_CAP_CCK_OFDM 0x2000 /* d11 cap. CCK/OFDM */ + +/* Extended capabilities IE bitfields */ +/* 20/40 BSS Coexistence Management support bit position */ +#define DOT11_EXT_CAP_OBSS_COEX_MGMT 0 +/* scheduled PSMP support bit position */ +#define DOT11_EXT_CAP_SPSMP 6 +/* BSS Transition Management support bit position */ +#define DOT11_EXT_CAP_BSS_TRANSITION_MGMT 19 +/* Interworking support bit position */ +#define DOT11_EXT_CAP_IW 31 +/* service Interval granularity bit position and mask */ +#define DOT11_EXT_CAP_SI 41 +#define DOT11_EXT_CAP_SI_MASK 0x0E + +/* + * Action Frame Constants + */ +#define DOT11_ACTION_HDR_LEN 2 /* action frame category + action field */ +#define DOT11_ACTION_CAT_OFF 0 /* category offset */ +#define DOT11_ACTION_ACT_OFF 1 /* action offset */ + +/* Action Category field (sec 7.3.1.11) */ +#define DOT11_ACTION_CAT_ERR_MASK 0x80 /* category error mask */ +#define DOT11_ACTION_CAT_MASK 0x7F /* category mask */ +#define DOT11_ACTION_CAT_SPECT_MNG 0 /* category spectrum management */ +#define DOT11_ACTION_CAT_QOS 1 /* category QoS */ +#define DOT11_ACTION_CAT_DLS 2 /* category DLS */ +#define DOT11_ACTION_CAT_BLOCKACK 3 /* category block ack */ +#define DOT11_ACTION_CAT_PUBLIC 4 /* category public */ +#define DOT11_ACTION_CAT_RRM 5 /* category radio measurements */ +#define DOT11_ACTION_CAT_FBT 6 /* category fast bss transition */ +#define DOT11_ACTION_CAT_HT 7 /* category for HT */ +#define DOT11_ACTION_CAT_SA_QUERY 8 /* security association query */ +#define DOT11_ACTION_CAT_PDPA 9 /* protected dual of public action */ +#define DOT11_ACTION_CAT_BSSMGMT 10 /* category for BSS transition management */ +#define DOT11_ACTION_NOTIFICATION 17 +#define DOT11_ACTION_CAT_VSP 126 /* protected vendor specific */ +#define DOT11_ACTION_CAT_VS 127 /* category Vendor Specific */ + +/* Spectrum Management Action IDs (sec 7.4.1) */ +#define DOT11_SM_ACTION_M_REQ 0 /* d11 action measurement request */ +#define DOT11_SM_ACTION_M_REP 1 /* d11 action measurement response */ +#define DOT11_SM_ACTION_TPC_REQ 2 /* d11 action TPC request */ +#define DOT11_SM_ACTION_TPC_REP 3 /* d11 action TPC response */ +#define DOT11_SM_ACTION_CHANNEL_SWITCH 4 /* d11 action channel switch */ +#define DOT11_SM_ACTION_EXT_CSA 5 /* d11 extened CSA for 11n */ + +/* HT action ids */ +#define DOT11_ACTION_ID_HT_CH_WIDTH 0 /* notify channel width action id */ +#define DOT11_ACTION_ID_HT_MIMO_PS 1 /* mimo ps action id */ + +/* Public action ids */ +#define DOT11_PUB_ACTION_BSS_COEX_MNG 0 /* 20/40 Coexistence Management action id */ +#define DOT11_PUB_ACTION_CHANNEL_SWITCH 4 /* d11 action channel switch */ + +/* Block Ack action types */ +#define DOT11_BA_ACTION_ADDBA_REQ 0 /* ADDBA Req action frame type */ +#define DOT11_BA_ACTION_ADDBA_RESP 1 /* ADDBA Resp action frame type */ +#define DOT11_BA_ACTION_DELBA 2 /* DELBA action frame type */ + +/* ADDBA action parameters */ +#define DOT11_ADDBA_PARAM_AMSDU_SUP 0x0001 /* AMSDU supported under BA */ +#define DOT11_ADDBA_PARAM_POLICY_MASK 0x0002 /* policy mask(ack vs delayed) */ +#define DOT11_ADDBA_PARAM_POLICY_SHIFT 1 /* policy shift */ +#define DOT11_ADDBA_PARAM_TID_MASK 0x003c /* tid mask */ +#define DOT11_ADDBA_PARAM_TID_SHIFT 2 /* tid shift */ +#define DOT11_ADDBA_PARAM_BSIZE_MASK 0xffc0 /* buffer size mask */ +#define DOT11_ADDBA_PARAM_BSIZE_SHIFT 6 /* buffer size shift */ + +#define DOT11_ADDBA_POLICY_DELAYED 0 /* delayed BA policy */ +#define DOT11_ADDBA_POLICY_IMMEDIATE 1 /* immediate BA policy */ + +/* Fast Transition action types */ +#define DOT11_FT_ACTION_FT_RESERVED 0 +#define DOT11_FT_ACTION_FT_REQ 1 /* FBT request - for over-the-DS FBT */ +#define DOT11_FT_ACTION_FT_RES 2 /* FBT response - for over-the-DS FBT */ +#define DOT11_FT_ACTION_FT_CON 3 /* FBT confirm - for OTDS with RRP */ +#define DOT11_FT_ACTION_FT_ACK 4 /* FBT ack */ + +/* DLS action types */ +#define DOT11_DLS_ACTION_REQ 0 /* DLS Request */ +#define DOT11_DLS_ACTION_RESP 1 /* DLS Response */ +#define DOT11_DLS_ACTION_TD 2 /* DLS Teardown */ + +/* Wireless Network Management (WNM) action types */ +#define DOT11_WNM_ACTION_EVENT_REQ 0 +#define DOT11_WNM_ACTION_EVENT_REP 1 +#define DOT11_WNM_ACTION_DIAG_REQ 2 +#define DOT11_WNM_ACTION_DIAG_REP 3 +#define DOT11_WNM_ACTION_LOC_CFG_REQ 4 +#define DOT11_WNM_ACTION_LOC_RFG_RESP 5 +#define DOT11_WNM_ACTION_BSS_TRANS_QURY 6 +#define DOT11_WNM_ACTION_BSS_TRANS_REQ 7 +#define DOT11_WNM_ACTION_BSS_TRANS_RESP 8 +#define DOT11_WNM_ACTION_FMS_REQ 9 +#define DOT11_WNM_ACTION_FMS_RESP 10 +#define DOT11_WNM_ACTION_COL_INTRFRNCE_REQ 11 +#define DOT11_WNM_ACTION_COL_INTRFRNCE_REP 12 +#define DOT11_WNM_ACTION_TFS_REQ 13 +#define DOT11_WNM_ACTION_TFS_RESP 14 +#define DOT11_WNM_ACTION_TFS_NOTIFY 15 +#define DOT11_WNM_ACTION_WNM_SLEEP_REQ 16 +#define DOT11_WNM_ACTION_WNM_SLEEP_RESP 17 +#define DOT11_WNM_ACTION_TIM_BCAST_REQ 18 +#define DOT11_WNM_ACTION_TIM_BCAST_RESP 19 +#define DOT11_WNM_ACTION_QOS_TRFC_CAP_UPD 20 +#define DOT11_WNM_ACTION_CHAN_USAGE_REQ 21 +#define DOT11_WNM_ACTION_CHAN_USAGE_RESP 22 +#define DOT11_WNM_ACTION_DMS_REQ 23 +#define DOT11_WNM_ACTION_DMS_RESP 24 +#define DOT11_WNM_ACTION_TMNG_MEASUR_REQ 25 +#define DOT11_WNM_ACTION_NOTFCTN_REQ 26 +#define DOT11_WNM_ACTION_NOTFCTN_RES 27 + +#define DOT11_MNG_COUNTRY_ID_LEN 3 + +/* DLS Request frame header */ +BWL_PRE_PACKED_STRUCT struct dot11_dls_req { + uint8 category; /* category of action frame (2) */ + uint8 action; /* DLS action: req (0) */ + struct ether_addr da; /* destination address */ + struct ether_addr sa; /* source address */ + uint16 cap; /* capability */ + uint16 timeout; /* timeout value */ + uint8 data[1]; /* IE:support rate, extend support rate, HT cap */ +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_dls_req dot11_dls_req_t; +#define DOT11_DLS_REQ_LEN 18 /* Fixed length */ + +/* DLS response frame header */ +BWL_PRE_PACKED_STRUCT struct dot11_dls_resp { + uint8 category; /* category of action frame (2) */ + uint8 action; /* DLS action: req (0) */ + uint16 status; /* status code field */ + struct ether_addr da; /* destination address */ + struct ether_addr sa; /* source address */ + uint8 data[1]; /* optional: capability, rate ... */ +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_dls_resp dot11_dls_resp_t; +#define DOT11_DLS_RESP_LEN 16 /* Fixed length */ + + +/* BSS Management Transition Query frame header */ +BWL_PRE_PACKED_STRUCT struct dot11_bss_trans_query { + uint8 category; /* category of action frame (10) */ + uint8 action; /* WNM action: trans_query (6) */ + uint8 token; /* dialog token */ + uint8 reason; /* transition query reason */ + uint8 data[1]; /* Elements */ +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_bss_trans_query dot11_bss_trans_query_t; +#define DOT11_BSS_TRANS_QUERY_LEN 4 /* Fixed length */ + +/* BSS Management Transition Request frame header */ +BWL_PRE_PACKED_STRUCT struct dot11_bss_trans_req { + uint8 category; /* category of action frame (10) */ + uint8 action; /* WNM action: trans_req (7) */ + uint8 token; /* dialog token */ + uint8 reqmode; /* transition request mode */ + uint16 disassoc_tmr; /* disassociation timer */ + uint8 validity_intrvl; /* validity interval */ + uint8 data[1]; /* optional: BSS term duration, ... */ + /* ...session info URL, list */ +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_bss_trans_req dot11_bss_trans_req_t; +#define DOT11_BSS_TRANS_REQ_LEN 7 /* Fixed length */ + +#define DOT11_BSS_TERM_DUR_LEN 12 /* Fixed length if present */ + + +/* BSS Mgmt Transition Request Mode Field - 802.11v */ +#define DOT11_BSS_TRNS_REQMODE_PREF_LIST_INCL 0x01 +#define DOT11_BSS_TRNS_REQMODE_ABRIDGED 0x02 +#define DOT11_BSS_TRNS_REQMODE_DISASSOC_IMMINENT 0x04 +#define DOT11_BSS_TRNS_REQMODE_BSS_TERM_INCL 0x08 +#define DOT11_BSS_TRNS_REQMODE_ESS_DISASSOC_IMNT 0x10 + + +/* BSS Management transition response frame header */ +BWL_PRE_PACKED_STRUCT struct dot11_bss_trans_res { + uint8 category; /* category of action frame (10) */ + uint8 action; /* WNM action: trans_res (8) */ + uint8 token; /* dialog token */ + uint8 status; /* transition status */ + uint8 term_delay; /* validity interval */ + uint8 data[1]; /* optional: BSS term duration, ... */ + /* ...session info URL, list */ +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_bss_trans_res dot11_bss_trans_res_t; +#define DOT11_BSS_TRANS_RES_LEN 5 /* Fixed length */ + +/* BSS Mgmt Transition Response Status Field */ +#define DOT11_BSS_TRNS_RES_STATUS_ACCEPT 0 +#define DOT11_BSS_TRNS_RES_STATUS_REJECT 1 +#define DOT11_BSS_TRNS_RES_STATUS_REJ_INSUFF_BCN 2 +#define DOT11_BSS_TRNS_RES_STATUS_REJ_INSUFF_CAP 3 +#define DOT11_BSS_TRNS_RES_STATUS_REJ_TERM_UNDESIRED 4 +#define DOT11_BSS_TRNS_RES_STATUS_REJ_TERM_DELAY_REQ 5 +#define DOT11_BSS_TRNS_RES_STATUS_REJ_BSS_LIST_PROVIDED 6 +#define DOT11_BSS_TRNS_RES_STATUS_REJ_NO_SUITABLE_BSS 7 +#define DOT11_BSS_TRNS_RES_STATUS_REJ_LEAVING_ESS 8 + + +/* Neighbor Report BSSID Information Field */ +#define DOT11_NBR_RPRT_BSSID_INFO_REACHABILTY 0x0003 +#define DOT11_NBR_RPRT_BSSID_INFO_SEC 0x0004 +#define DOT11_NBR_RPRT_BSSID_INFO_KEY_SCOPE 0x0008 +#define DOT11_NBR_RPRT_BSSID_INFO_CAP 0x03f0 + +#define DOT11_NBR_RPRT_BSSID_INFO_CAP_SPEC_MGMT 0x0010 +#define DOT11_NBR_RPRT_BSSID_INFO_CAP_QOS 0x0020 +#define DOT11_NBR_RPRT_BSSID_INFO_CAP_APSD 0x0040 +#define DOT11_NBR_RPRT_BSSID_INFO_CAP_RDIO_MSMT 0x0080 +#define DOT11_NBR_RPRT_BSSID_INFO_CAP_DEL_BA 0x0100 +#define DOT11_NBR_RPRT_BSSID_INFO_CAP_IMM_BA 0x0200 + +/* Neighbor Report Subelements */ +#define DOT11_NBR_RPRT_SUBELEM_BSS_CANDDT_PREF_ID 3 + + +BWL_PRE_PACKED_STRUCT struct dot11_addba_req { + uint8 category; /* category of action frame (3) */ + uint8 action; /* action: addba req */ + uint8 token; /* identifier */ + uint16 addba_param_set; /* parameter set */ + uint16 timeout; /* timeout in seconds */ + uint16 start_seqnum; /* starting sequence number */ +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_addba_req dot11_addba_req_t; +#define DOT11_ADDBA_REQ_LEN 9 /* length of addba req frame */ + +BWL_PRE_PACKED_STRUCT struct dot11_addba_resp { + uint8 category; /* category of action frame (3) */ + uint8 action; /* action: addba resp */ + uint8 token; /* identifier */ + uint16 status; /* status of add request */ + uint16 addba_param_set; /* negotiated parameter set */ + uint16 timeout; /* negotiated timeout in seconds */ +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_addba_resp dot11_addba_resp_t; +#define DOT11_ADDBA_RESP_LEN 9 /* length of addba resp frame */ + +/* DELBA action parameters */ +#define DOT11_DELBA_PARAM_INIT_MASK 0x0800 /* initiator mask */ +#define DOT11_DELBA_PARAM_INIT_SHIFT 11 /* initiator shift */ +#define DOT11_DELBA_PARAM_TID_MASK 0xf000 /* tid mask */ +#define DOT11_DELBA_PARAM_TID_SHIFT 12 /* tid shift */ + +BWL_PRE_PACKED_STRUCT struct dot11_delba { + uint8 category; /* category of action frame (3) */ + uint8 action; /* action: addba req */ + uint16 delba_param_set; /* paarmeter set */ + uint16 reason; /* reason for dellba */ +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_delba dot11_delba_t; +#define DOT11_DELBA_LEN 6 /* length of delba frame */ + +/* SA Query action field value */ +#define SA_QUERY_REQUEST 0 +#define SA_QUERY_RESPONSE 1 + +/* ************* 802.11r related definitions. ************* */ + +/* Over-the-DS Fast Transition Request frame header */ +BWL_PRE_PACKED_STRUCT struct dot11_ft_req { + uint8 category; /* category of action frame (6) */ + uint8 action; /* action: ft req */ + uint8 sta_addr[ETHER_ADDR_LEN]; + uint8 tgt_ap_addr[ETHER_ADDR_LEN]; + uint8 data[1]; /* Elements */ +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_ft_req dot11_ft_req_t; +#define DOT11_FT_REQ_FIXED_LEN 14 + +/* Over-the-DS Fast Transition Response frame header */ +BWL_PRE_PACKED_STRUCT struct dot11_ft_res { + uint8 category; /* category of action frame (6) */ + uint8 action; /* action: ft resp */ + uint8 sta_addr[ETHER_ADDR_LEN]; + uint8 tgt_ap_addr[ETHER_ADDR_LEN]; + uint16 status; /* status code */ + uint8 data[1]; /* Elements */ +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_ft_res dot11_ft_res_t; +#define DOT11_FT_RES_FIXED_LEN 16 + + +/* ************* 802.11k related definitions. ************* */ + +/* Radio measurements enabled capability ie */ + +#define DOT11_RRM_CAP_LEN 5 /* length of rrm cap bitmap */ +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; + +/* Bitmap definitions for cap ie */ +#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 + + +/* Operating Class (formerly "Regulatory Class") definitions */ +#define DOT11_OP_CLASS_NONE 255 + + +/* Radio Measurements action ids */ +#define DOT11_RM_ACTION_RM_REQ 0 /* Radio measurement request */ +#define DOT11_RM_ACTION_RM_REP 1 /* Radio measurement report */ +#define DOT11_RM_ACTION_LM_REQ 2 /* Link measurement request */ +#define DOT11_RM_ACTION_LM_REP 3 /* Link measurement report */ +#define DOT11_RM_ACTION_NR_REQ 4 /* Neighbor report request */ +#define DOT11_RM_ACTION_NR_REP 5 /* Neighbor report response */ + +/* Generic radio measurement action frame header */ +BWL_PRE_PACKED_STRUCT struct dot11_rm_action { + uint8 category; /* category of action frame (5) */ + uint8 action; /* radio measurement action */ + uint8 token; /* dialog 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; /* category of action frame (5) */ + uint8 action; /* radio measurement action */ + uint8 token; /* dialog token */ + uint16 reps; /* no. of repetitions */ +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_rmreq dot11_rmreq_t; +#define DOT11_RMREQ_LEN 5 + +BWL_PRE_PACKED_STRUCT struct dot11_rm_ie { + uint8 id; + uint8 len; + uint8 token; + uint8 mode; + uint8 type; +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_rm_ie dot11_rm_ie_t; +#define DOT11_RM_IE_LEN 5 + +/* Definitions for "mode" bits in rm req */ +#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 /* Duration Mandatory */ + +/* Definitions for "mode" bits in rm rep */ +#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; + uint8 len; + uint8 token; + uint8 mode; + uint8 type; + uint8 reg; + uint8 channel; + uint16 interval; + uint16 duration; + uint8 bcn_mode; + struct ether_addr bssid; +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_rmreq_bcn dot11_rmreq_bcn_t; +#define DOT11_RMREQ_BCN_LEN 18 + +BWL_PRE_PACKED_STRUCT struct dot11_rmrep_bcn { + uint8 reg; + uint8 channel; + uint32 starttime[2]; + uint16 duration; + uint8 frame_info; + uint8 rcpi; + uint8 rsni; + 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 + +/* Beacon request measurement mode */ +#define DOT11_RMREQ_BCN_PASSIVE 0 +#define DOT11_RMREQ_BCN_ACTIVE 1 +#define DOT11_RMREQ_BCN_TABLE 2 + +/* Sub-element IDs for Beacon Request */ +#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 + +/* Reporting Detail element definition */ +#define DOT11_RMREQ_BCN_REPDET_FIXED 0 /* Fixed length fields only */ +#define DOT11_RMREQ_BCN_REPDET_REQUEST 1 /* + requested information elems */ +#define DOT11_RMREQ_BCN_REPDET_ALL 2 /* All fields */ + +/* Sub-element IDs for Beacon Report */ +#define DOT11_RMREP_BCN_FRM_BODY 1 + +/* Neighbor measurement report */ +BWL_PRE_PACKED_STRUCT struct dot11_rmrep_nbr { + struct ether_addr bssid; + uint32 bssid_info; + uint8 reg; + uint8 channel; + uint8 phytype; + uchar sub_elements[1]; /* Variable size data */ +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_rmrep_nbr dot11_rmrep_nbr_t; +#define DOT11_RMREP_NBR_LEN 13 + +/* MLME Enumerations */ +#define DOT11_BSSTYPE_INFRASTRUCTURE 0 /* d11 infrastructure */ +#define DOT11_BSSTYPE_INDEPENDENT 1 /* d11 independent */ +#define DOT11_BSSTYPE_ANY 2 /* d11 any BSS type */ +#define DOT11_SCANTYPE_ACTIVE 0 /* d11 scan active */ +#define DOT11_SCANTYPE_PASSIVE 1 /* d11 scan passive */ + +/* Link Measurement */ +BWL_PRE_PACKED_STRUCT struct dot11_lmreq { + uint8 category; /* category of action frame (5) */ + uint8 action; /* radio measurement action */ + uint8 token; /* dialog token */ + uint8 txpwr; /* Transmit Power Used */ + uint8 maxtxpwr; /* Max Transmit Power */ +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_lmreq dot11_lmreq_t; +#define DOT11_LMREQ_LEN 5 + +BWL_PRE_PACKED_STRUCT struct dot11_lmrep { + uint8 category; /* category of action frame (5) */ + uint8 action; /* radio measurement action */ + uint8 token; /* dialog token */ + dot11_tpc_rep_t tpc; /* TPC element */ + uint8 rxant; /* Receive Antenna ID */ + uint8 txant; /* Transmit Antenna ID */ + uint8 rcpi; /* RCPI */ + uint8 rsni; /* RSNI */ +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_lmrep dot11_lmrep_t; +#define DOT11_LMREP_LEN 11 + +/* 802.11 BRCM "Compromise" Pre N constants */ +#define PREN_PREAMBLE 24 /* green field preamble time */ +#define PREN_MM_EXT 12 /* extra mixed mode preamble time */ +#define PREN_PREAMBLE_EXT 4 /* extra preamble (multiply by unique_streams-1) */ + +/* 802.11N PHY constants */ +#define RIFS_11N_TIME 2 /* NPHY RIFS time */ + +/* 802.11 HT PLCP format 802.11n-2009, sec 20.3.9.4.3 + * HT-SIG is composed of two 24 bit parts, HT-SIG1 and HT-SIG2 + */ +/* HT-SIG1 */ +#define HT_SIG1_MCS_MASK 0x00007F +#define HT_SIG1_CBW 0x000080 +#define HT_SIG1_HT_LENGTH 0xFFFF00 + +/* HT-SIG2 */ +#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 + +/* 802.11 A PHY constants */ +#define APHY_SLOT_TIME 9 /* APHY slot time */ +#define APHY_SIFS_TIME 16 /* APHY SIFS time */ +#define APHY_DIFS_TIME (APHY_SIFS_TIME + (2 * APHY_SLOT_TIME)) /* APHY DIFS time */ +#define APHY_PREAMBLE_TIME 16 /* APHY preamble time */ +#define APHY_SIGNAL_TIME 4 /* APHY signal time */ +#define APHY_SYMBOL_TIME 4 /* APHY symbol time */ +#define APHY_SERVICE_NBITS 16 /* APHY service nbits */ +#define APHY_TAIL_NBITS 6 /* APHY tail nbits */ +#define APHY_CWMIN 15 /* APHY cwmin */ + +/* 802.11 B PHY constants */ +#define BPHY_SLOT_TIME 20 /* BPHY slot time */ +#define BPHY_SIFS_TIME 10 /* BPHY SIFS time */ +#define BPHY_DIFS_TIME 50 /* BPHY DIFS time */ +#define BPHY_PLCP_TIME 192 /* BPHY PLCP time */ +#define BPHY_PLCP_SHORT_TIME 96 /* BPHY PLCP short time */ +#define BPHY_CWMIN 31 /* BPHY cwmin */ + +/* 802.11 G constants */ +#define DOT11_OFDM_SIGNAL_EXTENSION 6 /* d11 OFDM signal extension */ + +#define PHY_CWMAX 1023 /* PHY cwmax */ + +#define DOT11_MAXNUMFRAGS 16 /* max # fragments per MSDU */ + +/* 802.11 AC (VHT) constants */ + +typedef int vht_group_id_t; + +/* for VHT-A1 */ +/* SIG-A1 reserved bits */ +#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 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 VHT_SIGA1_NSTS_SHIFT 10 +#define VHT_SIGA1_NSTS_SHIFT_MASK_USER0 0x001C00 + +#define VHT_SIGA1_PARTIAL_AID_SHIFT 13 + +/* for VHT-A2 */ +#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 VHT_SIGA2_B9_RESERVED 0x000200 +#define VHT_SIGA2_TAIL_MASK 0xfc0000 +#define VHT_SIGA2_TAIL_VALUE 0x000000 + +#define VHT_SIGA2_SVC_BITS 16 +#define VHT_SIGA2_TAIL_BITS 6 + + +/* dot11Counters Table - 802.11 spec., Annex D */ +typedef struct d11cnt { + 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 */ + uint32 rxundec; /* dot11WEPUndecryptableCount */ +} d11cnt_t; + +/* OUI for BRCM proprietary IE */ +#define BRCM_PROP_OUI "\x00\x90\x4C" /* Broadcom proprietary OUI */ + + +/* BRCM OUI: Used in the proprietary(221) IE in all broadcom devices */ +#define BRCM_OUI "\x00\x10\x18" /* Broadcom OUI */ + +/* BRCM info element */ +BWL_PRE_PACKED_STRUCT struct brcm_ie { + uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */ + uint8 len; /* IE length */ + uint8 oui[3]; /* Proprietary OUI, BRCM_OUI */ + uint8 ver; /* type/ver of this IE */ + uint8 assoc; /* # of assoc STAs */ + uint8 flags; /* misc flags */ + uint8 flags1; /* misc flags */ + uint16 amsdu_mtu_pref; /* preferred A-MSDU MTU */ +} BWL_POST_PACKED_STRUCT; +typedef struct brcm_ie brcm_ie_t; +#define BRCM_IE_LEN 11 /* BRCM IE length */ +#define BRCM_IE_VER 2 /* BRCM IE version */ +#define BRCM_IE_LEGACY_AES_VER 1 /* BRCM IE legacy AES version */ + +/* brcm_ie flags */ +#define BRF_LZWDS 0x4 /* lazy wds enabled */ +#define BRF_BLOCKACK 0x8 /* BlockACK capable */ + +/* brcm_ie flags1 */ +#define BRF1_AMSDU 0x1 /* A-MSDU capable */ +#define BRF1_WMEPS 0x4 /* AP is capable of handling WME + PS w/o APSD */ +#define BRF1_PSOFIX 0x8 /* AP has fixed PS mode out-of-order packets */ +#define BRF1_RX_LARGE_AGG 0x10 /* device can rx large aggregates */ +#define BRF1_RFAWARE_DCS 0x20 /* RFAWARE dynamic channel selection (DCS) */ +#define BRF1_SOFTAP 0x40 /* Configure as Broadcom SOFTAP */ + +/* Vendor IE structure */ +BWL_PRE_PACKED_STRUCT struct vndr_ie { + uchar id; + uchar len; + uchar oui [3]; + uchar data [1]; /* Variable size data */ +} BWL_POST_PACKED_STRUCT; +typedef struct vndr_ie vndr_ie_t; + +#define VNDR_IE_HDR_LEN 2 /* id + len field */ +#define VNDR_IE_MIN_LEN 3 /* size of the oui field */ +#define VNDR_IE_FIXED_LEN (VNDR_IE_HDR_LEN + VNDR_IE_MIN_LEN) +#define VNDR_IE_MAX_LEN 256 /* verdor IE max length */ + +/* ************* HT definitions. ************* */ +#define MCSSET_LEN 16 /* 16-bits per 8-bit set to give 128-bits bitmap of MCS Index */ +#define MAX_MCS_NUM (128) /* max mcs number = 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; +} BWL_POST_PACKED_STRUCT; +typedef struct ht_cap_ie ht_cap_ie_t; + +/* CAP IE: HT 1.0 spec. simply stole a 802.11 IE, we use our prop. IE until this is resolved */ +/* the capability IE is primarily used to convey this nodes abilities */ +BWL_PRE_PACKED_STRUCT struct ht_prop_cap_ie { + uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */ + uint8 len; /* IE length */ + uint8 oui[3]; /* Proprietary OUI, BRCM_PROP_OUI */ + uint8 type; /* type inidicates what follows */ + 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 /* overhead bytes for prop oui ie */ +#define HT_CAP_IE_LEN 26 /* HT capability len (based on .11n d2.0) */ +#define HT_CAP_IE_TYPE 51 + +#define HT_CAP_LDPC_CODING 0x0001 /* Support for rx of LDPC coded pkts */ +#define HT_CAP_40MHZ 0x0002 /* FALSE:20Mhz, TRUE:20/40MHZ supported */ +#define HT_CAP_MIMO_PS_MASK 0x000C /* Mimo PS mask */ +#define HT_CAP_MIMO_PS_SHIFT 0x0002 /* Mimo PS shift */ +#define HT_CAP_MIMO_PS_OFF 0x0003 /* Mimo PS, no restriction */ +#define HT_CAP_MIMO_PS_RTS 0x0001 /* Mimo PS, send RTS/CTS around MIMO frames */ +#define HT_CAP_MIMO_PS_ON 0x0000 /* Mimo PS, MIMO disallowed */ +#define HT_CAP_GF 0x0010 /* Greenfield preamble support */ +#define HT_CAP_SHORT_GI_20 0x0020 /* 20MHZ short guard interval support */ +#define HT_CAP_SHORT_GI_40 0x0040 /* 40Mhz short guard interval support */ +#define HT_CAP_TX_STBC 0x0080 /* Tx STBC support */ +#define HT_CAP_RX_STBC_MASK 0x0300 /* Rx STBC mask */ +#define HT_CAP_RX_STBC_SHIFT 8 /* Rx STBC shift */ +#define HT_CAP_DELAYED_BA 0x0400 /* delayed BA support */ +#define HT_CAP_MAX_AMSDU 0x0800 /* Max AMSDU size in bytes , 0=3839, 1=7935 */ + +#define HT_CAP_DSSS_CCK 0x1000 /* DSSS/CCK supported by the BSS */ +#define HT_CAP_PSMP 0x2000 /* Power Save Multi Poll support */ +#define HT_CAP_40MHZ_INTOLERANT 0x4000 /* 40MHz Intolerant */ +#define HT_CAP_LSIG_TXOP 0x8000 /* L-SIG TXOP protection support */ + +#define HT_CAP_RX_STBC_NO 0x0 /* no rx STBC support */ +#define HT_CAP_RX_STBC_ONE_STREAM 0x1 /* rx STBC support of 1 spatial stream */ +#define HT_CAP_RX_STBC_TWO_STREAM 0x2 /* rx STBC support of 1-2 spatial streams */ +#define HT_CAP_RX_STBC_THREE_STREAM 0x3 /* rx STBC support of 1-3 spatial streams */ + +#define VHT_MAX_MPDU 11454 /* max mpdu size for now (bytes) */ +#define VHT_MPDU_MSDU_DELTA 56 /* Difference in spec - vht mpdu, amsdu len */ +/* Max AMSDU len - per spec */ +#define VHT_MAX_AMSDU (VHT_MAX_MPDU - VHT_MPDU_MSDU_DELTA) + +#define HT_MAX_AMSDU 7935 /* max amsdu size (bytes) per the HT spec */ +#define HT_MIN_AMSDU 3835 /* min amsdu size (bytes) per the HT spec */ + +#define HT_PARAMS_RX_FACTOR_MASK 0x03 /* ampdu rcv factor mask */ +#define HT_PARAMS_DENSITY_MASK 0x1C /* ampdu density mask */ +#define HT_PARAMS_DENSITY_SHIFT 2 /* ampdu density shift */ + +/* HT/AMPDU specific define */ +#define AMPDU_MAX_MPDU_DENSITY 7 /* max mpdu density; in 1/4 usec units */ +#define AMPDU_DENSITY_NONE 0 /* No density requirement */ +#define AMPDU_DENSITY_1over4_US 1 /* 1/4 us density */ +#define AMPDU_DENSITY_1over2_US 2 /* 1/2 us density */ +#define AMPDU_DENSITY_1_US 3 /* 1 us density */ +#define AMPDU_DENSITY_2_US 4 /* 2 us density */ +#define AMPDU_DENSITY_4_US 5 /* 4 us density */ +#define AMPDU_DENSITY_8_US 6 /* 8 us density */ +#define AMPDU_DENSITY_16_US 7 /* 16 us density */ +#define AMPDU_RX_FACTOR_8K 0 /* max rcv ampdu len (8kb) */ +#define AMPDU_RX_FACTOR_16K 1 /* max rcv ampdu len (16kb) */ +#define AMPDU_RX_FACTOR_32K 2 /* max rcv ampdu len (32kb) */ +#define AMPDU_RX_FACTOR_64K 3 /* max rcv ampdu len (64kb) */ +#define AMPDU_RX_FACTOR_BASE 8*1024 /* ampdu factor base for rx len */ + +#define AMPDU_DELIMITER_LEN 4 /* length of ampdu delimiter */ +#define AMPDU_DELIMITER_LEN_MAX 63 /* max length of ampdu delimiter(enforced in HW) */ + +#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; /* control channel number */ + uint8 byte1; /* ext ch,rec. ch. width, RIFS support */ + uint16 opmode; /* operation mode */ + uint16 misc_bits; /* misc bits */ + uint8 basic_mcs[MCSSET_LEN]; /* required MCS set */ +} BWL_POST_PACKED_STRUCT; +typedef struct ht_add_ie ht_add_ie_t; + +/* ADD IE: HT 1.0 spec. simply stole a 802.11 IE, we use our prop. IE until this is resolved */ +/* the additional IE is primarily used to convey the current BSS configuration */ +BWL_PRE_PACKED_STRUCT struct ht_prop_add_ie { + uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */ + uint8 len; /* IE length */ + uint8 oui[3]; /* Proprietary OUI, BRCM_PROP_OUI */ + uint8 type; /* indicates what follows */ + 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 + +/* byte1 defn's */ +#define HT_BW_ANY 0x04 /* set, STA can use 20 or 40MHz */ +#define HT_RIFS_PERMITTED 0x08 /* RIFS allowed */ + +/* opmode defn's */ +#define HT_OPMODE_MASK 0x0003 /* protection mode mask */ +#define HT_OPMODE_SHIFT 0 /* protection mode shift */ +#define HT_OPMODE_PURE 0x0000 /* protection mode PURE */ +#define HT_OPMODE_OPTIONAL 0x0001 /* protection mode optional */ +#define HT_OPMODE_HT20IN40 0x0002 /* protection mode 20MHz HT in 40MHz BSS */ +#define HT_OPMODE_MIXED 0x0003 /* protection mode Mixed Mode */ +#define HT_OPMODE_NONGF 0x0004 /* protection mode non-GF */ +#define DOT11N_TXBURST 0x0008 /* Tx burst limit */ +#define DOT11N_OBSS_NONHT 0x0010 /* OBSS Non-HT STA present */ + +/* misc_bites defn's */ +#define HT_BASIC_STBC_MCS 0x007f /* basic STBC MCS */ +#define HT_DUAL_STBC_PROT 0x0080 /* Dual STBC Protection */ +#define HT_SECOND_BCN 0x0100 /* Secondary beacon support */ +#define HT_LSIG_TXOP 0x0200 /* L-SIG TXOP Protection full support */ +#define HT_PCO_ACTIVE 0x0400 /* PCO active */ +#define HT_PCO_PHASE 0x0800 /* PCO phase */ +#define HT_DUALCTS_PROTECTION 0x0080 /* DUAL CTS protection needed */ + +/* Tx Burst Limits */ +#define DOT11N_2G_TXBURST_LIMIT 6160 /* 2G band Tx burst limit per 802.11n Draft 1.10 (usec) */ +#define DOT11N_5G_TXBURST_LIMIT 3080 /* 5G band Tx burst limit per 802.11n Draft 1.10 (usec) */ + +/* Macros for opmode */ +#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) /* mixed mode present */ +#define HT_HT20_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ + == HT_OPMODE_HT20IN40) /* 20MHz HT present */ +#define HT_OPTIONAL_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ + == HT_OPMODE_OPTIONAL) /* Optional protection present */ +#define HT_USE_PROTECTION(add_ie) (HT_HT20_PRESENT((add_ie)) || \ + HT_MIXEDMODE_PRESENT((add_ie))) /* use protection */ +#define HT_NONGF_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_NONGF) \ + == HT_OPMODE_NONGF) /* non-GF present */ +#define DOT11N_TXBURST_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & DOT11N_TXBURST) \ + == DOT11N_TXBURST) /* Tx Burst present */ +#define DOT11N_OBSS_NONHT_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & DOT11N_OBSS_NONHT) \ + == DOT11N_OBSS_NONHT) /* OBSS Non-HT present */ + +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; +} BWL_POST_PACKED_STRUCT; +typedef struct obss_params obss_params_t; + +BWL_PRE_PACKED_STRUCT struct dot11_obss_ie { + 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) /* HT OBSS len (based on 802.11n d3.0) */ + +/* HT control field */ +#define HT_CTRL_LA_TRQ 0x00000002 /* sounding request */ +#define HT_CTRL_LA_MAI 0x0000003C /* MCS request or antenna selection indication */ +#define HT_CTRL_LA_MAI_SHIFT 2 +#define HT_CTRL_LA_MAI_MRQ 0x00000004 /* MCS request */ +#define HT_CTRL_LA_MAI_MSI 0x00000038 /* MCS request sequence identifier */ +#define HT_CTRL_LA_MFSI 0x000001C0 /* MFB sequence identifier */ +#define HT_CTRL_LA_MFSI_SHIFT 6 +#define HT_CTRL_LA_MFB_ASELC 0x0000FE00 /* MCS feedback, antenna selection command/data */ +#define HT_CTRL_LA_MFB_ASELC_SH 9 +#define HT_CTRL_LA_ASELC_CMD 0x00000C00 /* ASEL command */ +#define HT_CTRL_LA_ASELC_DATA 0x0000F000 /* ASEL data */ +#define HT_CTRL_CAL_POS 0x00030000 /* Calibration position */ +#define HT_CTRL_CAL_SEQ 0x000C0000 /* Calibration sequence */ +#define HT_CTRL_CSI_STEERING 0x00C00000 /* CSI/Steering */ +#define HT_CTRL_CSI_STEER_SHIFT 22 +#define HT_CTRL_CSI_STEER_NFB 0 /* no fedback required */ +#define HT_CTRL_CSI_STEER_CSI 1 /* CSI, H matrix */ +#define HT_CTRL_CSI_STEER_NCOM 2 /* non-compressed beamforming */ +#define HT_CTRL_CSI_STEER_COM 3 /* compressed beamforming */ +#define HT_CTRL_NDP_ANNOUNCE 0x01000000 /* NDP announcement */ +#define HT_CTRL_AC_CONSTRAINT 0x40000000 /* AC Constraint */ +#define HT_CTRL_RDG_MOREPPDU 0x80000000 /* RDG/More PPDU */ + +#define HT_OPMODE_OPTIONAL 0x0001 /* protection mode optional */ +#define HT_OPMODE_HT20IN40 0x0002 /* protection mode 20MHz HT in 40MHz BSS */ +#define HT_OPMODE_MIXED 0x0003 /* protection mode Mixed Mode */ +#define HT_OPMODE_NONGF 0x0004 /* protection mode non-GF */ +#define DOT11N_TXBURST 0x0008 /* Tx burst limit */ +#define DOT11N_OBSS_NONHT 0x0010 /* OBSS Non-HT STA present */ + +/* ************* VHT definitions. ************* */ + +BWL_PRE_PACKED_STRUCT struct vht_cap_ie { + uint32 vht_cap_info; + /* supported MCS set - 64 bit field */ + 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; +/* 4B cap_info + 8B supp_mcs */ +#define VHT_CAP_IE_LEN 12 +/* 32bit - cap info */ +#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 + +/* 64-bit Supp MCS. */ +#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 + +/* VHT Capabilities Supported Channel Width */ +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; + +/* VHT Capabilities Supported max MPDU LEN */ +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; + +/* VHT Operation Element */ +BWL_PRE_PACKED_STRUCT struct vht_op_ie { + uint8 chan_width; + uint8 chan1; + uint8 chan2; + uint16 supp_mcs; /* same def as above in vht cap */ +} BWL_POST_PACKED_STRUCT; +typedef struct vht_op_ie vht_op_ie_t; +/* 3B VHT Op info + 2B Basic MCS */ +#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; + +/* Def for rx & tx basic mcs maps - ea ss num has 2 bits of info */ +#define VHT_MCS_MAP_GET_SS_IDX(nss) (((nss)-1)*2) +#define VHT_MCS_MAP_GET_MCS_PER_SS(nss, mcsMap) \ + (((mcsMap) >> VHT_MCS_MAP_GET_SS_IDX(nss)) & 0x3) +#define VHT_MCS_MAP_SET_MCS_PER_SS(nss, numMcs, mcsMap) \ + ((mcsMap) |= (((numMcs) & 0x3) << VHT_MCS_MAP_GET_SS_IDX(nss))) + +/* ************* WPA definitions. ************* */ +#define WPA_OUI "\x00\x50\xF2" /* WPA OUI */ +#define WPA_OUI_LEN 3 /* WPA OUI length */ +#define WPA_OUI_TYPE 1 +#define WPA_VERSION 1 /* WPA version */ +#define WPA2_OUI "\x00\x0F\xAC" /* WPA2 OUI */ +#define WPA2_OUI_LEN 3 /* WPA2 OUI length */ +#define WPA2_VERSION 1 /* WPA2 version */ +#define WPA2_VERSION_LEN 2 /* WAP2 version length */ + +/* ************* WPS definitions. ************* */ +#define WPS_OUI "\x00\x50\xF2" /* WPS OUI */ +#define WPS_OUI_LEN 3 /* WPS OUI length */ +#define WPS_OUI_TYPE 4 + +/* ************* WFA definitions. ************* */ + +#ifdef P2P_IE_OVRD +#define WFA_OUI MAC_OUI +#else +#define WFA_OUI "\x50\x6F\x9A" /* WFA OUI */ +#endif /* P2P_IE_OVRD */ +#define WFA_OUI_LEN 3 /* WFA OUI length */ +#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 +#ifdef WLTDLS +#define WFA_OUI_TYPE_WFD 10 +#endif /* WTDLS */ + +/* RSN authenticated key managment suite */ +#define RSN_AKM_NONE 0 /* None (IBSS) */ +#define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */ +#define RSN_AKM_PSK 2 /* Pre-shared Key */ +#define RSN_AKM_FBT_1X 3 /* Fast Bss transition using 802.1X */ +#define RSN_AKM_FBT_PSK 4 /* Fast Bss transition using Pre-shared Key */ +#define RSN_AKM_MFP_1X 5 /* SHA256 key derivation, using 802.1X */ +#define RSN_AKM_MFP_PSK 6 /* SHA256 key derivation, using Pre-shared Key */ +#define RSN_AKM_TPK 7 /* TPK(TDLS Peer Key) handshake */ + +/* Key related defines */ +#define DOT11_MAX_DEFAULT_KEYS 4 /* number of default keys */ +#define DOT11_MAX_KEY_SIZE 32 /* max size of any key */ +#define DOT11_MAX_IV_SIZE 16 /* max size of any IV */ +#define DOT11_EXT_IV_FLAG (1<<5) /* flag to indicate IV is > 4 bytes */ +#define DOT11_WPA_KEY_RSC_LEN 8 /* WPA RSC key len */ + +#define WEP1_KEY_SIZE 5 /* max size of any WEP key */ +#define WEP1_KEY_HEX_SIZE 10 /* size of WEP key in hex. */ +#define WEP128_KEY_SIZE 13 /* max size of any WEP key */ +#define WEP128_KEY_HEX_SIZE 26 /* size of WEP key in hex. */ +#define TKIP_MIC_SIZE 8 /* size of TKIP MIC */ +#define TKIP_EOM_SIZE 7 /* max size of TKIP EOM */ +#define TKIP_EOM_FLAG 0x5a /* TKIP EOM flag byte */ +#define TKIP_KEY_SIZE 32 /* size of any TKIP key */ +#define TKIP_MIC_AUTH_TX 16 /* offset to Authenticator MIC TX key */ +#define TKIP_MIC_AUTH_RX 24 /* offset to Authenticator MIC RX key */ +#define TKIP_MIC_SUP_RX TKIP_MIC_AUTH_TX /* offset to Supplicant MIC RX key */ +#define TKIP_MIC_SUP_TX TKIP_MIC_AUTH_RX /* offset to Supplicant MIC TX key */ +#define AES_KEY_SIZE 16 /* size of AES key */ +#define AES_MIC_SIZE 8 /* size of AES MIC */ +#define BIP_KEY_SIZE 16 /* size of BIP key */ + +/* WCN */ +#define WCN_OUI "\x00\x50\xf2" /* WCN OUI */ +#define WCN_TYPE 4 /* WCN type */ +#ifdef BCMWAPI_WPI +#define SMS4_KEY_LEN 16 +#define SMS4_WPI_CBC_MAC_LEN 16 +#endif + + +/* 802.11r protocol definitions */ + +/* Mobility Domain IE */ +BWL_PRE_PACKED_STRUCT struct dot11_mdid_ie { + uint8 id; + uint8 len; + uint16 mdid; /* Mobility Domain Id */ + uint8 cap; +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_mdid_ie dot11_mdid_ie_t; + +#define FBT_MDID_CAP_OVERDS 0x01 /* Fast Bss transition over the DS support */ +#define FBT_MDID_CAP_RRP 0x02 /* Resource request protocol support */ + +/* Fast Bss Transition IE */ +BWL_PRE_PACKED_STRUCT struct dot11_ft_ie { + uint8 id; + uint8 len; + uint16 mic_control; /* 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; /* timeout interval type */ + uint32 value; /* timeout interval value */ +} BWL_POST_PACKED_STRUCT; +typedef struct dot11_timeout_ie dot11_timeout_ie_t; + + +/* GTK ie */ +BWL_PRE_PACKED_STRUCT struct dot11_gtk_ie { + uint8 id; + uint8 len; + uint16 key_info; + uint8 key_len; + uint8 rsc[8]; + uint8 data[1]; +} BWL_POST_PACKED_STRUCT; +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" + + +/* ************* WMM Parameter definitions. ************* */ +#define WMM_OUI "\x00\x50\xF2" /* WNN OUI */ +#define WMM_OUI_LEN 3 /* WMM OUI length */ +#define WMM_OUI_TYPE 2 /* WMM OUT type */ +#define WMM_VERSION 1 +#define WMM_VERSION_LEN 1 + +/* WMM OUI subtype */ +#define WMM_OUI_SUBTYPE_PARAMETER 1 +#define WMM_PARAMETER_IE_LEN 24 + +/* Link Identifier Element */ +BWL_PRE_PACKED_STRUCT struct link_id_ie { + uint8 id; + uint8 len; + struct ether_addr bssid; + struct ether_addr tdls_init_mac; + struct ether_addr tdls_resp_mac; +} BWL_POST_PACKED_STRUCT; +typedef struct link_id_ie link_id_ie_t; +#define TDLS_LINK_ID_IE_LEN 18 + +/* Link Wakeup Schedule Element */ +BWL_PRE_PACKED_STRUCT struct wakeup_sch_ie { + uint8 id; + uint8 len; + uint32 offset; /* in ms between TSF0 and start of 1st Awake Window */ + uint32 interval; /* in ms bwtween the start of 2 Awake Windows */ + uint32 awake_win_slots; /* in backof slots, duration of Awake Window */ + uint32 max_wake_win; /* in ms, max duration of Awake Window */ + uint16 idle_cnt; /* number of consecutive Awake Windows */ +} BWL_POST_PACKED_STRUCT; +typedef struct wakeup_sch_ie wakeup_sch_ie_t; +#define TDLS_WAKEUP_SCH_IE_LEN 18 + +/* Channel Switch Timing Element */ +BWL_PRE_PACKED_STRUCT struct channel_switch_timing_ie { + uint8 id; + uint8 len; + uint16 switch_time; /* in ms, time to switch channels */ + uint16 switch_timeout; /* in ms */ +} BWL_POST_PACKED_STRUCT; +typedef struct channel_switch_timing_ie channel_switch_timing_ie_t; +#define TDLS_CHANNEL_SWITCH_TIMING_IE_LEN 4 + +/* PTI Control Element */ +BWL_PRE_PACKED_STRUCT struct pti_control_ie { + uint8 id; + uint8 len; + uint8 tid; + uint16 seq_control; +} BWL_POST_PACKED_STRUCT; +typedef struct pti_control_ie pti_control_ie_t; +#define TDLS_PTI_CONTROL_IE_LEN 3 + +/* PU Buffer Status Element */ +BWL_PRE_PACKED_STRUCT struct pu_buffer_status_ie { + uint8 id; + uint8 len; + uint8 status; +} BWL_POST_PACKED_STRUCT; +typedef struct pu_buffer_status_ie pu_buffer_status_ie_t; +#define TDLS_PU_BUFFER_STATUS_IE_LEN 1 +#define TDLS_PU_BUFFER_STATUS_AC_BK 1 +#define TDLS_PU_BUFFER_STATUS_AC_BE 2 +#define TDLS_PU_BUFFER_STATUS_AC_VI 4 +#define TDLS_PU_BUFFER_STATUS_AC_VO 8 + +#ifdef BCMWAPI_WAI +#define WAPI_IE_MIN_LEN 20 /* WAPI IE min length */ +#define WAPI_VERSION 1 /* WAPI version */ +#define WAPI_VERSION_LEN 2 /* WAPI version length */ +#define WAPI_OUI "\x00\x14\x72" /* WAPI OUI */ +#define WAPI_OUI_LEN DOT11_OUI_LEN /* WAPI OUI length */ +#endif /* BCMWAPI_WAI */ + +/* This marks the end of a packed structure section. */ +#include + +#endif /* _802_11_H_ */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/proto/802.1d.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/proto/802.1d.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/proto/802.1d.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/proto/802.1d.h 2014-02-15 00:43:44.793014092 +0100 @@ -0,0 +1,50 @@ +/* + * 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 types and constants relating to 802.1D + * + * $Id: 802.1d.h 241182 2011-02-17 21:50:03Z $ + */ + +#ifndef _802_1_D_ +#define _802_1_D_ + +/* 802.1D priority defines */ +#define PRIO_8021D_NONE 2 /* None = - */ +#define PRIO_8021D_BK 1 /* BK - Background */ +#define PRIO_8021D_BE 0 /* BE - Best-effort */ +#define PRIO_8021D_EE 3 /* EE - Excellent-effort */ +#define PRIO_8021D_CL 4 /* CL - Controlled Load */ +#define PRIO_8021D_VI 5 /* Vi - Video */ +#define PRIO_8021D_VO 6 /* Vo - Voice */ +#define PRIO_8021D_NC 7 /* NC - Network Control */ +#define MAXPRIO 7 /* 0-7 */ +#define NUMPRIO (MAXPRIO + 1) + +#define ALLPRIO -1 /* All prioirty */ + +/* Converts prio to precedence since the numerical value of + * PRIO_8021D_BE and PRIO_8021D_NONE are swapped. + */ +#define PRIO2PREC(prio) \ + (((prio) == PRIO_8021D_NONE || (prio) == PRIO_8021D_BE) ? ((prio^2)) : (prio)) + +#endif /* _802_1_D__ */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/proto/bcmeth.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/proto/bcmeth.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/proto/bcmeth.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/proto/bcmeth.h 2014-02-15 00:43:44.793014092 +0100 @@ -0,0 +1,112 @@ +/* + * Broadcom Ethernettype protocol 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: bcmeth.h 294352 2011-11-06 19:23:00Z $ + */ + +/* + * Broadcom Ethernet protocol defines + */ + +#ifndef _BCMETH_H_ +#define _BCMETH_H_ + +#ifndef _TYPEDEFS_H_ +#include +#endif + +/* This marks the start of a packed structure section. */ +#include + +/* ETHER_TYPE_BRCM is defined in ethernet.h */ + +/* + * Following the 2byte BRCM ether_type is a 16bit BRCM subtype field + * in one of two formats: (only subtypes 32768-65535 are in use now) + * + * subtypes 0-32767: + * 8 bit subtype (0-127) + * 8 bit length in bytes (0-255) + * + * subtypes 32768-65535: + * 16 bit big-endian subtype + * 16 bit big-endian length in bytes (0-65535) + * + * length is the number of additional bytes beyond the 4 or 6 byte header + * + * Reserved values: + * 0 reserved + * 5-15 reserved for iLine protocol assignments + * 17-126 reserved, assignable + * 127 reserved + * 32768 reserved + * 32769-65534 reserved, assignable + * 65535 reserved + */ + +/* + * While adding the subtypes and their specific processing code make sure + * bcmeth_bcm_hdr_t is the first data structure in the user specific data structure definition + */ + +#define BCMILCP_SUBTYPE_RATE 1 +#define BCMILCP_SUBTYPE_LINK 2 +#define BCMILCP_SUBTYPE_CSA 3 +#define BCMILCP_SUBTYPE_LARQ 4 +#define BCMILCP_SUBTYPE_VENDOR 5 +#define BCMILCP_SUBTYPE_FLH 17 + +#define BCMILCP_SUBTYPE_VENDOR_LONG 32769 +#define BCMILCP_SUBTYPE_CERT 32770 +#define BCMILCP_SUBTYPE_SES 32771 + + +#define BCMILCP_BCM_SUBTYPE_RESERVED 0 +#define BCMILCP_BCM_SUBTYPE_EVENT 1 +#define BCMILCP_BCM_SUBTYPE_SES 2 +/* + * The EAPOL type is not used anymore. Instead EAPOL messages are now embedded + * within BCMILCP_BCM_SUBTYPE_EVENT type messages + */ +/* #define BCMILCP_BCM_SUBTYPE_EAPOL 3 */ +#define BCMILCP_BCM_SUBTYPE_DPT 4 + +#define BCMILCP_BCM_SUBTYPEHDR_MINLENGTH 8 +#define BCMILCP_BCM_SUBTYPEHDR_VERSION 0 + +/* These fields are stored in network order */ +typedef BWL_PRE_PACKED_STRUCT struct bcmeth_hdr +{ + uint16 subtype; /* Vendor specific..32769 */ + uint16 length; + uint8 version; /* Version is 0 */ + uint8 oui[3]; /* Broadcom OUI */ + /* user specific Data */ + uint16 usr_subtype; +} BWL_POST_PACKED_STRUCT bcmeth_hdr_t; + + +/* This marks the end of a packed structure section. */ +#include + +#endif /* _BCMETH_H_ */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/proto/bcmevent.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/proto/bcmevent.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/proto/bcmevent.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/proto/bcmevent.h 2014-02-15 00:43:44.793014092 +0100 @@ -0,0 +1,368 @@ +/* + * Broadcom Event protocol 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. + * + * Dependencies: proto/bcmeth.h + * + * $Id: bcmevent.h 374275 2012-12-12 11:44:18Z $ + * + */ + +/* + * Broadcom Ethernet Events protocol defines + * + */ + +#ifndef _BCMEVENT_H_ +#define _BCMEVENT_H_ + +#ifndef _TYPEDEFS_H_ +#include +#endif + +/* This marks the start of a packed structure section. */ +#include + +#define BCM_EVENT_MSG_VERSION 2 /* wl_event_msg_t struct version */ +#define BCM_MSG_IFNAME_MAX 16 /* max length of interface name */ + +/* flags */ +#define WLC_EVENT_MSG_LINK 0x01 /* link is up */ +#define WLC_EVENT_MSG_FLUSHTXQ 0x02 /* flush tx queue on MIC error */ +#define WLC_EVENT_MSG_GROUP 0x04 /* group MIC error */ +#define WLC_EVENT_MSG_UNKBSS 0x08 /* unknown source bsscfg */ +#define WLC_EVENT_MSG_UNKIF 0x10 /* unknown source OS i/f */ + +/* these fields are stored in network order */ + +/* version 1 */ +typedef BWL_PRE_PACKED_STRUCT struct +{ + uint16 version; + uint16 flags; /* see flags below */ + uint32 event_type; /* Message (see below) */ + uint32 status; /* Status code (see below) */ + uint32 reason; /* Reason code (if applicable) */ + uint32 auth_type; /* WLC_E_AUTH */ + uint32 datalen; /* data buf */ + struct ether_addr addr; /* Station address (if applicable) */ + char ifname[BCM_MSG_IFNAME_MAX]; /* name of the packet incoming interface */ +} BWL_POST_PACKED_STRUCT wl_event_msg_v1_t; + +/* the current version */ +typedef BWL_PRE_PACKED_STRUCT struct +{ + uint16 version; + uint16 flags; /* see flags below */ + uint32 event_type; /* Message (see below) */ + uint32 status; /* Status code (see below) */ + uint32 reason; /* Reason code (if applicable) */ + uint32 auth_type; /* WLC_E_AUTH */ + uint32 datalen; /* data buf */ + struct ether_addr addr; /* Station address (if applicable) */ + char ifname[BCM_MSG_IFNAME_MAX]; /* name of the packet incoming interface */ + uint8 ifidx; /* destination OS i/f index */ + uint8 bsscfgidx; /* source bsscfg index */ +} BWL_POST_PACKED_STRUCT wl_event_msg_t; + +/* used by driver msgs */ +typedef BWL_PRE_PACKED_STRUCT struct bcm_event { + struct ether_header eth; + bcmeth_hdr_t bcm_hdr; + wl_event_msg_t event; + /* data portion follows */ +} BWL_POST_PACKED_STRUCT bcm_event_t; + +#define BCM_MSG_LEN (sizeof(bcm_event_t) - sizeof(bcmeth_hdr_t) - sizeof(struct ether_header)) + +/* Event messages */ +#define WLC_E_SET_SSID 0 /* indicates status of set SSID */ +#define WLC_E_JOIN 1 /* differentiates join IBSS from found (WLC_E_START) IBSS */ +#define WLC_E_START 2 /* STA founded an IBSS or AP started a BSS */ +#define WLC_E_AUTH 3 /* 802.11 AUTH request */ +#define WLC_E_AUTH_IND 4 /* 802.11 AUTH indication */ +#define WLC_E_DEAUTH 5 /* 802.11 DEAUTH request */ +#define WLC_E_DEAUTH_IND 6 /* 802.11 DEAUTH indication */ +#define WLC_E_ASSOC 7 /* 802.11 ASSOC request */ +#define WLC_E_ASSOC_IND 8 /* 802.11 ASSOC indication */ +#define WLC_E_REASSOC 9 /* 802.11 REASSOC request */ +#define WLC_E_REASSOC_IND 10 /* 802.11 REASSOC indication */ +#define WLC_E_DISASSOC 11 /* 802.11 DISASSOC request */ +#define WLC_E_DISASSOC_IND 12 /* 802.11 DISASSOC indication */ +#define WLC_E_QUIET_START 13 /* 802.11h Quiet period started */ +#define WLC_E_QUIET_END 14 /* 802.11h Quiet period ended */ +#define WLC_E_BEACON_RX 15 /* BEACONS received/lost indication */ +#define WLC_E_LINK 16 /* generic link indication */ +#define WLC_E_MIC_ERROR 17 /* TKIP MIC error occurred */ +#define WLC_E_NDIS_LINK 18 /* NDIS style link indication */ +#define WLC_E_ROAM 19 /* roam attempt occurred: indicate status & reason */ +#define WLC_E_TXFAIL 20 /* change in dot11FailedCount (txfail) */ +#define WLC_E_PMKID_CACHE 21 /* WPA2 pmkid cache indication */ +#define WLC_E_RETROGRADE_TSF 22 /* current AP's TSF value went backward */ +#define WLC_E_PRUNE 23 /* AP was pruned from join list for reason */ +#define WLC_E_AUTOAUTH 24 /* report AutoAuth table entry match for join attempt */ +#define WLC_E_EAPOL_MSG 25 /* Event encapsulating an EAPOL message */ +#define WLC_E_SCAN_COMPLETE 26 /* Scan results are ready or scan was aborted */ +#define WLC_E_ADDTS_IND 27 /* indicate to host addts fail/success */ +#define WLC_E_DELTS_IND 28 /* indicate to host delts fail/success */ +#define WLC_E_BCNSENT_IND 29 /* indicate to host of beacon transmit */ +#define WLC_E_BCNRX_MSG 30 /* Send the received beacon up to the host */ +#define WLC_E_BCNLOST_MSG 31 /* indicate to host loss of beacon */ +#define WLC_E_ROAM_PREP 32 /* before attempting to roam */ +#define WLC_E_PFN_NET_FOUND 33 /* PFN network found event */ +#define WLC_E_PFN_NET_LOST 34 /* PFN network lost event */ +#define WLC_E_RESET_COMPLETE 35 +#define WLC_E_JOIN_START 36 +#define WLC_E_ROAM_START 37 +#define WLC_E_ASSOC_START 38 +#define WLC_E_IBSS_ASSOC 39 +#define WLC_E_RADIO 40 +#define WLC_E_PSM_WATCHDOG 41 /* PSM microcode watchdog fired */ +#define WLC_E_PROBREQ_MSG 44 /* probe request received */ +#define WLC_E_SCAN_CONFIRM_IND 45 +#define WLC_E_PSK_SUP 46 /* WPA Handshake fail */ +#define WLC_E_COUNTRY_CODE_CHANGED 47 +#define WLC_E_EXCEEDED_MEDIUM_TIME 48 /* WMMAC excedded medium time */ +#define WLC_E_ICV_ERROR 49 /* WEP ICV error occurred */ +#define WLC_E_UNICAST_DECODE_ERROR 50 /* Unsupported unicast encrypted frame */ +#define WLC_E_MULTICAST_DECODE_ERROR 51 /* Unsupported multicast encrypted frame */ +#define WLC_E_TRACE 52 +#ifdef WLBTAMP +#define WLC_E_BTA_HCI_EVENT 53 /* BT-AMP HCI event */ +#endif +#define WLC_E_IF 54 /* I/F change (for dongle host notification) */ +#define WLC_E_P2P_DISC_LISTEN_COMPLETE 55 /* listen state expires */ +#define WLC_E_RSSI 56 /* indicate RSSI change based on configured levels */ +#define WLC_E_PFN_SCAN_COMPLETE 57 /* PFN completed scan of network list */ +#define WLC_E_EXTLOG_MSG 58 +#define WLC_E_ACTION_FRAME 59 /* Action frame Rx */ +#define WLC_E_ACTION_FRAME_COMPLETE 60 /* Action frame Tx complete */ +#define WLC_E_PRE_ASSOC_IND 61 /* assoc request received */ +#define WLC_E_PRE_REASSOC_IND 62 /* re-assoc request received */ +#define WLC_E_CHANNEL_ADOPTED 63 +#define WLC_E_AP_STARTED 64 /* AP started */ +#define WLC_E_DFS_AP_STOP 65 /* AP stopped due to DFS */ +#define WLC_E_DFS_AP_RESUME 66 /* AP resumed due to DFS */ +#define WLC_E_WAI_STA_EVENT 67 /* WAI stations event */ +#define WLC_E_WAI_MSG 68 /* event encapsulating an WAI message */ +#define WLC_E_ESCAN_RESULT 69 /* escan result event */ +#define WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE 70 /* action frame off channel complete */ +#define WLC_E_PROBRESP_MSG 71 /* probe response received */ +#define WLC_E_P2P_PROBREQ_MSG 72 /* P2P Probe request received */ +#define WLC_E_DCS_REQUEST 73 + +#define WLC_E_FIFO_CREDIT_MAP 74 /* credits for D11 FIFOs. [AC0,AC1,AC2,AC3,BC_MC,ATIM] */ + +#define WLC_E_ACTION_FRAME_RX 75 /* Received action frame event WITH + * wl_event_rx_frame_data_t header + */ +#define WLC_E_WAKE_EVENT 76 /* Wake Event timer fired, used for wake WLAN test mode */ +#define WLC_E_RM_COMPLETE 77 /* Radio measurement complete */ +#define WLC_E_HTSFSYNC 78 /* Synchronize TSF with the host */ +#define WLC_E_OVERLAY_REQ 79 /* request an overlay IOCTL/iovar from the host */ +#define WLC_E_CSA_COMPLETE_IND 80 /* 802.11 CHANNEL SWITCH ACTION completed */ +#define WLC_E_EXCESS_PM_WAKE_EVENT 81 /* excess PM Wake Event to inform host */ +#define WLC_E_PFN_SCAN_NONE 82 /* no PFN networks around */ +#define WLC_E_PFN_SCAN_ALLGONE 83 /* last found PFN network gets lost */ +#define WLC_E_GTK_PLUMBED 84 +#define WLC_E_ASSOC_IND_NDIS 85 /* 802.11 ASSOC indication for NDIS only */ +#define WLC_E_REASSOC_IND_NDIS 86 /* 802.11 REASSOC indication for NDIS only */ +#define WLC_E_ASSOC_REQ_IE 87 +#define WLC_E_ASSOC_RESP_IE 88 +#define WLC_E_ASSOC_RECREATED 89 /* association recreated on resume */ +#define WLC_E_ACTION_FRAME_RX_NDIS 90 /* rx action frame event for NDIS only */ +#define WLC_E_AUTH_REQ 91 /* authentication request received */ +#define WLC_E_TDLS_PEER_EVENT 92 /* discovered peer, connected or disconnected peer */ +#define WLC_E_SPEEDY_RECREATE_FAIL 93 /* fast assoc recreation failed */ +#define WLC_E_SERVICE_FOUND 102 /* desired service found */ +#define WLC_E_GAS_FRAGMENT_RX 103 /* GAS fragment received */ +#define WLC_E_GAS_COMPLETE 104 /* GAS sessions all complete */ +#define WLC_E_P2PO_ADD_DEVICE 105 /* New device found by p2p offload */ +#define WLC_E_P2PO_DEL_DEVICE 106 /* device has been removed by p2p offload */ +#define WLC_E_LAST 107 /* highest val + 1 for range checking */ + + +/* Table of event name strings for UIs and debugging dumps */ +typedef struct { + uint event; + const char *name; +} bcmevent_name_t; + +extern const bcmevent_name_t bcmevent_names[]; +extern const int bcmevent_names_size; + +/* Event status codes */ +#define WLC_E_STATUS_SUCCESS 0 /* operation was successful */ +#define WLC_E_STATUS_FAIL 1 /* operation failed */ +#define WLC_E_STATUS_TIMEOUT 2 /* operation timed out */ +#define WLC_E_STATUS_NO_NETWORKS 3 /* failed due to no matching network found */ +#define WLC_E_STATUS_ABORT 4 /* operation was aborted */ +#define WLC_E_STATUS_NO_ACK 5 /* protocol failure: packet not ack'd */ +#define WLC_E_STATUS_UNSOLICITED 6 /* AUTH or ASSOC packet was unsolicited */ +#define WLC_E_STATUS_ATTEMPT 7 /* attempt to assoc to an auto auth configuration */ +#define WLC_E_STATUS_PARTIAL 8 /* scan results are incomplete */ +#define WLC_E_STATUS_NEWSCAN 9 /* scan aborted by another scan */ +#define WLC_E_STATUS_NEWASSOC 10 /* scan aborted due to assoc in progress */ +#define WLC_E_STATUS_11HQUIET 11 /* 802.11h quiet period started */ +#define WLC_E_STATUS_SUPPRESS 12 /* user disabled scanning (WLC_SET_SCANSUPPRESS) */ +#define WLC_E_STATUS_NOCHANS 13 /* no allowable channels to scan */ +#define WLC_E_STATUS_CS_ABORT 15 /* abort channel select */ +#define WLC_E_STATUS_ERROR 16 /* request failed due to error */ + +/* roam reason codes */ +#define WLC_E_REASON_INITIAL_ASSOC 0 /* initial assoc */ +#define WLC_E_REASON_LOW_RSSI 1 /* roamed due to low RSSI */ +#define WLC_E_REASON_DEAUTH 2 /* roamed due to DEAUTH indication */ +#define WLC_E_REASON_DISASSOC 3 /* roamed due to DISASSOC indication */ +#define WLC_E_REASON_BCNS_LOST 4 /* roamed due to lost beacons */ +#define WLC_E_REASON_MINTXRATE 9 /* roamed because at mintxrate for too long */ +#define WLC_E_REASON_TXFAIL 10 /* We can hear AP, but AP can't hear us */ + +/* Roam codes used primarily by CCX */ +#define WLC_E_REASON_FAST_ROAM_FAILED 5 /* roamed due to fast roam failure */ +#define WLC_E_REASON_DIRECTED_ROAM 6 /* roamed due to request by AP */ +#define WLC_E_REASON_TSPEC_REJECTED 7 /* roamed due to TSPEC rejection */ +#define WLC_E_REASON_BETTER_AP 8 /* roamed due to finding better AP */ + + +#define WLC_E_REASON_REQUESTED_ROAM 11 /* roamed due to BSS Mgmt Transition request by AP */ + +/* prune reason codes */ +#define WLC_E_PRUNE_ENCR_MISMATCH 1 /* encryption mismatch */ +#define WLC_E_PRUNE_BCAST_BSSID 2 /* AP uses a broadcast BSSID */ +#define WLC_E_PRUNE_MAC_DENY 3 /* STA's MAC addr is in AP's MAC deny list */ +#define WLC_E_PRUNE_MAC_NA 4 /* STA's MAC addr is not in AP's MAC allow list */ +#define WLC_E_PRUNE_REG_PASSV 5 /* AP not allowed due to regulatory restriction */ +#define WLC_E_PRUNE_SPCT_MGMT 6 /* AP does not support STA locale spectrum mgmt */ +#define WLC_E_PRUNE_RADAR 7 /* AP is on a radar channel of STA locale */ +#define WLC_E_RSN_MISMATCH 8 /* STA does not support AP's RSN */ +#define WLC_E_PRUNE_NO_COMMON_RATES 9 /* No rates in common with AP */ +#define WLC_E_PRUNE_BASIC_RATES 10 /* STA does not support all basic rates of BSS */ +#define WLC_E_PRUNE_CIPHER_NA 12 /* BSS's cipher not supported */ +#define WLC_E_PRUNE_KNOWN_STA 13 /* AP is already known to us as a STA */ +#define WLC_E_PRUNE_WDS_PEER 15 /* AP is already known to us as a WDS peer */ +#define WLC_E_PRUNE_QBSS_LOAD 16 /* QBSS LOAD - AAC is too low */ +#define WLC_E_PRUNE_HOME_AP 17 /* prune home AP */ + +/* WPA failure reason codes carried in the WLC_E_PSK_SUP event */ +#define WLC_E_SUP_OTHER 0 /* Other reason */ +#define WLC_E_SUP_DECRYPT_KEY_DATA 1 /* Decryption of key data failed */ +#define WLC_E_SUP_BAD_UCAST_WEP128 2 /* Illegal use of ucast WEP128 */ +#define WLC_E_SUP_BAD_UCAST_WEP40 3 /* Illegal use of ucast WEP40 */ +#define WLC_E_SUP_UNSUP_KEY_LEN 4 /* Unsupported key length */ +#define WLC_E_SUP_PW_KEY_CIPHER 5 /* Unicast cipher mismatch in pairwise key */ +#define WLC_E_SUP_MSG3_TOO_MANY_IE 6 /* WPA IE contains > 1 RSN IE in key msg 3 */ +#define WLC_E_SUP_MSG3_IE_MISMATCH 7 /* WPA IE mismatch in key message 3 */ +#define WLC_E_SUP_NO_INSTALL_FLAG 8 /* INSTALL flag unset in 4-way msg */ +#define WLC_E_SUP_MSG3_NO_GTK 9 /* encapsulated GTK missing from msg 3 */ +#define WLC_E_SUP_GRP_KEY_CIPHER 10 /* Multicast cipher mismatch in group key */ +#define WLC_E_SUP_GRP_MSG1_NO_GTK 11 /* encapsulated GTK missing from group msg 1 */ +#define WLC_E_SUP_GTK_DECRYPT_FAIL 12 /* GTK decrypt failure */ +#define WLC_E_SUP_SEND_FAIL 13 /* message send failure */ +#define WLC_E_SUP_DEAUTH 14 /* received FC_DEAUTH */ +#define WLC_E_SUP_WPA_PSK_TMO 15 /* WPA PSK 4-way handshake timeout */ + +/* Event data for events that include frames received over the air */ +/* WLC_E_PROBRESP_MSG + * WLC_E_P2P_PROBREQ_MSG + * WLC_E_ACTION_FRAME_RX + */ +typedef BWL_PRE_PACKED_STRUCT struct wl_event_rx_frame_data { + uint16 version; + uint16 channel; /* Matches chanspec_t format from bcmwifi_channels.h */ + int32 rssi; + uint32 mactime; + uint32 rate; +} BWL_POST_PACKED_STRUCT wl_event_rx_frame_data_t; + +#define BCM_RX_FRAME_DATA_VERSION 1 + +/* WLC_E_IF event data */ +typedef struct wl_event_data_if { + uint8 ifidx; /* RTE virtual device index (for dongle) */ + uint8 opcode; /* see I/F opcode */ + uint8 reserved; + uint8 bssidx; /* bsscfg index */ + uint8 role; /* see I/F role */ +} wl_event_data_if_t; + +/* opcode in WLC_E_IF event */ +#define WLC_E_IF_ADD 1 /* bsscfg add */ +#define WLC_E_IF_DEL 2 /* bsscfg delete */ +#define WLC_E_IF_CHANGE 3 /* bsscfg role change */ + +/* I/F role code in WLC_E_IF event */ +#define WLC_E_IF_ROLE_STA 0 /* Infra STA */ +#define WLC_E_IF_ROLE_AP 1 /* Access Point */ +#define WLC_E_IF_ROLE_WDS 2 /* WDS link */ +#define WLC_E_IF_ROLE_P2P_GO 3 /* P2P Group Owner */ +#define WLC_E_IF_ROLE_P2P_CLIENT 4 /* P2P Client */ +#ifdef WLBTAMP +#define WLC_E_IF_ROLE_BTA_CREATOR 5 /* BT-AMP Creator */ +#define WLC_E_IF_ROLE_BTA_ACCEPTOR 6 /* BT-AMP Acceptor */ +#endif + +/* Reason codes for LINK */ +#define WLC_E_LINK_BCN_LOSS 1 /* Link down because of beacon loss */ +#define WLC_E_LINK_DISASSOC 2 /* Link down because of disassoc */ +#define WLC_E_LINK_ASSOC_REC 3 /* Link down because assoc recreate failed */ +#define WLC_E_LINK_BSSCFG_DIS 4 /* Link down due to bsscfg down */ + +/* reason codes for WLC_E_OVERLAY_REQ event */ +#define WLC_E_OVL_DOWNLOAD 0 /* overlay download request */ +#define WLC_E_OVL_UPDATE_IND 1 /* device indication of host overlay update */ + +/* reason codes for WLC_E_TDLS_PEER_EVENT event */ +#define WLC_E_TDLS_PEER_DISCOVERED 0 /* peer is ready to establish TDLS */ +#define WLC_E_TDLS_PEER_CONNECTED 1 +#define WLC_E_TDLS_PEER_DISCONNECTED 2 + +/* GAS event data */ +typedef BWL_PRE_PACKED_STRUCT struct wl_event_gas { + uint16 channel; /* channel of GAS protocol */ + uint8 dialog_token; /* GAS dialog token */ + uint8 fragment_id; /* fragment id */ + uint16 status_code; /* status code on GAS completion */ + uint16 data_len; /* length of data to follow */ + uint8 data[1]; /* variable length specified by data_len */ +} BWL_POST_PACKED_STRUCT wl_event_gas_t; + +/* service discovery TLV */ +typedef BWL_PRE_PACKED_STRUCT struct wl_sd_tlv { + uint16 length; /* length of response_data */ + uint8 protocol; /* service protocol type */ + uint8 transaction_id; /* service transaction id */ + uint8 status_code; /* status code */ + uint8 data[1]; /* response data */ +} BWL_POST_PACKED_STRUCT wl_sd_tlv_t; + +/* service discovery event data */ +typedef BWL_PRE_PACKED_STRUCT struct wl_event_sd { + uint16 channel; /* channel */ + uint8 count; /* number of tlvs */ + wl_sd_tlv_t tlv[1]; /* service discovery TLV */ +} BWL_POST_PACKED_STRUCT wl_event_sd_t; + +/* This marks the end of a packed structure section. */ +#include + +#endif /* _BCMEVENT_H_ */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/proto/bcmip.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/proto/bcmip.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/proto/bcmip.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/proto/bcmip.h 2014-02-15 00:43:44.793014092 +0100 @@ -0,0 +1,210 @@ +/* + * 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 IP Protocol + * + * $Id: bcmip.h 290206 2011-10-17 19:13:51Z $ + */ + +#ifndef _bcmip_h_ +#define _bcmip_h_ + +#ifndef _TYPEDEFS_H_ +#include +#endif + +/* This marks the start of a packed structure section. */ +#include + + +/* IPV4 and IPV6 common */ +#define IP_VER_OFFSET 0x0 /* offset to version field */ +#define IP_VER_MASK 0xf0 /* version mask */ +#define IP_VER_SHIFT 4 /* version shift */ +#define IP_VER_4 4 /* version number for IPV4 */ +#define IP_VER_6 6 /* version number for IPV6 */ + +#define IP_VER(ip_body) \ + ((((uint8 *)(ip_body))[IP_VER_OFFSET] & IP_VER_MASK) >> IP_VER_SHIFT) + +#define IP_PROT_ICMP 0x1 /* ICMP protocol */ +#define IP_PROT_IGMP 0x2 /* IGMP protocol */ +#define IP_PROT_TCP 0x6 /* TCP protocol */ +#define IP_PROT_UDP 0x11 /* UDP protocol type */ +#define IP_PROT_ICMP6 0x3a /* ICMPv6 protocol type */ + +/* IPV4 field offsets */ +#define IPV4_VER_HL_OFFSET 0 /* version and ihl byte offset */ +#define IPV4_TOS_OFFSET 1 /* type of service offset */ +#define IPV4_PKTLEN_OFFSET 2 /* packet length offset */ +#define IPV4_PKTFLAG_OFFSET 6 /* more-frag,dont-frag flag offset */ +#define IPV4_PROT_OFFSET 9 /* protocol type offset */ +#define IPV4_CHKSUM_OFFSET 10 /* IP header checksum offset */ +#define IPV4_SRC_IP_OFFSET 12 /* src IP addr offset */ +#define IPV4_DEST_IP_OFFSET 16 /* dest IP addr offset */ +#define IPV4_OPTIONS_OFFSET 20 /* IP options offset */ + +/* IPV4 field decodes */ +#define IPV4_VER_MASK 0xf0 /* IPV4 version mask */ +#define IPV4_VER_SHIFT 4 /* IPV4 version shift */ + +#define IPV4_HLEN_MASK 0x0f /* IPV4 header length mask */ +#define IPV4_HLEN(ipv4_body) (4 * (((uint8 *)(ipv4_body))[IPV4_VER_HL_OFFSET] & IPV4_HLEN_MASK)) + +#define IPV4_ADDR_LEN 4 /* IPV4 address length */ + +#define IPV4_ADDR_NULL(a) ((((uint8 *)(a))[0] | ((uint8 *)(a))[1] | \ + ((uint8 *)(a))[2] | ((uint8 *)(a))[3]) == 0) + +#define IPV4_ADDR_BCAST(a) ((((uint8 *)(a))[0] & ((uint8 *)(a))[1] & \ + ((uint8 *)(a))[2] & ((uint8 *)(a))[3]) == 0xff) + +#define IPV4_TOS_DSCP_MASK 0xfc /* DiffServ codepoint mask */ +#define IPV4_TOS_DSCP_SHIFT 2 /* DiffServ codepoint shift */ + +#define IPV4_TOS(ipv4_body) (((uint8 *)(ipv4_body))[IPV4_TOS_OFFSET]) + +#define IPV4_TOS_PREC_MASK 0xe0 /* Historical precedence mask */ +#define IPV4_TOS_PREC_SHIFT 5 /* Historical precedence shift */ + +#define IPV4_TOS_LOWDELAY 0x10 /* Lowest delay requested */ +#define IPV4_TOS_THROUGHPUT 0x8 /* Best throughput requested */ +#define IPV4_TOS_RELIABILITY 0x4 /* Most reliable delivery requested */ + +#define IPV4_PROT(ipv4_body) (((uint8 *)(ipv4_body))[IPV4_PROT_OFFSET]) + +#define IPV4_FRAG_RESV 0x8000 /* Reserved */ +#define IPV4_FRAG_DONT 0x4000 /* Don't fragment */ +#define IPV4_FRAG_MORE 0x2000 /* More fragments */ +#define IPV4_FRAG_OFFSET_MASK 0x1fff /* Fragment offset */ + +#define IPV4_ADDR_STR_LEN 16 /* Max IP address length in string format */ + +/* IPV4 packet formats */ +BWL_PRE_PACKED_STRUCT struct ipv4_addr { + uint8 addr[IPV4_ADDR_LEN]; +} BWL_POST_PACKED_STRUCT; + +BWL_PRE_PACKED_STRUCT struct ipv4_hdr { + uint8 version_ihl; /* Version and Internet Header Length */ + uint8 tos; /* Type Of Service */ + uint16 tot_len; /* Number of bytes in packet (max 65535) */ + uint16 id; + uint16 frag; /* 3 flag bits and fragment offset */ + uint8 ttl; /* Time To Live */ + uint8 prot; /* Protocol */ + uint16 hdr_chksum; /* IP header checksum */ + uint8 src_ip[IPV4_ADDR_LEN]; /* Source IP Address */ + uint8 dst_ip[IPV4_ADDR_LEN]; /* Destination IP Address */ +} BWL_POST_PACKED_STRUCT; + +/* IPV6 field offsets */ +#define IPV6_PAYLOAD_LEN_OFFSET 4 /* payload length offset */ +#define IPV6_NEXT_HDR_OFFSET 6 /* next header/protocol offset */ +#define IPV6_HOP_LIMIT_OFFSET 7 /* hop limit offset */ +#define IPV6_SRC_IP_OFFSET 8 /* src IP addr offset */ +#define IPV6_DEST_IP_OFFSET 24 /* dst IP addr offset */ + +/* IPV6 field decodes */ +#define IPV6_TRAFFIC_CLASS(ipv6_body) \ + (((((uint8 *)(ipv6_body))[0] & 0x0f) << 4) | \ + ((((uint8 *)(ipv6_body))[1] & 0xf0) >> 4)) + +#define IPV6_FLOW_LABEL(ipv6_body) \ + (((((uint8 *)(ipv6_body))[1] & 0x0f) << 16) | \ + (((uint8 *)(ipv6_body))[2] << 8) | \ + (((uint8 *)(ipv6_body))[3])) + +#define IPV6_PAYLOAD_LEN(ipv6_body) \ + ((((uint8 *)(ipv6_body))[IPV6_PAYLOAD_LEN_OFFSET + 0] << 8) | \ + ((uint8 *)(ipv6_body))[IPV6_PAYLOAD_LEN_OFFSET + 1]) + +#define IPV6_NEXT_HDR(ipv6_body) \ + (((uint8 *)(ipv6_body))[IPV6_NEXT_HDR_OFFSET]) + +#define IPV6_PROT(ipv6_body) IPV6_NEXT_HDR(ipv6_body) + +#define IPV6_ADDR_LEN 16 /* IPV6 address length */ + +/* IPV4 TOS or IPV6 Traffic Classifier or 0 */ +#define IP_TOS46(ip_body) \ + (IP_VER(ip_body) == IP_VER_4 ? IPV4_TOS(ip_body) : \ + IP_VER(ip_body) == IP_VER_6 ? IPV6_TRAFFIC_CLASS(ip_body) : 0) + +/* IPV6 extension headers (options) */ +#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; +} + +/* This marks the end of a packed structure section. */ +#include + +#endif /* _bcmip_h_ */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/proto/bt_amp_hci.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/proto/bt_amp_hci.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/proto/bt_amp_hci.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/proto/bt_amp_hci.h 2014-02-15 00:43:44.793014092 +0100 @@ -0,0 +1,441 @@ +/* + * BT-AMP (BlueTooth Alternate Mac and Phy) HCI (Host/Controller Interface) + * + * 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: bt_amp_hci.h 294267 2011-11-04 23:41:52Z $ +*/ + +#ifndef _bt_amp_hci_h +#define _bt_amp_hci_h + +/* This marks the start of a packed structure section. */ +#include + + +/* AMP HCI CMD packet format */ +typedef BWL_PRE_PACKED_STRUCT struct amp_hci_cmd { + uint16 opcode; + uint8 plen; + uint8 parms[1]; +} BWL_POST_PACKED_STRUCT amp_hci_cmd_t; + +#define HCI_CMD_PREAMBLE_SIZE OFFSETOF(amp_hci_cmd_t, parms) +#define HCI_CMD_DATA_SIZE 255 + +/* AMP HCI CMD opcode layout */ +#define HCI_CMD_OPCODE(ogf, ocf) ((((ogf) & 0x3F) << 10) | ((ocf) & 0x03FF)) +#define HCI_CMD_OGF(opcode) ((uint8)(((opcode) >> 10) & 0x3F)) +#define HCI_CMD_OCF(opcode) ((opcode) & 0x03FF) + +/* AMP HCI command opcodes */ +#define HCI_Read_Failed_Contact_Counter HCI_CMD_OPCODE(0x05, 0x0001) +#define HCI_Reset_Failed_Contact_Counter HCI_CMD_OPCODE(0x05, 0x0002) +#define HCI_Read_Link_Quality HCI_CMD_OPCODE(0x05, 0x0003) +#define HCI_Read_Local_AMP_Info HCI_CMD_OPCODE(0x05, 0x0009) +#define HCI_Read_Local_AMP_ASSOC HCI_CMD_OPCODE(0x05, 0x000A) +#define HCI_Write_Remote_AMP_ASSOC HCI_CMD_OPCODE(0x05, 0x000B) +#define HCI_Create_Physical_Link HCI_CMD_OPCODE(0x01, 0x0035) +#define HCI_Accept_Physical_Link_Request HCI_CMD_OPCODE(0x01, 0x0036) +#define HCI_Disconnect_Physical_Link HCI_CMD_OPCODE(0x01, 0x0037) +#define HCI_Create_Logical_Link HCI_CMD_OPCODE(0x01, 0x0038) +#define HCI_Accept_Logical_Link HCI_CMD_OPCODE(0x01, 0x0039) +#define HCI_Disconnect_Logical_Link HCI_CMD_OPCODE(0x01, 0x003A) +#define HCI_Logical_Link_Cancel HCI_CMD_OPCODE(0x01, 0x003B) +#define HCI_Flow_Spec_Modify HCI_CMD_OPCODE(0x01, 0x003C) +#define HCI_Write_Flow_Control_Mode HCI_CMD_OPCODE(0x01, 0x0067) +#define HCI_Read_Best_Effort_Flush_Timeout HCI_CMD_OPCODE(0x01, 0x0069) +#define HCI_Write_Best_Effort_Flush_Timeout HCI_CMD_OPCODE(0x01, 0x006A) +#define HCI_Short_Range_Mode HCI_CMD_OPCODE(0x01, 0x006B) +#define HCI_Reset HCI_CMD_OPCODE(0x03, 0x0003) +#define HCI_Read_Connection_Accept_Timeout HCI_CMD_OPCODE(0x03, 0x0015) +#define HCI_Write_Connection_Accept_Timeout HCI_CMD_OPCODE(0x03, 0x0016) +#define HCI_Read_Link_Supervision_Timeout HCI_CMD_OPCODE(0x03, 0x0036) +#define HCI_Write_Link_Supervision_Timeout HCI_CMD_OPCODE(0x03, 0x0037) +#define HCI_Enhanced_Flush HCI_CMD_OPCODE(0x03, 0x005F) +#define HCI_Read_Logical_Link_Accept_Timeout HCI_CMD_OPCODE(0x03, 0x0061) +#define HCI_Write_Logical_Link_Accept_Timeout HCI_CMD_OPCODE(0x03, 0x0062) +#define HCI_Set_Event_Mask_Page_2 HCI_CMD_OPCODE(0x03, 0x0063) +#define HCI_Read_Location_Data_Command HCI_CMD_OPCODE(0x03, 0x0064) +#define HCI_Write_Location_Data_Command HCI_CMD_OPCODE(0x03, 0x0065) +#define HCI_Read_Local_Version_Info HCI_CMD_OPCODE(0x04, 0x0001) +#define HCI_Read_Local_Supported_Commands HCI_CMD_OPCODE(0x04, 0x0002) +#define HCI_Read_Buffer_Size HCI_CMD_OPCODE(0x04, 0x0005) +#define HCI_Read_Data_Block_Size HCI_CMD_OPCODE(0x04, 0x000A) + +/* AMP HCI command parameters */ +typedef BWL_PRE_PACKED_STRUCT struct read_local_cmd_parms { + uint8 plh; + uint8 offset[2]; /* length so far */ + uint8 max_remote[2]; +} BWL_POST_PACKED_STRUCT read_local_cmd_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct write_remote_cmd_parms { + uint8 plh; + uint8 offset[2]; + uint8 len[2]; + uint8 frag[1]; +} BWL_POST_PACKED_STRUCT write_remote_cmd_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct phy_link_cmd_parms { + uint8 plh; + uint8 key_length; + uint8 key_type; + uint8 key[1]; +} BWL_POST_PACKED_STRUCT phy_link_cmd_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct dis_phy_link_cmd_parms { + uint8 plh; + uint8 reason; +} BWL_POST_PACKED_STRUCT dis_phy_link_cmd_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct log_link_cmd_parms { + uint8 plh; + uint8 txflow[16]; + uint8 rxflow[16]; +} BWL_POST_PACKED_STRUCT log_link_cmd_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct ext_flow_spec { + uint8 id; + uint8 service_type; + uint8 max_sdu[2]; + uint8 sdu_ia_time[4]; + uint8 access_latency[4]; + uint8 flush_timeout[4]; +} BWL_POST_PACKED_STRUCT ext_flow_spec_t; + +typedef BWL_PRE_PACKED_STRUCT struct log_link_cancel_cmd_parms { + uint8 plh; + uint8 tx_fs_ID; +} BWL_POST_PACKED_STRUCT log_link_cancel_cmd_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct flow_spec_mod_cmd_parms { + uint8 llh[2]; + uint8 txflow[16]; + uint8 rxflow[16]; +} BWL_POST_PACKED_STRUCT flow_spec_mod_cmd_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct plh_pad { + uint8 plh; + uint8 pad; +} BWL_POST_PACKED_STRUCT plh_pad_t; + +typedef BWL_PRE_PACKED_STRUCT union hci_handle { + uint16 bredr; + plh_pad_t amp; +} BWL_POST_PACKED_STRUCT hci_handle_t; + +typedef BWL_PRE_PACKED_STRUCT struct ls_to_cmd_parms { + hci_handle_t handle; + uint8 timeout[2]; +} BWL_POST_PACKED_STRUCT ls_to_cmd_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct befto_cmd_parms { + uint8 llh[2]; + uint8 befto[4]; +} BWL_POST_PACKED_STRUCT befto_cmd_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct srm_cmd_parms { + uint8 plh; + uint8 srm; +} BWL_POST_PACKED_STRUCT srm_cmd_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct ld_cmd_parms { + uint8 ld_aware; + uint8 ld[2]; + uint8 ld_opts; + uint8 l_opts; +} BWL_POST_PACKED_STRUCT ld_cmd_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct eflush_cmd_parms { + uint8 llh[2]; + uint8 packet_type; +} BWL_POST_PACKED_STRUCT eflush_cmd_parms_t; + +/* Generic AMP extended flow spec service types */ +#define EFS_SVCTYPE_NO_TRAFFIC 0 +#define EFS_SVCTYPE_BEST_EFFORT 1 +#define EFS_SVCTYPE_GUARANTEED 2 + +/* AMP HCI event packet format */ +typedef BWL_PRE_PACKED_STRUCT struct amp_hci_event { + uint8 ecode; + uint8 plen; + uint8 parms[1]; +} BWL_POST_PACKED_STRUCT amp_hci_event_t; + +#define HCI_EVT_PREAMBLE_SIZE OFFSETOF(amp_hci_event_t, parms) + +/* AMP HCI event codes */ +#define HCI_Command_Complete 0x0E +#define HCI_Command_Status 0x0F +#define HCI_Flush_Occurred 0x11 +#define HCI_Enhanced_Flush_Complete 0x39 +#define HCI_Physical_Link_Complete 0x40 +#define HCI_Channel_Select 0x41 +#define HCI_Disconnect_Physical_Link_Complete 0x42 +#define HCI_Logical_Link_Complete 0x45 +#define HCI_Disconnect_Logical_Link_Complete 0x46 +#define HCI_Flow_Spec_Modify_Complete 0x47 +#define HCI_Number_of_Completed_Data_Blocks 0x48 +#define HCI_Short_Range_Mode_Change_Complete 0x4C +#define HCI_Status_Change_Event 0x4D +#define HCI_Vendor_Specific 0xFF + +/* AMP HCI event mask bit positions */ +#define HCI_Physical_Link_Complete_Event_Mask 0x0001 +#define HCI_Channel_Select_Event_Mask 0x0002 +#define HCI_Disconnect_Physical_Link_Complete_Event_Mask 0x0004 +#define HCI_Logical_Link_Complete_Event_Mask 0x0020 +#define HCI_Disconnect_Logical_Link_Complete_Event_Mask 0x0040 +#define HCI_Flow_Spec_Modify_Complete_Event_Mask 0x0080 +#define HCI_Number_of_Completed_Data_Blocks_Event_Mask 0x0100 +#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; + uint8 cmdpkts; + uint16 opcode; +} BWL_POST_PACKED_STRUCT cmd_status_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct cmd_complete_parms { + uint8 cmdpkts; + uint16 opcode; + uint8 parms[1]; +} BWL_POST_PACKED_STRUCT cmd_complete_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct flush_occurred_evt_parms { + uint16 handle; +} BWL_POST_PACKED_STRUCT flush_occurred_evt_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct write_remote_evt_parms { + uint8 status; + uint8 plh; +} BWL_POST_PACKED_STRUCT write_remote_evt_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct read_local_evt_parms { + uint8 status; + uint8 plh; + uint16 len; + uint8 frag[1]; +} BWL_POST_PACKED_STRUCT read_local_evt_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct read_local_info_evt_parms { + uint8 status; + uint8 AMP_status; + uint32 bandwidth; + uint32 gbandwidth; + uint32 latency; + uint32 PDU_size; + uint8 ctrl_type; + uint16 PAL_cap; + uint16 AMP_ASSOC_len; + uint32 max_flush_timeout; + uint32 be_flush_timeout; +} BWL_POST_PACKED_STRUCT read_local_info_evt_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct log_link_evt_parms { + uint8 status; + uint16 llh; + uint8 plh; + uint8 tx_fs_ID; +} BWL_POST_PACKED_STRUCT log_link_evt_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct disc_log_link_evt_parms { + uint8 status; + uint16 llh; + uint8 reason; +} BWL_POST_PACKED_STRUCT disc_log_link_evt_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct log_link_cancel_evt_parms { + uint8 status; + uint8 plh; + uint8 tx_fs_ID; +} BWL_POST_PACKED_STRUCT log_link_cancel_evt_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct flow_spec_mod_evt_parms { + uint8 status; + uint16 llh; +} BWL_POST_PACKED_STRUCT flow_spec_mod_evt_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct phy_link_evt_parms { + uint8 status; + uint8 plh; +} BWL_POST_PACKED_STRUCT phy_link_evt_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct dis_phy_link_evt_parms { + uint8 status; + uint8 plh; + uint8 reason; +} BWL_POST_PACKED_STRUCT dis_phy_link_evt_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct read_ls_to_evt_parms { + uint8 status; + hci_handle_t handle; + uint16 timeout; +} BWL_POST_PACKED_STRUCT read_ls_to_evt_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct read_lla_ca_to_evt_parms { + uint8 status; + uint16 timeout; +} BWL_POST_PACKED_STRUCT read_lla_ca_to_evt_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct read_data_block_size_evt_parms { + uint8 status; + uint16 ACL_pkt_len; + uint16 data_block_len; + uint16 data_block_num; +} BWL_POST_PACKED_STRUCT read_data_block_size_evt_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct data_blocks { + uint16 handle; + uint16 pkts; + uint16 blocks; +} BWL_POST_PACKED_STRUCT data_blocks_t; + +typedef BWL_PRE_PACKED_STRUCT struct num_completed_data_blocks_evt_parms { + uint16 num_blocks; + uint8 num_handles; + data_blocks_t completed[1]; +} BWL_POST_PACKED_STRUCT num_completed_data_blocks_evt_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct befto_evt_parms { + uint8 status; + uint32 befto; +} BWL_POST_PACKED_STRUCT befto_evt_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct srm_evt_parms { + uint8 status; + uint8 plh; + uint8 srm; +} BWL_POST_PACKED_STRUCT srm_evt_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct contact_counter_evt_parms { + uint8 status; + uint8 llh[2]; + uint16 counter; +} BWL_POST_PACKED_STRUCT contact_counter_evt_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct contact_counter_reset_evt_parms { + uint8 status; + uint8 llh[2]; +} BWL_POST_PACKED_STRUCT contact_counter_reset_evt_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct read_linkq_evt_parms { + uint8 status; + hci_handle_t handle; + uint8 link_quality; +} BWL_POST_PACKED_STRUCT read_linkq_evt_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct ld_evt_parms { + uint8 status; + uint8 ld_aware; + uint8 ld[2]; + uint8 ld_opts; + uint8 l_opts; +} BWL_POST_PACKED_STRUCT ld_evt_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct eflush_complete_evt_parms { + uint16 handle; +} BWL_POST_PACKED_STRUCT eflush_complete_evt_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct vendor_specific_evt_parms { + uint8 len; + uint8 parms[1]; +} BWL_POST_PACKED_STRUCT vendor_specific_evt_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct local_version_info_evt_parms { + uint8 status; + uint8 hci_version; + uint16 hci_revision; + uint8 pal_version; + uint16 mfg_name; + uint16 pal_subversion; +} BWL_POST_PACKED_STRUCT local_version_info_evt_parms_t; + +#define MAX_SUPPORTED_CMD_BYTE 64 +typedef BWL_PRE_PACKED_STRUCT struct local_supported_cmd_evt_parms { + uint8 status; + uint8 cmd[MAX_SUPPORTED_CMD_BYTE]; +} BWL_POST_PACKED_STRUCT local_supported_cmd_evt_parms_t; + +typedef BWL_PRE_PACKED_STRUCT struct status_change_evt_parms { + uint8 status; + uint8 amp_status; +} BWL_POST_PACKED_STRUCT status_change_evt_parms_t; + +/* AMP HCI error codes */ +#define HCI_SUCCESS 0x00 +#define HCI_ERR_ILLEGAL_COMMAND 0x01 +#define HCI_ERR_NO_CONNECTION 0x02 +#define HCI_ERR_MEMORY_FULL 0x07 +#define HCI_ERR_CONNECTION_TIMEOUT 0x08 +#define HCI_ERR_MAX_NUM_OF_CONNECTIONS 0x09 +#define HCI_ERR_CONNECTION_EXISTS 0x0B +#define HCI_ERR_CONNECTION_DISALLOWED 0x0C +#define HCI_ERR_CONNECTION_ACCEPT_TIMEOUT 0x10 +#define HCI_ERR_UNSUPPORTED_VALUE 0x11 +#define HCI_ERR_ILLEGAL_PARAMETER_FMT 0x12 +#define HCI_ERR_CONN_TERM_BY_LOCAL_HOST 0x16 +#define HCI_ERR_UNSPECIFIED 0x1F +#define HCI_ERR_UNIT_KEY_USED 0x26 +#define HCI_ERR_QOS_REJECTED 0x2D +#define HCI_ERR_PARAM_OUT_OF_RANGE 0x30 +#define HCI_ERR_NO_SUITABLE_CHANNEL 0x39 +#define HCI_ERR_CHANNEL_MOVE 0xFF + +/* AMP HCI ACL Data packet format */ +typedef BWL_PRE_PACKED_STRUCT struct amp_hci_ACL_data { + uint16 handle; /* 12-bit connection handle + 2-bit PB and 2-bit BC flags */ + uint16 dlen; /* data total length */ + uint8 data[1]; +} BWL_POST_PACKED_STRUCT amp_hci_ACL_data_t; + +#define HCI_ACL_DATA_PREAMBLE_SIZE OFFSETOF(amp_hci_ACL_data_t, data) + +#define HCI_ACL_DATA_BC_FLAGS (0x0 << 14) +#define HCI_ACL_DATA_PB_FLAGS (0x3 << 12) + +#define HCI_ACL_DATA_HANDLE(handle) ((handle) & 0x0fff) +#define HCI_ACL_DATA_FLAGS(handle) ((handle) >> 12) + +/* AMP Activity Report packet formats */ +typedef BWL_PRE_PACKED_STRUCT struct amp_hci_activity_report { + uint8 ScheduleKnown; + uint8 NumReports; + uint8 data[1]; +} BWL_POST_PACKED_STRUCT amp_hci_activity_report_t; + +typedef BWL_PRE_PACKED_STRUCT struct amp_hci_activity_report_triple { + uint32 StartTime; + uint32 Duration; + uint32 Periodicity; +} BWL_POST_PACKED_STRUCT amp_hci_activity_report_triple_t; + +#define HCI_AR_SCHEDULE_KNOWN 0x01 + + +/* This marks the end of a packed structure section. */ +#include + +#endif /* _bt_amp_hci_h_ */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/proto/eapol.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/proto/eapol.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/proto/eapol.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/proto/eapol.h 2014-02-15 00:43:44.793014092 +0100 @@ -0,0 +1,193 @@ +/* + * 802.1x EAPOL definitions + * + * See + * IEEE Std 802.1X-2001 + * IEEE 802.1X RADIUS Usage Guidelines + * + * Copyright (C) 2002 Broadcom Corporation + * + * $Id: eapol.h 241182 2011-02-17 21:50:03Z $ + */ + +#ifndef _eapol_h_ +#define _eapol_h_ + +#ifndef _TYPEDEFS_H_ +#include +#endif + +/* This marks the start of a packed structure section. */ +#include + +#include + +/* EAPOL for 802.3/Ethernet */ +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) */ +} 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 +#define LEAP_EAPOL_VERSION 1 +#define SES_EAPOL_VERSION 1 + +/* EAPOL types */ +#define EAP_PACKET 0 +#define EAPOL_START 1 +#define EAPOL_LOGOFF 2 +#define EAPOL_KEY 3 +#define EAPOL_ASF 4 + +/* EAPOL-Key types */ +#define EAPOL_RC4_KEY 1 +#define EAPOL_WPA2_KEY 2 /* 802.11i/WPA2 */ +#define EAPOL_WPA_KEY 254 /* WPA */ + +/* RC4 EAPOL-Key header field sizes */ +#define EAPOL_KEY_REPLAY_LEN 8 +#define EAPOL_KEY_IV_LEN 16 +#define EAPOL_KEY_SIG_LEN 16 + +/* RC4 EAPOL-Key */ +typedef BWL_PRE_PACKED_STRUCT struct { + unsigned char type; /* Key Descriptor Type */ + unsigned short length; /* Key Length (unaligned) */ + unsigned char replay[EAPOL_KEY_REPLAY_LEN]; /* Replay Counter */ + unsigned char iv[EAPOL_KEY_IV_LEN]; /* Key IV */ + unsigned char index; /* Key Flags & Index */ + unsigned char signature[EAPOL_KEY_SIG_LEN]; /* Key Signature */ + unsigned char key[1]; /* Key (optional) */ +} BWL_POST_PACKED_STRUCT eapol_key_header_t; + +#define EAPOL_KEY_HEADER_LEN 44 + +/* RC4 EAPOL-Key flags */ +#define EAPOL_KEY_FLAGS_MASK 0x80 +#define EAPOL_KEY_BROADCAST 0 +#define EAPOL_KEY_UNICAST 0x80 + +/* RC4 EAPOL-Key index */ +#define EAPOL_KEY_INDEX_MASK 0x7f + +/* WPA/802.11i/WPA2 EAPOL-Key header field sizes */ +#define EAPOL_WPA_KEY_REPLAY_LEN 8 +#define EAPOL_WPA_KEY_NONCE_LEN 32 +#define EAPOL_WPA_KEY_IV_LEN 16 +#define EAPOL_WPA_KEY_RSC_LEN 8 +#define EAPOL_WPA_KEY_ID_LEN 8 +#define EAPOL_WPA_KEY_MIC_LEN 16 +#define EAPOL_WPA_KEY_DATA_LEN (EAPOL_WPA_MAX_KEY_SIZE + AKW_BLOCK_LEN) +#define EAPOL_WPA_MAX_KEY_SIZE 32 + +/* WPA EAPOL-Key */ +typedef BWL_PRE_PACKED_STRUCT struct { + unsigned char type; /* Key Descriptor Type */ + unsigned short key_info; /* Key Information (unaligned) */ + unsigned short key_len; /* Key Length (unaligned) */ + unsigned char replay[EAPOL_WPA_KEY_REPLAY_LEN]; /* Replay Counter */ + unsigned char nonce[EAPOL_WPA_KEY_NONCE_LEN]; /* Nonce */ + unsigned char iv[EAPOL_WPA_KEY_IV_LEN]; /* Key IV */ + unsigned char rsc[EAPOL_WPA_KEY_RSC_LEN]; /* Key RSC */ + unsigned char id[EAPOL_WPA_KEY_ID_LEN]; /* WPA:Key ID, 802.11i/WPA2: Reserved */ + unsigned char mic[EAPOL_WPA_KEY_MIC_LEN]; /* Key MIC */ + unsigned short data_len; /* Key Data Length */ + unsigned char data[EAPOL_WPA_KEY_DATA_LEN]; /* Key data */ +} BWL_POST_PACKED_STRUCT eapol_wpa_key_header_t; + +#define EAPOL_WPA_KEY_LEN 95 + +/* WPA/802.11i/WPA2 KEY KEY_INFO bits */ +#define WPA_KEY_DESC_V1 0x01 +#define WPA_KEY_DESC_V2 0x02 +#define WPA_KEY_DESC_V3 0x03 +#define WPA_KEY_PAIRWISE 0x08 +#define WPA_KEY_INSTALL 0x40 +#define WPA_KEY_ACK 0x80 +#define WPA_KEY_MIC 0x100 +#define WPA_KEY_SECURE 0x200 +#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 +#define WPA_KEY_INDEX_2 0x20 +#define WPA_KEY_INDEX_3 0x30 +#define WPA_KEY_INDEX_MASK 0x30 +#define WPA_KEY_INDEX_SHIFT 0x04 + +/* 802.11i/WPA2-only KEY KEY_INFO bits */ +#define WPA_KEY_ENCRYPTED_DATA 0x1000 + +/* Key Data encapsulation */ +typedef BWL_PRE_PACKED_STRUCT struct { + uint8 type; + uint8 length; + uint8 oui[3]; + uint8 subtype; + uint8 data[1]; +} BWL_POST_PACKED_STRUCT eapol_wpa2_encap_data_t; + +#define EAPOL_WPA2_ENCAP_DATA_HDR_LEN 6 + +#define WPA2_KEY_DATA_SUBTYPE_GTK 1 +#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 { + uint8 flags; + uint8 reserved; + uint8 gtk[EAPOL_WPA_MAX_KEY_SIZE]; +} BWL_POST_PACKED_STRUCT eapol_wpa2_key_gtk_encap_t; + +#define EAPOL_WPA2_KEY_GTK_ENCAP_HDR_LEN 2 + +#define WPA2_GTK_INDEX_MASK 0x03 +#define WPA2_GTK_INDEX_SHIFT 0x00 + +#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]; + uint8 mac[ETHER_ADDR_LEN]; + uint8 stakey[EAPOL_WPA_MAX_KEY_SIZE]; +} BWL_POST_PACKED_STRUCT eapol_wpa2_key_stakey_encap_t; + +#define WPA2_KEY_DATA_PAD 0xdd + + +/* This marks the end of a packed structure section. */ +#include + +#endif /* _eapol_h_ */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/proto/ethernet.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/proto/ethernet.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/proto/ethernet.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/proto/ethernet.h 2014-02-15 00:43:44.793014092 +0100 @@ -0,0 +1,190 @@ +/* + * From FreeBSD 2.2.7: Fundamental constants relating to ethernet. + * + * 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: ethernet.h 309193 2012-01-19 00:03:57Z $ + */ + +#ifndef _NET_ETHERNET_H_ /* use native BSD ethernet.h when available */ +#define _NET_ETHERNET_H_ + +#ifndef _TYPEDEFS_H_ +#include "typedefs.h" +#endif + +/* This marks the start of a packed structure section. */ +#include + + +/* + * The number of bytes in an ethernet (MAC) address. + */ +#define ETHER_ADDR_LEN 6 + +/* + * The number of bytes in the type field. + */ +#define ETHER_TYPE_LEN 2 + +/* + * The number of bytes in the trailing CRC field. + */ +#define ETHER_CRC_LEN 4 + +/* + * The length of the combined header. + */ +#define ETHER_HDR_LEN (ETHER_ADDR_LEN * 2 + ETHER_TYPE_LEN) + +/* + * The minimum packet length. + */ +#define ETHER_MIN_LEN 64 + +/* + * The minimum packet user data length. + */ +#define ETHER_MIN_DATA 46 + +/* + * The maximum packet length. + */ +#define ETHER_MAX_LEN 1518 + +/* + * The maximum packet user data length. + */ +#define ETHER_MAX_DATA 1500 + +/* ether types */ +#define ETHER_TYPE_MIN 0x0600 /* Anything less than MIN is a length */ +#define ETHER_TYPE_IP 0x0800 /* IP */ +#define ETHER_TYPE_ARP 0x0806 /* ARP */ +#define ETHER_TYPE_8021Q 0x8100 /* 802.1Q */ +#define ETHER_TYPE_IPV6 0x86dd /* IPv6 */ +#define ETHER_TYPE_BRCM 0x886c /* Broadcom Corp. */ +#define ETHER_TYPE_802_1X 0x888e /* 802.1x */ +#define ETHER_TYPE_802_1X_PREAUTH 0x88c7 /* 802.1x preauthentication */ +#define ETHER_TYPE_WAI 0x88b4 /* WAI */ +#define ETHER_TYPE_89_0D 0x890d /* 89-0d frame for TDLS */ + +#define ETHER_TYPE_IPV6 0x86dd /* IPV6 */ + +/* Broadcom subtype follows ethertype; First 2 bytes are reserved; Next 2 are subtype; */ +#define ETHER_BRCM_SUBTYPE_LEN 4 /* Broadcom 4 byte subtype */ + +/* ether header */ +#define ETHER_DEST_OFFSET (0 * ETHER_ADDR_LEN) /* dest address offset */ +#define ETHER_SRC_OFFSET (1 * ETHER_ADDR_LEN) /* src address offset */ +#define ETHER_TYPE_OFFSET (2 * ETHER_ADDR_LEN) /* ether type offset */ + +/* + * A macro to validate a length with + */ +#define ETHER_IS_VALID_LEN(foo) \ + ((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN) + +#define ETHER_FILL_MCAST_ADDR_FROM_IP(ea, mgrp_ip) { \ + ((uint8 *)ea)[0] = 0x01; \ + ((uint8 *)ea)[1] = 0x00; \ + ((uint8 *)ea)[2] = 0x5e; \ + ((uint8 *)ea)[3] = ((mgrp_ip) >> 16) & 0x7f; \ + ((uint8 *)ea)[4] = ((mgrp_ip) >> 8) & 0xff; \ + ((uint8 *)ea)[5] = ((mgrp_ip) >> 0) & 0xff; \ +} + +#ifndef __INCif_etherh /* Quick and ugly hack for VxWorks */ +/* + * Structure of a 10Mb/s Ethernet header. + */ +BWL_PRE_PACKED_STRUCT struct ether_header { + uint8 ether_dhost[ETHER_ADDR_LEN]; + uint8 ether_shost[ETHER_ADDR_LEN]; + uint16 ether_type; +} BWL_POST_PACKED_STRUCT; + +/* + * Structure of a 48-bit Ethernet address. + */ +BWL_PRE_PACKED_STRUCT struct ether_addr { + uint8 octet[ETHER_ADDR_LEN]; +} BWL_POST_PACKED_STRUCT; +#endif /* !__INCif_etherh Quick and ugly hack for VxWorks */ + +/* + * Takes a pointer, set, test, clear, toggle locally admininistered + * address bit in the 48-bit Ethernet address. + */ +#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] & 0xfd)) +#define ETHER_TOGGLE_LOCALADDR(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] ^ 2)) + +/* Takes a pointer, marks unicast address bit in the MAC address */ +#define ETHER_SET_UNICAST(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] & ~1)) + +/* + * Takes a pointer, returns true if a 48-bit multicast address + * (including broadcast, since it is all ones) + */ +#define ETHER_ISMULTI(ea) (((const uint8 *)(ea))[0] & 1) + + +/* compare two ethernet addresses - assumes the pointers can be referenced as shorts */ +#define ether_cmp(a, b) (!(((short*)(a))[0] == ((short*)(b))[0]) | \ + !(((short*)(a))[1] == ((short*)(b))[1]) | \ + !(((short*)(a))[2] == ((short*)(b))[2])) + +/* copy an ethernet address - assumes the pointers can be referenced as shorts */ +#define ether_copy(s, d) { \ + ((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}}; +static const struct ether_addr ether_null = {{0, 0, 0, 0, 0, 0}}; + +#define ETHER_ISBCAST(ea) ((((uint8 *)(ea))[0] & \ + ((uint8 *)(ea))[1] & \ + ((uint8 *)(ea))[2] & \ + ((uint8 *)(ea))[3] & \ + ((uint8 *)(ea))[4] & \ + ((uint8 *)(ea))[5]) == 0xff) +#define ETHER_ISNULLADDR(ea) ((((uint8 *)(ea))[0] | \ + ((uint8 *)(ea))[1] | \ + ((uint8 *)(ea))[2] | \ + ((uint8 *)(ea))[3] | \ + ((uint8 *)(ea))[4] | \ + ((uint8 *)(ea))[5]) == 0) + +#define ETHER_MOVE_HDR(d, s) \ +do { \ + struct ether_header t; \ + t = *(struct ether_header *)(s); \ + *(struct ether_header *)(d) = t; \ +} while (0) + +/* This marks the end of a packed structure section. */ +#include + +#endif /* _NET_ETHERNET_H_ */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/proto/p2p.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/proto/p2p.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/proto/p2p.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/proto/p2p.h 2014-02-15 00:43:44.793014092 +0100 @@ -0,0 +1,579 @@ +/* + * 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 types and constants relating to WFA P2P (aka WiFi Direct) + * + * $Id: p2p.h 356417 2012-09-12 16:41:24Z $ + */ + +#ifndef _P2P_H_ +#define _P2P_H_ + +#ifndef _TYPEDEFS_H_ +#include +#endif +#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 */ + +/* 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 */ +} 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_ID_LEN 1 /* ID filed length */ +#define P2P_ATTR_LEN_LEN 2 /* length field length */ +#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_OP_CHANNEL 17 /* Operating Channel */ +#define P2P_SEID_INVITE_FLAGS 18 /* Invitation Flags */ +#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) */ +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 */ +} 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 */ +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) */ +} 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 */ +} BWL_POST_PACKED_STRUCT; +typedef struct wifi_p2p_cfg_tmo_se_s wifi_p2p_cfg_tmo_se_t; + +/* WiFi P2P IE subelement: Listen Channel */ +BWL_PRE_PACKED_STRUCT struct wifi_p2p_listen_channel_se_s { + uint8 eltId; /* SE ID: P2P_SEID_CHANNEL */ + uint8 len[2]; /* SE length not including eltId, len fields */ + uint8 country[3]; /* Country String */ + uint8 op_class; /* Operating Class */ + uint8 channel; /* Channel */ +} BWL_POST_PACKED_STRUCT; +typedef struct wifi_p2p_listen_channel_se_s wifi_p2p_listen_channel_se_t; + +/* WiFi P2P IE subelement: P2P Group BSSID */ +BWL_PRE_PACKED_STRUCT struct wifi_p2p_grp_bssid_se_s { + uint8 eltId; /* SE ID: P2P_SEID_GRP_BSSID */ + uint8 len[2]; /* SE length not including eltId, len fields */ + uint8 mac[6]; /* P2P group bssid */ +} BWL_POST_PACKED_STRUCT; +typedef struct wifi_p2p_grp_bssid_se_s wifi_p2p_grp_bssid_se_t; + +/* WiFi P2P IE subelement: P2P Group ID */ +BWL_PRE_PACKED_STRUCT struct wifi_p2p_grp_id_se_s { + uint8 eltId; /* SE ID: P2P_SEID_GROUP_ID */ + uint8 len[2]; /* SE length not including eltId, len fields */ + uint8 mac[6]; /* P2P device address */ + uint8 ssid[1]; /* ssid. device id. variable length */ +} BWL_POST_PACKED_STRUCT; +typedef struct wifi_p2p_grp_id_se_s wifi_p2p_grp_id_se_t; + +/* WiFi P2P IE subelement: P2P Interface */ +BWL_PRE_PACKED_STRUCT struct wifi_p2p_intf_se_s { + uint8 eltId; /* SE ID: P2P_SEID_P2P_IF */ + uint8 len[2]; /* SE length not including eltId, len fields */ + uint8 mac[6]; /* P2P device address */ + uint8 ifaddrs; /* P2P Interface Address count */ + uint8 ifaddr[1][6]; /* P2P Interface Address list */ +} BWL_POST_PACKED_STRUCT; +typedef struct wifi_p2p_intf_se_s wifi_p2p_intf_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_* */ +} 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 */ +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 */ +} BWL_POST_PACKED_STRUCT; +typedef struct wifi_p2p_ext_se_s wifi_p2p_ext_se_t; + +#define P2P_EXT_MIN 10 /* minimum 10ms */ + +/* 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 */ +} 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 */ +} 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 */ +} 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_CHAN_LIST */ + 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 */ +} BWL_POST_PACKED_STRUCT; +typedef struct wifi_p2p_chanlist_se_s wifi_p2p_chanlist_se_t; + +/* WiFi Primary Device Type structure */ +BWL_PRE_PACKED_STRUCT struct wifi_p2p_pri_devtype_s { + uint16 cat_id; /* Category ID */ + uint8 OUI[3]; /* WFA OUI: 0x0050F2 */ + uint8 oui_type; /* WPS_OUI_TYPE */ + uint16 sub_cat_id; /* Sub Category ID */ +} BWL_POST_PACKED_STRUCT; +typedef struct wifi_p2p_pri_devtype_s wifi_p2p_pri_devtype_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 */ +} BWL_POST_PACKED_STRUCT; +typedef struct wifi_p2p_devinfo_se_s wifi_p2p_devinfo_se_t; + +#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 */ +} 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 */ +} 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 */ +} 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 */ +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 */ +} BWL_POST_PACKED_STRUCT; +typedef struct wifi_p2p_grpinfo_se_s wifi_p2p_grpinfo_se_t; + +/* WiFi IE subelement: Operating Channel */ +BWL_PRE_PACKED_STRUCT struct wifi_p2p_op_channel_se_s { + uint8 eltId; /* SE ID: P2P_SEID_OP_CHANNEL */ + uint8 len[2]; /* SE length not including eltId, len fields */ + uint8 country[3]; /* Country String */ + uint8 op_class; /* Operating Class */ + uint8 channel; /* Channel */ +} BWL_POST_PACKED_STRUCT; +typedef struct wifi_p2p_op_channel_se_s wifi_p2p_op_channel_se_t; + +/* WiFi IE subelement: INVITATION FLAGS */ +BWL_PRE_PACKED_STRUCT struct wifi_p2p_invite_flags_se_s { + uint8 eltId; /* SE ID: P2P_SEID_INVITE_FLAGS */ + uint8 len[2]; /* SE length not including eltId, len fields */ + uint8 flags; /* Flags */ +} BWL_POST_PACKED_STRUCT; +typedef struct wifi_p2p_invite_flags_se_s wifi_p2p_invite_flags_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 + */ +} BWL_POST_PACKED_STRUCT; +typedef struct wifi_p2p_action_frame wifi_p2p_action_frame_t; +#define P2P_AF_CATEGORY 0x7f + +#define P2P_AF_FIXED_LEN 7 + +/* 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 + */ +} 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 Response */ +#define P2P_PAF_SUBTYPE_INVALID 255 /* Invalid Subtype */ + +/* 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 */ +BWL_PRE_PACKED_STRUCT struct wifi_p2p_noa_desc { + uint8 cnt_type; /* Count/Type */ + uint32 duration; /* Duration */ + uint32 interval; /* Interval */ + uint32 start; /* Start Time */ +} 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) */ +} BWL_POST_PACKED_STRUCT; +typedef struct wifi_p2p_noa_se wifi_p2p_noa_se_t; + +#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_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, + SVC_RPOTYPE_UPNP = 2, + SVC_RPOTYPE_WSD = 3, + 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, + P2PSD_RESP_STATUS_DATA_NA = 2, + 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 */ +} 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 + */ +} 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 + */ +} 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 */ +} 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 */ + +} 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 */ +} 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 */ +} 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 */ + +} 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 */ +} 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 */ +} 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 + */ +} 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_ */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/proto/sdspi.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/proto/sdspi.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/proto/sdspi.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/proto/sdspi.h 2014-02-15 00:43:44.793014092 +0100 @@ -0,0 +1,75 @@ +/* + * SD-SPI Protocol Standard + * + * 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: sdspi.h 241182 2011-02-17 21:50:03Z $ + */ +#ifndef _SD_SPI_H +#define _SD_SPI_H + +#define SPI_START_M BITFIELD_MASK(1) /* Bit [31] - Start Bit */ +#define SPI_START_S 31 +#define SPI_DIR_M BITFIELD_MASK(1) /* Bit [30] - Direction */ +#define SPI_DIR_S 30 +#define SPI_CMD_INDEX_M BITFIELD_MASK(6) /* Bits [29:24] - Command number */ +#define SPI_CMD_INDEX_S 24 +#define SPI_RW_M BITFIELD_MASK(1) /* Bit [23] - Read=0, Write=1 */ +#define SPI_RW_S 23 +#define SPI_FUNC_M BITFIELD_MASK(3) /* Bits [22:20] - Function Number */ +#define SPI_FUNC_S 20 +#define SPI_RAW_M BITFIELD_MASK(1) /* Bit [19] - Read After Wr */ +#define SPI_RAW_S 19 +#define SPI_STUFF_M BITFIELD_MASK(1) /* Bit [18] - Stuff bit */ +#define SPI_STUFF_S 18 +#define SPI_BLKMODE_M BITFIELD_MASK(1) /* Bit [19] - Blockmode 1=blk */ +#define SPI_BLKMODE_S 19 +#define SPI_OPCODE_M BITFIELD_MASK(1) /* Bit [18] - OP Code */ +#define SPI_OPCODE_S 18 +#define SPI_ADDR_M BITFIELD_MASK(17) /* Bits [17:1] - Address */ +#define SPI_ADDR_S 1 +#define SPI_STUFF0_M BITFIELD_MASK(1) /* Bit [0] - Stuff bit */ +#define SPI_STUFF0_S 0 + +#define SPI_RSP_START_M BITFIELD_MASK(1) /* Bit [7] - Start Bit (always 0) */ +#define SPI_RSP_START_S 7 +#define SPI_RSP_PARAM_ERR_M BITFIELD_MASK(1) /* Bit [6] - Parameter Error */ +#define SPI_RSP_PARAM_ERR_S 6 +#define SPI_RSP_RFU5_M BITFIELD_MASK(1) /* Bit [5] - RFU (Always 0) */ +#define SPI_RSP_RFU5_S 5 +#define SPI_RSP_FUNC_ERR_M BITFIELD_MASK(1) /* Bit [4] - Function number error */ +#define SPI_RSP_FUNC_ERR_S 4 +#define SPI_RSP_CRC_ERR_M BITFIELD_MASK(1) /* Bit [3] - COM CRC Error */ +#define SPI_RSP_CRC_ERR_S 3 +#define SPI_RSP_ILL_CMD_M BITFIELD_MASK(1) /* Bit [2] - Illegal Command error */ +#define SPI_RSP_ILL_CMD_S 2 +#define SPI_RSP_RFU1_M BITFIELD_MASK(1) /* Bit [1] - RFU (Always 0) */ +#define SPI_RSP_RFU1_S 1 +#define SPI_RSP_IDLE_M BITFIELD_MASK(1) /* Bit [0] - In idle state */ +#define SPI_RSP_IDLE_S 0 + +/* SD-SPI Protocol Definitions */ +#define SDSPI_COMMAND_LEN 6 /* Number of bytes in an SD command */ +#define SDSPI_START_BLOCK 0xFE /* SD Start Block Token */ +#define SDSPI_IDLE_PAD 0xFF /* SD-SPI idle value for MOSI */ +#define SDSPI_START_BIT_MASK 0x80 + +#endif /* _SD_SPI_H */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/proto/vlan.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/proto/vlan.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/proto/vlan.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/proto/vlan.h 2014-02-15 00:43:44.793014092 +0100 @@ -0,0 +1,69 @@ +/* + * 802.1Q VLAN protocol 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: vlan.h 241182 2011-02-17 21:50:03Z $ + */ + +#ifndef _vlan_h_ +#define _vlan_h_ + +#ifndef _TYPEDEFS_H_ +#include +#endif + +/* This marks the start of a packed structure section. */ +#include + +#define VLAN_VID_MASK 0xfff /* low 12 bits are vlan id */ +#define VLAN_CFI_SHIFT 12 /* canonical format indicator bit */ +#define VLAN_PRI_SHIFT 13 /* user priority */ + +#define VLAN_PRI_MASK 7 /* 3 bits of priority */ + +#define VLAN_TAG_LEN 4 +#define VLAN_TAG_OFFSET (2 * ETHER_ADDR_LEN) /* offset in Ethernet II packet only */ + +#define VLAN_TPID 0x8100 /* VLAN ethertype/Tag Protocol ID */ + +struct ethervlan_header { + uint8 ether_dhost[ETHER_ADDR_LEN]; + uint8 ether_shost[ETHER_ADDR_LEN]; + uint16 vlan_type; /* 0x8100 */ + uint16 vlan_tag; /* priority, cfi and vid */ + uint16 ether_type; +}; + +#define ETHERVLAN_HDR_LEN (ETHER_HDR_LEN + VLAN_TAG_LEN) + + +/* This marks the end of a packed structure section. */ +#include + +#define ETHERVLAN_MOVE_HDR(d, s) \ +do { \ + struct ethervlan_header t; \ + t = *(struct ethervlan_header *)(s); \ + *(struct ethervlan_header *)(d) = t; \ +} while (0) + +#endif /* _vlan_h_ */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/proto/wpa.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/proto/wpa.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/proto/wpa.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/proto/wpa.h 2014-02-15 00:43:44.793014092 +0100 @@ -0,0 +1,206 @@ +/* + * Fundamental types and constants relating to WPA + * + * 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: wpa.h 261155 2011-05-23 23:51:32Z $ + */ + +#ifndef _proto_wpa_h_ +#define _proto_wpa_h_ + +#include +#include + + +/* This marks the start of a packed structure section. */ +#include + +/* Reason Codes */ + +/* 13 through 23 taken from IEEE Std 802.11i-2004 */ +#define DOT11_RC_INVALID_WPA_IE 13 /* Invalid info. element */ +#define DOT11_RC_MIC_FAILURE 14 /* Michael failure */ +#define DOT11_RC_4WH_TIMEOUT 15 /* 4-way handshake timeout */ +#define DOT11_RC_GTK_UPDATE_TIMEOUT 16 /* Group key update timeout */ +#define DOT11_RC_WPA_IE_MISMATCH 17 /* WPA IE in 4-way handshake differs from + * (re-)assoc. request/probe response + */ +#define DOT11_RC_INVALID_MC_CIPHER 18 /* Invalid multicast cipher */ +#define DOT11_RC_INVALID_UC_CIPHER 19 /* Invalid unicast cipher */ +#define DOT11_RC_INVALID_AKMP 20 /* Invalid authenticated key management protocol */ +#define DOT11_RC_BAD_WPA_VERSION 21 /* Unsupported WPA version */ +#define DOT11_RC_INVALID_WPA_CAP 22 /* Invalid WPA IE capabilities */ +#define DOT11_RC_8021X_AUTH_FAIL 23 /* 802.1X authentication failure */ + +#define WPA2_PMKID_LEN 16 + +/* WPA IE fixed portion */ +typedef BWL_PRE_PACKED_STRUCT struct +{ + uint8 tag; /* TAG */ + uint8 length; /* TAG length */ + uint8 oui[3]; /* IE OUI */ + uint8 oui_type; /* OUI type */ + BWL_PRE_PACKED_STRUCT struct { + uint8 low; + uint8 high; + } BWL_POST_PACKED_STRUCT version; /* IE version */ +} BWL_POST_PACKED_STRUCT wpa_ie_fixed_t; +#define WPA_IE_OUITYPE_LEN 4 +#define WPA_IE_FIXED_LEN 8 +#define WPA_IE_TAG_FIXED_LEN 6 + +typedef BWL_PRE_PACKED_STRUCT struct { + uint8 tag; /* TAG */ + uint8 length; /* TAG length */ + BWL_PRE_PACKED_STRUCT struct { + uint8 low; + uint8 high; + } BWL_POST_PACKED_STRUCT version; /* IE version */ +} BWL_POST_PACKED_STRUCT wpa_rsn_ie_fixed_t; +#define WPA_RSN_IE_FIXED_LEN 4 +#define WPA_RSN_IE_TAG_FIXED_LEN 2 +typedef uint8 wpa_pmkid_t[WPA2_PMKID_LEN]; + +/* WPA suite/multicast suite */ +typedef BWL_PRE_PACKED_STRUCT struct +{ + uint8 oui[3]; + uint8 type; +} BWL_POST_PACKED_STRUCT wpa_suite_t, wpa_suite_mcast_t; +#define WPA_SUITE_LEN 4 + +/* WPA unicast suite list/key management suite list */ +typedef BWL_PRE_PACKED_STRUCT struct +{ + BWL_PRE_PACKED_STRUCT struct { + uint8 low; + uint8 high; + } BWL_POST_PACKED_STRUCT count; + wpa_suite_t list[1]; +} BWL_POST_PACKED_STRUCT wpa_suite_ucast_t, wpa_suite_auth_key_mgmt_t; +#define WPA_IE_SUITE_COUNT_LEN 2 +typedef BWL_PRE_PACKED_STRUCT struct +{ + BWL_PRE_PACKED_STRUCT struct { + uint8 low; + uint8 high; + } BWL_POST_PACKED_STRUCT count; + wpa_pmkid_t list[1]; +} BWL_POST_PACKED_STRUCT wpa_pmkid_list_t; + +/* WPA cipher suites */ +#define WPA_CIPHER_NONE 0 /* None */ +#define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */ +#define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */ +#define WPA_CIPHER_AES_OCB 3 /* AES (OCB) */ +#define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */ +#define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */ +#define WPA_CIPHER_BIP 6 /* WEP (104-bit) */ +#define WPA_CIPHER_TPK 7 /* Group addressed traffic not allowed */ +#ifdef BCMWAPI_WPI +#define WAPI_CIPHER_NONE WPA_CIPHER_NONE +#define WAPI_CIPHER_SMS4 11 + +#define WAPI_CSE_WPI_SMS4 1 +#endif /* BCMWAPI_WPI */ + + +#define IS_WPA_CIPHER(cipher) ((cipher) == WPA_CIPHER_NONE || \ + (cipher) == WPA_CIPHER_WEP_40 || \ + (cipher) == WPA_CIPHER_WEP_104 || \ + (cipher) == WPA_CIPHER_TKIP || \ + (cipher) == WPA_CIPHER_AES_OCB || \ + (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) + +/* convert WAPI_CSE_WPI_XXX to WAPI_CIPHER_XXX */ +#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 /* BCMWAPI_WAI */ + + +/* WPA TKIP countermeasures parameters */ +#define WPA_TKIP_CM_DETECT 60 /* multiple MIC failure window (seconds) */ +#define WPA_TKIP_CM_BLOCK 60 /* countermeasures active window (seconds) */ + +/* RSN IE defines */ +#define RSN_CAP_LEN 2 /* Length of RSN capabilities field (2 octets) */ + +/* RSN Capabilities defined in 802.11i */ +#define RSN_CAP_PREAUTH 0x0001 +#define RSN_CAP_NOPAIRWISE 0x0002 +#define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C +#define RSN_CAP_PTK_REPLAY_CNTR_SHIFT 2 +#define RSN_CAP_GTK_REPLAY_CNTR_MASK 0x0030 +#define RSN_CAP_GTK_REPLAY_CNTR_SHIFT 4 +#define RSN_CAP_1_REPLAY_CNTR 0 +#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 + +/* WPA capabilities defined in 802.11i */ +#define WPA_CAP_4_REPLAY_CNTRS RSN_CAP_4_REPLAY_CNTRS +#define WPA_CAP_16_REPLAY_CNTRS RSN_CAP_16_REPLAY_CNTRS +#define WPA_CAP_REPLAY_CNTR_SHIFT RSN_CAP_PTK_REPLAY_CNTR_SHIFT +#define WPA_CAP_REPLAY_CNTR_MASK RSN_CAP_PTK_REPLAY_CNTR_MASK + +/* WPA capabilities defined in 802.11zD9.0 */ +#define WPA_CAP_PEER_KEY_ENABLE (0x1 << 1) /* bit 9 */ + +/* WPA Specific defines */ +#define WPA_CAP_LEN RSN_CAP_LEN /* Length of RSN capabilities in RSN IE (2 octets) */ +#define WPA_PMKID_CNT_LEN 2 /* Length of RSN PMKID count (2 octests) */ + +#define WPA_CAP_WPA2_PREAUTH RSN_CAP_PREAUTH + +#ifdef BCMWAPI_WAI +#define WAPI_CAP_PREAUTH RSN_CAP_PREAUTH + +/* Other WAI definition */ +#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 /* 0xA00000 */ +#define WAPI_MSK_REKEY_COUNT 0x4000000 /* 0xA00000 */ +#endif /* BCMWAPI_WAI */ +#define WPA2_PMKID_COUNT_LEN 2 + + +/* This marks the end of a packed structure section. */ +#include + +#endif /* _proto_wpa_h_ */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/sbchipc.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/sbchipc.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/sbchipc.h 2014-01-27 01:30:30.101433269 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/sbchipc.h 2014-02-15 00:43:44.793014092 +0100 @@ -5,9 +5,9 @@ * 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 385540 2013-02-15 23:14:50Z $ + * $Id: sbchipc.h 347614 2012-07-27 10:24:51Z $ * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -291,10 +291,10 @@ typedef volatile struct { uint32 pllcontrol_data; uint32 pmustrapopt; /* 0x668, corerev >= 28 */ uint32 pmu_xtalfreq; /* 0x66C, pmurev >= 10 */ - uint32 retention_ctl; /* 0x670 */ + uint32 retention_ctl; /* 0x670 */ uint32 PAD[3]; - uint32 retention_grpidx; /* 0x680 */ - uint32 retention_grpctl; /* 0x684 */ + uint32 retention_grpidx; /* 0x680 */ + uint32 retention_grpctl; /* 0x684 */ uint32 PAD[94]; uint16 sromotp[512]; /* 0x800 */ #ifdef NFLASH_SUPPORT @@ -362,56 +362,14 @@ typedef volatile struct { uint32 nand_ctrl_status; #endif /* NFLASH_SUPPORT */ uint32 gci_corecaps0; /* GCI starting at 0xC00 */ - uint32 gci_corecaps1; - uint32 gci_corecaps2; - uint32 gci_corectrl; - uint32 gci_corestat; /* 0xC10 */ - uint32 gci_intstat; /* 0xC14 */ - uint32 gci_intmask; /* 0xC18 */ - uint32 gci_wakemask; /* 0xC1C */ - uint32 gci_levelintstat; /* 0xC20 */ - uint32 gci_eventintstat; /* 0xC24 */ - uint32 PAD[6]; - uint32 gci_indirect_addr; /* 0xC40 */ - uint32 gci_gpioctl; /* 0xC44 */ - uint32 PAD; - uint32 gci_gpiomask; /* 0xC4C */ - uint32 PAD; - uint32 gci_miscctl; /* 0xC54 */ - uint32 PAD[2]; - uint32 gci_input[32]; /* C60 */ - uint32 gci_event[32]; /* CE0 */ - uint32 gci_output[4]; /* D60 */ - uint32 gci_control_0; /* 0xD70 */ - uint32 gci_control_1; /* 0xD74 */ - uint32 gci_level_polreg; /* 0xD78 */ - uint32 gci_levelintmask; /* 0xD7C */ - uint32 gci_eventintmask; /* 0xD80 */ - uint32 PAD[3]; - uint32 gci_inbandlevelintmask; /* 0xD90 */ - uint32 gci_inbandeventintmask; /* 0xD94 */ - uint32 PAD[2]; - uint32 gci_seciauxtx; /* 0xDA0 */ - uint32 gci_seciauxrx; /* 0xDA4 */ - uint32 gci_secitx_datatag; /* 0xDA8 */ - uint32 gci_secirx_datatag; /* 0xDAC */ - uint32 gci_secitx_datamask; /* 0xDB0 */ - uint32 gci_seciusef0tx_reg; /* 0xDB4 */ - uint32 gci_secif0tx_offset; /* 0xDB8 */ - uint32 gci_secif0rx_offset; /* 0xDBC */ - uint32 gci_secif1tx_offset; /* 0xDC0 */ - uint32 PAD[3]; - uint32 gci_uartescval; /* DD0 */ - uint32 PAD[3]; - uint32 gci_secibauddiv; /* DE0 */ - uint32 gci_secifcr; /* DE4 */ - uint32 gci_secilcr; /* DE8 */ - uint32 gci_secimcr; /* DEC */ - uint32 PAD[2]; - uint32 gci_baudadj; /* DF8 */ - uint32 PAD; - uint32 gci_chipctrl; /* 0xE00 */ - uint32 gci_chipsts; /* 0xE04 */ + uint32 gci_corecaps1; + uint32 gci_corecaps2; + uint32 gci_corectrl; + uint32 gci_corestat; /* 0xC10 */ + uint32 PAD[11]; + uint32 gci_indirect_addr; /* 0xC40 */ + uint32 PAD[111]; + uint32 gci_chipctrl; /* 0xE00 */ } chipcregs_t; #endif /* _LANGUAGE_ASSEMBLY */ @@ -517,11 +475,8 @@ typedef volatile struct { #define CC_CAP2_GSIO 0x00000002 /* GSIO (spi/i2c) present, rev >= 37 */ /* capabilities extension */ -#define CC_CAP_EXT_SECI_PRESENT 0x00000001 /* SECI present */ -#define CC_CAP_EXT_GCI_PRESENT 0x00000004 /* GCI present */ +#define CC_CAP_EXT_SECI_PRESENT 0x00000001 /* SECI present */ -/* WL Channel Info to BT via GCI - bits 40 - 47 */ -#define GCI_WL_CHN_INFO_MASK (0xFF00) /* PLL type */ #define PLL_NONE 0x00000000 #define PLL_TYPE1 0x00010000 /* 48MHz base, 3 dividers */ @@ -538,28 +493,6 @@ typedef volatile struct { /* ALP clock on pre-PMU chips */ #define ALP_CLOCK 20000000 -#ifdef CFG_SIM -#define NS_ALP_CLOCK 84922 -#define NS_SLOW_ALP_CLOCK 84922 -#define NS_CPU_CLOCK 534500 -#define NS_SLOW_CPU_CLOCK 534500 -#define NS_SI_CLOCK 271750 -#define NS_SLOW_SI_CLOCK 271750 -#define NS_FAST_MEM_CLOCK 271750 -#define NS_MEM_CLOCK 271750 -#define NS_SLOW_MEM_CLOCK 271750 -#else -#define NS_ALP_CLOCK 125000000 -#define NS_SLOW_ALP_CLOCK 100000000 -#define NS_CPU_CLOCK 1000000000 -#define NS_SLOW_CPU_CLOCK 800000000 -#define NS_SI_CLOCK 250000000 -#define NS_SLOW_SI_CLOCK 200000000 -#define NS_FAST_MEM_CLOCK 800000000 -#define NS_MEM_CLOCK 533000000 -#define NS_SLOW_MEM_CLOCK 400000000 -#endif /* CFG_SIM */ - /* HT clock */ #define HT_CLOCK 80000000 @@ -884,33 +817,6 @@ typedef volatile struct { #define PCTL_ILP_DIV_EN 0x00000002 #define PCTL_LPO_SEL 0x00000001 -/* Retention Control */ -#define PMU_RCTL_CLK_DIV_SHIFT 0 -#define PMU_RCTL_CHAIN_LEN_SHIFT 12 -#define PMU_RCTL_MACPHY_DISABLE_SHIFT 26 -#define PMU_RCTL_MACPHY_DISABLE_MASK (1 << 26) -#define PMU_RCTL_LOGIC_DISABLE_SHIFT 27 -#define PMU_RCTL_LOGIC_DISABLE_MASK (1 << 27) -#define PMU_RCTL_MEMSLP_LOG_SHIFT 28 -#define PMU_RCTL_MEMSLP_LOG_MASK (1 << 28) -#define PMU_RCTL_MEMRETSLP_LOG_SHIFT 29 -#define PMU_RCTL_MEMRETSLP_LOG_MASK (1 << 29) - -/* Retention Group Control */ -#define PMU_RCTLGRP_CHAIN_LEN_SHIFT 0 -#define PMU_RCTLGRP_RMODE_ENABLE_SHIFT 14 -#define PMU_RCTLGRP_RMODE_ENABLE_MASK (1 << 14) -#define PMU_RCTLGRP_DFT_ENABLE_SHIFT 15 -#define PMU_RCTLGRP_DFT_ENABLE_MASK (1 << 15) -#define PMU_RCTLGRP_NSRST_DISABLE_SHIFT 16 -#define PMU_RCTLGRP_NSRST_DISABLE_MASK (1 << 16) -/* Retention Group Control special for 4334 */ -#define PMU4334_RCTLGRP_CHAIN_LEN_GRP0 338 -#define PMU4334_RCTLGRP_CHAIN_LEN_GRP1 315 -/* Retention Group Control special for 43341 */ -#define PMU43341_RCTLGRP_CHAIN_LEN_GRP0 366 -#define PMU43341_RCTLGRP_CHAIN_LEN_GRP1 330 - /* Fields in clkstretch */ #define CSTRETCH_HT 0xffff0000 #define CSTRETCH_ALP 0x0000ffff @@ -978,8 +884,6 @@ typedef volatile struct { #define SFLASH_AT 0x200 /* Atmel serial flash */ #define NFLASH 0x300 #define PFLASH 0x700 /* Parallel flash */ -#define QSPIFLASH_ST 0x800 -#define QSPIFLASH_AT 0x900 /* Bits in the ExtBus config registers */ #define CC_CFG_EN 0x0001 /* Enable */ @@ -1175,7 +1079,6 @@ typedef volatile struct { /* PMU chip control0 register */ #define PMU_CHIPCTL0 0 -#define PMU43143_CC0_SDIO_DRSTR_OVR (1 << 31) /* sdio drive strength override enable */ /* clock req types */ #define PMU_CC1_CLKREQ_TYPE_SHIFT 19 @@ -1209,9 +1112,6 @@ typedef volatile struct { #define PMU_CC3_ENABLE_RF_SHIFT 22 #define PMU_CC3_RF_DISABLE_IVALUE_SHIFT 23 -/* PMU chip control5 register */ -#define PMU_CHIPCTL5 5 - /* PMU corerev and chip specific PLL controls. * PMU_PLL_XX where is PMU corerev and is an arbitrary number @@ -1600,10 +1500,6 @@ typedef volatile struct { #define CCTRL43217_EXTPA_C0 (1<<13) /* core0 extPA in ChipControl 1, bit 13 */ #define CCTRL43217_EXTPA_C1 (1<<8) /* core1 extPA in ChipControl 1, bit 8 */ -/* 43228 Chip specific ChipControl register bits */ -#define CCTRL43228_EXTPA_C0 (1<<14) /* core1 extPA in ChipControl 1, bit 14 */ -#define CCTRL43228_EXTPA_C1 (1<<9) /* core0 extPA in ChipControl 1, bit 1 */ - /* 4328 resources */ #define RES4328_EXT_SWITCHER_PWM 0 /* 0x00001 */ #define RES4328_BB_SWITCHER_PWM 1 /* 0x00002 */ @@ -1847,36 +1743,9 @@ typedef volatile struct { #define CST43239_CHIPMODE_GSPI(cs) (((cs) & (1 << 0)) == (1 << 0)) /* gSPI */ /* 4324 resources */ -/* 43242 use same PMU as 4324 */ -#define RES4324_LPLDO_PU 0 -#define RES4324_RESET_PULLDN_DIS 1 -#define RES4324_PMU_BG_PU 2 -#define RES4324_HSIC_LDO_PU 3 -#define RES4324_CBUCK_LPOM_PU 4 -#define RES4324_CBUCK_PFM_PU 5 -#define RES4324_CLDO_PU 6 -#define RES4324_LPLDO2_LVM 7 -#define RES4324_LNLDO1_PU 8 -#define RES4324_LNLDO2_PU 9 -#define RES4324_LDO3P3_PU 10 -#define RES4324_OTP_PU 11 -#define RES4324_XTAL_PU 12 -#define RES4324_BBPLL_PU 13 -#define RES4324_LQ_AVAIL 14 -#define RES4324_WL_CORE_READY 17 -#define RES4324_ILP_REQ 18 -#define RES4324_ALP_AVAIL 19 -#define RES4324_PALDO_PU 20 -#define RES4324_RADIO_PU 21 -#define RES4324_SR_CLK_STABLE 22 -#define RES4324_SR_SAVE_RESTORE 23 -#define RES4324_SR_PHY_PWRSW 24 -#define RES4324_SR_PHY_PIC 25 -#define RES4324_SR_SUBCORE_PWRSW 26 -#define RES4324_SR_SUBCORE_PIC 27 -#define RES4324_SR_MEM_PM0 28 +#define RES4324_OTP_PU 10 #define RES4324_HT_AVAIL 29 -#define RES4324_MACPHY_CLKAVAIL 30 +#define RES4324_MACPHY_CLKAVAIL 30 /* 4324 Chip specific ChipStatus register bits */ #define CST4324_SPROM_MASK 0x00000080 @@ -1887,9 +1756,6 @@ typedef volatile struct { #define CST4324_CHIPMODE_SDIOD(cs) ((~(cs)) & (1 << 2)) /* SDIO || gSPI */ #define CST4324_CHIPMODE_USB20D(cs) (((cs) & CST4324_CHIPMODE_MASK) == 0x6) /* USB || USBDA */ -/* 43242 Chip specific ChipStatus register bits */ -#define CST43242_SFLASH_MASK 0x00000008 - /* 4331 resources */ #define RES4331_REGULATOR 0 #define RES4331_ILP_REQUEST 1 @@ -2125,42 +1991,6 @@ typedef volatile struct { #define PMU_VREG0_DISABLE_PULLD_BT_SHIFT 2 #define PMU_VREG0_DISABLE_PULLD_WL_SHIFT 3 -#define PMU_VREG4_ADDR 4 - -#define PMU_VREG4_CLDO_PWM_SHIFT 4 -#define PMU_VREG4_CLDO_PWM_MASK 0x7 - -#define PMU_VREG4_LPLDO1_SHIFT 15 -#define PMU_VREG4_LPLDO1_MASK 0x7 -#define PMU_VREG4_LPLDO1_1p20V 0 -#define PMU_VREG4_LPLDO1_1p15V 1 -#define PMU_VREG4_LPLDO1_1p10V 2 -#define PMU_VREG4_LPLDO1_1p25V 3 -#define PMU_VREG4_LPLDO1_1p05V 4 -#define PMU_VREG4_LPLDO1_1p00V 5 -#define PMU_VREG4_LPLDO1_0p95V 6 -#define PMU_VREG4_LPLDO1_0p90V 7 - -#define PMU_VREG4_LPLDO2_LVM_SHIFT 18 -#define PMU_VREG4_LPLDO2_LVM_MASK 0x7 -#define PMU_VREG4_LPLDO2_HVM_SHIFT 21 -#define PMU_VREG4_LPLDO2_HVM_MASK 0x7 -#define PMU_VREG4_LPLDO2_LVM_HVM_MASK 0x3f -#define PMU_VREG4_LPLDO2_1p00V 0 -#define PMU_VREG4_LPLDO2_1p15V 1 -#define PMU_VREG4_LPLDO2_1p20V 2 -#define PMU_VREG4_LPLDO2_1p10V 3 -#define PMU_VREG4_LPLDO2_0p90V 4 /* 4 - 7 is 0.90V */ - -#define PMU_VREG4_HSICLDO_BYPASS_SHIFT 27 -#define PMU_VREG4_HSICLDO_BYPASS_MASK 0x1 - -#define PMU_VREG5_ADDR 5 -#define PMU_VREG5_HSICAVDD_PD_SHIFT 6 -#define PMU_VREG5_HSICAVDD_PD_MASK 0x1 -#define PMU_VREG5_HSICDVDD_PD_SHIFT 11 -#define PMU_VREG5_HSICDVDD_PD_MASK 0x1 - /* 4334 resources */ #define RES4334_LPLDO_PU 0 #define RES4334_RESET_PULLDN_DIS 1 @@ -2216,78 +2046,12 @@ typedef volatile struct { #define PCTL_4334_GPIO3_ENAB (1 << 3) /* 4334 Chip control */ -#define CCTRL4334_PMU_WAKEUP_GPIO1 (1 << 0) -#define CCTRL4334_PMU_WAKEUP_HSIC (1 << 1) -#define CCTRL4334_PMU_WAKEUP_AOS (1 << 2) -#define CCTRL4334_HSIC_WAKE_MODE (1 << 3) -#define CCTRL4334_HSIC_INBAND_GPIO1 (1 << 4) #define CCTRL4334_HSIC_LDO_PU (1 << 23) -/* 4334 Chip control 3 */ -#define CCTRL4334_BLOCK_EXTRNL_WAKE (1 << 4) -#define CCTRL4334_SAVERESTORE_FIX (1 << 5) - -/* 43341 Chip control 3 */ -#define CCTRL43341_BLOCK_EXTRNL_WAKE (1 << 13) -#define CCTRL43341_SAVERESTORE_FIX (1 << 14) -#define CCTRL43341_BT_ISO_SEL (1 << 16) - -/* 4334 Chip specific ChipControl1 register bits */ -#define CCTRL1_4334_GPIO_SEL (1 << 0) /* 1=select GPIOs to be muxed out */ -#define CCTRL1_4334_ERCX_SEL (1 << 1) /* 1=select ERCX BT coex to be muxed out */ -#define CCTRL1_4334_SDIO_HOST_WAKE (1 << 2) /* SDIO: 1=configure GPIO0 for host wake */ -#define CCTRL1_4334_JTAG_DISABLE (1 << 3) /* 1=disable JTAG interface on mux'd pins */ -#define CCTRL1_4334_UART_ON_4_5 (1 << 28) /* 1=UART_TX/UART_RX muxed on GPIO_4/5 (4334B0/1) */ - /* 4324 Chip specific ChipControl1 register bits */ #define CCTRL1_4324_GPIO_SEL (1 << 0) /* 1=select GPIOs to be muxed out */ #define CCTRL1_4324_SDIO_HOST_WAKE (1 << 2) /* SDIO: 1=configure GPIO0 for host wake */ -/* 43143 chip-specific ChipStatus register bits based on Confluence documentation */ -/* register contains strap values sampled during POR */ -#define CST43143_REMAP_TO_ROM (3 << 0) /* 00=Boot SRAM, 01=Boot ROM, 10=Boot SFLASH */ -#define CST43143_SDIO_EN (1 << 2) /* 0 = USB Enab, SDIO pins are GPIO or I2S */ -#define CST43143_SDIO_ISO (1 << 3) /* 1 = SDIO isolated */ -#define CST43143_USB_CPU_LESS (1 << 4) /* 1 = CPULess mode Enabled */ -#define CST43143_CBUCK_MODE (3 << 6) /* Indicates what controller mode CBUCK is in */ -#define CST43143_POK_CBUCK (1 << 8) /* 1 = 1.2V CBUCK voltage ready */ -#define CST43143_PMU_OVRSPIKE (1 << 9) -#define CST43143_PMU_OVRTEMP (0xF << 10) -#define CST43143_SR_FLL_CAL_DONE (1 << 14) -#define CST43143_USB_PLL_LOCKDET (1 << 15) -#define CST43143_PMU_PLL_LOCKDET (1 << 16) -#define CST43143_CHIPMODE_SDIOD(cs) (((cs) & CST43143_SDIO_EN) != 0) /* SDIO */ - -/* 43143 Chip specific ChipControl register bits */ -/* 00: SECI is disabled (JATG functional), 01: 2 wire, 10: 4 wire */ -#define CCTRL_43143_SECI (1<<0) -#define CCTRL_43143_BT_LEGACY (1<<1) -#define CCTRL_43143_I2S_MODE (1<<2) /* 0: SDIO enabled */ -#define CCTRL_43143_I2S_MASTER (1<<3) /* 0: I2S MCLK input disabled */ -#define CCTRL_43143_I2S_FULL (1<<4) /* 0: I2S SDIN and SPDIF_TX inputs disabled */ -#define CCTRL_43143_GSIO (1<<5) /* 0: sFlash enabled */ -#define CCTRL_43143_RF_SWCTRL_MASK (7<<6) /* 0: disabled */ -#define CCTRL_43143_RF_SWCTRL_0 (1<<6) -#define CCTRL_43143_RF_SWCTRL_1 (2<<6) -#define CCTRL_43143_RF_SWCTRL_2 (4<<6) -#define CCTRL_43143_RF_XSWCTRL (1<<9) /* 0: UART enabled */ -#define CCTRL_43143_HOST_WAKE0 (1<<11) /* 1: SDIO separate interrupt output from GPIO4 */ -#define CCTRL_43143_HOST_WAKE1 (1<<12) /* 1: SDIO separate interrupt output from GPIO16 */ - -/* 43143 resources, based on pmu_params.xls V1.19 */ -#define RES43143_EXT_SWITCHER_PWM 0 /* 0x00001 */ -#define RES43143_XTAL_PU 1 /* 0x00002 */ -#define RES43143_ILP_REQUEST 2 /* 0x00004 */ -#define RES43143_ALP_AVAIL 3 /* 0x00008 */ -#define RES43143_WL_CORE_READY 4 /* 0x00010 */ -#define RES43143_BBPLL_PWRSW_PU 5 /* 0x00020 */ -#define RES43143_HT_AVAIL 6 /* 0x00040 */ -#define RES43143_RADIO_PU 7 /* 0x00080 */ -#define RES43143_MACPHY_CLK_AVAIL 8 /* 0x00100 */ -#define RES43143_OTP_PU 9 /* 0x00200 */ -#define RES43143_LQ_AVAIL 10 /* 0x00400 */ - -#define PMU43143_XTAL_CORE_SIZE_MASK 0x3F /* 4313 resources */ #define RES4313_BB_PU_RSRC 0 @@ -2390,19 +2154,11 @@ typedef volatile struct { #define FLSTRCF4706_1ST_MADDR_SEG_256MB 0x00000070 /* 256MB */ /* 4360 Chip specific ChipControl register bits */ -#define CCTRL4360_I2C_MODE (1 << 0) -#define CCTRL4360_UART_MODE (1 << 1) #define CCTRL4360_SECI_MODE (1 << 2) #define CCTRL4360_BTSWCTRL_MODE (1 << 3) -#define CCTRL4360_DISCRETE_FEMCTRL_MODE (1 << 4) -#define CCTRL4360_DIGITAL_PACTRL_MODE (1 << 5) -#define CCTRL4360_BTSWCTRL_AND_DIGPA_PRESENT (1 << 6) -#define CCTRL4360_EXTRA_GPIO_MODE (1 << 7) #define CCTRL4360_EXTRA_FEMCTRL_MODE (1 << 8) #define CCTRL4360_BT_LGCY_MODE (1 << 9) #define CCTRL4360_CORE2FEMCTRL4_ON (1 << 21) -#define CCTRL4360_SECI_ON_GPIO01 (1 << 24) - /* 4360 PMU resources and chip status bits */ #define RES4360_REGULATOR 0 @@ -2433,13 +2189,6 @@ typedef volatile struct { #define CCTRL_4360_UART_SEL 0x2 -/* defines to detect active host interface in use */ -#define CHIP_HOSTIF_PCIEMODE 0x1 -#define CHIP_HOSTIF_USBMODE 0x2 -#define CHIP_HOSTIF_SDIOMODE 0x4 -#define CHIP_HOSTIF_PCIE(sih) (si_chip_hostif(sih) == CHIP_HOSTIF_PCIEMODE) -#define CHIP_HOSTIF_SDIO(sih) (si_chip_hostif(sih) == CHIP_HOSTIF_SDIOMODE) - /* 4335 resources */ #define RES4335_LPLDO_PO 0 #define RES4335_PMU_BG_PU 1 @@ -2488,226 +2237,10 @@ typedef volatile struct { #define CCTRL1_4335_GPIO_SEL (1 << 0) /* 1=select GPIOs to be muxed out */ #define CCTRL1_4335_SDIO_HOST_WAKE (1 << 2) /* SDIO: 1=configure GPIO0 for host wake */ -#define CR4_4335_RAM_BASE (0x180000) -#define PATCHTBL_SIZE (0x800) -#define CR4_4350_RAM_BASE (0x180000) -#define CR4_4360_RAM_BASE (0x0) - - -/* 4335 chip OTP present & OTP select bits. */ -#define SPROM4335_OTP_SELECT 0x00000010 -#define SPROM4335_OTP_PRESENT 0x00000020 - -/* 4335 GCI specific bits. */ -#define CC4335_GCI_STRAP_OVERRIDE_SFLASH_PRESENT (1 << 24) -#define CC4335_GCI_STRAP_OVERRIDE_SFLASH_TYPE 25 -#define CC4335_GCI_FUNC_SEL_PAD_SDIO 0x00707770 - -/* SFLASH clkdev specific bits. */ -#define CC4335_SFLASH_CLKDIV_MASK 0x1F000000 -#define CC4335_SFLASH_CLKDIV_SHIFT 25 - -/* 4335 OTP bits for SFLASH. */ -#define CC4335_SROM_OTP_SFLASH 40 -#define CC4335_SROM_OTP_SFLASH_PRESENT 0x1 -#define CC4335_SROM_OTP_SFLASH_TYPE 0x2 -#define CC4335_SROM_OTP_SFLASH_CLKDIV_MASK 0x003C -#define CC4335_SROM_OTP_SFLASH_CLKDIV_SHIFT 2 - -/* 4335 resources--END */ +#define CR4_RAM_BASE (0x180000) -/* 4350 Chipcommon ChipStatus bits */ -#define CST4350_SDIO_MODE 0x00000001 -#define CST4350_HSIC20D_MODE 0x00000002 -#define CST4350_BP_ON_HSIC_CLK 0x00000004 -#define CST4350_PCIE_MODE 0x00000008 -#define CST4350_USB20D_MODE 0x00000010 -#define CST4350_USB30D_MODE 0x00000020 -#define CST4350_SPROM_PRESENT 0x00000040 -#define CST4350_RSRC_INIT_MODE_0 0x00000080 -#define CST4350_RSRC_INIT_MODE_1 0x00000100 -#define CST4350_SEL0_SDIO 0x00000200 -#define CST4350_SEL1_SDIO 0x00000400 -#define CST4350_SDIO_PAD_MODE 0x00000800 -#define CST4350_BBPLL_LOCKED 0x00001000 -#define CST4350_USBPLL_LOCKED 0x00002000 -#define CST4350_LINE_STATE 0x0000C000 -#define CST4350_SERDES_PIPE_PLLLOCK 0x00010000 -#define CST4350_BT_READY 0x00020000 -#define CST4350_SFLASH_PRESENT 0x00040000 -#define CST4350_CPULESS_ENABLE 0x00080000 -#define CST4350_STRAP_HOST_IFC_1 0x00100000 -#define CST4350_STRAP_HOST_IFC_2 0x00200000 -#define CST4350_STRAP_HOST_IFC_3 0x00400000 -#define CST4350_RAW_SPROM_PRESENT 0x00800000 -#define CST4350_APP_CLK_SWITCH_SEL_RDBACK 0x01000000 -#define CST4350_RAW_RSRC_INIT_MODE_0 0x02000000 -#define CST4350_SDIO_PAD_VDDIO 0x04000000 -#define CST4350_GSPI_MODE 0x08000000 -#define CST4350_PACKAGE_OPTION 0xF0000000 - -/* strap_host_ifc strap value */ -#define CST4350_HOST_IFC_MASK 0x00700000 -#define CST4350_HOST_IFC_SHIFT 20 - -/* host_ifc raw mode */ -#define CST4350_IFC_MODE_SDIOD 0x0 -#define CST4350_IFC_MODE_HSIC20D 0x1 -#define CST4350_IFC_MODE_HSIC30D 0x2 -#define CST4350_IFC_MODE_PCIE 0x3 -#define CST4350_IFC_MODE_USB20D 0x4 -#define CST4350_IFC_MODE_USB30D 0x5 -#define CST4350_IFC_MODE_USB30D_WL 0x6 -#define CST4350_IFC_MODE_USB30D_BT 0x7 - -#define CST4350_IFC_MODE(cs) ((cs & CST4350_HOST_IFC_MASK) >> CST4350_HOST_IFC_SHIFT) - -#define CST4350_CHIPMODE_SDIOD(cs) (CST4350_IFC_MODE(cs) == (CST4350_IFC_MODE_SDIOD)) -#define CST4350_CHIPMODE_USB20D(cs) ((CST4350_IFC_MODE(cs)) == (CST4350_IFC_MODE_USB20D)) -#define CST4350_CHIPMODE_HSIC20D(cs) (CST4350_IFC_MODE(cs) == (CST4350_IFC_MODE_HSIC20D)) -#define CST4350_CHIPMODE_HSIC30D(cs) (CST4350_IFC_MODE(cs) == (CST4350_IFC_MODE_HSIC30D)) -#define CST4350_CHIPMODE_USB30D(cs) (CST4350_IFC_MODE(cs) == (CST4350_IFC_MODE_USB30D)) -#define CST4350_CHIPMODE_USB30D_WL(cs) (CST4350_IFC_MODE(cs) == (CST4350_IFC_MODE_USB30D_WL)) -#define CST4350_CHIPMODE_PCIE(cs) (CST4350_IFC_MODE(cs) == (CST4350_IFC_MODE_PCIE)) - -/* 4350 PMU resources */ -#define RES4350_LPLDO_PU 0 -#define RES4350_PMU_BG_PU 1 -#define RES4350_PMU_SLEEP 2 -#define RES4350_RSVD_3 3 -#define RES4350_CBUCK_LPOM_PU 4 -#define RES4350_CBUCK_PFM_PU 5 -#define RES4350_COLD_START_WAIT 6 -#define RES4350_RSVD_7 7 -#define RES4350_LNLDO_PU 8 -#define RES4350_XTALLDO_PU 9 -#define RES4350_LDO3P3_PU 10 -#define RES4350_OTP_PU 11 -#define RES4350_XTAL_PU 12 -#define RES4350_SR_CLK_START 13 -#define RES4350_LQ_AVAIL 14 -#define RES4350_LQ_START 15 -#define RES4350_RSVD_16 16 -#define RES4350_WL_CORE_RDY 17 -#define RES4350_ILP_REQ 18 -#define RES4350_ALP_AVAIL 19 -#define RES4350_MINI_PMU 20 -#define RES4350_RADIO_PU 21 -#define RES4350_SR_CLK_STABLE 22 -#define RES4350_SR_SAVE_RESTORE 23 -#define RES4350_SR_PHY_PWRSW 24 -#define RES4350_SR_VDDM_PWRSW 25 -#define RES4350_SR_SUBCORE_PWRSW 26 -#define RES4350_SR_SLEEP 27 -#define RES4350_HT_START 28 -#define RES4350_HT_AVAIL 29 -#define RES4350_MACPHY_CLKAVAIL 30 - -#define MUXENAB4350_UART_MASK (0x0000000f) - -/* 4350 GCI function sel values */ -#define CC4350_FNSEL_HWDEF (0) -#define CC4350_FNSEL_SAMEASPIN (1) -#define CC4350_FNSEL_UART (2) -#define CC4350_FNSEL_SFLASH (3) -#define CC4350_FNSEL_SPROM (4) -#define CC4350_FNSEL_I2C (5) -#define CC4350_FNSEL_MISC0 (6) -#define CC4350_FNSEL_GCI (7) -#define CC4350_FNSEL_MISC1 (8) -#define CC4350_FNSEL_MISC2 (9) -#define CC4350_FNSEL_PWDOG (10) -#define CC4350_FNSEL_IND (12) -#define CC4350_FNSEL_PDN (13) -#define CC4350_FNSEL_PUP (14) -#define CC4350_FNSEL_TRISTATE (15) - -/* 4350 GPIO */ -#define CC4350_PIN_GPIO_00 (0) -#define CC4350_PIN_GPIO_01 (1) -#define CC4350_PIN_GPIO_02 (2) -#define CC4350_PIN_GPIO_03 (3) -#define CC4350_PIN_GPIO_04 (4) -#define CC4350_PIN_GPIO_05 (5) -#define CC4350_PIN_GPIO_06 (6) -#define CC4350_PIN_GPIO_07 (7) -#define CC4350_PIN_GPIO_08 (8) -#define CC4350_PIN_GPIO_09 (9) -#define CC4350_PIN_GPIO_10 (10) -#define CC4350_PIN_GPIO_11 (11) -#define CC4350_PIN_GPIO_12 (12) -#define CC4350_PIN_GPIO_13 (13) -#define CC4350_PIN_GPIO_14 (14) -#define CC4350_PIN_GPIO_15 (15) - -#define CC2_4350_MEMLPLDO_PWRSW_EN_MASK (1 << 21) -#define CC2_4350_MEMLPLDO_PWRSW_EN_SHIFT (21) -#define CC2_4350_SDIO_AOS_WAKEUP_MASK (1 << 24) -#define CC2_4350_SDIO_AOS_WAKEUP_SHIFT (24) - -/* Applies to 4335/4350/4345 */ -#define CC3_SR_CLK_SR_MEM_MASK (1 << 0) -#define CC3_SR_CLK_SR_MEM_SHIFT (0) -#define CC3_SR_BIT1_TBD_MASK (1 << 1) -#define CC3_SR_BIT1_TBD_SHIFT (1) -#define CC3_SR_ENGINE_ENABLE_MASK (1 << 2) -#define CC3_SR_ENGINE_ENABLE_SHIFT (2) -#define CC3_SR_BIT3_TBD_MASK (1 << 3) -#define CC3_SR_BIT3_TBD_SHIFT (3) -#define CC3_SR_MINDIV_FAST_CLK_MASK (0xF << 4) -#define CC3_SR_MINDIV_FAST_CLK_SHIFT (4) -#define CC3_SR_R23_SR2_RISE_EDGE_TRIG_MASK (1 << 8) -#define CC3_SR_R23_SR2_RISE_EDGE_TRIG_SHIFT (8) -#define CC3_SR_R23_SR2_FALL_EDGE_TRIG_MASK (1 << 9) -#define CC3_SR_R23_SR2_FALL_EDGE_TRIG_SHIFT (9) -#define CC3_SR_R23_SR_RISE_EDGE_TRIG_MASK (1 << 10) -#define CC3_SR_R23_SR_RISE_EDGE_TRIG_SHIFT (10) -#define CC3_SR_R23_SR_FALL_EDGE_TRIG_MASK (1 << 11) -#define CC3_SR_R23_SR_FALL_EDGE_TRIG_SHIFT (11) -#define CC3_SR_NUM_CLK_HIGH_MASK (0x7 << 12) -#define CC3_SR_NUM_CLK_HIGH_SHIFT (12) -#define CC3_SR_BIT15_TBD_MASK (1 << 15) -#define CC3_SR_BIT15_TBD_SHIFT (15) -#define CC3_SR_PHY_FUNC_PIC_MASK (1 << 16) -#define CC3_SR_PHY_FUNC_PIC_SHIFT (16) -#define CC3_SR_BIT17_19_TBD_MASK (0x7 << 17) -#define CC3_SR_BIT17_19_TBD_SHIFT (17) -#define CC3_SR_CHIP_TRIGGER_1_MASK (1 << 20) -#define CC3_SR_CHIP_TRIGGER_1_SHIFT (20) -#define CC3_SR_CHIP_TRIGGER_2_MASK (1 << 21) -#define CC3_SR_CHIP_TRIGGER_2_SHIFT (21) -#define CC3_SR_CHIP_TRIGGER_3_MASK (1 << 22) -#define CC3_SR_CHIP_TRIGGER_3_SHIFT (22) -#define CC3_SR_CHIP_TRIGGER_4_MASK (1 << 23) -#define CC3_SR_CHIP_TRIGGER_4_SHIFT (23) -#define CC3_SR_ALLOW_SBC_FUNC_PIC_MASK (1 << 24) -#define CC3_SR_ALLOW_SBC_FUNC_PIC_SHIFT (24) -#define CC3_SR_BIT25_26_TBD_MASK (0x3 << 25) -#define CC3_SR_BIT25_26_TBD_SHIFT (25) -#define CC3_SR_ALLOW_SBC_STBY_MASK (1 << 27) -#define CC3_SR_ALLOW_SBC_STBY_SHIFT (27) -#define CC3_SR_GPIO_MUX_MASK (0xF << 28) -#define CC3_SR_GPIO_MUX_SHIFT (28) - -/* Applies to 4335/4350/4345 */ -#define CC4_SR_INIT_ADDR_MASK (0x3FF0000) -#define CC4_4350_SR_ASM_ADDR (0x30) -#define CC4_4335_SR_ASM_ADDR (0x48) -#define CC4_SR_INIT_ADDR_SHIFT (16) - -#define CC4_4350_EN_SR_CLK_ALP_MASK (1 << 30) -#define CC4_4350_EN_SR_CLK_ALP_SHIFT (30) -#define CC4_4350_EN_SR_CLK_HT_MASK (1 << 31) -#define CC4_4350_EN_SR_CLK_HT_SHIFT (31) - -#define VREG4_4350_MEMLPDO_PU_MASK (1 << 31) -#define VREG4_4350_MEMLPDO_PU_SHIFT 31 - -#define CC6_4350_PCIE_CLKREQ_WAKEUP_MASK (1 << 4) -#define CC6_4350_PCIE_CLKREQ_WAKEUP_SHIFT (4) -#define CC6_4350_PMU_WAKEUP_ALPAVAIL_MASK (1 << 6) -#define CC6_4350_PMU_WAKEUP_ALPAVAIL_SHIFT (6) +/* 4335 resources--END */ /* GCI chipcontrol register indices */ #define CC_GCI_CHIPCTRL_00 (0) @@ -2720,9 +2253,6 @@ typedef volatile struct { #define CC_GCI_CHIPCTRL_07 (7) #define CC_GCI_CHIPCTRL_08 (8) -#define CC_GCI_06_JTAG_SEL_SHIFT 4 -#define CC_GCI_06_JTAG_SEL_MASK (1 << 4) - #define CC_GCI_NUMCHIPCTRLREGS(cap1) ((cap1 & 0xF00) >> 8) /* 4335 pins @@ -2791,11 +2321,6 @@ typedef volatile struct { */ #define MUXENAB4335_UART_MASK (0x0000000f) -#define MUXENAB4335_UART_SHIFT 0 -#define MUXENAB4335_HOSTWAKE_MASK (0x000000f0) /* configure GPIO for SDIO host_wake */ -#define MUXENAB4335_HOSTWAKE_SHIFT 4 -#define MUXENAB4335_GETIX(val, name) \ - ((((val) & MUXENAB4335_ ## name ## _MASK) >> MUXENAB4335_ ## name ## _SHIFT) - 1) /* defines to detect active host interface in use */ #define CHIP_HOSTIF_USB(sih) (si_chip_hostif(sih) & CST4360_MODE_USB) diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/sbconfig.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/sbconfig.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/sbconfig.h 2014-01-27 01:30:30.101433269 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/sbconfig.h 2014-02-15 00:43:44.793014092 +0100 @@ -1,7 +1,7 @@ /* * Broadcom SiliconBackplane hardware register definitions. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/sbhnddma.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/sbhnddma.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/sbhnddma.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/sbhnddma.h 2014-02-15 00:43:44.794014114 +0100 @@ -2,7 +2,7 @@ * Generic Broadcom Home Networking Division (HND) DMA engine HW interface * This supports the following chips: BCM42xx, 44xx, 47xx . * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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: sbhnddma.h 373617 2012-12-07 23:03:08Z $ + * $Id: sbhnddma.h 309193 2012-01-19 00:03:57Z $ */ #ifndef _sbhnddma_h_ @@ -247,33 +247,10 @@ typedef volatile struct { */ #define D64RINGALIGN_BITS 13 #define D64MAXRINGSZ (1 << D64RINGALIGN_BITS) -#define D64RINGBOUNDARY (1 << D64RINGALIGN_BITS) +#define D64RINGALIGN (1 << D64RINGALIGN_BITS) #define D64MAXDD (D64MAXRINGSZ / sizeof (dma64dd_t)) -/* for cores with large descriptor ring support, descriptor ring size can be up to 4096 */ -#define D64MAXDD_LARGE ((1 << 16) / sizeof (dma64dd_t)) - -/* for cores with large descriptor ring support (4k descriptors), descriptor ring cannot cross - * 64K boundary - */ -#define D64RINGBOUNDARY_LARGE (1 << 16) - -/* - * Default DMA Burstlen values for USBRev >= 12 and SDIORev >= 11. - * When this field contains the value N, the burst length is 2**(N + 4) bytes. - */ -#define D64_DEF_USBBURSTLEN 2 -#define D64_DEF_SDIOBURSTLEN 1 - - -#ifndef D64_USBBURSTLEN -#define D64_USBBURSTLEN DMA_BL_64 -#endif -#ifndef D64_SDIOBURSTLEN -#define D64_SDIOBURSTLEN DMA_BL_32 -#endif - /* transmit channel control */ #define D64_XC_XE 0x00000001 /* transmit enable */ #define D64_XC_SE 0x00000002 /* transmit suspend request */ @@ -295,7 +272,7 @@ typedef volatile struct { #define D64_XP_LD_MASK 0x00001fff /* last valid descriptor */ /* transmit channel status */ -#define D64_XS0_CD_MASK (di->d64_xs0_cd_mask) /* current descriptor pointer */ +#define D64_XS0_CD_MASK 0x00001fff /* current descriptor pointer */ #define D64_XS0_XS_MASK 0xf0000000 /* transmit state */ #define D64_XS0_XS_SHIFT 28 #define D64_XS0_XS_DISABLED 0x00000000 /* disabled */ @@ -304,7 +281,7 @@ typedef volatile struct { #define D64_XS0_XS_STOPPED 0x30000000 /* stopped */ #define D64_XS0_XS_SUSP 0x40000000 /* suspend pending */ -#define D64_XS1_AD_MASK (di->d64_xs1_ad_mask) /* active descriptor */ +#define D64_XS1_AD_MASK 0x00001fff /* active descriptor */ #define D64_XS1_XE_MASK 0xf0000000 /* transmit errors */ #define D64_XS1_XE_SHIFT 28 #define D64_XS1_XE_NOERR 0x00000000 /* no error */ @@ -322,7 +299,6 @@ typedef volatile struct { #define D64_RC_SH 0x00000200 /* separate rx header descriptor enable */ #define D64_RC_OC 0x00000400 /* overflow continue */ #define D64_RC_PD 0x00000800 /* parity check disable */ -#define D64_RC_GE 0x00004000 /* Glom enable */ #define D64_RC_AE 0x00030000 /* address extension bits */ #define D64_RC_AE_SHIFT 16 #define D64_RC_BL_MASK 0x001C0000 /* BurstLen bits */ @@ -344,7 +320,7 @@ typedef volatile struct { #define D64_RP_LD_MASK 0x00001fff /* last valid descriptor */ /* receive channel status */ -#define D64_RS0_CD_MASK (di->d64_rs0_cd_mask) /* current descriptor pointer */ +#define D64_RS0_CD_MASK 0x00001fff /* current descriptor pointer */ #define D64_RS0_RS_MASK 0xf0000000 /* receive state */ #define D64_RS0_RS_SHIFT 28 #define D64_RS0_RS_DISABLED 0x00000000 /* disabled */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/sbpcmcia.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/sbpcmcia.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/sbpcmcia.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/sbpcmcia.h 2014-02-15 00:43:44.794014114 +0100 @@ -1,7 +1,7 @@ /* * BCM43XX Sonics SiliconBackplane PCMCIA core hardware definitions. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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: sbpcmcia.h 381094 2013-01-25 04:45:06Z $ + * $Id: sbpcmcia.h 326494 2012-04-09 13:29:57Z $ */ #ifndef _SBPCMCIA_H diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/sbsdio.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/sbsdio.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/sbsdio.h 2014-01-27 01:30:30.101433269 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/sbsdio.h 2014-02-15 00:43:44.793014092 +0100 @@ -4,7 +4,7 @@ * * SDIO core support 1bit, 4 bit SDIO mode as well as SPI mode. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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 383835 2013-02-07 23:32:39Z $ + * $Id: sbsdio.h 361940 2012-10-10 08:32:12Z $ */ #ifndef _SBSDIO_H @@ -101,7 +101,6 @@ * => busy signal is asserted between data blocks. */ #define SBSDIO_MESBUSYCTRL_MASK 0x7f -#define SBSDIO_MESBUSYCTRL_ENAB 0x80 /* Enable busy capability for MES access */ /* SBSDIO_DEVICE_CTL */ #define SBSDIO_DEVCTL_SETBUSY 0x01 /* 1: device will assert busy signal when @@ -117,9 +116,12 @@ * external pads in tri-state; requires * sdio bus power cycle to clear (rev 9) */ +#define SBSDIO_DEVCTL_SB_RST_CTL 0x30 /* Force SD->SB reset mapping (rev 11) */ +#define SBSDIO_DEVCTL_RST_CORECTL 0x00 /* Determined by CoreControl bit */ +#define SBSDIO_DEVCTL_RST_BPRESET 0x10 /* Force backplane reset */ +#define SBSDIO_DEVCTL_RST_NOBPRESET 0x20 /* Force no backplane reset */ #define SBSDIO_DEVCTL_EN_F2_BLK_WATERMARK 0x10 /* Enable function 2 tx for each block */ -#define SBSDIO_DEVCTL_F2WM_ENAB 0x10 /* Enable F2 Watermark */ -#define SBSDIO_DEVCTL_NONDAT_PADS_ISO 0x20 /* Isolate sdio clk and cmd (non-data) */ + /* SBSDIO_FUNC1_CHIPCLKCSR */ #define SBSDIO_FORCE_ALP 0x01 /* Force ALP request to backplane */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/sbsdpcmdev.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/sbsdpcmdev.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/sbsdpcmdev.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/sbsdpcmdev.h 2014-02-15 00:43:44.794014114 +0100 @@ -2,7 +2,7 @@ * Broadcom SiliconBackplane SDIO/PCMCIA hardware-specific * device core support * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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 336848 2012-06-05 11:28:07Z $ + * $Id: sbsdpcmdev.h 347614 2012-07-27 10:24:51Z $ */ #ifndef _sbsdpcmdev_h_ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/sbsocram.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/sbsocram.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/sbsocram.h 2014-01-27 01:30:30.101433269 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/sbsocram.h 2014-02-15 00:43:44.793014092 +0100 @@ -1,7 +1,7 @@ /* * BCM47XX Sonics SiliconBackplane embedded ram core * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/sdio.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/sdio.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/sdio.h 2014-01-27 01:30:30.101433269 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/sdio.h 2014-02-15 00:43:44.793014092 +0100 @@ -2,7 +2,7 @@ * SDIO spec header file * Protocol and standard (common) device definitions * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/sdioh.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/sdioh.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/sdioh.h 2014-01-27 01:30:30.101433269 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/sdioh.h 2014-02-15 00:43:44.793014092 +0100 @@ -2,7 +2,7 @@ * SDIO Host Controller Spec header file * Register map and definitions for the Standard Host Controller * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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 345499 2012-07-18 06:59:05Z $ + * $Id: sdioh.h 347633 2012-07-27 11:02:02Z $ */ #ifndef _SDIOH_H @@ -90,8 +90,8 @@ #define SD3_PresetVal_SDR104 0x06c #define SD3_PresetVal_DDR50 0x06e /* SDIO3.0 Revx specific Registers */ -#define SD3_Tuning_Info_Register 0x0EC -#define SD3_WL_BT_reset_register 0x0F0 +#define SD3_Tuning_Info_Register 0x0EC +#define SD3_WL_BT_reset_register 0x0F0 /* preset value indices */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/sdiovar.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/sdiovar.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/sdiovar.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/sdiovar.h 2014-02-15 00:43:44.794014114 +0100 @@ -2,7 +2,7 @@ * Structure used by apps whose drivers access SDIO drivers. * Pulled out separately so dhdu and wlu can both use it. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/siutils.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/siutils.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/siutils.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/siutils.h 2014-02-15 00:43:44.794014114 +0100 @@ -2,7 +2,7 @@ * Misc utility routines for accessing the SOC Interconnects * of Broadcom HNBU chips. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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: siutils.h 385510 2013-02-15 21:02:07Z $ + * $Id: siutils.h 347614 2012-07-27 10:24:51Z $ */ #ifndef _siutils_h_ @@ -160,7 +160,6 @@ extern bool si_pci_war16165(si_t *sih); extern uint si_corelist(si_t *sih, uint coreid[]); extern uint si_coreid(si_t *sih); extern uint si_flag(si_t *sih); -extern uint si_flag_alt(si_t *sih); extern uint si_intflag(si_t *sih); extern uint si_coreidx(si_t *sih); extern uint si_coreunit(si_t *sih); @@ -171,8 +170,6 @@ extern void si_setosh(si_t *sih, osl_t * extern uint si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val); extern void *si_coreregs(si_t *sih); extern uint si_wrapperreg(si_t *sih, uint32 offset, uint32 mask, uint32 val); -extern uint si_core_wrapperreg(si_t *sih, uint32 coreidx, uint32 offset, uint32 mask, uint32 val); -extern void *si_wrapperregs(si_t *sih); extern uint32 si_core_cflags(si_t *sih, uint32 mask, uint32 val); extern void si_core_cflags_wo(si_t *sih, uint32 mask, uint32 val); extern uint32 si_core_sflags(si_t *sih, uint32 mask, uint32 val); @@ -190,7 +187,6 @@ 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); extern uint32 si_clock_rate(uint32 pll_type, uint32 n, uint32 m); -extern uint si_chip_hostif(si_t *sih); extern bool si_read_pmu_autopll(si_t *sih); extern uint32 si_clock(si_t *sih); extern uint32 si_alp_clock(si_t *sih); @@ -262,8 +258,6 @@ static INLINE void * si_eci_init(si_t *s #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_gci(sih) 0 -static INLINE void * si_gci_init(si_t *sih) {return NULL;} /* OTP status */ extern bool si_is_otp_disabled(si_t *sih); @@ -303,8 +297,6 @@ extern char *si_coded_devpathvar(si_t *s extern uint8 si_pcieclkreq(si_t *sih, uint32 mask, uint32 val); extern uint32 si_pcielcreg(si_t *sih, uint32 mask, uint32 val); -extern uint8 si_pcieltrenable(si_t *sih, uint32 mask, uint32 val); -extern void si_pcie_set_error_injection(si_t *sih, uint32 mode); extern void si_war42780_clkreq(si_t *sih, bool clkreq); extern void si_pci_down(si_t *sih); extern void si_pci_up(si_t *sih); @@ -328,7 +320,6 @@ extern void si_btc_enable_chipcontrol(si 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 void si_pmu_synth_pwrsw_4313_war(si_t *sih); extern uint si_pll_reset(si_t *sih); /* === debug routines === */ @@ -336,13 +327,10 @@ extern bool si_taclear(si_t *sih, bool d -extern uint32 si_ccreg(si_t *sih, uint32 offset, uint32 mask, uint32 val); 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 void si_pcie_set_maxpayload_size(si_t *sih, uint16 size); -extern uint16 si_pcie_get_maxpayload_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); @@ -356,27 +344,4 @@ extern uint32 si_tcm_size(si_t *sih); extern int si_set_sromctl(si_t *sih, uint32 value); extern uint32 si_get_sromctl(si_t *sih); - -extern uint32 si_gci_direct(si_t *sih, uint offset, uint32 mask, uint32 val); -extern void si_gci_reset(si_t *sih); -extern void si_gci_set_functionsel(si_t *sih, uint32 pin, uint8 fnsel); -extern uint8 si_gci_get_chipctrlreg_idx(uint32 pin, uint32 *regidx, uint32 *pos); -extern uint32 si_gci_chipcontrol(si_t *sih, uint reg, uint32 mask, uint32 val); - -#define CHIPCTRLREG2 0x2 -#define CHIPCTRLREG3 0x3 -#define CHIPCTRLREG4 0x4 -#define MINRESMASKREG 0x618 -#define CHIPCTRLADDR 0x650 -#define CHIPCTRLDATA 0x654 -#define RSRCTABLEADDR 0x620 -#define RSRCUPDWNTIME 0x628 -#define PMUREG_RESREQ_MASK 0x68c - -void -si_update_masks(si_t *sih); - -void -si_force_islanding(si_t *sih, bool enable); - #endif /* _siutils_h_ */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/trxhdr.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/trxhdr.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/trxhdr.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/trxhdr.h 2014-02-15 00:43:44.794014114 +0100 @@ -1,7 +1,7 @@ /* * TRX image file header format. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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: trxhdr.h 349211 2012-08-07 09:45:24Z $ + * $Id: trxhdr.h 260898 2011-05-20 23:11:12Z $ */ #ifndef _TRX_HDR_H @@ -30,62 +30,23 @@ #include #define TRX_MAGIC 0x30524448 /* "HDR0" */ +#define TRX_VERSION 1 /* Version 1 */ #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_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_BOOTLOADER 0x40 /* the image is a bootloader */ +#define TRX_MAX_OFFSET 3 /* Max number of individual files */ -#define TRX_V1 1 -#define TRX_V1_MAX_OFFSETS 3 /* V1: Max number of individual files */ - -#ifndef BCMTRXV2 -#define TRX_VERSION TRX_V1 /* Version 1 */ -#define TRX_MAX_OFFSET TRX_V1_MAX_OFFSETS -#endif - -/* BMAC Host driver/application like bcmdl need to support both Ver 1 as well as - * Ver 2 of trx header. To make it generic, trx_header is structure is modified - * as below where size of "offsets" field will vary as per the TRX version. - * Currently, BMAC host driver and bcmdl are modified to support TRXV2 as well. - * To make sure, other applications like "dhdl" which are yet to be enhanced to support - * TRXV2 are not broken, new macro and structure defintion take effect only when BCMTRXV2 - * is defined. - */ struct trx_header { uint32 magic; /* "HDR0" */ uint32 len; /* Length of file including header */ uint32 crc32; /* 32-bit CRC from flag_version to end of file */ uint32 flag_version; /* 0:15 flags, 16:31 version */ -#ifndef BCMTRXV2 uint32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of header */ -#else - uint32 offsets[1]; /* Offsets of partitions from start of header */ -#endif }; -#ifdef BCMTRXV2 -#define TRX_VERSION TRX_V2 /* Version 2 */ -#define TRX_MAX_OFFSET TRX_V2_MAX_OFFSETS - -#define TRX_V2 2 -/* V2: Max number of individual files - * To support SDR signature + Config data region - */ -#define TRX_V2_MAX_OFFSETS 5 -#define SIZEOF_TRXHDR_V1 (sizeof(struct trx_header)+(TRX_V1_MAX_OFFSETS-1)*sizeof(uint32)) -#define SIZEOF_TRXHDR_V2 (sizeof(struct trx_header)+(TRX_V2_MAX_OFFSETS-1)*sizeof(uint32)) -#define TRX_VER(trx) (trx->flag_version>>16) -#define ISTRX_V1(trx) (TRX_VER(trx) == TRX_V1) -#define ISTRX_V2(trx) (TRX_VER(trx) == TRX_V2) -/* For V2, return size of V2 size: others, return V1 size */ -#define SIZEOF_TRX(trx) (ISTRX_V2(trx) ? SIZEOF_TRXHDR_V2: SIZEOF_TRXHDR_V1) -#else -#define SIZEOF_TRX(trx) (sizeof(struct trx_header)) -#endif /* BCMTRXV2 */ - /* Compatibility */ typedef struct trx_header TRXHDR, *PTRXHDR; diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/typedefs.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/typedefs.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/typedefs.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/typedefs.h 2014-02-15 00:43:44.794014114 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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: typedefs.h 397286 2013-04-18 01:42:19Z $ + * $Id: typedefs.h 286783 2011-09-29 06:18:57Z $ */ #ifndef _TYPEDEFS_H_ @@ -121,7 +121,7 @@ typedef long unsigned int size_t; #if defined(__GNUC__) && defined(__STRICT_ANSI__) #define TYPEDEF_INT64 #define TYPEDEF_UINT64 -#endif /* defined(__GNUC__) && defined(__STRICT_ANSI__) */ +#endif /* ICL accepts unsigned 64 bit type only, and complains in ANSI mode * for signed or unsigned diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/usbrdl.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/usbrdl.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/usbrdl.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/usbrdl.h 2014-02-15 00:43:44.794014114 +0100 @@ -0,0 +1,114 @@ +/* + * 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 + + +#define DL_GETSTATE 0 +#define DL_CHECK_CRC 1 +#define DL_GO 2 +#define DL_START 3 +#define DL_REBOOT 4 +#define DL_GETVER 5 +#define DL_GO_PROTECTED 6 +#define DL_EXEC 7 +#define DL_RESETCFG 8 +#define DL_DEFER_RESP_OK 9 + +#define DL_HWCMD_MASK 0xfc +#define DL_RDHW 0x10 +#define DL_RDHW32 0x10 +#define DL_RDHW16 0x11 +#define DL_RDHW8 0x12 +#define DL_WRHW 0x14 +#define DL_WRHW_BLK 0x13 + +#define DL_CMD_RDHW 1 +#define DL_CMD_WRHW 2 + + + +#define DL_WAITING 0 +#define DL_READY 1 +#define DL_BAD_HDR 2 +#define DL_BAD_CRC 3 +#define DL_RUNNABLE 4 +#define DL_START_FAIL 5 +#define DL_NVRAM_TOOBIG 6 +#define DL_IMAGE_TOOBIG 7 + +#define TIMEOUT 5000 + +struct bcm_device_id { + char *name; + uint32 vend; + uint32 prod; +}; + +typedef struct { + uint32 state; + uint32 bytes; +} rdl_state_t; + +typedef struct { + uint32 chip; + uint32 chiprev; + uint32 ramsize; + uint32 remapbase; + uint32 boardtype; + uint32 boardrev; +} bootrom_id_t; + + +typedef struct { + uint32 cmd; + uint32 addr; + uint32 len; + uint32 data; +} hwacc_t; + + +typedef struct { + uint32 cmd; + uint32 addr; + uint32 len; + uint8 data[1]; +} hwacc_blk_t; + + + +#define QUERY_STRING_MAX 32 +typedef struct { + uint32 cmd; + char var[QUERY_STRING_MAX]; +} 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 + +#define RDL_CHUNK 1500 + + +#define TRX_OFFSETS_DLFWLEN_IDX 0 +#define TRX_OFFSETS_JUMPTO_IDX 1 +#define TRX_OFFSETS_NVM_LEN_IDX 2 + +#define TRX_OFFSETS_DLBASE_IDX 0 + +#endif diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/wlfc_proto.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/wlfc_proto.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/wlfc_proto.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/wlfc_proto.h 2014-02-15 00:43:44.794014114 +0100 @@ -1,5 +1,5 @@ /* -* Copyright (C) 1999-2013, Broadcom Corporation +* 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 @@ -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 381382 2013-01-27 07:13:00Z $ +* $Id: wlfc_proto.h 361006 2012-10-05 07:45:51Z $ * */ #ifndef __wlfc_proto_definitions_h__ @@ -34,8 +34,7 @@ --------------------------------------------------------------------------- | 3 | 2 | (count, handle, prec_bmp)| Set the credit depth for a MAC dstn --------------------------------------------------------------------------- - | 4 | 4+ | see pkttag comments | TXSTATUS - | | | TX status & timestamps | Present only when pkt timestamp is enabled + | 4 | 4 | see pkttag comments | TXSTATUS --------------------------------------------------------------------------- | 5 | 4 | see pkttag comments | PKKTTAG [host->firmware] --------------------------------------------------------------------------- @@ -63,9 +62,11 @@ | 13 | 3 | (count, handle, prec_bmp)| One time request for packet to a specific | | | | MAC destination. --------------------------------------------------------------------------- - | 15 | 12 | (pkttag, timestamps) | Send TX timestamp at reception from host + | 15 | 1 | interface ID | NIC period start --------------------------------------------------------------------------- - | 16 | 12 | (pkttag, timestamps) | Send WLAN RX timestamp along with RX frame + | 16 | 1 | interface ID | NIC period end + --------------------------------------------------------------------------- + | 17 | 3 | (ifid, txs) | Action frame tx status --------------------------------------------------------------------------- | 255 | N/A | N/A | FILLER - This is a special type | | | | that has no length or value. @@ -81,7 +82,7 @@ #define WLFC_CTL_TYPE_MACDESC_ADD 6 #define WLFC_CTL_TYPE_MACDESC_DEL 7 -#define WLFC_CTL_TYPE_RSSI 8 +#define WLFC_CTL_TYPE_RSSI 8 #define WLFC_CTL_TYPE_INTERFACE_OPEN 9 #define WLFC_CTL_TYPE_INTERFACE_CLOSE 10 @@ -92,12 +93,11 @@ #define WLFC_CTL_TYPE_MAC_REQUEST_PACKET 13 #define WLFC_CTL_TYPE_HOST_REORDER_RXPKTS 14 -#define WLFC_CTL_TYPE_TX_ENTRY_STAMP 15 -#define WLFC_CTL_TYPE_RX_STAMP 16 - -#define WLFC_CTL_TYPE_TRANS_ID 18 -#define WLFC_CTL_TYPE_COMP_TXSTATUS 19 - +#define WLFC_CTL_TYPE_NIC_PRD_START 15 +#define WLFC_CTL_TYPE_NIC_PRD_END 16 +#define WLFC_CTL_TYPE_AF_TXS 17 +#define WLFC_CTL_TYPE_TRANS_ID 18 +#define WLFC_CTL_TYPE_COMP_TXSTATUS 19 #define WLFC_CTL_TYPE_FILLER 255 @@ -118,6 +118,10 @@ #define WLFC_CTL_VALUE_LEN_REQUEST_CREDIT 3 /* credit, MAC-handle, prec_bitmap */ #define WLFC_CTL_VALUE_LEN_REQUEST_PACKET 3 /* credit, MAC-handle, prec_bitmap */ +#define WLFC_CTL_VALUE_LEN_NIC_PRD_START 1 +#define WLFC_CTL_VALUE_LEN_NIC_PRD_END 1 +#define WLFC_CTL_VALUE_LEN_AF_TXS 3 + #define WLFC_PKTID_GEN_MASK 0x80000000 #define WLFC_PKTID_GEN_SHIFT 31 @@ -223,8 +227,7 @@ #define WLHOST_REORDERDATA_CURIDX_VALID 0x04 #define WLHOST_REORDERDATA_EXPIDX_VALID 0x08 #define WLHOST_REORDERDATA_NEW_HOLE 0x10 - /* transaction id data len byte 0: rsvd, byte 1: seqnumber, byte 2-5 will be used for timestampe */ -#define WLFC_CTL_TRANS_ID_LEN 6 +#define WLFC_CTL_TRANS_ID_LEN 6 #endif /* __wlfc_proto_definitions_h__ */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/include/wlioctl.h linux-sunxi-new/drivers/net/wireless/bcmdhd/include/wlioctl.h --- linux-sunxi/drivers/net/wireless/bcmdhd/include/wlioctl.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/include/wlioctl.h 2014-02-15 00:43:44.794014114 +0100 @@ -4,7 +4,7 @@ * * Definitions subject to change without notice. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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: wlioctl.h 419132 2013-08-19 21:33:05Z $ + * $Id: wlioctl.h 366141 2012-11-01 01:55:06Z $ */ #ifndef _wlioctl_h_ @@ -63,12 +63,6 @@ typedef struct remote_ioctl { } rem_ioctl_t; #define REMOTE_SIZE sizeof(rem_ioctl_t) - -typedef struct { - uint32 num; - chanspec_t list[1]; -} chanspec_list_t; - #define ACTION_FRAME_SIZE 1800 typedef struct wl_action_frame { @@ -215,8 +209,8 @@ typedef struct wl_bss_info { uint32 nbss_cap; /* 802.11N+AC BSS Capabilities */ uint8 ctl_ch; /* 802.11N BSS control channel number */ uint8 padding1[3]; /* explicit struct alignment padding */ - uint16 vht_rxmcsmap; /* VHT rx mcs map (802.11ac VHT_CAP_MCS_MAP_*) */ - uint16 vht_txmcsmap; /* VHT tx mcs map (802.11ac VHT_CAP_MCS_MAP_*) */ + 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 */ @@ -310,7 +304,7 @@ typedef struct wl_clm_dload_info wl_clm_ typedef struct wlc_ssid { uint32 SSID_len; - uchar SSID[DOT11_MAX_SSID_LEN]; + uchar SSID[32]; } wlc_ssid_t; #ifndef LINUX_POSTMOGRIFY_REMOVAL @@ -364,8 +358,6 @@ typedef struct wl_extdscan_params { #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_SCANFLAGS_OFFCHAN 0x08 /* allow scanning/reporting off-channel APs */ -#define WL_SCANFLAGS_HOTSPOT 0x10 /* automatic ANQP to hotspot APs */ #define WL_SCAN_PARAMS_SSID_MAX 10 @@ -498,7 +490,6 @@ typedef struct wl_rateset_args { uint32 count; /* # rates in this set */ uint8 rates[WL_MAXRATES_IN_SET]; /* rates in 500kbps units w/hi bit set if basic */ uint8 mcs[MCSSET_LEN]; /* supported mcs index bit map */ - uint16 vht_mcs[VHT_CAP_MCS_MAP_NSS_MAX]; /* supported mcs index bit map per nss */ } wl_rateset_args_t; /* uint32 list */ @@ -512,10 +503,10 @@ typedef struct wl_uint32_list { /* used for association with a specific BSSID and chanspec list */ typedef struct wl_assoc_params { struct ether_addr bssid; /* 00:00:00:00:00:00: broadcast scan */ - uint16 bssid_cnt; /* 0: use chanspec_num, and the single bssid, - * otherwise count of chanspecs in chanspec_list - * AND paired bssids following chanspec_list - */ + uint16 bssid_cnt; /* 0: use chanspec_num, and the single bssid, + * otherwise count of chanspecs in chanspec_list + * AND paired bssids following chanspec_list + */ int32 chanspec_num; /* 0: all available channels, * otherwise count of chanspecs in chanspec_list */ @@ -604,7 +595,6 @@ typedef struct wl_extjoin_params { #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_TXBF 0x00200000 /* bit indicates TXBF mode */ #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 */ @@ -865,8 +855,10 @@ typedef enum sup_auth_status { #define CRYPTO_ALGO_WEP_MMH 9 #define CRYPTO_ALGO_NALG 10 #endif +#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 CRYPTO_ALGO_BIP 13 /* 802.11w BIP (aes cmac) */ #define WSEC_GEN_MIC_ERROR 0x0001 #define WSEC_GEN_REPLAY 0x0002 @@ -933,10 +925,15 @@ typedef struct { #define WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED)) #define WSEC_SES_OW_ENABLED(wsec) ((wsec) & SES_OW_ENABLED) +#ifdef BCMWAPI_WPI +#define SMS4_ENABLED 0x0100 +#endif /* BCMWAPI_WPI */ +#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) */ @@ -952,6 +949,12 @@ typedef struct { #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 */ +#ifdef BCMWAPI_WAI +#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 */ #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. */ @@ -1055,32 +1058,6 @@ typedef struct wme_tx_params_s wme_tx_pa #define WL_WME_TX_PARAMS_IO_BYTES (sizeof(wme_tx_params_t) * AC_COUNT) -typedef struct wl_plc_nodelist { - uint count; /* Number of nodes */ - struct _node { - struct ether_addr ea; /* Node ether address */ - uint32 node_type; /* Node type */ - uint32 cost; /* PLC affinity */ - } node[1]; -} wl_plc_nodelist_t; - -typedef struct wl_plc_params { - uint32 cmd; /* Command */ - bool plc_failover; /* PLC failover control/status */ - struct ether_addr node_ea; /* Node ether address */ - uint32 cost; /* Link cost or mac cost */ -} wl_plc_params_t; - -#define PLC_CMD_FAILOVER 1 -#define PLC_CMD_MAC_COST 2 -#define PLC_CMD_LINK_COST 3 -#define PLC_CMD_NODE_LIST 4 - -#define NODE_TYPE_UNKNOWN 0 /* Unknown link */ -#define NODE_TYPE_WIFI_ONLY 1 /* Pure Wireless STA node */ -#define NODE_TYPE_PLC_ONLY 2 /* Pure PLC only node */ -#define NODE_TYPE_WIFI_PLC 3 /* WiFi PLC capable node */ - /* 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. */ @@ -1226,7 +1203,7 @@ typedef struct { /* Get MAC rate histogram response */ typedef struct { - uint32 rate[DOT11_RATE_MAX + 1]; /* Rates */ + uint32 rate[WLC_MAXRATE + 1]; /* Rates */ uint32 mcs[WL_RATESET_SZ_HT_MCS * WL_TX_CHAINS_MAX]; /* MCS counts */ uint32 vht[WL_RATESET_SZ_VHT_MCS][WL_TX_CHAINS_MAX]; /* VHT counts */ uint32 tsf_timer[2][2]; /* Start and End time for 8bytes value */ @@ -1284,7 +1261,6 @@ typedef struct wlc_rev_info { uint phyrev; /* phy revision */ uint anarev; /* anacore rev */ uint chippkg; /* chip package info */ - uint nvramrev; /* nvram revision number */ } wlc_rev_info_t; #define WL_REV_INFO_LEGACY_LENGTH 48 @@ -1618,9 +1594,7 @@ typedef struct wlc_iov_trx_s { #define WLC_NVRAM_SET 265 #define WLC_NVRAM_DUMP 266 #define WLC_REBOOT 267 -#endif /* LINUX_POSTMOGRIFY_REMOVAL */ #define WLC_SET_WSEC_PMK 268 -#ifndef LINUX_POSTMOGRIFY_REMOVAL #define WLC_GET_AUTH_MODE 269 #define WLC_SET_AUTH_MODE 270 #define WLC_GET_WAKEENTRY 271 @@ -1670,8 +1644,7 @@ typedef struct wlc_iov_trx_s { /* #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_GET_RSSI_QDB 318 /* qdB portion of the RSSI */ -#define WLC_LAST 319 +#define WLC_LAST 318 #ifndef EPICTRL_COOKIE #define EPICTRL_COOKIE 0xABADCEDE @@ -1742,7 +1715,12 @@ typedef struct { /* 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 */ +#ifdef BCM4330_CHIP +#define WL_AUTH_OPEN_SHARED 2 /* try open, then shared if open failed w/rc 13 */ +#else +/* BCM4334(Phoenex branch) value changed to 3 */ +#define WL_AUTH_OPEN_SHARED 3 /* try open, then shared if open failed w/rc 13 */ +#endif #endif /* LINUX_POSTMOGRIFY_REMOVAL */ /* Bit masks for radio disabled status - returned by WL_GET_RADIO */ @@ -1755,17 +1733,6 @@ typedef struct { #define WL_SPURAVOID_ON1 1 #define WL_SPURAVOID_ON2 2 - -#define WL_4335_SPURAVOID_ON1 1 -#define WL_4335_SPURAVOID_ON2 2 -#define WL_4335_SPURAVOID_ON3 3 -#define WL_4335_SPURAVOID_ON4 4 -#define WL_4335_SPURAVOID_ON5 5 -#define WL_4335_SPURAVOID_ON6 6 -#define WL_4335_SPURAVOID_ON7 7 -#define WL_4335_SPURAVOID_ON8 8 -#define WL_4335_SPURAVOID_ON9 9 - /* Override bit for WLC_SET_TXPWR. if set, ignore other level limits */ #define WL_TXPWR_OVERRIDE (1U<<31) #define WL_TXPWR_NEG (1U<<30) @@ -1774,16 +1741,6 @@ typedef struct { #define WL_PHY_PAVARS_LEN 32 /* Phy type, Band range, chain, a1[0], b0[0], b1[0] ... */ #define WL_PHY_PAVAR_VER 1 /* pavars version */ -#define WL_PHY_PAVARS2_NUM 3 /* a1, b0, b1 */ -typedef struct wl_pavars2 { - uint16 ver; /* version of this struct */ - uint16 len; /* len of this structure */ - uint16 inuse; /* driver return 1 for a1,b0,b1 in current band range */ - uint16 phy_type; /* phy type */ - uint16 bandrange; - uint16 chain; - uint16 inpa[WL_PHY_PAVARS2_NUM]; /* phy pavars for one band range */ -} wl_pavars2_t; typedef struct wl_po { uint16 phy_type; /* Phy type */ @@ -1835,12 +1792,6 @@ typedef struct wl_po { #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 @@ -2041,8 +1992,6 @@ typedef struct wl_samplecollect_args { uint8 module_sel1; uint8 module_sel2; uint16 nsamps; - int bitStart; - uint32 gpioCapMask; } wl_samplecollect_args_t; #define WL_SAMPLEDATA_HEADER_TYPE 1 @@ -2062,117 +2011,6 @@ typedef struct wl_sampledata { uint32 flag; /* bit def */ } wl_sampledata_t; -/* WL_OTA START */ - -#define WL_OTA_ARG_PARSE_BLK_SIZE 1200 -#define WL_OTA_TEST_MAX_NUM_RATE 30 -#define WL_OTA_TEST_MAX_NUM_SEQ 100 - -/* OTA Test Status */ -enum { - WL_OTA_TEST_IDLE, /* Default Idle state */ - WL_OTA_TEST_ACTIVE, /* Test Running */ - WL_OTA_TEST_SUCCESS, /* Successfully Finished Test */ - WL_OTA_TEST_FAIL /* Test Failed in the Middle */ -}; -/* OTA SYNC Status */ -enum { - WL_OTA_SYNC_IDLE, /* Idle state */ - WL_OTA_SYNC_ACTIVE, /* Waiting for Sync */ - WL_OTA_SYNC_FAIL /* Sync pkt not recieved */ -}; - -/* Various error states dut can get stuck during test */ -enum { - WL_OTA_SKIP_TEST_CAL_FAIL = 1, /* Phy calibration failed */ - WL_OTA_SKIP_TEST_SYNCH_FAIL, /* Sync Packet not recieved */ - WL_OTA_SKIP_TEST_FILE_DWNLD_FAIL, /* Cmd flow file download failed */ - WL_OTA_SKIP_TEST_NO_TEST_FOUND, /* No test found in Flow file */ - WL_OTA_SKIP_TEST_WL_NOT_UP, /* WL UP failed */ - WL_OTA_SKIP_TEST_UNKNOWN_CALL /* Unintentional scheduling on ota test */ -}; - -/* Differentiator for ota_tx and ota_rx */ -enum { - WL_OTA_TEST_TX, /* ota_tx */ - WL_OTA_TEST_RX /* ota_rx */ -}; - -/* Catch 3 modes of operation: 20Mhz, 40Mhz, 20 in 40 Mhz */ -enum { - WL_OTA_TEST_BW_20_IN_40MHZ, /* 20 in 40 operation */ - WL_OTA_TEST_BW_20MHZ, /* 20 Mhz operation */ - WL_OTA_TEST_BW_40MHZ /* full 40Mhz operation */ -}; -typedef struct ota_rate_info { - uint8 rate_cnt; /* Total number of rates */ - uint8 rate_val_mbps[WL_OTA_TEST_MAX_NUM_RATE]; /* array of rates from 1mbps to 130mbps */ - /* for legacy rates : ratein mbps * 2 */ - /* for HT rates : mcs index */ -} ota_rate_info_t; - -typedef struct ota_power_info { - int8 pwr_ctrl_on; /* power control on/off */ - int8 start_pwr; /* starting power/index */ - int8 delta_pwr; /* delta power/index */ - int8 end_pwr; /* end power/index */ -} ota_power_info_t; - -typedef struct ota_packetengine { - uint16 delay; /* Inter-packet delay */ - /* for ota_tx, delay is tx ifs in micro seconds */ - /* for ota_rx, delay is wait time in milliseconds */ - uint16 nframes; /* Number of frames */ - uint16 length; /* Packet length */ -} ota_packetengine_t; - -/* Test info vector */ -typedef struct wl_ota_test_args { - uint8 cur_test; /* test phase */ - uint8 chan; /* channel */ - uint8 bw; /* bandwidth */ - char control_band; /* control band */ - uint8 stf_mode; /* stf mode */ - ota_rate_info_t rt_info; /* Rate info */ - ota_packetengine_t pkteng; /* packeteng info */ - uint8 txant; /* tx antenna */ - uint8 rxant; /* rx antenna */ - ota_power_info_t pwr_info; /* power sweep info */ - uint8 wait_for_sync; /* wait for sync or not */ -} wl_ota_test_args_t; - -typedef struct wl_ota_test_vector { - wl_ota_test_args_t test_arg[WL_OTA_TEST_MAX_NUM_SEQ]; /* Test argument struct */ - uint16 test_cnt; /* Total no of test */ - bool file_dwnld_valid; /* File successfully downloaded */ - uint8 sync_timeout; /* sync packet timeout */ - int8 sync_fail_action; /* sync fail action */ - struct ether_addr sync_mac; /* macaddress for sync pkt */ - struct ether_addr tx_mac; /* macaddress for tx */ - struct ether_addr rx_mac; /* macaddress for rx */ - int8 loop_test; /* dbg feature to loop the test */ -} wl_ota_test_vector_t; - - -/* struct copied back form dongle to host to query the status */ -typedef struct wl_ota_test_status { - int16 cur_test_cnt; /* test phase */ - int8 skip_test_reason; /* skip test reasoin */ - wl_ota_test_args_t test_arg; /* cur test arg details */ - uint16 test_cnt; /* total no of test downloaded */ - bool file_dwnld_valid; /* file successfully downloaded ? */ - uint8 sync_timeout; /* sync timeout */ - int8 sync_fail_action; /* sync fail action */ - struct ether_addr sync_mac; /* macaddress for sync pkt */ - struct ether_addr tx_mac; /* tx mac address */ - struct ether_addr rx_mac; /* rx mac address */ - uint8 test_stage; /* check the test status */ - int8 loop_test; /* Debug feature to puts test enfine in a loop */ - uint8 sync_status; /* sync status */ -} wl_ota_test_status_t; - -/* WL_OTA END */ - /* wl_radar_args_t */ typedef struct { int npulses; /* required number of pulses at n * t_int */ @@ -2352,168 +2190,168 @@ typedef struct { typedef struct txppr { /* start of 20MHz tx power limits */ - int8 b20_1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ - int8 b20_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */ - int8 b20_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */ - - int8 b20_1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ - int8 b20_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ - int8 b20_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */ - int8 b20_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ - int8 b20_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */ - - int8 b20_1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ - int8 b20_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ - int8 b20_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */ - int8 b20_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ - int8 b20_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */ - int8 b20_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */ - - int8 b20_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */ - int8 b20_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */ - int8 b20_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */ - int8 b20_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */ - int8 b20_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */ - int8 b20_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */ - int8 b20_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */ - int8 b20_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */ + 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 */ - int8 b40_dummy1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ - int8 b40_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */ - int8 b40_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */ - - int8 b40_dummy1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ - int8 b40_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ - int8 b40_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */ - int8 b40_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ - int8 b40_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */ - - int8 b40_dummy1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ - int8 b40_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ - int8 b40_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */ - int8 b40_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ - int8 b40_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */ - int8 b40_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */ - - int8 b40_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */ - int8 b40_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */ - int8 b40_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */ - int8 b40_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */ - int8 b40_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */ - int8 b40_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */ - int8 b40_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */ - int8 b40_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */ + 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 */ - int8 b20in40_1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ - int8 b20in40_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */ - int8 b20in40_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */ - - int8 b20in40_1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ - int8 b20in40_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ - int8 b20in40_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */ - int8 b20in40_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ - int8 b20in40_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */ - - int8 b20in40_1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ - int8 b20in40_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* 20 in 40 MHz Legacy OFDM CDD */ - int8 b20in40_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */ - int8 b20in40_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ - int8 b20in40_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */ - int8 b20in40_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */ - - int8 b20in40_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */ - int8 b20in40_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */ - int8 b20in40_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */ - int8 b20in40_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */ - int8 b20in40_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */ - int8 b20in40_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */ - int8 b20in40_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */ - int8 b20in40_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */ + 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 */ - int8 b80_dummy1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ - int8 b80_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */ - int8 b80_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */ - - int8 b80_dummy1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ - int8 b80_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ - int8 b80_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */ - int8 b80_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ - int8 b80_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */ - - int8 b80_dummy1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ - int8 b80_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ - int8 b80_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */ - int8 b80_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ - int8 b80_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */ - int8 b80_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */ - - int8 b80_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */ - int8 b80_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */ - int8 b80_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */ - int8 b80_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */ - int8 b80_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */ - int8 b80_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */ - int8 b80_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */ - int8 b80_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */ + 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 */ - int8 b20in80_1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ - int8 b20in80_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */ - int8 b20in80_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */ - - int8 b20in80_1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ - int8 b20in80_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ - int8 b20in80_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */ - int8 b20in80_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ - int8 b20in80_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */ - - int8 b20in80_1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ - int8 b20in80_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ - int8 b20in80_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */ - int8 b20in80_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ - int8 b20in80_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */ - int8 b20in80_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */ - - int8 b20in80_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */ - int8 b20in80_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */ - int8 b20in80_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */ - int8 b20in80_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */ - int8 b20in80_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */ - int8 b20in80_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */ - int8 b20in80_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */ - int8 b20in80_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */ + 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 */ - int8 b40in80_dummy1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ - int8 b40in80_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */ - int8 b40in80_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */ - - int8 b40in80_dummy1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ - int8 b40in80_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ - int8 b40in80_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */ - int8 b40in80_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ - int8 b40in80_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */ - - int8 b40in80_dummy1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ - int8 b40in80_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* MHz Legacy OFDM CDD */ - int8 b40in80_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */ - int8 b40in80_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ - int8 b40in80_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */ - int8 b40in80_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */ - - int8 b40in80_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */ - int8 b40in80_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */ - int8 b40in80_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */ - int8 b40in80_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */ - int8 b40in80_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */ - int8 b40in80_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */ - int8 b40in80_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */ - int8 b40in80_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */ + 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 */ - int8 mcs32; /* C_CHECK - THIS NEEDS TO BE REMOVED THROUGHOUT THE CODE */ + uint8 mcs32; /* C_CHECK - THIS NEEDS TO BE REMOVED THROUGHOUT THE CODE */ } txppr_t; /* 20MHz */ @@ -2695,35 +2533,45 @@ typedef struct txppr { #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 */ - uint32 buflen; /* ppr buffer length */ - uint8 pprbuf[1]; /* Latest target power buffer */ + uint8 ppr[WL_TX_POWER_RATES]; /* Latest target power */ } wl_txppr_t; #define WL_TXPPR_VERSION 0 #define WL_TXPPR_LENGTH (sizeof(wl_txppr_t)) -#define TX_POWER_T_VERSION 44 +#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 -#define WL_BW_160MHZ 3 /* tx_power_t.flags bits */ -/* use for defined PPR_API */ +#ifdef PPR_API +#define WL_TX_POWER2_F_ENABLED 1 +#define WL_TX_POWER2_F_HW 2 +#define WL_TX_POWER2_F_MIMO 4 +#define WL_TX_POWER2_F_SISO 8 +#define WL_TX_POWER2_F_HT 0x10 +#else #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 -#define WL_TX_POWER_F_VHT 0x20 - +#endif typedef struct { uint32 flags; chanspec_t chanspec; /* txpwr report for this channel */ @@ -2733,7 +2581,9 @@ typedef struct { 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 w/o adjustment */ + 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 */ @@ -2747,10 +2597,11 @@ typedef struct { int8 channel_bandwidth; /* 20, 40 or 80 MHz bandwidth? */ uint8 version; /* Version of the data format wlu <--> driver */ uint8 display_core; /* Displayed curpower core */ - int8 target_offsets[4]; /* Target power offsets for current rate per core */ - uint32 last_tx_ratespec; /* Ratespec for last transmition */ - int8 SARLIMIT[MAX_STREAMS_SUPPORTED]; +#ifdef PPR_API +} tx_power_new_t; +#else } tx_power_t; +#endif typedef struct tx_inst_power { uint8 txpwr_est_Pout[2]; /* Latest estimate for 2.4 and 5 Ghz */ @@ -2893,20 +2744,7 @@ typedef struct wl_txchain_pwr_offsets { #define WL_PSTA_VAL 0x00008000 #define WL_TBTT_VAL 0x00010000 #define WL_NIC_VAL 0x00020000 -#define WL_PWRSEL_VAL 0x00040000 -#define WL_TRF_MGMT_VAL 0x00080000 -#define WL_L2FILTER_VAL 0x00100000 -#define WL_TSO_VAL 0x00200000 -#define WL_MQ_VAL 0x00400000 -/* These 3 levels are currently not used in trunk but in Aardvark and Phoenix2 with != values */ -#define WL_LPC_VAL 0x00800000 -#define WL_TXBF_VAL 0x01000000 -#define WL_P2PO_VAL 0x02000000 -/* This level is synchronized with other branches */ -#define WL_WNM_VAL 0x04000000 -/* This level is currently not used in trunk but used in Phoenix2 */ -#define WL_SRSCAN_VAL 0x08000000 - +#define WL_PWRSEL_VAL 0x00040000 /* use top-bit for WL_TIME_STAMP_VAL because this is a modifier * rather than a message-type of its own */ @@ -2939,9 +2777,7 @@ typedef struct wl_txchain_pwr_offsets { #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_W6 22 /* off upon boot, could be turned on later */ -#define WL_LED_WI7 23 /* off upon boot, could be turned on later */ -#define WL_LED_NUMBEHAVIOR 24 +#define WL_LED_NUMBEHAVIOR 22 /* led behavior numeric value format */ #define WL_LED_BEH_MASK 0x7f /* behavior mask */ @@ -2999,7 +2835,7 @@ typedef struct wl_txchain_pwr_offsets { * * 4. BAND RSSI - 2 octets * offset 0: band types - * offset 1: +ve RSSI boost value in dB + * offset 1: +ve RSSI boost balue in dB */ /* join preference types */ @@ -3263,12 +3099,6 @@ typedef struct { uint32 pstatxbcmc; /* count of bcmc frames transmitted on all psta */ uint32 cso_passthrough; /* hw cso required but passthrough */ - uint32 chained; /* number of frames chained */ - uint32 chainedsz1; /* number of chain size 1 frames */ - uint32 unchained; /* number of frames not chained */ - uint32 maxchainsz; /* max chain size so far */ - uint32 currchainsz; /* current chain size */ - uint32 cso_normal; /* hw cso hdr for normal process */ } wl_cnt_t; #ifndef LINUX_POSTMOGRIFY_REMOVAL @@ -3709,14 +3539,13 @@ struct tslist { #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_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 */ -#define TDLS_MANUAL_EP_WFD_TPQ 8 /* WiFi-Display Tunneled Probe reQuest */ /* structure for tdls iovars */ typedef struct tdls_iovar { @@ -3727,16 +3556,14 @@ typedef struct tdls_iovar { } tdls_iovar_t; /* modes */ -#define TDLS_WFD_IE_TX 0 -#define TDLS_WFD_IE_RX 1 -#define TDLS_WFD_PROBE_IE_TX 2 -#define TDLS_WFD_PROBE_IE_RX 3 -#define TDLS_WFD_IE_SIZE 512 +#define TDLS_WFD_IE_TX 0 +#define TDLS_WFD_IE_RX 1 +#define TDLS_WFD_IE_SIZE 255 /* structure for tdls wfd ie */ typedef struct tdls_wfd_ie_iovar { struct ether_addr ea; /* Station address */ uint8 mode; - uint16 length; + uint8 length; uint8 data[TDLS_WFD_IE_SIZE]; } tdls_wfd_ie_iovar_t; #endif /* WLTDLS */ @@ -3799,11 +3626,11 @@ typedef struct wme_max_bandwidth { /* 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 */ +#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_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 */ @@ -3868,13 +3695,11 @@ enum { #define ENABLE_ADAPTSCAN_BIT 6 #define IMMEDIATE_EVENT_BIT 8 #define SUPPRESS_SSID_BIT 9 -#define ENABLE_NET_OFFLOAD_BIT 10 -/* report found/lost events for SSID and BSSID networks seperately */ -#define REPORT_SEPERATELY_BIT 11 +#define ENABLE_NET_OFFLOAD_BIT 10 #define SORT_CRITERIA_MASK 0x0001 -#define AUTO_NET_SWITCH_MASK 0x0002 -#define ENABLE_BKGRD_SCAN_MASK 0x0004 +#define AUTO_NET_SWITCH_MASK 0x0002 +#define ENABLE_BKGRD_SCAN_MASK 0x0004 #define IMMEDIATE_SCAN_MASK 0x0008 #define AUTO_CONNECT_MASK 0x0010 @@ -3883,10 +3708,8 @@ enum { #define IMMEDIATE_EVENT_MASK 0x0100 #define SUPPRESS_SSID_MASK 0x0200 #define ENABLE_NET_OFFLOAD_MASK 0x0400 -/* report found/lost events for SSID and BSSID networks seperately */ -#define REPORT_SEPERATELY_MASK 0x0800 -#define PFN_VERSION 2 +#define PFN_VERSION 2 #define PFN_SCANRESULT_VERSION 1 #define MAX_PFN_LIST_COUNT 16 @@ -3896,10 +3719,7 @@ enum { #define DEFAULT_BESTN 2 #define DEFAULT_MSCAN 0 #define DEFAULT_REPEAT 10 -#define DEFAULT_EXP 2 - -#define PFN_PARTIAL_SCAN_BIT 0 -#define PFN_PARTIAL_SCAN_MASK 1 +#define DEFAULT_EXP 2 /* PFN network info structure */ typedef struct wl_pfn_subnet_info { @@ -3915,22 +3735,6 @@ typedef struct wl_pfn_net_info { uint16 timestamp; /* age in seconds */ } wl_pfn_net_info_t; -typedef struct wl_pfn_lnet_info { - wl_pfn_subnet_info_t pfnsubnet; /* BSSID + channel + SSID len + SSID */ - uint16 flags; /* partial scan, etc */ - int16 RSSI; /* receive signal strength (in dBm) */ - uint32 timestamp; /* age in miliseconds */ - uint16 rtt0; /* estimated distance to this AP in centimeters */ - uint16 rtt1; /* standard deviation of the distance to this AP in centimeters */ -} wl_pfn_lnet_info_t; - -typedef struct wl_pfn_lscanresults { - uint32 version; - uint32 status; - uint32 count; - wl_pfn_lnet_info_t netinfo[1]; -} wl_pfn_lscanresults_t; - typedef struct wl_pfn_scanresults { uint32 version; uint32 status; @@ -3943,127 +3747,57 @@ typedef struct wl_pfn_param { int32 version; /* PNO parameters version */ int32 scan_freq; /* Scan frequency */ int32 lost_network_timeout; /* Timeout in sec. to declare - * discovered network as lost - */ + * discovered network as lost + */ int16 flags; /* Bit field to control features - * of PFN such as sort criteria auto - * enable switch and background scan - */ + * 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 */ + * 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; + struct ether_addr macaddr; /* Bit4: suppress_lost, Bit3: suppress_found */ - uint16 flags; + uint16 flags; } wl_pfn_bssid_t; #define WL_PFN_SUPPRESSFOUND_MASK 0x08 #define WL_PFN_SUPPRESSLOST_MASK 0x10 -#define WL_PFN_RSSI_MASK 0xff00 -#define WL_PFN_RSSI_SHIFT 8 typedef struct wl_pfn_cfg { - uint32 reporttype; - int32 channel_num; - uint16 channel_list[WL_NUMCHANNELS]; - uint32 flags; + uint32 reporttype; + int32 channel_num; + uint16 channel_list[WL_NUMCHANNELS]; } wl_pfn_cfg_t; -#define WL_PFN_REPORT_ALLNET 0 -#define WL_PFN_REPORT_SSIDNET 1 -#define WL_PFN_REPORT_BSSIDNET 2 - -#define WL_PFN_CFG_FLAGS_PROHIBITED 0x00000001 /* Accept and use prohibited channels */ -#define WL_PFN_CFG_FLAGS_RESERVED 0xfffffffe /* Remaining reserved for future use */ +#define WL_PFN_REPORT_ALLNET 0 +#define WL_PFN_REPORT_SSIDNET 1 +#define WL_PFN_REPORT_BSSIDNET 2 typedef struct wl_pfn { - 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 */ + 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; -typedef struct wl_pfn_list { - uint32 version; - uint32 enabled; - uint32 count; - wl_pfn_t pfn[1]; -} wl_pfn_list_t; -#define WL_PFN_HIDDEN_BIT 2 +#define WL_PFN_HIDDEN_BIT 2 #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 -#ifndef BESTN_MAX -#define BESTN_MAX 3 -#endif - -#ifndef MSCAN_MAX -#define MSCAN_MAX 90 -#endif +#define PNO_SCAN_MIN_FW_SEC 10 /* min time scan time in SEC */ +#define WL_PFN_HIDDEN_MASK 0x4 #endif /* LINUX_POSTMOGRIFY_REMOVAL */ -/* Service discovery */ -typedef struct { - uint8 transaction_id; /* Transaction id */ - uint8 protocol; /* Service protocol type */ - uint16 query_len; /* Length of query */ - uint16 response_len; /* Length of response */ - uint8 qrbuf[1]; -} wl_p2po_qr_t; - -typedef struct { - uint16 period; /* extended listen period */ - uint16 interval; /* extended listen interval */ -} wl_p2po_listen_t; - -/* ANQP offload */ - -#define ANQPO_MAX_QUERY_SIZE 256 -typedef struct { - uint16 max_retransmit; /* -1 use default, max retransmit on no ACK from peer */ - uint16 response_timeout; /* -1 use default, msec to wait for resp after tx packet */ - uint16 max_comeback_delay; /* -1 use default, max comeback delay in resp else fail */ - uint16 max_retries; /* -1 use default, max retries on failure */ - uint16 query_len; /* length of ANQP query */ - uint8 query_data[1]; /* ANQP encoded query (max ANQPO_MAX_QUERY_SIZE) */ -} wl_anqpo_set_t; - -typedef struct { - uint16 channel; /* channel of the peer */ - struct ether_addr addr; /* addr of the peer */ -} wl_anqpo_peer_t; - -#define ANQPO_MAX_PEER_LIST 64 -typedef struct { - uint16 count; /* number of peers in list */ - wl_anqpo_peer_t peer[1]; /* max ANQPO_MAX_PEER_LIST */ -} wl_anqpo_peer_list_t; - -#define ANQPO_MAX_IGNORE_SSID 64 -typedef struct { - bool is_clear; /* set to clear list (not used on GET) */ - uint16 count; /* number of SSID in list */ - wlc_ssid_t ssid[1]; /* max ANQPO_MAX_IGNORE_SSID */ -} wl_anqpo_ignore_ssid_list_t; - -#define ANQPO_MAX_IGNORE_BSSID 64 -typedef struct { - bool is_clear; /* set to clear list (not used on GET) */ - uint16 count; /* number of addr in list */ - struct ether_addr bssid[1]; /* max ANQPO_MAX_IGNORE_BSSID */ -} wl_anqpo_ignore_bssid_list_t; - /* TCP Checksum Offload defines */ #define TOE_TX_CSUM_OL 0x00000001 #define TOE_RX_CSUM_OL 0x00000002 @@ -4116,7 +3850,7 @@ struct toe_ol_stats_t { #define ARP_ERRTEST_REPLY_HOST 0x2 #define ARP_MULTIHOMING_MAX 8 /* Maximum local host IP addresses */ -#define ND_MULTIHOMING_MAX 10 /* Maximum local host IP addresses */ +#define ND_MULTIHOMING_MAX 8 /* Maximum local host IP addresses */ /* Arp offload statistic counts */ struct arp_ol_stats_t { @@ -4224,15 +3958,6 @@ typedef struct wl_pkt_filter_stats { uint32 num_pkts_discarded; /* # packets discarded by dongle for all filters */ } wl_pkt_filter_stats_t; -#define RSN_KCK_LENGTH 16 -#define RSN_KEK_LENGTH 16 -#define RSN_REPLAY_LEN 8 -typedef struct _gtkrefresh { - uchar KCK[RSN_KCK_LENGTH]; - uchar KEK[RSN_KEK_LENGTH]; - uchar ReplayCounter[RSN_REPLAY_LEN]; -} gtk_keyinfo_t, *pgtk_keyinfo_t; - /* Sequential Commands ioctl */ typedef struct wl_seq_cmd_ioctl { uint32 cmd; /* common ioctl definition */ @@ -4265,8 +3990,6 @@ typedef struct wl_seq_cmd_ioctl { #define WL_PKTENG_SYNCHRONOUS 0x100 /* synchronous flag */ -#define WL_PKTENG_MAXPKTSZ 16384 /* max pktsz limit for pkteng */ - typedef struct wl_pkteng { uint32 flags; uint32 delay; /* Inter-packet delay */ @@ -4286,7 +4009,6 @@ typedef struct wl_pkteng_stats { int32 rssi; /* RSSI */ int32 snr; /* signal to noise ratio */ uint16 rxpktcnt[NUM_80211_RATES+1]; - uint8 rssi_qdb; /* qdB portion of the computed rssi */ } wl_pkteng_stats_t; @@ -4310,14 +4032,14 @@ typedef struct wl_pkteng_stats { #define MAGIC_PKT_MINLEN 102 /* Magic pkt min length is 6 * 0xFF + 16 * ETHER_ADDR_LEN */ #define WOWL_PATTEN_TYPE_ARP (1 << 0) /* ARP offload Pattern */ -#define WOWL_PATTEN_TYPE_NA (1 << 1) /* NA offload Pattern */ +#define WOWL_PATTEN_TYPE_NA (1 << 1) /* NA offload Pattern */ typedef struct { uint32 masksize; /* Size of the mask in #of bytes */ uint32 offset; /* Offset to start looking for the packet in # of bytes */ - uint32 patternoffset; /* Offset of start of pattern in the structure */ + uint32 patternoffset; /* Offset of start of pattern in the structure */ uint32 patternsize; /* Size of the pattern itself in #of bytes */ - uint32 id; /* id */ + uint32 id; /* id */ uint32 reasonsize; /* Size of the wakeup reason code */ uint32 flags; /* Flags to tell the pattern type and other properties */ /* Mask follows the structure above */ @@ -4451,37 +4173,6 @@ typedef struct { uint32 queue_capacity; /* the maximum capacity of the queue */ } pktq_log_counters_v01_t; -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 */ - uint32 rtsfail; /* count of rts attempts that failed to receive cts */ - uint32 acked; /* count of packets sent (acked) successfully */ -} pktq_log_counters_v02_t; - #define sacrified sacrificed typedef struct { @@ -4490,21 +4181,12 @@ typedef struct { char headings[1]; } pktq_log_format_v01_t; -typedef struct { - uint8 num_prec[WL_IOV_MAC_PARAM_LEN]; - pktq_log_counters_v02_t counters[WL_IOV_MAC_PARAM_LEN][WL_IOV_PKTQ_LOG_PRECS]; - uint32 throughput[WL_IOV_MAC_PARAM_LEN][WL_IOV_PKTQ_LOG_PRECS]; - uint32 time_delta; - char headings[1]; -} pktq_log_format_v02_t; - typedef struct { uint32 version; wl_iov_mac_params_t params; union { pktq_log_format_v01_t v01; - pktq_log_format_v02_t v02; } pktq_log; } wl_iov_pktq_log_t; @@ -4662,21 +4344,6 @@ typedef struct { #define VNDR_IE_IWAPID_FLAG 0x40 /* vendor IE in IW advertisement protocol ID field */ #define VNDR_IE_CUSTOM_FLAG 0x100 /* allow custom IE id */ -#if defined(WLP2P) -/* P2P Action Frames flags (spec ordered) */ -#define VNDR_IE_GONREQ_FLAG 0x001000 -#define VNDR_IE_GONRSP_FLAG 0x002000 -#define VNDR_IE_GONCFM_FLAG 0x004000 -#define VNDR_IE_INVREQ_FLAG 0x008000 -#define VNDR_IE_INVRSP_FLAG 0x010000 -#define VNDR_IE_DISREQ_FLAG 0x020000 -#define VNDR_IE_DISRSP_FLAG 0x040000 -#define VNDR_IE_PRDREQ_FLAG 0x080000 -#define VNDR_IE_PRDRSP_FLAG 0x100000 - -#define VNDR_IE_P2PAF_SHIFT 12 -#endif /* WLP2P */ - #define VNDR_IE_INFO_HDR_LEN (sizeof(uint32)) typedef BWL_PRE_PACKED_STRUCT struct { @@ -4751,40 +4418,26 @@ typedef BWL_PRE_PACKED_STRUCT struct { } BWL_POST_PACKED_STRUCT txfailinfo_t; #endif /* WLMEDIA_TXFAILEVENT */ -typedef BWL_PRE_PACKED_STRUCT 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 w/o 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 */ - int8 clm_limits[WL_NUMRATES]; /* regulatory limits - 20, 40 or 80MHz */ - int8 clm_limits_subchan1[WL_NUMRATES]; /* regulatory limits - 20in40 or 40in80 */ - int8 clm_limits_subchan2[WL_NUMRATES]; /* 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 */ - uint8 display_core; /* Displayed curpower core */ - int8 target_offsets[4]; /* Target power offsets for current rate per core */ - uint32 last_tx_ratespec; /* Ratespec for last transmition */ - uint user_target; /* user limit */ - uint32 board_limit_len; /* length of board limit buffer */ - uint32 target_len; /* length of target power buffer */ - int8 SARLIMIT[MAX_STREAMS_SUPPORTED]; - uint8 pprdata[1]; /* ppr serialization buffer */ -} BWL_POST_PACKED_STRUCT tx_pwr_rpt_t; - #endif /* LINUX_POSTMOGRIFY_REMOVAL */ /* no strict structure packing */ #include +#ifdef BCMWAPI_WAI +#define IV_LEN 16 /* XXX, same as SMS4_WPI_PN_LEN */ +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 */ + #ifndef LINUX_POSTMOGRIFY_REMOVAL /* Global ASSERT Logging */ #define ASSERTLOG_CUR_VER 0x0100 @@ -4818,12 +4471,10 @@ typedef struct assertlog_results { /* define for apcs reason code */ #define APCS_INIT 0 -#define APCS_IOCTL 1 -#define APCS_CHANIM 2 +#define APCS_IOCTL 1 +#define APCS_CHANIM 2 #define APCS_CSTIMER 3 #define APCS_BTA 4 -#define APCS_TXDLY 5 -#define APCS_NONACSD 6 /* number of ACS record entries */ #define CHANIM_ACS_RECORD 10 @@ -5095,9 +4746,7 @@ typedef struct wl_nic_cnx { uint8 SSID_len; uint8 SSID[32]; struct ether_addr abssid; - uint16 beacon_interval; - uint16 sync_threshold; - uint16 beacon_wait_time; + uint8 join_period; } wl_nic_cnx_t; /* opcode */ @@ -5111,23 +4760,16 @@ typedef struct wl_nic_cnx { typedef struct wl_nic_cfg { uint8 version; uint8 beacon_mode; + uint16 beacon_interval; uint8 diluted_beacon_period; - uint8 beacon_probability; - uint8 num_awake_window_params; - struct { - uint8 channel_number; - uint8 awake_window_length; - uint8 repeat_EQC; - } awake_window_params[3]; + 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; - uint8 CWmin_af; - uint8 NIC_priority; - uint8 NIC_data_ind; - uint8 allowed_wakeup_delay; } wl_nic_cfg_t; /* version */ @@ -5149,6 +4791,7 @@ typedef struct wl_nic_frm { } wl_nic_frm_t; /* type */ +#define WL_NIC_FRM_MYNET 1 #define WL_NIC_FRM_ACTION 2 /* i/f query */ @@ -5161,17 +4804,8 @@ typedef struct wl_nic_ifq { /* nic_dm iovar */ typedef struct wl_nic_dm { uint8 enab; - uint8 rsvd; - /* the following fields are valid when enabling... */ chanspec_t chspec; - uint8 DATA_priority; - uint8 NIC_priority; } wl_nic_dm_t; - -/* immediate scan request */ -typedef struct wl_nic_isq { - uint8 scan_length; -} wl_nic_isq_t; #endif /* WLNIC */ /* RFAWARE def */ @@ -5316,13 +4950,6 @@ enum { SPATIAL_MODE_MAX_IDX }; -#define WLC_TXCORE_MAX 4 /* max number of txcore supports */ -#define WLC_SUBBAND_MAX 4 /* max number of sub-band supports */ -typedef struct { - uint8 band2g[WLC_TXCORE_MAX]; - uint8 band5g[WLC_SUBBAND_MAX][WLC_TXCORE_MAX]; -} sar_limit_t; - /* IOVAR "mempool" parameter. Used to retrieve a list of memory pool statistics. */ typedef struct wl_mempool_stats { int num; /* Number of memory pools */ @@ -5358,23 +4985,15 @@ typedef struct { #define TRF_MGMT_MAX_PRIORITIES 3 #define TRF_MGMT_FLAG_ADD_DSCP 0x0001 /* Add DSCP to IP TOS field */ -#define TRF_MGMT_FLAG_DISABLE_SHAPING 0x0002 /* Don't shape traffic */ -#define TRF_MGMT_FLAG_MANAGE_LOCAL_TRAFFIC 0x0008 /* Manage traffic over our local subnet */ -#define TRF_MGMT_FLAG_FILTER_ON_MACADDR 0x0010 /* filter on MAC address */ -#define TRF_MGMT_FLAG_NO_RX 0x0020 /* do not apply fiters to rx packets */ - -#define TRF_FILTER_MAC_ADDR 0x0001 /* L2 filter use dst mac address for filtering */ -#define TRF_FILTER_IP_ADDR 0x0002 /* L3 filter use ip ddress for filtering */ -#define TRF_FILTER_L4 0x0004 /* L4 filter use tcp/udp for filtering */ -#define TRF_FILTER_FAVORED 0x0010 /* Tag the packet FAVORED */ +#define TRF_MGMT_FLAG_DISABLE_SHAPING 0x0002 /* Only support traffic clasification */ +#define TRF_MGMT_FLAG_DISABLE_PRIORITY_TAGGING 0x0004 /* Don't override packet's priority */ /* Traffic management priority classes */ typedef enum trf_mgmt_priority_class { - trf_mgmt_priority_low = 0, /* Maps to 802.1p BK */ - trf_mgmt_priority_medium = 1, /* Maps to 802.1p BE */ - trf_mgmt_priority_high = 2, /* Maps to 802.1p VI */ - trf_mgmt_priority_nochange = 3, /* do not update the priority */ - trf_mgmt_priority_invalid = (trf_mgmt_priority_nochange + 1) + trf_mgmt_priority_low = 0, /* Maps to 802.1p BO */ + trf_mgmt_priority_medium = 1, /* Maps to 802.1p BE */ + trf_mgmt_priority_high = 2, /* Maps to 802.1p VI */ + trf_mgmt_priority_invalid = (trf_mgmt_priority_high + 1) } trf_mgmt_priority_class_t; /* Traffic management configuration parameters */ @@ -5456,163 +5075,5 @@ typedef struct powersel_params { uint8 pwr_sel_exp_time; /* Time lapse for expiry of database */ } powersel_params_t; -/* tx pkt delay statistics */ -#define SCB_RETRY_SHORT_DEF 7 /* Default Short retry Limit */ -#define WLPKTDLY_HIST_NBINS 16 /* number of bins used in the Delay histogram */ - -/* structure to store per-AC delay statistics */ -typedef struct scb_delay_stats { - uint32 txmpdu_lost; /* number of MPDUs lost */ - uint32 txmpdu_cnt[SCB_RETRY_SHORT_DEF]; /* retry times histogram */ - uint32 delay_sum[SCB_RETRY_SHORT_DEF]; /* cumulative packet latency */ - uint32 delay_min; /* minimum packet latency observed */ - uint32 delay_max; /* maximum packet latency observed */ - uint32 delay_avg; /* packet latency average */ - uint32 delay_hist[WLPKTDLY_HIST_NBINS]; /* delay histogram */ -} scb_delay_stats_t; - -/* structure for txdelay event */ -typedef struct txdelay_event { - uint8 status; - int rssi; - chanim_stats_t chanim_stats; - scb_delay_stats_t delay_stats[AC_COUNT]; -} txdelay_event_t; - -/* structure for txdelay parameters */ -typedef struct txdelay_params { - uint16 ratio; /* Avg Txdelay Delta */ - uint8 cnt; /* Sample cnt */ - uint8 period; /* Sample period */ - uint8 tune; /* Debug */ -} txdelay_params_t; - -#define WL_RELMCAST_MAX_CLIENT 32 -#define WL_RELMCAST_FLAG_INBLACKLIST 1 -#define WL_RELMCAST_FLAG_ACTIVEACKER 2 -#define WL_RELMCAST_FLAG_RELMCAST 4 -#define WL_RELMCAST_MAX_TABLE_ENTRY 4 - -#define WL_RELMCAST_VER 1 -#define WL_RELMCAST_INDEX_ACK_ALL 255 -#define WL_RELMCAST_NUM_OF_MC_STREAMS 4 -#define WL_RELMCAST_MAX_TRS_PER_GROUP 1 -#define WL_RELMCAST_ACK_MCAST0 0x02 -#define WL_RELMCAST_ACK_MCAST_ALL 0x01 -#define WL_RELMCAST_ACTF_TIME_MIN 300 /* time in ms */ -#define WL_RELMCAST_ACTF_TIME_MAX 20000 /* time in ms */ - -enum { - RELMCAST_ENTRY_OP_DISABLE = 0, - RELMCAST_ENTRY_OP_DELETE, - RELMCAST_ENTRY_OP_ENABLE, - RELMCAST_ENTRY_OP_ACK_ALL -}; - -enum { - WL_RELMCAST_MODE_RECEIVER = 0, - WL_RELMCAST_MODE_TRANSMITTER, - WL_RELMCAST_MODE_INITIATOR -}; - -typedef struct wl_relmcast_client { - uint8 flag; - int16 rssi; - struct ether_addr addr; -} wl_relmcast_client_t; - -typedef struct wl_relmcast_st { - uint8 ver; - uint8 num; - wl_relmcast_client_t clients[WL_RELMCAST_MAX_CLIENT]; - uint16 err; -} wl_relmcast_status_t; - -typedef struct wl_relmcast_entry { - int8 flag; - struct ether_addr addr; -} wl_relmcast_entry_t; - -typedef struct wl_relmcast_entry_table { - int8 index; - int8 opcode; - wl_relmcast_entry_t entry[WL_RELMCAST_MAX_TABLE_ENTRY]; -} wl_relmcast_entry_table_t; - -typedef struct wl_tr_Info { - struct ether_addr addr; - uint32 timeVal; - uint16 seq; -} wl_tr_Info_t; - -typedef struct wl_mcGrpEntry { - struct ether_addr mcaddr; - struct ether_addr ar; - wl_tr_Info_t trInfo[WL_RELMCAST_MAX_TRS_PER_GROUP]; -} wl_mcGrpEntry_t; - -typedef struct wl_mcAckAllEntry { - struct ether_addr ar; - wl_tr_Info_t trInfo[WL_RELMCAST_NUM_OF_MC_STREAMS]; -} wl_mcAckAllEntry_t; - -typedef struct wl_relmcast_globalMcTbl { - uint8 activeMask; - wl_mcAckAllEntry_t ackAll; - wl_mcGrpEntry_t mcEntry[WL_RELMCAST_NUM_OF_MC_STREAMS]; -} wl_relmcast_globalMcTbl_t; #endif /* LINUX_POSTMOGRIFY_REMOVAL */ - -/* fbt_cap: FBT assoc / reassoc modes. */ -#define WLC_FBT_CAP_DRV_4WAY_AND_REASSOC 1 /* Driver 4-way handshake & reassoc (WLFBT). */ - -typedef struct bcnreq { - uint8 bcn_mode; - int dur; - int channel; - struct ether_addr da; - uint16 random_int; - wlc_ssid_t ssid; - uint16 reps; -} bcnreq_t; - -typedef struct rrmreq { - struct ether_addr da; - uint8 reg; - uint8 chan; - uint16 random_int; - uint16 dur; - uint16 reps; -} rrmreq_t; - -typedef struct framereq { - struct ether_addr da; - uint8 reg; - uint8 chan; - uint16 random_int; - uint16 dur; - struct ether_addr ta; - uint16 reps; -} framereq_t; - -typedef struct statreq { - struct ether_addr da; - struct ether_addr peer; - uint16 random_int; - uint16 dur; - uint8 group_id; - uint16 reps; -} statreq_t; - -typedef struct wl_el_set_params_s { - uint8 set; /* Set number */ - uint32 size; /* Size to make/expand */ -} wl_el_set_params_t; - -typedef struct wl_el_tag_params_s { - uint16 tag; - uint8 set; - uint8 flags; -} wl_el_tag_params_t; - #endif /* _wlioctl_h_ */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/Kconfig linux-sunxi-new/drivers/net/wireless/bcmdhd/Kconfig --- linux-sunxi/drivers/net/wireless/bcmdhd/Kconfig 2014-01-27 01:30:30.100433249 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/Kconfig 2014-02-15 00:43:44.791014047 +0100 @@ -1,33 +1,22 @@ config BCMDHD tristate "Broadcom 4329/30 wireless cards support" depends on MMC + default n ---help--- This module adds support for wireless adapters based on Broadcom 4329/30 chipset. - This driver uses the kernel's wireless extensions subsystem. - - If you choose to build a module, it'll be called dhd. Say M if - unsure. - -config BCM4339 - tristate "Broadcom 4339 wireless cards support" - depends on BCMDHD - ---help--- - This module adds support for wireless adapters based on - Broadcom 4339 chipset. - config BCMDHD_FW_PATH depends on BCMDHD string "Firmware path" - default "/system/etc/firmware/fw_bcmdhd.bin" + default "/system/vendor/modules/fw_bcmxxxx.bin" ---help--- Path to the firmware file. config BCMDHD_NVRAM_PATH depends on BCMDHD string "NVRAM path" - default "/system/etc/wifi/bcmdhd.cal" + default "/system/vendor/modules/nvram_apxxxx.txt" ---help--- Path to the calibration file. @@ -39,16 +28,18 @@ config BCMDHD_WEXT help Enables WEXT support -config DHD_USE_STATIC_BUF - bool "Enable memory preallocation" +choice + depends on BCMDHD + prompt "Interrupt type" +config BCMDHD_OOB depends on BCMDHD - default n + bool "Out-of-Band Interrupt" ---help--- - Use memory preallocated in platform - -config DHD_USE_SCHED_SCAN - bool "Use CFG80211 sched scan" - depends on BCMDHD && CFG80211 - default n + Interrupt through WL_HOST_WAKE. +config BCMDHD_SDIO_IRQ + depends on BCMDHD + bool "In-Band Interrupt" + default y ---help--- - Use CFG80211 sched scan + Interrupt through SDIO DAT[1] +endchoice diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/linux_osl.c linux-sunxi-new/drivers/net/wireless/bcmdhd/linux_osl.c --- linux-sunxi/drivers/net/wireless/bcmdhd/linux_osl.c 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/linux_osl.c 2014-02-15 00:43:44.795014136 +0100 @@ -1,7 +1,7 @@ /* * Linux OS Independent Layer * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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: linux_osl.c 412994 2013-07-17 12:38:03Z $ + * $Id: linux_osl.c 373382 2012-12-07 07:59:52Z $ */ #define LINUX_PORT @@ -36,7 +36,6 @@ #include - #include #define PCI_CFG_RETRY 10 @@ -101,29 +100,13 @@ struct osl_info { uint magic; void *pdev; atomic_t malloced; - atomic_t pktalloced; /* Number of allocated packet buffers */ uint failed; uint bustype; bcm_mem_link_t *dbgmem_list; spinlock_t dbgmem_lock; -#ifdef BCMDBG_CTRACE - spinlock_t ctrace_lock; - struct list_head ctrace_list; - int ctrace_num; -#endif /* BCMDBG_CTRACE */ spinlock_t pktalloc_lock; }; -#define OSL_PKTTAG_CLEAR(p) \ -do { \ - struct sk_buff *s = (struct sk_buff *)(p); \ - ASSERT(OSL_PKTTAG_SZ == 32); \ - *(uint32 *)(&s->cb[0]) = 0; *(uint32 *)(&s->cb[4]) = 0; \ - *(uint32 *)(&s->cb[8]) = 0; *(uint32 *)(&s->cb[12]) = 0; \ - *(uint32 *)(&s->cb[16]) = 0; *(uint32 *)(&s->cb[20]) = 0; \ - *(uint32 *)(&s->cb[24]) = 0; *(uint32 *)(&s->cb[28]) = 0; \ -} while (0) - /* PCMCIA attribute space access macros */ /* Global ASSERT type flag */ @@ -173,14 +156,15 @@ static int16 linuxbcmerrormap[] = -ENODEV, /* BCME_NODEVICE */ -EINVAL, /* BCME_NMODE_DISABLED */ -ENODATA, /* BCME_NONRESIDENT */ - -EINVAL, /* BCME_SCANREJECT */ - -EINVAL, /* BCME_USAGE_ERROR */ - -EIO, /* BCME_IOCTL_ERROR */ - -EIO, /* BCME_SERIAL_PORT_ERR */ /* When an new error code is added to bcmutils.h, add os * specific error translation here as well */ +/* check if BCME_LAST changed since the last time this function was updated */ +#if BCME_LAST != -42 +#error "You need to add a OS error translation in the linuxbcmerrormap \ + for new error code defined in bcmutils.h" +#endif }; /* translate bcmerrors into linux errors */ @@ -202,14 +186,8 @@ osl_t * osl_attach(void *pdev, uint bustype, bool pkttag) { osl_t *osh; - gfp_t flags; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) - flags = (in_atomic() || irqs_disabled()) ? GFP_ATOMIC : GFP_KERNEL; -#else - flags = GFP_ATOMIC; -#endif - if (!(osh = kmalloc(sizeof(osl_t), flags))) + if (!(osh = kmalloc(sizeof(osl_t), GFP_ATOMIC))) return osh; ASSERT(osh); @@ -251,10 +229,6 @@ osl_attach(void *pdev, uint bustype, boo if (!(bcm_static_buf = (bcm_static_buf_t *)dhd_os_prealloc(osh, 3, STATIC_BUF_SIZE+ STATIC_BUF_TOTAL_LEN))) { printk("can not alloc static buf!\n"); - bcm_static_skb = NULL; - ASSERT(osh->magic == OS_HANDLE_MAGIC); - kfree(osh); - return NULL; } else printk("alloc static buf at %x!\n", (unsigned int)bcm_static_buf); @@ -270,30 +244,16 @@ osl_attach(void *pdev, uint bustype, boo void *skb_buff_ptr = 0; bcm_static_skb = (bcm_static_pkt_t *)((char *)bcm_static_buf + 2048); skb_buff_ptr = dhd_os_prealloc(osh, 4, 0); - if (!skb_buff_ptr) { - printk("cannot alloc static buf!\n"); - bcm_static_buf = NULL; - bcm_static_skb = NULL; - ASSERT(osh->magic == OS_HANDLE_MAGIC); - kfree(osh); - return NULL; - } - bcopy(skb_buff_ptr, bcm_static_skb, sizeof(struct sk_buff *) * + bcopy(skb_buff_ptr, bcm_static_skb, sizeof(struct sk_buff *)* (STATIC_PKT_MAX_NUM * 2 + STATIC_PKT_4PAGE_NUM)); - for (i = 0; i < STATIC_PKT_MAX_NUM * 2 + STATIC_PKT_4PAGE_NUM; i++) + for (i = 0; i < (STATIC_PKT_MAX_NUM * 2 + STATIC_PKT_4PAGE_NUM); i++) bcm_static_skb->pkt_use[i] = 0; sema_init(&bcm_static_skb->osl_pkt_sem, 1); } #endif /* CONFIG_DHD_USE_STATIC_BUF */ -#ifdef BCMDBG_CTRACE - spin_lock_init(&osh->ctrace_lock); - INIT_LIST_HEAD(&osh->ctrace_list); - osh->ctrace_num = 0; -#endif /* BCMDBG_CTRACE */ - spin_lock_init(&(osh->pktalloc_lock)); return osh; @@ -318,17 +278,13 @@ osl_detach(osl_t *osh) kfree(osh); } -static struct sk_buff *osl_alloc_skb(osl_t *osh, unsigned int len) +static struct sk_buff *osl_alloc_skb(unsigned int len) { - struct sk_buff *skb; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25) - gfp_t flags = (in_atomic() || irqs_disabled()) ? GFP_ATOMIC : GFP_KERNEL; - - skb = __dev_alloc_skb(len, flags); + return __dev_alloc_skb(len, GFP_ATOMIC); #else - skb = dev_alloc_skb(len); -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25) */ - return skb; + return dev_alloc_skb(len); +#endif } #ifdef CTFPOOL @@ -364,7 +320,7 @@ osl_ctfpool_add(osl_t *osh) } /* Allocate a new skb and add it to the ctfpool */ - skb = osl_alloc_skb(osh, osh->ctfpool->obj_size); + skb = osl_alloc_skb(osh->ctfpool->obj_size); if (skb == NULL) { printf("%s: skb alloc of len %d failed\n", __FUNCTION__, osh->ctfpool->obj_size); @@ -411,15 +367,9 @@ osl_ctfpool_replenish(osl_t *osh, uint t int32 osl_ctfpool_init(osl_t *osh, uint numobj, uint size) { - gfp_t flags; - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) - flags = (in_atomic() || irqs_disabled()) ? GFP_ATOMIC : GFP_KERNEL; -#else - flags = GFP_ATOMIC; -#endif - osh->ctfpool = kzalloc(sizeof(ctfpool_t), flags); + osh->ctfpool = kmalloc(sizeof(ctfpool_t), GFP_ATOMIC); ASSERT(osh->ctfpool); + bzero(osh->ctfpool, sizeof(ctfpool_t)); osh->ctfpool->max_obj = numobj; osh->ctfpool->obj_size = size; @@ -532,13 +482,9 @@ osl_pktfastget(osl_t *osh, uint len) /* Init skb struct */ skb->next = skb->prev = NULL; -#if defined(__ARM_ARCH_7A__) - skb->data = skb->head + NET_SKB_PAD; - skb->tail = skb->head + NET_SKB_PAD; -#else skb->data = skb->head + 16; skb->tail = skb->head + 16; -#endif /* __ARM_ARCH_7A__ */ + skb->len = 0; skb->cloned = 0; #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14) @@ -546,9 +492,6 @@ osl_pktfastget(osl_t *osh, uint len) #endif atomic_set(&skb->users, 1); - PKTSETCLINK(skb, NULL); - PKTCCLRATTR(skb); - return skb; } #endif /* CTFPOOL */ @@ -560,30 +503,22 @@ osl_pktfastget(osl_t *osh, uint len) struct sk_buff * BCMFASTPATH osl_pkt_tonative(osl_t *osh, void *pkt) { +#ifndef WL_UMK struct sk_buff *nskb; -#ifdef BCMDBG_CTRACE - struct sk_buff *nskb1, *nskb2; + unsigned long flags; #endif if (osh->pub.pkttag) - OSL_PKTTAG_CLEAR(pkt); + bzero((void*)((struct sk_buff *)pkt)->cb, OSL_PKTTAG_SZ); +#ifndef WL_UMK /* Decrement the packet counter */ for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) { - atomic_sub(PKTISCHAINED(nskb) ? PKTCCNT(nskb) : 1, &osh->pktalloced); - -#ifdef BCMDBG_CTRACE - for (nskb1 = nskb; nskb1 != NULL; nskb1 = nskb2) { - if (PKTISCHAINED(nskb1)) { - nskb2 = PKTCLINK(nskb1); - } - else - nskb2 = NULL; - - DEL_CTRACE(osh, nskb1); - } -#endif /* BCMDBG_CTRACE */ + spin_lock_irqsave(&osh->pktalloc_lock, flags); + osh->pub.pktalloced--; + spin_unlock_irqrestore(&osh->pktalloc_lock, flags); } +#endif /* WL_UMK */ return (struct sk_buff *)pkt; } @@ -591,67 +526,49 @@ osl_pkt_tonative(osl_t *osh, void *pkt) * In the process, native packet is destroyed, there is no copying * Also, a packettag is zeroed out */ -#ifdef BCMDBG_CTRACE -void * BCMFASTPATH -osl_pkt_frmnative(osl_t *osh, void *pkt, int line, char *file) -#else void * BCMFASTPATH osl_pkt_frmnative(osl_t *osh, void *pkt) -#endif /* BCMDBG_CTRACE */ { +#ifndef WL_UMK struct sk_buff *nskb; -#ifdef BCMDBG_CTRACE - struct sk_buff *nskb1, *nskb2; + unsigned long flags; #endif if (osh->pub.pkttag) - OSL_PKTTAG_CLEAR(pkt); + bzero((void*)((struct sk_buff *)pkt)->cb, OSL_PKTTAG_SZ); +#ifndef WL_UMK /* Increment the packet counter */ for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) { - atomic_add(PKTISCHAINED(nskb) ? PKTCCNT(nskb) : 1, &osh->pktalloced); - -#ifdef BCMDBG_CTRACE - for (nskb1 = nskb; nskb1 != NULL; nskb1 = nskb2) { - if (PKTISCHAINED(nskb1)) { - nskb2 = PKTCLINK(nskb1); - } - else - nskb2 = NULL; - - ADD_CTRACE(osh, nskb1, file, line); - } -#endif /* BCMDBG_CTRACE */ + spin_lock_irqsave(&osh->pktalloc_lock, flags); + osh->pub.pktalloced++; + spin_unlock_irqrestore(&osh->pktalloc_lock, flags); } +#endif /* WL_UMK */ return (void *)pkt; } /* Return a new packet. zero out pkttag */ -#ifdef BCMDBG_CTRACE -void * BCMFASTPATH -osl_pktget(osl_t *osh, uint len, int line, char *file) -#else void * BCMFASTPATH osl_pktget(osl_t *osh, uint len) -#endif /* BCMDBG_CTRACE */ { struct sk_buff *skb; + unsigned long flags; #ifdef CTFPOOL /* Allocate from local pool */ skb = osl_pktfastget(osh, len); - if ((skb != NULL) || ((skb = osl_alloc_skb(osh, len)) != NULL)) { + if ((skb != NULL) || ((skb = osl_alloc_skb(len)) != NULL)) { #else /* CTFPOOL */ - if ((skb = osl_alloc_skb(osh, len))) { + if ((skb = osl_alloc_skb(len))) { #endif /* CTFPOOL */ - skb->tail += len; - skb->len += len; + skb_put(skb, len); skb->priority = 0; -#ifdef BCMDBG_CTRACE - ADD_CTRACE(osh, skb, file, line); -#endif - atomic_inc(&osh->pktalloced); + + spin_lock_irqsave(&osh->pktalloc_lock, flags); + osh->pub.pktalloced++; + spin_unlock_irqrestore(&osh->pktalloc_lock, flags); } return ((void*) skb); @@ -674,17 +591,10 @@ osl_pktfastfree(osl_t *osh, struct sk_bu /* We only need to init the fields that we change */ skb->dev = NULL; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) skb->dst = NULL; -#endif - OSL_PKTTAG_CLEAR(skb); + memset(skb->cb, 0, sizeof(skb->cb)); skb->ip_summed = 0; - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) - skb_orphan(skb); -#else skb->destructor = NULL; -#endif ctfpool = (ctfpool_t *)CTFPOOLPTR(osh, skb); ASSERT(ctfpool != NULL); @@ -707,12 +617,7 @@ void BCMFASTPATH osl_pktfree(osl_t *osh, void *p, bool send) { struct sk_buff *skb, *nskb; - - if (osh == NULL) - { - printk("%s: osh == NULL \n", __FUNCTION__); - return; - } + unsigned long flags; skb = (struct sk_buff*) p; @@ -726,21 +631,16 @@ osl_pktfree(osl_t *osh, void *p, bool se nskb = skb->next; skb->next = NULL; -#ifdef BCMDBG_CTRACE - DEL_CTRACE(osh, skb); -#endif #ifdef CTFPOOL - if (PKTISFAST(osh, skb)) { - if (atomic_read(&skb->users) == 1) - smp_rmb(); - else if (!atomic_dec_and_test(&skb->users)) - goto next_skb; + if ((PKTISFAST(osh, skb)) && (atomic_read(&skb->users) == 1)) osl_pktfastfree(osh, skb); - } else -#endif + else { +#else /* CTFPOOL */ { +#endif /* CTFPOOL */ + if (skb->destructor) /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if * destructor exists @@ -752,10 +652,9 @@ osl_pktfree(osl_t *osh, void *p, bool se */ dev_kfree_skb(skb); } -#ifdef CTFPOOL -next_skb: -#endif - atomic_dec(&osh->pktalloced); + spin_lock_irqsave(&osh->pktalloc_lock, flags); + osh->pub.pktalloced--; + spin_unlock_irqrestore(&osh->pktalloc_lock, flags); skb = nskb; } } @@ -767,8 +666,10 @@ osl_pktget_static(osl_t *osh, uint len) int i = 0; struct sk_buff *skb; + if (len > DHD_SKB_MAX_BUFSIZE) { - printk("%s: attempt to allocate huge packet (0x%x)\n", __FUNCTION__, len); + printk("osl_pktget_static: Do we really need this big skb??" + " len=%d\n", len); return osl_pktget(osh, len); } @@ -793,6 +694,7 @@ osl_pktget_static(osl_t *osh, uint len) } if (len <= DHD_SKB_2PAGE_BUFSIZE) { + for (i = 0; i < STATIC_PKT_MAX_NUM; i++) { if (bcm_static_skb->pkt_use[i + STATIC_PKT_MAX_NUM] == 0) @@ -824,7 +726,7 @@ osl_pktget_static(osl_t *osh, uint len) #endif up(&bcm_static_skb->osl_pkt_sem); - printk("%s: all static pkt in use!\n", __FUNCTION__); + printk("osl_pktget_static: all static pkt in use!\n"); return osl_pktget(osh, len); } @@ -855,39 +757,18 @@ osl_pktfree_static(osl_t *osh, void *p, } #ifdef ENHANCED_STATIC_BUF if (p == bcm_static_skb->skb_16k) { - bcm_static_skb->pkt_use[STATIC_PKT_MAX_NUM * 2] = 0; + bcm_static_skb->pkt_use[STATIC_PKT_MAX_NUM*2] = 0; up(&bcm_static_skb->osl_pkt_sem); return; } #endif up(&bcm_static_skb->osl_pkt_sem); + osl_pktfree(osh, p, send); + return; } #endif /* CONFIG_DHD_USE_STATIC_BUF */ -int osh_pktpadtailroom(osl_t *osh, void* p, int pad) -{ - int err; - int ntail; - struct sk_buff* skb = (struct sk_buff*)p; - - ntail = skb->data_len + pad - (skb->end - skb->tail); - if (likely(skb_cloned(skb) || ntail > 0)) { - err = pskb_expand_head(skb, 0, ntail, GFP_ATOMIC); - if (unlikely(err)) - goto done; - } - - err = skb_linearize(skb); - if (unlikely(err)) - goto done; - - memset(skb->data + skb->len, 0, pad); - -done: - return err; -} - uint32 osl_pci_read_config(osl_t *osh, uint offset, uint size) { @@ -944,11 +825,7 @@ osl_pci_slot(osl_t *osh) { ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); -#if defined(__ARM_ARCH_7A__) && LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35) - return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn) + 1; -#else return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn); -#endif } /* return the pci device pointed by osh->pdev */ @@ -981,7 +858,6 @@ void * osl_malloc(osl_t *osh, uint size) { void *addr; - gfp_t flags; /* only ASSERT if osh is defined */ if (osh) @@ -1021,12 +897,7 @@ osl_malloc(osl_t *osh, uint size) original: #endif /* CONFIG_DHD_USE_STATIC_BUF */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) - flags = (in_atomic() || irqs_disabled()) ? GFP_ATOMIC : GFP_KERNEL; -#else - flags = GFP_ATOMIC; -#endif - if ((addr = kmalloc(size, flags)) == NULL) { + if ((addr = kmalloc(size, GFP_ATOMIC)) == NULL) { if (osh) osh->failed++; return (NULL); @@ -1093,7 +964,6 @@ osl_dma_consistent_align(void) void* osl_dma_alloc_consistent(osl_t *osh, uint size, uint16 align_bits, uint *alloced, ulong *pap) { - void *va; uint16 align = (1 << align_bits); ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); @@ -1101,14 +971,7 @@ osl_dma_alloc_consistent(osl_t *osh, uin size += align; *alloced = size; -#ifdef __ARM_ARCH_7A__ - va = kmalloc(size, GFP_ATOMIC | __GFP_ZERO); - if (va) - *pap = (ulong)__virt_to_phys((ulong)va); -#else - va = pci_alloc_consistent(osh->pdev, size, (dma_addr_t*)pap); -#endif - return va; + return (pci_alloc_consistent(osh->pdev, size, (dma_addr_t*)pap)); } void @@ -1116,52 +979,16 @@ osl_dma_free_consistent(osl_t *osh, void { ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); -#ifdef __ARM_ARCH_7A__ - kfree(va); -#else pci_free_consistent(osh->pdev, size, va, (dma_addr_t)pa); -#endif } uint BCMFASTPATH -osl_dma_map(osl_t *osh, void *va, uint size, int direction, void *p, hnddma_seg_map_t *dmah) +osl_dma_map(osl_t *osh, void *va, uint size, int direction) { int dir; ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; - -#if defined(__ARM_ARCH_7A__) && defined(BCMDMASGLISTOSL) - if (dmah != NULL) { - int32 nsegs, i, totsegs = 0, totlen = 0; - struct scatterlist *sg, _sg[MAX_DMA_SEGS * 2]; - struct sk_buff *skb; - for (skb = (struct sk_buff *)p; skb != NULL; skb = PKTNEXT(osh, skb)) { - sg = &_sg[totsegs]; - if (skb_is_nonlinear(skb)) { - nsegs = skb_to_sgvec(skb, sg, 0, PKTLEN(osh, skb)); - ASSERT((nsegs > 0) && (totsegs + nsegs <= MAX_DMA_SEGS)); - pci_map_sg(osh->pdev, sg, nsegs, dir); - } else { - nsegs = 1; - ASSERT(totsegs + nsegs <= MAX_DMA_SEGS); - sg->page_link = 0; - sg_set_buf(sg, PKTDATA(osh, skb), PKTLEN(osh, skb)); - pci_map_single(osh->pdev, PKTDATA(osh, skb), PKTLEN(osh, skb), dir); - } - totsegs += nsegs; - totlen += PKTLEN(osh, skb); - } - dmah->nsegs = totsegs; - dmah->origsize = totlen; - for (i = 0, sg = _sg; i < totsegs; i++, sg++) { - dmah->segs[i].addr = sg_phys(sg); - dmah->segs[i].length = sg->length; - } - return dmah->segs[0].addr; - } -#endif /* __ARM_ARCH_7A__ && BCMDMASGLISTOSL */ - return (pci_map_single(osh->pdev, va, size, dir)); } @@ -1190,11 +1017,10 @@ osl_assert(const char *exp, const char * if (!basename) basename = file; -#ifdef BCMASSERT_LOG snprintf(tempbuf, 64, "\"%s\": file \"%s\", line %d\n", exp, basename, line); + printk("%s", tempbuf); -#endif /* BCMASSERT_LOG */ } @@ -1212,47 +1038,22 @@ osl_delay(uint usec) } } -void -osl_sleep(uint ms) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) - if (ms < 20) - usleep_range(ms*1000, ms*1000 + 1000); - else -#endif - msleep(ms); -} - /* Clone a packet. * The pkttag contents are NOT cloned. */ -#ifdef BCMDBG_CTRACE -void * -osl_pktdup(osl_t *osh, void *skb, int line, char *file) -#else void * osl_pktdup(osl_t *osh, void *skb) -#endif /* BCMDBG_CTRACE */ { void * p; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) - gfp_t flags; -#endif - - ASSERT(!PKTISCHAINED(skb)); + unsigned long irqflags; /* clear the CTFBUF flag if set and map the rest of the buffer * before cloning. */ PKTCTFMAP(osh, skb); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) - flags = (in_atomic() || irqs_disabled()) ? GFP_ATOMIC : GFP_KERNEL; - if ((p = pskb_copy((struct sk_buff *)skb, flags)) == NULL) -#else if ((p = skb_clone((struct sk_buff *)skb, GFP_ATOMIC)) == NULL) -#endif return NULL; #ifdef CTFPOOL @@ -1273,83 +1074,17 @@ osl_pktdup(osl_t *osh, void *skb) } #endif /* CTFPOOL */ - /* Clear PKTC context */ - PKTSETCLINK(p, NULL); - PKTCCLRFLAGS(p); - PKTCSETCNT(p, 1); - PKTCSETLEN(p, PKTLEN(osh, skb)); - /* skb_clone copies skb->cb.. we don't want that */ if (osh->pub.pkttag) - OSL_PKTTAG_CLEAR(p); + bzero((void*)((struct sk_buff *)p)->cb, OSL_PKTTAG_SZ); /* Increment the packet counter */ - atomic_inc(&osh->pktalloced); -#ifdef BCMDBG_CTRACE - ADD_CTRACE(osh, (struct sk_buff *)p, file, line); -#endif + spin_lock_irqsave(&osh->pktalloc_lock, irqflags); + osh->pub.pktalloced++; + spin_unlock_irqrestore(&osh->pktalloc_lock, irqflags); return (p); } -#ifdef BCMDBG_CTRACE -int osl_pkt_is_frmnative(osl_t *osh, struct sk_buff *pkt) -{ - unsigned long flags; - struct sk_buff *skb; - int ck = FALSE; - - spin_lock_irqsave(&osh->ctrace_lock, flags); - - list_for_each_entry(skb, &osh->ctrace_list, ctrace_list) { - if (pkt == skb) { - ck = TRUE; - break; - } - } - - spin_unlock_irqrestore(&osh->ctrace_lock, flags); - return ck; -} - -void osl_ctrace_dump(osl_t *osh, struct bcmstrbuf *b) -{ - unsigned long flags; - struct sk_buff *skb; - int idx = 0; - int i, j; - - spin_lock_irqsave(&osh->ctrace_lock, flags); - - if (b != NULL) - bcm_bprintf(b, " Total %d sbk not free\n", osh->ctrace_num); - else - printk(" Total %d sbk not free\n", osh->ctrace_num); - - list_for_each_entry(skb, &osh->ctrace_list, ctrace_list) { - if (b != NULL) - bcm_bprintf(b, "[%d] skb %p:\n", ++idx, skb); - else - printk("[%d] skb %p:\n", ++idx, skb); - - for (i = 0; i < skb->ctrace_count; i++) { - j = (skb->ctrace_start + i) % CTRACE_NUM; - if (b != NULL) - bcm_bprintf(b, " [%s(%d)]\n", skb->func[j], skb->line[j]); - else - printk(" [%s(%d)]\n", skb->func[j], skb->line[j]); - } - if (b != NULL) - bcm_bprintf(b, "\n"); - else - printk("\n"); - } - - spin_unlock_irqrestore(&osh->ctrace_lock, flags); - - return; -} -#endif /* BCMDBG_CTRACE */ - /* * OSLREGOPS specifies the use of osl_XXX routines to be used for register access @@ -1359,12 +1094,6 @@ void osl_ctrace_dump(osl_t *osh, struct * BINOSL selects the slightly slower function-call-based binary compatible osl. */ -uint -osl_pktalloced(osl_t *osh) -{ - return (atomic_read(&osh->pktalloced)); -} - /* Linux Kernel: File Operations: start */ void * osl_os_open_image(char *filename) @@ -1406,21 +1135,4 @@ osl_os_close_image(void *image) if (image) filp_close((struct file *)image, NULL); } - -int -osl_os_image_size(void *image) -{ - int len = 0, curroffset; - - if (image) { - /* store the current offset */ - curroffset = generic_file_llseek(image, 0, 1); - /* goto end of file to get length */ - len = generic_file_llseek(image, 0, 2); - /* restore back the offset */ - generic_file_llseek(image, curroffset, 0); - } - return len; -} - /* Linux Kernel: File Operations: end */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/Makefile linux-sunxi-new/drivers/net/wireless/bcmdhd/Makefile --- linux-sunxi/drivers/net/wireless/bcmdhd/Makefile 2014-01-27 01:30:30.101433269 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/Makefile 2014-02-15 00:43:44.792014069 +0100 @@ -1,36 +1,42 @@ # bcmdhd -# -# -# -# -# - -DHDCFLAGS = -Wall -Wstrict-prototypes -Dlinux -DBCMDRIVER \ +DHDCFLAGS = -Wall -Wstrict-prototypes -Dlinux -DBCMDRIVER \ -DBCMDONGLEHOST -DUNRELEASEDCHIP -DBCMDMA32 -DBCMFILEIMAGE \ - -DDHDTHREAD -DDHD_DEBUG -DSDTEST -DBDC \ + -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 \ -DWIFI_ACT_FRAME -DARP_OFFLOAD_SUPPORT \ - -DKEEP_ALIVE -DGET_CUSTOM_MAC_ENABLE -DPKT_FILTER_SUPPORT \ + -DKEEP_ALIVE -DPKT_FILTER_SUPPORT \ -DEMBEDDED_PLATFORM -DENABLE_INSMOD_NO_FW_LOAD -DPNO_SUPPORT \ - -DDHD_USE_IDLECOUNT -DSET_RANDOM_MAC_SOFTAP -DROAM_ENABLE -DVSDB \ - -DWL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST \ - -DESCAN_RESULT_PATCH -DSDIO_CRC_ERROR_FIX \ - -DDHD_DONOT_FORWARD_BCMEVENT_AS_NETWORK_PKT -DRXFRAME_THREAD \ - -DSUPPORT_PM2_ONLY -DWLTDLS \ - -DMIRACAST_AMPDU_SIZE=8 \ - -Idrivers/net/wireless/bcmdhd -Idrivers/net/wireless/bcmdhd/include \ - -Idrivers/net/wireless/bcmdhd/common/include + -DDHD_USE_IDLECOUNT -DSET_RANDOM_MAC_SOFTAP -DVSDB \ + -DWL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST -DSDIO_CRC_ERROR_FIX \ + -DESCAN_RESULT_PATCH -DHT40_GO -DPASS_ARP_PACKET -DSUPPORT_PM2_ONLY \ + -DDHD_DONOT_FORWARD_BCMEVENT_AS_NETWORK_PKT -DAMPDU_HOSTREORDER \ + -DDISABLE_FW_ROAM_SUSPEND -DDISABLE_BUILTIN_ROAM \ + -DCUSTOM_SDIO_F2_BLKSIZE=128 -DWL_SDO -DWL_SUPPORT_BACKPORTED_KPATCHES\ + -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 dhd_sdio.o bcmwifi_channels.o bcmevent.o hndpmu.o \ - bcmsdh.o dhd_cdc.o bcmsdh_linux.o dhd_common.o dhd_wlfc.o dhd_ip.o \ - linux_osl.o bcmsdh_sdmmc.o dhd_custom_gpio.o sbutils.o wldev_common.o \ - wl_android.o dhd_pno.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 obj-$(CONFIG_BCMDHD) += bcmdhd.o bcmdhd-objs += $(DHDOFILES) + +DHDOFILES += dhd_gpio.o +DHDCFLAGS += -DCUSTOMER_HW +#DHDCFLAGS += -DBCMWAPI_WPI -DBCMWAPI_WAI + +ifeq ($(CONFIG_BCMDHD_OOB),y) +DHDCFLAGS += -DOOB_INTR_ONLY -DHW_OOB -DCUSTOMER_OOB +else +DHDCFLAGS += -DSDIO_ISR_THREAD +endif + +ifeq ($(CONFIG_BCMDHD_AG),y) + DHDCFLAGS += -DBAND_AG +endif + ifneq ($(CONFIG_WIRELESS_EXT),) bcmdhd-objs += wl_iw.o DHDCFLAGS += -DSOFTAP -DWL_WIRELESS_EXT -DUSE_IW @@ -38,11 +44,10 @@ endif ifneq ($(CONFIG_CFG80211),) bcmdhd-objs += wl_cfg80211.o wl_cfgp2p.o wl_linux_mon.o dhd_cfg80211.o DHDCFLAGS += -DWL_CFG80211 -DWL_CFG80211_STA_EVENT -DWL_ENABLE_P2P_IF -DHDCFLAGS += -DWL_IFACE_COMB_NUM_CHANNELS -DHDCFLAGS += -DCUSTOM_ROAM_TRIGGER_SETTING=-75 -DHDCFLAGS += -DCUSTOM_ROAM_DELTA_SETTING=10 +DHDCFLAGS += -DCUSTOM_ROAM_TRIGGER_SETTING=-65 +DHDCFLAGS += -DCUSTOM_ROAM_DELTA_SETTING=15 DHDCFLAGS += -DCUSTOM_KEEP_ALIVE_SETTING=28000 -DHDCFLAGS += -DCUSTOM_PNO_EVENT_LOCK_xTIME=10 +DHDCFLAGS += -DCUSTOM_PNO_EVENT_LOCK_xTIME=7 endif ifneq ($(CONFIG_DHD_USE_SCHED_SCAN),) DHDCFLAGS += -DWL_SCHED_SCAN @@ -51,28 +56,3 @@ EXTRA_CFLAGS = $(DHDCFLAGS) ifeq ($(CONFIG_BCMDHD),m) EXTRA_LDFLAGS += --strip-debug endif - -DHDCFLAGS += -DCUSTOM_TDLS_RSSI_THRESHOLD_HIGH=-60 -DHDCFLAGS += -DCUSTOM_TDLS_RSSI_THRESHOLD_LOW=-70 -DHDCFLAGS += -DCUSTOM_TDLS_IDLE_MODE_SETTING=40000 - -######################### -# Chip dependent feature -######################### -ifneq ($(CONFIG_BCM4339),) -DHDCFLAGS += -DCUSTOM_GLOM_SETTING=8 -DCUSTOM_RXCHAIN=1 -DHDCFLAGS += -DUSE_DYNAMIC_F2_BLKSIZE -DDYNAMIC_F2_BLKSIZE_FOR_NONLEGACY=128 -DHDCFLAGS += -DBCMSDIOH_TXGLOM -DCUSTOM_TXGLOM=1 -DBCMSDIOH_TXGLOM_HIGHSPEED -DHDCFLAGS += -DCUSTOM_SDIO_F2_BLKSIZE=512 -DHDCFLAGS += -DDHDTCPACK_SUPPRESS -DHDCFLAGS += -DUSE_WL_TXBF -DHDCFLAGS += -DUSE_WL_FRAMEBURST -DHDCFLAGS += -DCUSTOM_AMPDU_BA_WSIZE=32 -DHDCFLAGS += -DPROP_TXSTATUS_VSDB -DHDCFLAGS += -DCUSTOM_MAX_TXGLOM_SIZE=32 -DHDCFLAGS += -DREPEAT_READFRAME -DHDCFLAGS += -DROAM_AP_ENV_DETECTION -DHDCFLAGS += -DWL11U -else -DHDCFLAGS += -DCUSTOM_SDIO_F2_BLKSIZE=128 -endif diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/sbutils.c linux-sunxi-new/drivers/net/wireless/bcmdhd/sbutils.c --- linux-sunxi/drivers/net/wireless/bcmdhd/sbutils.c 2014-01-27 01:30:30.108433411 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/sbutils.c 2014-02-15 00:43:44.795014136 +0100 @@ -2,7 +2,7 @@ * Misc utility routines for accessing chip-specific features * of the SiliconBackplane-based Broadcom chips. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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: sbutils.c 379512 2013-01-17 22:49:08Z $ + * $Id: sbutils.c 310902 2012-01-26 19:45:33Z $ */ #include @@ -510,11 +510,10 @@ _sb_scan(si_info_t *sii, uint32 sba, voi uint32 ccrev = sb_corerev(&sii->pub); /* determine numcores - this is the total # cores in the chip */ - if (((ccrev == 4) || (ccrev >= 6))) { - ASSERT(cc); + if (((ccrev == 4) || (ccrev >= 6))) numcores = (R_REG(sii->osh, &cc->chipid) & CID_CC_MASK) >> CID_CC_SHIFT; - } else { + else { /* Older chips */ uint chip = CHIPID(sii->pub.chip); diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/siutils.c linux-sunxi-new/drivers/net/wireless/bcmdhd/siutils.c --- linux-sunxi/drivers/net/wireless/bcmdhd/siutils.c 2014-01-27 01:30:30.100433249 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/siutils.c 2014-02-15 00:43:44.791014047 +0100 @@ -2,7 +2,7 @@ * Misc utility routines for accessing chip-specific features * of the SiliconBackplane-based Broadcom chips. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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: siutils.c 414368 2013-07-24 15:00:23Z $ + * $Id: siutils.c 347632 2012-07-27 11:00:35Z $ */ #include @@ -45,7 +45,6 @@ #include #include - #include "siutils_priv.h" /* local prototypes */ @@ -110,7 +109,6 @@ si_kattach(osl_t *osh) void *regs = NULL; regs = REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE); - ASSERT(osh); if (si_doattach(&ksii, BCM4710_DEVICE_ID, osh, regs, SI_BUS, NULL, osh != SI_OSH ? &ksii.vars : NULL, @@ -318,8 +316,7 @@ si_doattach(si_info_t *sii, uint devid, chipcregs_t *cc; char *pvars = NULL; uint origidx; -#if !defined(_CFEZ_) || defined(CFG_WL) -#endif + ASSERT(GOODREGS(regs)); bzero((uchar*)sii, sizeof(si_info_t)); @@ -372,13 +369,16 @@ si_doattach(si_info_t *sii, uint devid, return NULL; } w = R_REG(osh, &cc->chipid); - if ((w & 0xfffff) == 148277) w -= 65532; 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 defined(HW_OOB) + bcmsdh_config_hw_oob_intr(sdh, sih->chip); +#endif + if ((CHIPID(sih->chip) == BCM4329_CHIP_ID) && (sih->chiprev == 0) && (sih->chippkg != BCM4329_289PIN_PKG_ID)) { sih->chippkg = BCM4329_182PIN_PKG_ID; @@ -389,12 +389,8 @@ si_doattach(si_info_t *sii, uint devid, if (CHIPTYPE(sii->pub.socitype) == SOCI_SB) { SI_MSG(("Found chip type SB (0x%08x)\n", w)); sb_scan(&sii->pub, regs, devid); - } else if ((CHIPTYPE(sii->pub.socitype) == SOCI_AI) || - (CHIPTYPE(sii->pub.socitype) == SOCI_NAI)) { - if (CHIPTYPE(sii->pub.socitype) == SOCI_AI) - SI_MSG(("Found chip type AI (0x%08x)\n", w)); - else - SI_MSG(("Found chip type NAI (0x%08x)\n", w)); + } else if (CHIPTYPE(sii->pub.socitype) == SOCI_AI) { + SI_MSG(("Found chip type AI (0x%08x)\n", w)); /* pass chipc address instead of original core base */ ai_scan(&sii->pub, (void *)(uintptr)cc, devid); } else if (CHIPTYPE(sii->pub.socitype) == SOCI_UBUS) { @@ -417,7 +413,6 @@ si_doattach(si_info_t *sii, uint devid, goto exit; } -#if !defined(_CFEZ_) || defined(CFG_WL) 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))) { @@ -446,7 +441,6 @@ si_doattach(si_info_t *sii, uint devid, if (bustype == PCI_BUS) { } -#endif pvars = NULL; BCM_REFERENCE(pvars); @@ -565,7 +559,7 @@ si_intflag(si_t *sih) if (CHIPTYPE(sih->socitype) == SOCI_SB) return sb_intflag(sih); - else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) + else if (CHIPTYPE(sih->socitype) == SOCI_AI) return R_REG(sii->osh, ((uint32 *)(uintptr) (sii->oob_router + OOB_STATUSA))); else { @@ -579,7 +573,7 @@ si_flag(si_t *sih) { if (CHIPTYPE(sih->socitype) == SOCI_SB) return sb_flag(sih); - else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) + else if (CHIPTYPE(sih->socitype) == SOCI_AI) return ai_flag(sih); else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) return ub_flag(sih); @@ -589,23 +583,12 @@ si_flag(si_t *sih) } } -uint -si_flag_alt(si_t *sih) -{ - if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) - return ai_flag_alt(sih); - else { - ASSERT(0); - return 0; - } -} - void si_setint(si_t *sih, int siflag) { if (CHIPTYPE(sih->socitype) == SOCI_SB) sb_setint(sih, siflag); - else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) + else if (CHIPTYPE(sih->socitype) == SOCI_AI) ai_setint(sih, siflag); else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) ub_setint(sih, siflag); @@ -662,7 +645,7 @@ si_corevendor(si_t *sih) { if (CHIPTYPE(sih->socitype) == SOCI_SB) return sb_corevendor(sih); - else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) + else if (CHIPTYPE(sih->socitype) == SOCI_AI) return ai_corevendor(sih); else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) return ub_corevendor(sih); @@ -683,7 +666,7 @@ si_corerev(si_t *sih) { if (CHIPTYPE(sih->socitype) == SOCI_SB) return sb_corerev(sih); - else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) + else if (CHIPTYPE(sih->socitype) == SOCI_AI) return ai_corerev(sih); else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) return ub_corerev(sih); @@ -727,18 +710,6 @@ si_corelist(si_t *sih, uint coreid[]) return (sii->numcores); } -/* return current wrapper mapping */ -void * -si_wrapperregs(si_t *sih) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - ASSERT(GOODREGS(sii->curwrap)); - - return (sii->curwrap); -} - /* return current register mapping */ void * si_coreregs(si_t *sih) @@ -767,7 +738,7 @@ si_setcore(si_t *sih, uint coreid, uint if (CHIPTYPE(sih->socitype) == SOCI_SB) return sb_setcoreidx(sih, idx); - else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) + else if (CHIPTYPE(sih->socitype) == SOCI_AI) return ai_setcoreidx(sih, idx); else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) return ub_setcoreidx(sih, idx); @@ -782,7 +753,7 @@ si_setcoreidx(si_t *sih, uint coreidx) { if (CHIPTYPE(sih->socitype) == SOCI_SB) return sb_setcoreidx(sih, coreidx); - else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) + else if (CHIPTYPE(sih->socitype) == SOCI_AI) return ai_setcoreidx(sih, coreidx); else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) return ub_setcoreidx(sih, coreidx); @@ -839,7 +810,7 @@ si_numaddrspaces(si_t *sih) { if (CHIPTYPE(sih->socitype) == SOCI_SB) return sb_numaddrspaces(sih); - else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) + else if (CHIPTYPE(sih->socitype) == SOCI_AI) return ai_numaddrspaces(sih); else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) return ub_numaddrspaces(sih); @@ -854,7 +825,7 @@ si_addrspace(si_t *sih, uint asidx) { if (CHIPTYPE(sih->socitype) == SOCI_SB) return sb_addrspace(sih, asidx); - else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) + else if (CHIPTYPE(sih->socitype) == SOCI_AI) return ai_addrspace(sih, asidx); else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) return ub_addrspace(sih, asidx); @@ -869,7 +840,7 @@ si_addrspacesize(si_t *sih, uint asidx) { if (CHIPTYPE(sih->socitype) == SOCI_SB) return sb_addrspacesize(sih, asidx); - else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) + else if (CHIPTYPE(sih->socitype) == SOCI_AI) return ai_addrspacesize(sih, asidx); else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) return ub_addrspacesize(sih, asidx); @@ -883,7 +854,7 @@ void si_coreaddrspaceX(si_t *sih, uint asidx, uint32 *addr, uint32 *size) { /* Only supported for SOCI_AI */ - if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) + if (CHIPTYPE(sih->socitype) == SOCI_AI) ai_coreaddrspaceX(sih, asidx, addr, size); else *size = 0; @@ -894,7 +865,7 @@ si_core_cflags(si_t *sih, uint32 mask, u { if (CHIPTYPE(sih->socitype) == SOCI_SB) return sb_core_cflags(sih, mask, val); - else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) + else if (CHIPTYPE(sih->socitype) == SOCI_AI) return ai_core_cflags(sih, mask, val); else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) return ub_core_cflags(sih, mask, val); @@ -909,7 +880,7 @@ si_core_cflags_wo(si_t *sih, uint32 mask { if (CHIPTYPE(sih->socitype) == SOCI_SB) sb_core_cflags_wo(sih, mask, val); - else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) + else if (CHIPTYPE(sih->socitype) == SOCI_AI) ai_core_cflags_wo(sih, mask, val); else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) ub_core_cflags_wo(sih, mask, val); @@ -922,7 +893,7 @@ si_core_sflags(si_t *sih, uint32 mask, u { if (CHIPTYPE(sih->socitype) == SOCI_SB) return sb_core_sflags(sih, mask, val); - else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) + else if (CHIPTYPE(sih->socitype) == SOCI_AI) return ai_core_sflags(sih, mask, val); else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) return ub_core_sflags(sih, mask, val); @@ -937,7 +908,7 @@ si_iscoreup(si_t *sih) { if (CHIPTYPE(sih->socitype) == SOCI_SB) return sb_iscoreup(sih); - else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) + else if (CHIPTYPE(sih->socitype) == SOCI_AI) return ai_iscoreup(sih); else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) return ub_iscoreup(sih); @@ -951,7 +922,7 @@ uint si_wrapperreg(si_t *sih, uint32 offset, uint32 mask, uint32 val) { /* only for AI back plane chips */ - if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) + if (CHIPTYPE(sih->socitype) == SOCI_AI) return (ai_wrap_reg(sih, offset, mask, val)); return 0; } @@ -961,7 +932,7 @@ si_corereg(si_t *sih, uint coreidx, uint { if (CHIPTYPE(sih->socitype) == SOCI_SB) return sb_corereg(sih, coreidx, regoff, mask, val); - else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) + else if (CHIPTYPE(sih->socitype) == SOCI_AI) return ai_corereg(sih, coreidx, regoff, mask, val); else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) return ub_corereg(sih, coreidx, regoff, mask, val); @@ -976,7 +947,7 @@ si_core_disable(si_t *sih, uint32 bits) { if (CHIPTYPE(sih->socitype) == SOCI_SB) sb_core_disable(sih, bits); - else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) + else if (CHIPTYPE(sih->socitype) == SOCI_AI) ai_core_disable(sih, bits); else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) ub_core_disable(sih, bits); @@ -987,7 +958,7 @@ si_core_reset(si_t *sih, uint32 bits, ui { if (CHIPTYPE(sih->socitype) == SOCI_SB) sb_core_reset(sih, bits, resetbits); - else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) + else if (CHIPTYPE(sih->socitype) == SOCI_AI) ai_core_reset(sih, bits, resetbits); else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) ub_core_reset(sih, bits, resetbits); @@ -1117,7 +1088,6 @@ si_clock_rate(uint32 pll_type, uint32 n, } - /* set chip watchdog reset timer to fire in 'ticks' */ void si_watchdog(si_t *sih, uint ticks) @@ -1126,7 +1096,6 @@ si_watchdog(si_t *sih, uint ticks) if (PMUCTL_ENAB(sih)) { -#if !defined(_CFEZ_) || defined(CFG_WL) if ((CHIPID(sih->chip) == BCM4319_CHIP_ID) && (CHIPREV(sih->chiprev) == 0) && (ticks != 0)) { si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, clk_ctl_st), ~0, 0x2); @@ -1134,7 +1103,6 @@ si_watchdog(si_t *sih, uint ticks) si_core_disable(sih, 1); si_setcore(sih, CC_CORE_ID, 0); } -#endif nb = (sih->ccrev < 26) ? 16 : ((sih->ccrev >= 37) ? 32 : 24); /* The mips compiler uses the sllv instruction, @@ -1197,7 +1165,6 @@ si_slowclk_src(si_info_t *sii) return (SCC_SS_XTAL); } else if (sii->pub.ccrev < 10) { cc = (chipcregs_t *)si_setcoreidx(&sii->pub, sii->curidx); - ASSERT(cc); return (R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_SS_MASK); } else /* Insta-clock */ return (SCC_SS_XTAL); @@ -1297,8 +1264,6 @@ si_clkctl_init(si_t *sih) si_clkctl_setdelay(sii, (void *)(uintptr)cc); - OSL_DELAY(20000); - if (!fast) si_setcoreidx(sih, origidx); } @@ -2086,7 +2051,6 @@ done: } -#if !defined(_CFEZ_) || defined(CFG_WL) void si_btcgpiowar(si_t *sih) { @@ -2283,7 +2247,6 @@ si_chipcontrl_epa4331_wowl(si_t *sih, bo } si_setcoreidx(sih, origidx); } -#endif uint si_pll_reset(si_t *sih) @@ -2318,12 +2281,6 @@ si_clk_pmu_htavail_set(si_t *sih, bool s { } -/* Re-enable synth_pwrsw resource in min_res_mask for 4313 */ -void -si_pmu_synth_pwrsw_4313_war(si_t *sih) -{ -} - /* WL/BT control for 4313 btcombo boards >= P250 */ void si_btcombo_p250_4313_war(si_t *sih) @@ -2415,7 +2372,6 @@ si_is_sprom_available(si_t *sih) sii = SI_INFO(sih); origidx = sii->curidx; cc = si_setcoreidx(sih, SI_CC_IDX); - ASSERT(cc); sromctrl = R_REG(sii->osh, &cc->sromcontrol); si_setcoreidx(sih, origidx); return (sromctrl & SRC_PRESENT); @@ -2454,14 +2410,11 @@ si_is_sprom_available(si_t *sih) return ((sih->chipst & CST43239_SPROM_MASK) && !(sih->chipst & CST43239_SFLASH_MASK)); case BCM4324_CHIP_ID: - case BCM43242_CHIP_ID: return ((sih->chipst & CST4324_SPROM_MASK) && !(sih->chipst & CST4324_SFLASH_MASK)); case BCM4335_CHIP_ID: return ((sih->chipst & CST4335_SPROM_MASK) && !(sih->chipst & CST4335_SFLASH_MASK)); - case BCM4350_CHIP_ID: - return (sih->chipst & CST4350_SPROM_PRESENT) != 0; case BCM43131_CHIP_ID: case BCM43217_CHIP_ID: case BCM43227_CHIP_ID: @@ -2515,20 +2468,3 @@ int si_set_sromctl(si_t *sih, uint32 val return BCME_OK; } - -uint -si_core_wrapperreg(si_t *sih, uint32 coreidx, uint32 offset, uint32 mask, uint32 val) -{ - uint origidx; - uint ret_val; - - origidx = si_coreidx(sih); - - si_setcoreidx(sih, coreidx); - - ret_val = si_wrapperreg(sih, offset, mask, val); - - /* return to the original core */ - si_setcoreidx(sih, origidx); - return ret_val; -} diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/siutils_priv.h linux-sunxi-new/drivers/net/wireless/bcmdhd/siutils_priv.h --- linux-sunxi/drivers/net/wireless/bcmdhd/siutils_priv.h 2014-01-27 01:30:30.100433249 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/siutils_priv.h 2014-02-15 00:43:44.791014047 +0100 @@ -1,7 +1,7 @@ /* * Include file private to the SOC Interconnect support files. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -21,13 +21,13 @@ * 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 385510 2013-02-15 21:02:07Z $ + * $Id: siutils_priv.h 309193 2012-01-19 00:03:57Z $ */ #ifndef _siutils_priv_h_ #define _siutils_priv_h_ -#define SI_ERROR(args) +#define SI_ERROR(args) printf args #define SI_MSG(args) @@ -146,7 +146,6 @@ typedef struct si_info { #define ILP_DIV_5MHZ 0 /* ILP = 5 MHz */ #define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */ -/* Force fast clock for 4360b0 */ #define PCI_FORCEHT(si) \ (((PCIE_GEN1(si)) && (si->pub.chip == BCM4311_CHIP_ID) && ((si->pub.chiprev <= 1))) || \ ((PCI(si) || PCIE_GEN1(si)) && (si->pub.chip == BCM4321_CHIP_ID)) || \ @@ -204,7 +203,6 @@ extern si_t *ai_kattach(osl_t *osh); extern void ai_scan(si_t *sih, void *regs, uint devid); extern uint ai_flag(si_t *sih); -extern uint ai_flag_alt(si_t *sih); extern void ai_setint(si_t *sih, int siflag); extern uint ai_coreidx(si_t *sih); extern uint ai_corevendor(si_t *sih); diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/uamp_api.h linux-sunxi-new/drivers/net/wireless/bcmdhd/uamp_api.h --- linux-sunxi/drivers/net/wireless/bcmdhd/uamp_api.h 2014-01-27 01:30:30.109433432 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/uamp_api.h 2014-02-15 00:43:44.795014136 +0100 @@ -3,7 +3,7 @@ * * Description: Universal AMP API * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/wl_android.c linux-sunxi-new/drivers/net/wireless/bcmdhd/wl_android.c --- linux-sunxi/drivers/net/wireless/bcmdhd/wl_android.c 2014-01-27 01:30:30.109433432 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/wl_android.c 2014-02-15 00:43:44.795014136 +0100 @@ -1,7 +1,7 @@ /* * Linux cfg80211 driver - Android related functions * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -21,13 +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_android.c 420671 2013-08-28 11:37:19Z $ + * $Id: wl_android.c 372668 2012-12-04 14:07:12Z $ */ #include #include -#include -#include #include #include @@ -37,9 +35,6 @@ #include #include #include -#ifdef PNO_SUPPORT -#include -#endif #include #ifdef WL_CFG80211 #include @@ -53,6 +48,44 @@ #endif #endif /* CONFIG_WIFI_CONTROL_FUNC */ +#ifndef WL_CFG80211 +#define htod32(i) i +#define htod16(i) i +#define dtoh32(i) i +#define dtoh16(i) i +#define htodchanspec(i) i +#define dtohchanspec(i) i +#endif + +/* message levels */ +#define ANDROID_ERROR_LEVEL 0x0001 +#define ANDROID_TRACE_LEVEL 0x0002 +#define ANDROID_INFO_LEVEL 0x0004 + +uint android_msg_level = ANDROID_ERROR_LEVEL; + +#define ANDROID_ERROR(x) \ + do { \ + if (android_msg_level & ANDROID_ERROR_LEVEL) { \ + printk(KERN_ERR "ANDROID-ERROR) "); \ + printk x; \ + } \ + } while (0) +#define ANDROID_TRACE(x) \ + do { \ + if (android_msg_level & ANDROID_TRACE_LEVEL) { \ + printk(KERN_ERR "ANDROID-TRACE) "); \ + printk x; \ + } \ + } while (0) +#define ANDROID_INFO(x) \ + do { \ + if (android_msg_level & ANDROID_INFO_LEVEL) { \ + printk(KERN_ERR "ANDROID-INFO) "); \ + printk x; \ + } \ + } while (0) + /* * Android private command strings, PLEASE define new private commands here * so they can be updated easily in the future (if needed) @@ -80,14 +113,12 @@ #define CMD_COUNTRY "COUNTRY" #define CMD_P2P_SET_NOA "P2P_SET_NOA" #if !defined WL_ENABLE_P2P_IF -#define CMD_P2P_GET_NOA "P2P_GET_NOA" -#endif /* WL_ENABLE_P2P_IF */ +#define CMD_P2P_GET_NOA "P2P_GET_NOA" +#endif #define CMD_P2P_SD_OFFLOAD "P2P_SD_" #define CMD_P2P_SET_PS "P2P_SET_PS" #define CMD_SET_AP_WPS_P2P_IE "SET_AP_WPS_P2P_IE" #define CMD_SETROAMMODE "SETROAMMODE" -#define CMD_MIRACAST "MIRACAST" - /* CCX Private Commands */ @@ -97,49 +128,34 @@ #define CMD_PNOSETUP_SET "PNOSETUP " #define CMD_PNOENABLE_SET "PNOFORCE" #define CMD_PNODEBUG_SET "PNODEBUG" -#define CMD_WLS_BATCHING "WLS_BATCHING" + +#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' + +typedef struct cmd_tlv { + char prefix; + char version; + char subver; + char reserved; +} cmd_tlv_t; #endif /* PNO_SUPPORT */ #define CMD_OKC_SET_PMK "SET_PMK" #define CMD_OKC_ENABLE "OKC_ENABLE" -/* miracast related definition */ -#define MIRACAST_MODE_OFF 0 -#define MIRACAST_MODE_SOURCE 1 -#define MIRACAST_MODE_SINK 2 - -#ifndef MIRACAST_AMPDU_SIZE -#define MIRACAST_AMPDU_SIZE 8 -#endif - -#ifndef MIRACAST_MCHAN_ALGO -#define MIRACAST_MCHAN_ALGO 1 -#endif - -#ifndef MIRACAST_MCHAN_BW -#define MIRACAST_MCHAN_BW 25 -#endif - -static LIST_HEAD(miracast_resume_list); -static u8 miracast_cur_mode; - -struct io_cfg { - s8 *iovar; - s32 param; - u32 ioctl; - void *arg; - u32 len; - struct list_head list; -}; - typedef struct android_wifi_priv_cmd { char *buf; int used_len; int total_len; } android_wifi_priv_cmd; - /** * Extern function declarations (TODO: move them to dhd_linux.h) */ @@ -149,7 +165,6 @@ int dhd_dev_init_ioctl(struct net_device #ifdef WL_CFG80211 int wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr); int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, char *command); -int wl_cfg80211_get_ioctl_version(void); #else int wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr) { return 0; } @@ -159,24 +174,20 @@ int wl_cfg80211_get_p2p_noa(struct net_d { return 0; } int wl_cfg80211_set_p2p_ps(struct net_device *net, char* buf, int len) { return 0; } -#endif /* WK_CFG80211 */ +#endif /* WL_CFG80211 */ + +extern int dhd_os_check_wakelock(void *dhdp); extern int dhd_os_check_if_up(void *dhdp); -#ifdef BCMLXSDMMC extern void *bcmsdh_get_drvdata(void); -#endif /* BCMLXSDMMC */ - - -#ifdef ENABLE_4335BT_WAR -extern int bcm_bt_lock(int cookie); -extern void bcm_bt_unlock(int cookie); -static int lock_cookie_wifi = 'W' | 'i'<<8 | 'F'<<16 | 'i'<<24; /* cookie is "WiFi" */ -#endif /* ENABLE_4335BT_WAR */ +#if defined(PROP_TXSTATUS) && !defined(PROP_TXSTATUS_VSDB) +extern int dhd_wlfc_init(dhd_pub_t *dhd); +extern void dhd_wlfc_deinit(dhd_pub_t *dhd); +#endif extern bool ap_fw_loaded; -#if defined(CUSTOMER_HW2) extern char iface_name[IFNAMSIZ]; -#endif +#define WIFI_TURNOFF_DELAY 0 /** * Local (static) functions and variables */ @@ -203,7 +214,7 @@ static int wl_android_get_link_speed(str /* Convert Kbps to Android Mbps */ link_speed = link_speed / 1000; bytes_written = snprintf(command, total_len, "LinkSpeed %d", link_speed); - DHD_INFO(("%s: command result is %s\n", __FUNCTION__, command)); + ANDROID_INFO(("%s: command result is %s\n", __FUNCTION__, command)); return bytes_written; } @@ -217,18 +228,21 @@ static int wl_android_get_rssi(struct ne error = wldev_get_rssi(net, &rssi); if (error) return -1; +#if defined(RSSIOFFSET) + rssi = wl_update_rssi_offset(rssi); +#endif error = wldev_get_ssid(net, &ssid); if (error) return -1; if ((ssid.SSID_len == 0) || (ssid.SSID_len > DOT11_MAX_SSID_LEN)) { - DHD_ERROR(("%s: wldev_get_ssid failed\n", __FUNCTION__)); + ANDROID_ERROR(("%s: wldev_get_ssid failed\n", __FUNCTION__)); } else { memcpy(command, ssid.SSID, ssid.SSID_len); bytes_written = ssid.SSID_len; } bytes_written += snprintf(&command[bytes_written], total_len, " rssi %d", rssi); - DHD_INFO(("%s: command result is %s (%d)\n", __FUNCTION__, command, bytes_written)); + ANDROID_INFO(("%s: command result is %s (%d)\n", __FUNCTION__, command, bytes_written)); return bytes_written; } @@ -238,19 +252,19 @@ static int wl_android_set_suspendopt(str int ret_now; int ret = 0; - suspend_flag = *(command + strlen(CMD_SETSUSPENDOPT) + 1) - '0'; + suspend_flag = *(command + strlen(CMD_SETSUSPENDOPT) + 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, 1))) - DHD_INFO(("%s: Suspend Flag %d -> %d\n", - __FUNCTION__, ret_now, suspend_flag)); - else - DHD_ERROR(("%s: failed %d\n", __FUNCTION__, ret)); - } + 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, 1))) + ANDROID_INFO(("%s: Suspend Flag %d -> %d\n", + __FUNCTION__, ret_now, suspend_flag)); + else + ANDROID_ERROR(("%s: failed %d\n", __FUNCTION__, ret)); + } return ret; } @@ -262,15 +276,15 @@ static int wl_android_set_suspendmode(st int suspend_flag; suspend_flag = *(command + strlen(CMD_SETSUSPENDMODE) + 1) - '0'; + if (suspend_flag != 0) suspend_flag = 1; if (!(ret = net_os_set_suspend(dev, suspend_flag, 0))) - DHD_INFO(("%s: Suspend Mode %d\n", __FUNCTION__, suspend_flag)); + ANDROID_INFO(("%s: Suspend Mode %d\n",__FUNCTION__,suspend_flag)); else - DHD_ERROR(("%s: failed %d\n", __FUNCTION__, ret)); + ANDROID_ERROR(("%s: failed %d\n",__FUNCTION__,ret)); #endif - return ret; } @@ -287,118 +301,7 @@ static int wl_android_get_band(struct ne return bytes_written; } - -#ifdef PNO_SUPPORT -#define PARAM_SIZE 50 -#define VALUE_SIZE 50 -static int -wls_parse_batching_cmd(struct net_device *dev, char *command, int total_len) -{ - int err = BCME_OK; - uint i, tokens; - char *pos, *pos2, *token, *token2, *delim; - char param[PARAM_SIZE], value[VALUE_SIZE]; - struct dhd_pno_batch_params batch_params; - DHD_PNO(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len)); - if (total_len < strlen(CMD_WLS_BATCHING)) { - DHD_ERROR(("%s argument=%d less min size\n", __FUNCTION__, total_len)); - err = BCME_ERROR; - goto exit; - } - pos = command + strlen(CMD_WLS_BATCHING) + 1; - memset(&batch_params, 0, sizeof(struct dhd_pno_batch_params)); - - if (!strncmp(pos, PNO_BATCHING_SET, strlen(PNO_BATCHING_SET))) { - pos += strlen(PNO_BATCHING_SET) + 1; - while ((token = strsep(&pos, PNO_PARAMS_DELIMETER)) != NULL) { - memset(param, 0, sizeof(param)); - memset(value, 0, sizeof(value)); - if (token == NULL || !*token) - break; - if (*token == '\0') - continue; - delim = strchr(token, PNO_PARAM_VALUE_DELLIMETER); - if (delim != NULL) - *delim = ' '; - - tokens = sscanf(token, "%s %s", param, value); - if (!strncmp(param, PNO_PARAM_SCANFREQ, strlen(PNO_PARAM_MSCAN))) { - batch_params.scan_fr = simple_strtol(value, NULL, 0); - DHD_PNO(("scan_freq : %d\n", batch_params.scan_fr)); - } else if (!strncmp(param, PNO_PARAM_BESTN, strlen(PNO_PARAM_MSCAN))) { - batch_params.bestn = simple_strtol(value, NULL, 0); - DHD_PNO(("bestn : %d\n", batch_params.bestn)); - } else if (!strncmp(param, PNO_PARAM_MSCAN, strlen(PNO_PARAM_MSCAN))) { - batch_params.mscan = simple_strtol(value, NULL, 0); - DHD_PNO(("mscan : %d\n", batch_params.mscan)); - } else if (!strncmp(param, PNO_PARAM_CHANNEL, strlen(PNO_PARAM_MSCAN))) { - i = 0; - pos2 = value; - tokens = sscanf(value, "<%s>", value); - if (tokens != 1) { - err = BCME_ERROR; - DHD_ERROR(("%s : invalid format for channel" - " <> params\n", __FUNCTION__)); - goto exit; - } - while ((token2 = strsep(&pos2, - PNO_PARAM_CHANNEL_DELIMETER)) != NULL) { - if (token2 == NULL || !*token2) - break; - if (*token2 == '\0') - continue; - if (*token2 == 'A' || *token2 == 'B') { - batch_params.band = (*token2 == 'A')? - WLC_BAND_5G : WLC_BAND_2G; - DHD_PNO(("band : %s\n", - (*token2 == 'A')? "A" : "B")); - } else { - batch_params.chan_list[i++] = - simple_strtol(token2, NULL, 0); - batch_params.nchan++; - DHD_PNO(("channel :%d\n", - batch_params.chan_list[i-1])); - } - } - } else if (!strncmp(param, PNO_PARAM_RTT, strlen(PNO_PARAM_MSCAN))) { - batch_params.rtt = simple_strtol(value, NULL, 0); - DHD_PNO(("rtt : %d\n", batch_params.rtt)); - } else { - DHD_ERROR(("%s : unknown param: %s\n", __FUNCTION__, param)); - err = BCME_ERROR; - goto exit; - } - } - err = dhd_dev_pno_set_for_batch(dev, &batch_params); - if (err < 0) { - DHD_ERROR(("failed to configure batch scan\n")); - } else { - memset(command, 0, total_len); - err = sprintf(command, "%d", err); - } - } else if (!strncmp(pos, PNO_BATCHING_GET, strlen(PNO_BATCHING_GET))) { - err = dhd_dev_pno_get_for_batch(dev, command, total_len); - if (err < 0) { - DHD_ERROR(("failed to getting batching results\n")); - } - } else if (!strncmp(pos, PNO_BATCHING_STOP, strlen(PNO_BATCHING_STOP))) { - err = dhd_dev_pno_stop_for_batch(dev); - if (err < 0) { - DHD_ERROR(("failed to stop batching scan\n")); - } else { - memset(command, 0, total_len); - err = sprintf(command, "OK"); - } - } else { - DHD_ERROR(("%s : unknown command\n", __FUNCTION__)); - err = BCME_ERROR; - goto exit; - } -exit: - return err; -} - -#ifndef WL_SCHED_SCAN +#if defined(PNO_SUPPORT) && !defined(WL_SCHED_SCAN) static int wl_android_set_pno_setup(struct net_device *dev, char *command, int total_len) { wlc_ssid_t ssids_local[MAX_PFN_LIST_COUNT]; @@ -431,16 +334,23 @@ static int wl_android_set_pno_setup(stru 0x00 }; #endif /* PNO_SET_DEBUG */ - DHD_PNO(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len)); + + ANDROID_INFO(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len)); if (total_len < (strlen(CMD_PNOSETUP_SET) + sizeof(cmd_tlv_t))) { - DHD_ERROR(("%s argument=%d less min size\n", __FUNCTION__, total_len)); + ANDROID_ERROR(("%s argument=%d less min size\n", __FUNCTION__, total_len)); 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++) + printf("%02X ", command[i]); + printf("\n"); total_len = sizeof(pno_in_example); #endif + str_ptr = command + strlen(CMD_PNOSETUP_SET); tlv_size_left = total_len - strlen(CMD_PNOSETUP_SET); @@ -449,57 +359,56 @@ static int wl_android_set_pno_setup(stru if ((cmd_tlv_temp->prefix == PNO_TLV_PREFIX) && (cmd_tlv_temp->version == PNO_TLV_VERSION) && - (cmd_tlv_temp->subtype == PNO_TLV_SUBTYPE_LEGACY_PNO)) { + (cmd_tlv_temp->subver == PNO_TLV_SUBVERSION)) { str_ptr += sizeof(cmd_tlv_t); tlv_size_left -= sizeof(cmd_tlv_t); if ((nssid = wl_iw_parse_ssid_list_tlv(&str_ptr, ssids_local, MAX_PFN_LIST_COUNT, &tlv_size_left)) <= 0) { - DHD_ERROR(("SSID is not presented or corrupted ret=%d\n", nssid)); + ANDROID_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)) { - DHD_ERROR(("%s scan duration corrupted field size %d\n", + ANDROID_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); - DHD_PNO(("%s: pno_time=%d\n", __FUNCTION__, pno_time)); + ANDROID_INFO(("%s: pno_time=%d\n", __FUNCTION__, pno_time)); if (str_ptr[0] != 0) { if ((str_ptr[0] != PNO_TLV_FREQ_REPEAT)) { - DHD_ERROR(("%s pno repeat : corrupted field\n", + ANDROID_ERROR(("%s pno repeat : corrupted field\n", __FUNCTION__)); goto exit_proc; } str_ptr++; pno_repeat = simple_strtoul(str_ptr, &str_ptr, 16); - DHD_PNO(("%s :got pno_repeat=%d\n", __FUNCTION__, pno_repeat)); + ANDROID_INFO(("%s :got pno_repeat=%d\n", __FUNCTION__, pno_repeat)); if (str_ptr[0] != PNO_TLV_FREQ_EXPO_MAX) { - DHD_ERROR(("%s FREQ_EXPO_MAX corrupted field size\n", + ANDROID_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); - DHD_PNO(("%s: pno_freq_expo_max=%d\n", + ANDROID_INFO(("%s: pno_freq_expo_max=%d\n", __FUNCTION__, pno_freq_expo_max)); } } } else { - DHD_ERROR(("%s get wrong TLV command\n", __FUNCTION__)); + ANDROID_ERROR(("%s get wrong TLV command\n", __FUNCTION__)); goto exit_proc; } - res = dhd_dev_pno_set_for_ssid(dev, ssids_local, nssid, pno_time, pno_repeat, - pno_freq_expo_max, NULL, 0); + res = dhd_dev_pno_set(dev, ssids_local, nssid, pno_time, pno_repeat, pno_freq_expo_max); + exit_proc: return res; } -#endif /* !WL_SCHED_SCAN */ -#endif /* PNO_SUPPORT */ +#endif /* PNO_SUPPORT && !WL_SCHED_SCAN */ static int wl_android_get_p2p_dev_addr(struct net_device *ndev, char *command, int total_len) { @@ -513,7 +422,6 @@ static int wl_android_get_p2p_dev_addr(s return bytes_written; } - /** * Global function definitions (declared in wl_android.h) */ @@ -525,7 +433,7 @@ int wl_android_wifi_on(struct net_device printk("%s in\n", __FUNCTION__); if (!dev) { - DHD_ERROR(("%s: dev is null\n", __FUNCTION__)); + ANDROID_ERROR(("%s: dev is null\n", __FUNCTION__)); return -EINVAL; } @@ -536,25 +444,40 @@ int wl_android_wifi_on(struct net_device ret = sdioh_start(NULL, 0); if (ret == 0) break; - DHD_ERROR(("\nfailed to power up wifi chip, retry again (%d left) **\n\n", + ANDROID_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")); + ANDROID_ERROR(("\nfailed to power up wifi chip, max retry reached **\n\n")); goto exit; } ret = dhd_dev_reset(dev, FALSE); + if (ret) + goto err; sdioh_start(NULL, 1); if (!ret) { - if (dhd_dev_init_ioctl(dev) < 0) + if (dhd_dev_init_ioctl(dev) < 0) { ret = -EFAULT; + goto err; + } } +#if defined(PROP_TXSTATUS) && !defined(PROP_TXSTATUS_VSDB) + dhd_wlfc_init(bcmsdh_get_drvdata()); +#endif g_wifi_on = TRUE; } exit: dhd_net_if_unlock(dev); + printk("%s: Success\n", __FUNCTION__); + return ret; +err: + dhd_dev_reset(dev, TRUE); + sdioh_stop(NULL); + dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF); + dhd_net_if_unlock(dev); + printk("%s: Failed\n", __FUNCTION__); return ret; } @@ -565,12 +488,15 @@ int wl_android_wifi_off(struct net_devic printk("%s in\n", __FUNCTION__); if (!dev) { - DHD_TRACE(("%s: dev is null\n", __FUNCTION__)); + ANDROID_TRACE(("%s: dev is null\n", __FUNCTION__)); return -EINVAL; } dhd_net_if_lock(dev); if (g_wifi_on) { +#if defined(PROP_TXSTATUS) && !defined(PROP_TXSTATUS_VSDB) + dhd_wlfc_deinit(bcmsdh_get_drvdata()); +#endif ret = dhd_dev_reset(dev, TRUE); sdioh_stop(NULL); dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF); @@ -588,16 +514,15 @@ static int wl_android_set_fwpath(struct bcm_strncpy_s(fw_path, sizeof(fw_path), command + strlen(CMD_SETFWPATH) + 1, MOD_PARAM_PATHLEN - 1); if (strstr(fw_path, "apsta") != NULL) { - DHD_INFO(("GOT APSTA FIRMWARE\n")); + ANDROID_INFO(("GOT APSTA FIRMWARE\n")); ap_fw_loaded = TRUE; } else { - DHD_INFO(("GOT STA FIRMWARE\n")); + ANDROID_INFO(("GOT STA FIRMWARE\n")); ap_fw_loaded = FALSE; } return 0; } - static int wl_android_set_pmk(struct net_device *dev, char *command, int total_len) { @@ -612,14 +537,14 @@ wl_android_set_pmk(struct net_device *de memcpy((char *)pmk, command + strlen("SET_PMK "), 32); error = wldev_iovar_setbuf(dev, "okc_info_pmk", pmk, 32, smbuf, sizeof(smbuf), NULL); if (error) { - DHD_ERROR(("Failed to set PMK for OKC, error = %d\n", error)); + ANDROID_ERROR(("Failed to set PMK for OKC, error = %d\n", error)); } #ifdef OKC_DEBUG - DHD_ERROR(("PMK is ")); + ANDROID_ERROR(("PMK is ")); for (i = 0; i < 32; i++) - DHD_ERROR(("%02X ", pmk[i])); + ANDROID_ERROR(("%02X ", pmk[i])); - DHD_ERROR(("\n")); + ANDROID_ERROR(("\n")); #endif return error; } @@ -633,205 +558,38 @@ wl_android_okc_enable(struct net_device okc_enable = command[strlen(CMD_OKC_ENABLE) + 1] - '0'; error = wldev_iovar_setint(dev, "okc_enable", okc_enable); if (error) { - DHD_ERROR(("Failed to %s OKC, error = %d\n", + ANDROID_ERROR(("Failed to %s OKC, error = %d\n", okc_enable ? "enable" : "disable", error)); } - wldev_iovar_setint(dev, "ccx_enable", 0); - return error; } - - int wl_android_set_roam_mode(struct net_device *dev, char *command, int total_len) { int error = 0; int mode = 0; if (sscanf(command, "%*s %d", &mode) != 1) { - DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__)); + ANDROID_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__)); return -1; } error = wldev_iovar_setint(dev, "roam_off", mode); if (error) { - DHD_ERROR(("%s: Failed to set roaming Mode %d, error = %d\n", + ANDROID_ERROR(("%s: Failed to set roaming Mode %d, error = %d\n", __FUNCTION__, mode, error)); return -1; } else - DHD_ERROR(("%s: succeeded to set roaming Mode %d, error = %d\n", + ANDROID_ERROR(("%s: succeeded to set roaming Mode %d, error = %d\n", __FUNCTION__, mode, error)); return 0; } -static int -wl_android_iolist_add(struct net_device *dev, struct list_head *head, struct io_cfg *config) -{ - struct io_cfg *resume_cfg; - s32 ret; - - resume_cfg = kzalloc(sizeof(struct io_cfg), GFP_KERNEL); - if (!resume_cfg) - return -ENOMEM; - - if (config->iovar) { - ret = wldev_iovar_getint(dev, config->iovar, &resume_cfg->param); - if (ret) { - DHD_ERROR(("%s: Failed to get current %s value\n", - __FUNCTION__, config->iovar)); - goto error; - } - - ret = wldev_iovar_setint(dev, config->iovar, config->param); - if (ret) { - DHD_ERROR(("%s: Failed to set %s to %d\n", __FUNCTION__, - config->iovar, config->param)); - goto error; - } - - resume_cfg->iovar = config->iovar; - } else { - resume_cfg->arg = kzalloc(config->len, GFP_KERNEL); - if (!resume_cfg->arg) { - ret = -ENOMEM; - goto error; - } - ret = wldev_ioctl(dev, config->ioctl, resume_cfg->arg, config->len, false); - if (ret) { - DHD_ERROR(("%s: Failed to get ioctl %d\n", __FUNCTION__, - config->ioctl)); - goto error; - } - ret = wldev_ioctl(dev, config->ioctl + 1, config->arg, config->len, true); - if (ret) { - DHD_ERROR(("%s: Failed to set %s to %d\n", __FUNCTION__, - config->iovar, config->param)); - goto error; - } - if (config->ioctl + 1 == WLC_SET_PM) - wl_cfg80211_update_power_mode(dev); - resume_cfg->ioctl = config->ioctl; - resume_cfg->len = config->len; - } - - list_add(&resume_cfg->list, head); - - return 0; -error: - kfree(resume_cfg->arg); - kfree(resume_cfg); - return ret; -} - -static void -wl_android_iolist_resume(struct net_device *dev, struct list_head *head) -{ - struct io_cfg *config; - struct list_head *cur, *q; - s32 ret = 0; - - list_for_each_safe(cur, q, head) { - config = list_entry(cur, struct io_cfg, list); - if (config->iovar) { - if (!ret) - ret = wldev_iovar_setint(dev, config->iovar, - config->param); - } else { - if (!ret) - ret = wldev_ioctl(dev, config->ioctl + 1, - config->arg, config->len, true); - if (config->ioctl + 1 == WLC_SET_PM) - wl_cfg80211_update_power_mode(dev); - kfree(config->arg); - } - list_del(cur); - kfree(config); - } -} - -static int -wl_android_set_miracast(struct net_device *dev, char *command, int total_len) -{ - int mode, val; - int ret = 0; - struct io_cfg config; - - if (sscanf(command, "%*s %d", &mode) != 1) { - DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__)); - return -1; - } - - DHD_INFO(("%s: enter miracast mode %d\n", __FUNCTION__, mode)); - - if (miracast_cur_mode == mode) - return 0; - - wl_android_iolist_resume(dev, &miracast_resume_list); - miracast_cur_mode = MIRACAST_MODE_OFF; - - switch (mode) { - case MIRACAST_MODE_SOURCE: - /* setting mchan_algo to platform specific value */ - config.iovar = "mchan_algo"; - config.param = MIRACAST_MCHAN_ALGO; - ret = wl_android_iolist_add(dev, &miracast_resume_list, &config); - if (ret) - goto resume; - - /* setting mchan_bw to platform specific value */ - config.iovar = "mchan_bw"; - config.param = MIRACAST_MCHAN_BW; - ret = wl_android_iolist_add(dev, &miracast_resume_list, &config); - if (ret) - goto resume; - - /* setting apmdu to platform specific value */ - config.iovar = "ampdu_mpdu"; - config.param = MIRACAST_AMPDU_SIZE; - ret = wl_android_iolist_add(dev, &miracast_resume_list, &config); - if (ret) - goto resume; - /* FALLTROUGH */ - /* Source mode shares most configurations with sink mode. - * Fall through here to avoid code duplication - */ - case MIRACAST_MODE_SINK: - /* disable internal roaming */ - config.iovar = "roam_off"; - config.param = 1; - ret = wl_android_iolist_add(dev, &miracast_resume_list, &config); - if (ret) - goto resume; - /* tunr off pm */ - val = 0; - config.iovar = NULL; - config.ioctl = WLC_GET_PM; - config.arg = &val; - config.len = sizeof(int); - ret = wl_android_iolist_add(dev, &miracast_resume_list, &config); - if (ret) - goto resume; - - break; - case MIRACAST_MODE_OFF: - default: - break; - } - miracast_cur_mode = mode; - - return 0; - -resume: - DHD_ERROR(("%s: turnoff miracast mode because of err %d\n", __FUNCTION__, ret)); - wl_android_iolist_resume(dev, &miracast_resume_list); - return ret; -} - int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) { -#define PRIVATE_COMMAND_MAX_LEN 8192 +#define PRIVATE_COMMAND_MAX_LEN 8192 int ret = 0; char *command = NULL; int bytes_written = 0; @@ -849,14 +607,13 @@ int wl_android_priv_cmd(struct net_devic } if (priv_cmd.total_len > PRIVATE_COMMAND_MAX_LEN) { - DHD_ERROR(("%s: too long priavte command\n", __FUNCTION__)); + ANDROID_ERROR(("%s: too long priavte command\n", __FUNCTION__)); ret = -EINVAL; - goto exit; } - command = kmalloc((priv_cmd.total_len + 1), GFP_KERNEL); + command = kmalloc(priv_cmd.total_len, GFP_KERNEL); if (!command) { - DHD_ERROR(("%s: failed to allocate memory\n", __FUNCTION__)); + ANDROID_ERROR(("%s: failed to allocate memory\n", __FUNCTION__)); ret = -ENOMEM; goto exit; } @@ -864,12 +621,11 @@ int wl_android_priv_cmd(struct net_devic ret = -EFAULT; goto exit; } - command[priv_cmd.total_len] = '\0'; - DHD_INFO(("%s: Android private cmd \"%s\" on %s\n", __FUNCTION__, command, ifr->ifr_name)); + ANDROID_INFO(("%s: Android private cmd \"%s\" on %s\n", __FUNCTION__, command, ifr->ifr_name)); if (strnicmp(command, CMD_START, strlen(CMD_START)) == 0) { - DHD_INFO(("%s, Received regular START command\n", __FUNCTION__)); + ANDROID_INFO(("%s, Received regular START command\n", __FUNCTION__)); bytes_written = wl_android_wifi_on(net); } else if (strnicmp(command, CMD_SETFWPATH, strlen(CMD_SETFWPATH)) == 0) { @@ -877,7 +633,7 @@ int wl_android_priv_cmd(struct net_devic } if (!g_wifi_on) { - DHD_ERROR(("%s: Ignore private cmd \"%s\" - iface %s is down\n", + ANDROID_ERROR(("%s: Ignore private cmd \"%s\" - iface %s is down\n", __FUNCTION__, command, ifr->ifr_name)); ret = 0; goto exit; @@ -942,7 +698,16 @@ int wl_android_priv_cmd(struct net_devic } else if (strnicmp(command, CMD_SETBAND, strlen(CMD_SETBAND)) == 0) { uint band = *(command + strlen(CMD_SETBAND) + 1) - '0'; +#ifdef WL_HOST_BAND_MGMT + if (wl_cfg80211_set_band(net, band) < 0) { + bytes_written = -1; + goto exit; + } + if (band == WLC_BAND_AUTO) + bytes_written = wldev_set_band(net, band); +#else bytes_written = wldev_set_band(net, band); +#endif /* WL_HOST_BAND_MGMT */ } else if (strnicmp(command, CMD_GETBAND, strlen(CMD_GETBAND)) == 0) { bytes_written = wl_android_get_band(net, command, priv_cmd.total_len); @@ -951,28 +716,21 @@ int wl_android_priv_cmd(struct net_devic /* CUSTOMER_SET_COUNTRY feature is define for only GGSM model */ else if (strnicmp(command, CMD_COUNTRY, strlen(CMD_COUNTRY)) == 0) { char *country_code = command + strlen(CMD_COUNTRY) + 1; - bytes_written = wldev_set_country(net, country_code, true, true); + bytes_written = wldev_set_country(net, country_code); } #endif /* WL_CFG80211 */ - - -#ifdef PNO_SUPPORT -#ifndef WL_SCHED_SCAN +#if defined(PNO_SUPPORT) && !defined(WL_SCHED_SCAN) else if (strnicmp(command, CMD_PNOSSIDCLR_SET, strlen(CMD_PNOSSIDCLR_SET)) == 0) { - bytes_written = dhd_dev_pno_stop_for_ssid(net); + bytes_written = dhd_dev_pno_reset(net); } else if (strnicmp(command, CMD_PNOSETUP_SET, strlen(CMD_PNOSETUP_SET)) == 0) { bytes_written = wl_android_set_pno_setup(net, command, priv_cmd.total_len); } else if (strnicmp(command, CMD_PNOENABLE_SET, strlen(CMD_PNOENABLE_SET)) == 0) { - int enable = *(command + strlen(CMD_PNOENABLE_SET) + 1) - '0'; - bytes_written = (enable)? 0 : dhd_dev_pno_stop_for_ssid(net); - } -#endif - else if (strnicmp(command, CMD_WLS_BATCHING, strlen(CMD_WLS_BATCHING)) == 0) { - bytes_written = wls_parse_batching_cmd(net, command, priv_cmd.total_len); + uint pfn_enabled = *(command + strlen(CMD_PNOENABLE_SET) + 1) - '0'; + bytes_written = dhd_dev_pno_enable(net, pfn_enabled); } -#endif /* PNO_SUPPORT */ +#endif /* PNO_SUPPORT && !WL_SCHED_SCAN */ else if (strnicmp(command, CMD_P2P_DEV_ADDR, strlen(CMD_P2P_DEV_ADDR)) == 0) { bytes_written = wl_android_get_p2p_dev_addr(net, command, priv_cmd.total_len); } @@ -1005,10 +763,8 @@ int wl_android_priv_cmd(struct net_devic bytes_written = wl_android_okc_enable(net, command, priv_cmd.total_len); else if (strnicmp(command, CMD_SETROAMMODE, strlen(CMD_SETROAMMODE)) == 0) bytes_written = wl_android_set_roam_mode(net, command, priv_cmd.total_len); - else if (strnicmp(command, CMD_MIRACAST, strlen(CMD_MIRACAST)) == 0) - bytes_written = wl_android_set_miracast(net, command, priv_cmd.total_len); else { - DHD_ERROR(("Unknown PRIVATE command %s - ignored\n", command)); + ANDROID_ERROR(("Unknown PRIVATE command %s - ignored\n", command)); snprintf(command, 3, "OK"); bytes_written = strlen("OK"); } @@ -1017,14 +773,14 @@ int wl_android_priv_cmd(struct net_devic if ((bytes_written == 0) && (priv_cmd.total_len > 0)) command[0] = '\0'; if (bytes_written >= priv_cmd.total_len) { - DHD_ERROR(("%s: bytes_written = %d\n", __FUNCTION__, bytes_written)); + ANDROID_ERROR(("%s: bytes_written = %d\n", __FUNCTION__, bytes_written)); bytes_written = priv_cmd.total_len; } else { bytes_written++; } priv_cmd.used_len = bytes_written; if (copy_to_user(priv_cmd.buf, command, bytes_written)) { - DHD_ERROR(("%s: failed to copy data to user buffer\n", __FUNCTION__)); + ANDROID_ERROR(("%s: failed to copy data to user buffer\n", __FUNCTION__)); ret = -EFAULT; } } @@ -1045,17 +801,14 @@ int wl_android_init(void) { int ret = 0; + dhd_msg_level |= DHD_ERROR_VAL; #ifdef ENABLE_INSMOD_NO_FW_LOAD dhd_download_fw_on_driverload = FALSE; #endif /* ENABLE_INSMOD_NO_FW_LOAD */ -#if defined(CUSTOMER_HW2) if (!iface_name[0]) { memset(iface_name, 0, IFNAMSIZ); bcm_strncpy_s(iface_name, IFNAMSIZ, "wlan", IFNAMSIZ); } -#endif - - return ret; } @@ -1063,37 +816,459 @@ int wl_android_exit(void) { int ret = 0; - return ret; } void wl_android_post_init(void) { - -#ifdef ENABLE_4335BT_WAR - bcm_bt_unlock(lock_cookie_wifi); - printk("%s: btlock released\n", __FUNCTION__); -#endif /* ENABLE_4335BT_WAR */ - if (!dhd_download_fw_on_driverload) { /* Call customer gpio to turn off power with WL_REG_ON signal */ dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF); - g_wifi_on = FALSE; + g_wifi_on = 0; + } +} + +#if defined(RSSIAVG) +void +wl_free_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl) +{ + wl_rssi_cache_t *node, *cur, **rssi_head; + int i=0; + + rssi_head = &rssi_cache_ctrl->m_cache_head; + node = *rssi_head; + + for (;node;) { + ANDROID_INFO(("%s: Free %d with BSSID %pM\n", + __FUNCTION__, i, &node->BSSID)); + cur = node; + node = cur->next; + kfree(cur); + i++; + } + *rssi_head = NULL; +} + +void +wl_delete_dirty_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl) +{ + wl_rssi_cache_t *node, *prev, **rssi_head; + int i = -1, tmp = 0; +#if defined(BSSCACHE) + int max = BSSCACHE_LEN; +#else + int max = RSSICACHE_LEN; +#endif + + rssi_head = &rssi_cache_ctrl->m_cache_head; + node = *rssi_head; + prev = node; + for (;node;) { + i++; + if (node->dirty >= max || node->dirty >= RSSICACHE_LEN) { + if (node == *rssi_head) { + tmp = 1; + *rssi_head = node->next; + } else { + tmp = 0; + prev->next = node->next; + } + ANDROID_INFO(("%s: Del %d with BSSID %pM\n", + __FUNCTION__, i, &node->BSSID)); + kfree(node); + if (tmp == 1) { + node = *rssi_head; + prev = node; + } else { + node = prev->next; + } + continue; + } + prev = node; + node = node->next; + } +} + +void +wl_reset_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl) +{ + wl_rssi_cache_t *node, **rssi_head; + + rssi_head = &rssi_cache_ctrl->m_cache_head; + + /* reset dirty */ + node = *rssi_head; + for (;node;) { + node->dirty += 1; + node = node->next; + } +} + +void +wl_update_connected_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, struct net_device *net) +{ + wl_rssi_cache_t *node, *prev, **rssi_head; + int j, k=0; + int rssi, error; + struct ether_addr bssid; + + error = wldev_ioctl(net, WLC_GET_BSSID, &bssid, sizeof(bssid), false); + if (error) + return; + error = wldev_get_rssi(net, &rssi); + if (error) + return; + + /* update RSSI */ + rssi_head = &rssi_cache_ctrl->m_cache_head; + node = *rssi_head; + for (;node;) { + if (!memcmp(&node->BSSID, &bssid, ETHER_ADDR_LEN)) { + ANDROID_INFO(("%s: Update %d with BSSID %pM, RSSI=%d\n", + __FUNCTION__, k, &bssid, rssi)); + for(j=0; jRSSI[j] = node->RSSI[j+1]; + node->RSSI[j] = rssi; + node->dirty = 0; + break; + } + prev = node; + node = node->next; + k++; + } +} + +void +wl_update_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, wl_scan_results_t *ss_list) +{ + wl_rssi_cache_t *node, *prev, *leaf, **rssi_head; + wl_bss_info_t *bi = NULL; + int i, j, k; + + if (!ss_list->count) + return; + + rssi_head = &rssi_cache_ctrl->m_cache_head; + + /* update RSSI */ + for (i = 0; i < ss_list->count; i++) { + node = *rssi_head; + prev = NULL; + k = 0; + bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : ss_list->bss_info; + for (;node;) { + if (!memcmp(&node->BSSID, &bi->BSSID, ETHER_ADDR_LEN)) { + ANDROID_INFO(("%s: Update %d with BSSID %pM, RSSI=%d, SSID \"%s\"\n", + __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID)); + for(j=0; jRSSI[j] = node->RSSI[j+1]; + node->RSSI[j] = dtoh16(bi->RSSI); + node->dirty = 0; + break; + } + prev = node; + node = node->next; + k++; + } + + if (node) + continue; + + leaf = kmalloc(sizeof(wl_rssi_cache_t), GFP_KERNEL); + if (!leaf) { + ANDROID_ERROR(("%s: Memory alloc failure %d\n", + __FUNCTION__, sizeof(wl_rssi_cache_t))); + return; + } + ANDROID_INFO(("%s: Add %d with cached BSSID %pM, RSSI=%d, SSID \"%s\" in the leaf\n", + __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID)); + + leaf->next = NULL; + leaf->dirty = 0; + memcpy(&leaf->BSSID, &bi->BSSID, ETHER_ADDR_LEN); + for (j=0; jRSSI[j] = dtoh16(bi->RSSI); + + if (!prev) + *rssi_head = leaf; + else + prev->next = leaf; + } +} + +int16 +wl_get_avg_rssi(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, void *addr) +{ + wl_rssi_cache_t *node, **rssi_head; + int j, rssi_sum, rssi=-200; + + rssi_head = &rssi_cache_ctrl->m_cache_head; + + /* reset dirty */ + node = *rssi_head; + for (;node;) { + if (!memcmp(&node->BSSID, addr, ETHER_ADDR_LEN)) { + rssi_sum = 0; + rssi = 0; + for (j=0; jRSSI[RSSIAVG_LEN-j-1]; + rssi = rssi_sum / j; + break; + } + node = node->next; + } + if (rssi >= -2) + rssi = -2; + if (rssi == -200) { + ANDROID_ERROR(("%s: BSSID %pM does not in RSSI cache\n", + __FUNCTION__, addr)); + } + return (int16)rssi; +} +#endif + +#if defined(RSSIOFFSET) +int +wl_update_rssi_offset(int rssi) +{ + uint chip, chiprev; + + chip = dhd_bus_chip_id(bcmsdh_get_drvdata()); + chiprev = dhd_bus_chiprev_id(bcmsdh_get_drvdata()); + if (chip == BCM4330_CHIP_ID && chiprev == BCM4330B2_CHIP_REV) { +#if defined(RSSIOFFSET_NEW) + int j; + for (j=0; j= -2) + rssi = -2; + return rssi; +} +#endif + +#if defined(BSSCACHE) +#define WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN 32 + +void +wl_free_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl) +{ + wl_bss_cache_t *node, *cur, **bss_head; + int i=0; + + ANDROID_TRACE(("%s called\n", __FUNCTION__)); + + bss_head = &bss_cache_ctrl->m_cache_head; + node = *bss_head; + + for (;node;) { + ANDROID_TRACE(("%s: Free %d with BSSID %pM\n", + __FUNCTION__, i, &node->results.bss_info->BSSID)); + cur = node; + node = cur->next; + kfree(cur); + i++; + } + *bss_head = NULL; +} + +void +wl_delete_dirty_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl) +{ + wl_bss_cache_t *node, *prev, **bss_head; + int i = -1, tmp = 0; + + bss_head = &bss_cache_ctrl->m_cache_head; + node = *bss_head; + prev = node; + for (;node;) { + i++; + if (node->dirty >= BSSCACHE_LEN) { + if (node == *bss_head) { + tmp = 1; + *bss_head = node->next; + } else { + tmp = 0; + prev->next = node->next; + } + ANDROID_TRACE(("%s: Del %d with BSSID %pM, RSSI=%d, SSID \"%s\"\n", + __FUNCTION__, i, &node->results.bss_info->BSSID, + dtoh16(node->results.bss_info->RSSI), node->results.bss_info->SSID)); + kfree(node); + if (tmp == 1) { + node = *bss_head; + prev = node; + } else { + node = prev->next; + } + continue; + } + prev = node; + node = node->next; + } +} + +void +wl_reset_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl) +{ + wl_bss_cache_t *node, **bss_head; + + bss_head = &bss_cache_ctrl->m_cache_head; + + /* reset dirty */ + node = *bss_head; + for (;node;) { + node->dirty += 1; + node = node->next; + } +} + +void +wl_update_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl, wl_scan_results_t *ss_list) +{ + wl_bss_cache_t *node, *prev, *leaf, *tmp, **bss_head; + wl_bss_info_t *bi = NULL; + int i, k=0; + + if (!ss_list->count) + return; + + bss_head = &bss_cache_ctrl->m_cache_head; + + for (i=0; i < ss_list->count; i++) { + node = *bss_head; + prev = NULL; + bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : ss_list->bss_info; + + for (;node;) { + if (!memcmp(&node->results.bss_info->BSSID, &bi->BSSID, ETHER_ADDR_LEN)) { + tmp = node; + leaf = kmalloc(dtoh32(bi->length) + WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN, GFP_KERNEL); + if (!leaf) { + ANDROID_ERROR(("%s: Memory alloc failure %d and keep old BSS info\n", + __FUNCTION__, dtoh32(bi->length) + WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN)); + break; + } + + memcpy(leaf->results.bss_info, bi, dtoh32(bi->length)); + leaf->next = node->next; + leaf->dirty = 0; + leaf->results.count = 1; + leaf->results.version = ss_list->version; + ANDROID_TRACE(("%s: Update %d with BSSID %pM, RSSI=%d, SSID \"%s\"\n", + __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID)); + if (!prev) + *bss_head = leaf; + else + prev->next = leaf; + node = leaf; + prev = node; + + kfree(tmp); + k++; + break; + } + prev = node; + node = node->next; + } + + if (node) + continue; + + leaf = kmalloc(dtoh32(bi->length) + WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN, GFP_KERNEL); + if (!leaf) { + ANDROID_ERROR(("%s: Memory alloc failure %d\n", __FUNCTION__, + dtoh32(bi->length) + WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN)); + return; + } + ANDROID_TRACE(("%s: Add %d with cached BSSID %pM, RSSI=%d, SSID \"%s\" in the leaf\n", + __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID)); + + memcpy(leaf->results.bss_info, bi, dtoh32(bi->length)); + leaf->next = NULL; + leaf->dirty = 0; + leaf->results.count = 1; + leaf->results.version = ss_list->version; + k++; + + if (!prev) + *bss_head = leaf; + else + prev->next = leaf; + } +} + +void +wl_run_bss_cache_timer(wl_bss_cache_ctrl_t *bss_cache_ctrl, int kick_off) +{ + struct timer_list **timer; + + timer = &bss_cache_ctrl->m_timer; + + if (*timer) { + if (kick_off) { + (*timer)->expires = jiffies + BSSCACHE_TIME * HZ / 1000; + add_timer(*timer); + ANDROID_TRACE(("%s: timer starts\n", __FUNCTION__)); + } else { + del_timer_sync(*timer); + ANDROID_TRACE(("%s: timer stops\n", __FUNCTION__)); + } } } +void +wl_set_bss_cache_timer_flag(ulong data) +{ + wl_bss_cache_ctrl_t *bss_cache_ctrl = (wl_bss_cache_ctrl_t *)data; + + bss_cache_ctrl->m_timer_expired = 1; + ANDROID_TRACE(("%s called\n", __FUNCTION__)); +} + +void +wl_release_bss_cache_ctrl(wl_bss_cache_ctrl_t *bss_cache_ctrl) +{ + ANDROID_TRACE(("%s:\n", __FUNCTION__)); + wl_free_bss_cache(bss_cache_ctrl); + wl_run_bss_cache_timer(bss_cache_ctrl, 0); + if (bss_cache_ctrl->m_timer) { + kfree(bss_cache_ctrl->m_timer); + } +} + +void +wl_init_bss_cache_ctrl(wl_bss_cache_ctrl_t *bss_cache_ctrl) +{ + ANDROID_TRACE(("%s:\n", __FUNCTION__)); + bss_cache_ctrl->m_timer_expired = 0; + + bss_cache_ctrl->m_timer = kmalloc(sizeof(struct timer_list), GFP_KERNEL); + if (!bss_cache_ctrl->m_timer) { + ANDROID_ERROR(("%s: Memory alloc failure\n", __FUNCTION__ )); + return; + } + init_timer(bss_cache_ctrl->m_timer); + bss_cache_ctrl->m_timer->function = (void *)wl_set_bss_cache_timer_flag; + bss_cache_ctrl->m_timer->data = (ulong)bss_cache_ctrl; +} +#endif /** * Functions for Android WiFi card detection */ #if defined(CONFIG_WIFI_CONTROL_FUNC) -bool g_wifi_poweron = FALSE; static int g_wifidev_registered = 0; static struct semaphore wifi_control_sem; static struct wifi_platform_data *wifi_control_data = NULL; static struct resource *wifi_irqres = NULL; -static struct regulator *wifi_regulator = NULL; static int wifi_add_dev(void); static void wifi_del_dev(void); @@ -1105,7 +1280,7 @@ int wl_android_wifictrl_func_add(void) ret = wifi_add_dev(); if (ret) { - DHD_ERROR(("%s: platform_driver_register failed\n", __FUNCTION__)); + ANDROID_ERROR(("%s: platform_driver_register failed\n", __FUNCTION__)); return ret; } g_wifidev_registered = 1; @@ -1113,7 +1288,7 @@ int wl_android_wifictrl_func_add(void) /* Waiting callback after platform_driver_register is done or exit with error */ if (down_timeout(&wifi_control_sem, msecs_to_jiffies(1000)) != 0) { ret = -EINVAL; - DHD_ERROR(("%s: platform_driver_register timeout\n", __FUNCTION__)); + ANDROID_ERROR(("%s: platform_driver_register timeout\n", __FUNCTION__)); } return ret; @@ -1134,14 +1309,14 @@ void* wl_android_prealloc(int section, u 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)); + ANDROID_INFO(("success alloc section %d\n", section)); if (size != 0L) bzero(alloc_ptr, size); return alloc_ptr; } } - DHD_ERROR(("can't alloc section %d\n", section)); + ANDROID_ERROR(("can't alloc section %d\n", section)); return NULL; } @@ -1160,38 +1335,19 @@ int wifi_get_irq_number(unsigned long *i int wifi_set_power(int on, unsigned long msec) { - int ret = 0; - DHD_ERROR(("%s = %d\n", __FUNCTION__, on)); - if (wifi_regulator && on) - ret = regulator_enable(wifi_regulator); + ANDROID_ERROR(("%s = %d\n", __FUNCTION__, on)); if (wifi_control_data && wifi_control_data->set_power) { -#ifdef ENABLE_4335BT_WAR - if (on) { - printk("WiFi: trying to acquire BT lock\n"); - if (bcm_bt_lock(lock_cookie_wifi) != 0) - printk("** WiFi: timeout in acquiring bt lock**\n"); - printk("%s: btlock acquired\n", __FUNCTION__); - } - else { - /* For a exceptional case, release btlock */ - bcm_bt_unlock(lock_cookie_wifi); - } -#endif /* ENABLE_4335BT_WAR */ - ret = wifi_control_data->set_power(on); + wifi_control_data->set_power(on); } - - if (wifi_regulator && !on) - ret = regulator_disable(wifi_regulator); - - if (msec && !ret) - OSL_SLEEP(msec); - return ret; + if (msec) + msleep(msec); + return 0; } #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) int wifi_get_mac_addr(unsigned char *buf) { - DHD_ERROR(("%s\n", __FUNCTION__)); + ANDROID_ERROR(("%s\n", __FUNCTION__)); if (!buf) return -EINVAL; if (wifi_control_data && wifi_control_data->get_mac_addr) { @@ -1204,7 +1360,7 @@ int wifi_get_mac_addr(unsigned char *buf #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) void *wifi_get_country_code(char *ccode) { - DHD_TRACE(("%s\n", __FUNCTION__)); + ANDROID_TRACE(("%s\n", __FUNCTION__)); if (!ccode) return NULL; if (wifi_control_data && wifi_control_data->get_country_code) { @@ -1216,63 +1372,25 @@ void *wifi_get_country_code(char *ccode) static int wifi_set_carddetect(int on) { - DHD_ERROR(("%s = %d\n", __FUNCTION__, on)); + ANDROID_ERROR(("%s = %d\n", __FUNCTION__, on)); if (wifi_control_data && wifi_control_data->set_carddetect) { wifi_control_data->set_carddetect(on); } return 0; } -static struct resource *get_wifi_irqres_from_of(struct platform_device *pdev) -{ - static struct resource gpio_wifi_irqres; - int irq; - int gpio = of_get_gpio(pdev->dev.of_node, 0); - if (gpio < 0) - return NULL; - irq = gpio_to_irq(gpio); - if (irq < 0) - return NULL; - - gpio_wifi_irqres.name = "bcmdhd_wlan_irq"; - gpio_wifi_irqres.start = irq; - gpio_wifi_irqres.end = irq; - gpio_wifi_irqres.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | - IORESOURCE_IRQ_SHAREABLE; - - return &gpio_wifi_irqres; -} - static int wifi_probe(struct platform_device *pdev) { - int err; - struct regulator *regulator; struct wifi_platform_data *wifi_ctrl = (struct wifi_platform_data *)(pdev->dev.platform_data); - if (!wifi_ctrl) { - regulator = regulator_get(&pdev->dev, "wlreg_on"); - if (IS_ERR(regulator)) - return PTR_ERR(regulator); - wifi_regulator = regulator; - } - wifi_irqres = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "bcmdhd_wlan_irq"); if (wifi_irqres == NULL) wifi_irqres = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "bcm4329_wlan_irq"); - if (wifi_irqres == NULL) - wifi_irqres = get_wifi_irqres_from_of(pdev); wifi_control_data = wifi_ctrl; - err = wifi_set_power(1, 0); /* Power On */ - if (unlikely(err)) { - DHD_ERROR(("%s: set_power failed. err=%d\n", __FUNCTION__, err)); - wifi_set_power(0, WIFI_TURNOFF_DELAY); - /* WL_REG_ON state unknown, Power off forcely */ - } else { - wifi_set_carddetect(1); /* CardDetect (0->1) */ - g_wifi_poweron = TRUE; - } + wifi_set_power(1, 0); /* Power On */ + wifi_set_carddetect(1); /* CardDetect (0->1) */ up(&wifi_control_sem); return 0; @@ -1282,24 +1400,12 @@ static int wifi_remove(struct platform_d { struct wifi_platform_data *wifi_ctrl = (struct wifi_platform_data *)(pdev->dev.platform_data); - struct io_cfg *cur, *q; - DHD_ERROR(("## %s\n", __FUNCTION__)); + ANDROID_ERROR(("## %s\n", __FUNCTION__)); wifi_control_data = wifi_ctrl; - if (g_wifi_poweron) { wifi_set_power(0, WIFI_TURNOFF_DELAY); /* Power Off */ wifi_set_carddetect(0); /* CardDetect (1->0) */ - g_wifi_poweron = FALSE; - list_for_each_entry_safe(cur, q, &miracast_resume_list, list) { - list_del(&cur->list); - kfree(cur); - } - } - if (wifi_regulator) { - regulator_put(wifi_regulator); - wifi_regulator = NULL; - } up(&wifi_control_sem); return 0; @@ -1307,7 +1413,11 @@ static int wifi_remove(struct platform_d static int wifi_suspend(struct platform_device *pdev, pm_message_t state) { - DHD_TRACE(("##> %s\n", __FUNCTION__)); + ANDROID_TRACE(("##> %s\n", __FUNCTION__)); +#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI) + if (dhd_os_check_wakelock(bcmsdh_get_drvdata())) + return -EBUSY; +#endif /* defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI) */ #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)) && defined(OOB_INTR_ONLY) && 1 bcmsdh_oob_intr_set(0); #endif /* (OOB_INTR_ONLY) */ @@ -1316,7 +1426,7 @@ static int wifi_suspend(struct platform_ static int wifi_resume(struct platform_device *pdev) { - DHD_TRACE(("##> %s\n", __FUNCTION__)); + ANDROID_TRACE(("##> %s\n", __FUNCTION__)); #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); @@ -1324,12 +1434,6 @@ static int wifi_resume(struct platform_d return 0; } -static const struct of_device_id wifi_device_dt_match[] = { - { .compatible = "android,bcmdhd_wlan", }, - {}, -}; -MODULE_DEVICE_TABLE(of, wifi_device_dt_match); - static struct platform_driver wifi_device = { .probe = wifi_probe, .remove = wifi_remove, @@ -1337,7 +1441,6 @@ static struct platform_driver wifi_devic .resume = wifi_resume, .driver = { .name = "bcmdhd_wlan", - .of_match_table = wifi_device_dt_match, } }; @@ -1354,7 +1457,7 @@ static struct platform_driver wifi_devic static int wifi_add_dev(void) { int ret = 0; - DHD_TRACE(("## Calling platform_driver_register\n")); + ANDROID_TRACE(("## Calling platform_driver_register\n")); ret = platform_driver_register(&wifi_device); if (ret) return ret; @@ -1365,7 +1468,7 @@ static int wifi_add_dev(void) static void wifi_del_dev(void) { - DHD_TRACE(("## Unregister platform_driver_register\n")); + ANDROID_TRACE(("## Unregister platform_driver_register\n")); platform_driver_unregister(&wifi_device); platform_driver_unregister(&wifi_device_legacy); } diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/wl_android.h linux-sunxi-new/drivers/net/wireless/bcmdhd/wl_android.h --- linux-sunxi/drivers/net/wireless/bcmdhd/wl_android.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/wl_android.h 2014-02-15 00:43:44.795014136 +0100 @@ -1,7 +1,7 @@ /* * Linux cfg80211 driver - Android related functions * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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.h 367305 2012-11-07 13:49:55Z $ + * $Id: wl_android.h 367273 2012-11-07 09:58:55Z $ */ #include @@ -32,8 +32,6 @@ * automatically */ - - /** * Android platform dependent functions, feel free to add Android specific functions here * (save the macros in dhd). Please do NOT declare functions that are NOT exposed to dhd @@ -51,6 +49,69 @@ int wl_android_wifi_on(struct net_device int wl_android_wifi_off(struct net_device *dev); int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd); +#define BSSCACHE +#define RSSIAVG +#define RSSIOFFSET +//#define RSSIOFFSET_NEW + +#if defined(RSSIAVG) +#define RSSIAVG_LEN 8 +#define RSSICACHE_LEN 8 + +typedef struct wl_rssi_cache { + struct wl_rssi_cache *next; + int dirty; + struct ether_addr BSSID; + int16 RSSI[RSSIAVG_LEN]; +} wl_rssi_cache_t; + +typedef struct wl_rssi_cache_ctrl { + wl_rssi_cache_t *m_cache_head; +} wl_rssi_cache_ctrl_t; + +void wl_free_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl); +void wl_delete_dirty_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl); +void wl_reset_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl); +void wl_update_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, wl_scan_results_t *ss_list); +void wl_update_connected_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, struct net_device *net); +int16 wl_get_avg_rssi(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, void *addr); +#endif + +#if defined(RSSIOFFSET) +#define RSSI_OFFSET 5 +#define RSSI_MAX -80 +#define RSSI_MIN -94 +#define RSSI_INT ((RSSI_MAX-RSSI_MIN)/RSSI_OFFSET) +#define BCM4330_CHIP_ID 0x4330 +#define BCM4330B2_CHIP_REV 4 +int wl_update_rssi_offset(int rssi); +#endif + +#if defined(BSSCACHE) +#define BSSCACHE_LEN 8 +#define BSSCACHE_TIME 15000 + +typedef struct wl_bss_cache { + struct wl_bss_cache *next; + int dirty; + wl_scan_results_t results; +} wl_bss_cache_t; + +typedef struct wl_bss_cache_ctrl { + wl_bss_cache_t *m_cache_head; + struct timer_list *m_timer; + int m_timer_expired; +} wl_bss_cache_ctrl_t; + +void wl_free_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl); +void wl_delete_dirty_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl); +void wl_reset_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl); +void wl_update_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl, wl_scan_results_t *ss_list); +void wl_run_bss_cache_timer(wl_bss_cache_ctrl_t *bss_cache_ctrl, int kick_off); +void wl_release_bss_cache_ctrl(wl_bss_cache_ctrl_t *bss_cache_ctrl); +void wl_init_bss_cache_ctrl(wl_bss_cache_ctrl_t *bss_cache_ctrl); +#endif + #if defined(CONFIG_WIFI_CONTROL_FUNC) int wl_android_wifictrl_func_add(void); void wl_android_wifictrl_func_del(void); diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/wl_cfg80211.c linux-sunxi-new/drivers/net/wireless/bcmdhd/wl_cfg80211.c --- linux-sunxi/drivers/net/wireless/bcmdhd/wl_cfg80211.c 2014-01-27 01:30:30.100433249 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/wl_cfg80211.c 2014-02-15 00:43:44.791014047 +0100 @@ -1,7 +1,7 @@ /* * Linux cfg80211 driver * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -21,8 +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_cfg80211.c 419844 2013-08-23 00:07:03Z $ + * $Id: wl_cfg80211.c 374275 2012-12-12 11:44:18Z $ */ + #include #include #include @@ -41,9 +42,6 @@ #include #include #include -#ifdef PNO_SUPPORT -#include -#endif /* PNO_SUPPORT */ #include #include @@ -56,7 +54,6 @@ #include #include #include - #include #include #include @@ -66,15 +63,44 @@ #ifdef PROP_TXSTATUS #include #endif +#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 */ #ifdef WL11U -#if !defined(WL_ENABLE_P2P_IF) && !defined(WL_CFG80211_P2P_DEV_IF) -#error You should enable 'WL_ENABLE_P2P_IF' or 'WL_CFG80211_P2P_DEV_IF' \ - according to Kernel version and is supported only in Android-JB -#endif /* !WL_ENABLE_P2P_IF && !WL_CFG80211_P2P_DEV_IF */ +#ifndef WL_ENABLE_P2P_IF +#error "You should enable WL_ENABLE_P2P_IF and Only supported in JB" +#endif #endif /* WL11U */ - #define IW_WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED)) static struct device *cfg80211_parent_dev = NULL; @@ -85,16 +111,15 @@ u32 wl_dbg_level = WL_DBG_ERR; #ifdef VSDB /* sleep time to keep STA's connecting or connection for continuous af tx or finding a peer */ -#define DEFAULT_SLEEP_TIME_VSDB 120 +#define DEFAULT_SLEEP_TIME_VSDB 200 #define OFF_CHAN_TIME_THRESHOLD_MS 200 -#define AF_RETRY_DELAY_TIME 40 /* if sta is connected or connecting, sleep for a while before retry af tx or finding a peer */ #define WL_AF_TX_KEEP_PRI_CONNECTION_VSDB(wl) \ do { \ if (wl_get_drv_status(wl, CONNECTED, wl_to_prmry_ndev(wl)) || \ wl_get_drv_status(wl, CONNECTING, wl_to_prmry_ndev(wl))) { \ - OSL_SLEEP(DEFAULT_SLEEP_TIME_VSDB); \ + msleep(DEFAULT_SLEEP_TIME_VSDB); \ } \ } while (0) #else /* VSDB */ @@ -143,69 +168,6 @@ static const struct ieee80211_regdomain REG_RULE(5470-10, 5850+10, 40, 6, 20, 0), } }; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) && \ - (defined(WL_IFACE_COMB_NUM_CHANNELS) || defined(WL_CFG80211_P2P_DEV_IF)) -/* - * Possible interface combinations supported by driver - * - * ADHOC Mode - #ADHOC <= 1 on channels = 1 - * SoftAP Mode - #AP <= 1 on channels = 1 - * STA + P2P Mode - #STA <= 2, #{P2P-GO, P2P-client} <= 1, #P2P-device <= 1 - * on channels = 2 - */ -static const struct ieee80211_iface_limit softap_limits[] = { - { - .max = 1, - .types = BIT(NL80211_IFTYPE_AP), - }, -}; - -static const struct ieee80211_iface_limit sta_p2p_limits[] = { - /* - * During P2P-GO removal, P2P-GO is first changed to STA and later only - * removed. So setting maximum possible number of STA interfaces as 2 to - * accommodate the above behaviour. - */ - { - .max = 2, - .types = BIT(NL80211_IFTYPE_STATION), - }, - { - .max = 2, - .types = BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_P2P_CLIENT), - }, -#if defined(WL_CFG80211_P2P_DEV_IF) - { - .max = 1, - .types = BIT(NL80211_IFTYPE_P2P_DEVICE), - }, -#endif /* WL_CFG80211_P2P_DEV_IF */ - { - .max = 1, - .types = BIT(NL80211_IFTYPE_ADHOC), - }, -}; - -static const struct ieee80211_iface_combination -softap_iface_combinations[] = { - { - .num_different_channels = 1, - .max_interfaces = 1, - .limits = softap_limits, - .n_limits = ARRAY_SIZE(softap_limits), - }, -}; - -static const struct ieee80211_iface_combination -sta_p2p_iface_combinations[] = { - { - .num_different_channels = 2, - .max_interfaces = 3, - .limits = sta_p2p_limits, - .n_limits = ARRAY_SIZE(sta_p2p_limits), - }, -}; -#endif /* LINUX_VER >= 3.0 && (WL_IFACE_COMB_NUM_CHANNELS || WL_CFG80211_P2P_DEV_IF) */ /* Data Element Definitions */ #define WPS_ID_CONFIG_METHODS 0x1008 @@ -242,20 +204,6 @@ sta_p2p_iface_combinations[] = { #define PM_BLOCK 1 #define PM_ENABLE 0 - - - -#ifndef RSSI_OFFSET -#define RSSI_OFFSET 0 -#endif - -#ifndef IBSS_COALESCE_ALLOWED -#define IBSS_COALESCE_ALLOWED 0 -#endif - -#ifndef IBSS_INITIAL_SCAN_ALLOWED -#define IBSS_INITIAL_SCAN_ALLOWED 0 -#endif /* * cfg80211_ops api/callback list */ @@ -265,14 +213,8 @@ static s32 wl_frame_get_mgmt(u16 fc, con static s32 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_scan_request *request, struct cfg80211_ssid *this_ssid); -#if defined(WL_CFG80211_P2P_DEV_IF) -static s32 -wl_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request); -#else -static s32 -wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, +static s32 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_scan_request *request); -#endif /* WL_CFG80211_P2P_DEV_IF */ static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed); static s32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ibss_params *params); @@ -288,21 +230,10 @@ static int wl_cfg80211_connect(struct wi struct cfg80211_connect_params *sme); static s32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code); -#if defined(WL_CFG80211_P2P_DEV_IF) -static s32 -wl_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, - enum nl80211_tx_power_setting type, s32 mbm); -#else -static s32 -wl_cfg80211_set_tx_power(struct wiphy *wiphy, - enum nl80211_tx_power_setting type, s32 dbm); -#endif /* WL_CFG80211_P2P_DEV_IF */ -#if defined(WL_CFG80211_P2P_DEV_IF) -static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, - struct wireless_dev *wdev, s32 *dbm); -#else +static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy, + enum nl80211_tx_power_setting type, + s32 dbm); static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm); -#endif /* WL_CFG80211_P2P_DEV_IF */ static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev, u8 key_idx, bool unicast, bool multicast); @@ -318,10 +249,13 @@ static s32 wl_cfg80211_get_key(struct wi static s32 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy, struct net_device *dev, u8 key_idx); static s32 wl_cfg80211_resume(struct wiphy *wiphy); +#if defined(WL_SUPPORT_BACKPORTED_KPATCHES) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, \ + 2, 0)) static s32 wl_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, - bcm_struct_cfgdev *cfgdev, u64 cookie); + struct net_device *dev, u64 cookie); static s32 wl_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, u8* mac_addr); +#endif #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) static s32 wl_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow); #else @@ -333,15 +267,8 @@ static s32 wl_cfg80211_del_pmksa(struct struct cfg80211_pmksa *pmksa); static s32 wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev); -static void wl_cfg80211_scan_abort(struct wl_priv *wl); static s32 wl_notify_escan_complete(struct wl_priv *wl, struct net_device *ndev, bool aborted, bool fw_abort); -#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 2, 0) -static s32 wl_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, - u8 *peer, enum nl80211_tdls_operation oper); -#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(3, 2, 0) */ -static int wl_cfg80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev); - /* * event & event Q handlers for cfg80211 interfaces */ @@ -362,16 +289,18 @@ static void wl_wakeup_event(struct wl_pr 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, - bcm_struct_cfgdev *cfgdev, const wl_event_msg_t *e, void *data); + struct net_device *ndev, + const wl_event_msg_t *e, void *data); static s32 wl_notify_roaming_status(struct wl_priv *wl, - bcm_struct_cfgdev *cfgdev, const wl_event_msg_t *e, void *data); -static s32 wl_notify_scan_status(struct wl_priv *wl, bcm_struct_cfgdev *cfgdev, + struct net_device *ndev, + const wl_event_msg_t *e, void *data); +static s32 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev, const wl_event_msg_t *e, void *data); static s32 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev, const wl_event_msg_t *e, void *data, bool completed); 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, bcm_struct_cfgdev *cfgdev, +static s32 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev, const wl_event_msg_t *e, void *data); #ifdef WL_SCHED_SCAN static s32 @@ -379,16 +308,11 @@ wl_notify_sched_scan_results(struct wl_p const wl_event_msg_t *e, void *data); #endif /* WL_SCHED_SCAN */ #ifdef PNO_SUPPORT -static s32 wl_notify_pfn_status(struct wl_priv *wl, bcm_struct_cfgdev *cfgdev, +static s32 wl_notify_pfn_status(struct wl_priv *wl, struct net_device *ndev, const wl_event_msg_t *e, void *data); #endif /* PNO_SUPPORT */ static s32 wl_notifier_change_state(struct wl_priv *wl, struct net_info *_net_info, enum wl_status state, bool set); - -#ifdef WLTDLS -static s32 wl_tdls_event_handler(struct wl_priv *wl, bcm_struct_cfgdev *cfgdev, - const wl_event_msg_t *e, void *data); -#endif /* WLTDLS */ /* * register/deregister parent device */ @@ -426,6 +350,10 @@ static s32 wl_set_key_mgmt(struct net_de 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); @@ -435,7 +363,6 @@ static void wl_ch_to_chanspec(int ch, */ static void wl_rst_ie(struct wl_priv *wl); static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v); -static void wl_update_hidden_ap_ie(struct wl_bss_info *bi, u8 *ie_stream, u32 *ie_size); static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size); static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size); static u32 wl_get_ielen(struct wl_priv *wl); @@ -448,21 +375,22 @@ wl_cfg80211_add_iw_ie(struct wl_priv *wl uint8 ie_id, uint8 *data, uint8 data_len); #endif /* WL11U */ -static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *dev, void *data); +static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *dev); static void wl_free_wdev(struct wl_priv *wl); -#ifdef CONFIG_CFG80211_INTERNAL_REGDB static int wl_cfg80211_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request); -#endif /* CONFIG_CFG80211_INTERNAL_REGDB */ static s32 wl_inform_bss(struct wl_priv *wl); -static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi); -static s32 wl_update_bss_info(struct wl_priv *wl, struct net_device *ndev); +static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi, u8 is_roam_done); +static s32 wl_update_bss_info(struct wl_priv *wl, struct net_device *ndev, u8 is_roam_done); static chanspec_t wl_cfg80211_get_shared_freq(struct wiphy *wiphy); s32 wl_cfg80211_channel_to_freq(u32 channel); - +#if defined(DHCP_SCAN_SUPPRESS) static void wl_cfg80211_work_handler(struct work_struct *work); +static void wl_cfg80211_scan_supp_timerfunc(ulong data); +#endif /* DHCP_SCAN_SUPPRESS */ + static s32 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev, u8 key_idx, const u8 *mac_addr, struct key_params *params); @@ -530,14 +458,10 @@ static __used u32 wl_find_msb(u16 bit16) */ static int wl_setup_rfkill(struct wl_priv *wl, bool setup); static int wl_rfkill_set(void *data, bool blocked); -#ifdef DEBUGFS_CFG80211 -static s32 wl_setup_debugfs(struct wl_priv *wl); -static s32 wl_free_debugfs(struct wl_priv *wl); -#endif static wl_scan_params_t *wl_cfg80211_scan_alloc_params(int channel, int nprobes, int *out_params_size); -static bool check_dev_role_integrity(struct wl_priv *wl, u32 dev_role); +static void get_primary_mac(struct wl_priv *wl, struct ether_addr *mac); /* * Some external functions, TODO: move them to dhd_linux.h @@ -550,10 +474,10 @@ int dhd_start_xmit(struct sk_buff *skb, -#define RETURN_EIO_IF_NOT_UP(wlpriv) \ +#define CHECK_SYS_UP(wlpriv) \ do { \ - struct net_device *checkSysUpNDev = wl_to_prmry_ndev(wlpriv); \ - if (unlikely(!wl_get_drv_status(wlpriv, READY, checkSysUpNDev))) { \ + 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; \ } \ @@ -572,7 +496,6 @@ extern int dhd_wlfc_init(dhd_pub_t *dhd) extern void dhd_wlfc_deinit(dhd_pub_t *dhd); #endif /* PROP_TXSTATUS_VSDB */ - #if (WL_DBG_LEVEL > 0) #define WL_DBG_ESTR_MAX 50 static s8 wl_dbg_estr[][WL_DBG_ESTR_MAX] = { @@ -629,18 +552,18 @@ static s8 wl_dbg_estr[][WL_DBG_ESTR_MAX] } static struct ieee80211_rate __wl_rates[] = { - RATETAB_ENT(DOT11_RATE_1M, 0), - RATETAB_ENT(DOT11_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE), - RATETAB_ENT(DOT11_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE), - RATETAB_ENT(DOT11_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE), - RATETAB_ENT(DOT11_RATE_6M, 0), - RATETAB_ENT(DOT11_RATE_9M, 0), - RATETAB_ENT(DOT11_RATE_12M, 0), - RATETAB_ENT(DOT11_RATE_18M, 0), - RATETAB_ENT(DOT11_RATE_24M, 0), - RATETAB_ENT(DOT11_RATE_36M, 0), - RATETAB_ENT(DOT11_RATE_48M, 0), - RATETAB_ENT(DOT11_RATE_54M, 0) + RATETAB_ENT(WLC_RATE_1M, 0), + RATETAB_ENT(WLC_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE), + RATETAB_ENT(WLC_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE), + RATETAB_ENT(WLC_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE), + RATETAB_ENT(WLC_RATE_6M, 0), + RATETAB_ENT(WLC_RATE_9M, 0), + RATETAB_ENT(WLC_RATE_12M, 0), + RATETAB_ENT(WLC_RATE_18M, 0), + RATETAB_ENT(WLC_RATE_24M, 0), + RATETAB_ENT(WLC_RATE_36M, 0), + RATETAB_ENT(WLC_RATE_48M, 0), + RATETAB_ENT(WLC_RATE_54M, 0) }; #define wl_a_rates (__wl_rates + 4) @@ -704,29 +627,14 @@ 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 }; -#if defined(USE_DYNAMIC_MAXPKT_RXGLOM) -static int maxrxpktglom = 0; -#endif - /* IOCtl version read from targeted driver */ static int ioctl_version; -#ifdef DEBUGFS_CFG80211 -#define S_SUBLOGLEVEL 20 -static const struct { - u32 log_level; - char *sublogname; -} sublogname_map[] = { - {WL_DBG_ERR, "ERR"}, - {WL_DBG_INFO, "INFO"}, - {WL_DBG_DBG, "DBG"}, - {WL_DBG_SCAN, "SCAN"}, - {WL_DBG_TRACE, "TRACE"}, - {WL_DBG_P2P_ACTION, "P2PACTION"} -}; -#endif /* Return a new chanspec given a legacy chanspec * Returns INVCHANSPEC on error @@ -918,14 +826,7 @@ wl_cfg80211_default_mgmt_stypes[NUM_NL80 BIT(IEEE80211_STYPE_AUTH >> 4) | BIT(IEEE80211_STYPE_DEAUTH >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4) - }, -#if defined(WL_CFG80211_P2P_DEV_IF) - [NL80211_IFTYPE_P2P_DEVICE] = { - .tx = 0xffff, - .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | - BIT(IEEE80211_STYPE_PROBE_REQ >> 4) - }, -#endif /* WL_CFG80211_P2P_DEV_IF */ + } }; static void swap_key_from_BE(struct wl_wsec_key *key) @@ -1064,16 +965,14 @@ static chanspec_t wl_cfg80211_get_shared else { bss = (struct wl_bss_info *) (wl->extra_buf + 4); chspec = bss->chanspec; - WL_DBG(("Valid BSS Found. chanspec:%d \n", chspec)); } return chspec; } -static bcm_struct_cfgdev * -wl_cfg80211_add_monitor_if(char *name) +static struct net_device* wl_cfg80211_add_monitor_if(char *name) { -#if defined(WL_ENABLE_P2P_IF) || defined(WL_CFG80211_P2P_DEV_IF) +#if defined(WLP2P) && defined(WL_ENABLE_P2P_IF) WL_INFO(("wl_cfg80211_add_monitor_if: No more support monitor interface\n")); return ERR_PTR(-EOPNOTSUPP); #else @@ -1081,17 +980,12 @@ wl_cfg80211_add_monitor_if(char *name) dhd_add_monitor(name, &ndev); WL_INFO(("wl_cfg80211_add_monitor_if net device returned: 0x%p\n", ndev)); - return ndev_to_cfgdev(ndev); -#endif /* WL_ENABLE_P2P_IF || WL_CFG80211_P2P_DEV_IF */ + return ndev; +#endif /* defined(WLP2P) && defined(WL_ENABLE_P2P_IF) */ } -static bcm_struct_cfgdev * -wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, -#if defined(WL_CFG80211_P2P_DEV_IF) - const char *name, -#else - char *name, -#endif /* WL_CFG80211_P2P_DEV_IF */ +static struct net_device * +wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name, enum nl80211_iftype type, u32 *flags, struct vif_params *params) { @@ -1134,10 +1028,6 @@ wl_cfg80211_add_virtual_iface(struct wip return NULL; case NL80211_IFTYPE_MONITOR: return wl_cfg80211_add_monitor_if(name); -#if defined(WL_CFG80211_P2P_DEV_IF) - case NL80211_IFTYPE_P2P_DEVICE: - return wl_cfgp2p_add_p2p_disc_if(); -#endif /* WL_CFG80211_P2P_DEV_IF */ case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_STATION: wlif_type = WL_P2P_IF_CLIENT; @@ -1159,7 +1049,6 @@ wl_cfg80211_add_virtual_iface(struct wip return NULL; } if (wl->p2p_supported && (wlif_type != -1)) { - ASSERT(wl->p2p); /* ensure expectation of p2p initialization */ if (wl_get_p2p_status(wl, IF_DELETING)) { /* wait till IF_DEL is complete * release the lock for the unregister to proceed @@ -1168,7 +1057,8 @@ wl_cfg80211_add_virtual_iface(struct wip rtnl_unlock(); rollback_lock = true; } - WL_INFO(("Released the lock and wait till IF_DEL is complete\n")); + WL_INFO(("%s: Released the lock and wait till IF_DEL is complete\n", + __func__)); timeout = wait_event_interruptible_timeout(wl->netif_change_event, (wl_get_p2p_status(wl, IF_DELETING) == false), msecs_to_jiffies(MAX_WAIT_TIME)); @@ -1211,7 +1101,7 @@ wl_cfg80211_add_virtual_iface(struct wip memset(wl->p2p->vir_ifname, 0, IFNAMSIZ); strncpy(wl->p2p->vir_ifname, name, IFNAMSIZ - 1); - wl_cfg80211_scan_abort(wl); + wl_notify_escan_complete(wl, _ndev, true, true); #ifdef PROP_TXSTATUS_VSDB if (!wl->wlfc_on && !disable_proptx) { dhd->wlfc_enabled = true; @@ -1274,10 +1164,6 @@ wl_cfg80211_add_virtual_iface(struct wip val = 1; /* Disable firmware roaming for P2P interface */ wldev_iovar_setint(_ndev, "roam_off", val); - - if (mode != WL_MODE_AP) - wldev_iovar_setint(_ndev, "buf_key_b4_m4", 1); - WL_ERR((" virtual interface(%s) is " "created net attach done\n", wl->p2p->vir_ifname)); if (mode == WL_MODE_AP) @@ -1287,12 +1173,6 @@ wl_cfg80211_add_virtual_iface(struct wip else if (type == NL80211_IFTYPE_P2P_GO) dhd_mode = DHD_FLAG_P2P_GO_MODE; DNGL_FUNC(dhd_cfg80211_set_p2p_info, (wl, dhd_mode)); -#ifdef PROP_TXSTATUS_VSDB - if (dhd->plat_enable) - dhd->plat_enable((void *)dhd); -#endif /* PROP_TXSTATUS_VSDB */ - /* reinitialize completion to clear previous count */ - INIT_COMPLETION(wl->iface_disable); } else { /* put back the rtnl_lock again */ if (rollback_lock) @@ -1302,7 +1182,8 @@ wl_cfg80211_add_virtual_iface(struct wip /* put back the rtnl_lock again */ if (rollback_lock) rtnl_lock(); - return ndev_to_cfgdev(_ndev); + return _ndev; + } else { wl_clr_p2p_status(wl, IF_ADD); WL_ERR((" virtual interface(%s) is not created \n", wl->p2p->vir_ifname)); @@ -1312,8 +1193,6 @@ wl_cfg80211_add_virtual_iface(struct wip if (dhd->wlfc_enabled && wl->wlfc_on) { dhd->wlfc_enabled = false; dhd_wlfc_deinit(dhd); - if (dhd->plat_deinit) - dhd->plat_deinit((void *)dhd); wl->wlfc_on = false; } #endif /* PROP_TXSTATUS_VSDB */ @@ -1326,27 +1205,21 @@ fail: } static s32 -wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev) +wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, struct net_device *dev) { - struct net_device *dev = NULL; struct ether_addr p2p_mac; struct wl_priv *wl = wiphy_priv(wiphy); s32 timeout = -1; s32 ret = 0; - s32 index = -1; WL_DBG(("Enter\n")); -#if defined(WL_CFG80211_P2P_DEV_IF) - if (cfgdev->iftype == NL80211_IFTYPE_P2P_DEVICE) { - return wl_cfgp2p_del_p2p_disc_if(cfgdev); + if (wl->p2p_net == dev) { + /* Since there is no ifidx corresponding to p2p0, cmds to + * firmware should be routed through primary I/F + */ + dev = wl_to_prmry_ndev(wl); } -#endif /* WL_CFG80211_P2P_DEV_IF */ - dev = cfgdev_to_wlc_ndev(cfgdev, wl); - if (wl_cfgp2p_find_idx(wl, dev, &index) != BCME_OK) { - WL_ERR(("Find p2p index from ndev(%p) failed\n", dev)); - return BCME_ERROR; - } if (wl->p2p_supported) { memcpy(p2p_mac.octet, wl->p2p->int_addr.octet, ETHER_ADDR_LEN); @@ -1360,11 +1233,6 @@ wl_cfg80211_del_virtual_iface(struct wip } wldev_iovar_setint(dev, "mpc", 1); - if (wl->pm_enable_work_on) { - cancel_delayed_work_sync(&wl->pm_enable_work); - wl->pm_enable_work_on = false; - } - /* for GC */ if (wl_get_drv_status(wl, DISCONNECTING, dev) && (wl_get_mode_by_netdev(wl, dev) != WL_MODE_AP)) { @@ -1387,13 +1255,11 @@ wl_cfg80211_del_virtual_iface(struct wip WL_ERR(("Wait for Link Down event for GO !!!\n")); wait_for_completion_timeout(&wl->iface_disable, msecs_to_jiffies(500)); + } else { + msleep(300); } } - wl_cfgp2p_clear_management_ie(wl, index); - - if (wl_get_mode_by_netdev(wl, dev) != WL_MODE_AP) - wldev_iovar_setint(dev, "buf_key_b4_m4", 0); - + wl_cfgp2p_clear_management_ie(wl, wl_cfgp2p_find_idx(wl, dev)); /* delete interface after link down */ ret = wl_cfgp2p_ifdel(wl, &p2p_mac); /* Firmware could not delete the interface so we will not get WLC_E_IF @@ -1419,9 +1285,6 @@ wl_cfg80211_del_virtual_iface(struct wip WL_ERR(("IFDEL didn't complete properly\n")); } ret = dhd_del_monitor(dev); - if (wl_get_mode_by_netdev(wl, dev) == WL_MODE_AP) { - DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_CANCEL((dhd_pub_t *)(wl->pub)); - } } } return ret; @@ -1434,10 +1297,8 @@ wl_cfg80211_change_virtual_iface(struct { s32 ap = 0; s32 infra = 0; - s32 ibss = 0; s32 wlif_type; s32 mode = 0; - s32 err = BCME_OK; chanspec_t chspec; struct wl_priv *wl = wiphy_priv(wiphy); dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub); @@ -1452,7 +1313,6 @@ wl_cfg80211_change_virtual_iface(struct break; case NL80211_IFTYPE_ADHOC: mode = WL_MODE_IBSS; - ibss = 1; break; case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_P2P_CLIENT: @@ -1516,16 +1376,6 @@ wl_cfg80211_change_virtual_iface(struct WL_DBG(("Change_virtual_iface for transition from GO/AP to client/STA")); } - if (ibss) { - infra = 0; - wl_set_mode_by_netdev(wl, ndev, mode); - err = wldev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(s32), true); - if (err < 0) { - WL_ERR(("SET Adhoc error %d\n", err)); - return -EINVAL; - } - } - ndev->ieee80211_ptr->iftype = type; return 0; } @@ -1575,9 +1425,7 @@ wl_cfg80211_ifdel_ops(struct net_device { struct wl_priv *wl = wlcfg_drv_priv; bool rollback_lock = false; - s32 type = -1; - s32 bssidx = -1; - + s32 index = 0; #ifdef PROP_TXSTATUS_VSDB dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub); #endif /* PROP_TXSTATUS_VSDB */ @@ -1601,29 +1449,20 @@ wl_cfg80211_ifdel_ops(struct net_device if (rollback_lock) rtnl_unlock(); } - WL_ERR(("IF_DEL event called from dongle, net %p, vif name: %s\n", - ndev, wl->p2p->vir_ifname)); + WL_ERR(("IF_DEL event called from dongle, net %x, vif name: %s\n", + (unsigned int)ndev, wl->p2p->vir_ifname)); memset(wl->p2p->vir_ifname, '\0', IFNAMSIZ); - if (wl_cfgp2p_find_idx(wl, ndev, &bssidx) != BCME_OK) { - WL_ERR(("Find p2p bssidx from ndev(%p) failed\n", ndev)); - return BCME_ERROR; - } - if (wl_cfgp2p_find_type(wl, bssidx, &type) != BCME_OK) { - WL_ERR(("Find p2p type from bssidx(%d) failed\n", bssidx)); - return BCME_ERROR; - } - wl_to_p2p_bss_ndev(wl, type) = NULL; - wl_to_p2p_bss_bssidx(wl, type) = WL_INVALID; + index = wl_cfgp2p_find_idx(wl, ndev); + wl_to_p2p_bss_ndev(wl, index) = NULL; + wl_to_p2p_bss_bssidx(wl, index) = WL_INVALID; wl->p2p->vif_created = false; - WL_DBG(("type : %d\n", type)); + WL_DBG(("index : %d\n", index)); #ifdef PROP_TXSTATUS_VSDB if (dhd->wlfc_enabled && wl->wlfc_on) { dhd->wlfc_enabled = false; dhd_wlfc_deinit(dhd); - if (dhd->plat_deinit) - dhd->plat_deinit((void *)dhd); wl->wlfc_on = false; } #endif /* PROP_TXSTATUS_VSDB */ @@ -1669,14 +1508,13 @@ wl_cfg80211_notify_ifchange(void) /* Find listen channel */ static s32 wl_find_listen_channel(struct wl_priv *wl, - const u8 *ie, u32 ie_len) + u8 *ie, u32 ie_len) { wifi_p2p_ie_t *p2p_ie; u8 *end, *pos; s32 listen_channel; - pos = (u8 *)ie; - p2p_ie = wl_cfgp2p_find_p2pie(pos, ie_len); + p2p_ie = wl_cfgp2p_find_p2pie(ie, ie_len); if (p2p_ie == NULL) return 0; @@ -1776,8 +1614,20 @@ static void wl_scan_prep(struct wl_scan_ continue; if (request->channels[i]->band == IEEE80211_BAND_2GHZ) { +#ifdef WL_HOST_BAND_MGMT + if (wl->curr_band == WLC_BAND_5G) { + WL_DBG(("In 5G only mode, omit 2G channel:%d\n", channel)); + continue; + } +#endif /* WL_HOST_BAND_MGMT */ chanspec |= WL_CHANSPEC_BAND_2G; } else { +#ifdef WL_HOST_BAND_MGMT + if (wl->curr_band == WLC_BAND_2G) { + WL_DBG(("In 2G only mode, omit 5G channel:%d\n", channel)); + continue; + } +#endif /* WL_HOST_BAND_MGMT */ chanspec |= WL_CHANSPEC_BAND_5G; } @@ -1822,9 +1672,8 @@ static void wl_scan_prep(struct wl_scan_ htod32((n_ssids << WL_SCAN_PARAMS_NSSID_SHIFT) | (n_channels & WL_SCAN_PARAMS_COUNT_MASK)); - if (n_channels == 1) { - params->active_time = htod32(WL_SCAN_CONNECT_DWELL_TIME_MS); - params->nprobes = htod32(params->active_time / WL_SCAN_JOIN_PROBE_INTERVAL_MS); + if (n_channels == 1 && wl_get_drv_status_all(wl, CONNECTED)) { + params->active_time = WL_SCAN_CONNECT_DWELL_TIME_MS; } } @@ -1926,7 +1775,6 @@ wl_get_valid_channels(struct net_device return err; } - static s32 wl_run_escan(struct wl_priv *wl, struct net_device *ndev, struct cfg80211_scan_request *request, uint16 action) @@ -1945,11 +1793,9 @@ wl_run_escan(struct wl_priv *wl, struct u16 *default_chan_list = NULL; wl_uint32_list_t *list; struct net_device *dev = NULL; - p2p_scan_purpose_t p2p_scan_purpose = P2P_SCAN_PURPOSE_MIN; WL_DBG(("Enter \n")); - /* scan request can come with empty request : perform all default scan */ if (!wl) { err = -EINVAL; goto exit; @@ -1977,11 +1823,12 @@ wl_run_escan(struct wl_priv *wl, struct err = -ENOMEM; goto exit; } + wl_scan_prep(¶ms->params, request); params->version = htod32(ESCAN_REQ_VERSION); params->action = htod16(action); - wl_escan_set_sync_id(params->sync_id, wl); + params->sync_id = htod16(0x1234); if (params_size + sizeof("escan") >= WLC_IOCTL_MEDLEN) { WL_ERR(("ioctl buffer length not sufficient\n")); kfree(params); @@ -2018,8 +1865,19 @@ wl_run_escan(struct wl_priv *wl, struct n_valid_chan = dtoh32(list->count); for (i = 0; i < num_chans; i++) { +#ifdef WL_HOST_BAND_MGMT + int channel_band = 0; +#endif /* WL_HOST_BAND_MGMT */ _freq = request->channels[i]->center_freq; channel = ieee80211_frequency_to_channel(_freq); +#ifdef WL_HOST_BAND_MGMT + channel_band = (channel > CH_MAX_2G_CHANNEL) ? + WLC_BAND_5G : WLC_BAND_2G; + if ((wl->curr_band != WLC_BAND_AUTO) && + (wl->curr_band != channel_band) && + !IS_P2P_SOCIAL_CHANNEL(channel)) + continue; +#endif /* WL_HOST_BAND_MGMT */ /* ignore DFS channels */ if (request->channels[i]->flags & @@ -2038,13 +1896,12 @@ wl_run_escan(struct wl_priv *wl, struct } } - if (num_chans == SOCIAL_CHAN_CNT && ( + if (num_chans == 3 && ( (default_chan_list[0] == SOCIAL_CHAN_1) && (default_chan_list[1] == SOCIAL_CHAN_2) && (default_chan_list[2] == SOCIAL_CHAN_3))) { /* SOCIAL CHANNELS 1, 6, 11 */ search_state = WL_P2P_DISC_ST_SEARCH; - p2p_scan_purpose = P2P_SCAN_SOCIAL_CHANNEL; WL_INFO(("P2P SEARCH PHASE START \n")); } else if ((dev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION)) && (wl_get_mode_by_netdev(wl, dev) == WL_MODE_AP)) { @@ -2052,32 +1909,16 @@ wl_run_escan(struct wl_priv *wl, struct WL_INFO(("Already a GO. Do SEARCH Only")); search_state = WL_P2P_DISC_ST_SEARCH; num_chans = n_nodfs; - p2p_scan_purpose = P2P_SCAN_NORMAL; - } else if (num_chans == 1) { - p2p_scan_purpose = P2P_SCAN_CONNECT_TRY; - } else if (num_chans == SOCIAL_CHAN_CNT + 1) { - /* SOCIAL_CHAN_CNT + 1 takes care of the Progressive scan supported by - * the supplicant - */ - p2p_scan_purpose = P2P_SCAN_SOCIAL_CHANNEL; } else { WL_INFO(("P2P SCAN STATE START \n")); num_chans = n_nodfs; - p2p_scan_purpose = P2P_SCAN_NORMAL; } - } else { - err = -EINVAL; - goto exit; + } err = wl_cfgp2p_escan(wl, ndev, wl->active_scan, num_chans, default_chan_list, search_state, action, - wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE), NULL, - p2p_scan_purpose); - - if (!err) - wl->p2p->search_state = search_state; - + wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE)); kfree(default_chan_list); } exit: @@ -2101,8 +1942,7 @@ wl_do_escan(struct wl_priv *wl, struct w wl_scan_results_t *results; WL_SCAN(("Enter \n")); mutex_lock(&wl->usr_sync); - - results = wl_escan_get_buf(wl, FALSE); + results = (wl_scan_results_t *) wl->escan_info.escan_buf; results->version = 0; results->count = 0; results->buflen = WL_SCAN_RESULTS_FIXED_SIZE; @@ -2139,6 +1979,7 @@ __wl_cfg80211_scan(struct wiphy *wiphy, bool p2p_ssid; #ifdef WL11U bcm_tlv_t *interworking_ie; + u32 ie_len; #endif s32 err = 0; s32 bssidx = -1; @@ -2147,16 +1988,13 @@ __wl_cfg80211_scan(struct wiphy *wiphy, unsigned long flags; static s32 busy_count = 0; - dhd_pub_t *dhd; - - dhd = (dhd_pub_t *)(wl->pub); - if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) { - WL_ERR(("Invalid Scan Command at SoftAP mode\n")); - return -EINVAL; + /* If scan req comes for p2p0, send it over primary I/F + * Scan results will be delivered corresponding to cfg80211_scan_request + */ + if (ndev == wl->p2p_net) { + ndev = wl_to_prmry_ndev(wl); } - ndev = ndev_to_wlc_ndev(ndev, wl); - if (WL_DRV_STATUS_SENDING_AF_FRM_EXT(wl)) { WL_ERR(("Sending Action Frames. Try it again.\n")); return -EAGAIN; @@ -2241,16 +2079,13 @@ __wl_cfg80211_scan(struct wiphy *wiphy, } } if (!wl->p2p_supported || !p2p_scan(wl)) { + bssidx = wl_cfgp2p_find_idx(wl, ndev); - if (wl_cfgp2p_find_idx(wl, ndev, &bssidx) != BCME_OK) { - WL_ERR(("Find p2p index from ndev(%p) failed\n", - ndev)); - err = BCME_ERROR; - goto scan_out; - } #ifdef WL11U if ((interworking_ie = wl_cfg80211_find_interworking_ie( (u8 *)request->ie, request->ie_len)) != NULL) { + ie_len = interworking_ie->len; + err = wl_cfg80211_add_iw_ie(wl, ndev, bssidx, VNDR_IE_CUSTOM_FLAG, interworking_ie->id, interworking_ie->data, interworking_ie->len); @@ -2267,7 +2102,6 @@ __wl_cfg80211_scan(struct wiphy *wiphy, wldev_iovar_setint_bsscfg(ndev, "grat_arp", 0, bssidx); - wl->wl11u = FALSE; /* we don't care about error */ } #endif /* WL11U */ @@ -2286,8 +2120,6 @@ __wl_cfg80211_scan(struct wiphy *wiphy, /* we don't do iscan in ibss */ ssids = this_ssid; } - if (request && !p2p_scan(wl)) - WL_TRACE_HW4(("START SCAN\n")); wl->scan_request = request; wl_set_drv_status(wl, SCANNING, ndev); if (iscan_req) { @@ -2302,10 +2134,10 @@ __wl_cfg80211_scan(struct wiphy *wiphy, /* find my listen channel */ wl->afx_hdl->my_listen_chan = - wl_find_listen_channel(wl, request->ie, + wl_find_listen_channel(wl, (u8 *)request->ie, request->ie_len); err = wl_cfgp2p_enable_discovery(wl, ndev, - request->ie, request->ie_len); + request->ie, request->ie_len); if (unlikely(err)) { goto scan_out; @@ -2353,11 +2185,13 @@ __wl_cfg80211_scan(struct wiphy *wiphy, } scan_success: + busy_count = 0; return 0; scan_out: + if (err == BCME_BUSY || err == BCME_NOTREADY) { WL_ERR(("Scan err = (%d), busy?%d", err, -EBUSY)); err = -EBUSY; @@ -2384,43 +2218,33 @@ scan_out: if ((ret = wldev_ioctl(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false)) == 0) WL_ERR(("FW is connected with " MACDBG "/n", - MAC2STRDBG(bssid.octet))); + MAC2STRDBG(bssid.octet))); else WL_ERR(("GET BSSID failed with %d\n", ret)); - wl_cfg80211_scan_abort(wl); + wl_cfg80211_disconnect(wiphy, ndev, DOT11_RC_DISASSOC_LEAVING); } } else { busy_count = 0; } - wl_clr_drv_status(wl, SCANNING, ndev); if (timer_pending(&wl->scan_timeout)) del_timer_sync(&wl->scan_timeout); spin_lock_irqsave(&wl->cfgdrv_lock, flags); wl->scan_request = NULL; spin_unlock_irqrestore(&wl->cfgdrv_lock, flags); - return err; } -#if defined(WL_CFG80211_P2P_DEV_IF) -static s32 -wl_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) -#else static s32 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_scan_request *request) -#endif /* WL_CFG80211_P2P_DEV_IF */ { s32 err = 0; struct wl_priv *wl = wiphy_priv(wiphy); -#if defined(WL_CFG80211_P2P_DEV_IF) - struct net_device *ndev = wl_to_prmry_ndev(wl); -#endif /* WL_CFG80211_P2P_DEV_IF */ WL_DBG(("Enter \n")); - RETURN_EIO_IF_NOT_UP(wl); + CHECK_SYS_UP(wl); err = __wl_cfg80211_scan(wiphy, ndev, request, NULL); if (unlikely(err)) { @@ -2478,7 +2302,7 @@ static s32 wl_cfg80211_set_wiphy_params( struct net_device *ndev = wl_to_prmry_ndev(wl); s32 err = 0; - RETURN_EIO_IF_NOT_UP(wl); + CHECK_SYS_UP(wl); WL_DBG(("Enter\n")); if (changed & WIPHY_PARAM_RTS_THRESHOLD && (wl->conf->rts_threshold != wiphy->rts_threshold)) { @@ -2513,149 +2337,6 @@ static s32 wl_cfg80211_set_wiphy_params( return err; } -static chanspec_t channel_to_chanspec(struct wiphy *wiphy, struct net_device *dev, u32 channel) -{ - struct wl_priv *wl = wiphy_priv(wiphy); - u8 *buf = NULL; - wl_uint32_list_t *list; - int err = BCME_OK; - chanspec_t c = 0, ret_c = 0; - int bw = 0, tmp_bw = 0; - int i; - u32 tmp_c, sb; - u16 kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; -#define LOCAL_BUF_SIZE 1024 - buf = (u8 *) kzalloc(LOCAL_BUF_SIZE, kflags); - if (!buf) { - WL_ERR(("buf memory alloc failed\n")); - goto exit; - } - list = (wl_uint32_list_t *)(void *)buf; - list->count = htod32(WL_NUMCHANSPECS); - err = wldev_iovar_getbuf_bsscfg(dev, "chanspecs", NULL, - 0, buf, LOCAL_BUF_SIZE, 0, &wl->ioctl_buf_sync); - if (err != BCME_OK) { - WL_ERR(("get chanspecs failed with %d\n", err)); - goto exit; - } - for (i = 0; i < dtoh32(list->count); i++) { - c = dtoh32(list->element[i]); - if (channel <= CH_MAX_2G_CHANNEL) { - if (!CHSPEC_IS20(c)) - continue; - if (channel == CHSPEC_CHANNEL(c)) { - ret_c = c; - bw = 20; - goto exit; - } - } - if (CHSPEC_IS20(c)) { - tmp_c = CHSPEC_CHANNEL(c); - tmp_bw = 20; - } - else if (CHSPEC_IS40(c)) { - tmp_c = CHSPEC_CHANNEL(c); - if (CHSPEC_SB_UPPER(c)) { - tmp_c += CH_10MHZ_APART; - } else { - tmp_c -= CH_10MHZ_APART; - } - tmp_bw = 40; - } - else { - tmp_c = CHSPEC_CHANNEL(c); - sb = c & WL_CHANSPEC_CTL_SB_MASK; - if (sb == WL_CHANSPEC_CTL_SB_LL) { - tmp_c -= (CH_10MHZ_APART + CH_20MHZ_APART); - } else if (sb == WL_CHANSPEC_CTL_SB_LU) { - tmp_c -= CH_10MHZ_APART; - } else if (sb == WL_CHANSPEC_CTL_SB_UL) { - tmp_c += CH_10MHZ_APART; - } else { - /* WL_CHANSPEC_CTL_SB_UU */ - tmp_c += (CH_10MHZ_APART + CH_20MHZ_APART); - } - tmp_bw = 80; - } - if (tmp_c != channel) - continue; - - if (tmp_bw > bw) { - bw = tmp_bw; - ret_c = c; - } - } -exit: - if (buf) - kfree(buf); -#undef LOCAL_BUF_SIZE - WL_INFO(("return chanspec %x %d\n", ret_c, bw)); - return ret_c; -} - -void -wl_cfg80211_ibss_vsie_set_buffer(vndr_ie_setbuf_t *ibss_vsie, int ibss_vsie_len) -{ - struct wl_priv *wl = wlcfg_drv_priv; - - if (wl != NULL && ibss_vsie != NULL) { - if (wl->ibss_vsie != NULL) { - kfree(wl->ibss_vsie); - } - wl->ibss_vsie = ibss_vsie; - wl->ibss_vsie_len = ibss_vsie_len; - } -} - -static void -wl_cfg80211_ibss_vsie_free(struct wl_priv *wl) -{ - /* free & initiralize VSIE (Vendor Specific IE) */ - if (wl->ibss_vsie != NULL) { - kfree(wl->ibss_vsie); - wl->ibss_vsie = NULL; - wl->ibss_vsie_len = 0; - } -} - -s32 -wl_cfg80211_ibss_vsie_delete(struct net_device *dev) -{ - struct wl_priv *wl = wlcfg_drv_priv; - char *ioctl_buf = NULL; - s32 ret = BCME_OK; - - if (wl != NULL && wl->ibss_vsie != NULL) { - ioctl_buf = kmalloc(WLC_IOCTL_MEDLEN, GFP_KERNEL); - if (!ioctl_buf) { - WL_ERR(("ioctl memory alloc failed\n")); - return -ENOMEM; - } - - /* change the command from "add" to "del" */ - strncpy(wl->ibss_vsie->cmd, "del", VNDR_IE_CMD_LEN - 1); - wl->ibss_vsie->cmd[VNDR_IE_CMD_LEN - 1] = '\0'; - - ret = wldev_iovar_setbuf(dev, "ie", - wl->ibss_vsie, wl->ibss_vsie_len, - ioctl_buf, WLC_IOCTL_MEDLEN, NULL); - WL_ERR(("ret=%d\n", ret)); - - if (ret == BCME_OK) { - /* free & initiralize VSIE */ - kfree(wl->ibss_vsie); - wl->ibss_vsie = NULL; - wl->ibss_vsie_len = 0; - } - - if (ioctl_buf) { - kfree(ioctl_buf); - } - } - - return ret; -} - static s32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ibss_params *params) @@ -2667,70 +2348,49 @@ wl_cfg80211_join_ibss(struct wiphy *wiph struct cfg80211_ssid ssid; s32 scan_retry = 0; s32 err = 0; - int scan_suppress = 1; - size_t join_params_size; - chanspec_t chanspec; + bool rollback_lock = false; WL_TRACE(("In\n")); - RETURN_EIO_IF_NOT_UP(wl); - WL_INFO(("JOIN BSSID:" MACDBG "\n", MAC2STRDBG(params->bssid))); - if (!params->ssid || params->ssid_len <= 0) { - WL_ERR(("Invalid parameter\n")); - return -EINVAL; - } - if (wl_get_drv_status(wl, CONNECTED, dev)) { - struct wlc_ssid *ssid = (struct wlc_ssid *)wl_read_prof(wl, dev, WL_PROF_SSID); - u8 *bssid = (u8 *)wl_read_prof(wl, dev, WL_PROF_BSSID); - if (!params->bssid || (memcmp(params->bssid, bssid, ETHER_ADDR_LEN) == 0 && - memcmp(params->ssid, ssid->SSID, ssid->SSID_len) == 0)) { - WL_ERR(("Connection already existed to " MACDBG "\n", - MAC2STRDBG((u8 *)wl_read_prof(wl, dev, WL_PROF_BSSID)))); - return -EISCONN; - } - WL_ERR(("Ignore Previous connecton to %s (" MACDBG ")\n", - ssid->SSID, MAC2STRDBG(bssid))); + CHECK_SYS_UP(wl); + if (params->bssid) { + WL_ERR(("Invalid bssid\n")); + return -EOPNOTSUPP; } - - /* remove the VSIE */ - wl_cfg80211_ibss_vsie_delete(dev); - bss = cfg80211_get_ibss(wiphy, NULL, params->ssid, params->ssid_len); if (!bss) { - if (IBSS_INITIAL_SCAN_ALLOWED == TRUE) { - memcpy(ssid.ssid, params->ssid, params->ssid_len); - ssid.ssid_len = params->ssid_len; - do { - if (unlikely - (__wl_cfg80211_scan(wiphy, dev, NULL, &ssid) == - -EBUSY)) { - wl_delay(150); - } else { - break; - } - } while (++scan_retry < WL_SCAN_RETRY_MAX); - - /* wait 4 secons till scan done.... */ - schedule_timeout_interruptible(msecs_to_jiffies(4000)); - bss = cfg80211_get_ibss(wiphy, NULL, - params->ssid, params->ssid_len); + memcpy(ssid.ssid, params->ssid, params->ssid_len); + ssid.ssid_len = params->ssid_len; + do { + if (unlikely + (__wl_cfg80211_scan(wiphy, dev, NULL, &ssid) == + -EBUSY)) { + wl_delay(150); + } else { + break; + } + } while (++scan_retry < WL_SCAN_RETRY_MAX); + /* to allow scan_inform to propagate to cfg80211 plane */ + if (rtnl_is_locked()) { + rtnl_unlock(); + rollback_lock = true; } + + /* wait 4 secons till scan done.... */ + schedule_timeout_interruptible(msecs_to_jiffies(4000)); + if (rollback_lock) + rtnl_lock(); + bss = cfg80211_get_ibss(wiphy, NULL, + params->ssid, params->ssid_len); } - if (bss && ((IBSS_COALESCE_ALLOWED == TRUE) || - ((IBSS_COALESCE_ALLOWED == FALSE) && params->bssid && - !memcmp(bss->bssid, params->bssid, ETHER_ADDR_LEN)))) { + if (bss) { wl->ibss_starter = false; WL_DBG(("Found IBSS\n")); } else { wl->ibss_starter = true; } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)) - chan = params->chandef.chan; -#else chan = params->channel; -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)) */ if (chan) wl->channel = ieee80211_frequency_to_channel(chan->center_freq); - chanspec = channel_to_chanspec(wiphy, dev, wl->channel); /* * Join with specific BSSID and cached SSID * If SSID is zero join based on BSSID only @@ -2739,56 +2399,18 @@ wl_cfg80211_join_ibss(struct wiphy *wiph memcpy((void *)join_params.ssid.SSID, (void *)params->ssid, params->ssid_len); join_params.ssid.SSID_len = htod32(params->ssid_len); - if (params->bssid) { - memcpy(&join_params.params.bssid, params->bssid, ETHER_ADDR_LEN); - err = wldev_ioctl(dev, WLC_SET_DESIRED_BSSID, &join_params.params.bssid, - ETHER_ADDR_LEN, true); - if (unlikely(err)) { - WL_ERR(("Error (%d)\n", err)); - return err; - } - } else + if (params->bssid) + memcpy(&join_params.params.bssid, params->bssid, + ETHER_ADDR_LEN); + else memset(&join_params.params.bssid, 0, ETHER_ADDR_LEN); - wldev_iovar_setint(dev, "ibss_coalesce_allowed", IBSS_COALESCE_ALLOWED); - - if (IBSS_INITIAL_SCAN_ALLOWED == FALSE) { - scan_suppress = TRUE; - /* Set the SCAN SUPRESS Flag in the firmware to skip join scan */ - err = wldev_ioctl(dev, WLC_SET_SCANSUPPRESS, &scan_suppress, sizeof(int), true); - if (unlikely(err)) { - WL_ERR(("Scan Supress Setting failed(%d)\n", err)); - return err; - } - } - - join_params.params.chanspec_list[0] = chanspec; - join_params.params.chanspec_num = 1; - wldev_iovar_setint(dev, "chanspec", chanspec); - join_params_size = sizeof(join_params); - - /* Disable Authentication, IBSS will add key if it required */ - wldev_iovar_setint(dev, "wpa_auth", WPA_AUTH_DISABLED); - wldev_iovar_setint(dev, "wsec", 0); - err = wldev_ioctl(dev, WLC_SET_SSID, &join_params, - join_params_size, true); + sizeof(join_params), true); if (unlikely(err)) { WL_ERR(("Error (%d)\n", err)); return err; } - - if (IBSS_INITIAL_SCAN_ALLOWED == FALSE) { - scan_suppress = FALSE; - /* Restore the SCAN SUPPRESS Falg */ - err = wldev_ioctl(dev, WLC_SET_SCANSUPPRESS, - &scan_suppress, sizeof(int), true); - if (unlikely(err)) { - WL_ERR(("Reset SCAN Suppress Flag failed (%d)\n", err)); - return err; - } - } - wl_update_prof(wl, dev, NULL, &join_params.ssid, WL_PROF_SSID); return err; } @@ -2796,31 +2418,13 @@ static s32 wl_cfg80211_leave_ibss(struct { struct wl_priv *wl = wiphy_priv(wiphy); s32 err = 0; - scb_val_t scbval; - u8 *curbssid; - RETURN_EIO_IF_NOT_UP(wl); + CHECK_SYS_UP(wl); wl_link_down(wl); - WL_ERR(("Leave IBSS\n")); - curbssid = wl_read_prof(wl, dev, WL_PROF_BSSID); - wl_set_drv_status(wl, DISCONNECTING, dev); - scbval.val = 0; - memcpy(&scbval.ea, curbssid, ETHER_ADDR_LEN); - err = wldev_ioctl(dev, WLC_DISASSOC, &scbval, - sizeof(scb_val_t), true); - if (unlikely(err)) { - wl_clr_drv_status(wl, DISCONNECTING, dev); - WL_ERR(("error(%d)\n", err)); - return err; - } - - /* remove the VSIE */ - wl_cfg80211_ibss_vsie_delete(dev); return err; } - static s32 wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme) { @@ -2828,11 +2432,7 @@ wl_set_wpa_version(struct net_device *de struct wl_security *sec; s32 val = 0; s32 err = 0; - s32 bssidx; - if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) { - WL_ERR(("Find p2p index from dev(%p) failed\n", dev)); - return BCME_ERROR; - } + s32 bssidx = wl_cfgp2p_find_idx(wl, dev); if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) val = WPA_AUTH_PSK | @@ -2846,6 +2446,13 @@ wl_set_wpa_version(struct net_device *de 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)) { @@ -2857,6 +2464,28 @@ wl_set_wpa_version(struct net_device *de 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) @@ -2865,12 +2494,7 @@ wl_set_auth_type(struct net_device *dev, struct wl_security *sec; s32 val = 0; s32 err = 0; - s32 bssidx; - if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) { - WL_ERR(("Find p2p index from dev(%p) failed\n", dev)); - return BCME_ERROR; - } - + s32 bssidx = wl_cfgp2p_find_idx(wl, dev); switch (sme->auth_type) { case NL80211_AUTHTYPE_OPEN_SYSTEM: val = WL_AUTH_OPEN_SYSTEM; @@ -2908,13 +2532,10 @@ wl_set_set_cipher(struct net_device *dev s32 pval = 0; s32 gval = 0; s32 err = 0; - s32 wsec_val = 0; - - s32 bssidx; - if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) { - WL_ERR(("Find p2p index from dev(%p) failed\n", dev)); - return BCME_ERROR; - } +#ifdef BCMWAPI_WPI + s32 val = 0; +#endif + s32 bssidx = wl_cfgp2p_find_idx(wl, dev); if (sme->crypto.n_ciphers_pairwise) { switch (sme->crypto.ciphers_pairwise[0]) { @@ -2926,9 +2547,17 @@ wl_set_set_cipher(struct net_device *dev pval = TKIP_ENABLED; break; case WLAN_CIPHER_SUITE_CCMP: + pval = AES_ENABLED; + break; 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])); @@ -2950,6 +2579,12 @@ wl_set_set_cipher(struct net_device *dev 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)); @@ -2962,16 +2597,19 @@ wl_set_set_cipher(struct net_device *dev if (is_wps_conn(sme)) { if (sme->privacy) err = wldev_iovar_setint_bsscfg(dev, "wsec", 4, bssidx); +#ifdef BCMWAPI_WPI + else 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); + } +#endif else /* WPS-2.0 allows no security */ err = wldev_iovar_setint_bsscfg(dev, "wsec", 0, bssidx); } else { WL_DBG((" NO, is_wps_conn, Set pval | gval to WSEC")); - wsec_val = pval | gval; - - WL_DBG((" Set WSEC to fW 0x%x \n", wsec_val)); err = wldev_iovar_setint_bsscfg(dev, "wsec", - wsec_val, bssidx); + pval | gval, bssidx); } if (unlikely(err)) { WL_ERR(("error (%d)\n", err)); @@ -2992,11 +2630,7 @@ wl_set_key_mgmt(struct net_device *dev, struct wl_security *sec; s32 val = 0; s32 err = 0; - s32 bssidx; - if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) { - WL_ERR(("Find p2p index from dev(%p) failed\n", dev)); - return BCME_ERROR; - } + s32 bssidx = wl_cfgp2p_find_idx(wl, dev); if (sme->crypto.n_akm_suites) { err = wldev_iovar_getint(dev, "wpa_auth", &val); @@ -3033,9 +2667,24 @@ wl_set_key_mgmt(struct net_device *dev, 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); if (unlikely(err)) { WL_ERR(("could not set wpa_auth (%d)\n", err)); @@ -3057,11 +2706,7 @@ wl_set_set_sharedkey(struct net_device * struct wl_wsec_key key; s32 val; s32 err = 0; - s32 bssidx; - if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) { - WL_ERR(("Find p2p index from dev(%p) failed\n", dev)); - return BCME_ERROR; - } + s32 bssidx = wl_cfgp2p_find_idx(wl, dev); WL_DBG(("key len (%d)\n", sme->key_len)); if (sme->key_len) { @@ -3069,9 +2714,17 @@ wl_set_set_sharedkey(struct net_device * 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 | - NL80211_WPA_VERSION_2)) && + NL80211_WPA_VERSION_2 +#ifdef BCMWAPI_WPI + | NL80211_WAPI_VERSION_1 +#endif + )) && (sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 | - WLAN_CIPHER_SUITE_WEP104))) + WLAN_CIPHER_SUITE_WEP104 +#ifdef BCMWAPI_WPI + | WLAN_CIPHER_SUITE_SMS4 +#endif + ))) { memset(&key, 0, sizeof(key)); key.len = (u32) sme->key_len; @@ -3089,6 +2742,11 @@ wl_set_set_sharedkey(struct net_device * 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])); @@ -3119,11 +2777,10 @@ wl_set_set_sharedkey(struct net_device * return err; } -#if defined(ESCAN_RESULT_PATCH) +#ifdef ESCAN_RESULT_PATCH static u8 connect_req_bssid[6]; static u8 broad_bssid[6]; -#endif /* ESCAN_RESULT_PATCH */ - +#endif static s32 @@ -3135,9 +2792,6 @@ wl_cfg80211_connect(struct wiphy *wiphy, wl_extjoin_params_t *ext_join_params; struct wl_join_params join_params; size_t join_params_size; -#if defined(ROAM_ENABLE) && defined(ROAM_AP_ENV_DETECTION) - dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub); -#endif /* ROAM_AP_ENV_DETECTION */ s32 err = 0; wpa_ie_fixed_t *wpa_ie; bcm_tlv_t *wpa2_ie; @@ -3145,9 +2799,7 @@ wl_cfg80211_connect(struct wiphy *wiphy, u32 wpaie_len = 0; u32 chan_cnt = 0; struct ether_addr bssid; - s32 bssidx; int ret; - int wait_cnt; WL_DBG(("In\n")); @@ -3156,13 +2808,7 @@ wl_cfg80211_connect(struct wiphy *wiphy, return -EOPNOTSUPP; } - if (unlikely(sme->ssid_len > DOT11_MAX_SSID_LEN)) { - WL_ERR(("Invalid SSID info: SSID=%s, length=%d\n", - sme->ssid, sme->ssid_len)); - return -EINVAL; - } - - RETURN_EIO_IF_NOT_UP(wl); + CHECK_SYS_UP(wl); /* * Cancel ongoing scan to sync up with sme state machine of cfg80211. @@ -3172,21 +2818,16 @@ wl_cfg80211_connect(struct wiphy *wiphy, wl_notify_escan_complete(wl, dev, true, true); } #endif -#ifdef WL_SCHED_SCAN - if (wl->sched_scan_req) { - wl_cfg80211_sched_scan_stop(wiphy, wl_to_prmry_ndev(wl)); - } -#endif -#if defined(ESCAN_RESULT_PATCH) - if (sme->bssid) +#ifdef ESCAN_RESULT_PATCH + if (sme->bssid) { memcpy(connect_req_bssid, sme->bssid, ETHER_ADDR_LEN); - else + } + else { bzero(connect_req_bssid, ETHER_ADDR_LEN); + } bzero(broad_bssid, ETHER_ADDR_LEN); #endif -#if defined(USE_DYNAMIC_MAXPKT_RXGLOM) - maxrxpktglom = 0; -#endif + bzero(&bssid, sizeof(bssid)); if (!wl_get_drv_status(wl, CONNECTED, dev)&& (ret = wldev_ioctl(dev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false)) == 0) { @@ -3206,23 +2847,12 @@ wl_cfg80211_connect(struct wiphy *wiphy, WL_ERR(("error (%d)\n", err)); return err; } - wait_cnt = 500/10; - while (wl_get_drv_status(wl, DISCONNECTING, dev) && wait_cnt) { - WL_DBG(("Waiting for disconnection terminated, wait_cnt: %d\n", - wait_cnt)); - wait_cnt--; - OSL_SLEEP(10); + while (wl_get_drv_status(wl, DISCONNECTING, dev)) { + WL_ERR(("Waiting for disconnection terminated.\n")); + msleep(20); } } else WL_DBG(("Currently not associated!\n")); - } else { - /* if status is DISCONNECTING, wait for disconnection terminated max 500 ms */ - wait_cnt = 500/10; - while (wl_get_drv_status(wl, DISCONNECTING, dev) && wait_cnt) { - WL_DBG(("Waiting for disconnection terminated, wait_cnt: %d\n", wait_cnt)); - wait_cnt--; - OSL_SLEEP(10); - } } /* Clean BSSID */ @@ -3232,11 +2862,7 @@ wl_cfg80211_connect(struct wiphy *wiphy, if (p2p_is_on(wl) && (dev != wl_to_prmry_ndev(wl))) { /* we only allow to connect using virtual interface in case of P2P */ - if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) { - WL_ERR(("Find p2p index from dev(%p) failed\n", dev)); - return BCME_ERROR; - } - wl_cfgp2p_set_management_ie(wl, dev, bssidx, + wl_cfgp2p_set_management_ie(wl, dev, wl_cfgp2p_find_idx(wl, dev), VNDR_IE_ASSOCREQ_FLAG, sme->ie, sme->ie_len); } else if (dev == wl_to_prmry_ndev(wl)) { /* find the RSN_IE */ @@ -3260,27 +2886,13 @@ wl_cfg80211_connect(struct wiphy *wiphy, wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync); } - if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) { - WL_ERR(("Find p2p index from dev(%p) failed\n", dev)); - return BCME_ERROR; - } - err = wl_cfgp2p_set_management_ie(wl, dev, bssidx, + err = wl_cfgp2p_set_management_ie(wl, dev, wl_cfgp2p_find_idx(wl, dev), VNDR_IE_ASSOCREQ_FLAG, (u8 *)sme->ie, sme->ie_len); if (unlikely(err)) { return err; } } -#if defined(ROAM_ENABLE) && defined(ROAM_AP_ENV_DETECTION) - if (dhd->roam_env_detection && (wldev_iovar_setint(dev, "roam_env_detection", - AP_ENV_DETECT_NOT_USED) == BCME_OK)) { - s32 roam_trigger[2] = {WL_AUTO_ROAM_TRIGGER, WLC_BAND_ALL}; - err = wldev_ioctl(dev, WLC_SET_ROAM_TRIGGER, roam_trigger, - sizeof(roam_trigger), true); - if (unlikely(err)) { - WL_ERR((" failed to restore roam_trigger for auto env detection\n")); - } - } -#endif /* ROAM_AP_ENV_DETECTION */ + if (chan) { wl->channel = ieee80211_frequency_to_channel(chan->center_freq); chan_cnt = 1; @@ -3288,6 +2900,17 @@ wl_cfg80211_connect(struct wiphy *wiphy, chan->center_freq, chan_cnt)); } 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); @@ -3295,11 +2918,21 @@ wl_cfg80211_connect(struct wiphy *wiphy, WL_ERR(("Invalid wpa_version\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)) { @@ -3336,14 +2969,14 @@ wl_cfg80211_connect(struct wiphy *wiphy, wl_update_prof(wl, dev, NULL, &ext_join_params->ssid, WL_PROF_SSID); ext_join_params->ssid.SSID_len = htod32(ext_join_params->ssid.SSID_len); /* increate dwell time to receive probe response or detect Beacon - * from target AP at a noisy air only when channel info is provided in connect command + * from target AP at a noisy air only during connect command */ - ext_join_params->scan.active_time = chan_cnt ? WL_SCAN_JOIN_ACTIVE_DWELL_TIME_MS : -1; - ext_join_params->scan.passive_time = chan_cnt ? WL_SCAN_JOIN_PASSIVE_DWELL_TIME_MS : -1; + ext_join_params->scan.active_time = WL_SCAN_JOIN_ACTIVE_DWELL_TIME_MS; + ext_join_params->scan.passive_time = WL_SCAN_JOIN_PASSIVE_DWELL_TIME_MS; /* Set up join scan parameters */ ext_join_params->scan.scan_type = -1; - ext_join_params->scan.nprobes = chan_cnt ? - (ext_join_params->scan.active_time/WL_SCAN_JOIN_PROBE_INTERVAL_MS) : -1; + ext_join_params->scan.nprobes + = (ext_join_params->scan.active_time/WL_SCAN_JOIN_PROBE_INTERVAL_MS); ext_join_params->scan.home_time = -1; if (sme->bssid) @@ -3371,13 +3004,8 @@ wl_cfg80211_connect(struct wiphy *wiphy, ext_join_params->ssid.SSID_len)); } wl_set_drv_status(wl, CONNECTING, dev); - - if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) { - WL_ERR(("Find p2p index from dev(%p) failed\n", dev)); - return BCME_ERROR; - } err = wldev_iovar_setbuf_bsscfg(dev, "join", ext_join_params, join_params_size, - wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync); + wl->ioctl_buf, WLC_IOCTL_MAXLEN, wl_cfgp2p_find_idx(wl, dev), &wl->ioctl_buf_sync); kfree(ext_join_params); if (err) { wl_clr_drv_status(wl, CONNECTING, dev); @@ -3403,7 +3031,7 @@ set_ssid: memcpy(&join_params.params.bssid, ðer_bcast, ETH_ALEN); wl_ch_to_chanspec(wl->channel, &join_params, &join_params_size); - WL_DBG(("join_param_size %zu\n", join_params_size)); + WL_DBG(("join_param_size %d\n", join_params_size)); if (join_params.ssid.SSID_len < IEEE80211_MAX_SSID_LEN) { WL_INFO(("ssid \"%s\", len (%d)\n", join_params.ssid.SSID, @@ -3429,7 +3057,7 @@ wl_cfg80211_disconnect(struct wiphy *wip s32 err = 0; u8 *curbssid; WL_ERR(("Reason %d\n", reason_code)); - RETURN_EIO_IF_NOT_UP(wl); + CHECK_SYS_UP(wl); act = *(bool *) wl_read_prof(wl, dev, WL_PROF_ACT); curbssid = wl_read_prof(wl, dev, WL_PROF_BSSID); if (act) { @@ -3458,15 +3086,9 @@ wl_cfg80211_disconnect(struct wiphy *wip return err; } -#if defined(WL_CFG80211_P2P_DEV_IF) -static s32 -wl_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, - enum nl80211_tx_power_setting type, s32 mbm) -#else static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy, enum nl80211_tx_power_setting type, s32 dbm) -#endif /* WL_CFG80211_P2P_DEV_IF */ { struct wl_priv *wl = wiphy_priv(wiphy); @@ -3474,14 +3096,8 @@ wl_cfg80211_set_tx_power(struct wiphy *w u16 txpwrmw; s32 err = 0; s32 disable = 0; - s32 txpwrqdbm; -#if defined(WL_CFG80211_P2P_DEV_IF) - s32 dbm = MBM_TO_DBM(mbm); -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) - dbm = MBM_TO_DBM(dbm); -#endif /* WL_CFG80211_P2P_DEV_IF */ - RETURN_EIO_IF_NOT_UP(wl); + CHECK_SYS_UP(wl); switch (type) { case NL80211_TX_POWER_AUTOMATIC: break; @@ -3511,14 +3127,8 @@ wl_cfg80211_set_tx_power(struct wiphy *w txpwrmw = 0xffff; else txpwrmw = (u16) dbm; - txpwrqdbm = (s32)bcm_mw_to_qdbm(txpwrmw); -#ifdef SUPPORT_WL_TXPOWER - if (type == NL80211_TX_POWER_AUTOMATIC) - txpwrqdbm = 127; - else - txpwrqdbm |= WL_TXPWR_OVERRIDE; -#endif /* SUPPORT_WL_TXPOWER */ - err = wldev_iovar_setint(ndev, "qtxpower", txpwrqdbm); + err = wldev_iovar_setint(ndev, "qtxpower", + (s32) (bcm_mw_to_qdbm(txpwrmw))); if (unlikely(err)) { WL_ERR(("qtxpower error (%d)\n", err)); return err; @@ -3528,12 +3138,7 @@ wl_cfg80211_set_tx_power(struct wiphy *w return err; } -#if defined(WL_CFG80211_P2P_DEV_IF) -static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, - struct wireless_dev *wdev, s32 *dbm) -#else static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm) -#endif /* WL_CFG80211_P2P_DEV_IF */ { struct wl_priv *wl = wiphy_priv(wiphy); struct net_device *ndev = wl_to_prmry_ndev(wl); @@ -3541,7 +3146,7 @@ static s32 wl_cfg80211_get_tx_power(stru u8 result; s32 err = 0; - RETURN_EIO_IF_NOT_UP(wl); + CHECK_SYS_UP(wl); err = wldev_iovar_getint(ndev, "qtxpower", &txpwrdbm); if (unlikely(err)) { WL_ERR(("error (%d)\n", err)); @@ -3561,21 +3166,16 @@ wl_cfg80211_config_default_key(struct wi u32 index; s32 wsec; s32 err = 0; - s32 bssidx; - if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) { - WL_ERR(("Find p2p index from dev(%p) failed\n", dev)); - return BCME_ERROR; - } + s32 bssidx = wl_cfgp2p_find_idx(wl, dev); WL_DBG(("key index (%d)\n", key_idx)); - RETURN_EIO_IF_NOT_UP(wl); + CHECK_SYS_UP(wl); err = wldev_iovar_getint_bsscfg(dev, "wsec", &wsec, bssidx); if (unlikely(err)) { WL_ERR(("WLC_GET_WSEC error (%d)\n", err)); return err; } - /* fix IOT issue with Apple Airport */ - if (wsec == WEP_ENABLED) { + if (wsec & WEP_ENABLED) { /* Just select a new current key */ index = (u32) key_idx; index = htod32(index); @@ -3595,12 +3195,8 @@ wl_add_keyext(struct wiphy *wiphy, struc struct wl_priv *wl = wiphy_priv(wiphy); struct wl_wsec_key key; s32 err = 0; - s32 bssidx; + s32 bssidx = wl_cfgp2p_find_idx(wl, dev); s32 mode = wl_get_mode_by_netdev(wl, dev); - if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) { - WL_ERR(("Find p2p index from dev(%p) failed\n", dev)); - return BCME_ERROR; - } memset(&key, 0, sizeof(key)); key.index = (u32) key_idx; @@ -3666,6 +3262,12 @@ wl_add_keyext(struct wiphy *wiphy, struc 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; @@ -3697,18 +3299,13 @@ wl_cfg80211_add_key(struct wiphy *wiphy, struct wl_priv *wl = wiphy_priv(wiphy); s32 mode = wl_get_mode_by_netdev(wl, dev); WL_DBG(("key index (%d)\n", key_idx)); - RETURN_EIO_IF_NOT_UP(wl); + CHECK_SYS_UP(wl); - if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) { - WL_ERR(("Find p2p index from dev(%p) failed\n", dev)); - return BCME_ERROR; - } + bssidx = wl_cfgp2p_find_idx(wl, dev); - if (mac_addr && - ((params->cipher != WLAN_CIPHER_SUITE_WEP40) && - (params->cipher != WLAN_CIPHER_SUITE_WEP104))) { - wl_add_keyext(wiphy, dev, key_idx, mac_addr, params); - goto exit; + if (mac_addr) { + wl_add_keyext(wiphy, dev, key_idx, mac_addr, params); + goto exit; } memset(&key, 0, sizeof(key)); @@ -3754,16 +3351,20 @@ wl_cfg80211_add_key(struct wiphy *wiphy, val = AES_ENABLED; WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n")); break; +#ifdef BCMWAPI_WPI + case WLAN_CIPHER_SUITE_SMS4: + key.algo = CRYPTO_ALGO_SMS4; + val = SMS4_ENABLED; + WL_DBG((" * wl_cfg80211_add_key, set key " + " to WLAN_CIPHER_SUITE_SMS4\n")); + break; +#endif /* BCMWAPI_WPI */ default: WL_ERR(("Invalid cipher (0x%x)\n", params->cipher)); return -EINVAL; } /* Set the new key/index */ - if ((mode == WL_MODE_IBSS) && (val & (TKIP_ENABLED | AES_ENABLED))) { - WL_ERR(("IBSS KEY setted\n")); - wldev_iovar_setint(dev, "wpa_auth", WPA_AUTH_NONE); - } swap_key_from_BE(&key); err = wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync); @@ -3796,19 +3397,14 @@ wl_cfg80211_del_key(struct wiphy *wiphy, struct wl_wsec_key key; struct wl_priv *wl = wiphy_priv(wiphy); s32 err = 0; - s32 bssidx; - if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) { - WL_ERR(("Find p2p index from dev(%p) failed\n", dev)); - return BCME_ERROR; - } - WL_DBG(("Enter\n")); + s32 bssidx = wl_cfgp2p_find_idx(wl, dev); + WL_DBG(("Enter\n")); #ifndef IEEE80211W if ((key_idx >= DOT11_MAX_DEFAULT_KEYS) && (key_idx < DOT11_MAX_DEFAULT_KEYS+2)) return -EINVAL; #endif - - RETURN_EIO_IF_NOT_UP(wl); + CHECK_SYS_UP(wl); memset(&key, 0, sizeof(key)); key.flags = WL_PRIMARY_KEY; @@ -3845,13 +3441,10 @@ wl_cfg80211_get_key(struct wiphy *wiphy, struct wl_security *sec; s32 wsec; s32 err = 0; - s32 bssidx; - if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) { - WL_ERR(("Find p2p index from dev(%p) failed\n", dev)); - return BCME_ERROR; - } + s32 bssidx = wl_cfgp2p_find_idx(wl, dev); + WL_DBG(("key index (%d)\n", key_idx)); - RETURN_EIO_IF_NOT_UP(wl); + CHECK_SYS_UP(wl); memset(&key, 0, sizeof(key)); key.index = key_idx; swap_key_to_BE(&key); @@ -3859,7 +3452,7 @@ wl_cfg80211_get_key(struct wiphy *wiphy, params.key_len = (u8) min_t(u8, DOT11_MAX_KEY_SIZE, key.len); memcpy(params.key, key.data, params.key_len); - err = wldev_iovar_getint_bsscfg(dev, "wsec", &wsec, bssidx); + wldev_iovar_getint_bsscfg(dev, "wsec", &wsec, bssidx); if (unlikely(err)) { WL_ERR(("WLC_GET_WSEC error (%d)\n", err)); return err; @@ -3883,6 +3476,13 @@ wl_cfg80211_get_key(struct wiphy *wiphy, 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((" * wl_cfg80211_add_key, set key" + "to WLAN_CIPHER_SUITE_SMS4\n")); + break; +#endif default: WL_ERR(("Invalid algo (0x%x)\n", wsec)); return -EINVAL; @@ -3914,7 +3514,7 @@ wl_cfg80211_get_station(struct wiphy *wi s8 eabuf[ETHER_ADDR_STR_LEN]; #endif dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub); - RETURN_EIO_IF_NOT_UP(wl); + 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, ETHER_ADDR_LEN, wl->ioctl_buf, WLC_IOCTL_SMLEN, &wl->ioctl_buf_sync); @@ -3939,8 +3539,7 @@ wl_cfg80211_get_station(struct wiphy *wi bcm_ether_ntoa((const struct ether_addr *)mac, eabuf), sinfo->inactive_time, sta->idle * 1000)); #endif - } else if (wl_get_mode_by_netdev(wl, dev) == WL_MODE_BSS || - wl_get_mode_by_netdev(wl, dev) == WL_MODE_IBSS) { + } else if (wl_get_mode_by_netdev(wl, dev) == WL_MODE_BSS) { get_pktcnt_t pktcnt; u8 *curmacp = wl_read_prof(wl, dev, WL_PROF_BSSID); if (!wl_get_drv_status(wl, CONNECTED, dev) || @@ -3961,28 +3560,10 @@ wl_cfg80211_get_station(struct wiphy *wi if (err) { WL_ERR(("Could not get rate (%d)\n", err)); } else { -#if defined(USE_DYNAMIC_MAXPKT_RXGLOM) - int rxpktglom; -#endif rate = dtoh32(rate); sinfo->filled |= STATION_INFO_TX_BITRATE; sinfo->txrate.legacy = rate * 5; WL_DBG(("Rate %d Mbps\n", (rate / 2))); -#if defined(USE_DYNAMIC_MAXPKT_RXGLOM) - rxpktglom = ((rate/2) > 150) ? 20 : 10; - - if (maxrxpktglom != rxpktglom) { - maxrxpktglom = rxpktglom; - WL_DBG(("Rate %d Mbps, update bus:maxtxpktglom=%d\n", (rate/2), - maxrxpktglom)); - err = wldev_iovar_setbuf(dev, "bus:maxtxpktglom", - (char*)&maxrxpktglom, 4, wl->ioctl_buf, - WLC_IOCTL_MAXLEN, NULL); - if (err < 0) { - WL_ERR(("set bus:maxtxpktglom failed, %d\n", err)); - } - } -#endif } memset(&scb_val, 0, sizeof(scb_val)); @@ -3993,7 +3574,10 @@ wl_cfg80211_get_station(struct wiphy *wi WL_ERR(("Could not get rssi (%d)\n", err)); goto get_station_err; } - rssi = dtoh32(scb_val.val) + RSSI_OFFSET; + rssi = dtoh32(scb_val.val); +#if defined(RSSIOFFSET) + rssi = wl_update_rssi_offset(rssi); +#endif sinfo->filled |= STATION_INFO_SIGNAL; sinfo->signal = rssi; WL_DBG(("RSSI %d dBm\n", rssi)); @@ -4012,15 +3596,12 @@ wl_cfg80211_get_station(struct wiphy *wi get_station_err: if (err && (err != -ERESTARTSYS)) { /* Disconnect due to zero BSSID or error to get RSSI */ - WL_ERR(("force cfg80211_disconnected: %d\n", err)); + WL_ERR(("force cfg80211_disconnected\n")); wl_clr_drv_status(wl, CONNECTED, dev); cfg80211_disconnected(dev, 0, NULL, 0, GFP_KERNEL); wl_link_down(wl); } } - else { - WL_ERR(("Invalid device mode %d\n", wl_get_mode_by_netdev(wl, dev))); - } return err; } @@ -4053,35 +3634,25 @@ wl_cfg80211_set_power_mgmt(struct wiphy struct net_info *_net_info = wl_get_netinfo_by_netdev(wl, dev); #if !defined(SUPPORT_PM2_ONLY) dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub); -#endif - RETURN_EIO_IF_NOT_UP(wl); - WL_DBG(("Enter\n")); -#if defined(WL_ENABLE_P2P_IF) - if (wl->p2p_net == dev || _net_info == NULL || wl->vsdb_mode || - !wl_get_drv_status(wl, CONNECTED, dev)) { -#else - if (_net_info == NULL || wl->vsdb_mode || - !wl_get_drv_status(wl, CONNECTED, dev)) { -#endif /* WL_ENABLE_P2P_IF */ +#endif /* (OEM_ANDROID) */ + CHECK_SYS_UP(wl); + + if (wl->p2p_net == dev || _net_info == NULL) { return err; } WL_DBG(("%s: Enter power save enabled %d\n", dev->name, enabled)); - /* Delete pm_enable_work */ - if (wl->pm_enable_work_on) { - cancel_delayed_work_sync(&wl->pm_enable_work); - wl->pm_enable_work_on = false; - } - #if !defined(SUPPORT_PM2_ONLY) /* android has special hooks to change pm when kernel suspended */ pm = enabled ? ((dhd->in_suspend) ? PM_MAX : PM_FAST) : PM_OFF; #else pm = enabled ? PM_FAST : PM_OFF; #endif /* SUPPORT_PM2_ONLY */ - if (_net_info->pm_block) { - WL_ERR(("%s:Do not enable the power save for pm_block %d\n", - dev->name, _net_info->pm_block)); + + if (_net_info->pm_block || wl->vsdb_mode) { + /* Do not enable the power save if it is p2p interface or vsdb mode is set */ + WL_DBG(("%s:Do not enable the power save for pm_block %d or vsdb_mode %d\n", + dev->name, _net_info->pm_block, wl->vsdb_mode)); pm = PM_OFF; } pm = htod32(pm); @@ -4140,10 +3711,11 @@ static s32 wl_cfg80211_resume(struct wip return err; } +static s32 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) -static s32 wl_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow) +wl_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow) #else -static s32 wl_cfg80211_suspend(struct wiphy *wiphy) +wl_cfg80211_suspend(struct wiphy *wiphy) #endif { #ifdef DHD_CLEAR_ON_SUSPEND @@ -4223,7 +3795,7 @@ wl_cfg80211_set_pmksa(struct wiphy *wiph s32 err = 0; int i; - RETURN_EIO_IF_NOT_UP(wl); + CHECK_SYS_UP(wl); for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++) if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID, ETHER_ADDR_LEN)) @@ -4256,11 +3828,11 @@ wl_cfg80211_del_pmksa(struct wiphy *wiph struct cfg80211_pmksa *pmksa) { struct wl_priv *wl = wiphy_priv(wiphy); - struct _pmkid_list pmkid = {0}; + struct _pmkid_list pmkid; s32 err = 0; int i; - RETURN_EIO_IF_NOT_UP(wl); + CHECK_SYS_UP(wl); memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETHER_ADDR_LEN); memcpy(pmkid.pmkid[0].PMKID, pmksa->pmkid, WPA2_PMKID_LEN); @@ -4303,7 +3875,7 @@ wl_cfg80211_flush_pmksa(struct wiphy *wi { struct wl_priv *wl = wiphy_priv(wiphy); s32 err = 0; - RETURN_EIO_IF_NOT_UP(wl); + CHECK_SYS_UP(wl); memset(wl->pmk_list, 0, sizeof(*wl->pmk_list)); err = wl_update_pmklist(dev, wl->pmk_list, err); return err; @@ -4323,7 +3895,7 @@ wl_cfg80211_scan_alloc_params(int channe params_size = WL_SCAN_PARAMS_FIXED_SIZE + 1 * sizeof(uint16); params = (wl_scan_params_t*) kzalloc(params_size, GFP_KERNEL); if (params == NULL) { - WL_ERR(("mem alloc failed (%d bytes)\n", params_size)); + WL_ERR(("%s: mem alloc failed (%d bytes)\n", __func__, params_size)); return params; } memset(params, 0, params_size); @@ -4351,31 +3923,30 @@ wl_cfg80211_scan_alloc_params(int channe return params; } -#if defined(WL_CFG80211_P2P_DEV_IF) -static s32 -wl_cfg80211_remain_on_channel(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev, - struct ieee80211_channel *channel, unsigned int duration, u64 *cookie) -#else static s32 -wl_cfg80211_remain_on_channel(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev, +wl_cfg80211_remain_on_channel(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_channel * channel, enum nl80211_channel_type channel_type, unsigned int duration, u64 *cookie) -#endif /* WL_CFG80211_P2P_DEV_IF */ { s32 target_channel; u32 id; - s32 err = BCME_OK; struct ether_addr primary_mac; struct net_device *ndev = NULL; - struct wl_priv *wl = wiphy_priv(wiphy); - ndev = cfgdev_to_wlc_ndev(cfgdev, wl); + s32 err = BCME_OK; + struct wl_priv *wl = wiphy_priv(wiphy); - WL_DBG(("Enter, channel: %d, duration ms (%d) SCANNING ?? %s \n", - ieee80211_frequency_to_channel(channel->center_freq), + WL_DBG(("Enter, ifindex: %d, channel: %d, duration ms (%d) SCANNING ?? %s \n", + dev->ifindex, ieee80211_frequency_to_channel(channel->center_freq), duration, (wl_get_drv_status(wl, SCANNING, ndev)) ? "YES":"NO")); + if (wl->p2p_net == dev) { + ndev = wl_to_prmry_ndev(wl); + } else { + ndev = dev; + } + if (!wl->p2p) { WL_ERR(("wl->p2p is not initialized\n")); err = BCME_ERROR; @@ -4383,16 +3954,14 @@ wl_cfg80211_remain_on_channel(struct wip } #ifndef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST - if (wl_get_drv_status_all(wl, SCANNING)) { - wl_notify_escan_complete(wl, wl->escan_info.ndev, true, true); + if (wl_get_drv_status(wl, SCANNING, ndev)) { + wl_notify_escan_complete(wl, ndev, true, true); } #endif /* not WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */ target_channel = ieee80211_frequency_to_channel(channel->center_freq); memcpy(&wl->remain_on_chan, channel, sizeof(struct ieee80211_channel)); -#if defined(WL_ENABLE_P2P_IF) wl->remain_on_chan_type = channel_type; -#endif /* WL_ENABLE_P2P_IF */ id = ++wl->last_roc_id; if (id == 0) id = ++wl->last_roc_id; @@ -4471,13 +4040,8 @@ wl_cfg80211_remain_on_channel(struct wip exit: if (err == BCME_OK) { WL_INFO(("Success\n")); -#if defined(WL_CFG80211_P2P_DEV_IF) - cfg80211_ready_on_channel(cfgdev, *cookie, channel, - duration, GFP_KERNEL); -#else - cfg80211_ready_on_channel(cfgdev, *cookie, channel, + cfg80211_ready_on_channel(dev, *cookie, channel, channel_type, duration, GFP_KERNEL); -#endif /* WL_CFG80211_P2P_DEV_IF */ } else { WL_ERR(("Fail to Set (err=%d cookie:%llu)\n", err, *cookie)); } @@ -4485,18 +4049,11 @@ exit: } static s32 -wl_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, - bcm_struct_cfgdev *cfgdev, u64 cookie) +wl_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, struct net_device *dev, + u64 cookie) { s32 err = 0; - -#if defined(WL_CFG80211_P2P_DEV_IF) - if (cfgdev->iftype == NL80211_IFTYPE_P2P_DEVICE) { - WL_DBG((" enter ) on P2P dedicated discover interface\n")); - } -#else - WL_DBG((" enter ) netdev_ifidx: %d \n", cfgdev->ifindex)); -#endif /* WL_CFG80211_P2P_DEV_IF */ + WL_DBG((" enter ) netdev_ifidx: %d \n", dev->ifindex)); return err; } @@ -4511,11 +4068,10 @@ wl_cfg80211_afx_handler(struct work_stru if (afx_instance != NULL && wl->afx_hdl->is_active) { if (wl->afx_hdl->is_listen && wl->afx_hdl->my_listen_chan) { ret = wl_cfgp2p_discover_listen(wl, wl->afx_hdl->my_listen_chan, - (100 * (1 + (RANDOM32() % 3)))); /* 100ms ~ 300ms */ + (100 * (1 + (random32() % 3)))); /* 100ms ~ 300ms */ } else { ret = wl_cfgp2p_act_frm_search(wl, wl->afx_hdl->dev, - wl->afx_hdl->bssidx, wl->afx_hdl->peer_listen_chan, - NULL); + wl->afx_hdl->bssidx, wl->afx_hdl->peer_listen_chan); } if (unlikely(ret != BCME_OK)) { WL_ERR(("ERROR occurred! returned value is (%d)\n", ret)); @@ -4550,7 +4106,7 @@ wl_cfg80211_af_searching_channel(struct /* search peer on peer's listen channel */ schedule_work(&wl->afx_hdl->work); wait_for_completion_timeout(&wl->act_frm_scan, - msecs_to_jiffies(WL_AF_SEARCH_TIME_MAX)); + msecs_to_jiffies(MAX_WAIT_TIME)); if ((wl->afx_hdl->peer_chan != WL_INVALID) || !(wl_get_drv_status(wl, FINDING_COMMON_CHANNEL, dev))) @@ -4563,12 +4119,10 @@ wl_cfg80211_af_searching_channel(struct wl->afx_hdl->is_listen = TRUE; schedule_work(&wl->afx_hdl->work); wait_for_completion_timeout(&wl->act_frm_scan, - msecs_to_jiffies(WL_AF_SEARCH_TIME_MAX)); + msecs_to_jiffies(MAX_WAIT_TIME)); } - if ((wl->afx_hdl->peer_chan != WL_INVALID) || - !(wl_get_drv_status(wl, FINDING_COMMON_CHANNEL, dev))) + if (!wl_get_drv_status(wl, FINDING_COMMON_CHANNEL, dev)) break; - wl->afx_hdl->retry++; WL_AF_TX_KEEP_PRI_CONNECTION_VSDB(wl); @@ -4611,7 +4165,6 @@ wl_cfg80211_config_p2p_pub_af_tx(struct config_af_params->search_channel = false; config_af_params->max_tx_retry = WL_AF_TX_MAX_RETRY; config_af_params->mpc_onoff = -1; - wl->next_af_subtype = P2P_PAF_SUBTYPE_INVALID; switch (act_frm->subtype) { case P2P_PAF_GON_REQ: { @@ -4630,7 +4183,7 @@ wl_cfg80211_config_p2p_pub_af_tx(struct case P2P_PAF_GON_RSP: { wl->next_af_subtype = act_frm->subtype + 1; /* increase dwell time to wait for CONF frame */ - af_params->dwell_time = WL_MED_DWELL_TIME + 100; + af_params->dwell_time = WL_MED_DWELL_TIME; break; } case P2P_PAF_GON_CONF: { @@ -4665,10 +4218,7 @@ wl_cfg80211_config_p2p_pub_af_tx(struct #endif /* WL_CFG80211_SYNC_GON */ break; case P2P_PAF_DEVDIS_REQ: { - if (IS_ACTPUB_WITHOUT_GROUP_ID(&act_frm->elts[0], - action_frame->len)) { - config_af_params->search_channel = true; - } + config_af_params->search_channel = true; wl->next_af_subtype = act_frm->subtype + 1; /* maximize dwell time to wait for RESP frame */ @@ -4683,7 +4233,7 @@ wl_cfg80211_config_p2p_pub_af_tx(struct #endif /* WL_CFG80211_SYNC_GON */ break; case P2P_PAF_PROVDIS_REQ: { - if (IS_ACTPUB_WITHOUT_GROUP_ID(&act_frm->elts[0], + if (IS_PROV_DISC_WITHOUT_GROUP_ID(&act_frm->elts[0], action_frame->len)) { config_af_params->search_channel = true; } @@ -4696,7 +4246,8 @@ wl_cfg80211_config_p2p_pub_af_tx(struct } case P2P_PAF_PROVDIS_RSP: { wl->next_af_subtype = P2P_PAF_GON_REQ; - af_params->dwell_time = WL_MIN_DWELL_TIME; + /* increase dwell time to MED level */ + af_params->dwell_time = WL_MED_DWELL_TIME; #ifdef WL_CFG80211_SYNC_GON config_af_params->extra_listen = false; #endif /* WL_CFG80211_SYNC_GON */ @@ -4710,50 +4261,12 @@ wl_cfg80211_config_p2p_pub_af_tx(struct return err; } -#ifdef WL11U -static bool -wl_cfg80211_check_DFS_channel(struct wl_priv *wl, wl_af_params_t *af_params, - void *frame, u16 frame_len) -{ - struct wl_scan_results *bss_list; - struct wl_bss_info *bi = NULL; - bool result = false; - s32 i; - - /* If DFS channel is 52~148, check to block it or not */ - if (af_params && - (af_params->channel >= 52 && af_params->channel <= 148)) { - if (!wl_cfgp2p_is_p2p_action(frame, frame_len)) { - bss_list = wl->bss_list; - bi = next_bss(bss_list, bi); - for_each_bss(bss_list, bi, i) { - if (CHSPEC_IS5G(bi->chanspec) && - ((bi->ctl_ch ? bi->ctl_ch : CHSPEC_CHANNEL(bi->chanspec)) - == af_params->channel)) { - result = true; /* do not block the action frame */ - break; - } - } - } - } - else { - result = true; - } - - WL_DBG(("result=%s", result?"true":"false")); - return result; -} -#endif /* WL11U */ - static bool wl_cfg80211_send_action_frame(struct wiphy *wiphy, struct net_device *dev, - bcm_struct_cfgdev *cfgdev, wl_af_params_t *af_params, + struct net_device *ndev, wl_af_params_t *af_params, wl_action_frame_t *action_frame, u16 action_frame_len, s32 bssidx) { -#ifdef WL11U - struct net_device *ndev = NULL; -#endif /* WL11U */ struct wl_priv *wl = wiphy_priv(wiphy); bool ack = false; u8 category, action; @@ -4764,13 +4277,7 @@ wl_cfg80211_send_action_frame(struct wip #endif dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub); -#ifdef WL11U -#if defined(WL_CFG80211_P2P_DEV_IF) - ndev = dev; -#else - ndev = ndev_to_cfgdev(cfgdev); -#endif /* WL_CFG80211_P2P_DEV_IF */ -#endif /* WL11U */ + wl_cfgp2p_print_actframe(true, action_frame->data, action_frame->len); category = action_frame->data[DOT11_ACTION_CAT_OFF]; action = action_frame->data[DOT11_ACTION_ACT_OFF]; @@ -4818,7 +4325,7 @@ wl_cfg80211_send_action_frame(struct wip } else { WL_DBG(("Unknown Frame: category 0x%x, action 0x%x, length %d\n", category, action, action_frame_len)); - } + } } else if (category == P2P_AF_CATEGORY) { /* do not configure anything. it will be sent with a default configuration */ } else { @@ -4842,6 +4349,7 @@ wl_cfg80211_send_action_frame(struct wip } else { config_af_params.search_channel = false; } + #ifdef WL11U if (ndev == wl_to_prmry_ndev(wl)) config_af_params.search_channel = false; @@ -4850,20 +4358,14 @@ wl_cfg80211_send_action_frame(struct wip #ifdef VSDB /* if connecting on primary iface, sleep for a while before sending af tx for VSDB */ if (wl_get_drv_status(wl, CONNECTING, wl_to_prmry_ndev(wl))) { - OSL_SLEEP(50); + msleep(50); } #endif /* if scan is ongoing, abort current scan. */ if (wl_get_drv_status_all(wl, SCANNING)) { - wl_notify_escan_complete(wl, wl->escan_info.ndev, true, true); - } -#ifdef WL11U - /* handling DFS channel exceptions */ - if (!wl_cfg80211_check_DFS_channel(wl, af_params, action_frame->data, action_frame->len)) { - return false; /* the action frame was blocked */ + wl_notify_escan_complete(wl, ndev, true, true); } -#endif /* WL11U */ /* set status and destination address before sending af */ if (wl->next_af_subtype != P2P_PAF_SUBTYPE_INVALID) { @@ -4881,31 +4383,24 @@ wl_cfg80211_send_action_frame(struct wip /* search peer's channel */ if (config_af_params.search_channel) { /* initialize afx_hdl */ - if (wl_cfgp2p_find_idx(wl, dev, &wl->afx_hdl->bssidx) != BCME_OK) { - WL_ERR(("Find p2p index from dev(%p) failed\n", dev)); - goto exit; - } + wl->afx_hdl->bssidx = wl_cfgp2p_find_idx(wl, dev); wl->afx_hdl->dev = dev; wl->afx_hdl->retry = 0; wl->afx_hdl->peer_chan = WL_INVALID; if (wl_cfg80211_af_searching_channel(wl, dev) == WL_INVALID) { WL_ERR(("couldn't find peer's channel.\n")); - wl_cfgp2p_print_actframe(true, action_frame->data, action_frame->len, - af_params->channel); goto exit; } - wl_clr_drv_status(wl, SCANNING, wl->afx_hdl->dev); - /* - * Abort scan even for VSDB scenarios. Scan gets aborted in firmware - * but after the check of piggyback algorithm. - * To take care of current piggback algo, lets abort the scan here itself. - */ - wl_notify_escan_complete(wl, dev, true, true); /* Suspend P2P discovery's search-listen to prevent it from * starting a scan or changing the channel. */ + wl_clr_drv_status(wl, SCANNING, wl->afx_hdl->dev); +/* Do not abort scan for VSDB. Scan will be aborted in firmware if necessary */ +#ifndef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST + wl_notify_escan_complete(wl, dev, true, true); +#endif /* not WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */ wl_cfgp2p_discover_enable_search(wl, false); /* update channel */ @@ -4916,8 +4411,6 @@ wl_cfg80211_send_action_frame(struct wip off_chan_started_jiffies = jiffies; #endif /* VSDB */ - wl_cfgp2p_print_actframe(true, action_frame->data, action_frame->len, af_params->channel); - /* Now send a tx action frame */ ack = wl_cfgp2p_tx_action_frame(wl, dev, af_params, bssidx) ? false : true; @@ -4929,8 +4422,7 @@ wl_cfg80211_send_action_frame(struct wip OFF_CHAN_TIME_THRESHOLD_MS) { WL_AF_TX_KEEP_PRI_CONNECTION_VSDB(wl); off_chan_started_jiffies = jiffies; - } else - OSL_SLEEP(AF_RETRY_DELAY_TIME); + } } #endif /* VSDB */ ack = wl_cfgp2p_tx_action_frame(wl, dev, af_params, bssidx) ? @@ -4987,16 +4479,8 @@ exit: return ack; } -#define MAX_NUM_OF_ASSOCIATED_DEV 64 -#if defined(WL_CFG80211_P2P_DEV_IF) -static s32 -wl_cfg80211_mgmt_tx(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev, - struct ieee80211_channel *channel, bool offchan, - unsigned int wait, const u8* buf, size_t len, bool no_cck, - bool dont_wait_for_ack, u64 *cookie) -#else static s32 -wl_cfg80211_mgmt_tx(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev, +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, @@ -5008,7 +4492,6 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, bool dont_wait_for_ack, #endif u64 *cookie) -#endif /* WL_CFG80211_P2P_DEV_IF */ { wl_action_frame_t *action_frame; wl_af_params_t *af_params; @@ -5024,12 +4507,19 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, WL_DBG(("Enter \n")); - dev = cfgdev_to_wlc_ndev(cfgdev, wl); + if (ndev == wl->p2p_net) { + dev = wl_to_prmry_ndev(wl); + } else { + /* If TX req is for any valid ifidx. Use as is */ + dev = ndev; + } + + /* find bssidx based on ndev */ + bssidx = wl_cfgp2p_find_idx(wl, dev); + if (bssidx == -1) { - /* find bssidx based on dev */ - if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) { - WL_ERR(("Find p2p index from dev(%p) failed\n", dev)); - return BCME_ERROR; + WL_ERR(("Can not find the bssidx for dev( %p )\n", dev)); + return -ENODEV; } if (p2p_is_on(wl)) { /* Suspend P2P discovery search-listen to prevent it from changing the @@ -5052,40 +4542,23 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, s32 ie_len = len - ie_offset; if (dev == wl_to_prmry_ndev(wl)) bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE); - wl_cfgp2p_set_management_ie(wl, dev, bssidx, + wl_cfgp2p_set_management_ie(wl, dev, bssidx, VNDR_IE_PRBRSP_FLAG, (u8 *)(buf + ie_offset), ie_len); - cfg80211_mgmt_tx_status(cfgdev, *cookie, buf, len, true, GFP_KERNEL); + cfg80211_mgmt_tx_status(ndev, *cookie, buf, len, true, GFP_KERNEL); goto exit; } else if (ieee80211_is_disassoc(mgmt->frame_control) || ieee80211_is_deauth(mgmt->frame_control)) { - char mac_buf[MAX_NUM_OF_ASSOCIATED_DEV * - sizeof(struct ether_addr) + sizeof(uint)] = {0}; - int num_associated = 0; - struct maclist *assoc_maclist = (struct maclist *)mac_buf; - if (!bcmp((const uint8 *)BSSID_BROADCAST, - (const struct ether_addr *)mgmt->da, ETHER_ADDR_LEN)) { - assoc_maclist->count = MAX_NUM_OF_ASSOCIATED_DEV; - err = wldev_ioctl(dev, WLC_GET_ASSOCLIST, - assoc_maclist, sizeof(mac_buf), false); - if (err < 0) - WL_ERR(("WLC_GET_ASSOCLIST error %d\n", err)); - else - num_associated = assoc_maclist->count; - } memcpy(scb_val.ea.octet, mgmt->da, ETH_ALEN); scb_val.val = mgmt->u.disassoc.reason_code; err = wldev_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scb_val, sizeof(scb_val_t), true); if (err < 0) WL_ERR(("WLC_SCB_DEAUTHENTICATE_FOR_REASON error %d\n", err)); - WL_ERR(("Disconnect STA : %s scb_val.val %d\n", + WL_DBG(("Disconnect STA : %s scb_val.val %d\n", bcm_ether_ntoa((const struct ether_addr *)mgmt->da, eabuf), scb_val.val)); - - if (num_associated > 0 && ETHER_ISBCAST(mgmt->da)) - wl_delay(400); - - cfg80211_mgmt_tx_status(cfgdev, *cookie, buf, len, true, GFP_KERNEL); + wl_delay(400); + cfg80211_mgmt_tx_status(ndev, *cookie, buf, len, true, GFP_KERNEL); goto exit; } else if (ieee80211_is_action(mgmt->frame_control)) { @@ -5146,9 +4619,10 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN], action_frame->len); - ack = wl_cfg80211_send_action_frame(wiphy, dev, cfgdev, af_params, + ack = wl_cfg80211_send_action_frame(wiphy, dev, ndev, af_params, action_frame, action_frame->len, bssidx); - cfg80211_mgmt_tx_status(cfgdev, *cookie, buf, len, ack, GFP_KERNEL); + + cfg80211_mgmt_tx_status(ndev, *cookie, buf, len, ack, GFP_KERNEL); kfree(af_params); exit: @@ -5157,11 +4631,11 @@ exit: static void -wl_cfg80211_mgmt_frame_register(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev, +wl_cfg80211_mgmt_frame_register(struct wiphy *wiphy, struct net_device *dev, u16 frame_type, bool reg) { - WL_DBG(("frame_type: %x, reg: %d\n", frame_type, reg)); + WL_DBG(("%s: frame_type: %x, reg: %d\n", __func__, frame_type, reg)); if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ)) return; @@ -5214,7 +4688,9 @@ wl_cfg80211_set_channel(struct wiphy *wi } param = {0, 0}; struct wl_priv *wl = wiphy_priv(wiphy); - dev = ndev_to_wlc_ndev(dev, wl); + if (wl->p2p_net == dev) { + dev = wl_to_prmry_ndev(wl); + } _chan = ieee80211_frequency_to_channel(chan->center_freq); WL_ERR(("netdev_ifidx(%d), chan_type(%d) target channel(%d) \n", dev->ifindex, channel_type, _chan)); @@ -5352,6 +4828,11 @@ wl_validate_wpa2ie(struct net_device *de 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; @@ -5376,6 +4857,11 @@ wl_validate_wpa2ie(struct net_device *de 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")); } @@ -5754,9 +5240,6 @@ wl_cfg80211_bcn_bringup_ap( s32 infra = 1; s32 join_params_size = 0; s32 ap = 1; -#ifdef DISABLE_11H_SOFTAP - s32 spect = 0; -#endif /* DISABLE_11H_SOFTAP */ s32 err = BCME_OK; WL_DBG(("Enter dev_role: %d\n", dev_role)); @@ -5782,9 +5265,6 @@ wl_cfg80211_bcn_bringup_ap( goto exit; } - /* Do abort scan before creating GO */ - wl_cfg80211_scan_abort(wl); - if ((err = wl_cfgp2p_bss(wl, dev, bssidx, 1)) < 0) { WL_ERR(("GO Bring up error %d\n", err)); goto exit; @@ -5808,14 +5288,6 @@ wl_cfg80211_bcn_bringup_ap( WL_ERR(("setting AP mode failed %d \n", err)); goto exit; } -#ifdef DISABLE_11H_SOFTAP - err = wldev_ioctl(dev, WLC_SET_SPECT_MANAGMENT, - &spect, sizeof(s32), true); - if (err < 0) { - WL_ERR(("SET SPECT_MANAGMENT error %d\n", err)); - goto exit; - } -#endif /* DISABLE_11H_SOFTAP */ err = wldev_ioctl(dev, WLC_UP, &ap, sizeof(s32), true); if (unlikely(err)) { @@ -5846,18 +5318,20 @@ exit: #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) s32 -wl_cfg80211_parse_ap_ies( +wl_cfg80211_parse_set_ies( struct net_device *dev, struct cfg80211_beacon_data *info, - struct parsed_ies *ies) + struct parsed_ies *ies, + u32 dev_role, + s32 bssidx) { - struct parsed_ies prb_ies; struct wl_priv *wl = wlcfg_drv_priv; - dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub); - u8 *vndr = NULL; - u32 vndr_ie_len = 0; + struct parsed_ies prb_ies; s32 err = BCME_OK; + memset(ies, 0, sizeof(struct parsed_ies)); + memset(&prb_ies, 0, sizeof(struct parsed_ies)); + /* Parse Beacon IEs */ if (wl_cfg80211_parse_ies((u8 *)info->tail, info->tail_len, ies) < 0) { @@ -5866,74 +5340,34 @@ wl_cfg80211_parse_ap_ies( goto fail; } - vndr = (u8 *)info->proberesp_ies; - vndr_ie_len = info->proberesp_ies_len; - - if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) { - /* SoftAP mode */ - struct ieee80211_mgmt *mgmt; - mgmt = (struct ieee80211_mgmt *)info->probe_resp; - if (mgmt != NULL) { - vndr = (u8 *)&mgmt->u.probe_resp.variable; - vndr_ie_len = info->probe_resp_len - - offsetof(struct ieee80211_mgmt, u.probe_resp.variable); - } + /* Set Beacon IEs to FW */ + if ((err = wl_cfgp2p_set_management_ie(wl, dev, bssidx, + VNDR_IE_BEACON_FLAG, (u8 *)info->tail, + info->tail_len)) < 0) { + WL_ERR(("Set Beacon IE Failed \n")); + } else { + WL_DBG(("Applied Vndr IEs for Beacon \n")); } /* Parse Probe Response IEs */ - if (wl_cfg80211_parse_ies(vndr, vndr_ie_len, &prb_ies) < 0) { - WL_ERR(("PROBE RESP get IEs failed \n")); + if (wl_cfg80211_parse_ies((u8 *)info->proberesp_ies, + info->proberesp_ies_len, &prb_ies) < 0) { + WL_ERR(("PRB RESP get IEs failed \n")); err = -EINVAL; - } - -fail: - - return err; -} - -s32 -wl_cfg80211_set_ies( - struct net_device *dev, - struct cfg80211_beacon_data *info, - s32 bssidx) -{ - struct wl_priv *wl = wlcfg_drv_priv; - dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub); - u8 *vndr = NULL; - u32 vndr_ie_len = 0; - s32 err = BCME_OK; - - /* Set Beacon IEs to FW */ - if ((err = wl_cfgp2p_set_management_ie(wl, dev, bssidx, - VNDR_IE_BEACON_FLAG, (u8 *)info->tail, - info->tail_len)) < 0) { - WL_ERR(("Set Beacon IE Failed \n")); - } else { - WL_DBG(("Applied Vndr IEs for Beacon \n")); - } - - vndr = (u8 *)info->proberesp_ies; - vndr_ie_len = info->proberesp_ies_len; - - if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) { - /* SoftAP mode */ - struct ieee80211_mgmt *mgmt; - mgmt = (struct ieee80211_mgmt *)info->probe_resp; - if (mgmt != NULL) { - vndr = (u8 *)&mgmt->u.probe_resp.variable; - vndr_ie_len = info->probe_resp_len - - offsetof(struct ieee80211_mgmt, u.probe_resp.variable); - } + goto fail; } /* Set Probe Response IEs to FW */ if ((err = wl_cfgp2p_set_management_ie(wl, dev, bssidx, - VNDR_IE_PRBRSP_FLAG, vndr, vndr_ie_len)) < 0) { + VNDR_IE_PRBRSP_FLAG, (u8 *)info->proberesp_ies, + info->proberesp_ies_len)) < 0) { WL_ERR(("Set Probe Resp IE Failed \n")); } else { WL_DBG(("Applied Vndr IEs for Probe Resp \n")); } +fail: + return err; } #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) */ @@ -6006,6 +5440,8 @@ static s32 wl_cfg80211_hostapd_sec( return 0; } +#if defined(WL_SUPPORT_BACKPORTED_KPATCHES) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, \ + 2, 0)) static s32 wl_cfg80211_del_station( struct wiphy *wiphy, @@ -6016,11 +5452,6 @@ wl_cfg80211_del_station( struct wl_priv *wl = wiphy_priv(wiphy); scb_val_t scb_val; s8 eabuf[ETHER_ADDR_STR_LEN]; - int err; - char mac_buf[MAX_NUM_OF_ASSOCIATED_DEV * - sizeof(struct ether_addr) + sizeof(uint)] = {0}; - struct maclist *assoc_maclist = (struct maclist *)mac_buf; - int num_associated = 0; WL_DBG(("Entry\n")); if (mac_addr == NULL) { @@ -6028,7 +5459,11 @@ wl_cfg80211_del_station( return 0; } - dev = ndev_to_wlc_ndev(ndev, wl); + if (ndev == wl->p2p_net) { + dev = wl_to_prmry_ndev(wl); + } else { + dev = ndev; + } if (p2p_is_on(wl)) { /* Suspend P2P discovery search-listen to prevent it from changing the @@ -6040,28 +5475,18 @@ wl_cfg80211_del_station( } } - assoc_maclist->count = MAX_NUM_OF_ASSOCIATED_DEV; - err = wldev_ioctl(ndev, WLC_GET_ASSOCLIST, - assoc_maclist, sizeof(mac_buf), false); - if (err < 0) - WL_ERR(("WLC_GET_ASSOCLIST error %d\n", err)); - else - num_associated = assoc_maclist->count; - memcpy(scb_val.ea.octet, mac_addr, ETHER_ADDR_LEN); scb_val.val = DOT11_RC_DEAUTH_LEAVING; - err = wldev_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scb_val, - sizeof(scb_val_t), true); - if (err < 0) - WL_ERR(("WLC_SCB_DEAUTHENTICATE_FOR_REASON err %d\n", err)); - WL_ERR(("Disconnect STA : %s scb_val.val %d\n", + if (wldev_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scb_val, + sizeof(scb_val_t), true)) + WL_ERR(("WLC_SCB_DEAUTHENTICATE_FOR_REASON failed\n")); + WL_DBG(("Disconnect STA : %s scb_val.val %d\n", bcm_ether_ntoa((const struct ether_addr *)mac_addr, eabuf), scb_val.val)); - - if (num_associated > 0 && ETHER_ISBCAST(mac_addr)) - wl_delay(400); + wl_delay(400); return 0; } +#endif /* WL_SUPPORT_BACKPORTED_KPATCHES || KERNEL_VER >= KERNEL_VERSION(3, 2, 0)) */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) static s32 @@ -6080,19 +5505,14 @@ wl_cfg80211_start_ap( if (dev == wl_to_prmry_ndev(wl)) { WL_DBG(("Start AP req on primary iface: Softap\n")); dev_role = NL80211_IFTYPE_AP; - } -#if defined(WL_ENABLE_P2P_IF) - else if (dev == wl->p2p_net) { + } else if (dev == wl->p2p_net) { /* Group Add request on p2p0 */ WL_DBG(("Start AP req on P2P iface: GO\n")); dev = wl_to_prmry_ndev(wl); dev_role = NL80211_IFTYPE_P2P_GO; } -#endif /* WL_ENABLE_P2P_IF */ - if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) { - WL_ERR(("Find p2p index from dev(%p) failed\n", dev)); - return BCME_ERROR; - } + + bssidx = wl_cfgp2p_find_idx(wl, dev); if (p2p_is_on(wl) && (bssidx == wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION))) { @@ -6100,26 +5520,15 @@ wl_cfg80211_start_ap( WL_DBG(("Start AP req on P2P connection iface\n")); } - if (!check_dev_role_integrity(wl, dev_role)) - goto fail; - -#if defined(WL_CFG80211_P2P_DEV_IF) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) - if ((err = wl_cfg80211_set_channel(wiphy, dev, - dev->ieee80211_ptr->preset_chandef.chan, - NL80211_CHAN_HT20) < 0)) { - WL_ERR(("Set channel failed \n")); - goto fail; - } -#endif /* WL_CFG80211_P2P_DEV_IF || (LINUX_VERSION >= VERSION(3, 6, 0)) */ - if ((err = wl_cfg80211_bcn_set_params(info, dev, dev_role, bssidx)) < 0) { WL_ERR(("Beacon params set failed \n")); goto fail; } - /* Parse IEs */ - if ((err = wl_cfg80211_parse_ap_ies(dev, &info->beacon, &ies)) < 0) { + /* Set IEs to FW */ + if ((err = wl_cfg80211_parse_set_ies(dev, &info->beacon, + &ies, dev_role, bssidx) < 0)) { WL_ERR(("Set IEs failed \n")); goto fail; } @@ -6139,10 +5548,6 @@ wl_cfg80211_start_ap( WL_DBG(("** AP/GO Created **\n")); - /* Set IEs to FW */ - if ((err = wl_cfg80211_set_ies(dev, &info->beacon, bssidx)) < 0) - WL_ERR(("Set IEs failed \n")); - fail: if (err) { WL_ERR(("ADD/SET beacon failed\n")); @@ -6167,42 +5572,33 @@ wl_cfg80211_stop_ap( WL_DBG(("Enter \n")); if (dev == wl_to_prmry_ndev(wl)) { dev_role = NL80211_IFTYPE_AP; - } -#if defined(WL_ENABLE_P2P_IF) - else if (dev == wl->p2p_net) { + } else if (dev == wl->p2p_net) { /* Group Add request on p2p0 */ dev = wl_to_prmry_ndev(wl); dev_role = NL80211_IFTYPE_P2P_GO; } -#endif /* WL_ENABLE_P2P_IF */ - if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) { - WL_ERR(("Find p2p index from dev(%p) failed\n", dev)); - return BCME_ERROR; - } + bssidx = wl_cfgp2p_find_idx(wl, dev); if (p2p_is_on(wl) && (bssidx == wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION))) { dev_role = NL80211_IFTYPE_P2P_GO; } - if (!check_dev_role_integrity(wl, dev_role)) - goto exit; - if (dev_role == NL80211_IFTYPE_AP) { /* SoftAp on primary Interface. * Shut down AP and turn on MPC */ - if ((err = wldev_ioctl(dev, WLC_SET_AP, &ap, sizeof(s32), true)) < 0) { - WL_ERR(("setting AP mode failed %d \n", err)); - err = -ENOTSUPP; - goto exit; - } err = wldev_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(s32), true); if (err < 0) { WL_ERR(("SET INFRA error %d\n", err)); err = -ENOTSUPP; goto exit; } + if ((err = wldev_ioctl(dev, WLC_SET_AP, &ap, sizeof(s32), true)) < 0) { + WL_ERR(("setting AP mode failed %d \n", err)); + err = -ENOTSUPP; + goto exit; + } err = wldev_ioctl(dev, WLC_UP, &ap, sizeof(s32), true); if (unlikely(err)) { @@ -6214,17 +5610,8 @@ wl_cfg80211_stop_ap( wl_clr_drv_status(wl, AP_CREATED, dev); /* Turn on the MPC */ wldev_iovar_setint(dev, "mpc", 1); - if (wl->ap_info) { - kfree(wl->ap_info->wpa_ie); - kfree(wl->ap_info->rsn_ie); - kfree(wl->ap_info->wps_ie); - kfree(wl->ap_info); - wl->ap_info = NULL; - } } else { WL_DBG(("Stopping P2P GO \n")); - DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE((dhd_pub_t *)(wl->pub), DHD_EVENT_TIMEOUT_MS*3); - DHD_OS_WAKE_LOCK_TIMEOUT((dhd_pub_t *)(wl->pub)); } exit: @@ -6247,35 +5634,22 @@ wl_cfg80211_change_beacon( if (dev == wl_to_prmry_ndev(wl)) { dev_role = NL80211_IFTYPE_AP; - } -#if defined(WL_ENABLE_P2P_IF) - else if (dev == wl->p2p_net) { + } else if (dev == wl->p2p_net) { /* Group Add request on p2p0 */ dev = wl_to_prmry_ndev(wl); dev_role = NL80211_IFTYPE_P2P_GO; } -#endif /* WL_ENABLE_P2P_IF */ - if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) { - WL_ERR(("Find p2p index from dev(%p) failed\n", dev)); - return BCME_ERROR; - } + + bssidx = wl_cfgp2p_find_idx(wl, dev); if (p2p_is_on(wl) && (bssidx == wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION))) { dev_role = NL80211_IFTYPE_P2P_GO; } - if (!check_dev_role_integrity(wl, dev_role)) - goto fail; - - /* Parse IEs */ - if ((err = wl_cfg80211_parse_ap_ies(dev, info, &ies)) < 0) { - WL_ERR(("Parse IEs failed \n")); - goto fail; - } - /* Set IEs to FW */ - if ((err = wl_cfg80211_set_ies(dev, info, bssidx)) < 0) { + if ((err = wl_cfg80211_parse_set_ies(dev, info, + &ies, dev_role, bssidx) < 0)) { WL_ERR(("Set IEs failed \n")); goto fail; } @@ -6304,32 +5678,25 @@ wl_cfg80211_add_set_beacon(struct wiphy struct parsed_ies ies; bcm_tlv_t *ssid_ie; bool pbc = 0; + WL_DBG(("interval (%d) dtim_period (%d) head_len (%d) tail_len (%d)\n", info->interval, info->dtim_period, info->head_len, info->tail_len)); if (dev == wl_to_prmry_ndev(wl)) { dev_role = NL80211_IFTYPE_AP; - } -#if defined(WL_ENABLE_P2P_IF) - else if (dev == wl->p2p_net) { + } else if (dev == wl->p2p_net) { /* Group Add request on p2p0 */ dev = wl_to_prmry_ndev(wl); dev_role = NL80211_IFTYPE_P2P_GO; } -#endif /* WL_ENABLE_P2P_IF */ - if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) { - WL_ERR(("Find p2p index from dev(%p) failed\n", dev)); - return BCME_ERROR; - } + + bssidx = wl_cfgp2p_find_idx(wl, dev); if (p2p_is_on(wl) && (bssidx == wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION))) { dev_role = NL80211_IFTYPE_P2P_GO; } - if (!check_dev_role_integrity(wl, dev_role)) - goto fail; - ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN; /* find the SSID */ if ((ssid_ie = bcm_parse_tlvs((u8 *)&info->head[ie_offset], @@ -6424,8 +5791,7 @@ fail: #define PNO_TIME 30 #define PNO_REPEAT 4 #define PNO_FREQ_EXPO_MAX 2 -static int -wl_cfg80211_sched_scan_start(struct wiphy *wiphy, +int wl_cfg80211_sched_scan_start(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_sched_scan_request *request) { @@ -6476,11 +5842,17 @@ wl_cfg80211_sched_scan_start(struct wiph } if (ssid_count) { - if ((ret = dhd_dev_pno_set_for_ssid(dev, ssids_local, request->n_match_sets, - pno_time, pno_repeat, pno_freq_expo_max, NULL, 0)) < 0) { + if ((ret = dhd_dev_pno_set(dev, ssids_local, request->n_match_sets, + pno_time, pno_repeat, pno_freq_expo_max)) < 0) { WL_ERR(("PNO setup failed!! ret=%d \n", ret)); return -EINVAL; } + + /* Enable the PNO */ + if (dhd_dev_pno_enable(dev, 1) < 0) { + WL_ERR(("PNO enable failed!! ret=%d \n", ret)); + return -EINVAL; + } wl->sched_scan_req = request; } else { return -EINVAL; @@ -6489,16 +5861,18 @@ wl_cfg80211_sched_scan_start(struct wiph return 0; } -static int -wl_cfg80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev) +int wl_cfg80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev) { struct wl_priv *wl = wiphy_priv(wiphy); WL_DBG(("Enter \n")); WL_PNO((">>> SCHED SCAN STOP\n")); - if (dhd_dev_pno_stop_for_ssid(dev) < 0) - WL_ERR(("PNO Stop for SSID failed")); + if (dhd_dev_pno_enable(dev, 0) < 0) + WL_ERR(("PNO disable failed")); + + if (dhd_dev_pno_reset(dev) < 0) + WL_ERR(("PNO reset failed")); if (wl->scan_request && wl->sched_scan_running) { WL_PNO((">>> Sched scan running. Aborting it..\n")); @@ -6516,10 +5890,6 @@ static struct cfg80211_ops wl_cfg80211_o .add_virtual_intf = wl_cfg80211_add_virtual_iface, .del_virtual_intf = wl_cfg80211_del_virtual_iface, .change_virtual_intf = wl_cfg80211_change_virtual_iface, -#if defined(WL_CFG80211_P2P_DEV_IF) - .start_p2p_device = wl_cfgp2p_start_p2p_device, - .stop_p2p_device = wl_cfgp2p_stop_p2p_device, -#endif /* WL_CFG80211_P2P_DEV_IF */ .scan = wl_cfg80211_scan, .set_wiphy_params = wl_cfg80211_set_wiphy_params, .join_ibss = wl_cfg80211_join_ibss, @@ -6545,10 +5915,8 @@ static struct cfg80211_ops wl_cfg80211_o .mgmt_tx = wl_cfg80211_mgmt_tx, .mgmt_frame_register = wl_cfg80211_mgmt_frame_register, .change_bss = wl_cfg80211_change_bss, -#if !defined(WL_CFG80211_P2P_DEV_IF) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)) .set_channel = wl_cfg80211_set_channel, -#endif /* !WL_CFG80211_P2P_DEV_IF && (LINUX_VERSION < VERSION(3, 6, 0)) */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0) .set_beacon = wl_cfg80211_add_set_beacon, .add_beacon = wl_cfg80211_add_set_beacon, #else @@ -6560,11 +5928,11 @@ static struct cfg80211_ops wl_cfg80211_o .sched_scan_start = wl_cfg80211_sched_scan_start, .sched_scan_stop = wl_cfg80211_sched_scan_stop, #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) */ +#if defined(WL_SUPPORT_BACKPORTED_KPATCHES) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, \ + 2, 0)) .del_station = wl_cfg80211_del_station, .mgmt_tx_cancel_wait = wl_cfg80211_mgmt_tx_cancel_wait, -#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 2, 0) - .tdls_oper = wl_cfg80211_tdls_oper -#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(3, 2, 0) */ +#endif /* WL_SUPPORT_BACKPORTED_KPATCHES || KERNEL_VERSION >= (3,2,0) */ }; s32 wl_mode_to_nl80211_iftype(s32 mode) @@ -6585,17 +5953,13 @@ s32 wl_mode_to_nl80211_iftype(s32 mode) return err; } -#ifdef CONFIG_CFG80211_INTERNAL_REGDB -/* Kernel Network Support->Wireless->Regulatory rules database - options should be enabled and regulatory CRDA regdb table populated in Kernel - for proper country reg notification -*/ static int wl_cfg80211_reg_notifier( struct wiphy *wiphy, struct regulatory_request *request) { struct wl_priv *wl = (struct wl_priv *)wiphy_priv(wiphy); + wl_country_t cspec = {{0}, 0, {0} }; int ret = 0; if (!request || !wl) { @@ -6607,36 +5971,44 @@ wl_cfg80211_reg_notifier( request->alpha2[0], request->alpha2[1], request->initiator)); /* We support only REGDOM_SET_BY_USER as of now */ - if ((request->initiator != NL80211_REGDOM_SET_BY_USER) && - (request->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE)) { - WL_ERR(("reg_notifier for intiator:%d not supported : set default\n", + if (request->initiator != NL80211_REGDOM_SET_BY_USER) { + WL_ERR(("reg_notifier for intiator:%d not supported \n", request->initiator)); - /* in case of no supported country by regdb - lets driver setup platform default Locale - */ + return -ENOTSUPP; } - WL_ERR(("Set country code %c%c from %s\n", - request->alpha2[0], request->alpha2[1], - ((request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) ? " 11d AP" : "User"))); + if (request->alpha2[0] == '0' && request->alpha2[1] == '0') { + /* world domain */ + WL_ERR(("World domain. Setting XY/4 \n")); + strncpy(cspec.country_abbrev, "XY", strlen("XY")); + cspec.rev = 4; + } else { + memcpy(cspec.country_abbrev, request->alpha2, 2); + cspec.country_abbrev[3] = '\0'; + cspec.rev = -1; /* Unspecified */ + } - if ((ret = wldev_set_country(wl_to_prmry_ndev(wl), request->alpha2, - false, (request->initiator == NL80211_REGDOM_SET_BY_USER ? true : false))) < 0) { + if ((ret = wldev_iovar_setbuf(wl_to_prmry_ndev(wl), "country", (char *)&cspec, + sizeof(cspec), wl->ioctl_buf, WLC_IOCTL_SMLEN, NULL)) < 0) { WL_ERR(("set country Failed :%d\n", ret)); + goto exit; } + if ((ret = wl_update_wiphybands(wl, false)) < 0) { + WL_ERR(("wl_update_wiphybands failed\n")); + goto exit; + } + + WL_DBG(("%s: set country '%s/%d' done\n", + __FUNCTION__, cspec.country_abbrev, cspec.rev)); + +exit: return ret; } -#endif /* CONFIG_CFG80211_INTERNAL_REGDB */ -static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev, void *data) +static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev) { s32 err = 0; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) && \ - (defined(WL_IFACE_COMB_NUM_CHANNELS) || defined(WL_CFG80211_P2P_DEV_IF)) - dhd_pub_t *dhd = (dhd_pub_t *)data; -#endif /* LINUX_VER >= 3.0 && (WL_IFACE_COMB_NUM_CHANNELS || WL_CFG80211_P2P_DEV_IF) */ - wdev->wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_priv)); if (unlikely(!wdev->wiphy)) { @@ -6657,34 +6029,11 @@ static s32 wl_setup_wiphy(struct wireles #endif /* WL_SCHED_SCAN */ wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) - | BIT(NL80211_IFTYPE_ADHOC) -#if !defined(WL_ENABLE_P2P_IF) +#if !(defined(WLP2P) && defined(WL_ENABLE_P2P_IF)) | BIT(NL80211_IFTYPE_MONITOR) -#endif /* !WL_ENABLE_P2P_IF */ -#if defined(WL_IFACE_COMB_NUM_CHANNELS) || defined(WL_CFG80211_P2P_DEV_IF) - | BIT(NL80211_IFTYPE_P2P_CLIENT) - | BIT(NL80211_IFTYPE_P2P_GO) -#endif /* WL_IFACE_COMB_NUM_CHANNELS || WL_CFG80211_P2P_DEV_IF */ -#if defined(WL_CFG80211_P2P_DEV_IF) - | BIT(NL80211_IFTYPE_P2P_DEVICE) -#endif /* WL_CFG80211_P2P_DEV_IF */ +#endif | BIT(NL80211_IFTYPE_AP); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) && \ - (defined(WL_IFACE_COMB_NUM_CHANNELS) || defined(WL_CFG80211_P2P_DEV_IF)) - if (dhd && dhd->op_mode == DHD_FLAG_HOSTAP_MODE) { - WL_DBG(("Setting interface combinations for SoftAP mode\n")); - wdev->wiphy->iface_combinations = softap_iface_combinations; - wdev->wiphy->n_iface_combinations = - ARRAY_SIZE(softap_iface_combinations); - } else { - WL_DBG(("Setting interface combinations for STA+P2P mode\n")); - wdev->wiphy->iface_combinations = sta_p2p_iface_combinations; - wdev->wiphy->n_iface_combinations = - ARRAY_SIZE(sta_p2p_iface_combinations); - } -#endif /* LINUX_VER >= 3.0 && (WL_IFACE_COMB_NUM_CHANNELS || WL_CFG80211_P2P_DEV_IF) */ - wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz; wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; @@ -6713,26 +6062,22 @@ static s32 wl_setup_wiphy(struct wireles * if needed so DON'T advertise that featur eto Supplicant. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) -/* wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM; */ + /* wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM; */ #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0) wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | WIPHY_FLAG_OFFCHAN_TX; #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) +#if defined(WL_SUPPORT_BACKPORTED_KPATCHES) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, \ + 4, 0)) /* From 3.4 kernel ownards AP_SME flag can be advertised * to remove the patch from supplicant */ wdev->wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME; -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) */ +#endif -#ifdef CONFIG_CFG80211_INTERNAL_REGDB wdev->wiphy->reg_notifier = wl_cfg80211_reg_notifier; -#endif /* CONFIG_CFG80211_INTERNAL_REGDB */ -#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 2, 0)) || 0 - wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; -#endif WL_DBG(("Registering custom regulatory)\n")); wdev->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; wiphy_apply_custom_regulatory(wdev->wiphy, &brcm_regdom); @@ -6742,12 +6087,6 @@ static s32 wl_setup_wiphy(struct wireles WL_ERR(("Couldn not register wiphy device (%d)\n", err)); wiphy_free(wdev->wiphy); } - -#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) && (LINUX_VERSION_CODE <= \ - KERNEL_VERSION(3, 3, 0))) && defined(WL_IFACE_COMB_NUM_CHANNELS) - wdev->wiphy->flags &= ~WIPHY_FLAG_ENFORCE_COMBINATIONS; -#endif /* ((LINUX_VER >= 3.0) && (LINUX_VER <= 3.3)) && WL_IFACE_COMB_NUM_CHANNELS */ - return err; } @@ -6770,25 +6109,81 @@ static void wl_free_wdev(struct wl_priv */ } +#if defined(RSSIAVG) +static wl_rssi_cache_ctrl_t g_rssi_cache_ctrl; +#endif +#if defined(BSSCACHE) +static wl_bss_cache_ctrl_t g_bss_cache_ctrl; +#endif + static s32 wl_inform_bss(struct wl_priv *wl) { struct wl_scan_results *bss_list; struct wl_bss_info *bi = NULL; /* must be initialized */ s32 err = 0; s32 i; +#if defined(RSSIAVG) + struct net_device *ndev = wl_to_prmry_ndev(wl); +#endif +#if defined(BSSCACHE) + wl_bss_cache_t *node; +#endif bss_list = wl->bss_list; - WL_DBG(("scanned AP count (%d)\n", bss_list->count)); +#if defined(BSSCACHE) + if (g_bss_cache_ctrl.m_timer_expired || (p2p_is_on(wl) && p2p_scan(wl))) { +#if defined(RSSIAVG) + wl_free_rssi_cache(&g_rssi_cache_ctrl); +#endif + wl_free_bss_cache(&g_bss_cache_ctrl); + g_bss_cache_ctrl.m_timer_expired ^= 1; + } + wl_update_bss_cache(&g_bss_cache_ctrl, bss_list); + wl_delete_dirty_bss_cache(&g_bss_cache_ctrl); + wl_reset_bss_cache(&g_bss_cache_ctrl); +#endif + +#if defined(RSSIAVG) +#if defined(BSSCACHE) + node = g_bss_cache_ctrl.m_cache_head; + for (;node;) { + wl_update_rssi_cache(&g_rssi_cache_ctrl, &node->results); + node = node->next; + } +#else + wl_update_rssi_cache(&g_rssi_cache_ctrl, bss_list); +#endif + if (!in_atomic()) + wl_update_connected_rssi_cache(&g_rssi_cache_ctrl, ndev); + wl_delete_dirty_rssi_cache(&g_rssi_cache_ctrl); + wl_reset_rssi_cache(&g_rssi_cache_ctrl); +#endif + + WL_SCAN(("scanned AP count (%d)\n", bss_list->count)); + +#if defined(BSSCACHE) + node = g_bss_cache_ctrl.m_cache_head; + for (i=0; node && iresults.bss_info; + err = wl_inform_single_bss(wl, bi, 0); + if (unlikely(err)) + break; + node = node->next; + } + wl_run_bss_cache_timer(&g_bss_cache_ctrl, 0); + wl_run_bss_cache_timer(&g_bss_cache_ctrl, 1); +#else bi = next_bss(bss_list, bi); for_each_bss(bss_list, bi, i) { - err = wl_inform_single_bss(wl, bi); + err = wl_inform_single_bss(wl, bi, 0); if (unlikely(err)) break; } +#endif return err; } -static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi) +static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi, u8 is_roam_done) { struct wiphy *wiphy = wl_to_wiphy(wl); struct ieee80211_mgmt *mgmt; @@ -6803,6 +6198,7 @@ static s32 wl_inform_single_bss(struct w u32 freq; s32 err = 0; gfp_t aflags; + u8 *ie_offset = NULL; if (unlikely(dtoh32(bi->length) > WL_BSS_INFO_MAX)) { WL_DBG(("Beacon is larger than buffer. Discarding\n")); @@ -6828,7 +6224,13 @@ static s32 wl_inform_single_bss(struct w kfree(notif_bss_info); return -EINVAL; } - notif_bss_info->rssi = dtoh16(bi->RSSI) + RSSI_OFFSET; + notif_bss_info->rssi = dtoh16(bi->RSSI); +#if defined(RSSIAVG) + notif_bss_info->rssi = wl_get_avg_rssi(&g_rssi_cache_ctrl, &bi->BSSID); +#endif +#if defined(RSSIOFFSET) + notif_bss_info->rssi = wl_update_rssi_offset(notif_bss_info->rssi); +#endif memcpy(mgmt->bssid, &bi->BSSID, ETHER_ADDR_LEN); mgmt_type = wl->active_scan ? IEEE80211_STYPE_PROBE_RESP : IEEE80211_STYPE_BEACON; @@ -6842,13 +6244,42 @@ static s32 wl_inform_single_bss(struct w beacon_proberesp->beacon_int = cpu_to_le16(bi->beacon_period); beacon_proberesp->capab_info = cpu_to_le16(bi->capability); wl_rst_ie(wl); - wl_update_hidden_ap_ie(bi, ((u8 *) bi) + bi->ie_offset, &bi->ie_length); - wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length); + + ie_offset = ((u8 *) bi) + bi->ie_offset; + + if (is_roam_done && ((int)(*(ie_offset)) == WLAN_EID_SSID && + ((int)(*(ie_offset+1)) == 0 || (int)(*(ie_offset+2)) == 0))) { + u8 *ie_new_offset = NULL; + uint8 ie_new_length; + + WL_ERR(("WAR trace: Changing the SSID Info, from beacon %d\n", + bi->flags & WL_BSS_FLAGS_FROM_BEACON)); + + ie_new_offset = (u8 *)kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL); + if (ie_new_offset) { + *(ie_new_offset) = WLAN_EID_SSID; + *(ie_new_offset+1) = bi->SSID_len; + memcpy(ie_new_offset+2, bi->SSID, bi->SSID_len); + ie_new_length = bi->ie_length - *(ie_offset+1) + bi->SSID_len; + + /* Copy the remaining IE apart from SSID IE from bi */ + memcpy(ie_new_offset+2 + bi->SSID_len, + ie_offset+2 + *(ie_offset+1), + bi->ie_length - 2 - *(ie_offset+1)); + wl_mrg_ie(wl, ie_new_offset, ie_new_length); + kfree(ie_new_offset); + } else { + wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length); + } + } else { + wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length); + } + wl_cp_ie(wl, beacon_proberesp->variable, WL_BSS_INFO_MAX - offsetof(struct wl_cfg80211_bss_info, frame_buf)); notif_bss_info->frame_len = offsetof(struct ieee80211_mgmt, u.beacon.variable) + wl_get_ielen(wl); -#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) +#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 @@ -6865,15 +6296,14 @@ static s32 wl_inform_single_bss(struct w kfree(notif_bss_info); return -EINVAL; } - WL_DBG(("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM" - "mgmt_type %d frame_len %d\n", bi->SSID, - notif_bss_info->rssi, notif_bss_info->channel, - mgmt->u.beacon.capab_info, &bi->BSSID, mgmt_type, - notif_bss_info->frame_len)); + WL_SCAN(("BSSID %pM, channel %d, rssi %d, capability 0x04%x, mgmt_type %d, " + "frame_len %d, SSID \"%s\"\n", &bi->BSSID, notif_bss_info->channel, + notif_bss_info->rssi, mgmt->u.beacon.capab_info, mgmt_type, + notif_bss_info->frame_len, bi->SSID)); signal = notif_bss_info->rssi * 100; if (!mgmt->u.probe_resp.timestamp) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) struct timespec ts; get_monotonic_boottime(&ts); mgmt->u.probe_resp.timestamp = ((u64)ts.tv_sec*1000000) @@ -6886,7 +6316,6 @@ static s32 wl_inform_single_bss(struct w #endif } - cbss = cfg80211_inform_bss_frame(wiphy, channel, mgmt, le16_to_cpu(notif_bss_info->frame_len), signal, aflags); if (unlikely(!cbss)) { @@ -6895,11 +6324,7 @@ static s32 wl_inform_single_bss(struct w return -EINVAL; } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)) - cfg80211_put_bss(wiphy, cbss); -#else cfg80211_put_bss(cbss); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) */ kfree(notif_bss_info); return err; } @@ -7068,7 +6493,7 @@ wl_notify_connect_status_ap(struct wl_pr kfree(body); return -EINVAL; } -#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) +#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS) freq = ieee80211_channel_to_frequency(channel); (void)band->band; #else @@ -7106,6 +6531,7 @@ exit: kfree(mgmt_frame); if (body) kfree(body); + return err; #else /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0) && !WL_CFG80211_STA_EVENT */ sinfo.filled = 0; if (((event == WLC_E_ASSOC_IND) || (event == WLC_E_REASSOC_IND)) && @@ -7149,97 +6575,39 @@ wl_get_auth_assoc_status(struct wl_priv } static s32 -wl_notify_connect_status_ibss(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data) -{ - s32 err = 0; - u32 event = ntoh32(e->event_type); - u16 flags = ntoh16(e->flags); - u32 status = ntoh32(e->status); - bool active; - - if (event == WLC_E_JOIN) { - WL_DBG(("joined in IBSS network\n")); - } - if (event == WLC_E_START) { - WL_DBG(("started IBSS network\n")); - } - if (event == WLC_E_JOIN || event == WLC_E_START || - (event == WLC_E_LINK && (flags == WLC_EVENT_MSG_LINK))) { - if (wl_get_drv_status(wl, CONNECTED, ndev)) { - /* ROAM or Redundant */ - u8 *cur_bssid = wl_read_prof(wl, ndev, WL_PROF_BSSID); - if (memcmp(cur_bssid, &e->addr, ETHER_ADDR_LEN) == 0) { - WL_DBG(("IBSS connected event from same BSSID(" - MACDBG "), ignore it\n", MAC2STRDBG(cur_bssid))); - return err; - } - WL_INFO(("IBSS BSSID is changed from " MACDBG " to " MACDBG "\n", - MAC2STRDBG(cur_bssid), MAC2STRDBG((u8 *)&e->addr))); - wl_get_assoc_ies(wl, ndev); - wl_update_prof(wl, ndev, NULL, (void *)&e->addr, WL_PROF_BSSID); - wl_update_bss_info(wl, ndev); - cfg80211_ibss_joined(ndev, (s8 *)&e->addr, GFP_KERNEL); - } - else { - /* New connection */ - WL_INFO(("IBSS connected to " MACDBG "\n", MAC2STRDBG((u8 *)&e->addr))); - wl_link_up(wl); - wl_get_assoc_ies(wl, ndev); - wl_update_prof(wl, ndev, NULL, (void *)&e->addr, WL_PROF_BSSID); - wl_update_bss_info(wl, ndev); - cfg80211_ibss_joined(ndev, (s8 *)&e->addr, GFP_KERNEL); - wl_set_drv_status(wl, CONNECTED, ndev); - active = true; - wl_update_prof(wl, ndev, NULL, (void *)&active, WL_PROF_ACT); - } - } else if ((event == WLC_E_LINK && !(flags & WLC_EVENT_MSG_LINK)) || - event == WLC_E_DEAUTH_IND || event == WLC_E_DISASSOC_IND) { - wl_clr_drv_status(wl, CONNECTED, ndev); - wl_link_down(wl); - wl_init_prof(wl, ndev); - } - else if (event == WLC_E_SET_SSID && status == WLC_E_STATUS_NO_NETWORKS) { - WL_DBG(("no action - join fail (IBSS mode)\n")); - } - else { - WL_DBG(("no action (IBSS mode)\n")); - } - return err; -} - -static s32 -wl_notify_connect_status(struct wl_priv *wl, bcm_struct_cfgdev *cfgdev, +wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev, const wl_event_msg_t *e, void *data) { bool act; - struct net_device *ndev = NULL; s32 err = 0; u32 event = ntoh32(e->event_type); - ndev = cfgdev_to_wlc_ndev(cfgdev, wl); - if (wl_get_mode_by_netdev(wl, ndev) == WL_MODE_AP) { - err = wl_notify_connect_status_ap(wl, ndev, e, data); - } else if (wl_get_mode_by_netdev(wl, ndev) == WL_MODE_IBSS) { - err = wl_notify_connect_status_ibss(wl, ndev, e, data); - } else if (wl_get_mode_by_netdev(wl, ndev) == WL_MODE_BSS) { + wl_notify_connect_status_ap(wl, ndev, e, data); + } else { WL_DBG(("wl_notify_connect_status : event %d status : %d ndev %p\n", ntoh32(e->event_type), ntoh32(e->status), ndev)); if (event == WLC_E_ASSOC || event == WLC_E_AUTH) { wl_get_auth_assoc_status(wl, ndev, e); - return 0; + return err; } if (wl_is_linkup(wl, e, ndev)) { wl_link_up(wl); act = true; - if (!wl_get_drv_status(wl, DISCONNECTING, ndev)) { + if (wl_is_ibssmode(wl, ndev)) { + printk("cfg80211_ibss_joined\n"); + cfg80211_ibss_joined(ndev, (s8 *)&e->addr, + GFP_KERNEL); + WL_DBG(("joined in IBSS network\n")); + } else { + if (!wl_get_drv_status(wl, DISCONNECTING, ndev)) { printk("wl_bss_connect_done succeeded with " MACDBG "\n", MAC2STRDBG((u8*)(&e->addr))); wl_bss_connect_done(wl, ndev, e, data, true); WL_DBG(("joined in BSS network \"%s\"\n", ((struct wlc_ssid *) wl_read_prof(wl, ndev, WL_PROF_SSID))->SSID)); + } } wl_update_prof(wl, ndev, e, &act, WL_PROF_ACT); wl_update_prof(wl, ndev, NULL, (void *)&e->addr, WL_PROF_BSSID); @@ -7261,6 +6629,7 @@ wl_notify_connect_status(struct wl_priv reason = ntoh32(e->reason); /* WLAN_REASON_UNSPECIFIED is used for hang up event in Android */ reason = (reason == WLAN_REASON_UNSPECIFIED)? 0 : reason; + printk("link down if %s may call cfg80211_disconnected. " "event : %d, reason=%d from " MACDBG "\n", ndev->name, event, ntoh32(e->reason), @@ -7322,28 +6691,21 @@ wl_notify_connect_status(struct wl_priv if (wl_get_drv_status(wl, CONNECTING, ndev)) wl_bss_connect_done(wl, ndev, e, data, false); } else { - WL_DBG(("%s nothing\n", __FUNCTION__)); + printk("%s nothing\n", __FUNCTION__); } - } else { - WL_ERR(("Invalid ndev status %d\n", wl_get_mode_by_netdev(wl, ndev))); } return err; } static s32 -wl_notify_roaming_status(struct wl_priv *wl, bcm_struct_cfgdev *cfgdev, +wl_notify_roaming_status(struct wl_priv *wl, struct net_device *ndev, const wl_event_msg_t *e, void *data) { bool act; - struct net_device *ndev = NULL; s32 err = 0; u32 event = be32_to_cpu(e->event_type); u32 status = be32_to_cpu(e->status); - WL_DBG(("Enter \n")); - - ndev = cfgdev_to_wlc_ndev(cfgdev, wl); - if (event == WLC_E_ROAM && status == WLC_E_STATUS_SUCCESS) { if (wl_get_drv_status(wl, CONNECTED, ndev)) wl_bss_roaming_done(wl, ndev, e, data); @@ -7395,8 +6757,8 @@ static s32 wl_get_assoc_ies(struct wl_pr if (conn_info->req_ie_len <= MAX_REQ_LINE) memcpy(conn_info->req_ie, wl->extra_buf, conn_info->req_ie_len); else { - WL_ERR(("IE size %d above max %d size \n", - conn_info->req_ie_len, MAX_REQ_LINE)); + WL_ERR(("%s IE size %d above max %d size \n", + __FUNCTION__, conn_info->req_ie_len, MAX_REQ_LINE)); return err; } } else { @@ -7413,8 +6775,8 @@ static s32 wl_get_assoc_ies(struct wl_pr if (conn_info->resp_ie_len <= MAX_REQ_LINE) memcpy(conn_info->resp_ie, wl->extra_buf, conn_info->resp_ie_len); else { - WL_ERR(("IE size %d above max %d size \n", - conn_info->resp_ie_len, MAX_REQ_LINE)); + WL_ERR(("%s IE size %d above max %d size \n", + __FUNCTION__, conn_info->resp_ie_len, MAX_REQ_LINE)); return err; } } else { @@ -7458,7 +6820,7 @@ static void wl_ch_to_chanspec(int ch, st } } -static s32 wl_update_bss_info(struct wl_priv *wl, struct net_device *ndev) +static s32 wl_update_bss_info(struct wl_priv *wl, struct net_device *ndev, u8 is_roam_done) { struct cfg80211_bss *bss; struct wl_bss_info *bi; @@ -7468,12 +6830,16 @@ static s32 wl_update_bss_info(struct wl_ s32 dtim_period; size_t ie_len; u8 *ie; + u8 *ssidie; u8 *curbssid; s32 err = 0; struct wiphy *wiphy; wiphy = wl_to_wiphy(wl); + if (wl_is_ibssmode(wl, ndev)) + return err; + ssid = (struct wlc_ssid *)wl_read_prof(wl, ndev, WL_PROF_SSID); curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID); bss = cfg80211_get_bss(wiphy, NULL, curbssid, @@ -7492,11 +6858,17 @@ static s32 wl_update_bss_info(struct wl_ } bi = (struct wl_bss_info *)(wl->extra_buf + 4); if (memcmp(bi->BSSID.octet, curbssid, ETHER_ADDR_LEN)) { - WL_ERR(("Bssid doesn't match\n")); err = -EIO; goto update_bss_info_out; } - err = wl_inform_single_bss(wl, bi); + + ie = ((u8 *)bi) + bi->ie_offset; + ie_len = bi->ie_length; + ssidie = (u8 *)cfg80211_find_ie(WLAN_EID_SSID, ie, ie_len); + if (ssidie && ssidie[1] == bi->SSID_len && !ssidie[2] && bi->SSID[0]) + memcpy(ssidie + 2, bi->SSID, bi->SSID_len); + + err = wl_inform_single_bss(wl, bi, is_roam_done); if (unlikely(err)) goto update_bss_info_out; @@ -7505,19 +6877,10 @@ static s32 wl_update_bss_info(struct wl_ beacon_interval = cpu_to_le16(bi->beacon_period); } else { WL_DBG(("Found the AP in the list - BSSID %pM\n", bss->bssid)); -#if defined(WL_CFG80211_P2P_DEV_IF) - ie = (u8 *)bss->ies->data; - ie_len = bss->ies->len; -#else ie = bss->information_elements; ie_len = bss->len_information_elements; -#endif /* WL_CFG80211_P2P_DEV_IF */ beacon_interval = bss->beacon_interval; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)) - cfg80211_put_bss(wiphy, bss); -#else cfg80211_put_bss(bss); -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) */ } tim = bcm_parse_tlvs(ie, ie_len, WLAN_EID_TIM); @@ -7541,9 +6904,6 @@ static s32 wl_update_bss_info(struct wl_ wl_update_prof(wl, ndev, NULL, &dtim_period, WL_PROF_DTIMPERIOD); update_bss_info_out: - if (unlikely(err)) { - WL_ERR(("Failed with error %d\n", err)); - } mutex_unlock(&wl->usr_sync); return err; } @@ -7555,52 +6915,21 @@ wl_bss_roaming_done(struct wl_priv *wl, struct wl_connect_info *conn_info = wl_to_conn(wl); s32 err = 0; u8 *curbssid; -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) - struct wl_bss_info *bss_info; - struct wiphy *wiphy = wl_to_wiphy(wl); - struct ieee80211_supported_band *band; - struct ieee80211_channel *notify_channel = NULL; - u8 *buf; - u16 channel; - u32 freq; -#endif /* LINUX_VERSION > 2.6.39 */ wl_get_assoc_ies(wl, ndev); wl_update_prof(wl, ndev, NULL, (void *)(e->addr.octet), WL_PROF_BSSID); curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID); - wl_update_bss_info(wl, ndev); + wl_update_bss_info(wl, ndev, 1); wl_update_pmklist(ndev, wl->pmk_list, err); - -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) - /* channel info for cfg80211_roamed introduced in 2.6.39-rc1 */ - buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); - if (!buf) - goto done; - - *(__le32 *)buf = htod32(WL_EXTRA_BUF_MAX); - err = wldev_ioctl(ndev, WLC_GET_BSS_INFO, buf, WL_EXTRA_BUF_MAX, false); - if (err) - goto done; - - bss_info = (struct wl_bss_info *)(buf + 4); - channel = bss_info->ctl_ch ? bss_info->ctl_ch : - CHSPEC_CHANNEL(wl_chspec_driver_to_host(bss_info->chanspec)); - if (channel <= CH_MAX_2G_CHANNEL) - band = wiphy->bands[IEEE80211_BAND_2GHZ]; - else - band = wiphy->bands[IEEE80211_BAND_5GHZ]; - freq = ieee80211_channel_to_frequency(channel, band->band); - notify_channel = ieee80211_get_channel(wiphy, freq); -done: - kfree(buf); -#endif /* LINUX_VERSION > 2.6.39 */ - printk("wl_bss_roaming_done succeeded to " MACDBG "\n", MAC2STRDBG((u8*)(&e->addr))); cfg80211_roamed(ndev, -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) - notify_channel, + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0) + NULL, /* struct cfg80211_bss *bss */ +#elif LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) + NULL, #endif curbssid, conn_info->req_ie, conn_info->req_ie_len, @@ -7618,9 +6947,6 @@ wl_bss_connect_done(struct wl_priv *wl, { struct wl_connect_info *conn_info = wl_to_conn(wl); struct wl_security *sec = wl_read_prof(wl, ndev, WL_PROF_SEC); -#if defined(ROAM_ENABLE) && defined(ROAM_AP_ENV_DETECTION) - dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub); -#endif /* ROAM_AP_ENV_DETECTION */ s32 err = 0; u8 *curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID); if (!sec) { @@ -7648,24 +6974,14 @@ wl_bss_connect_done(struct wl_priv *wl, } #endif /* ESCAN_RESULT_PATCH */ if (wl_get_drv_status(wl, CONNECTING, ndev)) { - wl_cfg80211_scan_abort(wl); wl_clr_drv_status(wl, CONNECTING, ndev); if (completed) { wl_get_assoc_ies(wl, ndev); wl_update_prof(wl, ndev, NULL, (void *)(e->addr.octet), WL_PROF_BSSID); curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID); - wl_update_bss_info(wl, ndev); + wl_update_bss_info(wl, ndev, 0); wl_update_pmklist(ndev, wl->pmk_list, err); wl_set_drv_status(wl, CONNECTED, ndev); -#if defined(ROAM_ENABLE) && defined(ROAM_AP_ENV_DETECTION) - if (dhd->roam_env_detection) - wldev_iovar_setint(ndev, "roam_env_detection", - AP_ENV_INDETERMINATE); -#endif /* ROAM_AP_ENV_DETECTION */ - if (ndev != wl_to_prmry_ndev(wl)) { - /* reinitialize completion to clear previous count */ - INIT_COMPLETION(wl->iface_disable); - } } cfg80211_connect_result(ndev, curbssid, @@ -7687,15 +7003,12 @@ wl_bss_connect_done(struct wl_priv *wl, } static s32 -wl_notify_mic_status(struct wl_priv *wl, bcm_struct_cfgdev *cfgdev, +wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev, const wl_event_msg_t *e, void *data) { - struct net_device *ndev = NULL; u16 flags = ntoh16(e->flags); enum nl80211_key_type key_type; - ndev = cfgdev_to_wlc_ndev(cfgdev, wl); - mutex_lock(&wl->usr_sync); if (flags & WLC_EVENT_MSG_GROUP) key_type = NL80211_KEYTYPE_GROUP; @@ -7711,15 +7024,11 @@ wl_notify_mic_status(struct wl_priv *wl, #ifdef PNO_SUPPORT static s32 -wl_notify_pfn_status(struct wl_priv *wl, bcm_struct_cfgdev *cfgdev, +wl_notify_pfn_status(struct wl_priv *wl, struct net_device *ndev, const wl_event_msg_t *e, void *data) { - struct net_device *ndev = NULL; - WL_ERR((">>> PNO Event\n")); - ndev = cfgdev_to_wlc_ndev(cfgdev, wl); - #ifndef WL_SCHED_SCAN mutex_lock(&wl->usr_sync); /* TODO: Use cfg80211_sched_scan_results(wiphy); */ @@ -7736,12 +7045,11 @@ wl_notify_pfn_status(struct wl_priv *wl, #endif /* PNO_SUPPORT */ static s32 -wl_notify_scan_status(struct wl_priv *wl, bcm_struct_cfgdev *cfgdev, +wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev, const wl_event_msg_t *e, void *data) { struct channel_info channel_inform; struct wl_scan_results *bss_list; - struct net_device *ndev = NULL; u32 len = WL_SCAN_BUF_MAX; s32 err = 0; unsigned long flags; @@ -7754,8 +7062,6 @@ wl_notify_scan_status(struct wl_priv *wl if (wl->iscan_on && wl->iscan_kickstart) return wl_wakeup_iscan(wl_to_iscan(wl)); - ndev = cfgdev_to_wlc_ndev(cfgdev, wl); - mutex_lock(&wl->usr_sync); wl_clr_drv_status(wl, SCANNING, ndev); err = wldev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform, @@ -7798,7 +7104,6 @@ scan_done_out: mutex_unlock(&wl->usr_sync); return err; } - static s32 wl_frame_get_mgmt(u16 fc, const struct ether_addr *da, const struct ether_addr *sa, const struct ether_addr *bssid, @@ -7844,39 +7149,33 @@ wl_frame_get_mgmt(u16 fc, const struct e void -wl_stop_wait_next_action_frame(struct wl_priv *wl) +wl_stop_wait_next_action_frame(struct wl_priv *wl, struct net_device *ndev) { - if (wl_get_drv_status_all(wl, SENDING_ACT_FRM)) { - if (!(wl_get_p2p_status(wl, ACTION_TX_COMPLETED) || - wl_get_p2p_status(wl, ACTION_TX_NOACK))) - wl_set_p2p_status(wl, ACTION_TX_COMPLETED); - + if (wl_get_drv_status_all(wl, SENDING_ACT_FRM) && + (wl_get_p2p_status(wl, ACTION_TX_COMPLETED) || + wl_get_p2p_status(wl, ACTION_TX_NOACK))) { WL_DBG(("*** Wake UP ** abort actframe iovar\n")); /* if channel is not zero, "actfame" uses off channel scan. * So abort scan for off channel completion. */ if (wl->af_sent_channel) - wl_cfg80211_scan_abort(wl); + /* wl_cfg80211_scan_abort(wl, ndev); */ + wl_notify_escan_complete(wl, + (ndev == wl->p2p_net) ? wl_to_prmry_ndev(wl) : ndev, true, true); } #ifdef WL_CFG80211_SYNC_GON else if (wl_get_drv_status_all(wl, WAITING_NEXT_ACT_FRM_LISTEN)) { WL_DBG(("*** Wake UP ** abort listen for next af frame\n")); /* So abort scan to cancel listen */ - wl_cfg80211_scan_abort(wl); + wl_notify_escan_complete(wl, + (ndev == wl->p2p_net) ? wl_to_prmry_ndev(wl) : ndev, true, true); } #endif /* WL_CFG80211_SYNC_GON */ } - -int wl_cfg80211_get_ioctl_version(void) -{ - return ioctl_version; -} - static s32 -wl_notify_rx_mgmt_frame(struct wl_priv *wl, bcm_struct_cfgdev *cfgdev, +wl_notify_rx_mgmt_frame(struct wl_priv *wl, struct net_device *ndev, const wl_event_msg_t *e, void *data) - { struct ieee80211_supported_band *band; struct wiphy *wiphy = wl_to_wiphy(wl); @@ -7885,7 +7184,7 @@ wl_notify_rx_mgmt_frame(struct wl_priv * bool isfree = false; s32 err = 0; s32 freq; - struct net_device *ndev = NULL; + struct net_device *dev = NULL; wifi_p2p_pub_act_frame_t *act_frm = NULL; wifi_p2p_action_frame_t *p2p_act_frm = NULL; wifi_p2psd_gas_pub_act_frame_t *sd_act_frm = NULL; @@ -7899,7 +7198,11 @@ wl_notify_rx_mgmt_frame(struct wl_priv * memset(&bssid, 0, ETHER_ADDR_LEN); - ndev = cfgdev_to_wlc_ndev(cfgdev, wl); + if (wl->p2p_net == ndev) { + dev = wl_to_prmry_ndev(wl); + } else { + dev = ndev; + } if (channel <= CH_MAX_2G_CHANNEL) band = wiphy->bands[IEEE80211_BAND_2GHZ]; @@ -7909,17 +7212,17 @@ wl_notify_rx_mgmt_frame(struct wl_priv * WL_ERR(("No valid band")); return -EINVAL; } -#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) +#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 if (event == WLC_E_ACTION_FRAME_RX) { - wldev_iovar_getbuf_bsscfg(ndev, "cur_etheraddr", + wldev_iovar_getbuf_bsscfg(dev, "cur_etheraddr", NULL, 0, wl->ioctl_buf, WLC_IOCTL_SMLEN, bsscfgidx, &wl->ioctl_buf_sync); - err = wldev_ioctl(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false); + err = wldev_ioctl(dev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false); if (err < 0) WL_ERR(("WLC_GET_BSSID error %d\n", err)); memcpy(da.octet, wl->ioctl_buf, ETHER_ADDR_LEN); @@ -7927,8 +7230,8 @@ wl_notify_rx_mgmt_frame(struct wl_priv * &mgmt_frame, &mgmt_frame_len, (u8 *)((wl_event_rx_frame_data_t *)rxframe + 1)); if (err < 0) { - WL_ERR(("Error in receiving action frame len %d channel %d freq %d\n", - mgmt_frame_len, channel, freq)); + WL_ERR(("%s: Error in receiving action frame len %d channel %d freq %d\n", + __func__, mgmt_frame_len, channel, freq)); goto exit; } isfree = true; @@ -7943,44 +7246,28 @@ wl_notify_rx_mgmt_frame(struct wl_priv * (void) p2p_act_frm; } else if (wl_cfgp2p_is_gas_action(&mgmt_frame[DOT11_MGMT_HDR_LEN], mgmt_frame_len - DOT11_MGMT_HDR_LEN)) { - sd_act_frm = (wifi_p2psd_gas_pub_act_frame_t *) (&mgmt_frame[DOT11_MGMT_HDR_LEN]); if (sd_act_frm && wl_get_drv_status_all(wl, WAITING_NEXT_ACT_FRM)) { if (wl->next_af_subtype == sd_act_frm->action) { WL_DBG(("We got a right next frame of SD!(%d)\n", sd_act_frm->action)); - wl_clr_drv_status(wl, WAITING_NEXT_ACT_FRM, ndev); + wl_clr_drv_status(wl, WAITING_NEXT_ACT_FRM, + (ndev == wl->p2p_net) ? + wl_to_prmry_ndev(wl) : ndev); /* Stop waiting for next AF. */ - wl_stop_wait_next_action_frame(wl); + wl_stop_wait_next_action_frame(wl, ndev); } } (void) sd_act_frm; } else { /* - * if we got normal action frame and ndev is p2p0, - * we have to change ndev from p2p0 to wlan0 + * if we got normal action frame and ndev is p2p0, + * we have to change ndev from p2p0 to wlan0 */ -#if defined(WL_ENABLE_P2P_IF) - if (wl->p2p_net == cfgdev) - cfgdev = wl_to_prmry_ndev(wl); -#endif /* WL_ENABLE_P2P_IF */ - - if (wl->next_af_subtype != P2P_PAF_SUBTYPE_INVALID) { - u8 action = 0; - if (wl_get_public_action(&mgmt_frame[DOT11_MGMT_HDR_LEN], - mgmt_frame_len - DOT11_MGMT_HDR_LEN, &action) != BCME_OK) { - WL_DBG(("Recived action is not public action frame\n")); - } else if (wl->next_af_subtype == action) { - WL_DBG(("Recived action is the waiting action(%d)\n", - action)); - wl_clr_drv_status(wl, WAITING_NEXT_ACT_FRM, ndev); - - /* Stop waiting for next AF. */ - wl_stop_wait_next_action_frame(wl); - } - } + if (wl->p2p_net == ndev) + ndev = wl_to_prmry_ndev(wl); } if (act_frm) { @@ -7989,22 +7276,24 @@ wl_notify_rx_mgmt_frame(struct wl_priv * if (wl->next_af_subtype == act_frm->subtype) { WL_DBG(("We got a right next frame!(%d)\n", act_frm->subtype)); - wl_clr_drv_status(wl, WAITING_NEXT_ACT_FRM, ndev); + wl_clr_drv_status(wl, WAITING_NEXT_ACT_FRM, + (ndev == wl->p2p_net) ? + wl_to_prmry_ndev(wl) : ndev); /* Stop waiting for next AF. */ - wl_stop_wait_next_action_frame(wl); + wl_stop_wait_next_action_frame(wl, ndev); } } } wl_cfgp2p_print_actframe(false, &mgmt_frame[DOT11_MGMT_HDR_LEN], - mgmt_frame_len - DOT11_MGMT_HDR_LEN, channel); + mgmt_frame_len - DOT11_MGMT_HDR_LEN); /* * After complete GO Negotiation, roll back to mpc mode */ if (act_frm && ((act_frm->subtype == P2P_PAF_GON_CONF) || (act_frm->subtype == P2P_PAF_PROVDIS_RSP))) { - wldev_iovar_setint(ndev, "mpc", 1); + wldev_iovar_setint(dev, "mpc", 1); } if (act_frm && (act_frm->subtype == P2P_PAF_GON_CONF)) { WL_DBG(("P2P: GO_NEG_PHASE status cleared \n")); @@ -8036,12 +7325,12 @@ wl_notify_rx_mgmt_frame(struct wl_priv * } #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) - cfg80211_rx_mgmt(cfgdev, freq, 0, mgmt_frame, mgmt_frame_len, GFP_ATOMIC); + cfg80211_rx_mgmt(ndev, freq, 0, mgmt_frame, mgmt_frame_len, GFP_ATOMIC); #else - cfg80211_rx_mgmt(cfgdev, freq, mgmt_frame, mgmt_frame_len, GFP_ATOMIC); + cfg80211_rx_mgmt(ndev, freq, mgmt_frame, mgmt_frame_len, GFP_ATOMIC); #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) */ - WL_DBG(("mgmt_frame_len (%d) , e->datalen (%d), channel (%d), freq (%d)\n", + WL_DBG(("%s: mgmt_frame_len (%d) , e->datalen (%d), channel (%d), freq (%d)\n", __func__, mgmt_frame_len, ntoh32(e->datalen), channel, freq)); exit: if (isfree) @@ -8059,15 +7348,14 @@ wl_notify_sched_scan_results(struct wl_p const wl_event_msg_t *e, void *data) { wl_pfn_net_info_t *netinfo, *pnetinfo; + struct cfg80211_scan_request request; struct wiphy *wiphy = wl_to_wiphy(wl); int err = 0; - struct cfg80211_scan_request *request = NULL; struct cfg80211_ssid ssid[MAX_PFN_LIST_COUNT]; struct ieee80211_channel *channel = NULL; int channel_req = 0; int band = 0; struct wl_pfn_scanresults *pfn_result = (struct wl_pfn_scanresults *)data; - int n_pfn_results = pfn_result->count; WL_DBG(("Enter\n")); @@ -8075,32 +7363,26 @@ wl_notify_sched_scan_results(struct wl_p WL_PNO(("PFN NET LOST event. Do Nothing \n")); return 0; } - WL_PNO((">>> PFN NET FOUND event. count:%d \n", n_pfn_results)); - if (n_pfn_results > 0) { + WL_PNO((">>> PFN NET FOUND event. count:%d \n", pfn_result->count)); + if (pfn_result->count > 0) { int i; - if (n_pfn_results > MAX_PFN_LIST_COUNT) - n_pfn_results = MAX_PFN_LIST_COUNT; - pnetinfo = (wl_pfn_net_info_t *)(data + sizeof(wl_pfn_scanresults_t) - - sizeof(wl_pfn_net_info_t)); - + memset(&request, 0x00, sizeof(struct cfg80211_scan_request)); memset(&ssid, 0x00, sizeof(ssid)); + request.wiphy = wiphy; - request = kzalloc(sizeof(*request) - + sizeof(*request->channels) * n_pfn_results, - GFP_KERNEL); + pnetinfo = (wl_pfn_net_info_t *)(data + sizeof(wl_pfn_scanresults_t) + - sizeof(wl_pfn_net_info_t)); channel = (struct ieee80211_channel *)kzalloc( - (sizeof(struct ieee80211_channel) * n_pfn_results), + (sizeof(struct ieee80211_channel) * MAX_PFN_LIST_COUNT), GFP_KERNEL); - if (!request || !channel) { + if (!channel) { WL_ERR(("No memory")); err = -ENOMEM; goto out_err; } - request->wiphy = wiphy; - - for (i = 0; i < n_pfn_results; i++) { + for (i = 0; i < pfn_result->count; i++) { netinfo = &pnetinfo[i]; if (!netinfo) { WL_ERR(("Invalid netinfo ptr. index:%d", i)); @@ -8118,7 +7400,7 @@ wl_notify_sched_scan_results(struct wl_p memcpy(ssid[i].ssid, netinfo->pfnsubnet.SSID, netinfo->pfnsubnet.SSID_len); ssid[i].ssid_len = netinfo->pfnsubnet.SSID_len; - request->n_ssids++; + request.n_ssids++; channel_req = netinfo->pfnsubnet.channel; band = (channel_req <= CH_MAX_2G_CHANNEL) ? NL80211_BAND_2GHZ @@ -8126,13 +7408,13 @@ wl_notify_sched_scan_results(struct wl_p channel[i].center_freq = ieee80211_channel_to_frequency(channel_req, band); channel[i].band = band; channel[i].flags |= IEEE80211_CHAN_NO_HT40; - request->channels[i] = &channel[i]; - request->n_channels++; + request.channels[i] = &channel[i]; + request.n_channels++; } /* assign parsed ssid array */ - if (request->n_ssids) - request->ssids = &ssid[0]; + if (request.n_ssids) + request.ssids = &ssid[0]; if (wl_get_drv_status_all(wl, SCANNING)) { /* Abort any on-going scan */ @@ -8146,7 +7428,6 @@ wl_notify_sched_scan_results(struct wl_p wl_clr_drv_status(wl, SCANNING, ndev); goto out_err; } - p2p_scan(wl) = false; } wl_set_drv_status(wl, SCANNING, ndev); @@ -8155,7 +7436,7 @@ wl_notify_sched_scan_results(struct wl_p err = wl_do_escan(wl, wiphy, ndev, NULL); #else WL_PNO((">>> Doing targeted ESCAN on PNO event\n")); - err = wl_do_escan(wl, wiphy, ndev, request); + err = wl_do_escan(wl, wiphy, ndev, &request); #endif if (err) { wl_clr_drv_status(wl, SCANNING, ndev); @@ -8167,8 +7448,6 @@ wl_notify_sched_scan_results(struct wl_p WL_ERR(("FALSE PNO Event. (pfn_count == 0) \n")); } out_err: - if (request) - kfree(request); if (channel) kfree(channel); return err; @@ -8217,32 +7496,11 @@ static void wl_init_event_handler(struct 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_JOIN] = wl_notify_connect_status; - wl->evt_handler[WLC_E_START] = wl_notify_connect_status; #ifdef PNO_SUPPORT wl->evt_handler[WLC_E_PFN_NET_FOUND] = wl_notify_pfn_status; #endif /* PNO_SUPPORT */ -#ifdef WLTDLS - wl->evt_handler[WLC_E_TDLS_PEER_EVENT] = wl_tdls_event_handler; -#endif /* WLTDLS */ } -#if defined(STATIC_WL_PRIV_STRUCT) -static void -wl_init_escan_result_buf(struct wl_priv *wl) -{ - wl->escan_info.escan_buf = dhd_os_prealloc(NULL, DHD_PREALLOC_WIPHY_ESCAN0, 0); - bzero(wl->escan_info.escan_buf, ESCAN_BUF_SIZE); -} - -static void -wl_deinit_escan_result_buf(struct wl_priv *wl) -{ - wl->escan_info.escan_buf = NULL; - -} -#endif /* STATIC_WL_PRIV_STRUCT */ - static s32 wl_init_priv_mem(struct wl_priv *wl) { WL_DBG(("Enter \n")); @@ -8304,7 +7562,8 @@ static s32 wl_init_priv_mem(struct wl_pr WL_ERR(("wl->ie alloc failed\n")); goto init_priv_mem_out; } - wl_init_escan_result_buf(wl); + wl->escan_info.escan_buf = dhd_os_prealloc(NULL, DHD_PREALLOC_WIPHY_ESCAN0, 0); + bzero(wl->escan_info.escan_buf, ESCAN_BUF_SIZE); #endif /* STATIC_WL_PRIV_STRUCT */ wl->afx_hdl = (void *)kzalloc(sizeof(*wl->afx_hdl), GFP_KERNEL); if (unlikely(!wl->afx_hdl)) { @@ -8349,7 +7608,7 @@ static void wl_deinit_priv_mem(struct wl wl->conn_info = NULL; kfree(wl->ie); wl->ie = NULL; - wl_deinit_escan_result_buf(wl); + wl->escan_info.escan_buf = NULL; #endif /* STATIC_WL_PRIV_STRUCT */ if (wl->afx_hdl) { cancel_work_sync(&wl->afx_hdl->work); @@ -8374,7 +7633,11 @@ static s32 wl_create_event_handler(struc /* Do not use DHD in cfg driver */ wl->event_tsk.thr_pid = -1; - PROC_START(wl_event_handler, wl, &wl->event_tsk, 0, "wl_event_handler"); +#ifdef USE_KTHREAD_API + PROC_START2(wl_event_handler, wl, &wl->event_tsk, 0, "wl_event_handler"); +#else + PROC_START(wl_event_handler, wl, &wl->event_tsk, 0); +#endif if (wl->event_tsk.thr_pid < 0) ret = -ENOMEM; return ret; @@ -8506,7 +7769,7 @@ static s32 wl_iscan_inprogress(struct wl wl_run_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE); mutex_unlock(&wl->usr_sync); /* Reschedule the timer */ - mod_timer(&iscan->timer, jiffies + msecs_to_jiffies(iscan->timer_ms)); + mod_timer(&iscan->timer, jiffies + msecs_to_jiffies(iscan->timer_ms)); iscan->timer_on = 1; return err; @@ -8554,7 +7817,7 @@ static s32 wl_iscan_thread(void *data) del_timer_sync(&iscan->timer); iscan->timer_on = 0; } - WL_DBG(("was terminated\n")); + WL_DBG(("%s was terminated\n", __func__)); return 0; } @@ -8569,19 +7832,17 @@ static void wl_scan_timeout(unsigned lon return; } bzero(&msg, sizeof(wl_event_msg_t)); - WL_ERR(("timer expired\n")); + WL_ERR(("timer expired\n")); if (wl->escan_on) { msg.event_type = hton32(WLC_E_ESCAN_RESULT); msg.status = hton32(WLC_E_STATUS_TIMEOUT); msg.reason = 0xFFFFFFFF; wl_cfg80211_event(wl_to_prmry_ndev(wl), &msg, NULL); } else { - /* Need to check it try to access SDIO */ WL_ERR(("SCAN Timeout(ISCAN)\n")); - wl_notify_iscan_complete(wl_to_iscan(wl), true); + 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; @@ -8637,37 +7898,16 @@ wl_cfg80211_netdev_notifier_call(struct return NOTIFY_DONE; switch (state) { case NETDEV_DOWN: - { - int max_wait_timeout = 2; - int max_wait_count = 100; - unsigned long limit = jiffies + max_wait_timeout * HZ; - while (work_pending(&wdev->cleanup_work)) { - if (refcnt%5 == 0) { - WL_ERR(("[NETDEV_DOWN] wait for " - "complete of cleanup_work" - " (%d th)\n", refcnt)); - } - if (!time_before(jiffies, limit)) { - WL_ERR(("[NETDEV_DOWN] cleanup_work" - " of CFG80211 is not" - " completed in %d sec\n", - max_wait_timeout)); - break; - } - if (refcnt >= max_wait_count) { - WL_ERR(("[NETDEV_DOWN] cleanup_work" - " of CFG80211 is not" - " completed in %d loop\n", - max_wait_count)); - break; - } + while (work_pending(&wdev->cleanup_work) && refcnt < 100) { + if (refcnt%5 == 0) + WL_ERR(("%s : [NETDEV_DOWN] work_pending (%d th)\n", + __FUNCTION__, refcnt)); set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(100); set_current_state(TASK_RUNNING); refcnt++; } break; - } case NETDEV_UNREGISTER: /* after calling list_del_rcu(&wdev->list) */ @@ -8693,72 +7933,55 @@ static struct notifier_block wl_cfg80211 .notifier_call = wl_cfg80211_netdev_notifier_call, }; -static void wl_cfg80211_scan_abort(struct wl_priv *wl) -{ - wl_scan_params_t *params = NULL; - s32 params_size = 0; - s32 err = BCME_OK; - struct net_device *dev = wl_to_prmry_ndev(wl); - if (!in_atomic()) { - /* Our scan params only need space for 1 channel and 0 ssids */ - params = wl_cfg80211_scan_alloc_params(-1, 0, ¶ms_size); - if (params == NULL) { - WL_ERR(("scan params allocation failed \n")); - err = -ENOMEM; - } else { - /* Do a scan abort to stop the driver's scan engine */ - err = wldev_ioctl(dev, WLC_SCAN, params, params_size, true); - if (err < 0) { - WL_ERR(("scan abort failed \n")); - } - kfree(params); - } - } -} - static s32 wl_notify_escan_complete(struct wl_priv *wl, struct net_device *ndev, bool aborted, bool fw_abort) { + wl_scan_params_t *params = NULL; + s32 params_size = 0; s32 err = BCME_OK; unsigned long flags; struct net_device *dev; WL_DBG(("Enter \n")); - if (!ndev) { - WL_ERR(("ndev is null\n")); - err = BCME_ERROR; - return err; - } - if (wl->escan_info.ndev != ndev) { + if (wl->escan_info.ndev != ndev) + { WL_ERR(("ndev is different %p %p\n", wl->escan_info.ndev, ndev)); - err = BCME_ERROR; return err; } if (wl->scan_request) { - dev = wl_to_prmry_ndev(wl); -#if defined(WL_ENABLE_P2P_IF) - if (wl->scan_request->dev != wl->p2p_net) + if (wl->scan_request->dev == wl->p2p_net) + dev = wl_to_prmry_ndev(wl); + else dev = wl->scan_request->dev; -#endif /* WL_ENABLE_P2P_IF */ } else { WL_DBG(("wl->scan_request is NULL may be internal scan." - "doing scan_abort for ndev %p primary %p", - ndev, wl_to_prmry_ndev(wl))); + "doing scan_abort for ndev %p primary %p p2p_net %p", + ndev, wl_to_prmry_ndev(wl), wl->p2p_net)); dev = ndev; } if (fw_abort && !in_atomic()) { - wl_cfg80211_scan_abort(wl); + /* Our scan params only need space for 1 channel and 0 ssids */ + params = wl_cfg80211_scan_alloc_params(-1, 0, ¶ms_size); + if (params == NULL) { + WL_ERR(("scan params allocation failed \n")); + err = -ENOMEM; + } else { + /* Do a scan abort to stop the driver's scan engine */ + err = wldev_ioctl(dev, WLC_SCAN, params, params_size, true); + if (err < 0) { + WL_ERR(("scan abort failed \n")); + } + } } - if (timer_pending(&wl->scan_timeout)) del_timer_sync(&wl->scan_timeout); #if defined(ESCAN_RESULT_PATCH) if (likely(wl->scan_request)) { - wl->bss_list = wl_escan_get_buf(wl, aborted); + wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf; wl_inform_bss(wl); } #endif /* ESCAN_RESULT_PATCH */ @@ -8766,7 +7989,9 @@ static s32 wl_notify_escan_complete(stru #ifdef WL_SCHED_SCAN if (wl->sched_scan_req && !wl->scan_request) { WL_PNO((">>> REPORTING SCHED SCAN RESULTS \n")); - if (!aborted) + if (aborted) + cfg80211_sched_scan_stopped(wl->sched_scan_req->wiphy); + else cfg80211_sched_scan_results(wl->sched_scan_req->wiphy); wl->sched_scan_running = FALSE; wl->sched_scan_req = NULL; @@ -8780,10 +8005,14 @@ static s32 wl_notify_escan_complete(stru wl_clr_p2p_status(wl, SCANNING); wl_clr_drv_status(wl, SCANNING, dev); spin_unlock_irqrestore(&wl->cfgdrv_lock, flags); + if (params) + kfree(params); + return err; } -static s32 wl_escan_handler(struct wl_priv *wl, bcm_struct_cfgdev *cfgdev, +static s32 wl_escan_handler(struct wl_priv *wl, + struct net_device *ndev, const wl_event_msg_t *e, void *data) { s32 err = BCME_OK; @@ -8793,7 +8022,6 @@ static s32 wl_escan_handler(struct wl_pr wl_bss_info_t *bss = NULL; wl_scan_results_t *list; wifi_p2p_ie_t * p2p_ie; - struct net_device *ndev = NULL; u32 bi_length; u32 i; u8 *p2p_dev_addr = NULL; @@ -8801,8 +8029,6 @@ static s32 wl_escan_handler(struct wl_pr WL_DBG((" enter event type : %d, status : %d \n", ntoh32(e->event_type), ntoh32(e->status))); - ndev = cfgdev_to_wlc_ndev(cfgdev, wl); - mutex_lock(&wl->usr_sync); /* P2P SCAN is coming from primary interface */ if (wl_get_p2p_status(wl, SCANNING)) { @@ -8815,16 +8041,13 @@ static s32 wl_escan_handler(struct wl_pr if (!ndev || !wl->escan_on || (!wl_get_drv_status(wl, SCANNING, ndev) && !wl->sched_scan_running)) { - WL_ERR(("escan is not ready ndev %p wl->escan_on %d" - " drv_status 0x%x e_type %d e_states %d\n", - ndev, wl->escan_on, wl_get_drv_status(wl, SCANNING, ndev), - ntoh32(e->event_type), ntoh32(e->status))); + WL_ERR(("escan is not ready ndev %p wl->escan_on %d drv_status 0x%x\n", + ndev, wl->escan_on, wl_get_drv_status(wl, SCANNING, ndev))); goto exit; } - escan_result = (wl_escan_result_t *)data; - if (status == WLC_E_STATUS_PARTIAL) { WL_INFO(("WLC_E_STATUS_PARTIAL \n")); + escan_result = (wl_escan_result_t *) data; if (!escan_result) { WL_ERR(("Invalid escan result (NULL pointer)\n")); goto exit; @@ -8843,9 +8066,6 @@ static s32 wl_escan_handler(struct wl_pr WL_ERR(("Invalid bss_info length %d: ignoring\n", bi_length)); goto exit; } - if (wl_escan_check_sync_id(status, escan_result->sync_id, - wl->escan_info.cur_sync_id) < 0) - goto exit; if (!(wl_to_wiphy(wl)->interface_modes & BIT(NL80211_IFTYPE_ADHOC))) { if (dtoh16(bi->capability) & DOT11_CAP_IBSS) { @@ -8858,17 +8078,10 @@ static s32 wl_escan_handler(struct wl_pr p2p_dev_addr = wl_cfgp2p_retreive_p2p_dev_addr(bi, bi_length); if (p2p_dev_addr && !memcmp(p2p_dev_addr, wl->afx_hdl->tx_dst_addr.octet, ETHER_ADDR_LEN)) { - s32 channel = wf_chspec_ctlchan( + s32 channel = CHSPEC_CHANNEL( wl_chspec_driver_to_host(bi->chanspec)); - - if ((channel > MAXCHANNEL) || (channel <= 0)) - channel = WL_INVALID; - else - WL_ERR(("ACTION FRAME SCAN : Peer " MACDBG " found," - " channel : %d\n", - MAC2STRDBG(wl->afx_hdl->tx_dst_addr.octet), - channel)); - + WL_DBG(("ACTION FRAME SCAN : Peer " MACDBG " found, channel : %d\n", + MAC2STRDBG(wl->afx_hdl->tx_dst_addr.octet), channel)); wl_clr_p2p_status(wl, SCANNING); wl->afx_hdl->peer_chan = channel; complete(&wl->act_frm_scan); @@ -8877,11 +8090,20 @@ static s32 wl_escan_handler(struct wl_pr } else { int cur_len = WL_SCAN_RESULTS_FIXED_SIZE; - list = wl_escan_get_buf(wl, FALSE); - if (scan_req_match(wl)) { + list = (wl_scan_results_t *)wl->escan_info.escan_buf; +#if defined(WLP2P) && defined(WL_ENABLE_P2P_IF) + if (wl->p2p_net && wl->scan_request && + wl->scan_request->dev == wl->p2p_net) +#else + if (p2p_is_on(wl) && p2p_scan(wl)) +#endif + { +#ifdef WL_HOST_BAND_MGMT + s32 channel = 0; + s32 channel_band = 0; +#endif /* WL_HOST_BAND_MGMT */ /* p2p scan && allow only probe response */ - if ((wl->p2p->search_state != WL_P2P_DISC_ST_SCAN) && - (bi->flags & WL_BSS_FLAGS_FROM_BEACON)) + if (bi->flags & WL_BSS_FLAGS_FROM_BEACON) goto exit; if ((p2p_ie = wl_cfgp2p_find_p2pie(((u8 *) bi) + bi->ie_offset, bi->ie_length)) == NULL) { @@ -8889,6 +8111,20 @@ static s32 wl_escan_handler(struct wl_pr " response/beacon\n")); goto exit; } +#ifdef WL_HOST_BAND_MGMT + channel = CHSPEC_CHANNEL(wl_chspec_driver_to_host(bi->chanspec)); + channel_band = (channel > CH_MAX_2G_CHANNEL) ? + WLC_BAND_5G : WLC_BAND_2G; + + + if ((wl->curr_band == WLC_BAND_5G) && + (channel_band == WLC_BAND_2G)) { + /* Avoid sending the GO results in band conflict */ + if (wl_cfgp2p_retreive_p2pattrib(p2p_ie, + P2P_SEID_GROUP_ID) != NULL) + goto exit; + } +#endif /* WL_HOST_BAND_MGMT */ } for (i = 0; i < list->count; i++) { bss = bss ? (wl_bss_info_t *)((uintptr)bss + dtoh32(bss->length)) @@ -8974,20 +8210,19 @@ static s32 wl_escan_handler(struct wl_pr WL_ERR(("Buffer is too small: ignoring\n")); goto exit; } - - memcpy(&(((char *)list)[list->buflen]), bi, bi_length); + if (strlen(bi->SSID) == 0) { // terence: fix for hidden SSID + WL_SCAN(("Skip hidden SSID %pM\n", &bi->BSSID)); + goto exit; + } + memcpy(&(wl->escan_info.escan_buf[list->buflen]), bi, bi_length); list->version = dtoh32(bi->version); list->buflen += bi_length; list->count++; - } } else if (status == WLC_E_STATUS_SUCCESS) { wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE; - wl_escan_print_sync_id(status, wl->escan_info.cur_sync_id, - escan_result->sync_id); - if (wl_get_drv_status_all(wl, FINDING_COMMON_CHANNEL)) { WL_INFO(("ACTION FRAME SCAN DONE\n")); wl_clr_p2p_status(wl, SCANNING); @@ -8996,20 +8231,13 @@ static s32 wl_escan_handler(struct wl_pr complete(&wl->act_frm_scan); } else if ((likely(wl->scan_request)) || (wl->sched_scan_running)) { WL_INFO(("ESCAN COMPLETED\n")); - wl->bss_list = wl_escan_get_buf(wl, FALSE); - if (!scan_req_match(wl)) { - WL_TRACE_HW4(("SCAN COMPLETED: scanned AP count=%d\n", - wl->bss_list->count)); - } + wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf; wl_inform_bss(wl); wl_notify_escan_complete(wl, ndev, false, false); } - wl_escan_increment_sync_id(wl, SCAN_BUF_NEXT); } else if (status == WLC_E_STATUS_ABORT) { wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE; - wl_escan_print_sync_id(status, escan_result->sync_id, - wl->escan_info.cur_sync_id); if (wl_get_drv_status_all(wl, FINDING_COMMON_CHANNEL)) { WL_INFO(("ACTION FRAME SCAN DONE\n")); wl_clr_drv_status(wl, SCANNING, wl->afx_hdl->dev); @@ -9018,16 +8246,14 @@ static s32 wl_escan_handler(struct wl_pr complete(&wl->act_frm_scan); } else if ((likely(wl->scan_request)) || (wl->sched_scan_running)) { WL_INFO(("ESCAN ABORTED\n")); - wl->bss_list = wl_escan_get_buf(wl, TRUE); - if (!scan_req_match(wl)) { - WL_TRACE_HW4(("SCAN ABORTED: scanned AP count=%d\n", - wl->bss_list->count)); - } + wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf; wl_inform_bss(wl); wl_notify_escan_complete(wl, ndev, true, false); } - wl_escan_increment_sync_id(wl, SCAN_BUF_CNT); - } else if (status == WLC_E_STATUS_NEWSCAN) { + } + else if (status == WLC_E_STATUS_NEWSCAN) + { + escan_result = (wl_escan_result_t *) data; WL_ERR(("WLC_E_STATUS_NEWSCAN : scan_request[%p]\n", wl->scan_request)); WL_ERR(("sync_id[%d], bss_count[%d]\n", escan_result->sync_id, escan_result->bss_count)); @@ -9040,8 +8266,6 @@ static s32 wl_escan_handler(struct wl_pr } else { WL_ERR(("unexpected Escan Event %d : abort\n", status)); wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE; - wl_escan_print_sync_id(status, escan_result->sync_id, - wl->escan_info.cur_sync_id); if (wl_get_drv_status_all(wl, FINDING_COMMON_CHANNEL)) { WL_INFO(("ACTION FRAME SCAN DONE\n")); wl_clr_p2p_status(wl, SCANNING); @@ -9049,22 +8273,15 @@ static s32 wl_escan_handler(struct wl_pr if (wl->afx_hdl->peer_chan == WL_INVALID) complete(&wl->act_frm_scan); } else if ((likely(wl->scan_request)) || (wl->sched_scan_running)) { - wl->bss_list = wl_escan_get_buf(wl, TRUE); - if (!scan_req_match(wl)) { - WL_TRACE_HW4(("SCAN ABORTED(UNEXPECTED): " - "scanned AP count=%d\n", - wl->bss_list->count)); - } + wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf; wl_inform_bss(wl); wl_notify_escan_complete(wl, ndev, true, false); } - wl_escan_increment_sync_id(wl, 2); } exit: mutex_unlock(&wl->usr_sync); return err; } - static void wl_cfg80211_concurrent_roam(struct wl_priv *wl, int enable) { u32 connected_cnt = wl_get_drv_status_all(wl, CONNECTED); @@ -9107,9 +8324,9 @@ static void wl_cfg80211_concurrent_roam( static void wl_cfg80211_determine_vsdb_mode(struct wl_priv *wl) { struct net_info *iter, *next; - u32 ctl_chan = 0; + u32 chan = 0; u32 chanspec = 0; - u32 pre_ctl_chan = 0; + u32 prev_chan = 0; u32 connected_cnt = wl_get_drv_status_all(wl, CONNECTED); wl->vsdb_mode = false; @@ -9118,34 +8335,33 @@ static void wl_cfg80211_determine_vsdb_m } for_each_ndev(wl, iter, next) { chanspec = 0; - ctl_chan = 0; + chan = 0; if (wl_get_drv_status(wl, CONNECTED, iter->ndev)) { if (wldev_iovar_getint(iter->ndev, "chanspec", (s32 *)&chanspec) == BCME_OK) { - chanspec = wl_chspec_driver_to_host(chanspec); - ctl_chan = wf_chspec_ctlchan(chanspec); - wl_update_prof(wl, iter->ndev, NULL, - &ctl_chan, WL_PROF_CHAN); - } - if (!wl->vsdb_mode) { - if (!pre_ctl_chan && ctl_chan) - pre_ctl_chan = ctl_chan; - else if (pre_ctl_chan && (pre_ctl_chan != ctl_chan)) { - wl->vsdb_mode = true; + chan = CHSPEC_CHANNEL(chanspec); + if (CHSPEC_IS40(chanspec)) { + if (CHSPEC_SB_UPPER(chanspec)) + chan += CH_10MHZ_APART; + else + chan -= CH_10MHZ_APART; } + wl_update_prof(wl, iter->ndev, NULL, + &chan, WL_PROF_CHAN); } + if (!prev_chan && chan) + prev_chan = chan; + else if (prev_chan && (prev_chan != chan)) + wl->vsdb_mode = true; } } - WL_ERR(("%s concurrency is enabled\n", wl->vsdb_mode ? "Multi Channel" : "Same Channel")); return; } - static s32 wl_notifier_change_state(struct wl_priv *wl, struct net_info *_net_info, enum wl_status state, bool set) { s32 pm = PM_FAST; s32 err = BCME_OK; - u32 mode; u32 chan = 0; struct net_info *iter, *next; struct net_device *primary_dev = wl_to_prmry_ndev(wl); @@ -9154,76 +8370,49 @@ static s32 wl_notifier_change_state(stru if (state != WL_STATUS_CONNECTED) return 0; - mode = wl_get_mode_by_netdev(wl, _net_info->ndev); + if (set) { wl_cfg80211_concurrent_roam(wl, 1); - if (mode == WL_MODE_AP) { - + if (wl_get_mode_by_netdev(wl, _net_info->ndev) == WL_MODE_AP) { + pm = PM_OFF; + WL_DBG(("%s:AP power save %s\n", _net_info->ndev->name, + pm ? "enabled" : "disabled")); + if ((err = wldev_ioctl(_net_info->ndev, WLC_SET_PM, + &pm, sizeof(pm), true)) != 0) { + if (err == -ENODEV) + WL_DBG(("%s:net_device is not ready\n", + _net_info->ndev->name)); + else + WL_ERR(("%s:error (%d)\n", _net_info->ndev->name, err)); + } if (wl_add_remove_eventmsg(primary_dev, WLC_E_P2P_PROBREQ_MSG, false)) WL_ERR((" failed to unset WLC_E_P2P_PROPREQ_MSG\n")); + return 0; } wl_cfg80211_determine_vsdb_mode(wl); - if (wl->vsdb_mode || _net_info->pm_block) { - if (wl->pm_enable_work_on) { - cancel_delayed_work_sync(&wl->pm_enable_work); - wl->pm_enable_work_on = false; - } - /* save PM_FAST in _net_info to restore this - * if _net_info->pm_block is false - */ - if (!_net_info->pm_block && (mode == WL_MODE_BSS)) { - _net_info->pm = PM_FAST; - _net_info->pm_restore = true; - } - pm = PM_OFF; - for_each_ndev(wl, iter, next) { - if (iter->pm_restore) - continue; - /* Save the current power mode */ - err = wldev_ioctl(iter->ndev, WLC_GET_PM, &iter->pm, - sizeof(iter->pm), false); - WL_DBG(("%s:power save %s\n", iter->ndev->name, - iter->pm ? "enabled" : "disabled")); - if (!err && iter->pm) { - iter->pm_restore = true; - } - - } - for_each_ndev(wl, iter, next) { - if ((err = wldev_ioctl(iter->ndev, WLC_SET_PM, &pm, - sizeof(pm), true)) != 0) { - if (err == -ENODEV) - WL_DBG(("%s:netdev not ready\n", iter->ndev->name)); - else - WL_ERR(("%s:error (%d)\n", iter->ndev->name, err)); - } else - iter->ndev->ieee80211_ptr->ps = false; + pm = PM_OFF; + for_each_ndev(wl, iter, next) { + if ((!wl->vsdb_mode) && (iter->ndev != _net_info->ndev)) { + /* Do not touch the other interfaces power save + * if we are not in vsdb mode + */ + continue; } - } else { - /* add PM Enable timer to go to power save mode - * if supplicant control pm mode, it will be cleared or - * updated by wl_cfg80211_set_power_mgmt() if not - for static IP & HW4 P2P, - * PM will be configured when timer expired - */ - - /* - * before calling pm_enable_timer, we need to set PM -1 for all ndev - */ - pm = PM_OFF; - - for_each_ndev(wl, iter, next) { - if ((err = wldev_ioctl(iter->ndev, WLC_SET_PM, &pm, - sizeof(pm), true)) != 0) { - if (err == -ENODEV) - WL_DBG(("%s:netdev not ready\n", iter->ndev->name)); - else - WL_ERR(("%s:error (%d)\n", iter->ndev->name, err)); - } + /* Save the current power mode */ + iter->pm_restore = true; + err = wldev_ioctl(iter->ndev, WLC_GET_PM, &iter->pm, + sizeof(iter->pm), false); + WL_DBG(("%s:power save %s\n", iter->ndev->name, + iter->pm ? "enabled" : "disabled")); + if ((err = wldev_ioctl(iter->ndev, WLC_SET_PM, &pm, + sizeof(pm), true)) != 0) { + if (err == -ENODEV) + WL_DBG(("%s:netdev not ready\n", iter->ndev->name)); + else + WL_ERR(("%s:error (%d)\n", iter->ndev->name, err)); + iter->ndev->ieee80211_ptr->ps = pm ? true: false; } - wl->pm_enable_work_on = true; - schedule_delayed_work(&wl->pm_enable_work, - msecs_to_jiffies(WL_PM_ENABLE_TIMEOUT)); } } else { /* clear */ @@ -9232,7 +8421,7 @@ static s32 wl_notifier_change_state(stru wl_update_prof(wl, _net_info->ndev, NULL, &chan, WL_PROF_CHAN); wl_cfg80211_determine_vsdb_mode(wl); for_each_ndev(wl, iter, next) { - if (iter->pm_restore && iter->pm) { + if (iter->pm_restore) { WL_DBG(("%s:restoring power save %s\n", iter->ndev->name, (iter->pm ? "enabled" : "disabled"))); err = wldev_ioctl(iter->ndev, @@ -9245,13 +8434,13 @@ static s32 wl_notifier_change_state(stru break; } iter->pm_restore = 0; - iter->ndev->ieee80211_ptr->ps = true; } } wl_cfg80211_concurrent_roam(wl, 0); } return err; } + static s32 wl_init_scan(struct wl_priv *wl) { struct wl_iscan_ctrl *iscan = wl_to_iscan(wl); @@ -9276,7 +8465,6 @@ static s32 wl_init_scan(struct wl_priv * } else if (wl->escan_on) { wl->evt_handler[WLC_E_ESCAN_RESULT] = wl_escan_handler; wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE; - wl_escan_init_sync_id(wl); } /* Init scan_timeout timer */ init_timer(&wl->scan_timeout); @@ -9342,7 +8530,7 @@ static void wl_deinit_priv(struct wl_pri unregister_netdevice_notifier(&wl_cfg80211_netdev_notifier); } -#if defined(WL_ENABLE_P2P_IF) +#if defined(WLP2P) && defined(WL_ENABLE_P2P_IF) static s32 wl_cfg80211_attach_p2p(void) { struct wl_priv *wl = wlcfg_drv_priv; @@ -9350,7 +8538,7 @@ static s32 wl_cfg80211_attach_p2p(void) WL_TRACE(("Enter \n")); if (wl_cfgp2p_register_ndev(wl) < 0) { - WL_ERR(("P2P attach failed. \n")); + WL_ERR(("%s: P2P attach failed. \n", __func__)); return -ENODEV; } @@ -9360,16 +8548,10 @@ static s32 wl_cfg80211_attach_p2p(void) static s32 wl_cfg80211_detach_p2p(void) { struct wl_priv *wl = wlcfg_drv_priv; - struct wireless_dev *wdev; + struct wireless_dev *wdev = wl->p2p_wdev; WL_DBG(("Enter \n")); - if (!wl) { - WL_ERR(("Invalid Ptr\n")); - return -EINVAL; - } else - wdev = wl->p2p_wdev; - - if (!wdev) { + if (!wdev || !wl) { WL_ERR(("Invalid Ptr\n")); return -EINVAL; } @@ -9383,7 +8565,7 @@ static s32 wl_cfg80211_detach_p2p(void) return 0; } -#endif /* WL_ENABLE_P2P_IF */ +#endif /* defined(WLP2P) && defined(WL_ENABLE_P2P_IF) */ s32 wl_cfg80211_attach_post(struct net_device *ndev) { @@ -9400,15 +8582,17 @@ s32 wl_cfg80211_attach_post(struct net_d return -EINVAL; } if (!wl_get_drv_status(wl, READY, ndev)) { - if (wl->wdev && wl_cfgp2p_supported(wl, ndev)) { - wl->wdev->wiphy->interface_modes |= + if (wl->wdev && + wl_cfgp2p_supported(wl, ndev)) { +#if !defined(WL_ENABLE_P2P_IF) + 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; -#if defined(WL_ENABLE_P2P_IF) +#if defined(WLP2P) && defined(WL_ENABLE_P2P_IF) if (wl->p2p_net) { /* Update MAC addr for p2p0 interface here. */ memcpy(wl->p2p_net->dev_addr, ndev->dev_addr, ETH_ALEN); @@ -9421,7 +8605,7 @@ s32 wl_cfg80211_attach_post(struct net_d " Couldn't update the MAC Address for p2p0 \n")); return -ENODEV; } -#endif /* WL_ENABLE_P2P_IF */ +#endif /* defined(WLP2P) && (WL_ENABLE_P2P_IF) */ wl->p2p_supported = true; } @@ -9451,7 +8635,7 @@ s32 wl_cfg80211_attach(struct net_device WL_ERR(("Could not allocate wireless device\n")); return -ENOMEM; } - err = wl_setup_wiphy(wdev, dev, data); + err = wl_setup_wiphy(wdev, dev); if (unlikely(err)) { kfree(wdev); return -ENOMEM; @@ -9481,36 +8665,31 @@ s32 wl_cfg80211_attach(struct net_device WL_ERR(("Failed to setup rfkill %d\n", err)); goto cfg80211_attach_out; } -#ifdef DEBUGFS_CFG80211 - err = wl_setup_debugfs(wl); - if (err) { - WL_ERR(("Failed to setup debugfs %d\n", err)); - goto cfg80211_attach_out; - } -#endif err = register_netdevice_notifier(&wl_cfg80211_netdev_notifier); if (err) { WL_ERR(("Failed to register notifierl %d\n", err)); goto cfg80211_attach_out; } #if defined(COEX_DHCP) - err = wl_cfg80211_btcoex_init(wl); - if (err) + if (wl_cfg80211_btcoex_init(wl)) goto cfg80211_attach_out; +#endif +#if defined(BSSCACHE) + wl_init_bss_cache_ctrl(&g_bss_cache_ctrl); #endif wlcfg_drv_priv = wl; -#if defined(WL_ENABLE_P2P_IF) +#if defined(WLP2P) && defined(WL_ENABLE_P2P_IF) err = wl_cfg80211_attach_p2p(); if (err) goto cfg80211_attach_out; -#endif /* WL_ENABLE_P2P_IF */ +#endif return err; cfg80211_attach_out: - wl_setup_rfkill(wl, FALSE); + err = wl_setup_rfkill(wl, FALSE); wl_free_wdev(wl); return err; } @@ -9526,29 +8705,28 @@ void wl_cfg80211_detach(void *para) #if defined(COEX_DHCP) wl_cfg80211_btcoex_deinit(wl); -#endif +#endif wl_setup_rfkill(wl, FALSE); -#ifdef DEBUGFS_CFG80211 - wl_free_debugfs(wl); -#endif if (wl->p2p_supported) { if (timer_pending(&wl->p2p->listen_timer)) del_timer_sync(&wl->p2p->listen_timer); wl_cfgp2p_deinit_priv(wl); } -#if defined(WL_CFG80211_P2P_DEV_IF) - wl_cfgp2p_del_p2p_disc_if(wl->p2p_wdev); -#elif defined(WL_ENABLE_P2P_IF) +#if defined(WLP2P) && defined(WL_ENABLE_P2P_IF) wl_cfg80211_detach_p2p(); -#endif /* WL_CFG80211_P2P_DEV_IF */ - - wl_cfg80211_ibss_vsie_free(wl); +#endif wl_deinit_priv(wl); wlcfg_drv_priv = NULL; wl_cfg80211_clear_parent_dev(); wl_free_wdev(wl); +#if defined(RSSIAVG) + wl_free_rssi_cache(&g_rssi_cache_ctrl); +#endif +#if defined(BSSCACHE) + wl_release_bss_cache_ctrl(&g_bss_cache_ctrl); +#endif /* PLEASE do NOT call any function after wl_free_wdev, the driver's private structure "wl", * which is the private part of wiphy, has been freed in wl_free_wdev !!!!!!!!!!! */ @@ -9562,7 +8740,6 @@ static void wl_wakeup_event(struct wl_pr } } -#if (defined(WL_CFG80211_P2P_DEV_IF) || defined(WL_ENABLE_P2P_IF)) static int wl_is_p2p_event(struct wl_event_q *e) { switch (e->etype) { @@ -9577,8 +8754,8 @@ static int wl_is_p2p_event(struct wl_eve case WLC_E_ACTION_FRAME_COMPLETE: if (e->emsg.ifidx != 0) { - WL_TRACE(("P2P event(%d) on virtual interface(ifidx:%d)\n", - e->etype, e->emsg.ifidx)); + WL_TRACE(("P2P Event on Virtual I/F (ifidx:%d) \n", + e->emsg.ifidx)); /* We are only bothered about the P2P events received * on primary interface. For rest of them return false * so that it is sent over the interface corresponding @@ -9586,30 +8763,33 @@ static int wl_is_p2p_event(struct wl_eve */ return FALSE; } else { - WL_TRACE(("P2P event(%d) on interface(ifidx:%d)\n", - e->etype, e->emsg.ifidx)); + WL_TRACE(("P2P Event on Primary I/F (ifidx:%d)." + " Sent it to p2p0 \n", e->emsg.ifidx)); return TRUE; } break; default: - WL_TRACE(("NON-P2P event(%d) on interface(ifidx:%d)\n", + WL_TRACE(("NON-P2P Event %d on ifidx (ifidx:%d) \n", e->etype, e->emsg.ifidx)); return FALSE; } } -#endif /* BCMDONGLEHOST && (WL_CFG80211_P2P_DEV_IF || WL_ENABLE_P2P_IF) */ static s32 wl_event_handler(void *data) { + struct net_device *netdev; struct wl_priv *wl = NULL; struct wl_event_q *e; tsk_ctl_t *tsk = (tsk_ctl_t *)data; - bcm_struct_cfgdev *cfgdev = NULL; wl = (struct wl_priv *)tsk->parent; - +#ifndef USE_KTHREAD_API + DAEMONIZE("dhd_cfg80211_event"); + complete(&tsk->completed); +#else WL_ERR(("tsk Enter, tsk = 0x%08x\n", (unsigned int)tsk)); +#endif while (down_interruptible (&tsk->sema) == 0) { SMP_RD_BARRIER_DEPENDS(); @@ -9621,31 +8801,15 @@ static s32 wl_event_handler(void *data) * there is no corresponding bsscfg for P2P interface. Map it to p2p0 * interface. */ -#if defined(WL_CFG80211_P2P_DEV_IF) - if ((wl_is_p2p_event(e) == TRUE) && (wl->p2p_wdev)) { - cfgdev = wl_to_p2p_wdev(wl); - } else { - cfgdev = ndev_to_wdev(dhd_idx2net((struct dhd_pub *)(wl->pub), - e->emsg.ifidx)); - } -#elif defined(WL_ENABLE_P2P_IF) if ((wl_is_p2p_event(e) == TRUE) && (wl->p2p_net)) { - cfgdev = wl->p2p_net; + netdev = wl->p2p_net; } else { - cfgdev = dhd_idx2net((struct dhd_pub *)(wl->pub), - e->emsg.ifidx); - } -#endif /* WL_CFG80211_P2P_DEV_IF */ - - if (!cfgdev) { -#if defined(WL_CFG80211_P2P_DEV_IF) - cfgdev = wl_to_prmry_wdev(wl); -#elif defined(WL_ENABLE_P2P_IF) - cfgdev = wl_to_prmry_ndev(wl); -#endif /* WL_CFG80211_P2P_DEV_IF */ + netdev = dhd_idx2net((struct dhd_pub *)(wl->pub), e->emsg.ifidx); } + if (!netdev) + netdev = wl_to_prmry_ndev(wl); if (e->etype < WLC_E_LAST && wl->evt_handler[e->etype]) { - wl->evt_handler[e->etype] (wl, cfgdev, &e->emsg, e->edata); + wl->evt_handler[e->etype] (wl, netdev, &e->emsg, e->edata); } else { WL_DBG(("Unknown Event (%d): ignoring\n", e->etype)); } @@ -9653,7 +8817,7 @@ static s32 wl_event_handler(void *data) } DHD_OS_WAKE_UNLOCK(wl->pub); } - WL_ERR(("was terminated\n")); + WL_ERR(("%s was terminated\n", __func__)); complete_and_exit(&tsk->completed, 0); return 0; } @@ -9915,7 +9079,6 @@ static int wl_construct_reginfo(struct w bool update; bool ht40_allowed; u8 *pbuf = NULL; - bool dfs_radar_disabled = FALSE; #define LOCAL_BUF_LEN 1024 pbuf = kzalloc(LOCAL_BUF_LEN, GFP_KERNEL); @@ -9924,7 +9087,7 @@ static int wl_construct_reginfo(struct w WL_ERR(("failed to allocate local buf\n")); return -ENOMEM; } - list = (wl_uint32_list_t *)(void *)pbuf; + list = (wl_uint32_list_t *)(void *) pbuf; list->count = htod32(WL_NUMCHANSPECS); @@ -9985,7 +9148,7 @@ static int wl_construct_reginfo(struct w else index = *n_cnt; if (index < array_size) { -#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) +#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS) band_chan_arr[index].center_freq = ieee80211_channel_to_frequency(channel); #else @@ -9996,8 +9159,8 @@ static int wl_construct_reginfo(struct w if (CHSPEC_IS40(c) && ht40_allowed) { /* assuming the order is HT20, HT40 Upper, - * HT40 lower from chanspecs - */ + HT40 lower from chanspecs + */ u32 ht40_flag = band_chan_arr[index].flags & IEEE80211_CHAN_NO_HT40; if (CHSPEC_SB_UPPER(c)) { if (ht40_flag == IEEE80211_CHAN_NO_HT40) @@ -10006,8 +9169,8 @@ static int wl_construct_reginfo(struct w band_chan_arr[index].flags |= IEEE80211_CHAN_NO_HT40PLUS; } else { /* It should be one of - * IEEE80211_CHAN_NO_HT40 or IEEE80211_CHAN_NO_HT40PLUS - */ + IEEE80211_CHAN_NO_HT40 or IEEE80211_CHAN_NO_HT40PLUS + */ band_chan_arr[index].flags &= ~IEEE80211_CHAN_NO_HT40; if (ht40_flag == IEEE80211_CHAN_NO_HT40) band_chan_arr[index].flags |= @@ -10015,26 +9178,21 @@ static int wl_construct_reginfo(struct w } } else { band_chan_arr[index].flags = IEEE80211_CHAN_NO_HT40; - if (!dfs_radar_disabled) { - if (band == IEEE80211_BAND_2GHZ) - channel |= WL_CHANSPEC_BAND_2G; - else - channel |= WL_CHANSPEC_BAND_5G; - channel |= WL_CHANSPEC_BW_20; - channel = wl_chspec_host_to_driver(channel); - err = wldev_iovar_getint(dev, "per_chan_info", &channel); - if (!err) { - if (channel & WL_CHAN_RADAR) - band_chan_arr[index].flags |= - (IEEE80211_CHAN_RADAR | - IEEE80211_CHAN_NO_IBSS); - if (channel & WL_CHAN_PASSIVE) - band_chan_arr[index].flags |= - IEEE80211_CHAN_PASSIVE_SCAN; - } else if (err == BCME_UNSUPPORTED) { - dfs_radar_disabled = TRUE; - WL_ERR(("does not support per_chan_info\n")); - } + if (band == IEEE80211_BAND_2GHZ) + channel |= WL_CHANSPEC_BAND_2G; + else + channel |= WL_CHANSPEC_BAND_5G; + channel |= WL_CHANSPEC_BW_20; + channel = wl_chspec_host_to_driver(channel); + err = wldev_iovar_getint(dev, "per_chan_info", &channel); + if (!err) { + if (channel & WL_CHAN_RADAR) + band_chan_arr[index].flags |= + (IEEE80211_CHAN_RADAR | + IEEE80211_CHAN_NO_IBSS); + if (channel & WL_CHAN_PASSIVE) + band_chan_arr[index].flags |= + IEEE80211_CHAN_PASSIVE_SCAN; } } if (!update) @@ -10079,8 +9237,6 @@ s32 wl_update_wiphybands(struct wl_priv } wiphy = wl_to_wiphy(wl); - wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz; - wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; err = wldev_ioctl(dev, WLC_GET_BAND, &cur_band, sizeof(s32), false); @@ -10093,10 +9249,10 @@ s32 wl_update_wiphybands(struct wl_priv if (unlikely(err)) { WL_ERR(("error reading nmode (%d)\n", err)); } else { - /* For nmodeonly check bw cap */ + /* For nmodeonly check bw cap */ err = wldev_iovar_getint(dev, "mimo_bw_cap", &bw_cap); if (unlikely(err)) { - WL_ERR(("error get mimo_bw_cap (%d)\n", err)); + WL_ERR(("error get mimo_bw_cap (%d)\n", err)); } } @@ -10107,6 +9263,7 @@ s32 wl_update_wiphybands(struct wl_priv goto end_bands; err = 0; } + nband = bandlist[0]; for (i = 1; i <= nband && i < ARRAYSIZE(bandlist); i++) { @@ -10174,8 +9331,22 @@ static s32 __wl_cfg80211_up(struct wl_pr err = dhd_monitor_init(wl->pub); err = wl_invoke_iscan(wl); +#ifdef WL_HOST_BAND_MGMT + /* By default the curr_band is initialized to BAND_AUTO */ + if (wl_cfg80211_set_band(ndev, WLC_BAND_AUTO) < 0) { + WL_ERR(("roam_band set failed\n")); + err = -1; + } +#endif /* WL_HOST_BAND_MGMT */ + +#if defined(DHCP_SCAN_SUPPRESS) + /* wlan scan_supp timer and work thread info */ + init_timer(&wl->scan_supp_timer); + wl->scan_supp_timer.data = (ulong)wl; + wl->scan_supp_timer.function = wl_cfg80211_scan_supp_timerfunc; + INIT_WORK(&wl->wlan_work, wl_cfg80211_work_handler); +#endif /* DHCP_SCAN_SUPPRESS */ - INIT_DELAYED_WORK(&wl->pm_enable_work, wl_cfg80211_work_handler); wl_set_drv_status(wl, READY, ndev); return err; } @@ -10186,38 +9357,21 @@ static s32 __wl_cfg80211_down(struct wl_ unsigned long flags; struct net_info *iter, *next; struct net_device *ndev = wl_to_prmry_ndev(wl); -#if defined(WL_CFG80211) && defined(WL_ENABLE_P2P_IF) struct net_device *p2p_net = wl->p2p_net; -#endif /* WL_CFG80211 && WL_ENABLE_P2P_IF */ - u32 bssidx = 0; -#ifdef PROP_TXSTATUS_VSDB - dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub); -#endif /* PROP_TXSTATUS_VSDB */ + u32 bssidx = wl_cfgp2p_find_idx(wl, ndev); WL_DBG(("In\n")); - if (wl->pm_enable_work_on) { - cancel_delayed_work_sync(&wl->pm_enable_work); - wl->pm_enable_work_on = false; - } - - if (wl->p2p_supported) { - wl_clr_p2p_status(wl, GO_NEG_PHASE); -#ifdef PROP_TXSTATUS_VSDB - if (wl->p2p->vif_created) { - if (dhd->wlfc_enabled && wl->wlfc_on) { - dhd->wlfc_enabled = false; - dhd_wlfc_deinit(dhd); - if (dhd->plat_deinit) - dhd->plat_deinit((void *)dhd); - wl->wlfc_on = false; - } - } -#endif /* PROP_TXSTATUS_VSDB */ - } +#if defined(DHCP_SCAN_SUPPRESS) + /* Force clear of scan_suppress */ + if (wl->scan_suppressed) + wl_cfg80211_scan_suppress(ndev, 0); + if (timer_pending(&wl->scan_supp_timer)) + del_timer_sync(&wl->scan_supp_timer); + cancel_work_sync(&wl->wlan_work); +#endif /* DHCP_SCAN_SUPPRESS */ - /* If primary BSS is operational (for e.g SoftAP), bring it down */ - if (!(wl_cfgp2p_find_idx(wl, ndev, &bssidx)) && - wl_cfgp2p_bss_isup(ndev, bssidx)) { + /* If BSS is operational (e.g SoftAp), bring it down */ + if (wl_cfgp2p_bss_isup(ndev, bssidx)) { if (wl_cfgp2p_bss(wl, ndev, bssidx, 0) < 0) WL_ERR(("BSS down failed \n")); } @@ -10225,10 +9379,10 @@ static s32 __wl_cfg80211_down(struct wl_ /* Check if cfg80211 interface is already down */ if (!wl_get_drv_status(wl, READY, ndev)) return err; /* it is even not ready */ + for_each_ndev(wl, iter, next) wl_set_drv_status(wl, SCAN_ABORTING, iter->ndev); - wl_term_iscan(wl); spin_lock_irqsave(&wl->cfgdrv_lock, flags); if (wl->scan_request) { @@ -10249,10 +9403,8 @@ static s32 __wl_cfg80211_down(struct wl_ } wl_to_prmry_ndev(wl)->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION; -#if defined(WL_CFG80211) && defined(WL_ENABLE_P2P_IF) if (p2p_net) dev_close(p2p_net); -#endif /* WL_CFG80211 && WL_ENABLE_P2P_IF */ DNGL_FUNC(dhd_cfg80211_down, (wl)); wl_flush_eq(wl); wl_link_down(wl); @@ -10310,6 +9462,13 @@ int wl_cfg80211_hang(struct net_device * WL_ERR(("In : chip crash eventing\n")); cfg80211_disconnected(dev, reason, NULL, 0, GFP_KERNEL); +#if defined(RSSIAVG) + wl_free_rssi_cache(&g_rssi_cache_ctrl); +#endif +#if defined(BSSCACHE) + wl_free_bss_cache(&g_bss_cache_ctrl); + wl_run_bss_cache_timer(&g_bss_cache_ctrl, 0); +#endif if (wl != NULL) { wl_link_down(wl); } @@ -10325,6 +9484,13 @@ s32 wl_cfg80211_down(void *para) WL_DBG(("In\n")); wl = wlcfg_drv_priv; mutex_lock(&wl->usr_sync); +#if defined(RSSIAVG) + wl_free_rssi_cache(&g_rssi_cache_ctrl); +#endif +#if defined(BSSCACHE) + wl_free_bss_cache(&g_bss_cache_ctrl); + wl_run_bss_cache_timer(&g_bss_cache_ctrl, 0); +#endif err = __wl_cfg80211_down(wl); mutex_unlock(&wl->usr_sync); @@ -10403,14 +9569,13 @@ wl_update_prof(struct wl_priv *wl, struc break; case WL_PROF_CHAN: profile->channel = *(u32*)data; - break; default: err = -EOPNOTSUPP; break; } spin_unlock_irqrestore(&wl->cfgdrv_lock, flags); - if (err == -EOPNOTSUPP) + if (err == EOPNOTSUPP) WL_ERR(("unsupported item (%d)\n", item)); return err; @@ -10461,29 +9626,6 @@ static __used s32 wl_add_ie(struct wl_pr return err; } -static void wl_update_hidden_ap_ie(struct wl_bss_info *bi, u8 *ie_stream, u32 *ie_size) -{ - u8 *ssidie; - ssidie = (u8 *)cfg80211_find_ie(WLAN_EID_SSID, ie_stream, *ie_size); - if (!ssidie) - return; - if (ssidie[1] != bi->SSID_len) { - if (ssidie[1]) { - WL_ERR(("%s: Wrong SSID len: %d != %d\n", - __FUNCTION__, ssidie[1], bi->SSID_len)); - return; - } - memmove(ssidie + bi->SSID_len + 2, ssidie + 2, *ie_size - (ssidie + 2 - ie_stream)); - memcpy(ssidie + 2, bi->SSID, bi->SSID_len); - *ie_size = *ie_size + bi->SSID_len; - ssidie[1] = bi->SSID_len; - return; - } - if (*(ssidie + 2) == '\0') - memcpy(ssidie + 2, bi->SSID, bi->SSID_len); - return; -} - static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size) { struct wl_ie *ie = wl_to_ie(wl); @@ -10556,9 +9698,9 @@ static void wl_init_eq_lock(struct wl_pr static void wl_delay(u32 ms) { if (in_atomic() || (ms < jiffies_to_msecs(1))) { - OSL_DELAY(ms*1000); + mdelay(ms); } else { - OSL_SLEEP(ms); + msleep(ms); } } @@ -10609,7 +9751,7 @@ s32 wl_cfg80211_channel_to_freq(u32 chan { int freq = 0; -#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) +#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS) freq = ieee80211_channel_to_frequency(channel); #else { @@ -10624,90 +9766,6 @@ s32 wl_cfg80211_channel_to_freq(u32 chan return freq; } - -#ifdef WLTDLS -static s32 -wl_tdls_event_handler(struct wl_priv *wl, bcm_struct_cfgdev *cfgdev, - const wl_event_msg_t *e, void *data) { - - struct net_device *ndev = NULL; - u32 reason = ntoh32(e->reason); - s8 *msg = NULL; - - ndev = cfgdev_to_wlc_ndev(cfgdev, wl); - - switch (reason) { - case WLC_E_TDLS_PEER_DISCOVERED : - msg = " TDLS PEER DISCOVERD "; - break; - case WLC_E_TDLS_PEER_CONNECTED : - msg = " TDLS PEER CONNECTED "; - break; - case WLC_E_TDLS_PEER_DISCONNECTED : - msg = "TDLS PEER DISCONNECTED "; - break; - } - if (msg) { - WL_ERR(("%s: " MACDBG " on %s ndev\n", msg, MAC2STRDBG((u8*)(&e->addr)), - (wl_to_prmry_ndev(wl) == ndev) ? "primary" : "secondary")); - } - return 0; - -} -#endif /* WLTDLS */ - -#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 2, 0) -static s32 -wl_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, - u8 *peer, enum nl80211_tdls_operation oper) -{ - s32 ret = 0; -#ifdef WLTDLS - struct wl_priv *wl = wlcfg_drv_priv; - tdls_iovar_t info; - - memset(&info, 0, sizeof(tdls_iovar_t)); - if (peer) - memcpy(&info.ea, peer, ETHER_ADDR_LEN); - switch (oper) { - case NL80211_TDLS_DISCOVERY_REQ: - /* turn on TDLS */ - ret = dhd_tdls_enable(dev, true, false, NULL); - if (ret < 0) - return ret; - info.mode = TDLS_MANUAL_EP_DISCOVERY; - break; - case NL80211_TDLS_SETUP: - /* auto mode on */ - ret = dhd_tdls_enable(dev, true, true, (struct ether_addr *)peer); - if (ret < 0) - return ret; - break; - case NL80211_TDLS_TEARDOWN: - info.mode = TDLS_MANUAL_EP_DELETE; - /* auto mode off */ - ret = dhd_tdls_enable(dev, true, false, (struct ether_addr *)peer); - if (ret < 0) - return ret; - break; - default: - WL_ERR(("Unsupported operation : %d\n", oper)); - goto out; - } - - if (info.mode) { - ret = wldev_iovar_setbuf(dev, "tdls_endpoint", &info, sizeof(info), - wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync); - if (ret) { - WL_ERR(("tdls_endpoint error %d\n", ret)); - } - } -out: -#endif /* WLTDLS */ - return ret; -} -#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(3, 2, 0) */ - s32 wl_cfg80211_set_wps_p2p_ie(struct net_device *net, char *buf, int len, enum wl_management_type type) { @@ -10719,16 +9777,14 @@ s32 wl_cfg80211_set_wps_p2p_ie(struct ne s32 pktflag = 0; wl = wlcfg_drv_priv; - if (wl_get_drv_status(wl, AP_CREATING, net)) { - /* Vendor IEs should be set to FW - * after SoftAP interface is brought up - */ - goto exit; - } else if (wl_get_drv_status(wl, AP_CREATED, net)) { + if (wl_get_drv_status(wl, AP_CREATING, net) || + wl_get_drv_status(wl, AP_CREATED, net)) { ndev = net; bssidx = 0; } else if (wl->p2p) { - net = ndev_to_wlc_ndev(net, wl); + if (net == wl->p2p_net) { + net = wl_to_prmry_ndev(wl); + } if (!wl->p2p->on) { get_primary_mac(wl, &primary_mac); wl_cfgp2p_generate_bss_mac(&primary_mac, &wl->p2p->dev_addr, @@ -10773,7 +9829,6 @@ exit: return ret; } - static const struct rfkill_ops wl_rfkill_ops = { .set_block = wl_rfkill_set }; @@ -10828,128 +9883,6 @@ err_out: return err; } -#ifdef DEBUGFS_CFG80211 -/** -* Format : echo "SCAN:1 DBG:1" > /sys/kernel/debug/dhd/debug_level -* to turn on SCAN and DBG log. -* To turn off SCAN partially, echo "SCAN:0" > /sys/kernel/debug/dhd/debug_level -* To see current setting of debug level, -* cat /sys/kernel/debug/dhd/debug_level -*/ -static ssize_t -wl_debuglevel_write(struct file *file, const char __user *userbuf, - size_t count, loff_t *ppos) -{ - char tbuf[S_SUBLOGLEVEL * ARRAYSIZE(sublogname_map)], sublog[S_SUBLOGLEVEL]; - char *params, *token, *colon; - uint i, tokens, log_on = 0; - memset(tbuf, 0, sizeof(tbuf)); - memset(sublog, 0, sizeof(sublog)); - if (copy_from_user(&tbuf, userbuf, min_t(size_t, sizeof(tbuf), count))) - return -EFAULT; - - params = &tbuf[0]; - colon = strchr(params, '\n'); - if (colon != NULL) - *colon = '\0'; - while ((token = strsep(¶ms, " ")) != NULL) { - memset(sublog, 0, sizeof(sublog)); - if (token == NULL || !*token) - break; - if (*token == '\0') - continue; - colon = strchr(token, ':'); - if (colon != NULL) { - *colon = ' '; - } - tokens = sscanf(token, "%s %u", sublog, &log_on); - if (colon != NULL) - *colon = ':'; - - if (tokens == 2) { - for (i = 0; i < ARRAYSIZE(sublogname_map); i++) { - if (!strncmp(sublog, sublogname_map[i].sublogname, - strlen(sublogname_map[i].sublogname))) { - if (log_on) - wl_dbg_level |= - (sublogname_map[i].log_level); - else - wl_dbg_level &= - ~(sublogname_map[i].log_level); - } - } - } else - WL_ERR(("%s: can't parse '%s' as a " - "SUBMODULE:LEVEL (%d tokens)\n", - tbuf, token, tokens)); - - - } - return count; -} - -static ssize_t -wl_debuglevel_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - char *param; - char tbuf[S_SUBLOGLEVEL * ARRAYSIZE(sublogname_map)]; - uint i; - memset(tbuf, 0, sizeof(tbuf)); - param = &tbuf[0]; - for (i = 0; i < ARRAYSIZE(sublogname_map); i++) { - param += snprintf(param, sizeof(tbuf) - 1, "%s:%d ", - sublogname_map[i].sublogname, - (wl_dbg_level & sublogname_map[i].log_level) ? 1 : 0); - } - *param = '\n'; - return simple_read_from_buffer(user_buf, count, ppos, tbuf, strlen(&tbuf[0])); - -} -static const struct file_operations fops_debuglevel = { - .open = NULL, - .write = wl_debuglevel_write, - .read = wl_debuglevel_read, - .owner = THIS_MODULE, - .llseek = NULL, -}; - -static s32 wl_setup_debugfs(struct wl_priv *wl) -{ - s32 err = 0; - struct dentry *_dentry; - if (!wl) - return -EINVAL; - wl->debugfs = debugfs_create_dir(KBUILD_MODNAME, NULL); - if (!wl->debugfs || IS_ERR(wl->debugfs)) { - if (wl->debugfs == ERR_PTR(-ENODEV)) - WL_ERR(("Debugfs is not enabled on this kernel\n")); - else - WL_ERR(("Can not create debugfs directory\n")); - wl->debugfs = NULL; - goto exit; - - } - _dentry = debugfs_create_file("debug_level", S_IRUSR | S_IWUSR, - wl->debugfs, wl, &fops_debuglevel); - if (!_dentry || IS_ERR(_dentry)) { - WL_ERR(("failed to create debug_level debug file\n")); - wl_free_debugfs(wl); - } -exit: - return err; -} -static s32 wl_free_debugfs(struct wl_priv *wl) -{ - if (!wl) - return -EINVAL; - if (wl->debugfs) - debugfs_remove_recursive(wl->debugfs); - wl->debugfs = NULL; - return 0; -} -#endif /* DEBUGFS_CFG80211 */ - struct device *wl_cfg80211_get_parent_dev(void) { return cfg80211_parent_dev; @@ -10965,27 +9898,13 @@ static void wl_cfg80211_clear_parent_dev cfg80211_parent_dev = NULL; } -void get_primary_mac(struct wl_priv *wl, struct ether_addr *mac) +static void get_primary_mac(struct wl_priv *wl, struct ether_addr *mac) { wldev_iovar_getbuf_bsscfg(wl_to_prmry_ndev(wl), "cur_etheraddr", NULL, 0, wl->ioctl_buf, WLC_IOCTL_SMLEN, 0, &wl->ioctl_buf_sync); memcpy(mac->octet, wl->ioctl_buf, ETHER_ADDR_LEN); } -static bool check_dev_role_integrity(struct wl_priv *wl, u32 dev_role) -{ - dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub); - if (((dev_role == NL80211_IFTYPE_AP) && - !(dhd->op_mode & DHD_FLAG_HOSTAP_MODE)) || - ((dev_role == NL80211_IFTYPE_P2P_GO) && - !(dhd->op_mode & DHD_FLAG_P2P_GO_MODE))) - { - WL_ERR(("device role select failed\n")); - return false; - } - return true; -} - int wl_cfg80211_do_driver_init(struct net_device *net) { struct wl_priv *wl = *(struct wl_priv **)netdev_priv(net); @@ -10999,17 +9918,17 @@ int wl_cfg80211_do_driver_init(struct ne return 0; } -void wl_cfg80211_enable_trace(bool set, u32 level) +void wl_cfg80211_enable_trace(u32 level) { - if (set) - wl_dbg_level = level & WL_DBG_LEVEL; - else - wl_dbg_level |= (WL_DBG_LEVEL & level); + wl_dbg_level = level; + printk("%s: wl_dbg_level = 0x%x\n", __FUNCTION__, wl_dbg_level); } +#if defined(WL_SUPPORT_BACKPORTED_KPATCHES) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, \ + 2, 0)) static s32 wl_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, - bcm_struct_cfgdev *cfgdev, u64 cookie) + struct net_device *dev, u64 cookie) { /* CFG80211 checks for tx_cancel_wait callback when ATTR_DURATION * is passed with CMD_FRAME. This callback is supposed to cancel @@ -11019,6 +9938,7 @@ wl_cfg80211_mgmt_tx_cancel_wait(struct w return 0; } +#endif /* WL_SUPPORT_BACKPORTED_KPATCHES || KERNEL >= 3.2.0 */ #ifdef WL11U bcm_tlv_t * @@ -11066,8 +9986,7 @@ wl_cfg80211_add_iw_ie(struct wl_priv *wl if (wl->iw_ie_len == data_len && !memcmp(wl->iw_ie, data, data_len)) { WL_ERR(("Previous IW IE is equals to current IE\n")); - err = BCME_OK; - goto exit; + return err; } strncpy(ie_setbuf->cmd, "add", VNDR_IE_CMD_LEN - 1); @@ -11091,7 +10010,7 @@ wl_cfg80211_add_iw_ie(struct wl_priv *wl wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync); if (err != BCME_OK) - goto exit; + return err; } ie_setbuf->ie_buffer.ie_list[0].ie_data.len = data_len; @@ -11108,67 +10027,101 @@ wl_cfg80211_add_iw_ie(struct wl_priv *wl err = wldev_iovar_setint_bsscfg(ndev, "grat_arp", 1, bssidx); } -exit: - if (ie_setbuf) - kfree(ie_setbuf); + kfree(ie_setbuf); return err; } #endif /* WL11U */ -static void wl_cfg80211_work_handler(struct work_struct * work) +#ifdef WL_HOST_BAND_MGMT +s32 +wl_cfg80211_set_band(struct net_device *ndev, int band) { - struct wl_priv *wl = NULL; - struct net_info *iter, *next; - s32 err = BCME_OK; - s32 pm = PM_FAST; + struct wl_priv *wl = wlcfg_drv_priv; + int ret = 0; + char ioctl_buf[50]; - wl = container_of(work, struct wl_priv, pm_enable_work.work); - WL_DBG(("Enter \n")); - if (wl->pm_enable_work_on) { - wl->pm_enable_work_on = false; - for_each_ndev(wl, iter, next) { - if (!wl_get_drv_status(wl, CONNECTED, iter->ndev) || - (wl_get_mode_by_netdev(wl, iter->ndev) != WL_MODE_BSS)) - continue; - if (iter->ndev) { - if ((err = wldev_ioctl(iter->ndev, WLC_SET_PM, - &pm, sizeof(pm), true)) != 0) { - if (err == -ENODEV) - WL_DBG(("%s:netdev not ready\n", iter->ndev->name)); - else - WL_ERR(("%s:error (%d)\n", iter->ndev->name, err)); - } else - iter->ndev->ieee80211_ptr->ps = true; - } - } + if ((band < WLC_BAND_AUTO) || (band > WLC_BAND_2G)) { + WL_ERR(("Invalid band\n")); + return -EINVAL; } + + if ((ret = wldev_iovar_setbuf(ndev, "roam_band", &band, + sizeof(int), ioctl_buf, sizeof(ioctl_buf), NULL)) < 0) { + WL_ERR(("seting roam_band failed code=%d\n", ret)); + return ret; + } + + WL_DBG(("Setting band to %d\n", band)); + wl->curr_band = band; + + return 0; } +#endif /* WL_HOST_BAND_MGMT */ -u8 -wl_get_action_category(void *frame, u32 frame_len) +#if defined(DHCP_SCAN_SUPPRESS) +static void wl_cfg80211_scan_supp_timerfunc(ulong data) { - u8 category; - u8 *ptr = (u8 *)frame; - if (frame == NULL) - return DOT11_ACTION_CAT_ERR_MASK; - if (frame_len < DOT11_ACTION_HDR_LEN) - return DOT11_ACTION_CAT_ERR_MASK; - category = ptr[DOT11_ACTION_CAT_OFF]; - WL_INFO(("Action Category: %d\n", category)); - return category; + struct wl_priv *wl = (struct wl_priv *)data; + + WL_DBG(("Enter \n")); + schedule_work(&wl->wlan_work); } -int -wl_get_public_action(void *frame, u32 frame_len, u8 *ret_action) +static void wl_cfg80211_work_handler(struct work_struct *work) { - u8 *ptr = (u8 *)frame; - if (frame == NULL || ret_action == NULL) - return BCME_ERROR; - if (frame_len < DOT11_ACTION_HDR_LEN) - return BCME_ERROR; - if (DOT11_ACTION_CAT_PUBLIC != wl_get_action_category(frame, frame_len)) - return BCME_ERROR; - *ret_action = ptr[DOT11_ACTION_ACT_OFF]; - WL_INFO(("Public Action : %d\n", *ret_action)); - return BCME_OK; + struct wl_priv *wl = wlcfg_drv_priv; + + wl = container_of(work, struct wl_priv, wlan_work); + + if (!wl) { + WL_ERR(("wl_priv ptr NULL\n")); + return; + } + + if (wl->scan_suppressed) { + /* There is pending scan_suppress. Clean it */ + WL_ERR(("Clean up from timer after %d msec\n", WL_SCAN_SUPPRESS_TIMEOUT)); + wl_cfg80211_scan_suppress(wl_to_prmry_ndev(wl), 0); + } +} + +int wl_cfg80211_scan_suppress(struct net_device *dev, int suppress) +{ + struct wl_priv *wl = wlcfg_drv_priv; + int ret = 0; + + if (!dev || !wl || ((suppress != 0) && (suppress != 1))) + return -EINVAL; + + if (suppress == wl->scan_suppressed) { + WL_DBG(("No change in scan_suppress state. Ignoring cmd..\n")); + return 0; + } + + if (timer_pending(&wl->scan_supp_timer)) + del_timer_sync(&wl->scan_supp_timer); + + if ((ret = wldev_ioctl(dev, WLC_SET_SCANSUPPRESS, + &suppress, sizeof(int), true)) < 0) { + WL_ERR(("Scan suppress setting failed ret:%d \n", ret)); + } else { + WL_DBG(("Scan suppress %s \n", suppress ? "Enabled" : "Disabled")); + wl->scan_suppressed = suppress; + } + + /* If scan_suppress is set, Start a timer to monitor it (just incase) */ + if (wl->scan_suppressed) { + if (ret) { + WL_ERR(("Retry scan_suppress reset at a later time \n")); + mod_timer(&wl->scan_supp_timer, + jiffies + msecs_to_jiffies(WL_SCAN_SUPPRESS_RETRY)); + } else { + WL_DBG(("Start wlan_timer to clear of scan_suppress \n")); + mod_timer(&wl->scan_supp_timer, + jiffies + msecs_to_jiffies(WL_SCAN_SUPPRESS_TIMEOUT)); + } + } + + return ret; } +#endif /* DHCP_SCAN_SUPPRESS */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/wl_cfg80211.h linux-sunxi-new/drivers/net/wireless/bcmdhd/wl_cfg80211.h --- linux-sunxi/drivers/net/wireless/bcmdhd/wl_cfg80211.h 2014-01-27 01:30:30.100433249 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/wl_cfg80211.h 2014-02-15 00:43:44.791014047 +0100 @@ -1,7 +1,7 @@ /* * Linux cfg80211 driver * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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 418267 2013-08-14 12:49:52Z $ + * $Id: wl_cfg80211.h 374275 2012-12-12 11:44:18Z $ */ #ifndef _wl_cfg80211_h_ @@ -44,12 +44,12 @@ struct wl_security; struct wl_ibss; -#define htod32(i) (i) -#define htod16(i) (i) -#define dtoh32(i) (i) -#define dtoh16(i) (i) -#define htodchanspec(i) (i) -#define dtohchanspec(i) (i) +#define htod32(i) i +#define htod16(i) i +#define dtoh32(i) i +#define dtoh16(i) i +#define htodchanspec(i) i +#define dtohchanspec(i) i #define WL_DBG_NONE 0 #define WL_DBG_P2P_ACTION (1 << 5) @@ -138,7 +138,7 @@ do { \ #define WL_SCAN_IE_LEN_MAX 2048 #define WL_BSS_INFO_MAX 2048 #define WL_ASSOC_INFO_MAX 512 -#define WL_IOCTL_LEN_MAX 2048 +#define WL_IOCTL_LEN_MAX 1024 #define WL_EXTRA_BUF_MAX 2048 #define WL_ISCAN_BUF_MAX 2048 #define WL_ISCAN_TIMER_INTERVAL_MS 3000 @@ -146,7 +146,7 @@ do { \ #define WL_AP_MAX 256 #define WL_FILE_NAME_MAX 256 #define WL_DWELL_TIME 200 -#define WL_MED_DWELL_TIME 400 +#define WL_MED_DWELL_TIME 400 #define WL_MIN_DWELL_TIME 100 #define WL_LONG_DWELL_TIME 1000 #define IFACE_MAX_CNT 2 @@ -156,24 +156,19 @@ do { \ #define WL_SCAN_JOIN_PASSIVE_DWELL_TIME_MS 400 #define WL_AF_TX_MAX_RETRY 5 -#define WL_AF_SEARCH_TIME_MAX 450 -#define WL_AF_TX_EXTRA_TIME_MAX 200 - #define WL_SCAN_TIMER_INTERVAL_MS 8000 /* Scan timeout */ #define WL_CHANNEL_SYNC_RETRY 5 #define WL_INVALID -1 /* Bring down SCB Timeout to 20secs from 60secs default */ #ifndef WL_SCB_TIMEOUT -#define WL_SCB_TIMEOUT 20 +#define WL_SCB_TIMEOUT 20 #endif /* SCAN_SUPPRESS timer values in ms */ #define WL_SCAN_SUPPRESS_TIMEOUT 31000 /* default Framwork DHCP timeout is 30 sec */ #define WL_SCAN_SUPPRESS_RETRY 3000 -#define WL_PM_ENABLE_TIMEOUT 3000 - /* driver status */ enum wl_status { WL_STATUS_READY = 0, @@ -274,8 +269,8 @@ struct wl_conf { struct ieee80211_channel channel; }; -typedef s32(*EVENT_HANDLER) (struct wl_priv *wl, bcm_struct_cfgdev *cfgdev, - const wl_event_msg_t *e, void *data); +typedef s32(*EVENT_HANDLER) (struct wl_priv *wl, + struct net_device *ndev, const wl_event_msg_t *e, void *data); /* bss inform structure for cfg80211 interface */ struct wl_cfg80211_bss_info { @@ -405,7 +400,7 @@ struct escan_info { #if defined(STATIC_WL_PRIV_STRUCT) #ifndef CONFIG_DHD_USE_STATIC_BUF #error STATIC_WL_PRIV_STRUCT should be used with CONFIG_DHD_USE_STATIC_BUF -#endif /* CONFIG_DHD_USE_STATIC_BUF */ +#endif u8 *escan_buf; #else u8 escan_buf[ESCAN_BUF_SIZE]; @@ -472,14 +467,11 @@ struct parsed_ies { }; - #ifdef WL11U /* Max length of Interworking element */ #define IW_IES_MAX_BUF_LEN 9 #endif -#ifdef WLFBT -#define FBT_KEYLEN 32 -#endif + #define MAX_EVENT_BUF_NUM 16 typedef struct wl_eventmsg_buf { u16 num; @@ -494,7 +486,6 @@ struct wl_priv { struct wireless_dev *wdev; /* representing wl cfg80211 device */ struct wireless_dev *p2p_wdev; /* representing wl cfg80211 device for P2P */ - struct net_device *p2p_net; /* reference to p2p0 interface */ struct wl_conf *conf; @@ -527,9 +518,7 @@ struct wl_priv { #else struct wl_connect_info conn_info; #endif -#ifdef DEBUGFS_CFG80211 - struct dentry *debugfs; -#endif /* DEBUGFS_CFG80211 */ + struct wl_pmk_list *pmk_list; /* wpa2 pmk list */ tsk_ctl_t event_tsk; /* task of main event handler thread */ void *pub; @@ -556,7 +545,7 @@ struct wl_priv { bool wlfc_on; bool vsdb_mode; bool roamoff_on_concurrent; - 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 */ @@ -589,14 +578,13 @@ struct wl_priv { #ifdef WL_SCHED_SCAN struct cfg80211_sched_scan_request *sched_scan_req; /* scheduled scan req */ #endif /* WL_SCHED_SCAN */ +#ifdef WL_HOST_BAND_MGMT + u8 curr_band; +#endif /* WL_HOST_BAND_MGMT */ bool scan_suppressed; struct timer_list scan_supp_timer; struct work_struct wlan_work; struct mutex event_sync; /* maily for up/down synchronization */ - bool pm_enable_work_on; - struct delayed_work pm_enable_work; - vndr_ie_setbuf_t *ibss_vsie; /* keep the VSIE for IBSS */ - int ibss_vsie_len; }; @@ -691,8 +679,8 @@ wl_set_status_all(struct wl_priv *wl, s3 return; /* change all status is not allowed */ default: return; /* unknown operation */ + } } - } } static inline void wl_set_status_by_netdev(struct wl_priv *wl, s32 status, @@ -787,47 +775,7 @@ wl_get_netinfo_by_netdev(struct wl_priv } #define wl_to_wiphy(w) (w->wdev->wiphy) #define wl_to_prmry_ndev(w) (w->wdev->netdev) -#define wl_to_prmry_wdev(w) (w->wdev) -#define wl_to_p2p_wdev(w) (w->p2p_wdev) #define ndev_to_wl(n) (wdev_to_wl(n->ieee80211_ptr)) -#define ndev_to_wdev(ndev) (ndev->ieee80211_ptr) -#define wdev_to_ndev(wdev) (wdev->netdev) - -#if defined(WL_ENABLE_P2P_IF) -#define ndev_to_wlc_ndev(ndev, wl) ((ndev == wl->p2p_net) ? \ - wl_to_prmry_ndev(wl) : ndev) -#else -#define ndev_to_wlc_ndev(ndev, wl) (ndev) -#endif /* WL_ENABLE_P2P_IF */ - -#if defined(WL_CFG80211_P2P_DEV_IF) -#define wdev_to_wlc_ndev(wdev, wl) \ - ((wdev->iftype == NL80211_IFTYPE_P2P_DEVICE) ? \ - wl_to_prmry_ndev(wl) : wdev_to_ndev(wdev)) -#define cfgdev_to_wlc_ndev(cfgdev, wl) wdev_to_wlc_ndev(cfgdev, wl) -#elif defined(WL_ENABLE_P2P_IF) -#define cfgdev_to_wlc_ndev(cfgdev, wl) ndev_to_wlc_ndev(cfgdev, wl) -#else -#define cfgdev_to_wlc_ndev(cfgdev, wl) (cfgdev) -#endif /* WL_CFG80211_P2P_DEV_IF */ - -#if defined(WL_CFG80211_P2P_DEV_IF) -#define ndev_to_cfgdev(ndev) ndev_to_wdev(ndev) -#else -#define ndev_to_cfgdev(ndev) (ndev) -#endif /* WL_CFG80211_P2P_DEV_IF */ - -#if defined(WL_CFG80211_P2P_DEV_IF) -#define scan_req_match(wl) (((wl) && (wl->scan_request) && \ - (wl->scan_request->wdev == wl->p2p_wdev)) ? true : false) -#elif defined(WL_ENABLE_P2P_IF) -#define scan_req_match(wl) (((wl) && (wl->scan_request) && \ - (wl->scan_request->dev == wl->p2p_net)) ? true : false) -#else -#define scan_req_match(wl) (((wl) && p2p_is_on(wl) && p2p_scan(wl)) ? \ - true : false) -#endif /* WL_CFG80211_P2P_DEV_IF */ - #define wl_to_sr(w) (w->scan_req_int) #if defined(STATIC_WL_PRIV_STRUCT) #define wl_to_ie(w) (w->ie) @@ -847,7 +795,7 @@ wl_get_netinfo_by_netdev(struct wl_priv (wl_set_status_by_netdev(wl, WL_STATUS_ ## stat, ndev, 1)) #define wl_clr_drv_status(wl, stat, ndev) \ (wl_set_status_by_netdev(wl, WL_STATUS_ ## stat, ndev, 2)) -#define wl_clr_drv_status_all(wl, stat) \ +#define wl_clr_drv_status_all(wl, stat) \ (wl_set_status_all(wl, WL_STATUS_ ## stat, 2)) #define wl_chg_drv_status(wl, stat, ndev) \ (wl_set_status_by_netdev(wl, WL_STATUS_ ## stat, ndev, 4)) @@ -895,30 +843,18 @@ extern s32 wl_cfg80211_set_p2p_ps(struct 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(bool set, u32 level); +void wl_cfg80211_enable_trace(u32 level); extern s32 wl_update_wiphybands(struct wl_priv *wl, bool notify); extern s32 wl_cfg80211_if_is_group_owner(void); extern chanspec_t wl_ch_host_to_driver(u16 channel); extern s32 wl_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add); -extern void wl_stop_wait_next_action_frame(struct wl_priv *wl); +extern void wl_stop_wait_next_action_frame(struct wl_priv *wl, struct net_device *ndev); +extern s32 wl_cfg80211_set_band(struct net_device *ndev, int band); extern int wl_cfg80211_update_power_mode(struct net_device *dev); +#if defined(DHCP_SCAN_SUPPRESS) +extern int wl_cfg80211_scan_suppress(struct net_device *dev, int suppress); +#endif /* OEM_ANDROID */ extern void wl_cfg80211_add_to_eventbuffer(wl_eventmsg_buf_t *ev, u16 event, bool set); extern s32 wl_cfg80211_apply_eventbuffer(struct net_device *ndev, struct wl_priv *wl, wl_eventmsg_buf_t *ev); -extern void get_primary_mac(struct wl_priv *wl, struct ether_addr *mac); -#define SCAN_BUF_CNT 2 -#define SCAN_BUF_NEXT 1 -#define wl_escan_set_sync_id(a, b) ((a) = htod16(0x1234)) -#define wl_escan_get_buf(a, b) ((wl_scan_results_t *) (a)->escan_info.escan_buf) -#define wl_escan_check_sync_id(a, b, c) 0 -#define wl_escan_print_sync_id(a, b, c) -#define wl_escan_increment_sync_id(a, b) -#define wl_escan_init_sync_id(a) -extern void wl_cfg80211_ibss_vsie_set_buffer(vndr_ie_setbuf_t *ibss_vsie, int ibss_vsie_len); -extern s32 wl_cfg80211_ibss_vsie_delete(struct net_device *dev); - -/* Action frame specific functions */ -extern u8 wl_get_action_category(void *frame, u32 frame_len); -extern int wl_get_public_action(void *frame, u32 frame_len, u8 *ret_action); - #endif /* _wl_cfg80211_h_ */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/wl_cfgp2p.c linux-sunxi-new/drivers/net/wireless/bcmdhd/wl_cfgp2p.c --- linux-sunxi/drivers/net/wireless/bcmdhd/wl_cfgp2p.c 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/wl_cfgp2p.c 2014-02-15 00:43:44.795014136 +0100 @@ -1,7 +1,7 @@ /* * Linux cfgp2p driver * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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 419821 2013-08-22 21:43:26Z $ + * $Id: wl_cfgp2p.c 372668 2012-12-04 14:07:12Z $ * */ #include @@ -53,24 +53,22 @@ static bool wl_cfgp2p_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len, const u8 *oui, u32 oui_len, u8 type); static u32 -wl_cfgp2p_vndr_ie(struct wl_priv *wl, u8 *iebuf, s32 pktflag, +wl_cfgp2p_vndr_ie(struct wl_priv *wl, u8 *iebuf, s32 bssidx, s32 pktflag, s8 *oui, s32 ie_id, s8 *data, s32 datalen, const s8* add_del_cmd); -static s32 wl_cfgp2p_cancel_listen(struct wl_priv *wl, struct net_device *ndev, - struct wireless_dev *wdev, bool notify); -#if defined(WL_ENABLE_P2P_IF) static int wl_cfgp2p_start_xmit(struct sk_buff *skb, struct net_device *ndev); 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); static int wl_cfgp2p_if_stop(struct net_device *net); +static s32 wl_cfgp2p_cancel_listen(struct wl_priv *wl, struct net_device *ndev, + bool notify); static const struct net_device_ops wl_cfgp2p_if_ops = { - .ndo_open = wl_cfgp2p_if_open, - .ndo_stop = wl_cfgp2p_if_stop, - .ndo_do_ioctl = wl_cfgp2p_do_ioctl, - .ndo_start_xmit = wl_cfgp2p_start_xmit, + .ndo_open = wl_cfgp2p_if_open, + .ndo_stop = wl_cfgp2p_if_stop, + .ndo_do_ioctl = wl_cfgp2p_do_ioctl, + .ndo_start_xmit = wl_cfgp2p_start_xmit, }; -#endif /* WL_ENABLE_P2P_IF */ bool wl_cfgp2p_is_pub_action(void *frame, u32 frame_len) { @@ -111,6 +109,12 @@ bool wl_cfgp2p_is_p2p_action(void *frame return false; } +/* +* Currently Action frame just pass to P2P interface regardless real dst. +* but GAS Action can be used for Hotspot2.0 as well +* Need to distingush that it's for P2P or HS20 +*/ +#ifdef WL11U #define GAS_RESP_LEN 2 #define DOUBLE_TLV_BODY_OFF 4 #define GAS_RESP_OFFSET 4 @@ -142,6 +146,7 @@ bool wl_cfgp2p_find_gas_subtype(u8 subty return false; } +#endif /* WL11U */ bool wl_cfgp2p_is_gas_action(void *frame, u32 frame_len) { @@ -152,16 +157,12 @@ bool wl_cfgp2p_is_gas_action(void *frame return false; sd_act_frm = (wifi_p2psd_gas_pub_act_frame_t *)frame; - if (frame_len < (sizeof(wifi_p2psd_gas_pub_act_frame_t) - 1)) + if (frame_len < sizeof(wifi_p2psd_gas_pub_act_frame_t) - 1) return false; if (sd_act_frm->category != P2PSD_ACTION_CATEGORY) return false; #ifdef WL11U - /* XXX Hotspot2.0 STA mode can receive only response - * SoftAP mode cannot run Hotspot2.0 compliant Ap because - * Hotspot2.0 support only Enterprise mode - */ if (sd_act_frm->action == P2PSD_ACTION_ID_GAS_IRESP) return wl_cfgp2p_find_gas_subtype(P2PSD_GAS_OUI_SUBTYPE, (u8 *)sd_act_frm->query_data + GAS_RESP_OFFSET, @@ -184,9 +185,9 @@ bool wl_cfgp2p_is_gas_action(void *frame return true; else return false; -#endif /* WL11U */ +#endif /* WLC11U */ } -void wl_cfgp2p_print_actframe(bool tx, void *frame, u32 frame_len, u32 channel) +void wl_cfgp2p_print_actframe(bool tx, void *frame, u32 frame_len) { wifi_p2p_pub_act_frame_t *pact_frm; wifi_p2p_action_frame_t *act_frm; @@ -198,44 +199,44 @@ void wl_cfgp2p_print_actframe(bool tx, v pact_frm = (wifi_p2p_pub_act_frame_t *)frame; switch (pact_frm->subtype) { case P2P_PAF_GON_REQ: - CFGP2P_ACTION(("%s P2P Group Owner Negotiation Req Frame," - " channel=%d\n", (tx)? "TX": "RX", channel)); + CFGP2P_ACTION(("%s P2P Group Owner Negotiation Req Frame\n", + (tx)? "TX": "RX")); break; case P2P_PAF_GON_RSP: - CFGP2P_ACTION(("%s P2P Group Owner Negotiation Rsp Frame," - " channel=%d\n", (tx)? "TX": "RX", channel)); + CFGP2P_ACTION(("%s P2P Group Owner Negotiation Rsp Frame\n", + (tx)? "TX": "RX")); break; case P2P_PAF_GON_CONF: - CFGP2P_ACTION(("%s P2P Group Owner Negotiation Confirm Frame," - " channel=%d\n", (tx)? "TX": "RX", channel)); + CFGP2P_ACTION(("%s P2P Group Owner Negotiation Confirm Frame\n", + (tx)? "TX": "RX")); break; case P2P_PAF_INVITE_REQ: - CFGP2P_ACTION(("%s P2P Invitation Request Frame," - " channel=%d\n", (tx)? "TX": "RX", channel)); + CFGP2P_ACTION(("%s P2P Invitation Request Frame\n", + (tx)? "TX": "RX")); break; case P2P_PAF_INVITE_RSP: - CFGP2P_ACTION(("%s P2P Invitation Response Frame," - " channel=%d\n", (tx)? "TX": "RX", channel)); + CFGP2P_ACTION(("%s P2P Invitation Response Frame\n", + (tx)? "TX": "RX")); break; case P2P_PAF_DEVDIS_REQ: - CFGP2P_ACTION(("%s P2P Device Discoverability Request Frame," - " channel=%d\n", (tx)? "TX": "RX", channel)); + CFGP2P_ACTION(("%s P2P Device Discoverability Request Frame\n", + (tx)? "TX": "RX")); break; case P2P_PAF_DEVDIS_RSP: - CFGP2P_ACTION(("%s P2P Device Discoverability Response Frame," - " channel=%d\n", (tx)? "TX": "RX", channel)); + CFGP2P_ACTION(("%s P2P Device Discoverability Response Frame\n", + (tx)? "TX": "RX")); break; case P2P_PAF_PROVDIS_REQ: - CFGP2P_ACTION(("%s P2P Provision Discovery Request Frame," - " channel=%d\n", (tx)? "TX": "RX", channel)); + CFGP2P_ACTION(("%s P2P Provision Discovery Request Frame\n", + (tx)? "TX": "RX")); break; case P2P_PAF_PROVDIS_RSP: - CFGP2P_ACTION(("%s P2P Provision Discovery Response Frame," - " channel=%d\n", (tx)? "TX": "RX", channel)); + CFGP2P_ACTION(("%s P2P Provision Discovery Response Frame\n", + (tx)? "TX": "RX")); break; default: - CFGP2P_ACTION(("%s Unknown P2P Public Action Frame," - " channel=%d\n", (tx)? "TX": "RX", channel)); + CFGP2P_ACTION(("%s Unknown P2P Public Action Frame\n", + (tx)? "TX": "RX")); } @@ -243,48 +244,48 @@ void wl_cfgp2p_print_actframe(bool tx, v act_frm = (wifi_p2p_action_frame_t *)frame; switch (act_frm->subtype) { case P2P_AF_NOTICE_OF_ABSENCE: - CFGP2P_ACTION(("%s P2P Notice of Absence Frame," - " channel=%d\n", (tx)? "TX": "RX", channel)); + CFGP2P_ACTION(("%s P2P Notice of Absence Frame\n", + (tx)? "TX": "RX")); break; case P2P_AF_PRESENCE_REQ: - CFGP2P_ACTION(("%s P2P Presence Request Frame," - " channel=%d\n", (tx)? "TX": "RX", channel)); + CFGP2P_ACTION(("%s P2P Presence Request Frame\n", + (tx)? "TX": "RX")); break; case P2P_AF_PRESENCE_RSP: - CFGP2P_ACTION(("%s P2P Presence Response Frame," - " channel=%d\n", (tx)? "TX": "RX", channel)); + CFGP2P_ACTION(("%s P2P Presence Response Frame\n", + (tx)? "TX": "RX")); break; case P2P_AF_GO_DISC_REQ: - CFGP2P_ACTION(("%s P2P Discoverability Request Frame," - " channel=%d\n", (tx)? "TX": "RX", channel)); + CFGP2P_ACTION(("%s P2P Discoverability Request Frame\n", + (tx)? "TX": "RX")); break; default: - CFGP2P_ACTION(("%s Unknown P2P Action Frame," - " channel=%d\n", (tx)? "TX": "RX", channel)); + CFGP2P_ACTION(("%s Unknown P2P Action Frame\n", + (tx)? "TX": "RX")); } } else if (wl_cfgp2p_is_gas_action(frame, 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_ACTION(("%s P2P GAS Initial Request," - " channel=%d\n", (tx)? "TX" : "RX", channel)); + CFGP2P_ACTION(("%s P2P GAS Initial Request\n", + (tx)? "TX" : "RX")); break; case P2PSD_ACTION_ID_GAS_IRESP: - CFGP2P_ACTION(("%s P2P GAS Initial Response," - " channel=%d\n", (tx)? "TX" : "RX", channel)); + CFGP2P_ACTION(("%s P2P GAS Initial Response\n", + (tx)? "TX" : "RX")); break; case P2PSD_ACTION_ID_GAS_CREQ: - CFGP2P_ACTION(("%s P2P GAS Comback Request," - " channel=%d\n", (tx)? "TX" : "RX", channel)); + CFGP2P_ACTION(("%s P2P GAS Comback Request\n", + (tx)? "TX" : "RX")); break; case P2PSD_ACTION_ID_GAS_CRESP: - CFGP2P_ACTION(("%s P2P GAS Comback Response," - " channel=%d\n", (tx)? "TX" : "RX", channel)); + CFGP2P_ACTION(("%s P2P GAS Comback Response\n", + (tx)? "TX" : "RX")); break; default: - CFGP2P_ACTION(("%s Unknown P2P GAS Frame," - " channel=%d\n", (tx)? "TX" : "RX", channel)); + CFGP2P_ACTION(("%s Unknown P2P GAS Frame\n", + (tx)? "TX" : "RX")); } @@ -359,11 +360,7 @@ wl_cfgp2p_set_firm_p2p(struct wl_priv *w s32 ret = BCME_OK; s32 val = 0; /* Do we have to check whether APSTA is enabled or not ? */ - ret = wldev_iovar_getint(ndev, "apsta", &val); - if (ret < 0) { - CFGP2P_ERR(("get apsta error %d\n", ret)); - return ret; - } + wldev_iovar_getint(ndev, "apsta", &val); if (val == 0) { val = 1; ret = wldev_ioctl(ndev, WLC_DOWN, &val, sizeof(s32), true); @@ -431,7 +428,7 @@ wl_cfgp2p_ifadd(struct wl_priv *wl, stru /* Disable a P2P BSS. * Parameters: - * @mac : MAC address of the BSS to disable + * @mac : MAC address of the BSS to create * Returns 0 if success. */ s32 @@ -452,7 +449,7 @@ wl_cfgp2p_ifdisable(struct wl_priv *wl, /* Delete a P2P BSS. * Parameters: - * @mac : MAC address of the BSS to delete + * @mac : MAC address of the BSS to create * Returns 0 if success. */ s32 @@ -569,12 +566,12 @@ wl_cfgp2p_set_p2p_mode(struct wl_priv *w struct net_device *dev; CFGP2P_DBG(("enter\n")); - if (unlikely(bssidx == WL_INVALID)) { + if (unlikely(bssidx == WL_INVALID || bssidx >= P2PAPI_BSSCFG_MAX)) { CFGP2P_ERR((" %d index out of range\n", bssidx)); return -1; } - dev = wl_cfgp2p_find_ndev(wl, bssidx); + dev = wl_to_p2p_bss_ndev(wl, bssidx); if (unlikely(dev == NULL)) { CFGP2P_ERR(("bssidx %d is not assigned\n", bssidx)); return BCME_NOTFOUND; @@ -698,14 +695,8 @@ wl_cfgp2p_enable_discovery(struct wl_pri const u8 *ie, u32 ie_len) { s32 ret = BCME_OK; - s32 bssidx; - - if (wl_to_prmry_ndev(wl) == dev) { - bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE); - } else if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) { - WL_ERR(("Find p2p index from dev(%p) failed\n", dev)); - return BCME_ERROR; - } + s32 bssidx = (wl_to_prmry_ndev(wl) == dev) ? + wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) : wl_cfgp2p_find_idx(wl, dev); if (wl_get_p2p_status(wl, DISCOVERY_ON)) { CFGP2P_INFO((" DISCOVERY is already initialized, we have nothing to do\n")); goto set_ie; @@ -781,8 +772,7 @@ exit: s32 wl_cfgp2p_escan(struct wl_priv *wl, struct net_device *dev, u16 active, u32 num_chans, u16 *channels, - s32 search_state, u16 action, u32 bssidx, struct ether_addr *tx_dst_addr, - p2p_scan_purpose_t p2p_scan_purpose) + s32 search_state, u16 action, u32 bssidx) { s32 ret = BCME_OK; s32 memsize; @@ -809,7 +799,7 @@ wl_cfgp2p_escan(struct wl_priv *wl, stru memsize = sizeof(wl_p2p_scan_t) + eparams_size; memblk = scanparambuf; if (memsize > sizeof(scanparambuf)) { - CFGP2P_ERR((" scanpar buf too small (%u > %zu)\n", + CFGP2P_ERR((" scanpar buf too small (%u > %u)\n", memsize, sizeof(scanparambuf))); return -1; } @@ -821,9 +811,8 @@ wl_cfgp2p_escan(struct wl_priv *wl, stru * because dongle use P2P WILDCARD internally by default */ wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SEARCH, 0, 0, bssidx); - /* use null ssid */ - ssid.SSID_len = 0; - memset(&ssid.SSID, 0, sizeof(ssid.SSID)); + ssid.SSID_len = htod32(0); + } else if (search_state == WL_P2P_DISC_ST_SCAN) { /* SCAN STATE 802.11 SCAN * WFD Supplicant has p2p_find command with (type=progressive, type= full) @@ -831,12 +820,12 @@ wl_cfgp2p_escan(struct wl_priv *wl, stru * we have to set ssid to P2P WILDCARD because * we just do broadcast scan unless setting SSID */ + strncpy(ssid.SSID, WL_P2P_WILDCARD_SSID, sizeof(ssid.SSID) - 1); + ssid.SSID[sizeof(ssid.SSID) - 1] = 0; + ssid.SSID_len = htod32(WL_P2P_WILDCARD_SSID_LEN); wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SCAN, 0, 0, bssidx); - /* use wild card ssid */ - ssid.SSID_len = WL_P2P_WILDCARD_SSID_LEN; - memset(&ssid.SSID, 0, sizeof(ssid.SSID)); - memcpy(&ssid.SSID, WL_P2P_WILDCARD_SSID, WL_P2P_WILDCARD_SSID_LEN); - } else { + } + else { CFGP2P_ERR((" invalid search state %d\n", search_state)); return -1; } @@ -853,42 +842,32 @@ wl_cfgp2p_escan(struct wl_priv *wl, stru else eparams->params.scan_type = DOT11_SCANTYPE_PASSIVE; - if (tx_dst_addr == NULL) - memcpy(&eparams->params.bssid, ðer_bcast, ETHER_ADDR_LEN); - else - memcpy(&eparams->params.bssid, tx_dst_addr, ETHER_ADDR_LEN); - + memcpy(&eparams->params.bssid, ðer_bcast, ETHER_ADDR_LEN); if (ssid.SSID_len) memcpy(&eparams->params.ssid, &ssid, sizeof(wlc_ssid_t)); eparams->params.home_time = htod32(P2PAPI_SCAN_HOME_TIME_MS); - switch (p2p_scan_purpose) { - case P2P_SCAN_SOCIAL_CHANNEL: - eparams->params.active_time = htod32(P2PAPI_SCAN_SOCIAL_DWELL_TIME_MS); - break; - case P2P_SCAN_AFX_PEER_NORMAL: - case P2P_SCAN_AFX_PEER_REDUCED: - eparams->params.active_time = htod32(P2PAPI_SCAN_AF_SEARCH_DWELL_TIME_MS); - break; - case P2P_SCAN_CONNECT_TRY: - eparams->params.active_time = htod32(WL_SCAN_CONNECT_DWELL_TIME_MS); - break; - default : - if (wl_get_drv_status_all(wl, CONNECTED)) - eparams->params.active_time = -1; - else - eparams->params.active_time = htod32(P2PAPI_SCAN_DWELL_TIME_MS); - break; - } - - if (p2p_scan_purpose == P2P_SCAN_CONNECT_TRY) + /* SOCIAL_CHAN_CNT + 1 takes care of the Progressive scan supported by + * the supplicant + */ + if ((num_chans == SOCIAL_CHAN_CNT) || (num_chans == SOCIAL_CHAN_CNT + 1)) + eparams->params.active_time = htod32(P2PAPI_SCAN_SOCIAL_DWELL_TIME_MS); + else if (num_chans == AF_PEER_SEARCH_CNT) + eparams->params.active_time = htod32(P2PAPI_SCAN_AF_SEARCH_DWELL_TIME_MS); + else if (wl_get_drv_status_all(wl, CONNECTED)) + eparams->params.active_time = -1; + else + eparams->params.active_time = htod32(P2PAPI_SCAN_DWELL_TIME_MS); + eparams->params.nprobes = htod32((eparams->params.active_time / + P2PAPI_SCAN_NPROBS_TIME_MS)); + + /* Override scan params to find a peer for a connection */ + if (num_chans == 1) { + eparams->params.active_time = htod32(WL_SCAN_CONNECT_DWELL_TIME_MS); eparams->params.nprobes = htod32(eparams->params.active_time / WL_SCAN_JOIN_PROBE_INTERVAL_MS); - else - eparams->params.nprobes = htod32((eparams->params.active_time / - P2PAPI_SCAN_NPROBS_TIME_MS)); - + } if (eparams->params.nprobes <= 0) eparams->params.nprobes = 1; @@ -903,7 +882,7 @@ wl_cfgp2p_escan(struct wl_priv *wl, stru } eparams->version = htod32(ESCAN_REQ_VERSION); eparams->action = htod16(action); - wl_escan_set_sync_id(eparams->sync_id, wl); + eparams->sync_id = htod16(0x1234); CFGP2P_INFO(("SCAN CHANNELS : ")); for (i = 0; i < num_chans; i++) { @@ -929,17 +908,16 @@ wl_cfgp2p_escan(struct wl_priv *wl, stru */ s32 wl_cfgp2p_act_frm_search(struct wl_priv *wl, struct net_device *ndev, - s32 bssidx, s32 channel, struct ether_addr *tx_dst_addr) + s32 bssidx, s32 channel) { s32 ret = 0; u32 chan_cnt = 0; u16 *default_chan_list = NULL; - p2p_scan_purpose_t p2p_scan_purpose = P2P_SCAN_AFX_PEER_NORMAL; if (!p2p_is_on(wl) || ndev == NULL || bssidx == WL_INVALID) return -BCME_ERROR; - CFGP2P_DBG((" Enter\n")); - if (bssidx == wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_PRIMARY)) - bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE); + CFGP2P_ERR((" Enter\n")); + if (bssidx == P2PAPI_BSSCFG_PRIMARY) + bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE); if (channel) chan_cnt = AF_PEER_SEARCH_CNT; else @@ -961,10 +939,9 @@ wl_cfgp2p_act_frm_search(struct wl_priv default_chan_list[1] = SOCIAL_CHAN_2; default_chan_list[2] = SOCIAL_CHAN_3; } - ret = wl_cfgp2p_escan(wl, ndev, true, chan_cnt, default_chan_list, WL_P2P_DISC_ST_SEARCH, - WL_SCAN_ACTION_START, bssidx, tx_dst_addr, p2p_scan_purpose); + WL_SCAN_ACTION_START, bssidx); kfree(default_chan_list); exit: return ret; @@ -980,9 +957,7 @@ exit: #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. */ -#ifndef WFA_OUI_TYPE_WFD #define WFA_OUI_TYPE_WFD 0x0a /* WiFi Display OUI TYPE */ -#endif #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) @@ -1071,50 +1046,45 @@ wl_cfgp2p_set_management_ie(struct wl_pr struct parsed_vndr_ies new_vndr_ies; s32 i; u8 *ptr; - s32 type = -1; s32 remained_buf_len; + #define IE_TYPE(type, bsstype) (wl_to_p2p_bss_saved_ie(wl, bsstype).p2p_ ## type ## _ie) #define IE_TYPE_LEN(type, bsstype) (wl_to_p2p_bss_saved_ie(wl, bsstype).p2p_ ## type ## _ie_len) memset(g_mgmt_ie_buf, 0, sizeof(g_mgmt_ie_buf)); curr_ie_buf = g_mgmt_ie_buf; CFGP2P_DBG((" bssidx %d, pktflag : 0x%02X\n", bssidx, pktflag)); if (wl->p2p != NULL) { - if (wl_cfgp2p_find_type(wl, bssidx, &type)) { - CFGP2P_ERR(("cannot find type from bssidx : %d\n", bssidx)); - return BCME_ERROR; - } - switch (pktflag) { case VNDR_IE_PRBREQ_FLAG : - mgmt_ie_buf = IE_TYPE(probe_req, type); - mgmt_ie_len = &IE_TYPE_LEN(probe_req, type); - mgmt_ie_buf_len = sizeof(IE_TYPE(probe_req, type)); + mgmt_ie_buf = IE_TYPE(probe_req, bssidx); + mgmt_ie_len = &IE_TYPE_LEN(probe_req, bssidx); + mgmt_ie_buf_len = sizeof(IE_TYPE(probe_req, bssidx)); break; case VNDR_IE_PRBRSP_FLAG : - mgmt_ie_buf = IE_TYPE(probe_res, type); - mgmt_ie_len = &IE_TYPE_LEN(probe_res, type); - mgmt_ie_buf_len = sizeof(IE_TYPE(probe_res, type)); + mgmt_ie_buf = IE_TYPE(probe_res, bssidx); + mgmt_ie_len = &IE_TYPE_LEN(probe_res, bssidx); + mgmt_ie_buf_len = sizeof(IE_TYPE(probe_res, bssidx)); break; case VNDR_IE_ASSOCREQ_FLAG : - mgmt_ie_buf = IE_TYPE(assoc_req, type); - mgmt_ie_len = &IE_TYPE_LEN(assoc_req, type); - mgmt_ie_buf_len = sizeof(IE_TYPE(assoc_req, type)); + mgmt_ie_buf = IE_TYPE(assoc_req, bssidx); + mgmt_ie_len = &IE_TYPE_LEN(assoc_req, bssidx); + mgmt_ie_buf_len = sizeof(IE_TYPE(assoc_req, bssidx)); break; case VNDR_IE_ASSOCRSP_FLAG : - mgmt_ie_buf = IE_TYPE(assoc_res, type); - mgmt_ie_len = &IE_TYPE_LEN(assoc_res, type); - mgmt_ie_buf_len = sizeof(IE_TYPE(assoc_res, type)); + mgmt_ie_buf = IE_TYPE(assoc_res, bssidx); + mgmt_ie_len = &IE_TYPE_LEN(assoc_res, bssidx); + mgmt_ie_buf_len = sizeof(IE_TYPE(assoc_res, bssidx)); break; case VNDR_IE_BEACON_FLAG : - mgmt_ie_buf = IE_TYPE(beacon, type); - mgmt_ie_len = &IE_TYPE_LEN(beacon, type); - mgmt_ie_buf_len = sizeof(IE_TYPE(beacon, type)); + mgmt_ie_buf = IE_TYPE(beacon, bssidx); + mgmt_ie_len = &IE_TYPE_LEN(beacon, bssidx); + mgmt_ie_buf_len = sizeof(IE_TYPE(beacon, bssidx)); break; default: mgmt_ie_buf = NULL; mgmt_ie_len = NULL; CFGP2P_ERR(("not suitable type\n")); - return BCME_ERROR; + return -1; } } else if (wl_get_mode_by_netdev(wl, ndev) == WL_MODE_AP) { switch (pktflag) { @@ -1132,7 +1102,7 @@ wl_cfgp2p_set_management_ie(struct wl_pr mgmt_ie_buf = NULL; mgmt_ie_len = NULL; CFGP2P_ERR(("not suitable type\n")); - return BCME_ERROR; + return -1; } bssidx = 0; } else if (wl_get_mode_by_netdev(wl, ndev) == WL_MODE_BSS) { @@ -1151,12 +1121,12 @@ wl_cfgp2p_set_management_ie(struct wl_pr mgmt_ie_buf = NULL; mgmt_ie_len = NULL; CFGP2P_ERR(("not suitable type\n")); - return BCME_ERROR; + return -1; } bssidx = 0; } else { CFGP2P_ERR(("not suitable type\n")); - return BCME_ERROR; + return -1; } if (vndr_ie_len > mgmt_ie_buf_len) { @@ -1202,7 +1172,7 @@ wl_cfgp2p_set_management_ie(struct wl_pr vndrie_info->vndrie.oui[2])); del_add_ie_buf_len = wl_cfgp2p_vndr_ie(wl, curr_ie_buf, - pktflag, vndrie_info->vndrie.oui, + bssidx, pktflag, vndrie_info->vndrie.oui, vndrie_info->vndrie.id, vndrie_info->ie_ptr + VNDR_IE_FIXED_LEN, vndrie_info->ie_len - VNDR_IE_FIXED_LEN, @@ -1232,7 +1202,7 @@ wl_cfgp2p_set_management_ie(struct wl_pr vndrie_info->vndrie.oui[2])); del_add_ie_buf_len = wl_cfgp2p_vndr_ie(wl, curr_ie_buf, - pktflag, vndrie_info->vndrie.oui, + bssidx, pktflag, vndrie_info->vndrie.oui, vndrie_info->vndrie.id, vndrie_info->ie_ptr + VNDR_IE_FIXED_LEN, vndrie_info->ie_len - VNDR_IE_FIXED_LEN, @@ -1283,11 +1253,9 @@ exit: s32 wl_cfgp2p_clear_management_ie(struct wl_priv *wl, s32 bssidx) { - s32 vndrie_flag[] = {VNDR_IE_BEACON_FLAG, VNDR_IE_PRBRSP_FLAG, VNDR_IE_ASSOCRSP_FLAG, VNDR_IE_PRBREQ_FLAG, VNDR_IE_ASSOCREQ_FLAG}; s32 index = -1; - s32 type = -1; struct net_device *ndev = wl_cfgp2p_find_ndev(wl, bssidx); #define INIT_IE(IE_TYPE, BSS_TYPE) \ do { \ @@ -1300,20 +1268,15 @@ wl_cfgp2p_clear_management_ie(struct wl_ CFGP2P_ERR(("invalid %s\n", (bssidx < 0) ? "bssidx" : "ndev")); return BCME_BADARG; } - - if (wl_cfgp2p_find_type(wl, bssidx, &type)) { - CFGP2P_ERR(("invalid argument\n")); - return BCME_BADARG; - } for (index = 0; index < ARRAYSIZE(vndrie_flag); index++) { /* clean up vndr ies in dongle */ wl_cfgp2p_set_management_ie(wl, ndev, bssidx, vndrie_flag[index], NULL, 0); } - INIT_IE(probe_req, type); - INIT_IE(probe_res, type); - INIT_IE(assoc_req, type); - INIT_IE(assoc_res, type); - INIT_IE(beacon, type); + INIT_IE(probe_req, bssidx); + INIT_IE(probe_res, bssidx); + INIT_IE(assoc_req, bssidx); + INIT_IE(assoc_res, bssidx); + INIT_IE(beacon, bssidx); return BCME_OK; } @@ -1395,7 +1358,7 @@ wl_cfgp2p_find_wfdie(u8 *parse, u32 len) return NULL; } static u32 -wl_cfgp2p_vndr_ie(struct wl_priv *wl, u8 *iebuf, s32 pktflag, +wl_cfgp2p_vndr_ie(struct wl_priv *wl, u8 *iebuf, s32 bssidx, s32 pktflag, s8 *oui, s32 ie_id, s8 *data, s32 datalen, const s8* add_del_cmd) { vndr_ie_setbuf_t hdr; /* aligned temporary vndr_ie buffer header */ @@ -1452,32 +1415,33 @@ wl_cfgp2p_vndr_ie(struct wl_priv *wl, u8 * Parameters: * @wl : wl_private data * @ndev : net device to search bssidx - * @bssidx : output arg to store bssidx of the bsscfg of firmware. - * Returns error + * Returns bssidx for ndev */ s32 -wl_cfgp2p_find_idx(struct wl_priv *wl, struct net_device *ndev, s32 *bssidx) +wl_cfgp2p_find_idx(struct wl_priv *wl, struct net_device *ndev) { u32 i; - if (ndev == NULL || bssidx == NULL) { - CFGP2P_ERR((" argument is invalid\n")); - return BCME_BADARG; + s32 index = -1; + + if (ndev == NULL) { + CFGP2P_ERR((" ndev is NULL\n")); + goto exit; } if (!wl->p2p_supported) { - *bssidx = P2PAPI_BSSCFG_PRIMARY; - return BCME_OK; + return P2PAPI_BSSCFG_PRIMARY; } - /* we cannot find the bssidx of DISCOVERY BSS - * because the ndev is same with ndev of PRIMARY BSS. - */ for (i = 0; i < P2PAPI_BSSCFG_MAX; i++) { if (ndev == wl_to_p2p_bss_ndev(wl, i)) { - *bssidx = wl_to_p2p_bss_bssidx(wl, i); - return BCME_OK; + index = wl_to_p2p_bss_bssidx(wl, i); + break; } } - return BCME_BADARG; + if (index == -1) + return P2PAPI_BSSCFG_PRIMARY; +exit: + return index; } + struct net_device * wl_cfgp2p_find_ndev(struct wl_priv *wl, s32 bssidx) { @@ -1498,52 +1462,24 @@ wl_cfgp2p_find_ndev(struct wl_priv *wl, exit: return ndev; } -/* - * Search the driver array idx based on bssidx argument - * Parameters: - * @wl : wl_private data - * @bssidx : bssidx which indicate bsscfg->idx of firmware. - * @type : output arg to store array idx of p2p->bss. - * Returns error - */ - -s32 -wl_cfgp2p_find_type(struct wl_priv *wl, s32 bssidx, s32 *type) -{ - u32 i; - if (bssidx < 0 || type == NULL) { - CFGP2P_ERR((" argument is invalid\n")); - goto exit; - } - - for (i = 0; i < P2PAPI_BSSCFG_MAX; i++) { - if (bssidx == wl_to_p2p_bss_bssidx(wl, i)) { - *type = i; - return BCME_OK; - } - } - -exit: - return BCME_BADARG; -} /* * Callback function for WLC_E_P2P_DISC_LISTEN_COMPLETE */ s32 -wl_cfgp2p_listen_complete(struct wl_priv *wl, bcm_struct_cfgdev *cfgdev, - const wl_event_msg_t *e, void *data) +wl_cfgp2p_listen_complete(struct wl_priv *wl, struct net_device *ndev, + const wl_event_msg_t *e, void *data) { s32 ret = BCME_OK; - struct net_device *ndev = NULL; - + struct net_device *netdev; if (!wl || !wl->p2p) return BCME_ERROR; - + if (wl->p2p_net == ndev) { + netdev = wl_to_prmry_ndev(wl); + } else { + netdev = ndev; + } CFGP2P_DBG((" Enter\n")); - - ndev = cfgdev_to_wlc_ndev(cfgdev, wl); - if (wl_get_p2p_status(wl, LISTEN_EXPIRED) == 0) { wl_set_p2p_status(wl, LISTEN_EXPIRED); if (timer_pending(&wl->p2p->listen_timer)) { @@ -1557,12 +1493,12 @@ wl_cfgp2p_listen_complete(struct wl_priv } #ifdef WL_CFG80211_SYNC_GON else if (wl_get_drv_status_all(wl, WAITING_NEXT_ACT_FRM_LISTEN)) { - wl_clr_drv_status(wl, WAITING_NEXT_ACT_FRM_LISTEN, ndev); + wl_clr_drv_status(wl, WAITING_NEXT_ACT_FRM_LISTEN, netdev); WL_DBG(("Listen DONE and wake up wait_next_af !!(%d)\n", jiffies_to_msecs(jiffies - wl->af_tx_sent_jiffies))); if (wl_get_drv_status_all(wl, WAITING_NEXT_ACT_FRM)) - wl_clr_drv_status(wl, WAITING_NEXT_ACT_FRM, ndev); + wl_clr_drv_status(wl, WAITING_NEXT_ACT_FRM, netdev); complete(&wl->wait_next_af); } @@ -1575,18 +1511,13 @@ wl_cfgp2p_listen_complete(struct wl_priv wl_get_drv_status_all(wl, FAKE_REMAINING_ON_CHANNEL)) { #endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */ WL_DBG(("Listen DONE for ramain on channel expired\n")); - wl_clr_drv_status(wl, REMAINING_ON_CHANNEL, ndev); + wl_clr_drv_status(wl, REMAINING_ON_CHANNEL, netdev); #ifdef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST - wl_clr_drv_status(wl, FAKE_REMAINING_ON_CHANNEL, ndev); + wl_clr_drv_status(wl, FAKE_REMAINING_ON_CHANNEL, netdev); #endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */ if (ndev && (ndev->ieee80211_ptr != NULL)) { -#if defined(WL_CFG80211_P2P_DEV_IF) - cfg80211_remain_on_channel_expired(cfgdev, wl->last_roc_id, - &wl->remain_on_chan, GFP_KERNEL); -#else - cfg80211_remain_on_channel_expired(cfgdev, wl->last_roc_id, + cfg80211_remain_on_channel_expired(ndev, wl->last_roc_id, &wl->remain_on_chan, wl->remain_on_chan_type, GFP_KERNEL); -#endif /* WL_CFG80211_P2P_DEV_IF */ } } if (wl_add_remove_eventmsg(wl_to_prmry_ndev(wl), @@ -1613,20 +1544,15 @@ wl_cfgp2p_listen_expired(unsigned long d CFGP2P_DBG((" Enter\n")); bzero(&msg, sizeof(wl_event_msg_t)); msg.event_type = hton32(WLC_E_P2P_DISC_LISTEN_COMPLETE); -#if defined(WL_ENABLE_P2P_IF) wl_cfg80211_event(wl->p2p_net ? wl->p2p_net : wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE), &msg, NULL); -#else - wl_cfg80211_event(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE), &msg, - NULL); -#endif /* WL_ENABLE_P2P_IF */ } /* * Routine for cancelling the P2P LISTEN */ static s32 wl_cfgp2p_cancel_listen(struct wl_priv *wl, struct net_device *ndev, - struct wireless_dev *wdev, bool notify) + bool notify) { WL_DBG(("Enter \n")); /* Irrespective of whether timer is running or not, reset @@ -1636,13 +1562,9 @@ wl_cfgp2p_cancel_listen(struct wl_priv * del_timer_sync(&wl->p2p->listen_timer); if (notify) if (ndev && ndev->ieee80211_ptr) { -#if defined(WL_CFG80211_P2P_DEV_IF) - cfg80211_remain_on_channel_expired(wdev, wl->last_roc_id, - &wl->remain_on_chan, GFP_KERNEL); -#else cfg80211_remain_on_channel_expired(ndev, wl->last_roc_id, - &wl->remain_on_chan, wl->remain_on_chan_type, GFP_KERNEL); -#endif /* WL_CFG80211_P2P_DEV_IF */ + &wl->remain_on_chan, wl->remain_on_chan_type, + GFP_KERNEL); } } return 0; @@ -1746,35 +1668,31 @@ wl_cfgp2p_discover_enable_search(struct * Callback function for WLC_E_ACTION_FRAME_COMPLETE, WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE */ s32 -wl_cfgp2p_action_tx_complete(struct wl_priv *wl, bcm_struct_cfgdev *cfgdev, +wl_cfgp2p_action_tx_complete(struct wl_priv *wl, struct net_device *ndev, const wl_event_msg_t *e, void *data) { s32 ret = BCME_OK; u32 event_type = ntoh32(e->event_type); u32 status = ntoh32(e->status); CFGP2P_DBG((" Enter\n")); - if (wl_get_drv_status_all(wl, SENDING_ACT_FRM)) { - if (event_type == WLC_E_ACTION_FRAME_COMPLETE) { - - CFGP2P_INFO((" WLC_E_ACTION_FRAME_COMPLETE is received : %d\n", status)); - if (status == WLC_E_STATUS_SUCCESS) { - wl_set_p2p_status(wl, ACTION_TX_COMPLETED); - CFGP2P_DBG(("WLC_E_ACTION_FRAME_COMPLETE : ACK\n")); - } - else { - if (!wl_get_p2p_status(wl, ACTION_TX_COMPLETED)) { - wl_set_p2p_status(wl, ACTION_TX_NOACK); - CFGP2P_INFO(("WLC_E_ACTION_FRAME_COMPLETE : NO ACK\n")); - wl_stop_wait_next_action_frame(wl); - } - } - } else { - CFGP2P_INFO((" WLC_E_ACTION_FRAME_OFFCHAN_COMPLETE is received," - "status : %d\n", status)); + if (event_type == WLC_E_ACTION_FRAME_COMPLETE) { - if (wl_get_drv_status_all(wl, SENDING_ACT_FRM)) - complete(&wl->send_af_done); + CFGP2P_INFO((" WLC_E_ACTION_FRAME_COMPLETE is received : %d\n", status)); + if (status == WLC_E_STATUS_SUCCESS) { + wl_set_p2p_status(wl, ACTION_TX_COMPLETED); + CFGP2P_DBG(("WLC_E_ACTION_FRAME_COMPLETE : ACK\n")); } + else { + wl_set_p2p_status(wl, ACTION_TX_NOACK); + CFGP2P_INFO(("WLC_E_ACTION_FRAME_COMPLETE : NO ACK\n")); + wl_stop_wait_next_action_frame(wl, ndev); + } + } else { + CFGP2P_INFO((" WLC_E_ACTION_FRAME_OFFCHAN_COMPLETE is received," + "status : %d\n", status)); + + if (wl_get_drv_status_all(wl, SENDING_ACT_FRM)) + complete(&wl->send_af_done); } return ret; } @@ -1791,7 +1709,6 @@ wl_cfgp2p_tx_action_frame(struct wl_priv wl_af_params_t *af_params, s32 bssidx) { s32 ret = BCME_OK; - s32 evt_ret = BCME_OK; s32 timeout = 0; wl_eventmsg_buf_t buf; @@ -1806,9 +1723,10 @@ wl_cfgp2p_tx_action_frame(struct wl_priv bzero(&buf, sizeof(wl_eventmsg_buf_t)); wl_cfg80211_add_to_eventbuffer(&buf, WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE, true); wl_cfg80211_add_to_eventbuffer(&buf, WLC_E_ACTION_FRAME_COMPLETE, true); - if ((evt_ret = wl_cfg80211_apply_eventbuffer(wl_to_prmry_ndev(wl), wl, &buf)) < 0) - return evt_ret; + if ((ret = wl_cfg80211_apply_eventbuffer(wl_to_prmry_ndev(wl), wl, &buf)) < 0) + return ret; +#define MAX_WAIT_TIME 2000 if (bssidx == P2PAPI_BSSCFG_PRIMARY) bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE); @@ -1825,10 +1743,9 @@ wl_cfgp2p_tx_action_frame(struct wl_priv goto exit; } - timeout = wait_for_completion_timeout(&wl->send_af_done, - msecs_to_jiffies(af_params->dwell_time + WL_AF_TX_EXTRA_TIME_MAX)); + timeout = wait_for_completion_timeout(&wl->send_af_done, msecs_to_jiffies(MAX_WAIT_TIME)); - if (timeout >= 0 && wl_get_p2p_status(wl, ACTION_TX_COMPLETED)) { + if (timeout > 0 && wl_get_p2p_status(wl, ACTION_TX_COMPLETED)) { CFGP2P_INFO(("tx action frame operation is completed\n")); ret = BCME_OK; } else { @@ -1845,11 +1762,10 @@ exit: bzero(&buf, sizeof(wl_eventmsg_buf_t)); wl_cfg80211_add_to_eventbuffer(&buf, WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE, false); wl_cfg80211_add_to_eventbuffer(&buf, WLC_E_ACTION_FRAME_COMPLETE, false); - if ((evt_ret = wl_cfg80211_apply_eventbuffer(wl_to_prmry_ndev(wl), wl, &buf)) < 0) { + if ((ret = wl_cfg80211_apply_eventbuffer(wl_to_prmry_ndev(wl), wl, &buf)) < 0) WL_ERR(("TX frame events revert back failed \n")); - return evt_ret; - } +#undef MAX_WAIT_TIME return ret; } @@ -2005,34 +1921,23 @@ wl_cfgp2p_supported(struct wl_priv *wl, } return p2p_supported; } + /* Cleanup P2P resources */ s32 wl_cfgp2p_down(struct wl_priv *wl) { - struct net_device *ndev = NULL; - struct wireless_dev *wdev = NULL; s32 i = 0, index = -1; - -#if defined(WL_CFG80211_P2P_DEV_IF) - ndev = wl_to_prmry_ndev(wl); - wdev = wl_to_p2p_wdev(wl); -#elif defined(WL_ENABLE_P2P_IF) - ndev = wl->p2p_net ? wl->p2p_net : wl_to_prmry_ndev(wl); - wdev = ndev_to_wdev(ndev); -#endif /* WL_CFG80211_P2P_DEV_IF */ - - wl_cfgp2p_cancel_listen(wl, ndev, wdev, TRUE); + wl_cfgp2p_cancel_listen(wl, + wl->p2p_net ? wl->p2p_net : wl_to_prmry_ndev(wl), TRUE); for (i = 0; i < P2PAPI_BSSCFG_MAX; i++) { index = wl_to_p2p_bss_bssidx(wl, i); if (index != WL_INVALID) wl_cfgp2p_clear_management_ie(wl, index); } -#if defined(WL_CFG80211_P2P_DEV_IF) - wl_cfgp2p_del_p2p_disc_if(wdev); -#endif /* WL_CFG80211_P2P_DEV_IF */ 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) { @@ -2175,7 +2080,7 @@ wl_cfgp2p_set_p2p_ps(struct wl_priv *wl, } if ((legacy_ps != -1) && ((legacy_ps == PM_MAX) || (legacy_ps == PM_OFF))) { -#if defined(SUPPORT_PM2_ONLY) +#if !defined(SUPPORT_PM2_ONLY) if (legacy_ps == PM_MAX) legacy_ps = PM_FAST; #endif /* SUPPORT_PM2_ONLY */ @@ -2250,47 +2155,20 @@ wl_cfgp2p_retreive_p2pattrib(void *buf, } #define P2P_GROUP_CAPAB_GO_BIT 0x01 - -u8* -wl_cfgp2p_find_attrib_in_all_p2p_Ies(u8 *parse, u32 len, u32 attrib) -{ - bcm_tlv_t *ie; - u8* pAttrib; - - CFGP2P_INFO(("Starting parsing parse %p attrib %d remaining len %d ", parse, attrib, len)); - while ((ie = bcm_parse_tlvs(parse, (int)len, DOT11_MNG_VS_ID))) { - if (wl_cfgp2p_is_p2p_ie((uint8*)ie, &parse, &len) == TRUE) { - /* Have the P2p ie. Now check for attribute */ - if ((pAttrib = wl_cfgp2p_retreive_p2pattrib(parse, attrib)) != NULL) { - CFGP2P_INFO(("P2P attribute %d was found at parse %p", - attrib, parse)); - return pAttrib; - } - else { - parse += (ie->len + TLV_HDR_LEN); - len -= (ie->len + TLV_HDR_LEN); - CFGP2P_INFO(("P2P Attribute %d not found Moving parse" - " to %p len to %d", attrib, parse, len)); - } - } - else { - /* It was not p2p IE. parse will get updated automatically to next TLV */ - CFGP2P_INFO(("IT was NOT P2P IE parse %p len %d", parse, len)); - } - } - CFGP2P_ERR(("P2P attribute %d was NOT found", attrib)); - return NULL; -} - u8 * wl_cfgp2p_retreive_p2p_dev_addr(wl_bss_info_t *bi, u32 bi_length) { + wifi_p2p_ie_t * p2p_ie = NULL; u8 *capability = NULL; bool p2p_go = 0; u8 *ptr = NULL; - if ((capability = wl_cfgp2p_find_attrib_in_all_p2p_Ies(((u8 *) bi) + bi->ie_offset, - bi->ie_length, P2P_SEID_P2P_INFO)) == NULL) { + if (!(p2p_ie = wl_cfgp2p_find_p2pie(((u8 *) bi) + bi->ie_offset, bi->ie_length))) { + WL_ERR(("P2P IE not found")); + return NULL; + } + + if (!(capability = wl_cfgp2p_retreive_p2pattrib(p2p_ie, P2P_SEID_P2P_INFO))) { WL_ERR(("P2P Capability attribute not found")); return NULL; } @@ -2302,13 +2180,11 @@ wl_cfgp2p_retreive_p2p_dev_addr(wl_bss_i } /* In probe responses, DEVICE INFO attribute will be present */ - if (!(ptr = wl_cfgp2p_find_attrib_in_all_p2p_Ies(((u8 *) bi) + bi->ie_offset, - bi->ie_length, P2P_SEID_DEV_INFO))) { + if (!(ptr = wl_cfgp2p_retreive_p2pattrib(p2p_ie, P2P_SEID_DEV_INFO))) { /* If DEVICE_INFO is not found, this might be a beacon frame. * check for DEVICE_ID in the beacon frame. */ - ptr = wl_cfgp2p_find_attrib_in_all_p2p_Ies(((u8 *) bi) + bi->ie_offset, - bi->ie_length, P2P_SEID_DEV_ID); + ptr = wl_cfgp2p_retreive_p2pattrib(p2p_ie, P2P_SEID_DEV_ID); } if (!ptr) @@ -2330,7 +2206,6 @@ struct ethtool_ops cfgp2p_ethtool_ops = }; #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) */ -#if defined(WL_ENABLE_P2P_IF) s32 wl_cfgp2p_register_ndev(struct wl_priv *wl) { @@ -2427,7 +2302,6 @@ wl_cfgp2p_unregister_ndev(struct wl_priv } static int wl_cfgp2p_start_xmit(struct sk_buff *skb, struct net_device *ndev) { - if (skb) { CFGP2P_DBG(("(%s) is not used for data operations.Droping the packet.\n", @@ -2469,7 +2343,6 @@ static int wl_cfgp2p_if_open(struct net_ if (!wdev || !wl || !wl->p2p) return -EINVAL; WL_TRACE(("Enter\n")); -#if !defined(WL_IFACE_COMB_NUM_CHANNELS) /* 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. @@ -2478,7 +2351,6 @@ static int wl_cfgp2p_if_open(struct net_ */ wdev->wiphy->interface_modes |= (BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO)); -#endif /* !WL_IFACE_COMB_NUM_CHANNELS */ wl_cfg80211_do_driver_init(net); return 0; @@ -2507,11 +2379,9 @@ static int wl_cfgp2p_if_stop(struct net_ spin_unlock_irqrestore(&wl->cfgdrv_lock, flags); if (clear_flag) wl_clr_drv_status(wl, SCANNING, net); -#if !defined(WL_IFACE_COMB_NUM_CHANNELS) wdev->wiphy->interface_modes = (wdev->wiphy->interface_modes) & (~(BIT(NL80211_IFTYPE_P2P_CLIENT)| BIT(NL80211_IFTYPE_P2P_GO))); -#endif /* !WL_IFACE_COMB_NUM_CHANNELS */ return 0; } @@ -2519,143 +2389,3 @@ bool wl_cfgp2p_is_ifops(const struct net { return (if_ops == &wl_cfgp2p_if_ops); } -#endif /* WL_ENABLE_P2P_IF */ - -#if defined(WL_CFG80211_P2P_DEV_IF) -struct wireless_dev * -wl_cfgp2p_add_p2p_disc_if(void) -{ - extern struct wl_priv *wlcfg_drv_priv; - struct wl_priv *wl = wlcfg_drv_priv; - struct wireless_dev *wdev = NULL; - struct ether_addr primary_mac; - - if (!wl) - return NULL; - - WL_TRACE(("Enter\n")); - - if (wl->p2p_wdev) { - CFGP2P_ERR(("p2p_wdev defined already.\n")); - return NULL; - } - - wdev = kzalloc(sizeof(*wdev), GFP_KERNEL); - if (unlikely(!wdev)) { - WL_ERR(("Could not allocate wireless device\n")); - return NULL; - } - - memset(&primary_mac, 0, sizeof(primary_mac)); - get_primary_mac(wl, &primary_mac); - wl_cfgp2p_generate_bss_mac(&primary_mac, - &wl->p2p->dev_addr, &wl->p2p->int_addr); - - wdev->wiphy = wl->wdev->wiphy; - wdev->iftype = NL80211_IFTYPE_P2P_DEVICE; - memcpy(wdev->address, &wl->p2p->dev_addr, ETHER_ADDR_LEN); - - /* store p2p wdev ptr for further reference. */ - wl->p2p_wdev = wdev; - - CFGP2P_ERR(("P2P interface registered\n")); - - return wdev; -} - -int -wl_cfgp2p_start_p2p_device(struct wiphy *wiphy, struct wireless_dev *wdev) -{ - int ret = 0; - extern struct wl_priv *wlcfg_drv_priv; - struct wl_priv *wl = wlcfg_drv_priv; - - if (!wl) - return -EINVAL; - - WL_TRACE(("Enter\n")); - - ret = wl_cfgp2p_set_firm_p2p(wl); - if (unlikely(ret < 0)) { - CFGP2P_ERR(("Set P2P in firmware failed, ret=%d\n", ret)); - goto exit; - } - - ret = wl_cfgp2p_enable_discovery(wl, wl_to_prmry_ndev(wl), NULL, 0); - if (unlikely(ret < 0)) { - CFGP2P_ERR(("P2P enable discovery failed, ret=%d\n", ret)); - goto exit; - } - - p2p_on(wl) = true; - - CFGP2P_DBG(("P2P interface started\n")); - -exit: - return ret; -} - -void -wl_cfgp2p_stop_p2p_device(struct wiphy *wiphy, struct wireless_dev *wdev) -{ - int ret = 0; - int clear_flag = 0; - unsigned long flags = 0; - struct net_device *ndev = NULL; - extern struct wl_priv *wlcfg_drv_priv; - struct wl_priv *wl = wlcfg_drv_priv; - - if (!wl || !wdev) - return; - - WL_TRACE(("Enter\n")); - - ndev = wdev_to_wlc_ndev(wdev, wl); - - spin_lock_irqsave(&wl->cfgdrv_lock, flags); - if (wl->scan_request && wl->scan_request->wdev == wdev) { - cfg80211_scan_done(wl->scan_request, true); - wl->scan_request = NULL; - clear_flag = 1; - } - spin_unlock_irqrestore(&wl->cfgdrv_lock, flags); - - if (clear_flag) - wl_clr_drv_status(wl, SCANNING, ndev); - - ret = wl_cfgp2p_disable_discovery(wl); - if (unlikely(ret < 0)) { - CFGP2P_ERR(("P2P disable discovery failed, ret=%d\n", ret)); - goto exit; - } - - p2p_on(wl) = false; - - CFGP2P_DBG(("P2P interface stopped\n")); - -exit: - return; -} - -int -wl_cfgp2p_del_p2p_disc_if(struct wireless_dev *wdev) -{ - extern struct wl_priv *wlcfg_drv_priv; - struct wl_priv *wl = wlcfg_drv_priv; - - if (!wdev) - return -EINVAL; - - WL_TRACE(("Enter\n")); - - cfg80211_unregister_wdev(wdev); - - kfree(wdev); - - wl->p2p_wdev = NULL; - - CFGP2P_ERR(("P2P interface unregistered\n")); - - return 0; -} -#endif /* WL_CFG80211_P2P_DEV_IF */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/wl_cfgp2p.h linux-sunxi-new/drivers/net/wireless/bcmdhd/wl_cfgp2p.h --- linux-sunxi/drivers/net/wireless/bcmdhd/wl_cfgp2p.h 2014-01-27 01:30:30.100433249 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/wl_cfgp2p.h 2014-02-15 00:43:44.791014047 +0100 @@ -1,7 +1,7 @@ /* * Linux cfgp2p driver * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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 415640 2013-07-31 02:43:28Z $ + * $Id: wl_cfgp2p.h 368091 2012-11-12 04:28:31Z $ */ #ifndef _wl_cfgp2p_h_ #define _wl_cfgp2p_h_ @@ -43,17 +43,6 @@ typedef enum { P2PAPI_BSSCFG_MAX } p2p_bsscfg_type_t; -typedef enum { - P2P_SCAN_PURPOSE_MIN, - P2P_SCAN_SOCIAL_CHANNEL, /* scan for social channel */ - P2P_SCAN_AFX_PEER_NORMAL, /* scan for action frame search */ - P2P_SCAN_AFX_PEER_REDUCED, /* scan for action frame search with short time */ - P2P_SCAN_DURING_CONNECTED, /* scan during connected status */ - P2P_SCAN_CONNECT_TRY, /* scan for connecting */ - P2P_SCAN_NORMAL, /* scan during not-connected status */ - P2P_SCAN_PURPOSE_MAX -} p2p_scan_purpose_t; - /* vendor ies max buffer length for probe response or beacon */ #define VNDR_IES_MAX_BUF_LEN 1400 /* normal vendor ies buffer length */ @@ -83,13 +72,12 @@ struct p2p_bss { struct p2p_info { bool on; /* p2p on/off switch */ bool scan; - int16 search_state; bool vif_created; s8 vir_ifname[IFNAMSIZ]; unsigned long status; struct ether_addr dev_addr; struct ether_addr int_addr; - struct p2p_bss bss[P2PAPI_BSSCFG_MAX]; + struct p2p_bss bss_idx[P2PAPI_BSSCFG_MAX]; struct timer_list listen_timer; wl_p2p_sched_t noa; wl_p2p_ops_t ops; @@ -127,11 +115,11 @@ enum wl_cfgp2p_status { }; -#define wl_to_p2p_bss_ndev(wl, type) ((wl)->p2p->bss[type].dev) -#define wl_to_p2p_bss_bssidx(wl, type) ((wl)->p2p->bss[type].bssidx) -#define wl_to_p2p_bss_saved_ie(wl, type) ((wl)->p2p->bss[type].saved_ie) -#define wl_to_p2p_bss_private(wl, type) ((wl)->p2p->bss[type].private_data) -#define wl_to_p2p_bss(wl, type) ((wl)->p2p->bss[type]) +#define wl_to_p2p_bss_ndev(wl, type) ((wl)->p2p->bss_idx[type].dev) +#define wl_to_p2p_bss_bssidx(wl, type) ((wl)->p2p->bss_idx[type].bssidx) +#define wl_to_p2p_bss_saved_ie(wl, type) ((wl)->p2p->bss_idx[type].saved_ie) +#define wl_to_p2p_bss_private(wl, 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, \ &(wl)->p2p->status)) #define wl_set_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? 0 : set_bit(WLP2P_STATUS_ ## stat, \ @@ -149,7 +137,6 @@ enum wl_cfgp2p_status { #define CFGP2P_ERROR_TEXT "CFGP2P-ERROR) " - #define CFGP2P_ERR(args) \ do { \ if (wl_dbg_level & WL_DBG_ERR) { \ @@ -167,7 +154,7 @@ enum wl_cfgp2p_status { #define CFGP2P_DBG(args) \ do { \ if (wl_dbg_level & WL_DBG_DBG) { \ - printk(KERN_DEBUG "CFGP2P-DEBUG) %s :", __func__); \ + printk(KERN_INFO "CFGP2P-DEBUG) %s :", __func__); \ printk args; \ } \ } while (0) @@ -175,7 +162,7 @@ enum wl_cfgp2p_status { #define CFGP2P_ACTION(args) \ do { \ if (wl_dbg_level & WL_DBG_P2P_ACTION) { \ - printk(KERN_DEBUG "CFGP2P-ACTION) %s :", __func__); \ + printk(KERN_INFO "CFGP2P-ACTION) %s :", __func__); \ printk args; \ } \ } while (0) @@ -187,27 +174,6 @@ enum wl_cfgp2p_status { timer->data = (unsigned long) wl; \ add_timer(timer); \ } while (0); - -#if !defined(WL_CFG80211_P2P_DEV_IF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) -#define WL_CFG80211_P2P_DEV_IF -#endif /* !WL_CFG80211_P2P_DEV_IF && (LINUX_VERSION >= VERSION(3, 8, 0)) */ - -#if defined(WL_ENABLE_P2P_IF) && (defined(WL_CFG80211_P2P_DEV_IF) || \ - (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))) -#error Disable 'WL_ENABLE_P2P_IF', if 'WL_CFG80211_P2P_DEV_IF' is enabled \ - or kernel version is 3.8.0 or above -#endif /* WL_ENABLE_P2P_IF && (WL_CFG80211_P2P_DEV_IF || (LINUX_VERSION >= VERSION(3, 8, 0))) */ - -#if !defined(WLP2P) && (defined(WL_ENABLE_P2P_IF) || defined(WL_CFG80211_P2P_DEV_IF)) -#error WLP2P not defined -#endif - -#if defined(WL_CFG80211_P2P_DEV_IF) -#define bcm_struct_cfgdev struct wireless_dev -#else -#define bcm_struct_cfgdev struct net_device -#endif /* WL_CFG80211_P2P_DEV_IF */ - extern void wl_cfgp2p_listen_expired(unsigned long data); extern bool @@ -216,10 +182,8 @@ extern bool wl_cfgp2p_is_p2p_action(void *frame, u32 frame_len); extern bool wl_cfgp2p_is_gas_action(void *frame, u32 frame_len); -extern bool -wl_cfgp2p_find_gas_subtype(u8 subtype, u8* data, u32 len); extern void -wl_cfgp2p_print_actframe(bool tx, void *frame, u32 frame_len, u32 channel); +wl_cfgp2p_print_actframe(bool tx, void *frame, u32 frame_len); extern s32 wl_cfgp2p_init_priv(struct wl_priv *wl); extern void @@ -251,12 +215,11 @@ wl_cfgp2p_disable_discovery(struct wl_pr extern s32 wl_cfgp2p_escan(struct wl_priv *wl, struct net_device *dev, u16 active, u32 num_chans, u16 *channels, - s32 search_state, u16 action, u32 bssidx, struct ether_addr *tx_dst_addr, - p2p_scan_purpose_t p2p_scan_purpose); + s32 search_state, u16 action, u32 bssidx); extern s32 wl_cfgp2p_act_frm_search(struct wl_priv *wl, struct net_device *ndev, - s32 bssidx, s32 channel, struct ether_addr *tx_dst_addr); + s32 bssidx, s32 channel); extern wpa_ie_fixed_t * wl_cfgp2p_find_wpaie(u8 *parse, u32 len); @@ -276,16 +239,14 @@ extern s32 wl_cfgp2p_clear_management_ie(struct wl_priv *wl, s32 bssidx); extern s32 -wl_cfgp2p_find_idx(struct wl_priv *wl, struct net_device *ndev, s32 *index); +wl_cfgp2p_find_idx(struct wl_priv *wl, struct net_device *ndev); extern struct net_device * wl_cfgp2p_find_ndev(struct wl_priv *wl, s32 bssidx); -extern s32 -wl_cfgp2p_find_type(struct wl_priv *wl, s32 bssidx, s32 *type); extern s32 -wl_cfgp2p_listen_complete(struct wl_priv *wl, bcm_struct_cfgdev *cfgdev, - const wl_event_msg_t *e, void *data); +wl_cfgp2p_listen_complete(struct wl_priv *wl, struct net_device *ndev, + const wl_event_msg_t *e, void *data); extern s32 wl_cfgp2p_discover_listen(struct wl_priv *wl, s32 channel, u32 duration_ms); @@ -293,9 +254,8 @@ extern s32 wl_cfgp2p_discover_enable_search(struct wl_priv *wl, u8 enable); extern s32 -wl_cfgp2p_action_tx_complete(struct wl_priv *wl, bcm_struct_cfgdev *cfgdev, - const wl_event_msg_t *e, void *data); - +wl_cfgp2p_action_tx_complete(struct wl_priv *wl, struct net_device *ndev, + const wl_event_msg_t *e, void *data); extern s32 wl_cfgp2p_tx_action_frame(struct wl_priv *wl, struct net_device *dev, wl_af_params_t *af_params, s32 bssidx); @@ -331,9 +291,6 @@ wl_cfgp2p_set_p2p_ps(struct wl_priv *wl, extern u8 * wl_cfgp2p_retreive_p2pattrib(void *buf, u8 element_id); -extern u8* -wl_cfgp2p_find_attrib_in_all_p2p_Ies(u8 *parse, u32 len, u32 attrib); - extern u8 * wl_cfgp2p_retreive_p2p_dev_addr(wl_bss_info_t *bi, u32 bi_length); @@ -346,20 +303,6 @@ wl_cfgp2p_unregister_ndev(struct wl_priv extern bool wl_cfgp2p_is_ifops(const struct net_device_ops *if_ops); -#if defined(WL_CFG80211_P2P_DEV_IF) -extern struct wireless_dev * -wl_cfgp2p_add_p2p_disc_if(void); - -extern int -wl_cfgp2p_start_p2p_device(struct wiphy *wiphy, struct wireless_dev *wdev); - -extern void -wl_cfgp2p_stop_p2p_device(struct wiphy *wiphy, struct wireless_dev *wdev); - -extern int -wl_cfgp2p_del_p2p_disc_if(struct wireless_dev *wdev); -#endif /* WL_CFG80211_P2P_DEV_IF */ - /* WiFi Direct */ #define SOCIAL_CHAN_1 1 #define SOCIAL_CHAN_2 6 @@ -375,16 +318,20 @@ wl_cfgp2p_del_p2p_disc_if(struct wireles #define WL_P2P_TEMP_CHAN 11 /* If the provision discovery is for JOIN operations, - * or the device discoverablity frame is destined to GO * then we need not do an internal scan to find GO. */ -#define IS_ACTPUB_WITHOUT_GROUP_ID(p2p_ie, len) \ +#define IS_PROV_DISC_WITHOUT_GROUP_ID(p2p_ie, len) \ (wl_cfgp2p_retreive_p2pattrib(p2p_ie, P2P_SEID_GROUP_ID) == NULL) #define IS_GAS_REQ(frame, len) (wl_cfgp2p_is_gas_action(frame, len) && \ ((frame->action == P2PSD_ACTION_ID_GAS_IREQ) || \ (frame->action == P2PSD_ACTION_ID_GAS_CREQ))) - +#define IS_P2P_PUB_ACT_REQ(frame, p2p_ie, len) \ + (wl_cfgp2p_is_pub_action(frame, len) && \ + ((frame->subtype == P2P_PAF_GON_REQ) || \ + (frame->subtype == P2P_PAF_INVITE_REQ) || \ + ((frame->subtype == P2P_PAF_PROVDIS_REQ) && \ + IS_PROV_DISC_WITHOUT_GROUP_ID(p2p_ie, len)))) #define IS_P2P_PUB_ACT_RSP_SUBTYPE(subtype) ((subtype == P2P_PAF_GON_RSP) || \ ((subtype == P2P_PAF_GON_CONF) || \ (subtype == P2P_PAF_INVITE_RSP) || \ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/wl_dbg.h linux-sunxi-new/drivers/net/wireless/bcmdhd/wl_dbg.h --- linux-sunxi/drivers/net/wireless/bcmdhd/wl_dbg.h 2014-01-27 01:30:30.107433391 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/wl_dbg.h 2014-02-15 00:43:44.795014136 +0100 @@ -2,7 +2,7 @@ * Minimal debug/trace/assert driver definitions for * Broadcom 802.11 Networking Adapter. * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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: wl_dbg.h 376019 2012-12-21 01:00:06Z $ + * $Id: wl_dbg.h 326635 2012-04-10 03:15:29Z $ */ diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/wldev_common.c linux-sunxi-new/drivers/net/wireless/bcmdhd/wldev_common.c --- linux-sunxi/drivers/net/wireless/bcmdhd/wldev_common.c 2014-01-27 01:30:30.108433411 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/wldev_common.c 2014-02-15 00:43:44.795014136 +0100 @@ -1,7 +1,7 @@ /* * Common function shared by Linux WEXT, cfg80211 and p2p drivers * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -32,12 +32,12 @@ #include #include -#define htod32(i) (i) -#define htod16(i) (i) -#define dtoh32(i) (i) -#define dtoh16(i) (i) -#define htodchanspec(i) (i) -#define dtohchanspec(i) (i) +#define htod32(i) i +#define htod16(i) i +#define dtoh32(i) i +#define dtoh16(i) i +#define htodchanspec(i) i +#define dtohchanspec(i) i #define WLDEV_ERROR(args) \ do { \ @@ -109,7 +109,6 @@ s32 wldev_iovar_setbuf( ret = wldev_ioctl(dev, WLC_SET_VAR, buf, iovar_len, TRUE); else ret = BCME_BUFTOOSHORT; - if (buf_sync) mutex_unlock(buf_sync); return ret; @@ -336,7 +335,7 @@ int wldev_set_band( } int wldev_set_country( - struct net_device *dev, char *country_code, bool notify, bool user_enforced) + struct net_device *dev, char *country_code) { int error = -1; wl_country_t cspec = {{0}, 0, {0}}; @@ -346,26 +345,20 @@ int wldev_set_country( if (!country_code) return error; - bzero(&scbval, sizeof(scb_val_t)); - error = wldev_iovar_getbuf(dev, "country", NULL, 0, &cspec, sizeof(cspec), NULL); - if (error < 0) { + error = wldev_iovar_getbuf(dev, "country", &cspec, sizeof(cspec), + smbuf, sizeof(smbuf), NULL); + if (error < 0) WLDEV_ERROR(("%s: get country failed = %d\n", __FUNCTION__, error)); - return error; - } if ((error < 0) || - (strncmp(country_code, cspec.country_abbrev, WLC_CNTRY_BUF_SZ) != 0)) { - - if (user_enforced) { - bzero(&scbval, sizeof(scb_val_t)); - error = wldev_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t), true); - if (error < 0) { - WLDEV_ERROR(("%s: set country failed due to Disassoc error %d\n", - __FUNCTION__, error)); - return error; - } + (strncmp(country_code, smbuf, WLC_CNTRY_BUF_SZ) != 0)) { + bzero(&scbval, sizeof(scb_val_t)); + error = wldev_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t), true); + if (error < 0) { + WLDEV_ERROR(("%s: set country failed due to Disassoc error %d\n", + __FUNCTION__, error)); + return error; } - cspec.rev = -1; memcpy(cspec.country_abbrev, country_code, WLC_CNTRY_BUF_SZ); memcpy(cspec.ccode, country_code, WLC_CNTRY_BUF_SZ); @@ -377,7 +370,7 @@ int wldev_set_country( __FUNCTION__, country_code, cspec.ccode, cspec.rev)); return error; } - dhd_bus_country_set(dev, &cspec, notify); + dhd_bus_country_set(dev, &cspec); WLDEV_ERROR(("%s: set country for %s as %s rev %d\n", __FUNCTION__, country_code, cspec.ccode, cspec.rev)); } diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/wldev_common.h linux-sunxi-new/drivers/net/wireless/bcmdhd/wldev_common.h --- linux-sunxi/drivers/net/wireless/bcmdhd/wldev_common.h 2014-01-27 01:30:30.108433411 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/wldev_common.h 2014-02-15 00:43:44.795014136 +0100 @@ -1,7 +1,7 @@ /* * Common function shared by Linux WEXT, cfg80211 and p2p drivers * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -84,10 +84,9 @@ s32 wldev_iovar_setint_bsscfg( struct net_device *dev, s8 *iovar, s32 val, s32 bssidx); extern void get_customized_country_code(char *country_iso_code, wl_country_t *cspec); -extern void dhd_bus_country_set(struct net_device *dev, wl_country_t *cspec, bool notify); +extern void dhd_bus_country_set(struct net_device *dev, wl_country_t *cspec); extern void dhd_bus_band_set(struct net_device *dev, uint band); -extern int wldev_set_country(struct net_device *dev, char *country_code, bool notify, - bool user_enforced); +extern int wldev_set_country(struct net_device *dev, char *country_code); 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); diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/wl_iw.c linux-sunxi-new/drivers/net/wireless/bcmdhd/wl_iw.c --- linux-sunxi/drivers/net/wireless/bcmdhd/wl_iw.c 2014-01-27 01:30:30.100433249 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/wl_iw.c 2014-02-15 00:43:44.791014047 +0100 @@ -1,7 +1,7 @@ /* * Linux Wireless Extensions support * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 @@ -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_iw.c 396420 2013-04-12 06:55:45Z $ + * $Id: wl_iw.c 352251 2012-08-22 06:08:38Z $ */ #if defined(USE_IW) @@ -38,6 +38,7 @@ #include #include + typedef const struct si_pub si_t; #include @@ -46,31 +47,6 @@ typedef const struct si_pub si_t; #include -/* Broadcom extensions to WEXT, linux upstream has obsoleted WEXT */ -#ifndef IW_AUTH_KEY_MGMT_FT_802_1X -#define IW_AUTH_KEY_MGMT_FT_802_1X 0x04 -#endif - -#ifndef IW_AUTH_KEY_MGMT_FT_PSK -#define IW_AUTH_KEY_MGMT_FT_PSK 0x08 -#endif - -#ifndef IW_ENC_CAPA_FW_ROAM_ENABLE -#define IW_ENC_CAPA_FW_ROAM_ENABLE 0x00000020 -#endif - - -/* FC9: wireless.h 2.6.25-14.fc9.i686 is missing these, even though WIRELESS_EXT is set to latest - * version 22. - */ -#ifndef IW_ENCODE_ALG_PMK -#define IW_ENCODE_ALG_PMK 4 -#endif -#ifndef IW_ENC_CAPA_4WAY_HANDSHAKE -#define IW_ENC_CAPA_4WAY_HANDSHAKE 0x00000010 -#endif -/* End FC9. */ - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) #include #endif @@ -82,7 +58,7 @@ tsk_ctl_t ap_eth_ctl; /* apsta AP netde 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; +uint iw_msg_level = WL_ERROR_VAL; #define MAX_WLIW_IOCTL_LEN 1024 @@ -103,10 +79,7 @@ extern int dhd_wait_pend8021x(struct net #endif /* WIRELESS_EXT < 19 */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) -#define DAEMONIZE(a) -#elif ((LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)) && \ - (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) #define DAEMONIZE(a) daemonize(a); \ allow_signal(SIGKILL); \ allow_signal(SIGTERM); @@ -431,9 +404,6 @@ wl_iw_set_pm( error = dev_wlc_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm)); return error; } - -#if WIRELESS_EXT > 17 -#endif /* WIRELESS_EXT > 17 */ #endif /* WIRELESS_EXT > 12 */ int @@ -684,7 +654,6 @@ wl_iw_get_range( {14, 29, 43, 58, 87, 116, 130, 144}, {27, 54, 81, 108, 162, 216, 243, 270}, {30, 60, 90, 120, 180, 240, 270, 300}}; - int fbt_cap = 0; WL_TRACE(("%s: SIOCGIWRANGE\n", dev->name)); @@ -740,18 +709,15 @@ wl_iw_get_range( range->num_bitrates = rateset.count; for (i = 0; i < rateset.count && i < IW_MAX_BITRATES; i++) range->bitrate[i] = (rateset.rates[i] & 0x7f) * 500000; /* convert to bps */ - if ((error = dev_wlc_intvar_get(dev, "nmode", &nmode))) - return error; + dev_wlc_intvar_get(dev, "nmode", &nmode); if ((error = dev_wlc_ioctl(dev, WLC_GET_PHYTYPE, &phytype, sizeof(phytype)))) return error; + if (nmode == 1 && ((phytype == WLC_PHY_TYPE_SSN) || (phytype == WLC_PHY_TYPE_LCN) || (phytype == WLC_PHY_TYPE_LCN40))) { - if ((error = dev_wlc_intvar_get(dev, "mimo_bw_cap", &bw_cap))) - return error; - if ((error = dev_wlc_intvar_get(dev, "sgi_tx", &sgi_tx))) - return error; - if ((error = dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(channel_info_t)))) - return error; + 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 || @@ -769,7 +735,6 @@ wl_iw_get_range( nrate_list2copy = 3; } range->num_bitrates += 8; - ASSERT(range->num_bitrates < IW_MAX_BITRATES); for (k = 0; i < range->num_bitrates; k++, i++) { /* convert to bps */ range->bitrate[i] = (nrate_list[nrate_list2copy][k]) * 500000; @@ -840,19 +805,10 @@ wl_iw_get_range( range->enc_capa |= IW_ENC_CAPA_CIPHER_TKIP; range->enc_capa |= IW_ENC_CAPA_CIPHER_CCMP; range->enc_capa |= IW_ENC_CAPA_WPA2; - - /* Determine driver FBT capability. */ - if (dev_wlc_intvar_get(dev, "fbt_cap", &fbt_cap) == 0) { - if (fbt_cap == WLC_FBT_CAP_DRV_4WAY_AND_REASSOC) { - /* Tell the host (e.g. wpa_supplicant) to let driver do the handshake */ - range->enc_capa |= IW_ENC_CAPA_4WAY_HANDSHAKE; - } - } - -#ifdef BCMFW_ROAM_ENABLE_WEXT - /* Advertise firmware roam capability to the external supplicant */ - range->enc_capa |= IW_ENC_CAPA_FW_ROAM_ENABLE; -#endif /* BCMFW_ROAM_ENABLE_WEXT */ +#if (defined(BCMSUP_PSK) && defined(WLFBT)) + /* Tell the host (e.g. wpa_supplicant) to let us do the handshake */ + range->enc_capa |= IW_ENC_CAPA_4WAY_HANDSHAKE; +#endif /* (defined (BCMSUP_PSK) && defined(WLFBT)) */ /* Event capability (kernel) */ IW_EVENT_CAPA_SET_KERNEL(range->event_capa); @@ -1338,12 +1294,14 @@ wl_iw_handle_scanresults_ies(char **even } ptr = ((uint8 *)bi) + sizeof(wl_bss_info_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 /* WLFBT */ while ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_WPA_ID))) { /* look for WPS IE */ @@ -2347,6 +2305,7 @@ wl_iw_set_encodeext( return error; } } +#if (defined(BCMSUP_PSK) && defined(WLFBT)) /* This case is used to allow an external 802.1x supplicant * to pass the PMK to the in-driver supplicant for use in * the 4-way handshake. @@ -2372,6 +2331,7 @@ wl_iw_set_encodeext( if (error) return error; } +#endif /* (defined (BCMSUP_PSK) && defined(WLFBT)) */ else { if (iwe->key_len > sizeof(key.data)) @@ -2573,8 +2533,7 @@ wl_iw_set_wpaauth( break; case IW_AUTH_CIPHER_PAIRWISE: - case IW_AUTH_CIPHER_GROUP: { - int fbt_cap = 0; + case IW_AUTH_CIPHER_GROUP: if (paramid == IW_AUTH_CIPHER_PAIRWISE) { iw->pwsec = paramval; @@ -2611,44 +2570,33 @@ wl_iw_set_wpaauth( if ((error = dev_wlc_intvar_set(dev, "wsec", val))) return error; - - /* Ensure in-dongle supplicant is turned on when FBT wants to do the 4-way - * handshake. - */ - if (dev_wlc_intvar_get(dev, "fbt_cap", &fbt_cap) == 0) { - if (fbt_cap == WLC_FBT_CAP_DRV_4WAY_AND_REASSOC) { - 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; - } - } +#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 /* WLFBT */ 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_FT_PSK | IW_AUTH_KEY_MGMT_PSK)) + if (paramval & IW_AUTH_KEY_MGMT_PSK) val = WPA_AUTH_PSK; else val = WPA_AUTH_UNSPECIFIED; - if (paramval & (IW_AUTH_KEY_MGMT_FT_802_1X | IW_AUTH_KEY_MGMT_FT_PSK)) - val |= WPA2_AUTH_FT; } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) { - if (paramval & (IW_AUTH_KEY_MGMT_FT_PSK | IW_AUTH_KEY_MGMT_PSK)) + if (paramval & IW_AUTH_KEY_MGMT_PSK) val = WPA2_AUTH_PSK; else val = WPA2_AUTH_UNSPECIFIED; - if (paramval & (IW_AUTH_KEY_MGMT_FT_802_1X | IW_AUTH_KEY_MGMT_FT_PSK)) - val |= WPA2_AUTH_FT; } WL_TRACE(("%s: %d: setting wpa_auth to %d\n", __FUNCTION__, __LINE__, val)); if ((error = dev_wlc_intvar_set(dev, "wpa_auth", val))) @@ -2913,19 +2861,13 @@ static const iw_handler wl_iw_handler[] enum { WL_IW_SET_LEDDC = SIOCIWFIRSTPRIV, WL_IW_SET_VLANMODE, - WL_IW_SET_PM, -#if WIRELESS_EXT > 17 -#endif /* WIRELESS_EXT > 17 */ - WL_IW_SET_LAST + WL_IW_SET_PM }; static iw_handler wl_iw_priv_handler[] = { wl_iw_set_leddc, wl_iw_set_vlanmode, - wl_iw_set_pm, -#if WIRELESS_EXT > 17 -#endif /* WIRELESS_EXT > 17 */ - NULL + wl_iw_set_pm }; static struct iw_priv_args wl_iw_priv_args[] = { @@ -2946,10 +2888,7 @@ static struct iw_priv_args wl_iw_priv_ar IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_pm" - }, -#if WIRELESS_EXT > 17 -#endif /* WIRELESS_EXT > 17 */ - { 0, 0, 0, { 0 } } + } }; const struct iw_handler_def wl_iw_handler_def = @@ -3558,7 +3497,7 @@ static void wl_iw_send_scan_complete(isc memset(&wrqu, 0, sizeof(wrqu)); - /* wext expects to get no data for SIOCGIWSCAN Event */ + /* wext expects to get no data for SIOCGIWSCAN Event */ wireless_send_event(iscan->dev, SIOCGIWSCAN, &wrqu, NULL); } diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/wl_iw.h linux-sunxi-new/drivers/net/wireless/bcmdhd/wl_iw.h --- linux-sunxi/drivers/net/wireless/bcmdhd/wl_iw.h 2014-01-27 01:30:30.101433269 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/wl_iw.h 2014-02-15 00:43:44.792014069 +0100 @@ -1,7 +1,7 @@ /* * Linux Wireless Extensions support * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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 diff -rupN linux-sunxi/drivers/net/wireless/bcmdhd/wl_linux_mon.c linux-sunxi-new/drivers/net/wireless/bcmdhd/wl_linux_mon.c --- linux-sunxi/drivers/net/wireless/bcmdhd/wl_linux_mon.c 2014-01-27 01:30:30.109433432 +0100 +++ linux-sunxi-new/drivers/net/wireless/bcmdhd/wl_linux_mon.c 2014-02-15 00:43:44.795014136 +0100 @@ -1,7 +1,7 @@ /* * Broadcom Dongle Host Driver (DHD), Linux monitor network interface * - * Copyright (C) 1999-2013, Broadcom Corporation + * 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