Signed-off-by: Fabio Berton <fabio.ber...@ossystems.com.br> --- ...LLVMLinux-use-static-inline-in-ARM-ftrace.patch | 49 ++ ...nux-Change-extern-inline-to-static-inline.patch | 58 ++ .../Set-dr_mode-to-otg.patch | 29 + ...flush-management-symbols-when-multi-cache.patch | 32 + ...initial-device-tree-support-to-the-sdio-m.patch | 132 ++++ .../0003-wlcore-add-mac-override-parameter.patch | 92 +++ .../linux/linux-variscite-3.14.28/defconfig | 462 +++++++++++++ ...et-wl-rx_filter_enabled-to-zero-after-rec.patch | 88 +++ ...el-Tx-watchdog-on-suspend-and-rearm-on-fi.patch | 88 +++ ...wlcore-block-read-writes-to-FW-during-ELP.patch | 46 ++ ...don-t-start-mac80211-PS-on-non-peer-HLIDs.patch | 38 + ...wl12xx-wl18xx-simplify-fw_status-handling.patch | 763 +++++++++++++++++++++ ...-wl12xx-wl18xx-configure-num_links-per-hw.patch | 375 ++++++++++ ...12xx-wl18xx-configure-max_stations-per-hw.patch | 132 ++++ ...xx-wl18xx-configure-iface_combinations-pe.patch | 193 ++++++ ...18xx-move-to-new-firmware-wl18xx-fw-3.bin.patch | 226 ++++++ ...ore-send-EAPOL-frames-with-voice-priority.patch | 49 ++ ...on-t-stop-sched_scan-on-interface-removal.patch | 35 + ...wlcore-wl18xx-allow-CCK-rates-for-AP-mode.patch | 61 ++ ...don-t-handle-unsetting-of-default-wep-key.patch | 38 + ...ider-multiple-APs-when-checking-active_li.patch | 64 ++ ...ecrease-warning-verbosity-during-recovery.patch | 54 ++ ...016-wlcore-increase-timeout-to-5000-msecs.patch | 31 + ...le-beacon-filtering-only-after-receiving-.patch | 86 +++ ...dd-support-for-STA-CSA-with-chan-contexts.patch | 32 + .../wifi/0019-wlcore-use-correct-LAA-bit.patch | 30 + ...copy-paste-bug-assign-from-src-struct-not.patch | 28 + recipes-kernel/linux/linux-variscite_3.14.28.bb | 46 ++ 28 files changed, 3357 insertions(+) create mode 100644 recipes-kernel/linux/linux-variscite-3.14.28/0001-ARM-8158-LLVMLinux-use-static-inline-in-ARM-ftrace.patch create mode 100644 recipes-kernel/linux/linux-variscite-3.14.28/0001-ARM-LLVMLinux-Change-extern-inline-to-static-inline.patch create mode 100644 recipes-kernel/linux/linux-variscite-3.14.28/Set-dr_mode-to-otg.patch create mode 100644 recipes-kernel/linux/linux-variscite-3.14.28/arm-Export-cache-flush-management-symbols-when-multi-cache.patch create mode 100644 recipes-kernel/linux/linux-variscite-3.14.28/boundarydevices/0002-wlcore-add-initial-device-tree-support-to-the-sdio-m.patch create mode 100644 recipes-kernel/linux/linux-variscite-3.14.28/boundarydevices/0003-wlcore-add-mac-override-parameter.patch create mode 100644 recipes-kernel/linux/linux-variscite-3.14.28/defconfig create mode 100644 recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0001-wlcore-memset-wl-rx_filter_enabled-to-zero-after-rec.patch create mode 100644 recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0002-wlcore-cancel-Tx-watchdog-on-suspend-and-rearm-on-fi.patch create mode 100644 recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0003-wlcore-block-read-writes-to-FW-during-ELP.patch create mode 100644 recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0004-wlcore-AP-don-t-start-mac80211-PS-on-non-peer-HLIDs.patch create mode 100644 recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0005-wlcore-wl12xx-wl18xx-simplify-fw_status-handling.patch create mode 100644 recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0006-wlcore-wl12xx-wl18xx-configure-num_links-per-hw.patch create mode 100644 recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0007-wlcore-wl12xx-wl18xx-configure-max_stations-per-hw.patch create mode 100644 recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0008-wlcore-wl12xx-wl18xx-configure-iface_combinations-pe.patch create mode 100644 recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0009-wl18xx-move-to-new-firmware-wl18xx-fw-3.bin.patch create mode 100644 recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0010-wlcore-send-EAPOL-frames-with-voice-priority.patch create mode 100644 recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0011-wlcore-don-t-stop-sched_scan-on-interface-removal.patch create mode 100644 recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0012-wlcore-wl18xx-allow-CCK-rates-for-AP-mode.patch create mode 100644 recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0013-wlcore-don-t-handle-unsetting-of-default-wep-key.patch create mode 100644 recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0014-wlcore-consider-multiple-APs-when-checking-active_li.patch create mode 100644 recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0015-wlcore-decrease-warning-verbosity-during-recovery.patch create mode 100644 recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0016-wlcore-increase-timeout-to-5000-msecs.patch create mode 100644 recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0017-wlcore-enable-beacon-filtering-only-after-receiving-.patch create mode 100644 recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0018-wlcore-add-support-for-STA-CSA-with-chan-contexts.patch create mode 100644 recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0019-wlcore-use-correct-LAA-bit.patch create mode 100644 recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0020-wlcore-fix-copy-paste-bug-assign-from-src-struct-not.patch create mode 100644 recipes-kernel/linux/linux-variscite_3.14.28.bb
diff --git a/recipes-kernel/linux/linux-variscite-3.14.28/0001-ARM-8158-LLVMLinux-use-static-inline-in-ARM-ftrace.patch b/recipes-kernel/linux/linux-variscite-3.14.28/0001-ARM-8158-LLVMLinux-use-static-inline-in-ARM-ftrace.patch new file mode 100644 index 0000000..348490a --- /dev/null +++ b/recipes-kernel/linux/linux-variscite-3.14.28/0001-ARM-8158-LLVMLinux-use-static-inline-in-ARM-ftrace.patch @@ -0,0 +1,49 @@ +From aeea3592a13bf12861943e44fc48f1f270941f8d Mon Sep 17 00:00:00 2001 +From: Behan Webster <beh...@converseincode.com> +Date: Wed, 24 Sep 2014 01:06:46 +0100 +Subject: ARM: 8158/1: LLVMLinux: use static inline in ARM ftrace.h + +With compilers which follow the C99 standard (like modern versions of gcc and +clang), "extern inline" does the wrong thing (emits code for an externally +linkable version of the inline function). In this case using static inline +and removing the NULL version of return_address in return_address.c does +the right thing. + +Signed-off-by: Behan Webster <beh...@converseincode.com> +Reviewed-by: Mark Charlebois <charl...@gmail.com> +Acked-by: Steven Rostedt <rost...@goodmis.org> +Signed-off-by: Russell King <rmk+ker...@arm.linux.org.uk> + +diff --git a/arch/arm/include/asm/ftrace.h b/arch/arm/include/asm/ftrace.h +index 39eb16b..bfe2a2f 100644 +--- a/arch/arm/include/asm/ftrace.h ++++ b/arch/arm/include/asm/ftrace.h +@@ -45,7 +45,7 @@ void *return_address(unsigned int); + + #else + +-extern inline void *return_address(unsigned int level) ++static inline void *return_address(unsigned int level) + { + return NULL; + } +diff --git a/arch/arm/kernel/return_address.c b/arch/arm/kernel/return_address.c +index fafedd8..f6aa84d 100644 +--- a/arch/arm/kernel/return_address.c ++++ b/arch/arm/kernel/return_address.c +@@ -63,11 +63,6 @@ void *return_address(unsigned int level) + #warning "TODO: return_address should use unwind tables" + #endif + +-void *return_address(unsigned int level) +-{ +- return NULL; +-} +- + #endif /* if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) / else */ + + EXPORT_SYMBOL_GPL(return_address); +-- +cgit v0.10.2 + + diff --git a/recipes-kernel/linux/linux-variscite-3.14.28/0001-ARM-LLVMLinux-Change-extern-inline-to-static-inline.patch b/recipes-kernel/linux/linux-variscite-3.14.28/0001-ARM-LLVMLinux-Change-extern-inline-to-static-inline.patch new file mode 100644 index 0000000..0247313 --- /dev/null +++ b/recipes-kernel/linux/linux-variscite-3.14.28/0001-ARM-LLVMLinux-Change-extern-inline-to-static-inline.patch @@ -0,0 +1,58 @@ +From a2561791169351cbf1ac5ca0c4299a0eef7eca65 Mon Sep 17 00:00:00 2001 +From: Behan Webster <beh...@converseincode.com> +Date: Tue, 3 Sep 2013 22:27:26 -0400 +Subject: [PATCH] ARM: LLVMLinux: Change "extern inline" to "static inline" in + glue-cache.h + +With compilers which follow the C99 standard (like modern versions of gcc and +clang), "extern inline" does the wrong thing (emits code for an externally +linkable version of the inline function). "static inline" is the correct choice +instead. + +Author: Behan Webster <beh...@converseincode.com> +Signed-off-by: Behan Webster <beh...@converseincode.com> +Reviewed-by: Mark Charlebois <charl...@gmail.com> +--- + arch/arm/include/asm/glue-cache.h | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +diff --git a/arch/arm/include/asm/glue-cache.h b/arch/arm/include/asm/glue-cache.h +index c81adc0..a3c24cd 100644 +--- a/arch/arm/include/asm/glue-cache.h ++++ b/arch/arm/include/asm/glue-cache.h +@@ -130,22 +130,22 @@ + #endif + + #ifndef __ASSEMBLER__ +-extern inline void nop_flush_icache_all(void) { } +-extern inline void nop_flush_kern_cache_all(void) { } +-extern inline void nop_flush_kern_cache_louis(void) { } +-extern inline void nop_flush_user_cache_all(void) { } +-extern inline void nop_flush_user_cache_range(unsigned long a, ++static inline void nop_flush_icache_all(void) { } ++static inline void nop_flush_kern_cache_all(void) { } ++static inline void nop_flush_kern_cache_louis(void) { } ++static inline void nop_flush_user_cache_all(void) { } ++static inline void nop_flush_user_cache_range(unsigned long a, + unsigned long b, unsigned int c) { } + +-extern inline void nop_coherent_kern_range(unsigned long a, unsigned long b) { } +-extern inline int nop_coherent_user_range(unsigned long a, ++static inline void nop_coherent_kern_range(unsigned long a, unsigned long b) { } ++static inline int nop_coherent_user_range(unsigned long a, + unsigned long b) { return 0; } +-extern inline void nop_flush_kern_dcache_area(void *a, size_t s) { } ++static inline void nop_flush_kern_dcache_area(void *a, size_t s) { } + +-extern inline void nop_dma_flush_range(const void *a, const void *b) { } ++static inline void nop_dma_flush_range(const void *a, const void *b) { } + +-extern inline void nop_dma_map_area(const void *s, size_t l, int f) { } +-extern inline void nop_dma_unmap_area(const void *s, size_t l, int f) { } ++static inline void nop_dma_map_area(const void *s, size_t l, int f) { } ++static inline void nop_dma_unmap_area(const void *s, size_t l, int f) { } + #endif + + #ifndef MULTI_CACHE +-- +2.1.4 diff --git a/recipes-kernel/linux/linux-variscite-3.14.28/Set-dr_mode-to-otg.patch b/recipes-kernel/linux/linux-variscite-3.14.28/Set-dr_mode-to-otg.patch new file mode 100644 index 0000000..222cb64 --- /dev/null +++ b/recipes-kernel/linux/linux-variscite-3.14.28/Set-dr_mode-to-otg.patch @@ -0,0 +1,29 @@ +From 94daa3c228195488521c06e9df0ccb6c0399aa4e Mon Sep 17 00:00:00 2001 +From: Fabio Berton <fabio.ber...@ossystems.com.br> +Date: Mon, 15 Feb 2016 11:31:39 -0200 +Subject: [PATCH] Set dr_mode to otg + +By default the OTG is configured to be "host". We need to switch dr_mode to +"otg", so OTG will work as device. + + +Signed-off-by: Fabio Berton <fabio.ber...@ossystems.com.br> +--- + arch/arm/boot/dts/imx6qdl-var-som.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/imx6qdl-var-som.dtsi b/arch/arm/boot/dts/imx6qdl-var-som.dtsi +index 6ad3773..8fb1d7e 100755 +--- a/arch/arm/boot/dts/imx6qdl-var-som.dtsi ++++ b/arch/arm/boot/dts/imx6qdl-var-som.dtsi +@@ -971,7 +971,7 @@ + #ifdef VAR_SOM_SOLO_VSC + dr_mode = "otg" ; /* Use "host" if you would like to use the USB0 type A connector (host mode only on VAR-SOM-SOLO) */ + #else +- dr_mode = "host" ; ++ dr_mode = "otg" ; + #endif + status = "okay"; + }; +-- +2.1.4 diff --git a/recipes-kernel/linux/linux-variscite-3.14.28/arm-Export-cache-flush-management-symbols-when-multi-cache.patch b/recipes-kernel/linux/linux-variscite-3.14.28/arm-Export-cache-flush-management-symbols-when-multi-cache.patch new file mode 100644 index 0000000..41be41a --- /dev/null +++ b/recipes-kernel/linux/linux-variscite-3.14.28/arm-Export-cache-flush-management-symbols-when-multi-cache.patch @@ -0,0 +1,32 @@ +From 07c2f624be197c5e1ee0d62f13327fea44446b90 Mon Sep 17 00:00:00 2001 +From: Pantelis Antoniou <pa...@antoniou-consulting.com> +Date: Fri, 4 Jan 2013 00:32:33 +0200 +Subject: [PATCH] arm: Export cache flush management symbols when !MULTI_CACHE + +When compiling a kernel without CONFIG_MULTI_CACHE enabled the +dma access functions end up not being exported. Fix it. + +Signed-off-by: Pantelis Antoniou <pa...@antoniou-consulting.com> +Signed-off-by: Otavio Salvador <ota...@ossystems.com.br> +--- + arch/arm/kernel/setup.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c +index aab70f6..63b310c 100644 +--- a/arch/arm/kernel/setup.c ++++ b/arch/arm/kernel/setup.c +@@ -1089,3 +1089,12 @@ const struct seq_operations cpuinfo_op = { + .stop = c_stop, + .show = c_show + }; ++ ++/* export the cache management functions */ ++#ifndef MULTI_CACHE ++ ++EXPORT_SYMBOL(__glue(_CACHE,_dma_map_area)); ++EXPORT_SYMBOL(__glue(_CACHE,_dma_unmap_area)); ++EXPORT_SYMBOL(__glue(_CACHE,_dma_flush_range)); ++ ++#endif + diff --git a/recipes-kernel/linux/linux-variscite-3.14.28/boundarydevices/0002-wlcore-add-initial-device-tree-support-to-the-sdio-m.patch b/recipes-kernel/linux/linux-variscite-3.14.28/boundarydevices/0002-wlcore-add-initial-device-tree-support-to-the-sdio-m.patch new file mode 100644 index 0000000..4733c67 --- /dev/null +++ b/recipes-kernel/linux/linux-variscite-3.14.28/boundarydevices/0002-wlcore-add-initial-device-tree-support-to-the-sdio-m.patch @@ -0,0 +1,132 @@ +From f82ba890ddfaeaca058c0d6f868ea40a1bb6ae24 Mon Sep 17 00:00:00 2001 +From: Luciano Coelho <coe...@ti.com> +Date: Tue, 25 Jun 2013 13:51:53 +0300 +Subject: [PATCH 1/2] wlcore: add initial device tree support to the sdio + module + +If platform data is not available, try to get the required information +from the device tree. Register an OF match table and parse the +appropriate device tree nodes. + +Parse interrupt property only, for now. + +Signed-off-by: Luciano Coelho <coe...@ti.com> +--- + drivers/net/wireless/ti/wlcore/sdio.c | 70 ++++++++++++++++++++++++++++++++--- + 1 file changed, 64 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c +index 29ef249..53bbb28 100644 +--- a/drivers/net/wireless/ti/wlcore/sdio.c ++++ b/drivers/net/wireless/ti/wlcore/sdio.c +@@ -30,7 +30,7 @@ + #include <linux/mmc/sdio_ids.h> + #include <linux/mmc/card.h> + #include <linux/mmc/host.h> +-#include <linux/gpio.h> ++#include <linux/of_irq.h> + #include <linux/wl12xx.h> + #include <linux/pm_runtime.h> + #include <linux/printk.h> +@@ -214,6 +214,43 @@ static struct wl1271_if_operations sdio_ops = { + .set_block_size = wl1271_sdio_set_block_size, + }; + ++static struct wl12xx_platform_data *wlcore_get_pdata_from_of(struct device *dev) ++{ ++ struct wl12xx_platform_data *pdata; ++ struct device_node *np = dev->of_node; ++ ++ if (!np) { ++ np = of_find_matching_node(NULL, dev->driver->of_match_table); ++ if (!np) { ++ dev_notice(dev, "device tree node not available\n"); ++ pdata = ERR_PTR(-ENODEV); ++ goto out; ++ } ++ } ++ ++ pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); ++ if (!pdata) { ++ dev_err(dev, "can't allocate platform data\n"); ++ pdata = ERR_PTR(-ENODEV); ++ goto out; ++ } ++ ++ pdata->irq = irq_of_parse_and_map(np, 0); ++ if (pdata->irq < 0) { ++ dev_err(dev, "can't get interrupt gpio from the device tree\n"); ++ goto out_free; ++ } ++ pdata->board_ref_clock = WL12XX_REFCLOCK_38; /* 38.4 MHz */ ++ goto out; ++ ++out_free: ++ kfree(pdata); ++ pdata = ERR_PTR(-ENODEV); ++ ++out: ++ return pdata; ++} ++ + static int wl1271_probe(struct sdio_func *func, + const struct sdio_device_id *id) + { +@@ -248,11 +285,23 @@ static int wl1271_probe(struct sdio_func *func, + /* Use block mode for transferring over one block size of data */ + func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE; + ++ /* The pdata allocated here is freed when the device is freed, ++ * so we don't need an additional out label to free it in case ++ * of error further on. ++ */ ++ ++ /* Try to get legacy platform data from the board file */ + pdev_data->pdata = wl12xx_get_platform_data(); + if (IS_ERR(pdev_data->pdata)) { +- ret = PTR_ERR(pdev_data->pdata); +- dev_err(glue->dev, "missing wlan platform data: %d\n", ret); +- goto out_free_glue; ++ dev_info(&func->dev, ++ "legacy platform data not found, trying device tree\n"); ++ ++ pdev_data->pdata = wlcore_get_pdata_from_of(&func->dev); ++ if (IS_ERR(pdev_data->pdata)) { ++ ret = PTR_ERR(pdev_data->pdata); ++ dev_err(&func->dev, "can't get platform data\n"); ++ goto out_free_glue; ++ } + } + + /* if sdio can keep power while host is suspended, enable wow */ +@@ -386,16 +435,25 @@ static const struct dev_pm_ops wl1271_sdio_pm_ops = { + }; + #endif + ++static const struct of_device_id wlcore_sdio_of_match_table[] = { ++ { .compatible = "ti,wilink6" }, ++ { .compatible = "ti,wilink7" }, ++ { .compatible = "ti,wilink8" }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, wlcore_sdio_of_match_table); ++ + static struct sdio_driver wl1271_sdio_driver = { + .name = "wl1271_sdio", + .id_table = wl1271_devices, + .probe = wl1271_probe, + .remove = wl1271_remove, +-#ifdef CONFIG_PM + .drv = { ++#ifdef CONFIG_PM + .pm = &wl1271_sdio_pm_ops, +- }, + #endif ++ .of_match_table = of_match_ptr(wlcore_sdio_of_match_table), ++ }, + }; + + static int __init wl1271_init(void) +-- +1.9.3 + diff --git a/recipes-kernel/linux/linux-variscite-3.14.28/boundarydevices/0003-wlcore-add-mac-override-parameter.patch b/recipes-kernel/linux/linux-variscite-3.14.28/boundarydevices/0003-wlcore-add-mac-override-parameter.patch new file mode 100644 index 0000000..65c4512 --- /dev/null +++ b/recipes-kernel/linux/linux-variscite-3.14.28/boundarydevices/0003-wlcore-add-mac-override-parameter.patch @@ -0,0 +1,92 @@ +From 4dca78d4c66c8bf6440e2fa86c155a1d969f39a6 Mon Sep 17 00:00:00 2001 +From: Troy Kisky <troy.ki...@boundarydevices.com> +Date: Wed, 23 May 2012 18:38:54 -0700 +Subject: [PATCH 2/2] wlcore: add mac override parameter + +Note the cmdline parameter would be wlcore.mac=nn:nn:nn:nn:nn:nn + +This moved since the 3.0.x kernels because of WL12xx restructuring. + +Signed-off-by: Troy Kisky <troy.ki...@boundarydevices.com> + +Conflicts: + drivers/net/wireless/wl12xx/main.c +--- + drivers/net/wireless/ti/wlcore/main.c | 40 ++++++++++++++++++++++++++++++++++- + 1 file changed, 39 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c +index b46b311..b1f5740 100644 +--- a/drivers/net/wireless/ti/wlcore/main.c ++++ b/drivers/net/wireless/ti/wlcore/main.c +@@ -47,6 +47,7 @@ static char *fwlog_param; + static int fwlog_mem_blocks = -1; + static int bug_on_recovery = -1; + static int no_recovery = -1; ++static char *mac_param; + + static void __wl1271_op_remove_interface(struct wl1271 *wl, + struct ieee80211_vif *vif, +@@ -5623,6 +5624,26 @@ out: + return ret; + } + ++static int parse_mac(unsigned char *mac, unsigned char const *str_mac) ++{ ++ int i = 0; ++ char *end; ++ int ret = -EINVAL; ++ ++ for (;;) { ++ mac[i++] = simple_strtoul(str_mac, &end, 16); ++ if (i == 6) { ++ if (!*end || (*end == ' ')) ++ ret = 0; ++ break; ++ } ++ str_mac = end + 1; ++ if ((*end != '-') && (*end != ':')) ++ break; ++ } ++ return ret; ++} ++ + static int wl1271_register_hw(struct wl1271 *wl) + { + int ret; +@@ -5631,7 +5652,21 @@ static int wl1271_register_hw(struct wl1271 *wl) + if (wl->mac80211_registered) + return 0; + +- if (wl->nvs_len >= 12) { ++ if (mac_param){ ++ u8 override_mac[ETH_ALEN]; ++ memset(override_mac, 0, ETH_ALEN); ++ ++ if (0 == parse_mac(override_mac, mac_param)) { ++ oui_addr = override_mac[0] << 16 ++ | override_mac[1] << 8 ++ | override_mac[2]; ++ nic_addr = override_mac[3] << 16 ++ | override_mac[4] << 8 ++ | override_mac[5]; ++ } else ++ pr_err("%s: error parsing mac %s\n", ++ __func__, mac_param); ++ } else if (wl->nvs_len >= 12) { + /* NOTE: The wl->nvs->nvs element must be first, in + * order to simplify the casting, we assume it is at + * the beginning of the wl->nvs structure. +@@ -6198,6 +6233,9 @@ MODULE_PARM_DESC(bug_on_recovery, "BUG() on fw recovery"); + module_param(no_recovery, int, S_IRUSR | S_IWUSR); + MODULE_PARM_DESC(no_recovery, "Prevent HW recovery. FW will remain stuck."); + ++module_param_named(mac, mac_param, charp, S_IRUGO); ++MODULE_PARM_DESC(mac, "mac address override"); ++ + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Luciano Coelho <coe...@ti.com>"); + MODULE_AUTHOR("Juuso Oikarinen <juuso.oikari...@nokia.com>"); +-- +1.9.3 + diff --git a/recipes-kernel/linux/linux-variscite-3.14.28/defconfig b/recipes-kernel/linux/linux-variscite-3.14.28/defconfig new file mode 100644 index 0000000..e345bf8 --- /dev/null +++ b/recipes-kernel/linux/linux-variscite-3.14.28/defconfig @@ -0,0 +1,462 @@ +CONFIG_LOCALVERSION="-1.1.0" +CONFIG_KERNEL_LZO=y +CONFIG_SYSVIPC=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_LOG_BUF_SHIFT=18 +CONFIG_CGROUPS=y +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_EXPERT=y +CONFIG_KALLSYMS_ALL=y +CONFIG_PERF_EVENTS=y +# CONFIG_SLUB_DEBUG is not set +# CONFIG_COMPAT_BRK is not set +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +# CONFIG_BLK_DEV_BSG is not set +CONFIG_GPIO_PCA953X=y +CONFIG_ARCH_MXC=y +CONFIG_MACH_IMX51_DT=y +CONFIG_MACH_EUKREA_CPUIMX51SD=y +CONFIG_SOC_IMX50=y +CONFIG_SOC_IMX53=y +CONFIG_SOC_IMX6Q=y +CONFIG_SOC_IMX6SL=y +CONFIG_SOC_IMX6SX=y +CONFIG_SOC_VF610=y +# CONFIG_SWP_EMULATE is not set +CONFIG_PCI=y +CONFIG_PCI_MSI=y +CONFIG_PCI_IMX6=y +CONFIG_SMP=y +CONFIG_VMSPLIT_2G=y +CONFIG_PREEMPT=y +CONFIG_AEABI=y +CONFIG_HIGHMEM=y +CONFIG_CMA=y +CONFIG_CMDLINE="noinitrd console=ttymxc0,115200" +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_ARM_IMX6Q_CPUFREQ=y +CONFIG_CPU_IDLE=y +CONFIG_VFP=y +CONFIG_NEON=y +CONFIG_BINFMT_MISC=m +CONFIG_PM_RUNTIME=y +CONFIG_PM_DEBUG=y +CONFIG_PM_TEST_SUSPEND=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_UDP_DIAG=m +CONFIG_IPV6=y +CONFIG_NETFILTER=y +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NF_CONNTRACK=y +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y +CONFIG_NETFILTER_XT_MATCH_HL=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +CONFIG_IP_SET=m +CONFIG_IP_VS=m +CONFIG_NF_CONNTRACK_IPV4=y +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_NF_NAT_IPV4=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_NF_CONNTRACK_IPV6=y +CONFIG_IP6_NF_IPTABLES=y +CONFIG_IP6_NF_FILTER=y +CONFIG_IP6_NF_TARGET_REJECT=y +CONFIG_VLAN_8021Q=y +CONFIG_LLC2=y +CONFIG_CAN=y +CONFIG_CAN_FLEXCAN=y +CONFIG_CAN_M_CAN=y +CONFIG_BT=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=y +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=y +CONFIG_BT_HCIUART=y +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIUART_3WIRE=y +CONFIG_BT_WILINK=y +CONFIG_CFG80211=m +CONFIG_NL80211_TESTMODE=y +CONFIG_CFG80211_DEVELOPER_WARNINGS=y +CONFIG_CFG80211_REG_DEBUG=y +CONFIG_CFG80211_DEBUGFS=y +CONFIG_CFG80211_WEXT=y +CONFIG_MAC80211=m +CONFIG_MAC80211_MESH=y +CONFIG_MAC80211_LEDS=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +# CONFIG_STANDALONE is not set +CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=320 +CONFIG_IMX_WEIM=y +CONFIG_CONNECTOR=y +CONFIG_MTD=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_STAA=y +CONFIG_MTD_PHYSMAP_OF=y +CONFIG_MTD_DATAFLASH=y +CONFIG_MTD_M25P80=y +CONFIG_MTD_SST25L=y +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_GPMI_NAND=y +CONFIG_MTD_NAND_MXC=y +CONFIG_MTD_SPI_NOR=y +CONFIG_SPI_FSL_QUADSPI=y +CONFIG_MTD_UBI=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_TIFM_CORE=m +CONFIG_EEPROM_AT24=y +CONFIG_EEPROM_AT25=y +# CONFIG_SCSI_PROC_FS is not set +CONFIG_BLK_DEV_SD=y +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SCAN_ASYNC=y +# CONFIG_SCSI_LOWLEVEL is not set +CONFIG_ATA=y +CONFIG_SATA_AHCI_PLATFORM=y +CONFIG_AHCI_IMX=y +CONFIG_PATA_IMX=y +CONFIG_NETDEVICES=y +# CONFIG_NET_VENDOR_BROADCOM is not set +CONFIG_CS89x0=y +CONFIG_CS89x0_PLATFORM=y +# CONFIG_NET_VENDOR_FARADAY is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MICROCHIP is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_SEEQ is not set +CONFIG_SMC91X=y +CONFIG_SMC911X=y +CONFIG_SMSC911X=y +# CONFIG_NET_VENDOR_STMICRO is not set +CONFIG_MICREL_PHY=y +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_RTL8152=m +CONFIG_USB_USBNET=m +CONFIG_USB_NET_CDC_EEM=m +CONFIG_HOSTAP=y +CONFIG_WL_TI=y +CONFIG_WL12XX=m +CONFIG_WL18XX=m +CONFIG_WLCORE_SDIO=m +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_EVDEV=y +CONFIG_KEYBOARD_GPIO=y +CONFIG_KEYBOARD_SNVS_PWRKEY=y +CONFIG_KEYBOARD_IMX=y +CONFIG_MOUSE_PS2=m +CONFIG_MOUSE_PS2_ELANTECH=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_FT5X06=y +CONFIG_TOUCHSCREEN_ADS7846=y +CONFIG_TOUCHSCREEN_CTW6120=y +CONFIG_TOUCHSCREEN_EGALAX=y +CONFIG_TOUCHSCREEN_ELAN=y +CONFIG_TOUCHSCREEN_MC13783=y +CONFIG_TOUCHSCREEN_STMPE=y +CONFIG_INPUT_MISC=y +CONFIG_INPUT_MMA8450=y +CONFIG_INPUT_ISL29023=y +CONFIG_SERIO_SERPORT=m +# CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVKMEM is not set +CONFIG_SERIAL_IMX=y +CONFIG_SERIAL_IMX_CONSOLE=y +CONFIG_SERIAL_FSL_LPUART=y +CONFIG_SERIAL_FSL_LPUART_CONSOLE=y +CONFIG_FSL_OTP=y +CONFIG_HW_RANDOM=y +# CONFIG_I2C_COMPAT is not set +CONFIG_I2C_CHARDEV=y +# CONFIG_I2C_HELPER_AUTO is not set +CONFIG_I2C_ALGOPCF=m +CONFIG_I2C_ALGOPCA=m +CONFIG_I2C_IMX=y +CONFIG_SPI=y +CONFIG_SPI_IMX=y +CONFIG_SPI_SPIDEV=y +CONFIG_GPIO_SYSFS=y +CONFIG_POWER_SUPPLY=y +CONFIG_SENSORS_MAX17135=y +CONFIG_SENSORS_MAG3110=y +CONFIG_THERMAL=y +CONFIG_CPU_THERMAL=y +CONFIG_IMX_THERMAL=y +CONFIG_DEVICE_THERMAL=y +CONFIG_WATCHDOG=y +CONFIG_IMX2_WDT=y +CONFIG_MFD_DA9052_I2C=y +CONFIG_MFD_MC13XXX_SPI=y +CONFIG_MFD_MC13XXX_I2C=y +CONFIG_MFD_MAX17135=y +CONFIG_MFD_SI476X_CORE=y +CONFIG_MFD_STMPE=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_ANATOP=y +CONFIG_REGULATOR_DA9052=y +CONFIG_REGULATOR_MAX17135=y +CONFIG_REGULATOR_MC13783=y +CONFIG_REGULATOR_MC13892=y +CONFIG_REGULATOR_PFUZE100=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_RADIO_SUPPORT=y +CONFIG_MEDIA_RC_SUPPORT=y +CONFIG_RC_DEVICES=y +CONFIG_IR_GPIO_CIR=y +CONFIG_MEDIA_USB_SUPPORT=y +CONFIG_USB_VIDEO_CLASS=m +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_VIDEO_MXC_OUTPUT=y +CONFIG_VIDEO_MXC_CAPTURE=m +CONFIG_MXC_CAMERA_OV5640=m +CONFIG_MXC_CAMERA_OV5642=m +CONFIG_MXC_CAMERA_OV5640_MIPI=m +CONFIG_MXC_TVIN_ADV7180=m +CONFIG_MXC_IPU_DEVICE_QUEUE_SDC=m +CONFIG_VIDEO_MXC_IPU_OUTPUT=y +CONFIG_VIDEO_MXC_PXP_V4L2=y +CONFIG_VIDEO_MXC_CSI_CAMERA=m +CONFIG_MXC_VADC=m +CONFIG_SOC_CAMERA=y +CONFIG_VIDEO_MX3=y +CONFIG_V4L_MEM2MEM_DRIVERS=y +CONFIG_VIDEO_CODA=y +CONFIG_RADIO_SI476X=y +CONFIG_SOC_CAMERA_OV2640=y +CONFIG_DRM=y +CONFIG_DRM_VIVANTE=y +CONFIG_FB=y +CONFIG_FB_MXS=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_LCD_CLASS_DEVICE=y +CONFIG_LCD_L4F00242T03=y +CONFIG_LCD_PLATFORM=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_PWM=y +CONFIG_FB_MXC_SYNC_PANEL=y +CONFIG_FB_MXC_LDB=y +CONFIG_FB_MXC_MIPI_DSI=y +CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL=y +CONFIG_FB_MXC_HDMI=y +CONFIG_FB_MXC_EINK_PANEL=y +CONFIG_FB_MXS_SII902X=y +CONFIG_FB_MXC_DCIC=m +CONFIG_HANNSTAR_CABC=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +CONFIG_LOGO=y +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_SOC=y +CONFIG_SND_IMX_SOC=y +CONFIG_SND_SOC_EUKREA_TLV320=y +CONFIG_SND_SOC_IMX_CS42888=y +CONFIG_SND_SOC_IMX_WM8962=y +CONFIG_SND_SOC_IMX_TLV320AIC3X=y +CONFIG_SND_SOC_IMX_SGTL5000=y +CONFIG_SND_SOC_IMX_MQS=y +CONFIG_SND_SOC_IMX_SPDIF=y +CONFIG_SND_SOC_IMX_MC13783=y +CONFIG_SND_SOC_IMX_HDMI=y +CONFIG_SND_SOC_IMX_SI476X=y +CONFIG_USB=y +CONFIG_USB_OTG_FSM=m +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_MXC=y +CONFIG_USB_EHCI_HCD_PLATFORM=m +CONFIG_USB_ACM=m +CONFIG_USB_WDM=m +CONFIG_USB_STORAGE=y +CONFIG_USB_CHIPIDEA=y +CONFIG_USB_CHIPIDEA_UDC=y +CONFIG_USB_CHIPIDEA_HOST=y +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SISUSBVGA=m +CONFIG_USB_EHSET_TEST_FIXTURE=m +CONFIG_NOP_USB_XCEIV=y +CONFIG_USB_MXS_PHY=y +CONFIG_USB_GADGET=y +CONFIG_USB_CONFIGFS=m +CONFIG_USB_CONFIGFS_SERIAL=y +CONFIG_USB_CONFIGFS_ACM=y +CONFIG_USB_CONFIGFS_OBEX=y +CONFIG_USB_CONFIGFS_NCM=y +CONFIG_USB_CONFIGFS_ECM=y +CONFIG_USB_CONFIGFS_ECM_SUBSET=y +CONFIG_USB_CONFIGFS_RNDIS=y +CONFIG_USB_CONFIGFS_EEM=y +CONFIG_USB_CONFIGFS_MASS_STORAGE=y +CONFIG_USB_CONFIGFS_F_LB_SS=y +CONFIG_USB_CONFIGFS_F_FS=y +CONFIG_USB_ZERO=m +CONFIG_USB_AUDIO=m +CONFIG_USB_ETH=m +CONFIG_USB_G_NCM=m +CONFIG_USB_GADGETFS=m +CONFIG_USB_FUNCTIONFS=m +CONFIG_USB_MASS_STORAGE=m +CONFIG_USB_G_SERIAL=m +CONFIG_USB_G_WEBCAM=m +CONFIG_MMC=y +CONFIG_MMC_UNSAFE_RESUME=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_ESDHC_IMX=y +CONFIG_MXC_IPU=y +CONFIG_MXC_MIPI_CSI2=y +CONFIG_MXC_MLB150=m +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_ONESHOT=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=y +CONFIG_LEDS_TRIGGER_GPIO=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +CONFIG_RTC_DRV_DS1307=y +CONFIG_RTC_DRV_MC13XXX=y +CONFIG_RTC_DRV_MXC=y +CONFIG_RTC_DRV_SNVS=y +CONFIG_DMADEVICES=y +CONFIG_MXC_PXP_V2=y +CONFIG_IMX_SDMA=y +CONFIG_MXS_DMA=y +CONFIG_STAGING=y +CONFIG_STAGING_MEDIA=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_IIO=y +CONFIG_VF610_ADC=y +CONFIG_PWM=y +CONFIG_PWM_IMX=y +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +# CONFIG_PRINT_QUOTA_WARNING is not set +CONFIG_AUTOFS4_FS=y +CONFIG_FUSE_FS=y +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_JFFS2_FS=y +CONFIG_UBIFS_FS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_ROOT_NFS=y +CONFIG_NLS_DEFAULT="cp437" +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_UTF8=y +CONFIG_DEBUG_FS=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_SCHED_DEBUG is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_FTRACE is not set +CONFIG_SECURITYFS=y +CONFIG_CRYPTO_USER=y +CONFIG_CRYPTO_AUTHENC=y +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_CCM=y +CONFIG_CRYPTO_GCM=y +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CTS=y +CONFIG_CRYPTO_LRW=y +CONFIG_CRYPTO_XTS=y +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_RMD128=y +CONFIG_CRYPTO_RMD160=y +CONFIG_CRYPTO_RMD256=y +CONFIG_CRYPTO_RMD320=y +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_TGR192=y +CONFIG_CRYPTO_WP512=y +CONFIG_CRYPTO_BLOWFISH=y +CONFIG_CRYPTO_CAMELLIA=y +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_TWOFISH=y +# CONFIG_CRYPTO_ANSI_CPRNG is not set +# CONFIG_CRYPTO_HW is not set +CONFIG_CRC_CCITT=m +CONFIG_CRC_T10DIF=y +CONFIG_CRC7=m +CONFIG_LIBCRC32C=m +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y diff --git a/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0001-wlcore-memset-wl-rx_filter_enabled-to-zero-after-rec.patch b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0001-wlcore-memset-wl-rx_filter_enabled-to-zero-after-rec.patch new file mode 100644 index 0000000..0d46cdb --- /dev/null +++ b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0001-wlcore-memset-wl-rx_filter_enabled-to-zero-after-rec.patch @@ -0,0 +1,88 @@ +From 02d0727ca3b0bc8194bd69cd52ddf9e4e2910890 Mon Sep 17 00:00:00 2001 +From: Nadim Zubidat <nad...@ti.com> +Date: Mon, 10 Feb 2014 13:47:17 +0200 +Subject: [PATCH 01/18] wlcore: memset wl->rx_filter_enabled to zero after + recovery + +zero rx_filter_enabled array after recovery to avoid +cases were the driver will keep trying to clear a +filter which is not configured in FW. + +Such case will cause consecutive recoveries due to +command execution failures. + +While on it, convert rx_filter_enabled to bitmap, +to save some memory and make sparse happy (it +doesn't like sizeof(bool array)). + +Signed-off-by: Nadim Zubidat <nad...@ti.com> +Signed-off-by: Eliad Peller <el...@wizery.com> +Signed-off-by: John W. Linville <linvi...@tuxdriver.com> +--- + drivers/net/wireless/ti/wlcore/main.c | 1 + + drivers/net/wireless/ti/wlcore/rx.c | 9 ++++++--- + drivers/net/wireless/ti/wlcore/wlcore.h | 2 +- + 3 files changed, 8 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c +index b46b311..da268e8 100644 +--- a/drivers/net/wireless/ti/wlcore/main.c ++++ b/drivers/net/wireless/ti/wlcore/main.c +@@ -1914,6 +1914,7 @@ static void wlcore_op_stop_locked(struct wl1271 *wl) + memset(wl->links_map, 0, sizeof(wl->links_map)); + memset(wl->roc_map, 0, sizeof(wl->roc_map)); + memset(wl->session_ids, 0, sizeof(wl->session_ids)); ++ memset(wl->rx_filter_enabled, 0, sizeof(wl->rx_filter_enabled)); + wl->active_sta_count = 0; + wl->active_link_count = 0; + +diff --git a/drivers/net/wireless/ti/wlcore/rx.c b/drivers/net/wireless/ti/wlcore/rx.c +index 6791a1a..94ab445 100644 +--- a/drivers/net/wireless/ti/wlcore/rx.c ++++ b/drivers/net/wireless/ti/wlcore/rx.c +@@ -302,7 +302,7 @@ int wl1271_rx_filter_enable(struct wl1271 *wl, + { + int ret; + +- if (wl->rx_filter_enabled[index] == enable) { ++ if (!!test_bit(index, wl->rx_filter_enabled) == enable) { + wl1271_warning("Request to enable an already " + "enabled rx filter %d", index); + return 0; +@@ -316,7 +316,10 @@ int wl1271_rx_filter_enable(struct wl1271 *wl, + return ret; + } + +- wl->rx_filter_enabled[index] = enable; ++ if (enable) ++ __set_bit(index, wl->rx_filter_enabled); ++ else ++ __clear_bit(index, wl->rx_filter_enabled); + + return 0; + } +@@ -326,7 +329,7 @@ int wl1271_rx_filter_clear_all(struct wl1271 *wl) + int i, ret = 0; + + for (i = 0; i < WL1271_MAX_RX_FILTERS; i++) { +- if (!wl->rx_filter_enabled[i]) ++ if (!test_bit(i, wl->rx_filter_enabled)) + continue; + ret = wl1271_rx_filter_enable(wl, i, 0, NULL); + if (ret) +diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h +index 06efc12..a3cc117 100644 +--- a/drivers/net/wireless/ti/wlcore/wlcore.h ++++ b/drivers/net/wireless/ti/wlcore/wlcore.h +@@ -451,7 +451,7 @@ struct wl1271 { + size_t fw_status_priv_len; + + /* RX Data filter rule state - enabled/disabled */ +- bool rx_filter_enabled[WL1271_MAX_RX_FILTERS]; ++ unsigned long rx_filter_enabled[BITS_TO_LONGS(WL1271_MAX_RX_FILTERS)]; + + /* size of the private static data */ + size_t static_data_priv_len; +-- +1.9.3 + diff --git a/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0002-wlcore-cancel-Tx-watchdog-on-suspend-and-rearm-on-fi.patch b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0002-wlcore-cancel-Tx-watchdog-on-suspend-and-rearm-on-fi.patch new file mode 100644 index 0000000..ed6a00a --- /dev/null +++ b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0002-wlcore-cancel-Tx-watchdog-on-suspend-and-rearm-on-fi.patch @@ -0,0 +1,88 @@ +From 9be86cf067f43c3a43a538189d773afc812e4017 Mon Sep 17 00:00:00 2001 +From: Arik Nemtsov <a...@wizery.com> +Date: Mon, 10 Feb 2014 13:47:18 +0200 +Subject: [PATCH 02/18] wlcore: cancel Tx watchdog on suspend and rearm on + first Tx after + +Sometimes a tx_flush during suspend fails, but the FW manages to flush +out the packets during the time when the host is supsended. Cancel +the Tx-watchdog on suspend to not cause a spurious recovery on resume +for that case. Set a flag to reinit the watchdog on the first Tx after +resume, so we'll still recover if the FW is not empty and there's +indeed a problem. + +Signed-off-by: Arik Nemtsov <a...@wizery.com> +Signed-off-by: Eliad Peller <el...@wizery.com> +Signed-off-by: John W. Linville <linvi...@tuxdriver.com> +--- + drivers/net/wireless/ti/wlcore/main.c | 13 +++++++++++++ + drivers/net/wireless/ti/wlcore/tx.c | 9 +++++++-- + drivers/net/wireless/ti/wlcore/wlcore_i.h | 1 + + 3 files changed, 21 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c +index da268e8..1e19196 100644 +--- a/drivers/net/wireless/ti/wlcore/main.c ++++ b/drivers/net/wireless/ti/wlcore/main.c +@@ -1767,6 +1767,12 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw, + flush_work(&wl->tx_work); + flush_delayed_work(&wl->elp_work); + ++ /* ++ * Cancel the watchdog even if above tx_flush failed. We will detect ++ * it on resume anyway. ++ */ ++ cancel_delayed_work(&wl->tx_watchdog_work); ++ + return 0; + } + +@@ -1824,6 +1830,13 @@ static int wl1271_op_resume(struct ieee80211_hw *hw) + + out: + wl->wow_enabled = false; ++ ++ /* ++ * Set a flag to re-init the watchdog on the first Tx after resume. ++ * That way we avoid possible conditions where Tx-complete interrupts ++ * fail to arrive and we perform a spurious recovery. ++ */ ++ set_bit(WL1271_FLAG_REINIT_TX_WDOG, &wl->flags); + mutex_unlock(&wl->mutex); + + return 0; +diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c +index 87cd707..ca886ef 100644 +--- a/drivers/net/wireless/ti/wlcore/tx.c ++++ b/drivers/net/wireless/ti/wlcore/tx.c +@@ -234,8 +234,13 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif, + wl->tx_blocks_available -= total_blocks; + wl->tx_allocated_blocks += total_blocks; + +- /* If the FW was empty before, arm the Tx watchdog */ +- if (wl->tx_allocated_blocks == total_blocks) ++ /* ++ * If the FW was empty before, arm the Tx watchdog. Also do ++ * this on the first Tx after resume, as we always cancel the ++ * watchdog on suspend. ++ */ ++ if (wl->tx_allocated_blocks == total_blocks || ++ test_and_clear_bit(WL1271_FLAG_REINIT_TX_WDOG, &wl->flags)) + wl12xx_rearm_tx_watchdog_locked(wl); + + ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); +diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h +index ce7261c..3815332 100644 +--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h ++++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h +@@ -240,6 +240,7 @@ enum wl12xx_flags { + WL1271_FLAG_VIF_CHANGE_IN_PROGRESS, + WL1271_FLAG_INTENDED_FW_RECOVERY, + WL1271_FLAG_IO_FAILED, ++ WL1271_FLAG_REINIT_TX_WDOG, + }; + + enum wl12xx_vif_flags { +-- +1.9.3 + diff --git a/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0003-wlcore-block-read-writes-to-FW-during-ELP.patch b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0003-wlcore-block-read-writes-to-FW-during-ELP.patch new file mode 100644 index 0000000..d9d4545 --- /dev/null +++ b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0003-wlcore-block-read-writes-to-FW-during-ELP.patch @@ -0,0 +1,46 @@ +From 51ae14d0eae31a7d678c201c9664efbb373f97fa Mon Sep 17 00:00:00 2001 +From: Barak Bercovitz <ba...@wizery.com> +Date: Mon, 10 Feb 2014 13:47:19 +0200 +Subject: [PATCH 03/18] wlcore: block read/writes to FW during ELP + +When the chip is in ELP mode read/write to FW is invalid and may cause +the lower layers to get stuck. The reads/writes concerning ELP wakeup +are the exception here and are checked for. In addition to blocking the +IO, produce a warning. + +Signed-off-by: Barak Bercovitz <ba...@wizery.com> +Signed-off-by: Eliad Peller <el...@wizery.com> +Signed-off-by: John W. Linville <linvi...@tuxdriver.com> +--- + drivers/net/wireless/ti/wlcore/io.h | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/ti/wlcore/io.h b/drivers/net/wireless/ti/wlcore/io.h +index 07e3d6a..0305729 100644 +--- a/drivers/net/wireless/ti/wlcore/io.h ++++ b/drivers/net/wireless/ti/wlcore/io.h +@@ -60,7 +60,9 @@ static inline int __must_check wlcore_raw_write(struct wl1271 *wl, int addr, + { + int ret; + +- if (test_bit(WL1271_FLAG_IO_FAILED, &wl->flags)) ++ if (test_bit(WL1271_FLAG_IO_FAILED, &wl->flags) || ++ WARN_ON((test_bit(WL1271_FLAG_IN_ELP, &wl->flags) && ++ addr != HW_ACCESS_ELP_CTRL_REG))) + return -EIO; + + ret = wl->if_ops->write(wl->dev, addr, buf, len, fixed); +@@ -76,7 +78,9 @@ static inline int __must_check wlcore_raw_read(struct wl1271 *wl, int addr, + { + int ret; + +- if (test_bit(WL1271_FLAG_IO_FAILED, &wl->flags)) ++ if (test_bit(WL1271_FLAG_IO_FAILED, &wl->flags) || ++ WARN_ON((test_bit(WL1271_FLAG_IN_ELP, &wl->flags) && ++ addr != HW_ACCESS_ELP_CTRL_REG))) + return -EIO; + + ret = wl->if_ops->read(wl->dev, addr, buf, len, fixed); +-- +1.9.3 + diff --git a/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0004-wlcore-AP-don-t-start-mac80211-PS-on-non-peer-HLIDs.patch b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0004-wlcore-AP-don-t-start-mac80211-PS-on-non-peer-HLIDs.patch new file mode 100644 index 0000000..4684662 --- /dev/null +++ b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0004-wlcore-AP-don-t-start-mac80211-PS-on-non-peer-HLIDs.patch @@ -0,0 +1,38 @@ +From 7a536265b0b470893c13dc0f094e3078521818e2 Mon Sep 17 00:00:00 2001 +From: Arik Nemtsov <a...@wizery.com> +Date: Mon, 10 Feb 2014 13:47:20 +0200 +Subject: [PATCH 04/18] wlcore: AP: don't start mac80211 PS on non-peer HLIDs + +It seems the wl18xx FW sometimes sends spurious changes on the PSM state +of the broadcast HLID. This causes us to search for a station on a +non-peer link and fail, causing warnings in our log. + +Prevent the driver from considering PSM changes for any non-peer HLIDs. + +Signed-off-by: Arik Nemtsov <a...@wizery.com> +Signed-off-by: Eliad Peller <el...@wizery.com> +Signed-off-by: John W. Linville <linvi...@tuxdriver.com> +--- + drivers/net/wireless/ti/wlcore/ps.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ti/wlcore/ps.c b/drivers/net/wireless/ti/wlcore/ps.c +index 26bfc36..b52516e 100644 +--- a/drivers/net/wireless/ti/wlcore/ps.c ++++ b/drivers/net/wireless/ti/wlcore/ps.c +@@ -280,7 +280,11 @@ void wl12xx_ps_link_start(struct wl1271 *wl, struct wl12xx_vif *wlvif, + struct ieee80211_sta *sta; + struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); + +- if (test_bit(hlid, &wl->ap_ps_map)) ++ if (WARN_ON_ONCE(wlvif->bss_type != BSS_TYPE_AP_BSS)) ++ return; ++ ++ if (!test_bit(hlid, wlvif->ap.sta_hlid_map) || ++ test_bit(hlid, &wl->ap_ps_map)) + return; + + wl1271_debug(DEBUG_PSM, "start mac80211 PSM on hlid %d pkts %d " +-- +1.9.3 + diff --git a/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0005-wlcore-wl12xx-wl18xx-simplify-fw_status-handling.patch b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0005-wlcore-wl12xx-wl18xx-simplify-fw_status-handling.patch new file mode 100644 index 0000000..3045788 --- /dev/null +++ b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0005-wlcore-wl12xx-wl18xx-simplify-fw_status-handling.patch @@ -0,0 +1,763 @@ +From 75fb4df7f804229372e073977615a149a4a28dc0 Mon Sep 17 00:00:00 2001 +From: Eliad Peller <el...@wizery.com> +Date: Mon, 10 Feb 2014 13:47:21 +0200 +Subject: [PATCH 05/18] wlcore/wl12xx/wl18xx: simplify fw_status handling + +Instead of splitting the fw_status into 2 and using some +complex calculations, read the fw status and let each low-level +driver (wl12xx/wl18xx) convert it into a common struct. + +This is required for the upcoming fw api changes, which +break the current logic anyway. + +Signed-off-by: Eliad Peller <el...@wizery.com> +Signed-off-by: John W. Linville <linvi...@tuxdriver.com> +--- + drivers/net/wireless/ti/wl12xx/main.c | 35 ++++++++++- + drivers/net/wireless/ti/wl12xx/wl12xx.h | 50 ++++++++++++++++ + drivers/net/wireless/ti/wl18xx/main.c | 39 ++++++++++++- + drivers/net/wireless/ti/wl18xx/tx.c | 4 +- + drivers/net/wireless/ti/wl18xx/wl18xx.h | 53 +++++++++++++++++ + drivers/net/wireless/ti/wlcore/cmd.c | 11 +++- + drivers/net/wireless/ti/wlcore/hw_ops.h | 9 +++ + drivers/net/wireless/ti/wlcore/main.c | 96 +++++++++++++++---------------- + drivers/net/wireless/ti/wlcore/rx.c | 2 +- + drivers/net/wireless/ti/wlcore/rx.h | 2 +- + drivers/net/wireless/ti/wlcore/wlcore.h | 7 ++- + drivers/net/wireless/ti/wlcore/wlcore_i.h | 72 ++++++++++------------- + 12 files changed, 277 insertions(+), 103 deletions(-) + +diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c +index be7129b..3ad8767 100644 +--- a/drivers/net/wireless/ti/wl12xx/main.c ++++ b/drivers/net/wireless/ti/wl12xx/main.c +@@ -1378,7 +1378,7 @@ static u32 wl12xx_get_rx_packet_len(struct wl1271 *wl, void *rx_data, + + static int wl12xx_tx_delayed_compl(struct wl1271 *wl) + { +- if (wl->fw_status_1->tx_results_counter == ++ if (wl->fw_status->tx_results_counter == + (wl->tx_results_count & 0xff)) + return 0; + +@@ -1438,6 +1438,37 @@ out: + return ret; + } + ++static void wl12xx_convert_fw_status(struct wl1271 *wl, void *raw_fw_status, ++ struct wl_fw_status *fw_status) ++{ ++ struct wl12xx_fw_status *int_fw_status = raw_fw_status; ++ ++ fw_status->intr = le32_to_cpu(int_fw_status->intr); ++ fw_status->fw_rx_counter = int_fw_status->fw_rx_counter; ++ fw_status->drv_rx_counter = int_fw_status->drv_rx_counter; ++ fw_status->tx_results_counter = int_fw_status->tx_results_counter; ++ fw_status->rx_pkt_descs = int_fw_status->rx_pkt_descs; ++ ++ fw_status->fw_localtime = le32_to_cpu(int_fw_status->fw_localtime); ++ fw_status->link_ps_bitmap = le32_to_cpu(int_fw_status->link_ps_bitmap); ++ fw_status->link_fast_bitmap = ++ le32_to_cpu(int_fw_status->link_fast_bitmap); ++ fw_status->total_released_blks = ++ le32_to_cpu(int_fw_status->total_released_blks); ++ fw_status->tx_total = le32_to_cpu(int_fw_status->tx_total); ++ ++ fw_status->counters.tx_released_pkts = ++ int_fw_status->counters.tx_released_pkts; ++ fw_status->counters.tx_lnk_free_pkts = ++ int_fw_status->counters.tx_lnk_free_pkts; ++ fw_status->counters.tx_voice_released_blks = ++ int_fw_status->counters.tx_voice_released_blks; ++ fw_status->counters.tx_last_rate = ++ int_fw_status->counters.tx_last_rate; ++ ++ fw_status->log_start_addr = le32_to_cpu(int_fw_status->log_start_addr); ++} ++ + static u32 wl12xx_sta_get_ap_rate_mask(struct wl1271 *wl, + struct wl12xx_vif *wlvif) + { +@@ -1677,6 +1708,7 @@ static struct wlcore_ops wl12xx_ops = { + .tx_delayed_compl = wl12xx_tx_delayed_compl, + .hw_init = wl12xx_hw_init, + .init_vif = NULL, ++ .convert_fw_status = wl12xx_convert_fw_status, + .sta_get_ap_rate_mask = wl12xx_sta_get_ap_rate_mask, + .get_pg_ver = wl12xx_get_pg_ver, + .get_mac = wl12xx_get_mac, +@@ -1725,6 +1757,7 @@ static int wl12xx_setup(struct wl1271 *wl) + wl->band_rate_to_idx = wl12xx_band_rate_to_idx; + wl->hw_tx_rate_tbl_size = WL12XX_CONF_HW_RXTX_RATE_MAX; + wl->hw_min_ht_rate = WL12XX_CONF_HW_RXTX_RATE_MCS0; ++ wl->fw_status_len = sizeof(struct wl12xx_fw_status); + wl->fw_status_priv_len = 0; + wl->stats.fw_stats_len = sizeof(struct wl12xx_acx_statistics); + wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ, &wl12xx_ht_cap); +diff --git a/drivers/net/wireless/ti/wl12xx/wl12xx.h b/drivers/net/wireless/ti/wl12xx/wl12xx.h +index 9e5484a..b9950f8 100644 +--- a/drivers/net/wireless/ti/wl12xx/wl12xx.h ++++ b/drivers/net/wireless/ti/wl12xx/wl12xx.h +@@ -79,4 +79,54 @@ struct wl12xx_priv { + struct wl127x_rx_mem_pool_addr *rx_mem_addr; + }; + ++struct wl12xx_fw_packet_counters { ++ /* Cumulative counter of released packets per AC */ ++ u8 tx_released_pkts[NUM_TX_QUEUES]; ++ ++ /* Cumulative counter of freed packets per HLID */ ++ u8 tx_lnk_free_pkts[WL12XX_MAX_LINKS]; ++ ++ /* Cumulative counter of released Voice memory blocks */ ++ u8 tx_voice_released_blks; ++ ++ /* Tx rate of the last transmitted packet */ ++ u8 tx_last_rate; ++ ++ u8 padding[2]; ++} __packed; ++ ++/* FW status registers */ ++struct wl12xx_fw_status { ++ __le32 intr; ++ u8 fw_rx_counter; ++ u8 drv_rx_counter; ++ u8 reserved; ++ u8 tx_results_counter; ++ __le32 rx_pkt_descs[WL12XX_NUM_RX_DESCRIPTORS]; ++ ++ __le32 fw_localtime; ++ ++ /* ++ * A bitmap (where each bit represents a single HLID) ++ * to indicate if the station is in PS mode. ++ */ ++ __le32 link_ps_bitmap; ++ ++ /* ++ * A bitmap (where each bit represents a single HLID) to indicate ++ * if the station is in Fast mode ++ */ ++ __le32 link_fast_bitmap; ++ ++ /* Cumulative counter of total released mem blocks since FW-reset */ ++ __le32 total_released_blks; ++ ++ /* Size (in Memory Blocks) of TX pool */ ++ __le32 tx_total; ++ ++ struct wl12xx_fw_packet_counters counters; ++ ++ __le32 log_start_addr; ++} __packed; ++ + #endif /* __WL12XX_PRIV_H__ */ +diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c +index ec37b16..cbf9bf3 100644 +--- a/drivers/net/wireless/ti/wl18xx/main.c ++++ b/drivers/net/wireless/ti/wl18xx/main.c +@@ -1133,6 +1133,39 @@ static int wl18xx_hw_init(struct wl1271 *wl) + return ret; + } + ++static void wl18xx_convert_fw_status(struct wl1271 *wl, void *raw_fw_status, ++ struct wl_fw_status *fw_status) ++{ ++ struct wl18xx_fw_status *int_fw_status = raw_fw_status; ++ ++ fw_status->intr = le32_to_cpu(int_fw_status->intr); ++ fw_status->fw_rx_counter = int_fw_status->fw_rx_counter; ++ fw_status->drv_rx_counter = int_fw_status->drv_rx_counter; ++ fw_status->tx_results_counter = int_fw_status->tx_results_counter; ++ fw_status->rx_pkt_descs = int_fw_status->rx_pkt_descs; ++ ++ fw_status->fw_localtime = le32_to_cpu(int_fw_status->fw_localtime); ++ fw_status->link_ps_bitmap = le32_to_cpu(int_fw_status->link_ps_bitmap); ++ fw_status->link_fast_bitmap = ++ le32_to_cpu(int_fw_status->link_fast_bitmap); ++ fw_status->total_released_blks = ++ le32_to_cpu(int_fw_status->total_released_blks); ++ fw_status->tx_total = le32_to_cpu(int_fw_status->tx_total); ++ ++ fw_status->counters.tx_released_pkts = ++ int_fw_status->counters.tx_released_pkts; ++ fw_status->counters.tx_lnk_free_pkts = ++ int_fw_status->counters.tx_lnk_free_pkts; ++ fw_status->counters.tx_voice_released_blks = ++ int_fw_status->counters.tx_voice_released_blks; ++ fw_status->counters.tx_last_rate = ++ int_fw_status->counters.tx_last_rate; ++ ++ fw_status->log_start_addr = le32_to_cpu(int_fw_status->log_start_addr); ++ ++ fw_status->priv = &int_fw_status->priv; ++} ++ + static void wl18xx_set_tx_desc_csum(struct wl1271 *wl, + struct wl1271_tx_hw_descr *desc, + struct sk_buff *skb) +@@ -1572,7 +1605,7 @@ static bool wl18xx_lnk_high_prio(struct wl1271 *wl, u8 hlid, + { + u8 thold; + struct wl18xx_fw_status_priv *status_priv = +- (struct wl18xx_fw_status_priv *)wl->fw_status_2->priv; ++ (struct wl18xx_fw_status_priv *)wl->fw_status->priv; + u32 suspend_bitmap = le32_to_cpu(status_priv->link_suspend_bitmap); + + /* suspended links are never high priority */ +@@ -1594,7 +1627,7 @@ static bool wl18xx_lnk_low_prio(struct wl1271 *wl, u8 hlid, + { + u8 thold; + struct wl18xx_fw_status_priv *status_priv = +- (struct wl18xx_fw_status_priv *)wl->fw_status_2->priv; ++ (struct wl18xx_fw_status_priv *)wl->fw_status->priv; + u32 suspend_bitmap = le32_to_cpu(status_priv->link_suspend_bitmap); + + if (test_bit(hlid, (unsigned long *)&suspend_bitmap)) +@@ -1632,6 +1665,7 @@ static struct wlcore_ops wl18xx_ops = { + .tx_immediate_compl = wl18xx_tx_immediate_completion, + .tx_delayed_compl = NULL, + .hw_init = wl18xx_hw_init, ++ .convert_fw_status = wl18xx_convert_fw_status, + .set_tx_desc_csum = wl18xx_set_tx_desc_csum, + .get_pg_ver = wl18xx_get_pg_ver, + .set_rx_csum = wl18xx_set_rx_csum, +@@ -1726,6 +1760,7 @@ static int wl18xx_setup(struct wl1271 *wl) + wl->band_rate_to_idx = wl18xx_band_rate_to_idx; + wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX; + wl->hw_min_ht_rate = WL18XX_CONF_HW_RXTX_RATE_MCS0; ++ wl->fw_status_len = sizeof(struct wl18xx_fw_status); + wl->fw_status_priv_len = sizeof(struct wl18xx_fw_status_priv); + wl->stats.fw_stats_len = sizeof(struct wl18xx_acx_statistics); + wl->static_data_priv_len = sizeof(struct wl18xx_static_data_priv); +diff --git a/drivers/net/wireless/ti/wl18xx/tx.c b/drivers/net/wireless/ti/wl18xx/tx.c +index 57c6943..be1ebd5 100644 +--- a/drivers/net/wireless/ti/wl18xx/tx.c ++++ b/drivers/net/wireless/ti/wl18xx/tx.c +@@ -32,7 +32,7 @@ static + void wl18xx_get_last_tx_rate(struct wl1271 *wl, struct ieee80211_vif *vif, + struct ieee80211_tx_rate *rate) + { +- u8 fw_rate = wl->fw_status_2->counters.tx_last_rate; ++ u8 fw_rate = wl->fw_status->counters.tx_last_rate; + + if (fw_rate > CONF_HW_RATE_INDEX_MAX) { + wl1271_error("last Tx rate invalid: %d", fw_rate); +@@ -139,7 +139,7 @@ static void wl18xx_tx_complete_packet(struct wl1271 *wl, u8 tx_stat_byte) + void wl18xx_tx_immediate_complete(struct wl1271 *wl) + { + struct wl18xx_fw_status_priv *status_priv = +- (struct wl18xx_fw_status_priv *)wl->fw_status_2->priv; ++ (struct wl18xx_fw_status_priv *)wl->fw_status->priv; + struct wl18xx_priv *priv = wl->priv; + u8 i; + +diff --git a/drivers/net/wireless/ti/wl18xx/wl18xx.h b/drivers/net/wireless/ti/wl18xx/wl18xx.h +index 9204e07..d32a6af 100644 +--- a/drivers/net/wireless/ti/wl18xx/wl18xx.h ++++ b/drivers/net/wireless/ti/wl18xx/wl18xx.h +@@ -109,6 +109,59 @@ struct wl18xx_fw_status_priv { + u8 padding[3]; + }; + ++struct wl18xx_fw_packet_counters { ++ /* Cumulative counter of released packets per AC */ ++ u8 tx_released_pkts[NUM_TX_QUEUES]; ++ ++ /* Cumulative counter of freed packets per HLID */ ++ u8 tx_lnk_free_pkts[WL12XX_MAX_LINKS]; ++ ++ /* Cumulative counter of released Voice memory blocks */ ++ u8 tx_voice_released_blks; ++ ++ /* Tx rate of the last transmitted packet */ ++ u8 tx_last_rate; ++ ++ u8 padding[2]; ++} __packed; ++ ++/* FW status registers */ ++struct wl18xx_fw_status { ++ __le32 intr; ++ u8 fw_rx_counter; ++ u8 drv_rx_counter; ++ u8 reserved; ++ u8 tx_results_counter; ++ __le32 rx_pkt_descs[WL18XX_NUM_RX_DESCRIPTORS]; ++ ++ __le32 fw_localtime; ++ ++ /* ++ * A bitmap (where each bit represents a single HLID) ++ * to indicate if the station is in PS mode. ++ */ ++ __le32 link_ps_bitmap; ++ ++ /* ++ * A bitmap (where each bit represents a single HLID) to indicate ++ * if the station is in Fast mode ++ */ ++ __le32 link_fast_bitmap; ++ ++ /* Cumulative counter of total released mem blocks since FW-reset */ ++ __le32 total_released_blks; ++ ++ /* Size (in Memory Blocks) of TX pool */ ++ __le32 tx_total; ++ ++ struct wl18xx_fw_packet_counters counters; ++ ++ __le32 log_start_addr; ++ ++ /* Private status to be used by the lower drivers */ ++ struct wl18xx_fw_status_priv priv; ++} __packed; ++ + #define WL18XX_PHY_VERSION_MAX_LEN 20 + + struct wl18xx_static_data_priv { +diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c +index 9b2ecf5..4d19fd2 100644 +--- a/drivers/net/wireless/ti/wlcore/cmd.c ++++ b/drivers/net/wireless/ti/wlcore/cmd.c +@@ -324,9 +324,14 @@ int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid) + __set_bit(link, wlvif->links_map); + spin_unlock_irqrestore(&wl->wl_lock, flags); + +- /* take the last "freed packets" value from the current FW status */ +- wl->links[link].prev_freed_pkts = +- wl->fw_status_2->counters.tx_lnk_free_pkts[link]; ++ /* ++ * take the last "freed packets" value from the current FW status. ++ * on recovery, we might not have fw_status yet, and ++ * tx_lnk_free_pkts will be NULL. check for it. ++ */ ++ if (wl->fw_status->counters.tx_lnk_free_pkts) ++ wl->links[link].prev_freed_pkts = ++ wl->fw_status->counters.tx_lnk_free_pkts[link]; + wl->links[link].wlvif = wlvif; + + /* +diff --git a/drivers/net/wireless/ti/wlcore/hw_ops.h b/drivers/net/wireless/ti/wlcore/hw_ops.h +index 51f8d63..1555ff9 100644 +--- a/drivers/net/wireless/ti/wlcore/hw_ops.h ++++ b/drivers/net/wireless/ti/wlcore/hw_ops.h +@@ -106,6 +106,15 @@ wlcore_hw_init_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif) + return 0; + } + ++static inline void ++wlcore_hw_convert_fw_status(struct wl1271 *wl, void *raw_fw_status, ++ struct wl_fw_status *fw_status) ++{ ++ BUG_ON(!wl->ops->convert_fw_status); ++ ++ wl->ops->convert_fw_status(wl, raw_fw_status, fw_status); ++} ++ + static inline u32 + wlcore_hw_sta_get_ap_rate_mask(struct wl1271 *wl, struct wl12xx_vif *wlvif) + { +diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c +index 1e19196..70a3e57 100644 +--- a/drivers/net/wireless/ti/wlcore/main.c ++++ b/drivers/net/wireless/ti/wlcore/main.c +@@ -357,12 +357,12 @@ static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl, + + static void wl12xx_irq_update_links_status(struct wl1271 *wl, + struct wl12xx_vif *wlvif, +- struct wl_fw_status_2 *status) ++ struct wl_fw_status *status) + { + u32 cur_fw_ps_map; + u8 hlid; + +- cur_fw_ps_map = le32_to_cpu(status->link_ps_bitmap); ++ cur_fw_ps_map = status->link_ps_bitmap; + if (wl->ap_fw_ps_map != cur_fw_ps_map) { + wl1271_debug(DEBUG_PSM, + "link ps prev 0x%x cur 0x%x changed 0x%x", +@@ -377,41 +377,38 @@ static void wl12xx_irq_update_links_status(struct wl1271 *wl, + wl->links[hlid].allocated_pkts); + } + +-static int wlcore_fw_status(struct wl1271 *wl, +- struct wl_fw_status_1 *status_1, +- struct wl_fw_status_2 *status_2) ++static int wlcore_fw_status(struct wl1271 *wl, struct wl_fw_status *status) + { + struct wl12xx_vif *wlvif; + struct timespec ts; + u32 old_tx_blk_count = wl->tx_blocks_available; + int avail, freed_blocks; + int i; +- size_t status_len; + int ret; + struct wl1271_link *lnk; + +- status_len = WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc) + +- sizeof(*status_2) + wl->fw_status_priv_len; +- +- ret = wlcore_raw_read_data(wl, REG_RAW_FW_STATUS_ADDR, status_1, +- status_len, false); ++ ret = wlcore_raw_read_data(wl, REG_RAW_FW_STATUS_ADDR, ++ wl->raw_fw_status, ++ wl->fw_status_len, false); + if (ret < 0) + return ret; + ++ wlcore_hw_convert_fw_status(wl, wl->raw_fw_status, wl->fw_status); ++ + wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, " + "drv_rx_counter = %d, tx_results_counter = %d)", +- status_1->intr, +- status_1->fw_rx_counter, +- status_1->drv_rx_counter, +- status_1->tx_results_counter); ++ status->intr, ++ status->fw_rx_counter, ++ status->drv_rx_counter, ++ status->tx_results_counter); + + for (i = 0; i < NUM_TX_QUEUES; i++) { + /* prevent wrap-around in freed-packets counter */ + wl->tx_allocated_pkts[i] -= +- (status_2->counters.tx_released_pkts[i] - ++ (status->counters.tx_released_pkts[i] - + wl->tx_pkts_freed[i]) & 0xff; + +- wl->tx_pkts_freed[i] = status_2->counters.tx_released_pkts[i]; ++ wl->tx_pkts_freed[i] = status->counters.tx_released_pkts[i]; + } + + +@@ -420,29 +417,28 @@ static int wlcore_fw_status(struct wl1271 *wl, + lnk = &wl->links[i]; + + /* prevent wrap-around in freed-packets counter */ +- diff = (status_2->counters.tx_lnk_free_pkts[i] - ++ diff = (status->counters.tx_lnk_free_pkts[i] - + lnk->prev_freed_pkts) & 0xff; + + if (diff == 0) + continue; + + lnk->allocated_pkts -= diff; +- lnk->prev_freed_pkts = status_2->counters.tx_lnk_free_pkts[i]; ++ lnk->prev_freed_pkts = status->counters.tx_lnk_free_pkts[i]; + + /* accumulate the prev_freed_pkts counter */ + lnk->total_freed_pkts += diff; + } + + /* prevent wrap-around in total blocks counter */ +- if (likely(wl->tx_blocks_freed <= +- le32_to_cpu(status_2->total_released_blks))) +- freed_blocks = le32_to_cpu(status_2->total_released_blks) - ++ if (likely(wl->tx_blocks_freed <= status->total_released_blks)) ++ freed_blocks = status->total_released_blks - + wl->tx_blocks_freed; + else + freed_blocks = 0x100000000LL - wl->tx_blocks_freed + +- le32_to_cpu(status_2->total_released_blks); ++ status->total_released_blks; + +- wl->tx_blocks_freed = le32_to_cpu(status_2->total_released_blks); ++ wl->tx_blocks_freed = status->total_released_blks; + + wl->tx_allocated_blocks -= freed_blocks; + +@@ -458,7 +454,7 @@ static int wlcore_fw_status(struct wl1271 *wl, + cancel_delayed_work(&wl->tx_watchdog_work); + } + +- avail = le32_to_cpu(status_2->tx_total) - wl->tx_allocated_blocks; ++ avail = status->tx_total - wl->tx_allocated_blocks; + + /* + * The FW might change the total number of TX memblocks before +@@ -477,15 +473,15 @@ static int wlcore_fw_status(struct wl1271 *wl, + + /* for AP update num of allocated TX blocks per link and ps status */ + wl12xx_for_each_wlvif_ap(wl, wlvif) { +- wl12xx_irq_update_links_status(wl, wlvif, status_2); ++ wl12xx_irq_update_links_status(wl, wlvif, status); + } + + /* update the host-chipset time offset */ + getnstimeofday(&ts); + wl->time_offset = (timespec_to_ns(&ts) >> 10) - +- (s64)le32_to_cpu(status_2->fw_localtime); ++ (s64)(status->fw_localtime); + +- wl->fw_fast_lnk_map = le32_to_cpu(status_2->link_fast_bitmap); ++ wl->fw_fast_lnk_map = status->link_fast_bitmap; + + return 0; + } +@@ -549,13 +545,13 @@ static int wlcore_irq_locked(struct wl1271 *wl) + clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags); + smp_mb__after_clear_bit(); + +- ret = wlcore_fw_status(wl, wl->fw_status_1, wl->fw_status_2); ++ ret = wlcore_fw_status(wl, wl->fw_status); + if (ret < 0) + goto out; + + wlcore_hw_tx_immediate_compl(wl); + +- intr = le32_to_cpu(wl->fw_status_1->intr); ++ intr = wl->fw_status->intr; + intr &= WLCORE_ALL_INTR_MASK; + if (!intr) { + done = true; +@@ -584,7 +580,7 @@ static int wlcore_irq_locked(struct wl1271 *wl) + if (likely(intr & WL1271_ACX_INTR_DATA)) { + wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA"); + +- ret = wlcore_rx(wl, wl->fw_status_1); ++ ret = wlcore_rx(wl, wl->fw_status); + if (ret < 0) + goto out; + +@@ -843,11 +839,11 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl) + wl12xx_cmd_stop_fwlog(wl); + + /* Read the first memory block address */ +- ret = wlcore_fw_status(wl, wl->fw_status_1, wl->fw_status_2); ++ ret = wlcore_fw_status(wl, wl->fw_status); + if (ret < 0) + goto out; + +- addr = le32_to_cpu(wl->fw_status_2->log_start_addr); ++ addr = wl->fw_status->log_start_addr; + if (!addr) + goto out; + +@@ -990,23 +986,23 @@ static int wlcore_fw_wakeup(struct wl1271 *wl) + + static int wl1271_setup(struct wl1271 *wl) + { +- wl->fw_status_1 = kzalloc(WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc) + +- sizeof(*wl->fw_status_2) + +- wl->fw_status_priv_len, GFP_KERNEL); +- if (!wl->fw_status_1) +- return -ENOMEM; ++ wl->raw_fw_status = kzalloc(wl->fw_status_len, GFP_KERNEL); ++ if (!wl->raw_fw_status) ++ goto err; + +- wl->fw_status_2 = (struct wl_fw_status_2 *) +- (((u8 *) wl->fw_status_1) + +- WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc)); ++ wl->fw_status = kzalloc(sizeof(*wl->fw_status), GFP_KERNEL); ++ if (!wl->fw_status) ++ goto err; + + wl->tx_res_if = kzalloc(sizeof(*wl->tx_res_if), GFP_KERNEL); +- if (!wl->tx_res_if) { +- kfree(wl->fw_status_1); +- return -ENOMEM; +- } ++ if (!wl->tx_res_if) ++ goto err; + + return 0; ++err: ++ kfree(wl->fw_status); ++ kfree(wl->raw_fw_status); ++ return -ENOMEM; + } + + static int wl12xx_set_power_on(struct wl1271 *wl) +@@ -1952,9 +1948,10 @@ static void wlcore_op_stop_locked(struct wl1271 *wl) + + wl1271_debugfs_reset(wl); + +- kfree(wl->fw_status_1); +- wl->fw_status_1 = NULL; +- wl->fw_status_2 = NULL; ++ kfree(wl->raw_fw_status); ++ wl->raw_fw_status = NULL; ++ kfree(wl->fw_status); ++ wl->fw_status = NULL; + kfree(wl->tx_res_if); + wl->tx_res_if = NULL; + kfree(wl->target_mem_map); +@@ -6025,7 +6022,8 @@ int wlcore_free_hw(struct wl1271 *wl) + kfree(wl->nvs); + wl->nvs = NULL; + +- kfree(wl->fw_status_1); ++ kfree(wl->raw_fw_status); ++ kfree(wl->fw_status); + kfree(wl->tx_res_if); + destroy_workqueue(wl->freezable_wq); + +diff --git a/drivers/net/wireless/ti/wlcore/rx.c b/drivers/net/wireless/ti/wlcore/rx.c +index 94ab445..a047e87 100644 +--- a/drivers/net/wireless/ti/wlcore/rx.c ++++ b/drivers/net/wireless/ti/wlcore/rx.c +@@ -203,7 +203,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length, + return is_data; + } + +-int wlcore_rx(struct wl1271 *wl, struct wl_fw_status_1 *status) ++int wlcore_rx(struct wl1271 *wl, struct wl_fw_status *status) + { + unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0}; + u32 buf_size; +diff --git a/drivers/net/wireless/ti/wlcore/rx.h b/drivers/net/wireless/ti/wlcore/rx.h +index 3363f60..a3b1618 100644 +--- a/drivers/net/wireless/ti/wlcore/rx.h ++++ b/drivers/net/wireless/ti/wlcore/rx.h +@@ -142,7 +142,7 @@ struct wl1271_rx_descriptor { + u8 reserved; + } __packed; + +-int wlcore_rx(struct wl1271 *wl, struct wl_fw_status_1 *status); ++int wlcore_rx(struct wl1271 *wl, struct wl_fw_status *status); + u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); + int wl1271_rx_filter_enable(struct wl1271 *wl, + int index, bool enable, +diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h +index a3cc117..cec5265 100644 +--- a/drivers/net/wireless/ti/wlcore/wlcore.h ++++ b/drivers/net/wireless/ti/wlcore/wlcore.h +@@ -73,6 +73,8 @@ struct wlcore_ops { + void (*tx_immediate_compl)(struct wl1271 *wl); + int (*hw_init)(struct wl1271 *wl); + int (*init_vif)(struct wl1271 *wl, struct wl12xx_vif *wlvif); ++ void (*convert_fw_status)(struct wl1271 *wl, void *raw_fw_status, ++ struct wl_fw_status *fw_status); + u32 (*sta_get_ap_rate_mask)(struct wl1271 *wl, + struct wl12xx_vif *wlvif); + int (*get_pg_ver)(struct wl1271 *wl, s8 *ver); +@@ -346,8 +348,8 @@ struct wl1271 { + u32 buffer_cmd; + u32 buffer_busyword[WL1271_BUSY_WORD_CNT]; + +- struct wl_fw_status_1 *fw_status_1; +- struct wl_fw_status_2 *fw_status_2; ++ void *raw_fw_status; ++ struct wl_fw_status *fw_status; + struct wl1271_tx_hw_res_if *tx_res_if; + + /* Current chipset configuration */ +@@ -448,6 +450,7 @@ struct wl1271 { + struct ieee80211_sta_ht_cap ht_cap[WLCORE_NUM_BANDS]; + + /* size of the private FW status data */ ++ size_t fw_status_len; + size_t fw_status_priv_len; + + /* RX Data filter rule state - enabled/disabled */ +diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h +index 3815332..32e1e8b 100644 +--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h ++++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h +@@ -120,70 +120,58 @@ struct wl1271_chip { + + #define AP_MAX_STATIONS 8 + +-struct wl_fw_packet_counters { +- /* Cumulative counter of released packets per AC */ +- u8 tx_released_pkts[NUM_TX_QUEUES]; +- +- /* Cumulative counter of freed packets per HLID */ +- u8 tx_lnk_free_pkts[WL12XX_MAX_LINKS]; +- +- /* Cumulative counter of released Voice memory blocks */ +- u8 tx_voice_released_blks; +- +- /* Tx rate of the last transmitted packet */ +- u8 tx_last_rate; +- +- u8 padding[2]; +-} __packed; +- +-/* FW status registers */ +-struct wl_fw_status_1 { +- __le32 intr; ++struct wl_fw_status { ++ u32 intr; + u8 fw_rx_counter; + u8 drv_rx_counter; +- u8 reserved; + u8 tx_results_counter; +- __le32 rx_pkt_descs[0]; +-} __packed; +- +-/* +- * Each HW arch has a different number of Rx descriptors. +- * The length of the status depends on it, since it holds an array +- * of descriptors. +- */ +-#define WLCORE_FW_STATUS_1_LEN(num_rx_desc) \ +- (sizeof(struct wl_fw_status_1) + \ +- (sizeof(((struct wl_fw_status_1 *)0)->rx_pkt_descs[0])) * \ +- num_rx_desc) ++ __le32 *rx_pkt_descs; + +-struct wl_fw_status_2 { +- __le32 fw_localtime; ++ u32 fw_localtime; + + /* + * A bitmap (where each bit represents a single HLID) + * to indicate if the station is in PS mode. + */ +- __le32 link_ps_bitmap; ++ u32 link_ps_bitmap; + + /* + * A bitmap (where each bit represents a single HLID) to indicate + * if the station is in Fast mode + */ +- __le32 link_fast_bitmap; ++ u32 link_fast_bitmap; + + /* Cumulative counter of total released mem blocks since FW-reset */ +- __le32 total_released_blks; ++ u32 total_released_blks; + + /* Size (in Memory Blocks) of TX pool */ +- __le32 tx_total; ++ u32 tx_total; + +- struct wl_fw_packet_counters counters; ++ struct { ++ /* ++ * Cumulative counter of released packets per AC ++ * (length of the array is NUM_TX_QUEUES) ++ */ ++ u8 *tx_released_pkts; ++ ++ /* ++ * Cumulative counter of freed packets per HLID ++ * (length of the array is WL12XX_MAX_LINKS) ++ */ ++ u8 *tx_lnk_free_pkts; ++ ++ /* Cumulative counter of released Voice memory blocks */ ++ u8 tx_voice_released_blks; ++ ++ /* Tx rate of the last transmitted packet */ ++ u8 tx_last_rate; ++ } counters; + +- __le32 log_start_addr; ++ u32 log_start_addr; + + /* Private status to be used by the lower drivers */ +- u8 priv[0]; +-} __packed; ++ void *priv; ++}; + + #define WL1271_MAX_CHANNELS 64 + struct wl1271_scan { +-- +1.9.3 + diff --git a/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0006-wlcore-wl12xx-wl18xx-configure-num_links-per-hw.patch b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0006-wlcore-wl12xx-wl18xx-configure-num_links-per-hw.patch new file mode 100644 index 0000000..878e872 --- /dev/null +++ b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0006-wlcore-wl12xx-wl18xx-configure-num_links-per-hw.patch @@ -0,0 +1,375 @@ +From da08fdfaf09f161c923c9d2b7db2fba8cc9c457c Mon Sep 17 00:00:00 2001 +From: Eliad Peller <el...@wizery.com> +Date: Mon, 10 Feb 2014 13:47:22 +0200 +Subject: [PATCH 06/18] wlcore/wl12xx/wl18xx: configure num_links per-hw + +Upcoming fw versions will have different max links support +(according to the hw). Get ready for it by configuring +wl->num_links per-hw, instead of using the const WL12XX_MAX_LINKS. + +However, continue using WLCORE_MAX_LINKS in order to simplify +structs declarations (we use it in multiple bitmaps, and converting +them to dynamic arrays is just cumbersome). + +Signed-off-by: Eliad Peller <el...@wizery.com> +Signed-off-by: John W. Linville <linvi...@tuxdriver.com> +--- + drivers/net/wireless/ti/wl12xx/main.c | 3 +++ + drivers/net/wireless/ti/wl12xx/wl12xx.h | 2 ++ + drivers/net/wireless/ti/wl18xx/main.c | 3 +++ + drivers/net/wireless/ti/wl18xx/wl18xx.h | 4 +++- + drivers/net/wireless/ti/wlcore/cmd.c | 4 ++-- + drivers/net/wireless/ti/wlcore/event.c | 4 ++-- + drivers/net/wireless/ti/wlcore/main.c | 12 ++++++++---- + drivers/net/wireless/ti/wlcore/rx.c | 8 ++++---- + drivers/net/wireless/ti/wlcore/tx.c | 20 ++++++++++---------- + drivers/net/wireless/ti/wlcore/wlcore.h | 8 +++++--- + drivers/net/wireless/ti/wlcore/wlcore_i.h | 13 +++++++++---- + 11 files changed, 51 insertions(+), 30 deletions(-) + +diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c +index 3ad8767..69df5bc 100644 +--- a/drivers/net/wireless/ti/wl12xx/main.c ++++ b/drivers/net/wireless/ti/wl12xx/main.c +@@ -1749,9 +1749,12 @@ static int wl12xx_setup(struct wl1271 *wl) + struct wlcore_platdev_data *pdev_data = dev_get_platdata(&wl->pdev->dev); + struct wl12xx_platform_data *pdata = pdev_data->pdata; + ++ BUILD_BUG_ON(WL12XX_MAX_LINKS > WLCORE_MAX_LINKS); ++ + wl->rtable = wl12xx_rtable; + wl->num_tx_desc = WL12XX_NUM_TX_DESCRIPTORS; + wl->num_rx_desc = WL12XX_NUM_RX_DESCRIPTORS; ++ wl->num_links = WL12XX_MAX_LINKS; + wl->num_channels = 1; + wl->num_mac_addr = WL12XX_NUM_MAC_ADDRESSES; + wl->band_rate_to_idx = wl12xx_band_rate_to_idx; +diff --git a/drivers/net/wireless/ti/wl12xx/wl12xx.h b/drivers/net/wireless/ti/wl12xx/wl12xx.h +index b9950f8..26b1a3f 100644 +--- a/drivers/net/wireless/ti/wl12xx/wl12xx.h ++++ b/drivers/net/wireless/ti/wl12xx/wl12xx.h +@@ -65,6 +65,8 @@ + + #define WL12XX_RX_BA_MAX_SESSIONS 3 + ++#define WL12XX_MAX_LINKS 12 ++ + struct wl127x_rx_mem_pool_addr { + u32 addr; + u32 addr_extra; +diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c +index cbf9bf3..6011b22 100644 +--- a/drivers/net/wireless/ti/wl18xx/main.c ++++ b/drivers/net/wireless/ti/wl18xx/main.c +@@ -1752,9 +1752,12 @@ static int wl18xx_setup(struct wl1271 *wl) + struct wl18xx_priv *priv = wl->priv; + int ret; + ++ BUILD_BUG_ON(WL18XX_MAX_LINKS > WLCORE_MAX_LINKS); ++ + wl->rtable = wl18xx_rtable; + wl->num_tx_desc = WL18XX_NUM_TX_DESCRIPTORS; + wl->num_rx_desc = WL18XX_NUM_RX_DESCRIPTORS; ++ wl->num_links = WL18XX_MAX_LINKS; + wl->num_channels = 2; + wl->num_mac_addr = WL18XX_NUM_MAC_ADDRESSES; + wl->band_rate_to_idx = wl18xx_band_rate_to_idx; +diff --git a/drivers/net/wireless/ti/wl18xx/wl18xx.h b/drivers/net/wireless/ti/wl18xx/wl18xx.h +index d32a6af..38174e9 100644 +--- a/drivers/net/wireless/ti/wl18xx/wl18xx.h ++++ b/drivers/net/wireless/ti/wl18xx/wl18xx.h +@@ -42,6 +42,8 @@ + + #define WL18XX_RX_BA_MAX_SESSIONS 5 + ++#define WL18XX_MAX_LINKS 12 ++ + struct wl18xx_priv { + /* buffer for sending commands to FW */ + u8 cmd_buf[WL18XX_CMD_MAX_SIZE]; +@@ -114,7 +116,7 @@ struct wl18xx_fw_packet_counters { + u8 tx_released_pkts[NUM_TX_QUEUES]; + + /* Cumulative counter of freed packets per HLID */ +- u8 tx_lnk_free_pkts[WL12XX_MAX_LINKS]; ++ u8 tx_lnk_free_pkts[WL18XX_MAX_LINKS]; + + /* Cumulative counter of released Voice memory blocks */ + u8 tx_voice_released_blks; +diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c +index 4d19fd2..ab5ca32 100644 +--- a/drivers/net/wireless/ti/wlcore/cmd.c ++++ b/drivers/net/wireless/ti/wlcore/cmd.c +@@ -312,8 +312,8 @@ static int wlcore_get_new_session_id(struct wl1271 *wl, u8 hlid) + int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid) + { + unsigned long flags; +- u8 link = find_first_zero_bit(wl->links_map, WL12XX_MAX_LINKS); +- if (link >= WL12XX_MAX_LINKS) ++ u8 link = find_first_zero_bit(wl->links_map, wl->num_links); ++ if (link >= wl->num_links) + return -EBUSY; + + wl->session_ids[link] = wlcore_get_new_session_id(wl, link); +diff --git a/drivers/net/wireless/ti/wlcore/event.c b/drivers/net/wireless/ti/wlcore/event.c +index 8d3b349..1f9a360 100644 +--- a/drivers/net/wireless/ti/wlcore/event.c ++++ b/drivers/net/wireless/ti/wlcore/event.c +@@ -67,7 +67,7 @@ static void wl1271_stop_ba_event(struct wl1271 *wl, struct wl12xx_vif *wlvif) + u8 hlid; + struct wl1271_link *lnk; + for_each_set_bit(hlid, wlvif->ap.sta_hlid_map, +- WL12XX_MAX_LINKS) { ++ wl->num_links) { + lnk = &wl->links[hlid]; + if (!lnk->ba_bitmap) + continue; +@@ -172,7 +172,7 @@ static void wlcore_disconnect_sta(struct wl1271 *wl, unsigned long sta_bitmap) + const u8 *addr; + int h; + +- for_each_set_bit(h, &sta_bitmap, WL12XX_MAX_LINKS) { ++ for_each_set_bit(h, &sta_bitmap, wl->num_links) { + bool found = false; + /* find the ap vif connected to this sta */ + wl12xx_for_each_wlvif_ap(wl, wlvif) { +diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c +index 70a3e57..c35d1dc 100644 +--- a/drivers/net/wireless/ti/wlcore/main.c ++++ b/drivers/net/wireless/ti/wlcore/main.c +@@ -372,7 +372,7 @@ static void wl12xx_irq_update_links_status(struct wl1271 *wl, + wl->ap_fw_ps_map = cur_fw_ps_map; + } + +- for_each_set_bit(hlid, wlvif->ap.sta_hlid_map, WL12XX_MAX_LINKS) ++ for_each_set_bit(hlid, wlvif->ap.sta_hlid_map, wl->num_links) + wl12xx_irq_ps_regulate_link(wl, wlvif, hlid, + wl->links[hlid].allocated_pkts); + } +@@ -412,7 +412,7 @@ static int wlcore_fw_status(struct wl1271 *wl, struct wl_fw_status *status) + } + + +- for_each_set_bit(i, wl->links_map, WL12XX_MAX_LINKS) { ++ for_each_set_bit(i, wl->links_map, wl->num_links) { + u8 diff; + lnk = &wl->links[i]; + +@@ -5855,7 +5855,7 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size, + int i, j, ret; + unsigned int order; + +- BUILD_BUG_ON(AP_MAX_STATIONS > WL12XX_MAX_LINKS); ++ BUILD_BUG_ON(AP_MAX_STATIONS > WLCORE_MAX_LINKS); + + hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops); + if (!hw) { +@@ -5878,8 +5878,12 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size, + + wl->hw = hw; + ++ /* ++ * wl->num_links is not configured yet, so just use WLCORE_MAX_LINKS. ++ * we don't allocate any additional resource here, so that's fine. ++ */ + for (i = 0; i < NUM_TX_QUEUES; i++) +- for (j = 0; j < WL12XX_MAX_LINKS; j++) ++ for (j = 0; j < WLCORE_MAX_LINKS; j++) + skb_queue_head_init(&wl->links[j].tx_queue[i]); + + skb_queue_head_init(&wl->deferred_rx_queue); +diff --git a/drivers/net/wireless/ti/wlcore/rx.c b/drivers/net/wireless/ti/wlcore/rx.c +index a047e87..e125974 100644 +--- a/drivers/net/wireless/ti/wlcore/rx.c ++++ b/drivers/net/wireless/ti/wlcore/rx.c +@@ -205,7 +205,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length, + + int wlcore_rx(struct wl1271 *wl, struct wl_fw_status *status) + { +- unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0}; ++ unsigned long active_hlids[BITS_TO_LONGS(WLCORE_MAX_LINKS)] = {0}; + u32 buf_size; + u32 fw_rx_counter = status->fw_rx_counter % wl->num_rx_desc; + u32 drv_rx_counter = wl->rx_counter % wl->num_rx_desc; +@@ -263,12 +263,12 @@ int wlcore_rx(struct wl1271 *wl, struct wl_fw_status *status) + wl->aggr_buf + pkt_offset, + pkt_len, rx_align, + &hlid) == 1) { +- if (hlid < WL12XX_MAX_LINKS) ++ if (hlid < wl->num_links) + __set_bit(hlid, active_hlids); + else + WARN(1, +- "hlid exceeded WL12XX_MAX_LINKS " +- "(%d)\n", hlid); ++ "hlid (%d) exceeded MAX_LINKS\n", ++ hlid); + } + + wl->rx_counter++; +diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c +index ca886ef..06ab5c6 100644 +--- a/drivers/net/wireless/ti/wlcore/tx.c ++++ b/drivers/net/wireless/ti/wlcore/tx.c +@@ -565,11 +565,11 @@ static struct sk_buff *wlcore_vif_dequeue_high_prio(struct wl1271 *wl, + int i, h, start_hlid; + + /* start from the link after the last one */ +- start_hlid = (wlvif->last_tx_hlid + 1) % WL12XX_MAX_LINKS; ++ start_hlid = (wlvif->last_tx_hlid + 1) % wl->num_links; + + /* dequeue according to AC, round robin on each link */ +- for (i = 0; i < WL12XX_MAX_LINKS; i++) { +- h = (start_hlid + i) % WL12XX_MAX_LINKS; ++ for (i = 0; i < wl->num_links; i++) { ++ h = (start_hlid + i) % wl->num_links; + + /* only consider connected stations */ + if (!test_bit(h, wlvif->links_map)) +@@ -693,8 +693,8 @@ static void wl1271_skb_queue_head(struct wl1271 *wl, struct wl12xx_vif *wlvif, + skb_queue_head(&wl->links[hlid].tx_queue[q], skb); + + /* make sure we dequeue the same packet next time */ +- wlvif->last_tx_hlid = (hlid + WL12XX_MAX_LINKS - 1) % +- WL12XX_MAX_LINKS; ++ wlvif->last_tx_hlid = (hlid + wl->num_links - 1) % ++ wl->num_links; + } + + spin_lock_irqsave(&wl->wl_lock, flags); +@@ -727,7 +727,7 @@ void wl12xx_rearm_rx_streaming(struct wl1271 *wl, unsigned long *active_hlids) + timeout = wl->conf.rx_streaming.duration; + wl12xx_for_each_wlvif_sta(wl, wlvif) { + bool found = false; +- for_each_set_bit(hlid, active_hlids, WL12XX_MAX_LINKS) { ++ for_each_set_bit(hlid, active_hlids, wl->num_links) { + if (test_bit(hlid, wlvif->links_map)) { + found = true; + break; +@@ -764,7 +764,7 @@ int wlcore_tx_work_locked(struct wl1271 *wl) + struct wl1271_tx_hw_descr *desc; + u32 buf_offset = 0, last_len = 0; + bool sent_packets = false; +- unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0}; ++ unsigned long active_hlids[BITS_TO_LONGS(WLCORE_MAX_LINKS)] = {0}; + int ret = 0; + int bus_ret = 0; + u8 hlid; +@@ -1066,7 +1066,7 @@ void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif) + int i; + + /* TX failure */ +- for_each_set_bit(i, wlvif->links_map, WL12XX_MAX_LINKS) { ++ for_each_set_bit(i, wlvif->links_map, wl->num_links) { + if (wlvif->bss_type == BSS_TYPE_AP_BSS && + i != wlvif->ap.bcast_hlid && i != wlvif->ap.global_hlid) { + /* this calls wl12xx_free_link */ +@@ -1090,7 +1090,7 @@ void wl12xx_tx_reset(struct wl1271 *wl) + + /* only reset the queues if something bad happened */ + if (wl1271_tx_total_queue_count(wl) != 0) { +- for (i = 0; i < WL12XX_MAX_LINKS; i++) ++ for (i = 0; i < wl->num_links; i++) + wl1271_tx_reset_link_queues(wl, i); + + for (i = 0; i < NUM_TX_QUEUES; i++) +@@ -1183,7 +1183,7 @@ void wl1271_tx_flush(struct wl1271 *wl) + WL1271_TX_FLUSH_TIMEOUT / 1000); + + /* forcibly flush all Tx buffers on our queues */ +- for (i = 0; i < WL12XX_MAX_LINKS; i++) ++ for (i = 0; i < wl->num_links; i++) + wl1271_tx_reset_link_queues(wl, i); + + out_wake: +diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h +index cec5265..98b1875 100644 +--- a/drivers/net/wireless/ti/wlcore/wlcore.h ++++ b/drivers/net/wireless/ti/wlcore/wlcore.h +@@ -222,7 +222,7 @@ struct wl1271 { + int channel; + u8 system_hlid; + +- unsigned long links_map[BITS_TO_LONGS(WL12XX_MAX_LINKS)]; ++ unsigned long links_map[BITS_TO_LONGS(WLCORE_MAX_LINKS)]; + unsigned long roles_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)]; + unsigned long roc_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)]; + unsigned long rate_policies_map[ +@@ -230,7 +230,7 @@ struct wl1271 { + unsigned long klv_templates_map[ + BITS_TO_LONGS(WLCORE_MAX_KLV_TEMPLATES)]; + +- u8 session_ids[WL12XX_MAX_LINKS]; ++ u8 session_ids[WLCORE_MAX_LINKS]; + + struct list_head wlvif_list; + +@@ -378,7 +378,7 @@ struct wl1271 { + * AP-mode - links indexed by HLID. The global and broadcast links + * are always active. + */ +- struct wl1271_link links[WL12XX_MAX_LINKS]; ++ struct wl1271_link links[WLCORE_MAX_LINKS]; + + /* number of currently active links */ + int active_link_count; +@@ -436,6 +436,8 @@ struct wl1271 { + u32 num_tx_desc; + /* number of RX descriptors the HW supports. */ + u32 num_rx_desc; ++ /* number of links the HW supports */ ++ u8 num_links; + + /* translate HW Tx rates to standard rate-indices */ + const u8 **band_rate_to_idx; +diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h +index 32e1e8b..256d09b 100644 +--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h ++++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h +@@ -58,10 +58,15 @@ + #define WL1271_DEFAULT_DTIM_PERIOD 1 + + #define WL12XX_MAX_ROLES 4 +-#define WL12XX_MAX_LINKS 12 + #define WL12XX_INVALID_ROLE_ID 0xff + #define WL12XX_INVALID_LINK_ID 0xff + ++/* ++ * max number of links allowed by all HWs. ++ * this is NOT the actual max links supported by the current hw. ++ */ ++#define WLCORE_MAX_LINKS 12 ++ + /* the driver supports the 2.4Ghz and 5Ghz bands */ + #define WLCORE_NUM_BANDS 2 + +@@ -156,7 +161,7 @@ struct wl_fw_status { + + /* + * Cumulative counter of freed packets per HLID +- * (length of the array is WL12XX_MAX_LINKS) ++ * (length of the array is wl->num_links) + */ + u8 *tx_lnk_free_pkts; + +@@ -357,7 +362,7 @@ struct wl12xx_vif { + + /* HLIDs bitmap of associated stations */ + unsigned long sta_hlid_map[BITS_TO_LONGS( +- WL12XX_MAX_LINKS)]; ++ WLCORE_MAX_LINKS)]; + + /* recoreded keys - set here before AP startup */ + struct wl1271_ap_key *recorded_keys[MAX_NUM_KEYS]; +@@ -374,7 +379,7 @@ struct wl12xx_vif { + /* counters of packets per AC, across all links in the vif */ + int tx_queue_count[NUM_TX_QUEUES]; + +- unsigned long links_map[BITS_TO_LONGS(WL12XX_MAX_LINKS)]; ++ unsigned long links_map[BITS_TO_LONGS(WLCORE_MAX_LINKS)]; + + u8 ssid[IEEE80211_MAX_SSID_LEN + 1]; + u8 ssid_len; +-- +1.9.3 + diff --git a/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0007-wlcore-wl12xx-wl18xx-configure-max_stations-per-hw.patch b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0007-wlcore-wl12xx-wl18xx-configure-max_stations-per-hw.patch new file mode 100644 index 0000000..03b1e11 --- /dev/null +++ b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0007-wlcore-wl12xx-wl18xx-configure-max_stations-per-hw.patch @@ -0,0 +1,132 @@ +From 32f0fd5b700064f821105be041d0075decc4ec64 Mon Sep 17 00:00:00 2001 +From: Eliad Peller <el...@wizery.com> +Date: Mon, 10 Feb 2014 13:47:23 +0200 +Subject: [PATCH 07/18] wlcore/wl12xx/wl18xx: configure max_stations per-hw + +Each hw supports a different max stations (connected to the +same ap). add a new wl->max_ap_stations and use it instead +of the current common AP_MAX_STATIONS. + +Signed-off-by: Eliad Peller <el...@wizery.com> +Signed-off-by: John W. Linville <linvi...@tuxdriver.com> +--- + drivers/net/wireless/ti/wl12xx/main.c | 2 ++ + drivers/net/wireless/ti/wl12xx/wl12xx.h | 1 + + drivers/net/wireless/ti/wl18xx/main.c | 2 ++ + drivers/net/wireless/ti/wl18xx/wl18xx.h | 1 + + drivers/net/wireless/ti/wlcore/main.c | 4 +--- + drivers/net/wireless/ti/wlcore/wlcore.h | 2 ++ + drivers/net/wireless/ti/wlcore/wlcore_i.h | 2 -- + 7 files changed, 9 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c +index 69df5bc..f486f0f 100644 +--- a/drivers/net/wireless/ti/wl12xx/main.c ++++ b/drivers/net/wireless/ti/wl12xx/main.c +@@ -1750,11 +1750,13 @@ static int wl12xx_setup(struct wl1271 *wl) + struct wl12xx_platform_data *pdata = pdev_data->pdata; + + BUILD_BUG_ON(WL12XX_MAX_LINKS > WLCORE_MAX_LINKS); ++ BUILD_BUG_ON(WL12XX_MAX_AP_STATIONS > WL12XX_MAX_LINKS); + + wl->rtable = wl12xx_rtable; + wl->num_tx_desc = WL12XX_NUM_TX_DESCRIPTORS; + wl->num_rx_desc = WL12XX_NUM_RX_DESCRIPTORS; + wl->num_links = WL12XX_MAX_LINKS; ++ wl->max_ap_stations = WL12XX_MAX_AP_STATIONS; + wl->num_channels = 1; + wl->num_mac_addr = WL12XX_NUM_MAC_ADDRESSES; + wl->band_rate_to_idx = wl12xx_band_rate_to_idx; +diff --git a/drivers/net/wireless/ti/wl12xx/wl12xx.h b/drivers/net/wireless/ti/wl12xx/wl12xx.h +index 26b1a3f..75c9265 100644 +--- a/drivers/net/wireless/ti/wl12xx/wl12xx.h ++++ b/drivers/net/wireless/ti/wl12xx/wl12xx.h +@@ -65,6 +65,7 @@ + + #define WL12XX_RX_BA_MAX_SESSIONS 3 + ++#define WL12XX_MAX_AP_STATIONS 8 + #define WL12XX_MAX_LINKS 12 + + struct wl127x_rx_mem_pool_addr { +diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c +index 6011b22..f19e9b5 100644 +--- a/drivers/net/wireless/ti/wl18xx/main.c ++++ b/drivers/net/wireless/ti/wl18xx/main.c +@@ -1753,11 +1753,13 @@ static int wl18xx_setup(struct wl1271 *wl) + int ret; + + BUILD_BUG_ON(WL18XX_MAX_LINKS > WLCORE_MAX_LINKS); ++ BUILD_BUG_ON(WL18XX_MAX_AP_STATIONS > WL18XX_MAX_LINKS); + + wl->rtable = wl18xx_rtable; + wl->num_tx_desc = WL18XX_NUM_TX_DESCRIPTORS; + wl->num_rx_desc = WL18XX_NUM_RX_DESCRIPTORS; + wl->num_links = WL18XX_MAX_LINKS; ++ wl->max_ap_stations = WL18XX_MAX_AP_STATIONS; + wl->num_channels = 2; + wl->num_mac_addr = WL18XX_NUM_MAC_ADDRESSES; + wl->band_rate_to_idx = wl18xx_band_rate_to_idx; +diff --git a/drivers/net/wireless/ti/wl18xx/wl18xx.h b/drivers/net/wireless/ti/wl18xx/wl18xx.h +index 38174e9..9785bf8 100644 +--- a/drivers/net/wireless/ti/wl18xx/wl18xx.h ++++ b/drivers/net/wireless/ti/wl18xx/wl18xx.h +@@ -42,6 +42,7 @@ + + #define WL18XX_RX_BA_MAX_SESSIONS 5 + ++#define WL18XX_MAX_AP_STATIONS 8 + #define WL18XX_MAX_LINKS 12 + + struct wl18xx_priv { +diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c +index c35d1dc..b649726 100644 +--- a/drivers/net/wireless/ti/wlcore/main.c ++++ b/drivers/net/wireless/ti/wlcore/main.c +@@ -4662,7 +4662,7 @@ static int wl1271_allocate_sta(struct wl1271 *wl, + int ret; + + +- if (wl->active_sta_count >= AP_MAX_STATIONS) { ++ if (wl->active_sta_count >= wl->max_ap_stations) { + wl1271_warning("could not allocate HLID - too much stations"); + return -EBUSY; + } +@@ -5855,8 +5855,6 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size, + int i, j, ret; + unsigned int order; + +- BUILD_BUG_ON(AP_MAX_STATIONS > WLCORE_MAX_LINKS); +- + hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops); + if (!hw) { + wl1271_error("could not alloc ieee80211_hw"); +diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h +index 98b1875..2356bdd 100644 +--- a/drivers/net/wireless/ti/wlcore/wlcore.h ++++ b/drivers/net/wireless/ti/wlcore/wlcore.h +@@ -438,6 +438,8 @@ struct wl1271 { + u32 num_rx_desc; + /* number of links the HW supports */ + u8 num_links; ++ /* max stations a single AP can support */ ++ u8 max_ap_stations; + + /* translate HW Tx rates to standard rate-indices */ + const u8 **band_rate_to_idx; +diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h +index 256d09b..a53a37f 100644 +--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h ++++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h +@@ -123,8 +123,6 @@ struct wl1271_chip { + + #define NUM_TX_QUEUES 4 + +-#define AP_MAX_STATIONS 8 +- + struct wl_fw_status { + u32 intr; + u8 fw_rx_counter; +-- +1.9.3 + diff --git a/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0008-wlcore-wl12xx-wl18xx-configure-iface_combinations-pe.patch b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0008-wlcore-wl12xx-wl18xx-configure-iface_combinations-pe.patch new file mode 100644 index 0000000..8cb6289 --- /dev/null +++ b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0008-wlcore-wl12xx-wl18xx-configure-iface_combinations-pe.patch @@ -0,0 +1,193 @@ +From abf0b24912640c4fa94b0a2f22ee9d51c8521b16 Mon Sep 17 00:00:00 2001 +From: Eliad Peller <el...@wizery.com> +Date: Mon, 10 Feb 2014 13:47:24 +0200 +Subject: [PATCH 08/18] wlcore/wl12xx/wl18xx: configure iface_combinations + per-hw + +Each hw supports a different iface combinations. +Define the supported combinations in each driver, +and save it in wl->iface_combinations. + +Since each driver defines its own combinations now, +it can also define its max supported channels, so +we no longer need to save and set it explicitly +in wlcore. + +Update wl18xx interface combinations to allow +multiple APs. + +Signed-off-by: Eliad Peller <el...@wizery.com> +Signed-off-by: John W. Linville <linvi...@tuxdriver.com> +--- + drivers/net/wireless/ti/wl12xx/main.c | 26 +++++++++++++++++++++- + drivers/net/wireless/ti/wl18xx/main.c | 39 ++++++++++++++++++++++++++++++++- + drivers/net/wireless/ti/wlcore/main.c | 28 ++--------------------- + drivers/net/wireless/ti/wlcore/wlcore.h | 5 +++-- + 4 files changed, 68 insertions(+), 30 deletions(-) + +diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c +index f486f0f..33071a7 100644 +--- a/drivers/net/wireless/ti/wl12xx/main.c ++++ b/drivers/net/wireless/ti/wl12xx/main.c +@@ -1743,6 +1743,29 @@ static struct ieee80211_sta_ht_cap wl12xx_ht_cap = { + }, + }; + ++static const struct ieee80211_iface_limit wl12xx_iface_limits[] = { ++ { ++ .max = 3, ++ .types = BIT(NL80211_IFTYPE_STATION), ++ }, ++ { ++ .max = 1, ++ .types = BIT(NL80211_IFTYPE_AP) | ++ BIT(NL80211_IFTYPE_P2P_GO) | ++ BIT(NL80211_IFTYPE_P2P_CLIENT), ++ }, ++}; ++ ++static const struct ieee80211_iface_combination ++wl12xx_iface_combinations[] = { ++ { ++ .max_interfaces = 3, ++ .limits = wl12xx_iface_limits, ++ .n_limits = ARRAY_SIZE(wl12xx_iface_limits), ++ .num_different_channels = 1, ++ }, ++}; ++ + static int wl12xx_setup(struct wl1271 *wl) + { + struct wl12xx_priv *priv = wl->priv; +@@ -1757,7 +1780,8 @@ static int wl12xx_setup(struct wl1271 *wl) + wl->num_rx_desc = WL12XX_NUM_RX_DESCRIPTORS; + wl->num_links = WL12XX_MAX_LINKS; + wl->max_ap_stations = WL12XX_MAX_AP_STATIONS; +- wl->num_channels = 1; ++ wl->iface_combinations = wl12xx_iface_combinations; ++ wl->n_iface_combinations = ARRAY_SIZE(wl12xx_iface_combinations); + wl->num_mac_addr = WL12XX_NUM_MAC_ADDRESSES; + wl->band_rate_to_idx = wl12xx_band_rate_to_idx; + wl->hw_tx_rate_tbl_size = WL12XX_CONF_HW_RXTX_RATE_MAX; +diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c +index f19e9b5..966a866 100644 +--- a/drivers/net/wireless/ti/wl18xx/main.c ++++ b/drivers/net/wireless/ti/wl18xx/main.c +@@ -1747,6 +1747,42 @@ static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap_2ghz = { + }, + }; + ++static const struct ieee80211_iface_limit wl18xx_iface_limits[] = { ++ { ++ .max = 3, ++ .types = BIT(NL80211_IFTYPE_STATION), ++ }, ++ { ++ .max = 1, ++ .types = BIT(NL80211_IFTYPE_AP) | ++ BIT(NL80211_IFTYPE_P2P_GO) | ++ BIT(NL80211_IFTYPE_P2P_CLIENT), ++ }, ++}; ++ ++static const struct ieee80211_iface_limit wl18xx_iface_ap_limits[] = { ++ { ++ .max = 2, ++ .types = BIT(NL80211_IFTYPE_AP), ++ }, ++}; ++ ++static const struct ieee80211_iface_combination ++wl18xx_iface_combinations[] = { ++ { ++ .max_interfaces = 3, ++ .limits = wl18xx_iface_limits, ++ .n_limits = ARRAY_SIZE(wl18xx_iface_limits), ++ .num_different_channels = 2, ++ }, ++ { ++ .max_interfaces = 2, ++ .limits = wl18xx_iface_ap_limits, ++ .n_limits = ARRAY_SIZE(wl18xx_iface_ap_limits), ++ .num_different_channels = 1, ++ } ++}; ++ + static int wl18xx_setup(struct wl1271 *wl) + { + struct wl18xx_priv *priv = wl->priv; +@@ -1760,7 +1796,8 @@ static int wl18xx_setup(struct wl1271 *wl) + wl->num_rx_desc = WL18XX_NUM_RX_DESCRIPTORS; + wl->num_links = WL18XX_MAX_LINKS; + wl->max_ap_stations = WL18XX_MAX_AP_STATIONS; +- wl->num_channels = 2; ++ wl->iface_combinations = wl18xx_iface_combinations; ++ wl->n_iface_combinations = ARRAY_SIZE(wl18xx_iface_combinations); + wl->num_mac_addr = WL18XX_NUM_MAC_ADDRESSES; + wl->band_rate_to_idx = wl18xx_band_rate_to_idx; + wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX; +diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c +index b649726..d16fb7e 100644 +--- a/drivers/net/wireless/ti/wlcore/main.c ++++ b/drivers/net/wireless/ti/wlcore/main.c +@@ -5690,28 +5690,6 @@ static void wl1271_unregister_hw(struct wl1271 *wl) + + } + +-static const struct ieee80211_iface_limit wlcore_iface_limits[] = { +- { +- .max = 3, +- .types = BIT(NL80211_IFTYPE_STATION), +- }, +- { +- .max = 1, +- .types = BIT(NL80211_IFTYPE_AP) | +- BIT(NL80211_IFTYPE_P2P_GO) | +- BIT(NL80211_IFTYPE_P2P_CLIENT), +- }, +-}; +- +-static struct ieee80211_iface_combination +-wlcore_iface_combinations[] = { +- { +- .max_interfaces = 3, +- .limits = wlcore_iface_limits, +- .n_limits = ARRAY_SIZE(wlcore_iface_limits), +- }, +-}; +- + static int wl1271_init_ieee80211(struct wl1271 *wl) + { + int i; +@@ -5832,10 +5810,8 @@ static int wl1271_init_ieee80211(struct wl1271 *wl) + NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P; + + /* allowed interface combinations */ +- wlcore_iface_combinations[0].num_different_channels = wl->num_channels; +- wl->hw->wiphy->iface_combinations = wlcore_iface_combinations; +- wl->hw->wiphy->n_iface_combinations = +- ARRAY_SIZE(wlcore_iface_combinations); ++ wl->hw->wiphy->iface_combinations = wl->iface_combinations; ++ wl->hw->wiphy->n_iface_combinations = wl->n_iface_combinations; + + SET_IEEE80211_DEV(wl->hw, wl->dev); + +diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h +index 2356bdd..a1cc1c6 100644 +--- a/drivers/net/wireless/ti/wlcore/wlcore.h ++++ b/drivers/net/wireless/ti/wlcore/wlcore.h +@@ -483,8 +483,9 @@ struct wl1271 { + + struct completion nvs_loading_complete; + +- /* number of concurrent channels the HW supports */ +- u32 num_channels; ++ /* interface combinations supported by the hw */ ++ const struct ieee80211_iface_combination *iface_combinations; ++ u8 n_iface_combinations; + }; + + int wlcore_probe(struct wl1271 *wl, struct platform_device *pdev); +-- +1.9.3 + diff --git a/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0009-wl18xx-move-to-new-firmware-wl18xx-fw-3.bin.patch b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0009-wl18xx-move-to-new-firmware-wl18xx-fw-3.bin.patch new file mode 100644 index 0000000..59f40b4 --- /dev/null +++ b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0009-wl18xx-move-to-new-firmware-wl18xx-fw-3.bin.patch @@ -0,0 +1,226 @@ +From 028e7243ac411c3aba7a754bcc775c2fbb0b3e5c Mon Sep 17 00:00:00 2001 +From: Eliad Peller <el...@wizery.com> +Date: Mon, 10 Feb 2014 13:47:25 +0200 +Subject: [PATCH 09/18] wl18xx: move to new firmware (wl18xx-fw-3.bin) + +Bump the min wl18xx fw version to 8.8.0.0.13 + +This fw is not backward compatible with older +firmware (due to api changes), so use bump +the firmware name as well. + +Some modifications were done to the driver-fw api +in order to support multiple APs. + +Additionally, some of the consts (such as max stations, +max links and max RX BA sessions) were changed. + +Signed-off-by: Arik Nemtsov <a...@wizery.com> +Signed-off-by: Eliad Peller <el...@wizery.com> +Signed-off-by: John W. Linville <linvi...@tuxdriver.com> +--- + drivers/net/wireless/ti/wl18xx/main.c | 2 +- + drivers/net/wireless/ti/wl18xx/wl18xx.h | 10 +++++----- + drivers/net/wireless/ti/wlcore/acx.c | 4 +++- + drivers/net/wireless/ti/wlcore/acx.h | 6 ++++-- + drivers/net/wireless/ti/wlcore/cmd.c | 5 ++++- + drivers/net/wireless/ti/wlcore/cmd.h | 7 +++++-- + drivers/net/wireless/ti/wlcore/main.c | 2 +- + drivers/net/wireless/ti/wlcore/tx.c | 2 +- + drivers/net/wireless/ti/wlcore/wlcore_i.h | 2 +- + 9 files changed, 25 insertions(+), 15 deletions(-) + +diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c +index 966a866..de5b4fa 100644 +--- a/drivers/net/wireless/ti/wl18xx/main.c ++++ b/drivers/net/wireless/ti/wl18xx/main.c +@@ -648,7 +648,7 @@ static const struct wl18xx_clk_cfg wl18xx_clk_table[NUM_CLOCK_CONFIGS] = { + }; + + /* TODO: maybe move to a new header file? */ +-#define WL18XX_FW_NAME "ti-connectivity/wl18xx-fw-2.bin" ++#define WL18XX_FW_NAME "ti-connectivity/wl18xx-fw-3.bin" + + static int wl18xx_identify_chip(struct wl1271 *wl) + { +diff --git a/drivers/net/wireless/ti/wl18xx/wl18xx.h b/drivers/net/wireless/ti/wl18xx/wl18xx.h +index 9785bf8..eb7cfe8 100644 +--- a/drivers/net/wireless/ti/wl18xx/wl18xx.h ++++ b/drivers/net/wireless/ti/wl18xx/wl18xx.h +@@ -26,10 +26,10 @@ + + /* minimum FW required for driver */ + #define WL18XX_CHIP_VER 8 +-#define WL18XX_IFTYPE_VER 5 ++#define WL18XX_IFTYPE_VER 8 + #define WL18XX_MAJOR_VER WLCORE_FW_VER_IGNORE + #define WL18XX_SUBTYPE_VER WLCORE_FW_VER_IGNORE +-#define WL18XX_MINOR_VER 39 ++#define WL18XX_MINOR_VER 13 + + #define WL18XX_CMD_MAX_SIZE 740 + +@@ -40,10 +40,10 @@ + + #define WL18XX_NUM_MAC_ADDRESSES 3 + +-#define WL18XX_RX_BA_MAX_SESSIONS 5 ++#define WL18XX_RX_BA_MAX_SESSIONS 13 + +-#define WL18XX_MAX_AP_STATIONS 8 +-#define WL18XX_MAX_LINKS 12 ++#define WL18XX_MAX_AP_STATIONS 10 ++#define WL18XX_MAX_LINKS 16 + + struct wl18xx_priv { + /* buffer for sending commands to FW */ +diff --git a/drivers/net/wireless/ti/wlcore/acx.c b/drivers/net/wireless/ti/wlcore/acx.c +index ec83675..71b244b 100644 +--- a/drivers/net/wireless/ti/wlcore/acx.c ++++ b/drivers/net/wireless/ti/wlcore/acx.c +@@ -1591,7 +1591,8 @@ out: + return ret; + } + +-int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr) ++int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, ++ struct wl12xx_vif *wlvif, u8 *addr) + { + struct wl1271_acx_inconnection_sta *acx = NULL; + int ret; +@@ -1603,6 +1604,7 @@ int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr) + return -ENOMEM; + + memcpy(acx->addr, addr, ETH_ALEN); ++ acx->role_id = wlvif->role_id; + + ret = wl1271_cmd_configure(wl, ACX_UPDATE_INCONNECTION_STA_LIST, + acx, sizeof(*acx)); +diff --git a/drivers/net/wireless/ti/wlcore/acx.h b/drivers/net/wireless/ti/wlcore/acx.h +index 6dcfad9..954d57e 100644 +--- a/drivers/net/wireless/ti/wlcore/acx.h ++++ b/drivers/net/wireless/ti/wlcore/acx.h +@@ -824,7 +824,8 @@ struct wl1271_acx_inconnection_sta { + struct acx_header header; + + u8 addr[ETH_ALEN]; +- u8 padding1[2]; ++ u8 role_id; ++ u8 padding; + } __packed; + + /* +@@ -1118,7 +1119,8 @@ int wl1271_acx_ps_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif, + bool enable); + int wl1271_acx_ap_max_tx_retry(struct wl1271 *wl, struct wl12xx_vif *wlvif); + int wl12xx_acx_config_ps(struct wl1271 *wl, struct wl12xx_vif *wlvif); +-int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr); ++int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, ++ struct wl12xx_vif *wlvif, u8 *addr); + int wl1271_acx_fm_coex(struct wl1271 *wl); + int wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl); + int wl12xx_acx_config_hangover(struct wl1271 *wl); +diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c +index ab5ca32..3463a67 100644 +--- a/drivers/net/wireless/ti/wlcore/cmd.c ++++ b/drivers/net/wireless/ti/wlcore/cmd.c +@@ -1532,6 +1532,7 @@ int wl12xx_cmd_add_peer(struct wl1271 *wl, struct wl12xx_vif *wlvif, + cmd->sp_len = sta->max_sp; + cmd->wmm = sta->wme ? 1 : 0; + cmd->session_id = wl->session_ids[hlid]; ++ cmd->role_id = wlvif->role_id; + + for (i = 0; i < NUM_ACCESS_CATEGORIES_COPY; i++) + if (sta->wme && (sta->uapsd_queues & BIT(i))) +@@ -1568,7 +1569,8 @@ out: + return ret; + } + +-int wl12xx_cmd_remove_peer(struct wl1271 *wl, u8 hlid) ++int wl12xx_cmd_remove_peer(struct wl1271 *wl, struct wl12xx_vif *wlvif, ++ u8 hlid) + { + struct wl12xx_cmd_remove_peer *cmd; + int ret; +@@ -1586,6 +1588,7 @@ int wl12xx_cmd_remove_peer(struct wl1271 *wl, u8 hlid) + /* We never send a deauth, mac80211 is in charge of this */ + cmd->reason_opcode = 0; + cmd->send_deauth_flag = 0; ++ cmd->role_id = wlvif->role_id; + + ret = wl1271_cmd_send(wl, CMD_REMOVE_PEER, cmd, sizeof(*cmd), 0); + if (ret < 0) { +diff --git a/drivers/net/wireless/ti/wlcore/cmd.h b/drivers/net/wireless/ti/wlcore/cmd.h +index 323d4a8..9cb3f44 100644 +--- a/drivers/net/wireless/ti/wlcore/cmd.h ++++ b/drivers/net/wireless/ti/wlcore/cmd.h +@@ -88,7 +88,8 @@ int wl12xx_roc(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 role_id, + int wl12xx_croc(struct wl1271 *wl, u8 role_id); + int wl12xx_cmd_add_peer(struct wl1271 *wl, struct wl12xx_vif *wlvif, + struct ieee80211_sta *sta, u8 hlid); +-int wl12xx_cmd_remove_peer(struct wl1271 *wl, u8 hlid); ++int wl12xx_cmd_remove_peer(struct wl1271 *wl, struct wl12xx_vif *wlvif, ++ u8 hlid); + void wlcore_set_pending_regdomain_ch(struct wl1271 *wl, u16 channel, + enum ieee80211_band band); + int wlcore_cmd_regdomain_config_locked(struct wl1271 *wl); +@@ -594,6 +595,8 @@ struct wl12xx_cmd_add_peer { + u8 sp_len; + u8 wmm; + u8 session_id; ++ u8 role_id; ++ u8 padding[3]; + } __packed; + + struct wl12xx_cmd_remove_peer { +@@ -602,7 +605,7 @@ struct wl12xx_cmd_remove_peer { + u8 hlid; + u8 reason_opcode; + u8 send_deauth_flag; +- u8 padding1; ++ u8 role_id; + } __packed; + + /* +diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c +index d16fb7e..73bf251 100644 +--- a/drivers/net/wireless/ti/wlcore/main.c ++++ b/drivers/net/wireless/ti/wlcore/main.c +@@ -4765,7 +4765,7 @@ static int wl12xx_sta_remove(struct wl1271 *wl, + if (WARN_ON(!test_bit(id, wlvif->ap.sta_hlid_map))) + return -EINVAL; + +- ret = wl12xx_cmd_remove_peer(wl, wl_sta->hlid); ++ ret = wl12xx_cmd_remove_peer(wl, wlvif, wl_sta->hlid); + if (ret < 0) + return ret; + +diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c +index 06ab5c6..9f7921d 100644 +--- a/drivers/net/wireless/ti/wlcore/tx.c ++++ b/drivers/net/wireless/ti/wlcore/tx.c +@@ -101,7 +101,7 @@ static void wl1271_tx_ap_update_inconnection_sta(struct wl1271 *wl, + * authentication response. this way it won't get de-authed by FW + * when transmitting too soon. + */ +- wl1271_acx_set_inconnection_sta(wl, hdr->addr1); ++ wl1271_acx_set_inconnection_sta(wl, wlvif, hdr->addr1); + + /* + * ROC for 1 second on the AP channel for completing the connection. +diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h +index a53a37f..756e890 100644 +--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h ++++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h +@@ -65,7 +65,7 @@ + * max number of links allowed by all HWs. + * this is NOT the actual max links supported by the current hw. + */ +-#define WLCORE_MAX_LINKS 12 ++#define WLCORE_MAX_LINKS 16 + + /* the driver supports the 2.4Ghz and 5Ghz bands */ + #define WLCORE_NUM_BANDS 2 +-- +1.9.3 + diff --git a/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0010-wlcore-send-EAPOL-frames-with-voice-priority.patch b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0010-wlcore-send-EAPOL-frames-with-voice-priority.patch new file mode 100644 index 0000000..790a859 --- /dev/null +++ b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0010-wlcore-send-EAPOL-frames-with-voice-priority.patch @@ -0,0 +1,49 @@ +From 2a5ad92e271e518281504eeeab1dd311351ff7b7 Mon Sep 17 00:00:00 2001 +From: Igal Chernobelsky <ig...@ti.com> +Date: Mon, 10 Feb 2014 13:47:26 +0200 +Subject: [PATCH 10/18] wlcore: send EAPOL frames with voice priority + +Send EAPOL frames with voice priority by setting (the new) +TX_HW_ATTR_EAPOL_FRAME bit in tx attribute. + +Sending EAPOL with voice priority fixes re-key +timeout issues during heavy traffic. + +Signed-off-by: Igal Chernobelsky <ig...@ti.com> +Signed-off-by: Eliad Peller <el...@wizery.com> +Signed-off-by: John W. Linville <linvi...@tuxdriver.com> +--- + drivers/net/wireless/ti/wlcore/tx.c | 4 ++++ + drivers/net/wireless/ti/wlcore/tx.h | 1 + + 2 files changed, 5 insertions(+) + +diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c +index 9f7921d..38b31a0 100644 +--- a/drivers/net/wireless/ti/wlcore/tx.c ++++ b/drivers/net/wireless/ti/wlcore/tx.c +@@ -362,6 +362,10 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif, + ieee80211_has_protected(frame_control)) + tx_attr |= TX_HW_ATTR_HOST_ENCRYPT; + ++ /* send EAPOL frames as voice */ ++ if (control->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO) ++ tx_attr |= TX_HW_ATTR_EAPOL_FRAME; ++ + desc->tx_attr = cpu_to_le16(tx_attr); + + wlcore_hw_set_tx_desc_csum(wl, desc, skb); +diff --git a/drivers/net/wireless/ti/wlcore/tx.h b/drivers/net/wireless/ti/wlcore/tx.h +index 35489c3..79cb3ff 100644 +--- a/drivers/net/wireless/ti/wlcore/tx.h ++++ b/drivers/net/wireless/ti/wlcore/tx.h +@@ -37,6 +37,7 @@ + #define TX_HW_ATTR_TX_CMPLT_REQ BIT(12) + #define TX_HW_ATTR_TX_DUMMY_REQ BIT(13) + #define TX_HW_ATTR_HOST_ENCRYPT BIT(14) ++#define TX_HW_ATTR_EAPOL_FRAME BIT(15) + + #define TX_HW_ATTR_OFST_SAVE_RETRIES 0 + #define TX_HW_ATTR_OFST_HEADER_PAD 1 +-- +1.9.3 + diff --git a/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0011-wlcore-don-t-stop-sched_scan-on-interface-removal.patch b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0011-wlcore-don-t-stop-sched_scan-on-interface-removal.patch new file mode 100644 index 0000000..ff26330 --- /dev/null +++ b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0011-wlcore-don-t-stop-sched_scan-on-interface-removal.patch @@ -0,0 +1,35 @@ +From 5a441f5ff75daf9c3c6657a66e2806a1255f5b84 Mon Sep 17 00:00:00 2001 +From: Barak Bercovitz <ba...@wizery.com> +Date: Mon, 10 Feb 2014 13:47:27 +0200 +Subject: [PATCH 11/18] wlcore: don't stop sched_scan on interface removal + +Stopping sched scan on interface removal (during recovery) +is no longer needed, as sched scanning is automatically +restarted by mac80211. + +Signed-off-by: Barak Bercovitz <ba...@wizery.com> +Signed-off-by: Eliad Peller <el...@wizery.com> +Signed-off-by: John W. Linville <linvi...@tuxdriver.com> +--- + drivers/net/wireless/ti/wlcore/main.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c +index 73bf251..bea2938 100644 +--- a/drivers/net/wireless/ti/wlcore/main.c ++++ b/drivers/net/wireless/ti/wlcore/main.c +@@ -2582,10 +2582,8 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl, + ieee80211_scan_completed(wl->hw, true); + } + +- if (wl->sched_vif == wlvif) { +- ieee80211_sched_scan_stopped(wl->hw); ++ if (wl->sched_vif == wlvif) + wl->sched_vif = NULL; +- } + + if (wl->roc_vif == vif) { + wl->roc_vif = NULL; +-- +1.9.3 + diff --git a/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0012-wlcore-wl18xx-allow-CCK-rates-for-AP-mode.patch b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0012-wlcore-wl18xx-allow-CCK-rates-for-AP-mode.patch new file mode 100644 index 0000000..fb89d6b --- /dev/null +++ b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0012-wlcore-wl18xx-allow-CCK-rates-for-AP-mode.patch @@ -0,0 +1,61 @@ +From bc566f9203c2813a2e083677eb99c62b1cb14d03 Mon Sep 17 00:00:00 2001 +From: Arik Nemtsov <a...@wizery.com> +Date: Mon, 10 Feb 2014 13:47:28 +0200 +Subject: [PATCH 12/18] wlcore: wl18xx: allow CCK rates for AP mode + +12xx chips allow only OFDM rates in AP mode for BT-Coex purposes. This +is no longer required in 18xx chips, starting with FW 8.6.0.0.8. + +Update the min allowed FW version in 18xx to support this functionality. + +Signed-off-by: Arik Nemtsov <a...@wizery.com> +Signed-off-by: Eliad Peller <el...@wizery.com> +Signed-off-by: John W. Linville <linvi...@tuxdriver.com> +--- + drivers/net/wireless/ti/wl12xx/main.c | 1 + + drivers/net/wireless/ti/wlcore/init.c | 2 +- + drivers/net/wireless/ti/wlcore/wlcore.h | 3 +++ + 3 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c +index 33071a7..d50dfac 100644 +--- a/drivers/net/wireless/ti/wl12xx/main.c ++++ b/drivers/net/wireless/ti/wl12xx/main.c +@@ -1789,6 +1789,7 @@ static int wl12xx_setup(struct wl1271 *wl) + wl->fw_status_len = sizeof(struct wl12xx_fw_status); + wl->fw_status_priv_len = 0; + wl->stats.fw_stats_len = sizeof(struct wl12xx_acx_statistics); ++ wl->ofdm_only_ap = true; + wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ, &wl12xx_ht_cap); + wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ, &wl12xx_ht_cap); + wl12xx_conf_init(wl); +diff --git a/drivers/net/wireless/ti/wlcore/init.c b/drivers/net/wireless/ti/wlcore/init.c +index 7699f9d..b376c99 100644 +--- a/drivers/net/wireless/ti/wlcore/init.c ++++ b/drivers/net/wireless/ti/wlcore/init.c +@@ -462,7 +462,7 @@ int wl1271_init_ap_rates(struct wl1271 *wl, struct wl12xx_vif *wlvif) + * If the basic rates contain OFDM rates, use OFDM only + * rates for unicast TX as well. Else use all supported rates. + */ +- if ((wlvif->basic_rate_set & CONF_TX_OFDM_RATES)) ++ if (wl->ofdm_only_ap && (wlvif->basic_rate_set & CONF_TX_OFDM_RATES)) + supported_rates = CONF_TX_OFDM_RATES; + else + supported_rates = CONF_TX_ENABLED_RATES; +diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h +index a1cc1c6..95a5450 100644 +--- a/drivers/net/wireless/ti/wlcore/wlcore.h ++++ b/drivers/net/wireless/ti/wlcore/wlcore.h +@@ -407,6 +407,9 @@ struct wl1271 { + /* AP-mode - number of currently connected stations */ + int active_sta_count; + ++ /* Flag determining whether AP should broadcast OFDM-only rates */ ++ bool ofdm_only_ap; ++ + /* last wlvif we transmitted from */ + struct wl12xx_vif *last_wlvif; + +-- +1.9.3 + diff --git a/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0013-wlcore-don-t-handle-unsetting-of-default-wep-key.patch b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0013-wlcore-don-t-handle-unsetting-of-default-wep-key.patch new file mode 100644 index 0000000..b523d7d --- /dev/null +++ b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0013-wlcore-don-t-handle-unsetting-of-default-wep-key.patch @@ -0,0 +1,38 @@ +From bf4e5f1ac0e2b277424ec0d035b1fbab46dd66bb Mon Sep 17 00:00:00 2001 +From: Eliad Peller <el...@wizery.com> +Date: Mon, 10 Feb 2014 13:47:29 +0200 +Subject: [PATCH 13/18] wlcore: don't handle unsetting of default wep key + +mac80211 unsets the default wep key on disassoc. +The fw doesn't support this notification, so simply +ignore it. + +The actual flow actually triggers fw recovery in some +cases, as mac80211 unsets the default key only after +disassoc, when wlvif->sta.hlid, resulting in invalid +hlid being passed to the fw. + +Signed-off-by: Eliad Peller <el...@wizery.com> +Signed-off-by: John W. Linville <linvi...@tuxdriver.com> +--- + drivers/net/wireless/ti/wlcore/main.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c +index bea2938..d80d40c 100644 +--- a/drivers/net/wireless/ti/wlcore/main.c ++++ b/drivers/net/wireless/ti/wlcore/main.c +@@ -3472,6 +3472,10 @@ static void wl1271_op_set_default_key_idx(struct ieee80211_hw *hw, + wl1271_debug(DEBUG_MAC80211, "mac80211 set default key idx %d", + key_idx); + ++ /* we don't handle unsetting of default key */ ++ if (key_idx == -1) ++ return; ++ + mutex_lock(&wl->mutex); + + if (unlikely(wl->state != WLCORE_STATE_ON)) { +-- +1.9.3 + diff --git a/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0014-wlcore-consider-multiple-APs-when-checking-active_li.patch b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0014-wlcore-consider-multiple-APs-when-checking-active_li.patch new file mode 100644 index 0000000..0558648 --- /dev/null +++ b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0014-wlcore-consider-multiple-APs-when-checking-active_li.patch @@ -0,0 +1,64 @@ +From 41ed1a787c4940d58d5870c633ab6291dd4679dd Mon Sep 17 00:00:00 2001 +From: Eliad Peller <el...@wizery.com> +Date: Mon, 10 Feb 2014 13:47:30 +0200 +Subject: [PATCH 14/18] wlcore: consider multiple APs when checking + active_link_count + +Each AP has its own global and broadcast links, so when +checking for active sta count (according to the active_link_count) +we must take them all into account. + +Signed-off-by: Eliad Peller <el...@wizery.com> +Signed-off-by: John W. Linville <linvi...@tuxdriver.com> +--- + drivers/net/wireless/ti/wlcore/main.c | 10 +++++----- + drivers/net/wireless/ti/wlcore/tx.c | 10 +++++----- + 2 files changed, 10 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c +index d80d40c..8106c96 100644 +--- a/drivers/net/wireless/ti/wlcore/main.c ++++ b/drivers/net/wireless/ti/wlcore/main.c +@@ -345,12 +345,12 @@ static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl, + * Start high-level PS if the STA is asleep with enough blocks in FW. + * Make an exception if this is the only connected link. In this + * case FW-memory congestion is less of a problem. +- * Note that a single connected STA means 3 active links, since we must +- * account for the global and broadcast AP links. The "fw_ps" check +- * assures us the third link is a STA connected to the AP. Otherwise +- * the FW would not set the PSM bit. ++ * Note that a single connected STA means 2*ap_count + 1 active links, ++ * since we must account for the global and broadcast AP links ++ * for each AP. The "fw_ps" check assures us the other link is a STA ++ * connected to the AP. Otherwise the FW would not set the PSM bit. + */ +- else if (wl->active_link_count > 3 && fw_ps && ++ else if (wl->active_link_count > (wl->ap_count*2 + 1) && fw_ps && + tx_pkts >= WL1271_PS_STA_MAX_PACKETS) + wl12xx_ps_link_start(wl, wlvif, hlid, true); + } +diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c +index 38b31a0..40b4311 100644 +--- a/drivers/net/wireless/ti/wlcore/tx.c ++++ b/drivers/net/wireless/ti/wlcore/tx.c +@@ -134,12 +134,12 @@ static void wl1271_tx_regulate_link(struct wl1271 *wl, + * into high-level PS and clean out its TX queues. + * Make an exception if this is the only connected link. In this + * case FW-memory congestion is less of a problem. +- * Note that a single connected STA means 3 active links, since we must +- * account for the global and broadcast AP links. The "fw_ps" check +- * assures us the third link is a STA connected to the AP. Otherwise +- * the FW would not set the PSM bit. ++ * Note that a single connected STA means 2*ap_count + 1 active links, ++ * since we must account for the global and broadcast AP links ++ * for each AP. The "fw_ps" check assures us the other link is a STA ++ * connected to the AP. Otherwise the FW would not set the PSM bit. + */ +- if (wl->active_link_count > 3 && fw_ps && ++ if (wl->active_link_count > (wl->ap_count*2 + 1) && fw_ps && + tx_pkts >= WL1271_PS_STA_MAX_PACKETS) + wl12xx_ps_link_start(wl, wlvif, hlid, true); + } +-- +1.9.3 + diff --git a/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0015-wlcore-decrease-warning-verbosity-during-recovery.patch b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0015-wlcore-decrease-warning-verbosity-during-recovery.patch new file mode 100644 index 0000000..781bea5 --- /dev/null +++ b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0015-wlcore-decrease-warning-verbosity-during-recovery.patch @@ -0,0 +1,54 @@ +From 1ede95007371c27729383c8977e04abf63874ea8 Mon Sep 17 00:00:00 2001 +From: Arik Nemtsov <a...@wizery.com> +Date: Mon, 10 Feb 2014 13:47:31 +0200 +Subject: [PATCH 15/18] wlcore: decrease warning verbosity during recovery + +Silently ignore repetitive scheduling of recovery work and commands +being passed to the bus when the HW is not available. This can happen +many times during recovery and slow it down. It also spams the kernel +logs. + +Signed-off-by: Arik Nemtsov <a...@wizery.com> +Signed-off-by: Eliad Peller <el...@wizery.com> +Signed-off-by: John W. Linville <linvi...@tuxdriver.com> +--- + drivers/net/wireless/ti/wlcore/cmd.c | 4 ++-- + drivers/net/wireless/ti/wlcore/main.c | 5 +++-- + 2 files changed, 5 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c +index 3463a67..40dc30f 100644 +--- a/drivers/net/wireless/ti/wlcore/cmd.c ++++ b/drivers/net/wireless/ti/wlcore/cmd.c +@@ -60,8 +60,8 @@ static int __wlcore_cmd_send(struct wl1271 *wl, u16 id, void *buf, + u16 status; + u16 poll_count = 0; + +- if (WARN_ON(wl->state == WLCORE_STATE_RESTARTING && +- id != CMD_STOP_FWLOGGER)) ++ if (unlikely(wl->state == WLCORE_STATE_RESTARTING && ++ id != CMD_STOP_FWLOGGER)) + return -EIO; + + cmd = buf; +diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c +index 8106c96..a2348b9 100644 +--- a/drivers/net/wireless/ti/wlcore/main.c ++++ b/drivers/net/wireless/ti/wlcore/main.c +@@ -782,10 +782,11 @@ out: + + void wl12xx_queue_recovery_work(struct wl1271 *wl) + { +- WARN_ON(!test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags)); +- + /* Avoid a recursive recovery */ + if (wl->state == WLCORE_STATE_ON) { ++ WARN_ON(!test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, ++ &wl->flags)); ++ + wl->state = WLCORE_STATE_RESTARTING; + set_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags); + wl1271_ps_elp_wakeup(wl); +-- +1.9.3 + diff --git a/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0016-wlcore-increase-timeout-to-5000-msecs.patch b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0016-wlcore-increase-timeout-to-5000-msecs.patch new file mode 100644 index 0000000..5eca1d7 --- /dev/null +++ b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0016-wlcore-increase-timeout-to-5000-msecs.patch @@ -0,0 +1,31 @@ +From 5b07d97a381508dfc79bda72778ac27c1bdba320 Mon Sep 17 00:00:00 2001 +From: Yaniv Machani <yani...@ti.com> +Date: Mon, 10 Feb 2014 13:47:32 +0200 +Subject: [PATCH 16/18] wlcore: increase timeout to 5000 msecs + +dfs configuration command might take longer than +the current timeout. increase it to 5 seconds. + +Signed-off-by: Yaniv Machani <yani...@ti.com> +Signed-off-by: Eliad Peller <el...@wizery.com> +Signed-off-by: John W. Linville <linvi...@tuxdriver.com> +--- + drivers/net/wireless/ti/wlcore/cmd.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ti/wlcore/cmd.h b/drivers/net/wireless/ti/wlcore/cmd.h +index 9cb3f44..b084830 100644 +--- a/drivers/net/wireless/ti/wlcore/cmd.h ++++ b/drivers/net/wireless/ti/wlcore/cmd.h +@@ -207,7 +207,7 @@ enum cmd_templ { + #define WL1271_COMMAND_TIMEOUT 2000 + #define WL1271_CMD_TEMPL_DFLT_SIZE 252 + #define WL1271_CMD_TEMPL_MAX_SIZE 512 +-#define WL1271_EVENT_TIMEOUT 1500 ++#define WL1271_EVENT_TIMEOUT 5000 + + struct wl1271_cmd_header { + __le16 id; +-- +1.9.3 + diff --git a/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0017-wlcore-enable-beacon-filtering-only-after-receiving-.patch b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0017-wlcore-enable-beacon-filtering-only-after-receiving-.patch new file mode 100644 index 0000000..4ca93ff --- /dev/null +++ b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0017-wlcore-enable-beacon-filtering-only-after-receiving-.patch @@ -0,0 +1,86 @@ +From d881fa2c5032918e2b03ce6e12a5886f08acb459 Mon Sep 17 00:00:00 2001 +From: Eliad Peller <el...@wizery.com> +Date: Mon, 10 Feb 2014 13:47:33 +0200 +Subject: [PATCH 17/18] wlcore: enable beacon filtering only after receiving a + beacon + +Enabling beacon filtering before receving a beacon +might result in not having a beacon at all for the +current connected AP, which prevents the station +from entering power-save. + +Replace the current approach (of starting beacon +filtering on init) and configure beacon filering +only after bss_conf->dtimper is set (which means +mac80211 already parsed a beacon). + +Signed-off-by: Eliad Peller <el...@wizery.com> +Signed-off-by: John W. Linville <linvi...@tuxdriver.com> +--- + drivers/net/wireless/ti/wlcore/acx.c | 3 ++- + drivers/net/wireless/ti/wlcore/init.c | 4 ++-- + drivers/net/wireless/ti/wlcore/main.c | 12 ++++++++++++ + 3 files changed, 16 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/ti/wlcore/acx.c b/drivers/net/wireless/ti/wlcore/acx.c +index 71b244b..b924cea 100644 +--- a/drivers/net/wireless/ti/wlcore/acx.c ++++ b/drivers/net/wireless/ti/wlcore/acx.c +@@ -358,7 +358,8 @@ int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, struct wl12xx_vif *wlvif, + struct acx_beacon_filter_option *beacon_filter = NULL; + int ret = 0; + +- wl1271_debug(DEBUG_ACX, "acx beacon filter opt"); ++ wl1271_debug(DEBUG_ACX, "acx beacon filter opt enable=%d", ++ enable_filter); + + if (enable_filter && + wl->conf.conn.bcn_filt_mode == CONF_BCN_FILT_MODE_DISABLED) +diff --git a/drivers/net/wireless/ti/wlcore/init.c b/drivers/net/wireless/ti/wlcore/init.c +index b376c99..199e941 100644 +--- a/drivers/net/wireless/ti/wlcore/init.c ++++ b/drivers/net/wireless/ti/wlcore/init.c +@@ -287,8 +287,8 @@ static int wl1271_init_sta_beacon_filter(struct wl1271 *wl, + if (ret < 0) + return ret; + +- /* enable beacon filtering */ +- ret = wl1271_acx_beacon_filter_opt(wl, wlvif, true); ++ /* disable beacon filtering until we get the first beacon */ ++ ret = wl1271_acx_beacon_filter_opt(wl, wlvif, false); + if (ret < 0) + return ret; + +diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c +index a2348b9..82d5461 100644 +--- a/drivers/net/wireless/ti/wlcore/main.c ++++ b/drivers/net/wireless/ti/wlcore/main.c +@@ -2941,6 +2941,11 @@ static int wlcore_unset_assoc(struct wl1271 *wl, struct wl12xx_vif *wlvif) + ret = wl1271_acx_keep_alive_mode(wl, wlvif, false); + if (ret < 0) + return ret; ++ ++ /* disable beacon filtering */ ++ ret = wl1271_acx_beacon_filter_opt(wl, wlvif, false); ++ if (ret < 0) ++ return ret; + } + + if (test_and_clear_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags)) { +@@ -4312,6 +4317,13 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, + } + } + ++ if ((changed & BSS_CHANGED_BEACON_INFO) && bss_conf->dtim_period) { ++ /* enable beacon filtering */ ++ ret = wl1271_acx_beacon_filter_opt(wl, wlvif, true); ++ if (ret < 0) ++ goto out; ++ } ++ + ret = wl1271_bss_erp_info_changed(wl, vif, bss_conf, changed); + if (ret < 0) + goto out; +-- +1.9.3 + diff --git a/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0018-wlcore-add-support-for-STA-CSA-with-chan-contexts.patch b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0018-wlcore-add-support-for-STA-CSA-with-chan-contexts.patch new file mode 100644 index 0000000..b92ceed --- /dev/null +++ b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0018-wlcore-add-support-for-STA-CSA-with-chan-contexts.patch @@ -0,0 +1,32 @@ +From 6b27fe51675fd462967b824f63c5c009e9616363 Mon Sep 17 00:00:00 2001 +From: Arik Nemtsov <a...@wizery.com> +Date: Mon, 10 Feb 2014 13:47:34 +0200 +Subject: [PATCH 18/18] wlcore: add support for STA CSA with chan contexts + +TI wl12xx/wl18xx cards support channel switch via a driver specific +switch_channel op while operating with channel contexts. + +Signed-off-by: Arik Nemtsov <a...@wizery.com> +Signed-off-by: Eliad Peller <el...@wizery.com> +Signed-off-by: John W. Linville <linvi...@tuxdriver.com> +--- + drivers/net/wireless/ti/wlcore/main.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c +index 82d5461..7aae5b3 100644 +--- a/drivers/net/wireless/ti/wlcore/main.c ++++ b/drivers/net/wireless/ti/wlcore/main.c +@@ -5737,7 +5737,8 @@ static int wl1271_init_ieee80211(struct wl1271 *wl) + IEEE80211_HW_AP_LINK_PS | + IEEE80211_HW_AMPDU_AGGREGATION | + IEEE80211_HW_TX_AMPDU_SETUP_IN_HW | +- IEEE80211_HW_QUEUE_CONTROL; ++ IEEE80211_HW_QUEUE_CONTROL | ++ IEEE80211_HW_CHANCTX_STA_CSA; + + wl->hw->wiphy->cipher_suites = cipher_suites; + wl->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); +-- +1.9.3 + diff --git a/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0019-wlcore-use-correct-LAA-bit.patch b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0019-wlcore-use-correct-LAA-bit.patch new file mode 100644 index 0000000..bb11801 --- /dev/null +++ b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0019-wlcore-use-correct-LAA-bit.patch @@ -0,0 +1,30 @@ +From 71a301bb461da1e42e6d2764d99c683289c96f33 Mon Sep 17 00:00:00 2001 +From: Eliad Peller <el...@wizery.com> +Date: Fri, 11 Jul 2014 03:01:29 +0300 +Subject: [PATCH] wlcore: use correct LAA bit + +The LAA bit is second bit of the MSB, not of the +third byte. + +Signed-off-by: Eliad Peller <el...@wizery.com> +Signed-off-by: John W. Linville <linvi...@tuxdriver.com> +--- + drivers/net/wireless/ti/wlcore/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c +index 1ab6dbd..4c16262 100644 +--- a/drivers/net/wireless/ti/wlcore/main.c ++++ b/drivers/net/wireless/ti/wlcore/main.c +@@ -5661,7 +5661,7 @@ static void wl12xx_derive_mac_addresses(struct wl1271 *wl, u32 oui, u32 nic) + memcpy(&wl->addresses[idx], &wl->addresses[0], + sizeof(wl->addresses[0])); + /* LAA bit */ +- wl->addresses[idx].addr[2] |= BIT(1); ++ wl->addresses[idx].addr[0] |= BIT(1); + } + + wl->hw->wiphy->n_addresses = WLCORE_NUM_MAC_ADDRESSES; +-- +1.9.3 + diff --git a/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0020-wlcore-fix-copy-paste-bug-assign-from-src-struct-not.patch b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0020-wlcore-fix-copy-paste-bug-assign-from-src-struct-not.patch new file mode 100644 index 0000000..71f0e1f --- /dev/null +++ b/recipes-kernel/linux/linux-variscite-3.14.28/upstream-backport/wifi/0020-wlcore-fix-copy-paste-bug-assign-from-src-struct-not.patch @@ -0,0 +1,28 @@ +From 96dae59155eb98dd0ba10e8fe5d130f425e406df Mon Sep 17 00:00:00 2001 +From: Giel van Schijndel <m...@mortis.eu> +Date: Wed, 7 Jan 2015 20:38:37 +0100 +Subject: [PATCH] wlcore: fix copy-paste bug: assign from src struct not dest + +Signed-off-by: Giel van Schijndel <m...@mortis.eu> +Reported-at: http://www.viva64.com/en/b/0299/ +Signed-off-by: Kalle Valo <kv...@codeaurora.org> +--- + drivers/net/wireless/ti/wlcore/acx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ti/wlcore/acx.c b/drivers/net/wireless/ti/wlcore/acx.c +index b924cea..f28fa3b 100644 +--- a/drivers/net/wireless/ti/wlcore/acx.c ++++ b/drivers/net/wireless/ti/wlcore/acx.c +@@ -1725,7 +1725,7 @@ int wl12xx_acx_config_hangover(struct wl1271 *wl) + acx->decrease_delta = conf->decrease_delta; + acx->quiet_time = conf->quiet_time; + acx->increase_time = conf->increase_time; +- acx->window_size = acx->window_size; ++ acx->window_size = conf->window_size; + + ret = wl1271_cmd_configure(wl, ACX_CONFIG_HANGOVER, acx, + sizeof(*acx)); +-- +1.9.3 + diff --git a/recipes-kernel/linux/linux-variscite_3.14.28.bb b/recipes-kernel/linux/linux-variscite_3.14.28.bb new file mode 100644 index 0000000..3ccb36f --- /dev/null +++ b/recipes-kernel/linux/linux-variscite_3.14.28.bb @@ -0,0 +1,46 @@ +# Copyright (C) 2013-14 Freescale Semiconductor +# Released under the MIT license (see COPYING.MIT for the terms) + +require recipes-kernel/linux/linux-imx.inc +require recipes-kernel/linux/linux-dtb.inc + +DEPENDS += "lzop-native bc-native" + +COMPATIBLE_MACHINE = "(mx6)" + +SRC_URI = "\ + git://github.com/varigit/linux-2.6-imx.git;protocol=git;branch=imx_3.14.28-r0_var3 \ + file://0001-ARM-LLVMLinux-Change-extern-inline-to-static-inline.patch \ + file://0001-ARM-8158-LLVMLinux-use-static-inline-in-ARM-ftrace.patch \ + \ + file://upstream-backport/wifi/0001-wlcore-memset-wl-rx_filter_enabled-to-zero-after-rec.patch \ + file://upstream-backport/wifi/0002-wlcore-cancel-Tx-watchdog-on-suspend-and-rearm-on-fi.patch \ + file://upstream-backport/wifi/0003-wlcore-block-read-writes-to-FW-during-ELP.patch \ + file://upstream-backport/wifi/0004-wlcore-AP-don-t-start-mac80211-PS-on-non-peer-HLIDs.patch \ + file://upstream-backport/wifi/0005-wlcore-wl12xx-wl18xx-simplify-fw_status-handling.patch \ + file://upstream-backport/wifi/0006-wlcore-wl12xx-wl18xx-configure-num_links-per-hw.patch \ + file://upstream-backport/wifi/0007-wlcore-wl12xx-wl18xx-configure-max_stations-per-hw.patch \ + file://upstream-backport/wifi/0008-wlcore-wl12xx-wl18xx-configure-iface_combinations-pe.patch \ + file://upstream-backport/wifi/0009-wl18xx-move-to-new-firmware-wl18xx-fw-3.bin.patch \ + file://upstream-backport/wifi/0010-wlcore-send-EAPOL-frames-with-voice-priority.patch \ + file://upstream-backport/wifi/0011-wlcore-don-t-stop-sched_scan-on-interface-removal.patch \ + file://upstream-backport/wifi/0012-wlcore-wl18xx-allow-CCK-rates-for-AP-mode.patch \ + file://upstream-backport/wifi/0013-wlcore-don-t-handle-unsetting-of-default-wep-key.patch \ + file://upstream-backport/wifi/0014-wlcore-consider-multiple-APs-when-checking-active_li.patch \ + file://upstream-backport/wifi/0015-wlcore-decrease-warning-verbosity-during-recovery.patch \ + file://upstream-backport/wifi/0016-wlcore-increase-timeout-to-5000-msecs.patch \ + file://upstream-backport/wifi/0017-wlcore-enable-beacon-filtering-only-after-receiving-.patch \ + file://upstream-backport/wifi/0018-wlcore-add-support-for-STA-CSA-with-chan-contexts.patch \ + file://upstream-backport/wifi/0019-wlcore-use-correct-LAA-bit.patch \ + file://upstream-backport/wifi/0020-wlcore-fix-copy-paste-bug-assign-from-src-struct-not.patch \ + file://boundarydevices/0002-wlcore-add-initial-device-tree-support-to-the-sdio-m.patch \ + file://boundarydevices/0003-wlcore-add-mac-override-parameter.patch \ + \ + file://arm-Export-cache-flush-management-symbols-when-multi-cache.patch \ + file://Set-dr_mode-to-otg.patch \ + \ + file://defconfig \ +" + +SRCREV = "52373bf29aac80cacc519f4cb8aed22af2a2370d" +LOCALVERSION = "-1.1.0" -- 2.1.4 -- _______________________________________________ meta-freescale mailing list meta-freescale@yoctoproject.org https://lists.yoctoproject.org/listinfo/meta-freescale