diff --git a/patches/openwrt/0018-Backport-mac80211-from-Barrier-Breaker-r40804.patch b/patches/openwrt/0018-Backport-mac80211-from-Barrier-Breaker-r40842.patch similarity index 73% rename from patches/openwrt/0018-Backport-mac80211-from-Barrier-Breaker-r40804.patch rename to patches/openwrt/0018-Backport-mac80211-from-Barrier-Breaker-r40842.patch index cb273fad..d0c627ea 100644 --- a/patches/openwrt/0018-Backport-mac80211-from-Barrier-Breaker-r40804.patch +++ b/patches/openwrt/0018-Backport-mac80211-from-Barrier-Breaker-r40842.patch @@ -1,9 +1,9 @@ From: Matthias Schiffer Date: Mon, 19 May 2014 15:59:37 +0200 -Subject: Backport mac80211 from Barrier Breaker (r40804) +Subject: Backport mac80211 from Barrier Breaker (r40842) diff --git a/package/mac80211/Makefile b/package/mac80211/Makefile -index 9a7093c..7eacf24 100644 +index 9a7093c..c286b0f 100644 --- a/package/mac80211/Makefile +++ b/package/mac80211/Makefile @@ -1,5 +1,5 @@ @@ -18,12 +18,12 @@ index 9a7093c..7eacf24 100644 PKG_NAME:=mac80211 -PKG_VERSION:=2014-01-23.1 -+PKG_VERSION:=2014-05-19 ++PKG_VERSION:=2014-05-22 PKG_RELEASE:=1 PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources PKG_BACKPORT_VERSION:= -PKG_MD5SUM:=8db16edbdaf4abc2e9c2f3b6c86736a6 -+PKG_MD5SUM:=ff5426bf85668c3c36c7f602adeb1e5b ++PKG_MD5SUM:=367937d4f8c05cb36ca989ee26abc3df PKG_SOURCE:=compat-wireless-$(PKG_VERSION)$(PKG_BACKPORT_VERSION).tar.bz2 PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION) @@ -51,15 +51,17 @@ index 9a7093c..7eacf24 100644 PKG_ATH10K_LINUX_FIRMWARE_SOURCE:=$(PKG_ATH10K_LINUX_FIRMWARE_NAME)-$(PKG_ATH10K_LINUX_FIRMWARE_VERSION).tar.bz2 PKG_ATH10K_LINUX_FIRMWARE_PROTO:=git PKG_ATH10K_LINUX_FIRMWARE_SOURCE_URL:=https://github.com/kvalo/ath10k-firmware.git -@@ -363,7 +363,7 @@ define KernelPackage/rtl8180 +@@ -363,8 +363,8 @@ define KernelPackage/rtl8180 $(call KernelPackage/rtl818x/Default) DEPENDS+= @PCI_SUPPORT TITLE+= (RTL8180 PCI) - FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rtl818x/rtl8180/rtl8180.ko +- AUTOLOAD:=$(call AutoLoad,27,rtl8180) + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rtl818x/rtl8180/rtl818x_pci.ko - AUTOLOAD:=$(call AutoLoad,27,rtl8180) ++ AUTOLOAD:=$(call AutoLoad,27,rtl818x_pci) endef + define KernelPackage/rtl8187 @@ -606,6 +606,19 @@ Atheros IEEE 802.11ac family of chipsets. For now only PCI is supported. endef @@ -1771,7 +1773,7 @@ index 5372114..168871a 100644 config LIB80211_CRYPT_WEP diff --git a/package/mac80211/patches/060-no_local_ssb_bcma.patch b/package/mac80211/patches/060-no_local_ssb_bcma.patch -index f4b9470..d550bba 100644 +index f4b9470..93197ae 100644 --- a/package/mac80211/patches/060-no_local_ssb_bcma.patch +++ b/package/mac80211/patches/060-no_local_ssb_bcma.patch @@ -1,6 +1,6 @@ @@ -1787,7 +1789,7 @@ index f4b9470..d550bba 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c -@@ -2734,7 +2734,7 @@ static struct ssb_device *b43_ssb_gpio_d -+@@ -2723,7 +2723,7 @@ static struct ssb_device *b43_ssb_gpio_d ++@@ -2733,7 +2733,7 @@ static struct ssb_device *b43_ssb_gpio_d { struct ssb_bus *bus = dev->dev->sdev->bus; @@ -1796,7 +1798,7 @@ index f4b9470..d550bba 100644 #else return bus->chipco.dev; -@@ -4751,7 +4751,7 @@ static int b43_wireless_core_init(struct -+@@ -4688,7 +4688,7 @@ static int b43_wireless_core_init(struct ++@@ -4698,7 +4698,7 @@ static int b43_wireless_core_init(struct } if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW) hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */ @@ -2092,7 +2094,7 @@ index 4654bc8..640d34e 100644 if (ieee80211_aes_ccm_decrypt( diff --git a/package/mac80211/patches/150-disable_addr_notifier.patch b/package/mac80211/patches/150-disable_addr_notifier.patch -index 7b50154..c80b2bb 100644 +index 7b50154..6a7f5c1 100644 --- a/package/mac80211/patches/150-disable_addr_notifier.patch +++ b/package/mac80211/patches/150-disable_addr_notifier.patch @@ -1,6 +1,6 @@ @@ -2117,7 +2119,7 @@ index 7b50154..c80b2bb 100644 unsigned long data, void *arg) { -@@ -1031,14 +1031,14 @@ int ieee80211_register_hw(struct ieee802 -+@@ -1034,14 +1034,14 @@ int ieee80211_register_hw(struct ieee802 ++@@ -1036,14 +1036,14 @@ int ieee80211_register_hw(struct ieee802 goto fail_pm_qos; } @@ -2126,7 +2128,7 @@ index 7b50154..c80b2bb 100644 result = register_inet6addr_notifier(&local->ifa6_notifier); if (result) -@@ -1047,13 +1047,13 @@ int ieee80211_register_hw(struct ieee802 -+@@ -1050,13 +1050,13 @@ int ieee80211_register_hw(struct ieee802 ++@@ -1052,13 +1052,13 @@ int ieee80211_register_hw(struct ieee802 return 0; @@ -2135,41 +2137,37 @@ index 7b50154..c80b2bb 100644 pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY, &local->network_latency_notifier); -@@ -1086,10 +1086,10 @@ void ieee80211_unregister_hw(struct ieee -+@@ -1101,10 +1101,10 @@ void ieee80211_unregister_hw(struct ieee ++@@ -1103,10 +1103,10 @@ void ieee80211_unregister_hw(struct ieee pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY, &local->network_latency_notifier); diff --git a/package/mac80211/patches/300-pending_work.patch b/package/mac80211/patches/300-pending_work.patch -index a1af6c2..dc1e265 100644 +index a1af6c2..0a2e86b 100644 --- a/package/mac80211/patches/300-pending_work.patch +++ b/package/mac80211/patches/300-pending_work.patch -@@ -1,4153 +1,4383 @@ +@@ -1,4153 +1,163 @@ -commit 93f310a38a1d81a4bc8fcd9bf29628bd721cf2ef -+commit ff9655bebd25d35ab13c2515a029723b69949720 ++commit 6df35206bc6c1c6aad1d8077df5786b4a7f77873 Author: Felix Fietkau -Date: Sun Apr 6 23:35:28 2014 +0200 -+Date: Mon May 19 21:20:49 2014 +0200 ++Date: Fri May 23 19:58:14 2014 +0200 - ath9k_hw: reduce ANI firstep range for older chips -+ ath9k: avoid passing buffers to the hardware during flush ++ mac80211: reduce packet loss notifications under load - Use 0-8 instead of 0-16, which is closer to the old implementation. - Also drop the overwrite of the firstep_low parameter to improve - stability. -+ The commit "ath9k: fix possible hang on flush" changed the receive code -+ to always link rx descriptors of processed frames, even when flushing. -+ In some cases, this leads to flushed rx buffers being passed to the -+ hardware while rx is already stopped. ++ During strong signal fluctuations under high throughput, few consecutive ++ failed A-MPDU transmissions can easily trigger packet loss notification, ++ and thus (in AP mode) client disconnection. - Signed-off-by: Felix Fietkau - +- Signed-off-by: Felix Fietkau +- -commit 584d297fd29fb39c76af25ae74ff9d5fe74c8a14 -Author: Helmut Schaa -Date: Wed Mar 12 10:37:55 2014 +0100 -+commit 46c5d7d207a2a0725066c0928fd19b8c578b7d4f -+Author: Oleksij Rempel -+Date: Tue May 20 00:02:03 2014 +0200 - +- - ath9k: Fix sequence number assignment for non-data frames - - Since commit 558ff225de80ac95b132d3a115ddadcd64498b4f (ath9k: fix @@ -2323,39 +2321,21 @@ index a1af6c2..dc1e265 100644 - Cc: - Cc: - Signed-off-by: Michael Braun -+ ath9k_htc: fix build with disabled debug -+ -+ CC [M] drivers/net/wireless/ath/ath9k/htc_drv_txrx.o -+ drivers/net/wireless/ath/ath9k/htc_drv_txrx.c: In function ‘ath9k_rx_prepare’: -+ drivers/net/wireless/ath/ath9k/htc_drv_txrx.c:1006:2: warning: passing argument 2 of ‘ath9k_htc_err_stat_rx’ from incompatible pointer type [enabled by default] -+ ath9k_htc_err_stat_rx(priv, &rx_stats); -+ ^ -+ In file included from drivers/net/wireless/ath/ath9k/htc_drv_txrx.c:17:0: -+ drivers/net/wireless/ath/ath9k/htc.h:380:20: note: expected ‘struct ath_htc_rx_status *’ but argument is of type ‘struct ath_rx_status *’ -+ static inline void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv, -+ -+ Signed-off-by: Oleksij Rempel - +- -commit 9d6ab9bdb9b368a6cf9519f0f92509b5b2c297ec -+commit 2d331334e9dc5659fdf9a89326c34c3db5a15279 - Author: Johannes Berg +-Author: Johannes Berg -Date: Mon Mar 3 14:19:08 2014 +0100 -+Date: Mon May 19 17:59:50 2014 +0200 - +- - cfg80211: remove racy beacon_interval assignment -+ cfg80211: constify wowlan/coalesce mask/pattern pointers - +- - In case of AP mode, the beacon interval is already reset to - zero inside cfg80211_stop_ap(), and in the other modes it - isn't relevant. Remove the assignment to remove a potential - race since the assignment isn't properly locked. -+ This requires changing the nl80211 parsing code a bit to use -+ intermediate pointers for the allocation, but clarifies the -+ API towards the drivers. - +- - Reported-by: Michal Kazior - Signed-off-by: Johannes Berg - +- Signed-off-by: Johannes Berg +- -commit 1abdeca3c6fb9cf1f84f85e78ed8d1c33bd69db0 -Author: Felix Fietkau -Date: Fri Feb 28 18:52:56 2014 +0100 @@ -2497,11 +2477,9 @@ index a1af6c2..dc1e265 100644 - Signed-off-by: Felix Fietkau - -commit d84856012e0f10fe598a5ad3b7b869397a089e07 -+commit 6788105c46babaa6938cbacb72fdf20bec4bb2e3 - Author: Johannes Berg +-Author: Johannes Berg -Date: Thu Feb 20 11:19:58 2014 +0100 -+Date: Mon May 19 17:53:16 2014 +0200 - +- - mac80211: fix station wakeup powersave race - - Consider the following (relatively unlikely) scenario: @@ -2519,32 +2497,24 @@ index a1af6c2..dc1e265 100644 - As a result, no frames will be delivered to the client, even - though it is awake, until it sends another frame to us that - triggers ieee80211_sta_ps_deliver_wakeup() in sta_ps_end(). -+ cfg80211: constify more pointers in the cfg80211 API - +- - Since we now take the PS spinlock, we can fix this while at - the same time removing the complexity with the pending skb - queue function. This was broken since my commit 50a9432daeec - ("mac80211: fix powersaving clients races") due to removing - the clearing of WLAN_STA_PS_STA in the RX path. -+ This also propagates through the drivers. - +- - While at it, fix a cleanup path issue when a station is - removed while the driver is still blocking its wakeup. -+ The orinoco driver uses the cfg80211 API structs for internal -+ bookkeeping, and so needs a (void *) cast that removes the -+ const - but that's OK because it allocates those pointers. - - Signed-off-by: Johannes Berg - +- +- Signed-off-by: Johannes Berg +- -commit 798f2786602cbe93e6b928299614aa36ebf50692 -+commit c3d95010fd881da0fa0a4e88532412f5d0c092f6 - Author: Johannes Berg +-Author: Johannes Berg -Date: Mon Feb 17 20:49:03 2014 +0100 -+Date: Mon May 19 17:19:31 2014 +0200 - +- - mac80211: insert stations before adding to driver -+ cfg80211: constify MAC addresses in cfg80211 ops - +- - There's a race condition in mac80211 because we add stations - to the internal lists after adding them to the driver, which - means that (for example) the following can happen: @@ -2566,17 +2536,13 @@ index a1af6c2..dc1e265 100644 - driver fails to add the station, in that case a bit more is - needed. To not make that overly complex prevent starting BA - sessions in the meantime. -+ This propagates through all the drivers and mac80211. - - Signed-off-by: Johannes Berg - +- +- Signed-off-by: Johannes Berg +- -commit b9ba6a520cb07ab3aa7aaaf9ce4a0bc7a6bc06fe -Author: Emmanuel Grumbach -Date: Thu Feb 20 09:22:11 2014 +0200 -+commit ddf1e6f0f0354c601af7d42e5ace4b51f8b0bffc -+Author: Luciano Coelho -+Date: Thu May 15 20:32:08 2014 +0300 - +- - mac80211: fix AP powersave TX vs. wakeup race - - There is a race between the TX path and the STA wakeup: while @@ -2584,24 +2550,18 @@ index a1af6c2..dc1e265 100644 - up, then the frames are transmitted. However, the RX and TX - path are concurrent, so the packet indicating wakeup can be - processed while a packet is being transmitted. -+ mac80211: fix csa_counter_offs argument name in docbook - +- - This can lead to a situation where the buffered frames list - is emptied on the one side, while a frame is being added on - the other side, as the station is still seen as sleeping in - the TX path. -+ The csa_counter_offs was erroneously described as csa_offs in -+ the docbook section. - +- - As a result, the newly added frame will not be send anytime - soon. It might be sent much later (and out of order) when the - station goes to sleep and wakes up the next time. -+ This fixes two warnings when making htmldocs (at least): - +- - Additionally, it can lead to the crash below. -+ Warning(include/net/mac80211.h:3428): No description found for parameter 'csa_counter_offs[IEEE80211_MAX_CSA_COUNTERS_NUM]' -+ Warning(include/net/mac80211.h:3428): Excess struct/union/enum/typedef member 'csa_offs' description in 'ieee80211_mutable_offsets' - +- - Fix all this by synchronising both paths with a new lock. - Both path are not fastpath since they handle PS situations. - @@ -2656,9 +2616,8 @@ index a1af6c2..dc1e265 100644 - when the status is not "IGNORE" nor "ALREADY_SET". - - Signed-off-by: Inbal Hacohen -+ Signed-off-by: Luciano Coelho - Signed-off-by: Johannes Berg - +- Signed-off-by: Johannes Berg +- -commit 6514c93afede55284e2cb63359aadedb85884c80 -Author: Jouni Malinen -Date: Tue Feb 18 20:41:08 2014 +0200 @@ -2674,19 +2633,13 @@ index a1af6c2..dc1e265 100644 -commit a63caf0a357ad5c1f08d6b7827dc76c451445017 -Author: Stanislaw Gruszka -Date: Wed Feb 19 13:15:17 2014 +0100 -+commit 202322d1c04b8e498bd5bb78606fcf3941512b35 -+Author: Luciano Coelho -+Date: Thu May 15 20:18:09 2014 +0300 - +- - ath9k: protect tid->sched check -+ cfg80211: add documentation for max_num_csa_counters - +- - We check tid->sched without a lock taken on ath_tx_aggr_sleep(). That - is race condition which can result of doing list_del(&tid->list) twice - (second time with poisoned list node) and cause crash like shown below: -+ Move the comment in the structure to a description of the -+ max_num_csa_counters field in the docbook area. - +- - [424271.637220] BUG: unable to handle kernel paging request at 00100104 - [424271.637328] IP: [] ath_tx_aggr_sleep+0x62/0xe0 [ath9k] - ... @@ -2709,46 +2662,31 @@ index a1af6c2..dc1e265 100644 - [424271.641266] [] ath_rx_tasklet+0x88e/0xf70 [ath9k] - [424271.641358] [] ? ieee80211_rx+0x1dc/0x7c0 [mac80211] - [424271.641445] [] ath9k_tasklet+0xcb/0x130 [ath9k] -+ This fixes a warning when building htmldocs (at least): - +- - Bug report: - https://bugzilla.kernel.org/show_bug.cgi?id=70551 -+ Warning(include/net/cfg80211.h:3064): No description found for parameter 'max_num_csa_counters' - +- - Reported-and-tested-by: Max Sydorenko - Cc: stable@vger.kernel.org - Signed-off-by: Stanislaw Gruszka -+ Signed-off-by: Luciano Coelho -+ Signed-off-by: Johannes Berg - +- -commit 82ed9e3ccc02797df2ffe4b78127c4cd5f799a41 -Author: Felix Fietkau -Date: Tue Feb 11 15:54:13 2014 +0100 -+commit 457a33192f64b7637e8fd0ae0e9f32701c908603 -+Author: Johannes Berg -+Date: Mon May 19 11:24:19 2014 +0200 - +- - mac80211: send control port protocol frames to the VO queue -+ mac80211: minstrel-ht: small clarifications - +- - Improves reliability of wifi connections with WPA, since authentication - frames are prioritized over normal traffic and also typically exempt - from aggregation. -+ Antonio and I were looking over this code and some things -+ didn't immediately make sense, so we came up with two small -+ clarifications. - +- - Cc: stable@vger.kernel.org - Signed-off-by: Felix Fietkau -+ Signed-off-by: Johannes Berg - +- -commit d4426800f71e972feaa33e04c5801fc730627bdd -Author: Stanislaw Gruszka -Date: Mon Feb 10 22:38:28 2014 +0100 -+commit 1e35dce952a64a957de97ae1f2bb19301756b936 -+Author: Andrei Otcheretianski -+Date: Fri May 9 14:11:50 2014 +0300 - +- - rtl8187: fix regression on MIPS without coherent DMA - - This patch fixes regression caused by commit a16dad77634 "MIPS: Fix @@ -2775,77 +2713,44 @@ index a1af6c2..dc1e265 100644 - reproducible regression and seems other possible corruptions do not - happen in practice, since Yeeloong laptop works stable without rtl8187 - driver. -+ mac80211: Handle the CSA counters correctly - +- - Bug report: - https://bugzilla.kernel.org/show_bug.cgi?id=54391 -+ Make the beacon CSA counters part of ieee80211_mutable_offsets and don't -+ decrement CSA counters when generating a beacon template. This permits the -+ driver to offload the CSA counters handling. Since mac80211 updates the probe -+ responses with the correct counter, the driver should sync the counter's value -+ with mac80211 using ieee80211_csa_update_counter function. - +- - Reported-by: Petr Pisar - Bisected-by: Tom Li - Reported-and-tested-by: Tom Li - Cc: stable@vger.kernel.org - Signed-off-by: Stanislaw Gruszka -+ Signed-off-by: Andrei Otcheretianski -+ Signed-off-by: Luciano Coelho -+ Signed-off-by: Johannes Berg - +- -commit e2f141d67ad1e7fe10aaab61811e8a409dfb2442 -Author: Sujith Manoharan -Date: Fri Feb 7 10:29:55 2014 +0530 -+commit e7b5c449815d28a2105fde5b42e112f78cc711ac -+Author: Andrei Otcheretianski -+Date: Fri May 9 14:11:49 2014 +0300 - +- - ath9k: Calculate IQ-CAL median -+ mac80211: Provide ieee80211_beacon_get_template API - +- - This patch adds a routine to calculate the median IQ correction - values for AR955x, which is used for outlier detection. - The normal method which is used for all other chips is - bypassed for AR955x. -+ Add a new API ieee80211_beacon_get_template, which doesn't -+ affect DTIM counter and should be used if the device generates beacon -+ frames, and new beacon template is needed. In addition set the offsets -+ to TIM IE for MESH interface. - +- - Signed-off-by: Sujith Manoharan -+ Signed-off-by: Andrei Otcheretianski -+ Signed-off-by: Luciano Coelho -+ Signed-off-by: Johannes Berg - +- -commit c52a6fce0820c8d0687443ab86058ae03b478c8f -Author: Sujith Manoharan -Date: Fri Feb 7 10:29:54 2014 +0530 -+commit e54eda80273ce8aded058c3c9365dca2342e2e75 -+Author: Andrei Otcheretianski -+Date: Fri May 9 14:11:47 2014 +0300 - +- - ath9k: Expand the IQ coefficient array -+ mac80211: Support multiple CSA counters - +- - This will be used for storing data for mutiple - IQ calibration runs, for AR955x. -+ Support up to IEEE80211_MAX_CSA_COUNTERS_NUM csa counters. -+ This is defined to be 2 now, to support both CSA and eCSA -+ counters. - +- - Signed-off-by: Sujith Manoharan -+ Signed-off-by: Andrei Otcheretianski -+ Signed-off-by: Luciano Coelho -+ Signed-off-by: Johannes Berg - +- -commit 034969ff5c2b6431d10e07c1938f0b916da85cc3 -Author: Sujith Manoharan -Date: Fri Feb 7 10:29:53 2014 +0530 -+commit 678e87c3b929dd60d59470e8981eb551cee10319 -+Author: Andrei Otcheretianski -+Date: Fri May 9 14:11:46 2014 +0300 - +- - ath9k: Modify IQ calibration for AR955x - - IQ calibration post-processing for AR955x is different @@ -2861,53 +2766,25 @@ index a1af6c2..dc1e265 100644 - in subsequent patches) is set to zero. - - Signed-off-by: Sujith Manoharan -+ cfg80211: Support multiple CSA counters -+ -+ Change the type of NL80211_ATTR_CSA_C_OFF_BEACON and -+ NL80211_ATTR_CSA_C_OFF_PRESP to be NLA_BINARY which allows -+ userspace to use beacons and probe responses with -+ multiple CSA counters. -+ This isn't breaking the API since userspace can -+ continue to use nla_put_u16 for this attributes, which -+ is equivalent to a single element u16 array. -+ In addition advertise max number of supported CSA counters. -+ This is needed when using CSA and eCSA IEs together. -+ -+ Signed-off-by: Andrei Otcheretianski -+ Signed-off-by: Luciano Coelho -+ Signed-off-by: Johannes Berg - +- -commit 9b1ed6454e6f3511f24266be99b4e403f243f6a8 -Author: Sujith Manoharan -Date: Fri Feb 7 10:29:52 2014 +0530 -+commit 93f4867a966cc8645659031bbd44a9bb4b78485f -+Author: Andrei Otcheretianski -+Date: Fri May 9 14:11:45 2014 +0300 - +- - ath9k: Fix magnitude/phase calculation -+ mac80211: Update CSA counters in mgmt frames - +- - Incorrect values are programmed in the registers - containing the IQ correction coefficients by the IQ-CAL - post-processing code. Fix this. -+ Track current csa counter value and use it -+ to update mgmt frames at the provided offsets. - +- - Signed-off-by: Sujith Manoharan -+ Signed-off-by: Andrei Otcheretianski -+ Signed-off-by: Luciano Coelho -+ Signed-off-by: Johannes Berg - +- -commit 36f93484f96f79171dcecb67c5ef0c3de22531a6 -Author: Sujith Manoharan -Date: Fri Feb 7 10:29:51 2014 +0530 -+commit 6c8461fcc03ff4d250027e47f53315b5e0ec43aa -+Author: Andrei Otcheretianski -+Date: Fri May 9 14:11:44 2014 +0300 - +- - ath9k: Rename ar9003_hw_tx_iqcal_load_avg_2_passes -+ cfg80211: Add API to update CSA counters in mgmt frames - +- - Use ar9003_hw_tx_iq_cal_outlier_detection instead. - - Signed-off-by: Sujith Manoharan @@ -2917,43 +2794,26 @@ index a1af6c2..dc1e265 100644 -Date: Fri Feb 7 10:29:50 2014 +0530 - - ath9k: Check explicitly for IQ calibration -+ Add NL80211_ATTR_CSA_C_OFFSETS_TX which holds an array -+ of offsets to the CSA counters which should be updated -+ when sending a management frames with NL80211_CMD_FRAME. - +- - In chips like AR955x, the initvals contain the information - whether IQ calibration is to be done in the HW when an - AGC calibration is triggered. Check if IQ-CAL is enabled - in the initvals before flagging 'txiqcal_done' as true. -+ This API should be used by the drivers that wish to keep the -+ CSA counter updated in probe responses, but do not implement -+ probe response offloading and so, do not use -+ ieee80211_proberesp_get function. - +- - Signed-off-by: Sujith Manoharan -+ Signed-off-by: Andrei Otcheretianski -+ Signed-off-by: Luciano Coelho -+ Signed-off-by: Johannes Berg - +- -commit cb4969634b93c4643a32cc3fbd27d2b288b25771 -Author: Sujith Manoharan -Date: Fri Feb 7 10:29:49 2014 +0530 -+commit 7d09fc9f1903b3d5e7d046bdf10467f37a97c4f9 -+Author: Luciano Coelho -+Date: Thu May 15 13:05:39 2014 +0300 - +- - ath9k: Fix IQ cal post processing for SoC -+ cfg80211: pass the actual iftype when calling cfg80211_chandef_dfs_required() - +- - Calibration data is not reused for SoC chips, so - call ar9003_hw_tx_iq_cal_post_proc() with the correct - argument. The 'is_reusable' flag is currently used - only for PC-OEM chips, but it makes things clearer to - specify it explicity. -+ There is no need to pass NL80211_IFTYPE_UNSPECIFIED when calling -+ cfg80211_chandef_dfs_required() since we always already have the -+ interface type. So, pass the actual interface type instead. - +- - Signed-off-by: Sujith Manoharan - -commit e138e0ef9560c46ce93dbb22a728a57888e94d1c @@ -2961,10 +2821,7 @@ index a1af6c2..dc1e265 100644 -Date: Mon Feb 3 13:31:37 2014 +0530 - - ath9k: Fix TX power calculation -+ Additionally, have cfg80211_chandef_dfs_required() WARN if the passed -+ interface type is NL80211_IFTYPE_UNSPECIFIED, so we can detect -+ problems more easily. - +- - The commit, "ath9k_hw: Fix incorrect Tx control power in AR9003 template" - fixed the incorrect values in the eeprom templates, but if - boards have already been calibrated with incorrect values, @@ -2973,33 +2830,22 @@ index a1af6c2..dc1e265 100644 - - Cc: Rajkumar Manoharan - Signed-off-by: Sujith Manoharan -+ Tested-by: Janusz Dziedzic -+ Reported-by: Eliad Peller -+ Signed-off-by: Luciano Coelho -+ Signed-off-by: Johannes Berg - +- -commit b9f268b5b01331c3c82179abca551429450e9417 -Author: Michal Kazior -Date: Wed Jan 29 14:22:27 2014 +0100 -+commit 2b7443b15f26ecb98281474666383cf2a882fbad -+Author: Janusz Dziedzic -+Date: Wed May 14 13:25:04 2014 +0200 - +- - cfg80211: consider existing DFS interfaces - - It was possible to break interface combinations in - the following way: -+ cfg80211: fix start_radar_detection issue - +- - combo 1: iftype = AP, num_ifaces = 2, num_chans = 2, - combo 2: iftype = AP, num_ifaces = 1, num_chans = 1, radar = HT20 -+ After patch: -+ cfg80211/mac80211: refactor cfg80211_chandef_dfs_required() - +- - With the above interface combinations it was - possible to: -+ start_radar_detection always fail with -EINVAL. - +- - step 1. start AP on DFS channel by matching combo 2 - step 2. start AP on non-DFS channel by matching combo 1 - @@ -3011,17 +2857,12 @@ index a1af6c2..dc1e265 100644 - is stored. - - Signed-off-by: Michal Kazior -+ Acked-by: Luciano Coelho -+ Signed-off-by: Janusz Dziedzic - Signed-off-by: Johannes Berg - +- Signed-off-by: Johannes Berg +- -commit bc9c62f5f511cc395c62dbf4cdd437f23db53b28 -Author: Antonio Quartulli -Date: Wed Jan 29 17:53:43 2014 +0100 -+commit 4f46eb8b28f96aca212a364e0fa847eb5333df67 -+Author: Felix Fietkau -+Date: Mon May 5 11:48:40 2014 +0200 - +- - cfg80211: fix channel configuration in IBSS join - - When receiving an IBSS_JOINED event select the BSS object @@ -3033,8 +2874,7 @@ index a1af6c2..dc1e265 100644 - The result is a mismatching channel configuration between - cfg80211 and the driver, that can lead to any sort of - problem. -+ cfg80211: allow restricting supported dfs regions - +- - The issue can be triggered by having an IBSS sitting on - given channel and then asking the driver to create a new - cell using the same BSSID but with a different frequency. @@ -3042,12 +2882,7 @@ index a1af6c2..dc1e265 100644 - this ambiguity and retrieve/create the correct BSS object. - All the users of cfg80211_ibss_joined() have been changed - accordingly. -+ At the moment, the ath9k/ath10k DFS module only supports detecting ETSI -+ radar patterns. -+ Add a bitmap in the interface combinations, indicating which DFS regions -+ are supported by the detector. If unset, support for all regions is -+ assumed. - +- - Moreover WARN when cfg80211_ibss_joined() gets a NULL - channel as argument and remove a bogus call of the same - function in ath6kl (it does not make sense to call @@ -3061,53 +2896,36 @@ index a1af6c2..dc1e265 100644 - Acked-by: Kalle Valo - Signed-off-by: Antonio Quartulli - [minor code cleanup in ath6kl] -+ Signed-off-by: Felix Fietkau - Signed-off-by: Johannes Berg - +- Signed-off-by: Johannes Berg +- -commit 7e0c41cb41f215aba2c39b1c237bb4d42ec49a85 -+commit 0277b034768d1800a00829a755fc56b925aa6b95 - Author: Johannes Berg +-Author: Johannes Berg -Date: Fri Jan 24 14:41:44 2014 +0100 -+Date: Wed Apr 30 14:19:04 2014 +0200 - +- - mac80211: fix bufferable MMPDU RX handling -+ mac80211: handle failed restart/resume better - +- - Action, disassoc and deauth frames are bufferable, and as such don't - have the PM bit in the frame control field reserved which means we - need to react to the bit when receiving in such a frame. -+ When the driver fails during HW restart or resume, the whole -+ stack goes into a very confused state with interfaces being -+ up while the hardware is down etc. - +- - Fix this by introducing a new helper ieee80211_is_bufferable_mmpdu() - and using it for the RX path that currently ignores the PM bit in - any non-data frames for doze->wake transitions, but listens to it in - all frames for wake->doze transitions, both of which are wrong. - - Also use the new helper in the TX path to clean up the code. -+ Address this by shutting down everything; we'll run into a -+ lot of warnings in the process but that's better than having -+ the whole stack get messed up. - -+ Reviewed-by: Arik Nemtsov - Signed-off-by: Johannes Berg - +- +- Signed-off-by: Johannes Berg +- -commit fc0df6d2343636e3f48a069330d5b972e3d8659d -Author: Janusz Dziedzic -Date: Fri Jan 24 14:29:21 2014 +0100 -+commit 43fd71bc4b83d24981e90ca178f505cf6a6b16dc -+Author: Luciano Coelho -+Date: Wed May 7 20:05:12 2014 +0300 - +- - cfg80211: set preset_chandef after channel switch -+ mac80211: fix sparse warning caused by __ieee80211_channel_switch() - +- - Set preset_chandef in channel switch notification. - In other case we will have old preset_chandef. -+ Commit 59af6928 (mac80211: fix CSA tx queue stopping) introduced a -+ sparse warning: - +- - Signed-off-by: Janusz Dziedzic - Signed-off-by: Johannes Berg - @@ -3116,57 +2934,38 @@ index a1af6c2..dc1e265 100644 -Date: Fri Jan 24 23:48:29 2014 +0100 - - mac80211: send ibss probe responses with noack flag -+ net/mac80211/cfg.c:3274:5: warning: symbol '__ieee80211_channel_switch' was not declared. Should it be static? - +- - Responding to probe requests for scanning clients will often create - excessive retries, as it happens quite often that the scanning client - already left the channel. Therefore do it like hostapd and send probe - responses for wildcard SSID only once by using the noack flag. -+ Fix it by declaring the function static. - +- - Signed-off-by: Simon Wunderlich - [fix typo & 'wildcard SSID' in commit log] -+ Signed-off-by: Luciano Coelho - Signed-off-by: Johannes Berg - +- Signed-off-by: Johannes Berg +- -commit 0b865d1e6b9c05052adae9315df7cb195dc60c3b -+commit dd4371e2957db19870bb22ab84e841e1ac6e8997 - Author: Luciano Coelho +-Author: Luciano Coelho -Date: Tue Jan 28 17:09:08 2014 +0200 -+Date: Wed May 7 19:07:05 2014 +0300 - +- - mac80211: ibss: remove unnecessary call to release channel -+ cfg80211: fix docbook warning -+ -+ When trying to generate documentation, at least xmldocs, we get the -+ following warning: -+ -+ Warning(include/net/cfg80211.h:461): No description found for parameter 'nl80211_iftype' - +- - The ieee80211_vif_use_channel() function calls - ieee80211_vif_release_channel(), so there's no need to call it - explicitly in __ieee80211_sta_join_ibss(). -+ Fix it by adding the iftype argument name to the -+ cfg80211_chandef_dfs_required() function declaration. - -+ Reported-and-tested-by: Masanari Iida - Signed-off-by: Luciano Coelho - Signed-off-by: Johannes Berg - +- +- Signed-off-by: Luciano Coelho +- Signed-off-by: Johannes Berg +- -commit e1b6c17e971f0a51ff86c2dac2584c63cd999cd7 -+commit 56de850ae960f096c784ec07864ca5b71abd16e6 - Author: Michal Kazior +-Author: Michal Kazior -Date: Wed Jan 29 07:56:21 2014 +0100 -+Date: Thu May 8 09:10:02 2014 +0200 - +- - mac80211: add missing CSA locking -+ mac80211: disconnect iface if CSA unexpectedly fails - +- - The patch adds a missing sdata lock and adds a few - lockdeps for easier maintenance. -+ It doesn't make much sense to leave a crippled -+ interface running. - +- - Signed-off-by: Michal Kazior - Signed-off-by: Johannes Berg - @@ -3175,76 +2974,48 @@ index a1af6c2..dc1e265 100644 -Date: Wed Jan 29 07:56:20 2014 +0100 - - mac80211: fix sdata->radar_required locking -+ As a side effect this will unblock tx queues with -+ CSA reason immediately after failure instead of -+ until after userspace requests interface to stop. - +- - radar_required setting wasn't protected by - local->mtx in some places. This should prevent - from scanning/radar detection/roc colliding. -+ This also gives userspace an opportunity to -+ indirectly see CSA failure. - - Signed-off-by: Michal Kazior -+ [small code cleanup] - Signed-off-by: Johannes Berg - +- +- Signed-off-by: Michal Kazior +- Signed-off-by: Johannes Berg +- -commit 5fcd5f1808813a3d9e502fd756e01bee8a79c85d -Author: Michal Kazior -Date: Wed Jan 29 07:56:19 2014 +0100 -+commit f5894c4f19e55bb1ea6376031fe9d47d7528be9e -+Author: Loic Poulain -+Date: Wed May 7 11:38:11 2014 +0200 - +- - mac80211: move csa_active setting in STA CSA -+ rfkill-gpio: Use gpio cansleep version - +- - The sdata->vif.csa_active could be left set after, - e.g. channel context constraints check fail in STA - mode leaving the interface in a strange state for - a brief period of time until it is disconnected. - This was harmless but ugly. -+ If gpio controller requires waiting for read and write -+ GPIO values, then we have to use the gpio cansleep api. -+ Fix the rfkill_gpio_set_power which calls only the -+ nonsleep version (causing kernel warning). -+ There is no problem to use the cansleep version here -+ because we are not in IRQ handler or similar context -+ (cf rfkill_set_block). - +- - Signed-off-by: Michal Kazior - Reviewed-by: Luciano Coelho -+ Signed-off-by: Loic Poulain - Signed-off-by: Johannes Berg - +- Signed-off-by: Johannes Berg +- -commit e486da4b7eed71821c6b4c1bb9ac62ffd3ab13e9 -+commit 47fdf5d4f3704d2db9d1c0f647f788edef104fc8 - Author: Michal Kazior +-Author: Michal Kazior -Date: Wed Jan 29 07:56:18 2014 +0100 -+Date: Wed Apr 9 15:45:36 2014 +0200 - +- - mac80211: fix possible memory leak on AP CSA failure -+ mac80211: ignore cqm during csa - +- - If CSA for AP interface failed and the interface - was not stopped afterwards another CSA request - would leak sdata->u.ap.next_beacon. -+ It is not guaranteed that multi-vif channel -+ switching is tightly synchronized. It makes sense -+ to ignore cqm (missing beacons, et al) while csa -+ is progressing and re-check it after it completes. - - Signed-off-by: Michal Kazior +- +- Signed-off-by: Michal Kazior - Reviewed-by: Luciano Coelho - Signed-off-by: Johannes Berg - +- Signed-off-by: Johannes Berg +- -commit 3a77ba08940682bf3d52cf14f980337324af9d4a -Author: Johannes Berg -Date: Sat Feb 1 00:33:29 2014 +0100 -+commit 1a8ed386e1684b266a15dacf675102ae53361ee5 -+Author: Michal Kazior -+Date: Wed Apr 9 15:11:01 2014 +0200 - +- - mac80211: fix fragmentation code, particularly for encryption - - The "new" fragmentation code (since my rewrite almost 5 years ago) @@ -3254,8 +3025,7 @@ index a1af6c2..dc1e265 100644 - originally ended, and thus causes the encryption MIC to be written - at that point, rather than where it belongs: immediately after the - data. -+ cfg80211: export interface stopping function - +- - The impact of this is that if software encryption is done, then - a) encryption doesn't work for the first fragment, the connection - becomes unusable as the first fragment will never be properly @@ -3263,27 +3033,20 @@ index a1af6c2..dc1e265 100644 - be wrong - b) we leak up to 8 bytes of plaintext (!) of the packet out into - the air -+ This exports a new cfg80211_stop_iface() function. - +- - This is only mitigated by the fact that many devices are capable - of doing encryption in hardware, in which case this can't happen - as the tail pointer is irrelevant in that case. Additionally, - fragmentation is not used very frequently and would normally have - to be configured manually. -+ This is intended for driver internal interface -+ combination management and channel switching. - +- - Fix this by using skb_trim() properly. -+ Due to locking issues (it re-enters driver) the -+ call is asynchronous and uses cfg80211 event -+ list/worker. - +- - Cc: stable@vger.kernel.org - Fixes: 2de8e0d999b8 ("mac80211: rewrite fragmentation") - Reported-by: Jouni Malinen -+ Signed-off-by: Michal Kazior - Signed-off-by: Johannes Berg - +- Signed-off-by: Johannes Berg +- -commit de5f242e0c10e841017e37eb8c38974a642dbca8 -Author: Sujith Manoharan -Date: Tue Jan 28 06:21:59 2014 +0530 @@ -3316,29 +3079,20 @@ index a1af6c2..dc1e265 100644 -commit a4a634a6937ebdd827fa58e8fcdb8ca49a3769f6 -Author: Emmanuel Grumbach -Date: Mon Jan 27 11:07:42 2014 +0200 -+commit 573f31d6d0e572ff8186c45a1ecd9273242233e6 -+Author: Michal Kazior -+Date: Wed Apr 9 15:11:00 2014 +0200 - +- - mac80211: release the channel in error path in start_ap -+ mac80211: split CSA finalize function - +- - When the driver cannot start the AP or when the assignement - of the beacon goes wrong, we need to unassign the vif. -+ Improves readability and modularity. - +- - Cc: stable@vger.kernel.org - Signed-off-by: Emmanuel Grumbach -+ Signed-off-by: Michal Kazior - Signed-off-by: Johannes Berg - +- Signed-off-by: Johannes Berg +- -commit dfb6889a75c601aedb7450b7e606668e77da6679 -Author: Johannes Berg -Date: Wed Jan 22 11:14:19 2014 +0200 -+commit 2d104d52e7c7640d68f29f2136dbe3938b7bc9ba -+Author: Michal Kazior -+Date: Wed Apr 9 15:10:59 2014 +0200 - +- - cfg80211: send scan results from work queue - - Due to the previous commit, when a scan finishes, it is in theory @@ -3360,37 +3114,11 @@ index a1af6c2..dc1e265 100644 - - As this can't work for wext, so we send the message immediately, - but this shouldn't be an issue since we still return -EBUSY. -+ mac80211: fix CSA tx queue stopping -+ -+ It was possible for tx queues to be stuck stopped -+ if AP CSA finalization failed. In that case -+ neither stop_ap nor do_stop woke the queues up. -+ This means it was impossible to perform tx at all -+ until driver was reloaded or a successful CSA was -+ performed later. -+ -+ It was possible to solve this in a simpler manner -+ however this is more robust and future proof -+ (having multi-vif CSA in mind). -+ -+ New sdata->csa_block_tx is introduced to keep -+ track of which interfaces requested tx to be -+ blocked for CSA. This is required because mac80211 -+ stops all tx queues for that purpose. This means -+ queues must be awoken only when last tx-blocking -+ CSA interface is finished. -+ -+ It is still possible to have tx queues stopped -+ after CSA failure but as soon as offending -+ interfaces are stopped from userspace (stop_ap or -+ ifdown) tx queues are woken up properly. - -+ Signed-off-by: Michal Kazior - Signed-off-by: Johannes Berg - +- +- Signed-off-by: Johannes Berg +- -commit 45b7ab41fc08627d9a8428cb413d5d84662a9707 -+commit 6be615d6d42aa7fdab6c4278031d8fa0953e594f - Author: Johannes Berg +-Author: Johannes Berg -Date: Wed Jan 22 11:14:18 2014 +0200 - - cfg80211: fix scan done race @@ -3419,8 +3147,7 @@ index a1af6c2..dc1e265 100644 -commit ae04fa489ab31b5a10d3cc8399f52761175d4321 -Author: Emmanuel Grumbach -Date: Thu Jan 23 14:28:16 2014 +0200 -+Date: Wed Apr 9 21:31:13 2014 +0200 - +- - mac80211: avoid deadlock revealed by lockdep - - sdata->u.ap.request_smps_work can’t be flushed synchronously @@ -3430,18 +3157,14 @@ index a1af6c2..dc1e265 100644 - stopped to its default: OFF. - - This solves: -+ mac80211: mark local variable __maybe_unused - +- - ====================================================== - [ INFO: possible circular locking dependency detected ] - 3.12.0-ipeer+ #2 Tainted: G O - ------------------------------------------------------- - rmmod/2867 is trying to acquire lock: - ((&sdata->u.ap.request_smps_work)){+.+...}, at: [] flush_work+0x0/0x90 -+ The 'local' variable in __ieee80211_vif_copy_chanctx_to_vlans() -+ is only used/needed when lockdep is compiled in, mark it as such -+ to avoid compile warnings in the other case. - +- - but task is already holding lock: - (&wdev->mtx){+.+.+.}, at: [] cfg80211_stop_ap+0x26/0x230 [cfg80211] - @@ -3501,53 +3224,38 @@ index a1af6c2..dc1e265 100644 - Unfortunately I forgot this during the merge window, but the - patch seems small enough to go in as a fix. The userspace API - bug that was the reason for disabling it has long been fixed. -+ While at it, fix some indentation where it's used. - -+ Reviewed-by: Luciano Coelho -+ Reviewed-by: Emmanuel Grumbach - Signed-off-by: Johannes Berg - +- +- Signed-off-by: Johannes Berg +- -commit 110a1c79acda14edc83b7c8dc5af9c7ddd23eb61 -Author: Pontus Fuchs -Date: Thu Jan 16 15:00:40 2014 +0100 -+commit 43279e584aeb78aa0c853728db047b58156c0753 -+Author: Arik Nemtsov -+Date: Thu May 1 10:17:28 2014 +0300 - +- - nl80211: Reset split_start when netlink skb is exhausted - - When the netlink skb is exhausted split_start is left set. In the - subsequent retry, with a larger buffer, the dump is continued from the - failing point instead of from the beginning. -+ mac80211: move TDLS code to another file - +- - This was causing my rt28xx based USB dongle to now show up when - running "iw list" with an old iw version without split dump support. -+ With new additions planned, this code is getting too big for cfg.c. - +- - Cc: stable@vger.kernel.org - Fixes: 3713b4e364ef ("nl80211: allow splitting wiphy information in dumps") - Signed-off-by: Pontus Fuchs - [avoid the entire workaround when state->split is set] -+ Signed-off-by: Arik Nemtsov - Signed-off-by: Johannes Berg - +- Signed-off-by: Johannes Berg +- -commit b4c31b45ffc7ef110fa9ecc34d7878fe7c5b9da4 -Author: Eliad Peller -Date: Sun Jan 12 11:06:37 2014 +0200 -+commit bf9c234b83c77f1ebbcbab73de2a9e4a5d4aafc6 -+Author: Arik Nemtsov -+Date: Thu May 1 10:17:27 2014 +0300 - +- - mac80211: move roc cookie assignment earlier -+ mac80211: set an external flag for TDLS stations - +- - ieee80211_start_roc_work() might add a new roc - to existing roc, and tell cfg80211 it has already - started. -+ Expose a new tdls flag for the public ieee80211_sta struct. -+ This can be used in some rate control decisions. - +- - However, this might happen before the roc cookie - was set, resulting in REMAIN_ON_CHANNEL (started) - event with null cookie. Consequently, it can make @@ -3557,59 +3265,44 @@ index a1af6c2..dc1e265 100644 - - Cc: stable@vger.kernel.org - Signed-off-by: Eliad Peller -+ Signed-off-by: Arik Nemtsov - Signed-off-by: Johannes Berg - +- Signed-off-by: Johannes Berg +- -commit cfdc9157bfd7bcf88ab4dae08873a9907eba984c -+commit 910e65141a17f645ab85dae1a497e64ebe63df70 - Author: Johannes Berg +-Author: Johannes Berg -Date: Fri Jan 24 14:06:29 2014 +0100 -+Date: Tue Apr 29 17:55:26 2014 +0200 - +- - nl80211: send event when AP operation is stopped -+ mac80211: remove BUG_ON usage - +- - There are a few cases, e.g. suspend, where an AP interface is - stopped by the kernel rather than by userspace request, most - commonly when suspending. To let userspace know about this, - send the NL80211_CMD_STOP_AP command as an event every time - an AP interface is stopped. This also happens when userspace - did in fact request the AP stop, but that's not a problem. -+ These BUG_ON statements should never trigger, but in the unlikely -+ event that somebody does manage don't stop everything but simply -+ exit the code path with an error. - +- - For full-MAC drivers this may need to be extended to also - cover cases where the device stopped the AP operation for - some reason, this a bit more complicated because then all - cfg80211 state also needs to be reset; such API is not part - of this patch. -+ Leave the one BUG_ON where changing it would result in a NULL -+ pointer dereference. - - Signed-off-by: Johannes Berg - +- +- Signed-off-by: Johannes Berg +- -commit d5d567eda7704f190379ca852a8f9a4112e3eee3 -+commit ff36b582a10285530351aab036087b57ddb4ae2b - Author: Johannes Berg +-Author: Johannes Berg -Date: Thu Jan 23 16:20:29 2014 +0100 -+Date: Tue Apr 29 17:52:36 2014 +0200 - +- - mac80211: add length check in ieee80211_is_robust_mgmt_frame() -+ cfg80211: remove BUG_ON usage - +- - A few places weren't checking that the frame passed to the - function actually has enough data even though the function - clearly documents it must have a payload byte. Make this - safer by changing the function to take an skb and checking - the length inside. The old version is preserved for now as - the rtl* drivers use it and don't have a correct skb. -+ These really can't trigger unless somebody messes up the code, -+ but don't make debugging it needlessly complicated, WARN and -+ return instead of BUG_ON(). - - Signed-off-by: Johannes Berg - +- +- Signed-off-by: Johannes Berg +- -commit f8f6d212a047fc65c7d3442dfc038f65517236fc -Author: Johannes Berg -Date: Fri Jan 24 10:53:53 2014 +0100 @@ -3687,8 +3380,8 @@ index a1af6c2..dc1e265 100644 - Cc: Helmut Schaa - Cc: Emmanuel Grumbach - Signed-off-by: Johannes Berg - --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c - +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c +---- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +-+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c -@@ -790,7 +790,7 @@ void ath6kl_cfg80211_connect_event(struc - if (nw_type & ADHOC_NETWORK) { - ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n", @@ -3712,9 +3405,7 @@ index a1af6c2..dc1e265 100644 -- cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL); - return; - } -+@@ -1759,7 +1759,7 @@ static bool is_rate_ht40(s32 rate, u8 *m -+ } - +- -@@ -3256,6 +3252,15 @@ static int ath6kl_cfg80211_sscan_start(s - struct ath6kl_vif *vif = netdev_priv(dev); - u16 interval; @@ -3774,10 +3465,7 @@ index a1af6c2..dc1e265 100644 - -@@ -1534,7 +1534,7 @@ EXPORT_SYMBOL(ath9k_hw_check_nav); - bool ath9k_hw_check_alive(struct ath_hw *ah) -+ static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev, -+- u8 *mac, struct station_info *sinfo) -++ const u8 *mac, struct station_info *sinfo) - { +- { - int count = 50; -- u32 reg; -+ u32 reg, last_val; @@ -3840,16 +3528,9 @@ index a1af6c2..dc1e265 100644 - goto out; - } -@@ -1866,7 +1866,7 @@ static void ath9k_set_coverage_class(str -+ struct ath6kl *ar = ath6kl_priv(dev); -+ struct ath6kl_vif *vif = netdev_priv(dev); -+@@ -2974,7 +2974,7 @@ static int ath6kl_stop_ap(struct wiphy * -+ static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - +- - static bool ath9k_has_tx_pending(struct ath_softc *sc) -+ static int ath6kl_del_station(struct wiphy *wiphy, struct net_device *dev, -+- u8 *mac) -++ const u8 *mac) - { +- { -- int i, npend; -+ int i, npend = 0; - @@ -3914,11 +3595,8 @@ index a1af6c2..dc1e265 100644 ---- a/include/linux/ieee80211.h -+++ b/include/linux/ieee80211.h -@@ -597,6 +597,20 @@ static inline int ieee80211_is_qos_nullf -+ struct ath6kl *ar = ath6kl_priv(dev); -+ struct ath6kl_vif *vif = netdev_priv(dev); -+@@ -2985,7 +2985,8 @@ static int ath6kl_del_station(struct wip - } - +- } +- - /** -+ * ieee80211_is_bufferable_mmpdu - check if frame is bufferable MMPDU -+ * @fc: frame control field in little-endian byteorder @@ -3938,19 +3616,8 @@ index a1af6c2..dc1e265 100644 - * @seq_ctrl: frame sequence control bytes in little-endian byteorder - */ -@@ -2192,10 +2206,10 @@ static inline u8 *ieee80211_get_DA(struc -+ static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev, -+- u8 *mac, struct station_parameters *params) -++ const u8 *mac, -++ struct station_parameters *params) -+ { -+ struct ath6kl *ar = ath6kl_priv(dev); -+ struct ath6kl_vif *vif = netdev_priv(dev); -+--- a/drivers/net/wireless/ath/ath6kl/wmi.c -++++ b/drivers/net/wireless/ath/ath6kl/wmi.c -+@@ -2320,7 +2320,7 @@ int ath6kl_wmi_addkey_cmd(struct wmi *wm -+ return ret; - } - +- } +- - /** -- * ieee80211_is_robust_mgmt_frame - check if frame is a robust management frame -+ * _ieee80211_is_robust_mgmt_frame - check if frame is a robust management frame @@ -3958,36 +3625,12 @@ index a1af6c2..dc1e265 100644 - */ --static inline bool ieee80211_is_robust_mgmt_frame(struct ieee80211_hdr *hdr) -+static inline bool _ieee80211_is_robust_mgmt_frame(struct ieee80211_hdr *hdr) -+-int ath6kl_wmi_add_krk_cmd(struct wmi *wmi, u8 if_idx, u8 *krk) -++int ath6kl_wmi_add_krk_cmd(struct wmi *wmi, u8 if_idx, const u8 *krk) -+ { -+ struct sk_buff *skb; -+ struct wmi_add_krk_cmd *cmd; -+--- a/drivers/net/wireless/ath/ath6kl/wmi.h -++++ b/drivers/net/wireless/ath/ath6kl/wmi.h -+@@ -2616,7 +2616,7 @@ int ath6kl_wmi_addkey_cmd(struct wmi *wm -+ u8 *key_material, -+ u8 key_op_ctrl, u8 *mac_addr, -+ enum wmi_sync_flag sync_flag); -+-int ath6kl_wmi_add_krk_cmd(struct wmi *wmi, u8 if_idx, u8 *krk); -++int ath6kl_wmi_add_krk_cmd(struct wmi *wmi, u8 if_idx, const u8 *krk); -+ int ath6kl_wmi_deletekey_cmd(struct wmi *wmi, u8 if_idx, u8 key_index); -+ int ath6kl_wmi_setpmkid_cmd(struct wmi *wmi, u8 if_idx, const u8 *bssid, -+ const u8 *pmkid, bool set); -+--- a/drivers/net/wireless/ath/ath9k/htc.h -++++ b/drivers/net/wireless/ath/ath9k/htc.h -+@@ -378,7 +378,7 @@ void ath9k_htc_get_et_stats(struct ieee8 -+ #define TX_QSTAT_INC(c) do { } while (0) -+ -+ static inline void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv, -+- struct ath_htc_rx_status *rxs) -++ struct ath_rx_status *rs); - { +- { - if (ieee80211_is_disassoc(hdr->frame_control) || - ieee80211_is_deauth(hdr->frame_control)) -@@ -2224,6 +2238,17 @@ static inline bool ieee80211_is_robust_m - } - +- } +- - /** -+ * ieee80211_is_robust_mgmt_frame - check if skb contains a robust mgmt frame -+ * @skb: the skb containing the frame, length will be checked @@ -4073,10 +3716,7 @@ index a1af6c2..dc1e265 100644 --void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp); -+void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, -+ struct ieee80211_channel *channel, gfp_t gfp); -+--- a/drivers/net/wireless/ath/wil6210/cfg80211.c -++++ b/drivers/net/wireless/ath/wil6210/cfg80211.c -+@@ -172,7 +172,7 @@ static int wil_cid_fill_sinfo(struct wil - +- - /** - * cfg80211_notify_new_candidate - notify cfg80211 of a new mesh peer candidate ---- a/include/uapi/linux/nl80211.h @@ -4107,16 +3747,8 @@ index a1af6c2..dc1e265 100644 - -- ieee80211_tx_skb_tid(sdata, skb, tid); -+ ieee80211_tx_skb(sdata, skb); -+ static int wil_cfg80211_get_station(struct wiphy *wiphy, -+ struct net_device *ndev, -+- u8 *mac, struct station_info *sinfo) -++ const u8 *mac, struct station_info *sinfo) -+ { -+ struct wil6210_priv *wil = wiphy_to_wil(wiphy); -+ int rc; -+@@ -671,7 +671,7 @@ static int wil_cfg80211_stop_ap(struct w - } - +- } +- - void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn) ---- a/net/mac80211/cfg.c -+++ b/net/mac80211/cfg.c @@ -4133,12 +3765,7 @@ index a1af6c2..dc1e265 100644 - mutex_unlock(&local->mtx); -@@ -1021,8 +1021,10 @@ static int ieee80211_start_ap(struct wip - IEEE80211_P2P_OPPPS_ENABLE_BIT; -+ static int wil_cfg80211_del_station(struct wiphy *wiphy, -+- struct net_device *dev, u8 *mac) -++ struct net_device *dev, const u8 *mac) -+ { -+ struct wil6210_priv *wil = wiphy_to_wil(wiphy); - +- - err = ieee80211_assign_beacon(sdata, ¶ms->beacon); -- if (err < 0) -+ if (err < 0) { @@ -4155,59 +3782,19 @@ index a1af6c2..dc1e265 100644 -+ ieee80211_vif_release_channel(sdata); - return err; - } -+--- a/drivers/net/wireless/ath/wil6210/main.c -++++ b/drivers/net/wireless/ath/wil6210/main.c -+@@ -81,7 +81,7 @@ static void wil_disconnect_cid(struct wi -+ memset(&sta->stats, 0, sizeof(sta->stats)); -+ } - +- -@@ -1053,6 +1056,7 @@ static int ieee80211_change_beacon(struc - int err; -+-static void _wil6210_disconnect(struct wil6210_priv *wil, void *bssid) -++static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid) -+ { -+ int cid = -ENOENT; -+ struct net_device *ndev = wil_to_ndev(wil); -+@@ -252,7 +252,7 @@ int wil_priv_init(struct wil6210_priv *w -+ return 0; -+ } - +- - sdata = IEEE80211_DEV_TO_SUB_IF(dev); -+ sdata_assert_lock(sdata); -+-void wil6210_disconnect(struct wil6210_priv *wil, void *bssid) -++void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid) -+ { -+ del_timer_sync(&wil->connect_timer); -+ _wil6210_disconnect(wil, bssid); -+--- a/drivers/net/wireless/ath/wil6210/wil6210.h -++++ b/drivers/net/wireless/ath/wil6210/wil6210.h -+@@ -508,7 +508,7 @@ void wil_wdev_free(struct wil6210_priv * -+ int wmi_set_mac_address(struct wil6210_priv *wil, void *addr); -+ int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, u8 chan); -+ int wmi_pcp_stop(struct wil6210_priv *wil); -+-void wil6210_disconnect(struct wil6210_priv *wil, void *bssid); -++void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid); -+ -+ int wil_rx_init(struct wil6210_priv *wil); -+ void wil_rx_fini(struct wil6210_priv *wil); -+--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c -++++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c -+@@ -2236,7 +2236,7 @@ brcmf_cfg80211_config_default_mgmt_key(s - +- - /* don't allow changing the beacon while CSA is in place - offset - * of channel switch counter may change -@@ -1080,6 +1084,8 @@ static int ieee80211_stop_ap(struct wiph - struct probe_resp *old_probe_resp; - struct cfg80211_chan_def chandef; -+ static s32 -+ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, -+- u8 *mac, struct station_info *sinfo) -++ const u8 *mac, struct station_info *sinfo) -+ { -+ struct brcmf_if *ifp = netdev_priv(ndev); -+ struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; -+@@ -4014,7 +4014,7 @@ brcmf_cfg80211_change_beacon(struct wiph - +- -+ sdata_assert_lock(sdata); -+ - old_beacon = sdata_dereference(sdata->u.ap.beacon, sdata); @@ -4216,16 +3803,7 @@ index a1af6c2..dc1e265 100644 -@@ -1090,8 +1096,6 @@ static int ieee80211_stop_ap(struct wiph - kfree(sdata->u.ap.next_beacon); - sdata->u.ap.next_beacon = NULL; -+ static int -+ brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, -+- u8 *mac) -++ const u8 *mac) -+ { -+ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); -+ struct brcmf_scb_val_le scbval; -+@@ -4242,7 +4242,7 @@ static int brcmf_convert_nl80211_tdls_op -+ } - +- -- cancel_work_sync(&sdata->u.ap.request_smps_work); -- - /* turn off carrier for this interface and dependent VLANs */ @@ -4252,29 +3830,7 @@ index a1af6c2..dc1e265 100644 -@@ -2638,6 +2646,24 @@ static int ieee80211_start_roc_work(stru - INIT_DELAYED_WORK(&roc->work, ieee80211_sw_roc_work); - INIT_LIST_HEAD(&roc->dependents); -+ static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy, -+- struct net_device *ndev, u8 *peer, -++ struct net_device *ndev, const u8 *peer, -+ enum nl80211_tdls_operation oper) -+ { -+ struct brcmf_if *ifp; -+--- a/drivers/net/wireless/libertas/cfg.c -++++ b/drivers/net/wireless/libertas/cfg.c -+@@ -1006,9 +1006,8 @@ struct cmd_key_material { -+ } __packed; -+ -+ static int lbs_set_key_material(struct lbs_private *priv, -+- int key_type, -+- int key_info, -+- u8 *key, u16 key_len) -++ int key_type, int key_info, -++ const u8 *key, u16 key_len) -+ { -+ struct cmd_key_material cmd; -+ int ret; -+@@ -1610,7 +1609,7 @@ static int lbs_cfg_del_key(struct wiphy -+ */ - +- -+ /* -+ * cookie is either the roc cookie (for normal roc) -+ * or the SKB (for mgmt TX) @@ -4299,24 +3855,7 @@ index a1af6c2..dc1e265 100644 -@@ -2772,24 +2798,6 @@ static int ieee80211_start_roc_work(stru - if (!queued) - list_add_tail(&roc->list, &local->roc_list); -+ static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev, -+- u8 *mac, struct station_info *sinfo) -++ const u8 *mac, struct station_info *sinfo) -+ { -+ struct lbs_private *priv = wiphy_priv(wiphy); -+ s8 signal, noise; -+--- a/drivers/net/wireless/libertas/defs.h -++++ b/drivers/net/wireless/libertas/defs.h -+@@ -90,7 +90,8 @@ do { if ((lbs_debug & (grp)) == (grp)) \ -+ #define lbs_deb_cfg80211(fmt, args...) LBS_DEB_LL(LBS_DEB_CFG80211, " cfg80211", fmt, ##args) -+ -+ #ifdef DEBUG -+-static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, int len) -++static inline void lbs_deb_hex(unsigned int grp, const char *prompt, -++ const u8 *buf, int len) -+ { -+ int i = 0; - +- -- /* -- * cookie is either the roc cookie (for normal roc) -- * or the SKB (for mgmt TX) @@ -4336,11 +3875,8 @@ index a1af6c2..dc1e265 100644 -- } -- - return 0; -+--- a/drivers/net/wireless/mwifiex/11n.h -++++ b/drivers/net/wireless/mwifiex/11n.h -+@@ -200,7 +200,7 @@ static inline int mwifiex_is_sta_11n_ena - } - +- } +- -@@ -3004,8 +3012,10 @@ void ieee80211_csa_finalize_work(struct - if (!ieee80211_sdata_running(sdata)) - goto unlock; @@ -4362,23 +3898,7 @@ index a1af6c2..dc1e265 100644 -+ - if (err < 0) - goto unlock; -+ static inline u8 -+-mwifiex_tdls_peer_11n_enabled(struct mwifiex_private *priv, u8 *ra) -++mwifiex_tdls_peer_11n_enabled(struct mwifiex_private *priv, const u8 *ra) -+ { -+ struct mwifiex_sta_node *node = mwifiex_get_sta_entry(priv, ra); -+ if (node) -+--- a/drivers/net/wireless/mwifiex/cfg80211.c -++++ b/drivers/net/wireless/mwifiex/cfg80211.c -+@@ -994,7 +994,7 @@ mwifiex_dump_station_info(struct mwifiex -+ */ -+ static int -+ mwifiex_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, -+- u8 *mac, struct station_info *sinfo) -++ const u8 *mac, struct station_info *sinfo) -+ { -+ struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); - +- - changed |= err; -- kfree(sdata->u.ap.next_beacon); -- sdata->u.ap.next_beacon = NULL; @@ -4389,35 +3909,10 @@ index a1af6c2..dc1e265 100644 -@@ -3066,7 +3076,7 @@ int ieee80211_channel_switch(struct wiph - struct ieee80211_if_mesh __maybe_unused *ifmsh; - int err, num_chanctx; -+@@ -1270,7 +1270,7 @@ static int mwifiex_cfg80211_change_beaco -+ */ -+ static int -+ mwifiex_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, -+- u8 *mac) -++ const u8 *mac) -+ { -+ struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); -+ struct mwifiex_sta_node *sta_node; -+@@ -2629,7 +2629,7 @@ static int mwifiex_cfg80211_set_coalesce -+ */ -+ static int -+ mwifiex_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, -+- u8 *peer, u8 action_code, u8 dialog_token, -++ const u8 *peer, u8 action_code, u8 dialog_token, -+ u16 status_code, u32 peer_capability, -+ const u8 *extra_ies, size_t extra_ies_len) -+ { -+@@ -2701,7 +2701,7 @@ mwifiex_cfg80211_tdls_mgmt(struct wiphy - +- -- lockdep_assert_held(&sdata->wdev.mtx); -+ sdata_assert_lock(sdata); -+ static int -+ mwifiex_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, -+- u8 *peer, enum nl80211_tdls_operation action) -++ const u8 *peer, enum nl80211_tdls_operation action) -+ { -+ struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); - +- - if (!list_empty(&local->roc_list) || local->scanning) - return -EBUSY; ---- a/net/mac80211/ht.c @@ -4428,30 +3923,20 @@ index a1af6c2..dc1e265 100644 - -- ieee80211_tx_skb_tid(sdata, skb, tid); -+ ieee80211_tx_skb(sdata, skb); -+@@ -2748,9 +2748,8 @@ mwifiex_cfg80211_tdls_oper(struct wiphy - } - +- } +- - void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, -@@ -466,7 +466,9 @@ void ieee80211_request_smps_ap_work(stru - u.ap.request_smps_work); -+ static int -+-mwifiex_cfg80211_add_station(struct wiphy *wiphy, -+- struct net_device *dev, -+- u8 *mac, struct station_parameters *params) -++mwifiex_cfg80211_add_station(struct wiphy *wiphy, struct net_device *dev, -++ const u8 *mac, struct station_parameters *params) -+ { -+ struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); - +- - sdata_lock(sdata); -- __ieee80211_request_smps_ap(sdata, sdata->u.ap.driver_smps_mode); -+ if (sdata_dereference(sdata->u.ap.beacon, sdata)) -+ __ieee80211_request_smps_ap(sdata, -+ sdata->u.ap.driver_smps_mode); - sdata_unlock(sdata); -+@@ -2765,9 +2764,9 @@ mwifiex_cfg80211_add_station(struct wiph - } - +- } +- ---- a/net/mac80211/iface.c -+++ b/net/mac80211/iface.c -@@ -770,12 +770,19 @@ static void ieee80211_do_stop(struct iee @@ -4475,201 +3960,47 @@ index a1af6c2..dc1e265 100644 -+ default: -+ break; -+ } -+ static int -+-mwifiex_cfg80211_change_station(struct wiphy *wiphy, -+- struct net_device *dev, -+- u8 *mac, struct station_parameters *params) -++mwifiex_cfg80211_change_station(struct wiphy *wiphy, struct net_device *dev, -++ const u8 *mac, -++ struct station_parameters *params) -+ { -+ int ret; -+ struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); -+--- a/drivers/net/wireless/mwifiex/main.h -++++ b/drivers/net/wireless/mwifiex/main.h -+@@ -910,8 +910,6 @@ int mwifiex_handle_uap_rx_forward(struct -+ struct sk_buff *skb); -+ int mwifiex_process_sta_event(struct mwifiex_private *); -+ int mwifiex_process_uap_event(struct mwifiex_private *); -+-struct mwifiex_sta_node * -+-mwifiex_get_sta_entry(struct mwifiex_private *priv, u8 *mac); -+ void mwifiex_delete_all_station_list(struct mwifiex_private *priv); -+ void *mwifiex_process_sta_txpd(struct mwifiex_private *, struct sk_buff *skb); -+ void *mwifiex_process_uap_txpd(struct mwifiex_private *, struct sk_buff *skb); -+@@ -1220,26 +1218,26 @@ void mwifiex_dnld_txpwr_table(struct mwi -+ extern const struct ethtool_ops mwifiex_ethtool_ops; -+ -+ void mwifiex_del_all_sta_list(struct mwifiex_private *priv); -+-void mwifiex_del_sta_entry(struct mwifiex_private *priv, u8 *mac); -++void mwifiex_del_sta_entry(struct mwifiex_private *priv, const u8 *mac); -+ void -+ mwifiex_set_sta_ht_cap(struct mwifiex_private *priv, const u8 *ies, -+ int ies_len, struct mwifiex_sta_node *node); -+ struct mwifiex_sta_node * -+-mwifiex_add_sta_entry(struct mwifiex_private *priv, u8 *mac); -++mwifiex_add_sta_entry(struct mwifiex_private *priv, const u8 *mac); -+ struct mwifiex_sta_node * -+-mwifiex_get_sta_entry(struct mwifiex_private *priv, u8 *mac); -+-int mwifiex_send_tdls_data_frame(struct mwifiex_private *priv, u8 *peer, -++mwifiex_get_sta_entry(struct mwifiex_private *priv, const u8 *mac); -++int mwifiex_send_tdls_data_frame(struct mwifiex_private *priv, const u8 *peer, -+ u8 action_code, u8 dialog_token, -+ u16 status_code, const u8 *extra_ies, -+ size_t extra_ies_len); -+-int mwifiex_send_tdls_action_frame(struct mwifiex_private *priv, -+- u8 *peer, u8 action_code, u8 dialog_token, -+- u16 status_code, const u8 *extra_ies, -+- size_t extra_ies_len); -++int mwifiex_send_tdls_action_frame(struct mwifiex_private *priv, const u8 *peer, -++ u8 action_code, u8 dialog_token, -++ u16 status_code, const u8 *extra_ies, -++ size_t extra_ies_len); -+ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv, -+ u8 *buf, int len); -+-int mwifiex_tdls_oper(struct mwifiex_private *priv, u8 *peer, u8 action); -+-int mwifiex_get_tdls_link_status(struct mwifiex_private *priv, u8 *mac); -++int mwifiex_tdls_oper(struct mwifiex_private *priv, const u8 *peer, u8 action); -++int mwifiex_get_tdls_link_status(struct mwifiex_private *priv, const u8 *mac); -+ void mwifiex_disable_all_tdls_links(struct mwifiex_private *priv); -+ bool mwifiex_is_bss_in_11ac_mode(struct mwifiex_private *priv); -+ u8 mwifiex_get_center_freq_index(struct mwifiex_private *priv, u8 band, -+--- a/drivers/net/wireless/mwifiex/tdls.c -++++ b/drivers/net/wireless/mwifiex/tdls.c -+@@ -25,8 +25,8 @@ -+ #define TDLS_RESP_FIX_LEN 8 -+ #define TDLS_CONFIRM_FIX_LEN 6 -+ -+-static void -+-mwifiex_restore_tdls_packets(struct mwifiex_private *priv, u8 *mac, u8 status) -++static void mwifiex_restore_tdls_packets(struct mwifiex_private *priv, -++ const u8 *mac, u8 status) -+ { -+ struct mwifiex_ra_list_tbl *ra_list; -+ struct list_head *tid_list; -+@@ -84,7 +84,8 @@ mwifiex_restore_tdls_packets(struct mwif -+ return; -+ } - +- - /* - * Remove all stations associated with this interface. -@@ -827,7 +834,9 @@ static void ieee80211_do_stop(struct iee - cancel_work_sync(&local->dynamic_ps_enable_work); -+-static void mwifiex_hold_tdls_packets(struct mwifiex_private *priv, u8 *mac) -++static void mwifiex_hold_tdls_packets(struct mwifiex_private *priv, -++ const u8 *mac) -+ { -+ struct mwifiex_ra_list_tbl *ra_list; -+ struct list_head *ra_list_head; -+@@ -228,7 +229,7 @@ mwifiex_tdls_add_ht_oper(struct mwifiex_ -+ } - +- - cancel_work_sync(&sdata->recalc_smps); -+ sdata_lock(sdata); - sdata->vif.csa_active = false; -+ sdata_unlock(sdata); - cancel_work_sync(&sdata->csa_finalize_work); -+ static int mwifiex_tdls_add_vht_oper(struct mwifiex_private *priv, -+- u8 *mac, struct sk_buff *skb) -++ const u8 *mac, struct sk_buff *skb) -+ { -+ struct mwifiex_bssdescriptor *bss_desc; -+ struct ieee80211_vht_operation *vht_oper; -+@@ -367,8 +368,9 @@ static void mwifiex_tdls_add_qos_capab(s -+ } - +- - cancel_delayed_work_sync(&sdata->dfs_cac_timer_work); ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -599,10 +599,10 @@ static int ieee80211_is_unicast_robust_m -+ static int mwifiex_prep_tdls_encap_data(struct mwifiex_private *priv, -+- u8 *peer, u8 action_code, u8 dialog_token, -+- u16 status_code, struct sk_buff *skb) -++ const u8 *peer, u8 action_code, -++ u8 dialog_token, -++ u16 status_code, struct sk_buff *skb) - { +- { - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; -+ struct ieee80211_tdls_data *tf; -+ int ret; -+@@ -506,7 +508,8 @@ static int mwifiex_prep_tdls_encap_data( -+ } - +- -- if (skb->len < 24 || is_multicast_ether_addr(hdr->addr1)) -+ if (is_multicast_ether_addr(hdr->addr1)) - return 0; -+ static void -+-mwifiex_tdls_add_link_ie(struct sk_buff *skb, u8 *src_addr, u8 *peer, u8 *bssid) -++mwifiex_tdls_add_link_ie(struct sk_buff *skb, const u8 *src_addr, -++ const u8 *peer, const u8 *bssid) -+ { -+ struct ieee80211_tdls_lnkie *lnkid; - +- -- return ieee80211_is_robust_mgmt_frame(hdr); -+ return ieee80211_is_robust_mgmt_frame(skb); -+@@ -520,8 +523,8 @@ mwifiex_tdls_add_link_ie(struct sk_buff -+ memcpy(lnkid->resp_sta, peer, ETH_ALEN); - } - -+-int mwifiex_send_tdls_data_frame(struct mwifiex_private *priv, -+- u8 *peer, u8 action_code, u8 dialog_token, -++int mwifiex_send_tdls_data_frame(struct mwifiex_private *priv, const u8 *peer, -++ u8 action_code, u8 dialog_token, -+ u16 status_code, const u8 *extra_ies, -+ size_t extra_ies_len) -+ { -+@@ -613,7 +616,8 @@ int mwifiex_send_tdls_data_frame(struct -+ } - +- } +- +- -@@ -610,10 +610,10 @@ static int ieee80211_is_multicast_robust -+ static int -+-mwifiex_construct_tdls_action_frame(struct mwifiex_private *priv, u8 *peer, -++mwifiex_construct_tdls_action_frame(struct mwifiex_private *priv, -++ const u8 *peer, -+ u8 action_code, u8 dialog_token, -+ u16 status_code, struct sk_buff *skb) - { +- { - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; -+@@ -691,10 +695,10 @@ mwifiex_construct_tdls_action_frame(stru -+ return 0; -+ } - +- -- if (skb->len < 24 || !is_multicast_ether_addr(hdr->addr1)) -+ if (!is_multicast_ether_addr(hdr->addr1)) - return 0; -+-int mwifiex_send_tdls_action_frame(struct mwifiex_private *priv, -+- u8 *peer, u8 action_code, u8 dialog_token, -+- u16 status_code, const u8 *extra_ies, -+- size_t extra_ies_len) -++int mwifiex_send_tdls_action_frame(struct mwifiex_private *priv, const u8 *peer, -++ u8 action_code, u8 dialog_token, -++ u16 status_code, const u8 *extra_ies, -++ size_t extra_ies_len) -+ { -+ struct sk_buff *skb; -+ struct mwifiex_txinfo *tx_info; -+@@ -901,7 +905,7 @@ void mwifiex_process_tdls_action_frame(s -+ } - +- -- return ieee80211_is_robust_mgmt_frame(hdr); -+ return ieee80211_is_robust_mgmt_frame(skb); -+ static int -+-mwifiex_tdls_process_config_link(struct mwifiex_private *priv, u8 *peer) -++mwifiex_tdls_process_config_link(struct mwifiex_private *priv, const u8 *peer) -+ { -+ struct mwifiex_sta_node *sta_ptr; -+ struct mwifiex_ds_tdls_oper tdls_oper; -+@@ -922,7 +926,7 @@ mwifiex_tdls_process_config_link(struct - } - -+ static int -+-mwifiex_tdls_process_create_link(struct mwifiex_private *priv, u8 *peer) -++mwifiex_tdls_process_create_link(struct mwifiex_private *priv, const u8 *peer) -+ { -+ struct mwifiex_sta_node *sta_ptr; -+ struct mwifiex_ds_tdls_oper tdls_oper; -+@@ -949,7 +953,7 @@ mwifiex_tdls_process_create_link(struct -+ } - +- } +- +- -@@ -626,7 +626,7 @@ static int ieee80211_get_mmie_keyidx(str - if (skb->len < 24 + sizeof(*mmie) || !is_multicast_ether_addr(hdr->da)) - return -1; @@ -4729,15 +4060,7 @@ index a1af6c2..dc1e265 100644 -+ ieee80211_is_robust_mgmt_frame(rx->skb))) - return -EACCES; - } -+ static int -+-mwifiex_tdls_process_disable_link(struct mwifiex_private *priv, u8 *peer) -++mwifiex_tdls_process_disable_link(struct mwifiex_private *priv, const u8 *peer) -+ { -+ struct mwifiex_sta_node *sta_ptr; -+ struct mwifiex_ds_tdls_oper tdls_oper; -+@@ -978,7 +982,7 @@ mwifiex_tdls_process_disable_link(struct -+ } - +- ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -452,8 +452,7 @@ static int ieee80211_use_mfp(__le16 fc, @@ -4816,36 +4139,17 @@ index a1af6c2..dc1e265 100644 - I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); -@@ -878,7 +890,7 @@ static int ieee80211_fragment(struct iee - } -+ static int -+-mwifiex_tdls_process_enable_link(struct mwifiex_private *priv, u8 *peer) -++mwifiex_tdls_process_enable_link(struct mwifiex_private *priv, const u8 *peer) -+ { -+ struct mwifiex_sta_node *sta_ptr; -+ struct ieee80211_mcs_info mcs; -+@@ -1035,7 +1039,7 @@ mwifiex_tdls_process_enable_link(struct -+ return 0; -+ } - +- - /* adjust first fragment's length */ -- skb->len = hdrlen + per_fragm; -+ skb_trim(skb, hdrlen + per_fragm); -+-int mwifiex_tdls_oper(struct mwifiex_private *priv, u8 *peer, u8 action) -++int mwifiex_tdls_oper(struct mwifiex_private *priv, const u8 *peer, u8 action) -+ { -+ switch (action) { -+ case MWIFIEX_TDLS_ENABLE_LINK: -+@@ -1050,7 +1054,7 @@ int mwifiex_tdls_oper(struct mwifiex_pri - return 0; - } - +- return 0; +- } +- -@@ -2900,7 +2912,7 @@ ieee80211_get_buffered_bc(struct ieee802 - cpu_to_le16(IEEE80211_FCTL_MOREDATA); - } -+-int mwifiex_get_tdls_link_status(struct mwifiex_private *priv, u8 *mac) -++int mwifiex_get_tdls_link_status(struct mwifiex_private *priv, const u8 *mac) -+ { -+ struct mwifiex_sta_node *sta_ptr; - +- -- if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) -+ if (sdata->vif.type == NL80211_IFTYPE_AP) - sdata = IEEE80211_DEV_TO_SUB_IF(skb->dev); @@ -4855,33 +4159,12 @@ index a1af6c2..dc1e265 100644 -+++ b/net/mac80211/wpa.c -@@ -499,7 +499,7 @@ ieee80211_crypto_ccmp_decrypt(struct iee - hdrlen = ieee80211_hdrlen(hdr->frame_control); -+--- a/drivers/net/wireless/mwifiex/util.c -++++ b/drivers/net/wireless/mwifiex/util.c -+@@ -259,7 +259,7 @@ int mwifiex_complete_cmd(struct mwifiex_ -+ * NULL is returned if station entry is not found in associated STA list. -+ */ -+ struct mwifiex_sta_node * -+-mwifiex_get_sta_entry(struct mwifiex_private *priv, u8 *mac) -++mwifiex_get_sta_entry(struct mwifiex_private *priv, const u8 *mac) -+ { -+ struct mwifiex_sta_node *node; - +- - if (!ieee80211_is_data(hdr->frame_control) && -- !ieee80211_is_robust_mgmt_frame(hdr)) -+ !ieee80211_is_robust_mgmt_frame(skb)) - return RX_CONTINUE; -+@@ -280,7 +280,7 @@ mwifiex_get_sta_entry(struct mwifiex_pri -+ * If received mac address is NULL, NULL is returned. -+ */ -+ struct mwifiex_sta_node * -+-mwifiex_add_sta_entry(struct mwifiex_private *priv, u8 *mac) -++mwifiex_add_sta_entry(struct mwifiex_private *priv, const u8 *mac) -+ { -+ struct mwifiex_sta_node *node; -+ unsigned long flags; -+@@ -332,7 +332,7 @@ mwifiex_set_sta_ht_cap(struct mwifiex_pr -+ } - +- - data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN - ---- a/net/wireless/ap.c -+++ b/net/wireless/ap.c @@ -4895,127 +4178,14 @@ index a1af6c2..dc1e265 100644 - rdev_set_qos_map(rdev, dev, NULL); -+ nl80211_send_ap_stopped(wdev); - } -+ /* This function will delete a station entry from station list */ -+-void mwifiex_del_sta_entry(struct mwifiex_private *priv, u8 *mac) -++void mwifiex_del_sta_entry(struct mwifiex_private *priv, const u8 *mac) -+ { -+ struct mwifiex_sta_node *node; -+ unsigned long flags; -+--- a/drivers/net/wireless/mwifiex/wmm.c -++++ b/drivers/net/wireless/mwifiex/wmm.c -+@@ -92,7 +92,7 @@ mwifiex_wmm_ac_debug_print(const struct -+ * The function also initializes the list with the provided RA. -+ */ -+ static struct mwifiex_ra_list_tbl * -+-mwifiex_wmm_allocate_ralist_node(struct mwifiex_adapter *adapter, u8 *ra) -++mwifiex_wmm_allocate_ralist_node(struct mwifiex_adapter *adapter, const u8 *ra) -+ { -+ struct mwifiex_ra_list_tbl *ra_list; - +- - return err; ---- a/net/wireless/core.c -+++ b/net/wireless/core.c -@@ -203,8 +203,11 @@ void cfg80211_stop_p2p_device(struct cfg -+@@ -139,8 +139,7 @@ static u8 mwifiex_get_random_ba_threshol -+ * This function allocates and adds a RA list for all TIDs -+ * with the given RA. -+ */ -+-void -+-mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra) -++void mwifiex_ralist_add(struct mwifiex_private *priv, const u8 *ra) -+ { -+ int i; -+ struct mwifiex_ra_list_tbl *ra_list; -+@@ -566,7 +565,7 @@ mwifiex_clean_txrx(struct mwifiex_privat -+ */ -+ static struct mwifiex_ra_list_tbl * -+ mwifiex_wmm_get_ralist_node(struct mwifiex_private *priv, u8 tid, -+- u8 *ra_addr) -++ const u8 *ra_addr) -+ { -+ struct mwifiex_ra_list_tbl *ra_list; -+ -+@@ -587,7 +586,8 @@ mwifiex_wmm_get_ralist_node(struct mwifi -+ * retrieved. -+ */ -+ struct mwifiex_ra_list_tbl * -+-mwifiex_wmm_get_queue_raptr(struct mwifiex_private *priv, u8 tid, u8 *ra_addr) -++mwifiex_wmm_get_queue_raptr(struct mwifiex_private *priv, u8 tid, -++ const u8 *ra_addr) -+ { -+ struct mwifiex_ra_list_tbl *ra_list; -+ -+--- a/drivers/net/wireless/mwifiex/wmm.h -++++ b/drivers/net/wireless/mwifiex/wmm.h -+@@ -99,7 +99,7 @@ mwifiex_wmm_is_ra_list_empty(struct list -+ -+ void mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv, -+ struct sk_buff *skb); -+-void mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra); -++void mwifiex_ralist_add(struct mwifiex_private *priv, const u8 *ra); -+ void mwifiex_rotate_priolists(struct mwifiex_private *priv, -+ struct mwifiex_ra_list_tbl *ra, int tid); -+ -+@@ -123,7 +123,8 @@ void mwifiex_wmm_setup_ac_downgrade(stru -+ int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv, -+ const struct host_cmd_ds_command *resp); -+ struct mwifiex_ra_list_tbl * -+-mwifiex_wmm_get_queue_raptr(struct mwifiex_private *priv, u8 tid, u8 *ra_addr); -++mwifiex_wmm_get_queue_raptr(struct mwifiex_private *priv, u8 tid, -++ const u8 *ra_addr); -+ u8 mwifiex_wmm_downgrade_tid(struct mwifiex_private *priv, u32 tid); -+ -+ #endif /* !_MWIFIEX_WMM_H_ */ -+--- a/drivers/net/wireless/orinoco/hw.c -++++ b/drivers/net/wireless/orinoco/hw.c -+@@ -988,8 +988,8 @@ int __orinoco_hw_setup_enc(struct orinoc -+ * tsc must be NULL or up to 8 bytes -+ */ -+ int __orinoco_hw_set_tkip_key(struct orinoco_private *priv, int key_idx, -+- int set_tx, u8 *key, u8 *rsc, size_t rsc_len, -+- u8 *tsc, size_t tsc_len) -++ int set_tx, const u8 *key, const u8 *rsc, -++ size_t rsc_len, const u8 *tsc, size_t tsc_len) -+ { -+ struct { -+ __le16 idx; -+--- a/drivers/net/wireless/orinoco/hw.h -++++ b/drivers/net/wireless/orinoco/hw.h -+@@ -38,8 +38,8 @@ int __orinoco_hw_set_wap(struct orinoco_ -+ int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv); -+ int __orinoco_hw_setup_enc(struct orinoco_private *priv); -+ int __orinoco_hw_set_tkip_key(struct orinoco_private *priv, int key_idx, -+- int set_tx, u8 *key, u8 *rsc, size_t rsc_len, -+- u8 *tsc, size_t tsc_len); -++ int set_tx, const u8 *key, const u8 *rsc, -++ size_t rsc_len, const u8 *tsc, size_t tsc_len); -+ int orinoco_clear_tkip_key(struct orinoco_private *priv, int key_idx); -+ int __orinoco_hw_set_multicast_list(struct orinoco_private *priv, -+ struct net_device *dev, -+--- a/drivers/net/wireless/orinoco/wext.c -++++ b/drivers/net/wireless/orinoco/wext.c -+@@ -52,9 +52,9 @@ static int orinoco_set_key(struct orinoc -+ priv->keys[index].seq_len = seq_len; -+ -+ if (key_len) -+- memcpy(priv->keys[index].key, key, key_len); -++ memcpy((void *)priv->keys[index].key, key, key_len); -+ if (seq_len) -+- memcpy(priv->keys[index].seq, seq, seq_len); -++ memcpy((void *)priv->keys[index].seq, seq, seq_len); -+ -+ switch (alg) { -+ case ORINOCO_ALG_TKIP: -+--- a/drivers/net/wireless/rndis_wlan.c -++++ b/drivers/net/wireless/rndis_wlan.c -+@@ -517,7 +517,7 @@ static int rndis_set_default_key(struct -+ u8 key_index, bool unicast, bool multicast); - +- - rdev->opencount--; -+ static int rndis_get_station(struct wiphy *wiphy, struct net_device *dev, -+- u8 *mac, struct station_info *sinfo); -++ const u8 *mac, struct station_info *sinfo); - +- -- WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev && -- !rdev->scan_req->notified); -+ if (rdev->scan_req && rdev->scan_req->wdev == wdev) { @@ -5023,11 +4193,8 @@ index a1af6c2..dc1e265 100644 -+ rdev->scan_req->aborted = true; -+ ___cfg80211_scan_done(rdev, false); -+ } -+ static int rndis_dump_station(struct wiphy *wiphy, struct net_device *dev, -+ int idx, u8 *mac, struct station_info *sinfo); -+@@ -2490,7 +2490,7 @@ static void rndis_fill_station_info(stru - } - +- } +- - static int cfg80211_rfkill_set_block(void *data, bool blocked) -@@ -447,9 +450,6 @@ int wiphy_register(struct wiphy *wiphy) - int i; @@ -5046,56 +4213,7 @@ index a1af6c2..dc1e265 100644 -- -- wdev->beacon_interval = 0; - } -+ static int rndis_get_station(struct wiphy *wiphy, struct net_device *dev, -+- u8 *mac, struct station_info *sinfo) -++ const u8 *mac, struct station_info *sinfo) -+ { -+ struct rndis_wlan_private *priv = wiphy_priv(wiphy); -+ struct usbnet *usbdev = priv->usbdev; -+--- a/drivers/net/wireless/ti/wlcore/main.c -++++ b/drivers/net/wireless/ti/wlcore/main.c -+@@ -1416,7 +1416,7 @@ void wl1271_rx_filter_free(struct wl12xx -+ -+ int wl1271_rx_filter_alloc_field(struct wl12xx_rx_filter *filter, -+ u16 offset, u8 flags, -+- u8 *pattern, u8 len) -++ const u8 *pattern, u8 len) -+ { -+ struct wl12xx_rx_filter_field *field; -+ -+--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h -++++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h -+@@ -512,8 +512,8 @@ int wl1271_recalc_rx_streaming(struct wl -+ void wl12xx_queue_recovery_work(struct wl1271 *wl); -+ size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen); -+ int wl1271_rx_filter_alloc_field(struct wl12xx_rx_filter *filter, -+- u16 offset, u8 flags, -+- u8 *pattern, u8 len); -++ u16 offset, u8 flags, -++ const u8 *pattern, u8 len); -+ void wl1271_rx_filter_free(struct wl12xx_rx_filter *filter); -+ struct wl12xx_rx_filter *wl1271_rx_filter_alloc(void); -+ int wl1271_rx_filter_get_fields_size(struct wl12xx_rx_filter *filter); -+--- a/include/net/cfg80211.h -++++ b/include/net/cfg80211.h -+@@ -341,8 +341,8 @@ struct vif_params { -+ * @seq_len: length of @seq. -+ */ -+ struct key_params { -+- u8 *key; -+- u8 *seq; -++ const u8 *key; -++ const u8 *seq; -+ int key_len; -+ int seq_len; -+ u32 cipher; -+@@ -458,7 +458,7 @@ bool cfg80211_chandef_usable(struct wiph -+ */ -+ int cfg80211_chandef_dfs_required(struct wiphy *wiphy, -+ const struct cfg80211_chan_def *chandef, -+- enum nl80211_iftype); -++ enum nl80211_iftype iftype); - +- - static int cfg80211_netdev_notifier_call(struct notifier_block *nb, -@@ -875,8 +873,11 @@ static int cfg80211_netdev_notifier_call - break; @@ -5108,66 +4226,7 @@ index a1af6c2..dc1e265 100644 -+ rdev->scan_req->aborted = true; -+ ___cfg80211_scan_done(rdev, false); -+ } -+ /** -+ * ieee80211_chandef_rate_flags - returns rate flags for a channel -+@@ -694,8 +694,10 @@ struct cfg80211_ap_settings { -+ * -+ * @chandef: defines the channel to use after the switch -+ * @beacon_csa: beacon data while performing the switch -+- * @counter_offset_beacon: offset for the counter within the beacon (tail) -+- * @counter_offset_presp: offset for the counter within the probe response -++ * @counter_offsets_beacon: offsets of the counters within the beacon (tail) -++ * @counter_offsets_presp: offsets of the counters within the probe response -++ * @n_counter_offsets_beacon: number of csa counters the beacon (tail) -++ * @n_counter_offsets_presp: number of csa counters in the probe response -+ * @beacon_after: beacon data to be used on the new channel -+ * @radar_required: whether radar detection is required on the new channel -+ * @block_tx: whether transmissions should be blocked while changing -+@@ -704,7 +706,10 @@ struct cfg80211_ap_settings { -+ struct cfg80211_csa_settings { -+ struct cfg80211_chan_def chandef; -+ struct cfg80211_beacon_data beacon_csa; -+- u16 counter_offset_beacon, counter_offset_presp; -++ const u16 *counter_offsets_beacon; -++ const u16 *counter_offsets_presp; -++ unsigned int n_counter_offsets_beacon; -++ unsigned int n_counter_offsets_presp; -+ struct cfg80211_beacon_data beacon_after; -+ bool radar_required; -+ bool block_tx; -+@@ -1164,7 +1169,7 @@ struct bss_parameters { -+ int use_cts_prot; -+ int use_short_preamble; -+ int use_short_slot_time; -+- u8 *basic_rates; -++ const u8 *basic_rates; -+ u8 basic_rates_len; -+ int ap_isolate; -+ int ht_opmode; -+@@ -1694,10 +1699,10 @@ struct cfg80211_disassoc_request { -+ * @ht_capa_mask: The bits of ht_capa which are to be used. -+ */ -+ struct cfg80211_ibss_params { -+- u8 *ssid; -+- u8 *bssid; -++ const u8 *ssid; -++ const u8 *bssid; -+ struct cfg80211_chan_def chandef; -+- u8 *ie; -++ const u8 *ie; -+ u8 ssid_len, ie_len; -+ u16 beacon_interval; -+ u32 basic_rates; -+@@ -1806,8 +1811,8 @@ struct cfg80211_bitrate_mask { -+ * @pmkid: The PMK material itself. -+ */ -+ struct cfg80211_pmksa { -+- u8 *bssid; -+- u8 *pmkid; -++ const u8 *bssid; -++ const u8 *pmkid; -+ }; - +- - if (WARN_ON(rdev->sched_scan_req && - rdev->sched_scan_req->dev == wdev->netdev)) { ---- a/net/wireless/core.h @@ -5187,32 +4246,7 @@ index a1af6c2..dc1e265 100644 -+ struct ieee80211_channel *channel; - } ij; - }; -+ /** -+@@ -1822,7 +1827,7 @@ struct cfg80211_pmksa { -+ * memory, free @mask only! -+ */ -+ struct cfg80211_pkt_pattern { -+- u8 *mask, *pattern; -++ const u8 *mask, *pattern; -+ int pattern_len; -+ int pkt_offset; -+ }; -+@@ -1986,6 +1991,8 @@ struct cfg80211_update_ft_ies_params { -+ * @len: buffer length -+ * @no_cck: don't use cck rates for this frame -+ * @dont_wait_for_ack: tells the low level not to wait for an ack -++ * @n_csa_offsets: length of csa_offsets array -++ * @csa_offsets: array of all the csa offsets in the frame -+ */ -+ struct cfg80211_mgmt_tx_params { -+ struct ieee80211_channel *chan; -+@@ -1995,6 +2002,8 @@ struct cfg80211_mgmt_tx_params { -+ size_t len; -+ bool no_cck; -+ bool dont_wait_for_ack; -++ int n_csa_offsets; -++ const u16 *csa_offsets; - }; +- }; -@@ -257,7 +259,8 @@ int __cfg80211_leave_ibss(struct cfg8021 - struct net_device *dev, bool nowext); - int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev, @@ -5318,7 +4352,7 @@ index a1af6c2..dc1e265 100644 -@@ -5509,11 +5515,40 @@ static int nl80211_start_sched_scan(stru - if (n_ssids > wiphy->max_sched_scan_ssids) - return -EINVAL; - +- -- if (info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) -+ /* -+ * First, count the number of 'real' matchsets. Due to an issue with @@ -5352,103 +4386,11 @@ index a1af6c2..dc1e265 100644 -+ default_match_rssi = nla_get_s32(rssi); -+ } -+ } -+ /** -+@@ -2336,28 +2345,29 @@ struct cfg80211_ops { -+ -+ -+ int (*add_station)(struct wiphy *wiphy, struct net_device *dev, -+- u8 *mac, struct station_parameters *params); -++ const u8 *mac, -++ struct station_parameters *params); -+ int (*del_station)(struct wiphy *wiphy, struct net_device *dev, -+- u8 *mac); -++ const u8 *mac); -+ int (*change_station)(struct wiphy *wiphy, struct net_device *dev, -+- u8 *mac, struct station_parameters *params); -++ const u8 *mac, -++ struct station_parameters *params); -+ int (*get_station)(struct wiphy *wiphy, struct net_device *dev, -+- u8 *mac, struct station_info *sinfo); -++ const u8 *mac, struct station_info *sinfo); -+ int (*dump_station)(struct wiphy *wiphy, struct net_device *dev, -+- int idx, u8 *mac, struct station_info *sinfo); -++ int idx, u8 *mac, struct station_info *sinfo); -+ -+ int (*add_mpath)(struct wiphy *wiphy, struct net_device *dev, -+- u8 *dst, u8 *next_hop); -++ const u8 *dst, const u8 *next_hop); -+ int (*del_mpath)(struct wiphy *wiphy, struct net_device *dev, -+- u8 *dst); -++ const u8 *dst); -+ int (*change_mpath)(struct wiphy *wiphy, struct net_device *dev, -+- u8 *dst, u8 *next_hop); -++ const u8 *dst, const u8 *next_hop); -+ int (*get_mpath)(struct wiphy *wiphy, struct net_device *dev, -+- u8 *dst, u8 *next_hop, -+- struct mpath_info *pinfo); -++ u8 *dst, u8 *next_hop, struct mpath_info *pinfo); -+ int (*dump_mpath)(struct wiphy *wiphy, struct net_device *dev, -+- int idx, u8 *dst, u8 *next_hop, -+- struct mpath_info *pinfo); -++ int idx, u8 *dst, u8 *next_hop, -++ struct mpath_info *pinfo); -+ int (*get_mesh_config)(struct wiphy *wiphy, -+ struct net_device *dev, -+ struct mesh_config *conf); -+@@ -2487,11 +2497,11 @@ struct cfg80211_ops { -+ struct cfg80211_gtk_rekey_data *data); -+ -+ int (*tdls_mgmt)(struct wiphy *wiphy, struct net_device *dev, -+- u8 *peer, u8 action_code, u8 dialog_token, -++ const u8 *peer, u8 action_code, u8 dialog_token, -+ u16 status_code, u32 peer_capability, -+ const u8 *buf, size_t len); -+ int (*tdls_oper)(struct wiphy *wiphy, struct net_device *dev, -+- u8 *peer, enum nl80211_tdls_operation oper); -++ const u8 *peer, enum nl80211_tdls_operation oper); -+ -+ int (*probe_client)(struct wiphy *wiphy, struct net_device *dev, -+ const u8 *peer, u64 *cookie); -+@@ -2638,6 +2648,7 @@ struct ieee80211_iface_limit { -+ * between infrastructure and AP types must match. This is required -+ * only in special cases. -+ * @radar_detect_widths: bitmap of channel widths supported for radar detection -++ * @radar_detect_regions: bitmap of regions supported for radar detection -+ * -+ * With this structure the driver can describe which interface -+ * combinations it supports concurrently. -+@@ -2695,6 +2706,7 @@ struct ieee80211_iface_combination { -+ u8 n_limits; -+ bool beacon_int_infra_match; -+ u8 radar_detect_widths; -++ u8 radar_detect_regions; -+ }; -+ -+ struct ieee80211_txrx_stypes { -+@@ -2925,6 +2937,11 @@ struct wiphy_vendor_command { -+ * (including P2P GO) or 0 to indicate no such limit is advertised. The -+ * driver is allowed to advertise a theoretical limit that it can reach in -+ * some cases, but may not always reach. -++ * -++ * @max_num_csa_counters: Number of supported csa_counters in beacons -++ * and probe responses. This value should be set if the driver -++ * wishes to limit the number of csa counters. Default (0) means -++ * infinite. -+ */ -+ struct wiphy { -+ /* assign these fields before you register the wiphy */ -+@@ -3045,6 +3062,8 @@ struct wiphy { -+ -+ u16 max_ap_assoc_sta; -+ -++ u8 max_num_csa_counters; - + +-+ -+ /* However, if there's no other matchset, add the RSSI one */ -+ if (!n_match_sets && default_match_rssi != NL80211_SCAN_RSSI_THOLD_OFF) -+ n_match_sets = 1; -+ char priv[0] __aligned(NETDEV_ALIGN); -+ }; - +- - if (n_match_sets > wiphy->max_match_sets) - return -EINVAL; -@@ -5634,11 +5669,22 @@ static int nl80211_start_sched_scan(stru @@ -5497,70 +4439,11 @@ index a1af6c2..dc1e265 100644 -- NL80211_SCAN_RSSI_THOLD_OFF; - i++; - } -+@@ -3273,7 +3292,7 @@ struct wireless_dev { -+ struct cfg80211_ibss_params ibss; -+ struct cfg80211_connect_params connect; -+ struct cfg80211_cached_keys *keys; -+- u8 *ie; -++ const u8 *ie; -+ size_t ie_len; -+ u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN]; -+ u8 ssid[IEEE80211_MAX_SSID_LEN]; -+@@ -3514,7 +3533,8 @@ int ieee80211_data_to_8023(struct sk_buf -+ * Return: 0 on success, or a negative error code. -+ */ -+ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, -+- enum nl80211_iftype iftype, u8 *bssid, bool qos); -++ enum nl80211_iftype iftype, const u8 *bssid, -++ bool qos); -+ -+ /** -+ * ieee80211_amsdu_to_8023s - decode an IEEE 802.11n A-MSDU frame -+@@ -4315,7 +4335,7 @@ void cfg80211_roamed_bss(struct net_devi -+ * and not try to connect to any AP any more. -+ */ -+ void cfg80211_disconnected(struct net_device *dev, u16 reason, -+- u8 *ie, size_t ie_len, gfp_t gfp); -++ const u8 *ie, size_t ie_len, gfp_t gfp); -+ -+ /** -+ * cfg80211_ready_on_channel - notification of remain_on_channel start -+@@ -4771,6 +4791,35 @@ int cfg80211_iter_combinations(struct wi -+ void *data), -+ void *data); -+ -++/* -++ * cfg80211_stop_iface - trigger interface disconnection -++ * -++ * @wiphy: the wiphy -++ * @wdev: wireless device -++ * @gfp: context flags -++ * -++ * Trigger interface to be stopped as if AP was stopped, IBSS/mesh left, STA -++ * disconnected. -++ * -++ * Note: This doesn't need any locks and is asynchronous. -++ */ -++void cfg80211_stop_iface(struct wiphy *wiphy, struct wireless_dev *wdev, -++ gfp_t gfp); - + +-+ -+ /* there was no other matchset, so the RSSI one is alone */ -+ if (i == 0) -+ request->match_sets[0].rssi_thold = default_match_rssi; -++/** -++ * cfg80211_shutdown_all_interfaces - shut down all interfaces for a wiphy -++ * @wiphy: the wiphy to shut down -++ * -++ * This function shuts down all interfaces belonging to this wiphy by -++ * calling dev_close() (and treating non-netdev interfaces as needed). -++ * It shouldn't really be used unless there are some fatal device errors -++ * that really can't be recovered in any other way. -++ * -++ * Callers must hold the RTNL and be able to deal with callbacks into -++ * the driver while the function is running. -++ */ -++void cfg80211_shutdown_all_interfaces(struct wiphy *wiphy); - + +-+ -+ request->min_rssi_thold = INT_MAX; -+ for (i = 0; i < n_match_sets; i++) -+ request->min_rssi_thold = @@ -5572,42 +4455,7 @@ index a1af6c2..dc1e265 100644 - - if (info->attrs[NL80211_ATTR_IE]) { -@@ -5751,7 +5810,7 @@ static int nl80211_start_radar_detection -+ /* Logging, debugging and troubleshooting/diagnostic helpers. */ -+ -+ /* wiphy_printk helpers, similar to dev_printk */ -+--- a/include/net/mac80211.h -++++ b/include/net/mac80211.h -+@@ -1113,7 +1113,9 @@ enum ieee80211_vif_flags { -+ * @addr: address of this interface -+ * @p2p: indicates whether this AP or STA interface is a p2p -+ * interface, i.e. a GO or p2p-sta respectively -+- * @csa_active: marks whether a channel switch is going on -++ * @csa_active: marks whether a channel switch is going on. Internally it is -++ * write-protected by sdata_lock and local->mtx so holding either is fine -++ * for read access. -+ * @driver_flags: flags/capabilities the driver has for this interface, -+ * these need to be set (or cleared) when the interface is added -+ * or, if supported by the driver, the interface type is changed -+@@ -1374,6 +1376,7 @@ struct ieee80211_sta_rates { -+ * the station moves to associated state. -+ * @smps_mode: current SMPS mode (off, static or dynamic) -+ * @rates: rate control selection table -++ * @tdls: indicates whether the STA is a TDLS peer -+ */ -+ struct ieee80211_sta { -+ u32 supp_rates[IEEE80211_NUM_BANDS]; -+@@ -1388,6 +1391,7 @@ struct ieee80211_sta { -+ enum ieee80211_sta_rx_bandwidth bandwidth; -+ enum ieee80211_smps_mode smps_mode; -+ struct ieee80211_sta_rates __rcu *rates; -++ bool tdls; -+ -+ /* must be last */ -+ u8 drv_priv[0] __aligned(sizeof(void *)); -+@@ -3407,6 +3411,47 @@ void ieee80211_tx_status_irqsafe(struct -+ */ -+ void ieee80211_report_low_ack(struct ieee80211_sta *sta, u32 num_packets); - +- - err = rdev->ops->start_radar_detection(&rdev->wiphy, dev, &chandef); - if (!err) { -- wdev->channel = chandef.chan; @@ -5641,73 +4489,8 @@ index a1af6c2..dc1e265 100644 - sband, -@@ -10054,40 +10116,31 @@ void nl80211_send_scan_start(struct cfg8 - NL80211_MCGRP_SCAN, GFP_KERNEL); -++#define IEEE80211_MAX_CSA_COUNTERS_NUM 2 -++ -++/** -++ * struct ieee80211_mutable_offsets - mutable beacon offsets -++ * @tim_offset: position of TIM element -++ * @tim_length: size of TIM element -++ * @csa_counter_offs: array of IEEE80211_MAX_CSA_COUNTERS_NUM offsets -++ * to CSA counters. This array can contain zero values which -++ * should be ignored. -++ */ -++struct ieee80211_mutable_offsets { -++ u16 tim_offset; -++ u16 tim_length; -++ -++ u16 csa_counter_offs[IEEE80211_MAX_CSA_COUNTERS_NUM]; -++}; -++ -++/** -++ * ieee80211_beacon_get_template - beacon template generation function -++ * @hw: pointer obtained from ieee80211_alloc_hw(). -++ * @vif: &struct ieee80211_vif pointer from the add_interface callback. -++ * @offs: &struct ieee80211_mutable_offsets pointer to struct that will -++ * receive the offsets that may be updated by the driver. -++ * -++ * If the driver implements beaconing modes, it must use this function to -++ * obtain the beacon template. -++ * -++ * This function should be used if the beacon frames are generated by the -++ * device, and then the driver must use the returned beacon as the template -++ * The driver or the device are responsible to update the DTIM and, when -++ * applicable, the CSA count. -++ * -++ * The driver is responsible for freeing the returned skb. -++ * -++ * Return: The beacon template. %NULL on error. -++ */ -++struct sk_buff * -++ieee80211_beacon_get_template(struct ieee80211_hw *hw, -++ struct ieee80211_vif *vif, -++ struct ieee80211_mutable_offsets *offs); -++ -+ /** -+ * ieee80211_beacon_get_tim - beacon generation function -+ * @hw: pointer obtained from ieee80211_alloc_hw(). -+@@ -3418,16 +3463,12 @@ void ieee80211_report_low_ack(struct iee -+ * Set to 0 if invalid (in non-AP modes). -+ * -+ * If the driver implements beaconing modes, it must use this function to -+- * obtain the beacon frame/template. -++ * obtain the beacon frame. -+ * -+ * If the beacon frames are generated by the host system (i.e., not in -+ * hardware/firmware), the driver uses this function to get each beacon -+- * frame from mac80211 -- it is responsible for calling this function -+- * before the beacon is needed (e.g. based on hardware interrupt). -+- * -+- * If the beacon frames are generated by the device, then the driver -+- * must use the returned beacon as the template and change the TIM IE -+- * according to the current DTIM parameters/TIM bitmap. -++ * frame from mac80211 -- it is responsible for calling this function exactly -++ * once before the beacon is needed (e.g. based on hardware interrupt). -+ * -+ * The driver is responsible for freeing the returned skb. -+ * -+@@ -3453,6 +3494,20 @@ static inline struct sk_buff *ieee80211_ - } - +- } +- --void nl80211_send_scan_done(struct cfg80211_registered_device *rdev, -- struct wireless_dev *wdev) -+struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev, @@ -5719,65 +4502,7 @@ index a1af6c2..dc1e265 100644 - if (!msg) -- return; -+ return NULL; -+ /** -++ * ieee80211_csa_update_counter - request mac80211 to decrement the csa counter -++ * @vif: &struct ieee80211_vif pointer from the add_interface callback. -++ * -++ * The csa counter should be updated after each beacon transmission. -++ * This function is called implicitly when -++ * ieee80211_beacon_get/ieee80211_beacon_get_tim are called, however if the -++ * beacon frames are generated by the device, the driver should call this -++ * function after each beacon transmission to sync mac80211's csa counters. -++ * -++ * Return: new csa counter value -++ */ -++u8 ieee80211_csa_update_counter(struct ieee80211_vif *vif); -++ -++/** -+ * ieee80211_csa_finish - notify mac80211 about channel switch -+ * @vif: &struct ieee80211_vif pointer from the add_interface callback. -+ * -+--- a/include/uapi/linux/nl80211.h -++++ b/include/uapi/linux/nl80211.h -+@@ -503,6 +503,9 @@ -+ * TX status event pertaining to the TX request. -+ * %NL80211_ATTR_TX_NO_CCK_RATE is used to decide whether to send the -+ * management frames at CCK rate or not in 2GHz band. -++ * %NL80211_ATTR_CSA_C_OFFSETS_TX is an array of offsets to CSA -++ * counters which will be updated to the current value. This attribute -++ * is used during CSA period. -+ * @NL80211_CMD_FRAME_WAIT_CANCEL: When an off-channel TX was requested, this -+ * command may be used with the corresponding cookie to cancel the wait -+ * time if it is known that it is no longer necessary. -+@@ -1525,10 +1528,10 @@ enum nl80211_commands { -+ * operation). -+ * @NL80211_ATTR_CSA_IES: Nested set of attributes containing the IE information -+ * for the time while performing a channel switch. -+- * @NL80211_ATTR_CSA_C_OFF_BEACON: Offset of the channel switch counter -+- * field in the beacons tail (%NL80211_ATTR_BEACON_TAIL). -+- * @NL80211_ATTR_CSA_C_OFF_PRESP: Offset of the channel switch counter -+- * field in the probe response (%NL80211_ATTR_PROBE_RESP). -++ * @NL80211_ATTR_CSA_C_OFF_BEACON: An array of offsets (u16) to the channel -++ * switch counters in the beacons tail (%NL80211_ATTR_BEACON_TAIL). -++ * @NL80211_ATTR_CSA_C_OFF_PRESP: An array of offsets (u16) to the channel -++ * switch counters in the probe response (%NL80211_ATTR_PROBE_RESP). -+ * -+ * @NL80211_ATTR_RXMGMT_FLAGS: flags for nl80211_send_mgmt(), u32. -+ * As specified in the &enum nl80211_rxmgmt_flags. -+@@ -1576,6 +1579,11 @@ enum nl80211_commands { -+ * advertise values that cannot always be met. In such cases, an attempt -+ * to add a new station entry with @NL80211_CMD_NEW_STATION may fail. -+ * -++ * @NL80211_ATTR_CSA_C_OFFSETS_TX: An array of csa counter offsets (u16) which -++ * should be updated when the frame is transmitted. -++ * @NL80211_ATTR_MAX_CSA_COUNTERS: U8 attribute used to advertise the maximum -++ * supported number of csa counters. -++ * -+ * @NL80211_ATTR_TDLS_PEER_CAPABILITY: flags for TDLS peer capabilities, u32. -+ * As specified in the &enum nl80211_tdls_peer_capability. -+ * -+@@ -1920,6 +1928,9 @@ enum nl80211_attrs { - +- - if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0, -- NL80211_CMD_NEW_SCAN_RESULTS) < 0) { -+ aborted ? NL80211_CMD_SCAN_ABORTED : @@ -5786,59 +4511,17 @@ index a1af6c2..dc1e265 100644 -- return; -+ return NULL; - } -+ NL80211_ATTR_IFACE_SOCKET_OWNER, - +- -- genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, -- NL80211_MCGRP_SCAN, GFP_KERNEL); -+ return msg; -++ NL80211_ATTR_CSA_C_OFFSETS_TX, -++ NL80211_ATTR_MAX_CSA_COUNTERS, -++ -+ /* add attributes here, update the policy in nl80211.c */ -+ -+ __NL80211_ATTR_AFTER_LAST, -+@@ -3688,6 +3699,8 @@ enum nl80211_iface_limit_attrs { -+ * different channels may be used within this group. -+ * @NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS: u32 attribute containing the bitmap -+ * of supported channel widths for radar detection. -++ * @NL80211_IFACE_COMB_RADAR_DETECT_REGIONS: u32 attribute containing the bitmap -++ * of supported regulatory regions for radar detection. -+ * @NUM_NL80211_IFACE_COMB: number of attributes -+ * @MAX_NL80211_IFACE_COMB: highest attribute number -+ * -+@@ -3721,6 +3734,7 @@ enum nl80211_if_combination_attrs { -+ NL80211_IFACE_COMB_STA_AP_BI_MATCH, -+ NL80211_IFACE_COMB_NUM_CHANNELS, -+ NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS, -++ NL80211_IFACE_COMB_RADAR_DETECT_REGIONS, -+ -+ /* keep last */ -+ NUM_NL80211_IFACE_COMB, -+--- a/net/mac80211/Makefile -++++ b/net/mac80211/Makefile -+@@ -25,7 +25,8 @@ mac80211-y := \ -+ wme.o \ -+ event.o \ -+ chan.o \ -+- trace.o mlme.o -++ trace.o mlme.o \ -++ tdls.o -+ -+ mac80211-$(CPTCFG_MAC80211_LEDS) += led.o -+ mac80211-$(CPTCFG_MAC80211_DEBUGFS) += \ -+--- a/net/mac80211/cfg.c -++++ b/net/mac80211/cfg.c -+@@ -777,7 +777,7 @@ static void ieee80211_get_et_strings(str - } - +- } +- --void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, -- struct wireless_dev *wdev) -+void nl80211_send_scan_result(struct cfg80211_registered_device *rdev, -+ struct sk_buff *msg) -+ static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev, -+- int idx, u8 *mac, struct station_info *sinfo) -++ int idx, u8 *mac, struct station_info *sinfo) - { +- { -- struct sk_buff *msg; -- -- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); @@ -5853,14 +4536,11 @@ index a1af6c2..dc1e265 100644 -- - genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, - NL80211_MCGRP_SCAN, GFP_KERNEL); -+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -+ struct ieee80211_local *local = sdata->local; -+@@ -807,7 +807,7 @@ static int ieee80211_dump_survey(struct - } +- } -@@ -11158,7 +11211,8 @@ void cfg80211_ch_switch_notify(struct ne - wdev->iftype != NL80211_IFTYPE_MESH_POINT)) - return; - +- -- wdev->channel = chandef->chan; -+ wdev->chandef = *chandef; -+ wdev->preset_chandef = *chandef; @@ -5868,63 +4548,38 @@ index a1af6c2..dc1e265 100644 - } - EXPORT_SYMBOL(cfg80211_ch_switch_notify); -@@ -11673,6 +11727,35 @@ void cfg80211_crit_proto_stopped(struct -+ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev, -+- u8 *mac, struct station_info *sinfo) -++ const u8 *mac, struct station_info *sinfo) -+ { -+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -+ struct ieee80211_local *local = sdata->local; -+@@ -1084,6 +1084,31 @@ static int ieee80211_change_beacon(struc -+ return 0; - } +- } - EXPORT_SYMBOL(cfg80211_crit_proto_stopped); - +- -+void nl80211_send_ap_stopped(struct wireless_dev *wdev) -++bool ieee80211_csa_needs_block_tx(struct ieee80211_local *local) - +{ +-+{ -+ struct wiphy *wiphy = wdev->wiphy; -+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); -+ struct sk_buff *msg; -+ void *hdr; -++ struct ieee80211_sub_if_data *sdata; - + +-+ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+ return; -++ lockdep_assert_held(&local->mtx); -++ -++ rcu_read_lock(); -++ list_for_each_entry_rcu(sdata, &local->interfaces, list) { -++ if (!ieee80211_sdata_running(sdata)) -++ continue; - + +-+ -+ hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_STOP_AP); -+ if (!hdr) -+ goto out; -++ if (!sdata->vif.csa_active) -++ continue; - + +-+ -+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || -+ nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex) || -+ nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev))) -+ goto out; -++ if (!sdata->csa_block_tx) -++ continue; - + +-+ -+ genlmsg_end(msg, hdr); -++ rcu_read_unlock(); -++ return true; -++ } -++ rcu_read_unlock(); - + +-+ -+ genlmsg_multicast_netns(&nl80211_fam, wiphy_net(wiphy), msg, 0, -+ NL80211_MCGRP_MLME, GFP_KERNEL); -+ return; -+ out: -+ nlmsg_free(msg); -++ return false; - +} - + +-+} +-+ - /* initialisation/exit functions */ - - int nl80211_init(void) @@ -5963,8 +4618,7 @@ index a1af6c2..dc1e265 100644 --void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev) -+void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, -+ bool send_message) -+ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) - { +- { - struct cfg80211_scan_request *request; - struct wireless_dev *wdev; -+ struct sk_buff *msg; @@ -5973,34 +4627,18 @@ index a1af6c2..dc1e265 100644 - #endif - - ASSERT_RTNL(); -+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -+@@ -1101,7 +1126,14 @@ static int ieee80211_stop_ap(struct wiph -+ old_probe_resp = sdata_dereference(sdata->u.ap.probe_resp, sdata); - +- -- request = rdev->scan_req; -+ if (rdev->scan_msg) { -+ nl80211_send_scan_result(rdev, rdev->scan_msg); -+ rdev->scan_msg = NULL; -+ return; -+ } -+ /* abort any running channel switch */ -++ mutex_lock(&local->mtx); -+ sdata->vif.csa_active = false; -++ if (!ieee80211_csa_needs_block_tx(local)) -++ ieee80211_wake_queues_by_reason(&local->hw, -++ IEEE80211_MAX_QUEUE_MAP, -++ IEEE80211_QUEUE_STOP_REASON_CSA); -++ mutex_unlock(&local->mtx); -++ -+ kfree(sdata->u.ap.next_beacon); -+ sdata->u.ap.next_beacon = NULL; - +- -+ request = rdev->scan_req; - if (!request) - return; -+@@ -1425,7 +1457,8 @@ static int sta_apply_parameters(struct i -+ } - +- -@@ -186,18 +193,16 @@ void ___cfg80211_scan_done(struct cfg802 - if (wdev->netdev) - cfg80211_sme_scan_done(wdev->netdev); @@ -6021,31 +4659,15 @@ index a1af6c2..dc1e265 100644 -+ spin_lock_bh(&rdev->bss_lock); -+ __cfg80211_bss_expire(rdev, request->scan_start); -+ spin_unlock_bh(&rdev->bss_lock); -+ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, -+- u8 *mac, struct station_parameters *params) -++ const u8 *mac, -++ struct station_parameters *params) -+ { -+ struct ieee80211_local *local = wiphy_priv(wiphy); -+ struct sta_info *sta; -+@@ -1459,6 +1492,8 @@ static int ieee80211_add_station(struct -+ if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))) { -+ sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); -+ sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC); -++ } else { -++ sta->sta.tdls = true; - } - +- } +- -+ msg = nl80211_build_scan_msg(rdev, wdev, request->aborted); -+ - #ifdef CPTCFG_CFG80211_WEXT - if (wdev->netdev && !request->aborted) { - memset(&wrqu, 0, sizeof(wrqu)); -@@ -211,6 +216,11 @@ void ___cfg80211_scan_done(struct cfg802 -+ err = sta_apply_parameters(local, sta, params); -+@@ -1492,7 +1527,7 @@ static int ieee80211_add_station(struct -+ } - +- - rdev->scan_req = NULL; - kfree(request); -+ @@ -6053,49 +4675,22 @@ index a1af6c2..dc1e265 100644 -+ rdev->scan_msg = msg; -+ else -+ nl80211_send_scan_result(rdev, msg); -+ static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev, -+- u8 *mac) -++ const u8 *mac) -+ { -+ struct ieee80211_sub_if_data *sdata; -+ -+@@ -1506,7 +1541,7 @@ static int ieee80211_del_station(struct - } - +- } +- - void __cfg80211_scan_done(struct work_struct *wk) -@@ -221,7 +231,7 @@ void __cfg80211_scan_done(struct work_st - scan_done_wk); -+ static int ieee80211_change_station(struct wiphy *wiphy, -+- struct net_device *dev, u8 *mac, -++ struct net_device *dev, const u8 *mac, -+ struct station_parameters *params) -+ { -+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -+@@ -1631,7 +1666,7 @@ out_err: - +- - rtnl_lock(); -- ___cfg80211_scan_done(rdev); -+ ___cfg80211_scan_done(rdev, true); - rtnl_unlock(); -+ #ifdef CPTCFG_MAC80211_MESH -+ static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev, -+- u8 *dst, u8 *next_hop) -++ const u8 *dst, const u8 *next_hop) -+ { -+ struct ieee80211_sub_if_data *sdata; -+ struct mesh_path *mpath; -+@@ -1659,7 +1694,7 @@ static int ieee80211_add_mpath(struct wi - } - +- } +- -@@ -1079,7 +1089,7 @@ int cfg80211_wext_siwscan(struct net_dev - if (IS_ERR(rdev)) - return PTR_ERR(rdev); -+ static int ieee80211_del_mpath(struct wiphy *wiphy, struct net_device *dev, -+- u8 *dst) -++ const u8 *dst) -+ { -+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - +- -- if (rdev->scan_req) { -+ if (rdev->scan_req || rdev->scan_msg) { - err = -EBUSY; @@ -6104,185 +4699,86 @@ index a1af6c2..dc1e265 100644 -@@ -1481,7 +1491,7 @@ int cfg80211_wext_giwscan(struct net_dev - if (IS_ERR(rdev)) - return PTR_ERR(rdev); -+@@ -1670,9 +1705,8 @@ static int ieee80211_del_mpath(struct wi -+ return 0; -+ } -+ -+-static int ieee80211_change_mpath(struct wiphy *wiphy, -+- struct net_device *dev, -+- u8 *dst, u8 *next_hop) -++static int ieee80211_change_mpath(struct wiphy *wiphy, struct net_device *dev, -++ const u8 *dst, const u8 *next_hop) -+ { -+ struct ieee80211_sub_if_data *sdata; -+ struct mesh_path *mpath; -+@@ -1764,8 +1798,8 @@ static int ieee80211_get_mpath(struct wi -+ } - +- -- if (rdev->scan_req) -+ if (rdev->scan_req || rdev->scan_msg) - return -EAGAIN; -+ static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev, -+- int idx, u8 *dst, u8 *next_hop, -+- struct mpath_info *pinfo) -++ int idx, u8 *dst, u8 *next_hop, -++ struct mpath_info *pinfo) -+ { -+ struct ieee80211_sub_if_data *sdata; -+ struct mesh_path *mpath; -+@@ -3019,26 +3053,11 @@ void ieee80211_csa_finish(struct ieee802 -+ } -+ EXPORT_SYMBOL(ieee80211_csa_finish); - +- - res = ieee80211_scan_results(rdev, info, extra, data->length); ---- a/net/wireless/sme.c -+++ b/net/wireless/sme.c -@@ -67,7 +67,7 @@ static int cfg80211_conn_scan(struct wir - ASSERT_RDEV_LOCK(rdev); - ASSERT_WDEV_LOCK(wdev); -+-static void ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata) -++static int ieee80211_set_after_csa_beacon(struct ieee80211_sub_if_data *sdata, -++ u32 *changed) -+ { -+- struct ieee80211_local *local = sdata->local; -+- int err, changed = 0; -+- -+- sdata_assert_lock(sdata); -+- -+- mutex_lock(&local->mtx); -+- sdata->radar_required = sdata->csa_radar_required; -+- err = ieee80211_vif_change_channel(sdata, &changed); -+- mutex_unlock(&local->mtx); -+- if (WARN_ON(err < 0)) -+- return; -+- -+- if (!local->use_chanctx) { -+- local->_oper_chandef = sdata->csa_chandef; -+- ieee80211_hw_config(local, 0); -+- } -++ int err; - +- -- if (rdev->scan_req) -+ if (rdev->scan_req || rdev->scan_msg) - return -EBUSY; -+- sdata->vif.csa_active = false; -+ switch (sdata->vif.type) { -+ case NL80211_IFTYPE_AP: -+ err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon); -+@@ -3046,35 +3065,75 @@ static void ieee80211_csa_finalize(struc -+ sdata->u.ap.next_beacon = NULL; - +- - if (wdev->conn->params.channel) ---- a/net/mac80211/mlme.c -+++ b/net/mac80211/mlme.c -@@ -1001,7 +1001,6 @@ ieee80211_sta_process_chanswitch(struct -+ if (err < 0) -+- return; -+- changed |= err; -++ return err; -++ *changed |= err; -+ break; -+ case NL80211_IFTYPE_ADHOC: -+ err = ieee80211_ibss_finish_csa(sdata); -+ if (err < 0) -+- return; -+- changed |= err; -++ return err; -++ *changed |= err; -+ break; -+ #ifdef CPTCFG_MAC80211_MESH -+ case NL80211_IFTYPE_MESH_POINT: -+ err = ieee80211_mesh_finish_csa(sdata); -+ if (err < 0) -+- return; -+- changed |= err; -++ return err; -++ *changed |= err; -+ break; -+ #endif -+ default: -+ WARN_ON(1); -+- return; -++ return -EINVAL; - } - +- } +- - ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED; -- sdata->vif.csa_active = true; -++ -++ return 0; -++} -++ -++static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata) -++{ -++ struct ieee80211_local *local = sdata->local; -++ u32 changed = 0; -++ int err; -++ -++ sdata_assert_lock(sdata); -++ lockdep_assert_held(&local->mtx); -++ -++ sdata->radar_required = sdata->csa_radar_required; -++ err = ieee80211_vif_change_channel(sdata, &changed); -++ if (err < 0) -++ return err; -++ -++ if (!local->use_chanctx) { -++ local->_oper_chandef = sdata->csa_chandef; -++ ieee80211_hw_config(local, 0); -++ } -++ -++ sdata->vif.csa_active = false; -++ -++ err = ieee80211_set_after_csa_beacon(sdata, &changed); -++ if (err) -++ return err; -++ -+ ieee80211_bss_info_change_notify(sdata, changed); -++ cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef); - +- - mutex_lock(&local->chanctx_mtx); - if (local->use_chanctx) { -@@ -1039,6 +1038,7 @@ ieee80211_sta_process_chanswitch(struct - mutex_unlock(&local->chanctx_mtx); -+- ieee80211_wake_queues_by_reason(&sdata->local->hw, -++ if (!ieee80211_csa_needs_block_tx(local)) -++ ieee80211_wake_queues_by_reason(&local->hw, -+ IEEE80211_MAX_QUEUE_MAP, -+ IEEE80211_QUEUE_STOP_REASON_CSA); - +- - sdata->csa_chandef = csa_ie.chandef; -+ sdata->vif.csa_active = true; -+- cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef); -++ return 0; -++} -++ -++static void ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata) -++{ -++ if (__ieee80211_csa_finalize(sdata)) { -++ sdata_info(sdata, "failed to finalize CSA, disconnecting\n"); -++ cfg80211_stop_iface(sdata->local->hw.wiphy, &sdata->wdev, -++ GFP_KERNEL); -++ } -+ } - +- - if (csa_ie.mode) - ieee80211_stop_queues_by_reason(&local->hw, ---- a/net/mac80211/chan.c -+++ b/net/mac80211/chan.c -@@ -196,6 +196,8 @@ static bool ieee80211_is_radar_required( -- { ++ Reduce the number of false positives by checking the A-MPDU status flag ++ and treating a failed A-MPDU as a single packet. ++ ++ Signed-off-by: Felix Fietkau ++ ++commit 7b7843a36fbcc568834404c7430ff895d8502131 ++Author: Felix Fietkau ++Date: Fri May 23 19:26:32 2014 +0200 ++ ++ mac80211: fix a memory leak on sta rate selection table ++ ++ Cc: stable@vger.kernel.org ++ Reported-by: Christophe Prévotaux ++ Signed-off-by: Felix Fietkau ++ ++commit 96892d6aa0a153423070addf3070bc79578b3897 ++Author: Felix Fietkau ++Date: Mon May 19 21:20:49 2014 +0200 ++ ++ ath9k: avoid passing buffers to the hardware during flush ++ ++ The commit "ath9k: fix possible hang on flush" changed the receive code ++ to always link rx descriptors of processed frames, even when flushing. ++ In some cases, this leads to flushed rx buffers being passed to the ++ hardware while rx is already stopped. ++ ++ Signed-off-by: Felix Fietkau ++ ++--- a/drivers/net/wireless/ath/ath9k/recv.c +++++ b/drivers/net/wireless/ath/ath9k/recv.c ++@@ -34,7 +34,8 @@ static inline bool ath9k_check_auto_slee ++ * buffer (or rx fifo). This can incorrectly acknowledge packets ++ * to a sender if last desc is self-linked. ++ */ ++-static void ath_rx_buf_link(struct ath_softc *sc, struct ath_rxbuf *bf) +++static void ath_rx_buf_link(struct ath_softc *sc, struct ath_rxbuf *bf, +++ bool flush) + { - struct ieee80211_sub_if_data *sdata; -+ void ieee80211_csa_finalize_work(struct work_struct *work) -+@@ -3082,8 +3141,11 @@ void ieee80211_csa_finalize_work(struct -+ struct ieee80211_sub_if_data *sdata = -+ container_of(work, struct ieee80211_sub_if_data, -+ csa_finalize_work); -++ struct ieee80211_local *local = sdata->local; - +- -+ lockdep_assert_held(&local->mtx); -+ sdata_lock(sdata); -++ mutex_lock(&local->mtx); - + +-+ - rcu_read_lock(); - list_for_each_entry_rcu(sdata, &local->interfaces, list) { - if (sdata->radar_required) { @@ -6302,12 +4798,7 @@ index a1af6c2..dc1e265 100644 - } -+ sdata->radar_required = radar_required; - mutex_unlock(&local->mtx); -+ /* AP might have been stopped while waiting for the lock. */ -+ if (!sdata->vif.csa_active) -+ goto unlock; -+@@ -3094,6 +3156,7 @@ void ieee80211_csa_finalize_work(struct -+ ieee80211_csa_finalize(sdata); - +- - memcpy(ifibss->bssid, bssid, ETH_ALEN); -@@ -318,7 +318,6 @@ static void __ieee80211_sta_join_ibss(st - rcu_assign_pointer(ifibss->presp, presp); @@ -6323,29 +4814,27 @@ index a1af6c2..dc1e265 100644 - netif_carrier_on(sdata->dev); -- cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL); -+ cfg80211_ibss_joined(sdata->dev, ifibss->bssid, chan, GFP_KERNEL); -+ unlock: -++ mutex_unlock(&local->mtx); -+ sdata_unlock(sdata); - } +- } ++ struct ath_hw *ah = sc->sc_ah; ++ struct ath_common *common = ath9k_hw_common(ah); ++@@ -59,18 +60,19 @@ static void ath_rx_buf_link(struct ath_s ++ common->rx_bufsize, ++ 0); - static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, -@@ -802,6 +801,8 @@ ieee80211_ibss_process_chanswitch(struct - int err; - u32 sta_flags; -+@@ -3129,9 +3192,25 @@ static int ieee80211_set_csa_beacon(stru -+ if (params->count <= 1) -+ break; ++- if (sc->rx.rxlink == NULL) ++- ath9k_hw_putrxbuf(ah, bf->bf_daddr); ++- else +++ if (sc->rx.rxlink) ++ *sc->rx.rxlink = bf->bf_daddr; +++ else if (!flush) +++ ath9k_hw_putrxbuf(ah, bf->bf_daddr); -+ sdata_assert_lock(sdata); -+- sdata->csa_counter_offset_beacon = -+- params->counter_offset_beacon; -+- sdata->csa_counter_offset_presp = params->counter_offset_presp; -++ if ((params->n_counter_offsets_beacon > -++ IEEE80211_MAX_CSA_COUNTERS_NUM) || -++ (params->n_counter_offsets_presp > -++ IEEE80211_MAX_CSA_COUNTERS_NUM)) -++ return -EINVAL; - + +-+ - sta_flags = IEEE80211_STA_DISABLE_VHT; - switch (ifibss->chandef.width) { - case NL80211_CHAN_WIDTH_5: @@ -6353,28 +4842,13 @@ index a1af6c2..dc1e265 100644 - memcpy(((struct ieee80211_mgmt *) skb->data)->da, mgmt->sa, ETH_ALEN); - ibss_dbg(sdata, "Sending ProbeResp to %pM\n", mgmt->sa); - IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; -++ /* make sure we don't have garbage in other counters */ -++ memset(sdata->csa_counter_offset_beacon, 0, -++ sizeof(sdata->csa_counter_offset_beacon)); -++ memset(sdata->csa_counter_offset_presp, 0, -++ sizeof(sdata->csa_counter_offset_presp)); - + +-+ -+ /* avoid excessive retries for probe request to wildcard SSIDs */ -+ if (pos[1] == 0) -+ IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_NO_ACK; -++ memcpy(sdata->csa_counter_offset_beacon, -++ params->counter_offsets_beacon, -++ params->n_counter_offsets_beacon * sizeof(u16)); -++ memcpy(sdata->csa_counter_offset_presp, -++ params->counter_offsets_presp, -++ params->n_counter_offsets_presp * sizeof(u16)); - + +-+ - ieee80211_tx_skb(sdata, skb); -+ err = ieee80211_assign_beacon(sdata, ¶ms->beacon_csa); -+ if (err < 0) { -+ kfree(sdata->u.ap.next_beacon); -+@@ -3220,8 +3299,9 @@ static int ieee80211_set_csa_beacon(stru -+ return 0; ++ sc->rx.rxlink = &ds->ds_link; } ---- a/net/mac80211/mesh.c @@ -6382,17 +4856,7 @@ index a1af6c2..dc1e265 100644 -@@ -872,6 +872,8 @@ ieee80211_mesh_process_chnswitch(struct - if (!ifmsh->mesh_id) - return false; -+-int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, -+- struct cfg80211_csa_settings *params) -++static int -++__ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, -++ struct cfg80211_csa_settings *params) -+ { -+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -+ struct ieee80211_local *local = sdata->local; -+@@ -3230,6 +3310,7 @@ int ieee80211_channel_switch(struct wiph -+ int err, num_chanctx, changed = 0; - +- -+ sdata_assert_lock(sdata); -+ - sta_flags = IEEE80211_STA_DISABLE_VHT; @@ -6425,17 +4889,11 @@ index a1af6c2..dc1e265 100644 -@@ -1766,7 +1766,8 @@ static void lbs_join_post(struct lbs_pri - memcpy(priv->wdev->ssid, params->ssid, params->ssid_len); - priv->wdev->ssid_len = params->ssid_len; -+ sdata_assert_lock(sdata); -++ lockdep_assert_held(&local->mtx); - +- -- cfg80211_ibss_joined(priv->dev, bssid, GFP_KERNEL); -+ cfg80211_ibss_joined(priv->dev, bssid, params->chandef.chan, -+ GFP_KERNEL); -+ if (!list_empty(&local->roc_list) || local->scanning) -+ return -EBUSY; -+@@ -3272,15 +3353,16 @@ int ieee80211_channel_switch(struct wiph -+ return err; - +- - /* TODO: consider doing this at MACREG_INT_CODE_LINK_SENSED time */ - priv->connect_status = LBS_CONNECTED; ---- a/drivers/net/wireless/mwifiex/cfg80211.c @@ -6460,510 +4918,70 @@ index a1af6c2..dc1e265 100644 -+ cfg80211_ibss_joined(usbdev->net, bssid, -+ get_current_channel(usbdev, NULL), -+ GFP_KERNEL); -+ sdata->csa_radar_required = params->radar_required; -+- -+- if (params->block_tx) -+- ieee80211_stop_queues_by_reason(&local->hw, -+- IEEE80211_MAX_QUEUE_MAP, -+- IEEE80211_QUEUE_STOP_REASON_CSA); -+- -+ sdata->csa_chandef = params->chandef; -++ sdata->csa_block_tx = params->block_tx; -++ sdata->csa_current_counter = params->count; -+ sdata->vif.csa_active = true; -+ -++ if (sdata->csa_block_tx) -++ ieee80211_stop_queues_by_reason(&local->hw, -++ IEEE80211_MAX_QUEUE_MAP, -++ IEEE80211_QUEUE_STOP_REASON_CSA); -++ -+ if (changed) { -+ ieee80211_bss_info_change_notify(sdata, changed); -+ drv_channel_switch_beacon(sdata, ¶ms->chandef); -+@@ -3292,6 +3374,20 @@ int ieee80211_channel_switch(struct wiph -+ return 0; -+ } - +- - kfree(info); -++int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, -++ struct cfg80211_csa_settings *params) -++{ -++ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -++ struct ieee80211_local *local = sdata->local; -++ int err; -++ -++ mutex_lock(&local->mtx); -++ err = __ieee80211_channel_switch(wiphy, dev, params); -++ mutex_unlock(&local->mtx); -++ -++ return err; -++} -++ -+ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, -+ struct cfg80211_mgmt_tx_params *params, -+ u64 *cookie) -+@@ -3304,6 +3400,7 @@ static int ieee80211_mgmt_tx(struct wiph -+ bool need_offchan = false; -+ u32 flags; -+ int ret; -++ u8 *data; - +- ---- a/net/wireless/ibss.c -+++ b/net/wireless/ibss.c -@@ -14,7 +14,8 @@ - #include "rdev-ops.h" -+ if (params->dont_wait_for_ack) -+ flags = IEEE80211_TX_CTL_NO_ACK; -+@@ -3397,7 +3494,20 @@ static int ieee80211_mgmt_tx(struct wiph -+ } -+ skb_reserve(skb, local->hw.extra_tx_headroom); - -+- memcpy(skb_put(skb, params->len), params->buf, params->len); -++ data = skb_put(skb, params->len); -++ memcpy(data, params->buf, params->len); -++ -++ /* Update CSA counters */ -++ if (sdata->vif.csa_active && -++ (sdata->vif.type == NL80211_IFTYPE_AP || -++ sdata->vif.type == NL80211_IFTYPE_ADHOC) && -++ params->n_csa_offsets) { -++ int i; -++ u8 c = sdata->csa_current_counter; -++ -++ for (i = 0; i < params->n_csa_offsets; i++) -++ data[params->csa_offsets[i]] = c; -++ } - +- +- --void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid) -+void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, -+ struct ieee80211_channel *channel) -- { ++-static void ath_rx_buf_relink(struct ath_softc *sc, struct ath_rxbuf *bf) +++static void ath_rx_buf_relink(struct ath_softc *sc, struct ath_rxbuf *bf, +++ bool flush) + { - struct wireless_dev *wdev = dev->ieee80211_ptr; - struct cfg80211_bss *bss; -@@ -28,8 +29,7 @@ void __cfg80211_ibss_joined(struct net_d - if (!wdev->ssid_len) - return; -+ IEEE80211_SKB_CB(skb)->flags = flags; ++ if (sc->rx.buf_hold) ++- ath_rx_buf_link(sc, sc->rx.buf_hold); +++ ath_rx_buf_link(sc, sc->rx.buf_hold, flush); -- bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, -- wdev->ssid, wdev->ssid_len, -+ bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, NULL, 0, - WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS); -+@@ -3506,320 +3616,6 @@ static int ieee80211_set_rekey_data(stru -+ return 0; -+ } - +- - if (WARN_ON(!bss)) -@@ -54,21 +54,26 @@ void __cfg80211_ibss_joined(struct net_d - #endif -+-static void ieee80211_tdls_add_ext_capab(struct sk_buff *skb) -+-{ -+- u8 *pos = (void *)skb_put(skb, 7); -+- -+- *pos++ = WLAN_EID_EXT_CAPABILITY; -+- *pos++ = 5; /* len */ -+- *pos++ = 0x0; -+- *pos++ = 0x0; -+- *pos++ = 0x0; -+- *pos++ = 0x0; -+- *pos++ = WLAN_EXT_CAPA5_TDLS_ENABLED; -+-} -+- -+-static u16 ieee80211_get_tdls_sta_capab(struct ieee80211_sub_if_data *sdata) -+-{ -+- struct ieee80211_local *local = sdata->local; -+- u16 capab; -+- -+- capab = 0; -+- if (ieee80211_get_sdata_band(sdata) != IEEE80211_BAND_2GHZ) -+- return capab; -+- -+- if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE)) -+- capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME; -+- if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE)) -+- capab |= WLAN_CAPABILITY_SHORT_PREAMBLE; -+- -+- return capab; -+-} -+- -+-static void ieee80211_tdls_add_link_ie(struct sk_buff *skb, u8 *src_addr, -+- u8 *peer, u8 *bssid) -+-{ -+- struct ieee80211_tdls_lnkie *lnkid; -+- -+- lnkid = (void *)skb_put(skb, sizeof(struct ieee80211_tdls_lnkie)); -+- -+- lnkid->ie_type = WLAN_EID_LINK_ID; -+- lnkid->ie_len = sizeof(struct ieee80211_tdls_lnkie) - 2; -+- -+- memcpy(lnkid->bssid, bssid, ETH_ALEN); -+- memcpy(lnkid->init_sta, src_addr, ETH_ALEN); -+- memcpy(lnkid->resp_sta, peer, ETH_ALEN); -+-} -+- -+-static int -+-ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev, -+- u8 *peer, u8 action_code, u8 dialog_token, -+- u16 status_code, struct sk_buff *skb) -+-{ -+- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -+- enum ieee80211_band band = ieee80211_get_sdata_band(sdata); -+- struct ieee80211_tdls_data *tf; -+- -+- tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u)); -+- -+- memcpy(tf->da, peer, ETH_ALEN); -+- memcpy(tf->sa, sdata->vif.addr, ETH_ALEN); -+- tf->ether_type = cpu_to_be16(ETH_P_TDLS); -+- tf->payload_type = WLAN_TDLS_SNAP_RFTYPE; -+- -+- switch (action_code) { -+- case WLAN_TDLS_SETUP_REQUEST: -+- tf->category = WLAN_CATEGORY_TDLS; -+- tf->action_code = WLAN_TDLS_SETUP_REQUEST; -+- -+- skb_put(skb, sizeof(tf->u.setup_req)); -+- tf->u.setup_req.dialog_token = dialog_token; -+- tf->u.setup_req.capability = -+- cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); -+- -+- ieee80211_add_srates_ie(sdata, skb, false, band); -+- ieee80211_add_ext_srates_ie(sdata, skb, false, band); -+- ieee80211_tdls_add_ext_capab(skb); -+- break; -+- case WLAN_TDLS_SETUP_RESPONSE: -+- tf->category = WLAN_CATEGORY_TDLS; -+- tf->action_code = WLAN_TDLS_SETUP_RESPONSE; -+- -+- skb_put(skb, sizeof(tf->u.setup_resp)); -+- tf->u.setup_resp.status_code = cpu_to_le16(status_code); -+- tf->u.setup_resp.dialog_token = dialog_token; -+- tf->u.setup_resp.capability = -+- cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); -+- -+- ieee80211_add_srates_ie(sdata, skb, false, band); -+- ieee80211_add_ext_srates_ie(sdata, skb, false, band); -+- ieee80211_tdls_add_ext_capab(skb); -+- break; -+- case WLAN_TDLS_SETUP_CONFIRM: -+- tf->category = WLAN_CATEGORY_TDLS; -+- tf->action_code = WLAN_TDLS_SETUP_CONFIRM; -+- -+- skb_put(skb, sizeof(tf->u.setup_cfm)); -+- tf->u.setup_cfm.status_code = cpu_to_le16(status_code); -+- tf->u.setup_cfm.dialog_token = dialog_token; -+- break; -+- case WLAN_TDLS_TEARDOWN: -+- tf->category = WLAN_CATEGORY_TDLS; -+- tf->action_code = WLAN_TDLS_TEARDOWN; -+- -+- skb_put(skb, sizeof(tf->u.teardown)); -+- tf->u.teardown.reason_code = cpu_to_le16(status_code); -+- break; -+- case WLAN_TDLS_DISCOVERY_REQUEST: -+- tf->category = WLAN_CATEGORY_TDLS; -+- tf->action_code = WLAN_TDLS_DISCOVERY_REQUEST; -+- -+- skb_put(skb, sizeof(tf->u.discover_req)); -+- tf->u.discover_req.dialog_token = dialog_token; -+- break; -+- default: -+- return -EINVAL; -+- } -+- -+- return 0; -+-} -+- -+-static int -+-ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev, -+- u8 *peer, u8 action_code, u8 dialog_token, -+- u16 status_code, struct sk_buff *skb) -+-{ -+- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -+- enum ieee80211_band band = ieee80211_get_sdata_band(sdata); -+- struct ieee80211_mgmt *mgmt; -+- -+- mgmt = (void *)skb_put(skb, 24); -+- memset(mgmt, 0, 24); -+- memcpy(mgmt->da, peer, ETH_ALEN); -+- memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); -+- memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN); -+- -+- mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | -+- IEEE80211_STYPE_ACTION); -+- -+- switch (action_code) { -+- case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: -+- skb_put(skb, 1 + sizeof(mgmt->u.action.u.tdls_discover_resp)); -+- mgmt->u.action.category = WLAN_CATEGORY_PUBLIC; -+- mgmt->u.action.u.tdls_discover_resp.action_code = -+- WLAN_PUB_ACTION_TDLS_DISCOVER_RES; -+- mgmt->u.action.u.tdls_discover_resp.dialog_token = -+- dialog_token; -+- mgmt->u.action.u.tdls_discover_resp.capability = -+- cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); -+- -+- ieee80211_add_srates_ie(sdata, skb, false, band); -+- ieee80211_add_ext_srates_ie(sdata, skb, false, band); -+- ieee80211_tdls_add_ext_capab(skb); -+- break; -+- default: -+- return -EINVAL; -+- } -+- -+- return 0; -+-} -+- -+-static int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, -+- u8 *peer, u8 action_code, u8 dialog_token, -+- u16 status_code, u32 peer_capability, -+- const u8 *extra_ies, size_t extra_ies_len) -+-{ -+- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -+- struct ieee80211_local *local = sdata->local; -+- struct sk_buff *skb = NULL; -+- bool send_direct; -+- int ret; -+- -+- if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)) -+- return -ENOTSUPP; -+- -+- /* make sure we are in managed mode, and associated */ -+- if (sdata->vif.type != NL80211_IFTYPE_STATION || -+- !sdata->u.mgd.associated) -+- return -EINVAL; -+- -+- tdls_dbg(sdata, "TDLS mgmt action %d peer %pM\n", -+- action_code, peer); -+- -+- skb = dev_alloc_skb(local->hw.extra_tx_headroom + -+- max(sizeof(struct ieee80211_mgmt), -+- sizeof(struct ieee80211_tdls_data)) + -+- 50 + /* supported rates */ -+- 7 + /* ext capab */ -+- extra_ies_len + -+- sizeof(struct ieee80211_tdls_lnkie)); -+- if (!skb) -+- return -ENOMEM; -+- -+- skb_reserve(skb, local->hw.extra_tx_headroom); -+- -+- switch (action_code) { -+- case WLAN_TDLS_SETUP_REQUEST: -+- case WLAN_TDLS_SETUP_RESPONSE: -+- case WLAN_TDLS_SETUP_CONFIRM: -+- case WLAN_TDLS_TEARDOWN: -+- case WLAN_TDLS_DISCOVERY_REQUEST: -+- ret = ieee80211_prep_tdls_encap_data(wiphy, dev, peer, -+- action_code, dialog_token, -+- status_code, skb); -+- send_direct = false; -+- break; -+- case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: -+- ret = ieee80211_prep_tdls_direct(wiphy, dev, peer, action_code, -+- dialog_token, status_code, -+- skb); -+- send_direct = true; -+- break; -+- default: -+- ret = -ENOTSUPP; -+- break; -+- } -+- -+- if (ret < 0) -+- goto fail; -+- -+- if (extra_ies_len) -+- memcpy(skb_put(skb, extra_ies_len), extra_ies, extra_ies_len); -+- -+- /* the TDLS link IE is always added last */ -+- switch (action_code) { -+- case WLAN_TDLS_SETUP_REQUEST: -+- case WLAN_TDLS_SETUP_CONFIRM: -+- case WLAN_TDLS_TEARDOWN: -+- case WLAN_TDLS_DISCOVERY_REQUEST: -+- /* we are the initiator */ -+- ieee80211_tdls_add_link_ie(skb, sdata->vif.addr, peer, -+- sdata->u.mgd.bssid); -+- break; -+- case WLAN_TDLS_SETUP_RESPONSE: -+- case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: -+- /* we are the responder */ -+- ieee80211_tdls_add_link_ie(skb, peer, sdata->vif.addr, -+- sdata->u.mgd.bssid); -+- break; -+- default: -+- ret = -ENOTSUPP; -+- goto fail; -+- } -+- -+- if (send_direct) { -+- ieee80211_tx_skb(sdata, skb); -+- return 0; -+- } -+- -+- /* -+- * According to 802.11z: Setup req/resp are sent in AC_BK, otherwise -+- * we should default to AC_VI. -+- */ -+- switch (action_code) { -+- case WLAN_TDLS_SETUP_REQUEST: -+- case WLAN_TDLS_SETUP_RESPONSE: -+- skb_set_queue_mapping(skb, IEEE80211_AC_BK); -+- skb->priority = 2; -+- break; -+- default: -+- skb_set_queue_mapping(skb, IEEE80211_AC_VI); -+- skb->priority = 5; -+- break; -+- } -+- -+- /* disable bottom halves when entering the Tx path */ -+- local_bh_disable(); -+- ret = ieee80211_subif_start_xmit(skb, dev); -+- local_bh_enable(); -+- -+- return ret; -+- -+-fail: -+- dev_kfree_skb(skb); -+- return ret; -+-} -+- -+-static int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, -+- u8 *peer, enum nl80211_tdls_operation oper) -+-{ -+- struct sta_info *sta; -+- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -+- -+- if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)) -+- return -ENOTSUPP; -+- -+- if (sdata->vif.type != NL80211_IFTYPE_STATION) -+- return -EINVAL; -+- -+- tdls_dbg(sdata, "TDLS oper %d peer %pM\n", oper, peer); -+- -+- switch (oper) { -+- case NL80211_TDLS_ENABLE_LINK: -+- rcu_read_lock(); -+- sta = sta_info_get(sdata, peer); -+- if (!sta) { -+- rcu_read_unlock(); -+- return -ENOLINK; -+- } -+- -+- set_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH); -+- rcu_read_unlock(); -+- break; -+- case NL80211_TDLS_DISABLE_LINK: -+- return sta_info_destroy_addr(sdata, peer); -+- case NL80211_TDLS_TEARDOWN: -+- case NL80211_TDLS_SETUP: -+- case NL80211_TDLS_DISCOVERY_REQ: -+- /* We don't support in-driver setup/teardown/discovery */ -+- return -ENOTSUPP; -+- default: -+- return -ENOTSUPP; -+- } -+- -+- return 0; -+-} -+- -+ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, -+ const u8 *peer, u64 *cookie) -+ { -+--- a/net/mac80211/chan.c -++++ b/net/mac80211/chan.c -+@@ -855,7 +855,7 @@ static void -+ __ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata, -+ bool clear) -+ { -+- struct ieee80211_local *local = sdata->local; -++ struct ieee80211_local *local __maybe_unused = sdata->local; -+ struct ieee80211_sub_if_data *vlan; -+ struct ieee80211_chanctx_conf *conf; -+ -+@@ -871,7 +871,7 @@ __ieee80211_vif_copy_chanctx_to_vlans(st -+ * to a channel context that has already been freed. -+ */ -+ conf = rcu_dereference_protected(sdata->vif.chanctx_conf, -+- lockdep_is_held(&local->chanctx_mtx)); -++ lockdep_is_held(&local->chanctx_mtx)); -+ WARN_ON(!conf); -+ -+ if (clear) -+--- a/net/mac80211/driver-ops.h -++++ b/net/mac80211/driver-ops.h -+@@ -5,11 +5,11 @@ -+ #include "ieee80211_i.h" -+ #include "trace.h" -+ -+-static inline void check_sdata_in_driver(struct ieee80211_sub_if_data *sdata) -++static inline bool check_sdata_in_driver(struct ieee80211_sub_if_data *sdata) -+ { -+- WARN(!(sdata->flags & IEEE80211_SDATA_IN_DRIVER), -+- "%s: Failed check-sdata-in-driver check, flags: 0x%x\n", -+- sdata->dev ? sdata->dev->name : sdata->name, sdata->flags); -++ return !WARN(!(sdata->flags & IEEE80211_SDATA_IN_DRIVER), -++ "%s: Failed check-sdata-in-driver check, flags: 0x%x\n", -++ sdata->dev ? sdata->dev->name : sdata->name, sdata->flags); ++ sc->rx.buf_hold = bf; } - +- --void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp) -+void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, -+ struct ieee80211_channel *channel, gfp_t gfp) -+ static inline struct ieee80211_sub_if_data * -+@@ -168,7 +168,8 @@ static inline int drv_change_interface(s -+ -+ might_sleep(); -+ -+- check_sdata_in_driver(sdata); -++ if (!check_sdata_in_driver(sdata)) -++ return -EIO; -+ -+ trace_drv_change_interface(local, sdata, type, p2p); -+ ret = local->ops->change_interface(&local->hw, &sdata->vif, type, p2p); -+@@ -181,7 +182,8 @@ static inline void drv_remove_interface( - { +- { - struct wireless_dev *wdev = dev->ieee80211_ptr; - struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); - struct cfg80211_event *ev; - unsigned long flags; -+ might_sleep(); - +- -- trace_cfg80211_ibss_joined(dev, bssid); -+ trace_cfg80211_ibss_joined(dev, bssid, channel); -+ -+ if (WARN_ON(!channel)) -+- check_sdata_in_driver(sdata); -++ if (!check_sdata_in_driver(sdata)) - + return; - +-+ return; +- - ev = kzalloc(sizeof(*ev), gfp); - if (!ev) -+ trace_drv_remove_interface(local, sdata); -+ local->ops->remove_interface(&local->hw, &sdata->vif); -+@@ -219,7 +221,8 @@ static inline void drv_bss_info_changed( -+ sdata->vif.type == NL80211_IFTYPE_MONITOR)) - return; - +- return; +- - ev->type = EVENT_IBSS_JOINED; -- memcpy(ev->cr.bssid, bssid, ETH_ALEN); -+ memcpy(ev->ij.bssid, bssid, ETH_ALEN); -+ ev->ij.channel = channel; -+- check_sdata_in_driver(sdata); -++ if (!check_sdata_in_driver(sdata)) -++ return; - +- - spin_lock_irqsave(&wdev->event_lock, flags); - list_add_tail(&ev->list, &wdev->event_list); -@@ -117,6 +122,7 @@ int __cfg80211_join_ibss(struct cfg80211 -+ trace_drv_bss_info_changed(local, sdata, info, changed); -+ if (local->ops->bss_info_changed) -+@@ -278,7 +281,8 @@ static inline int drv_set_key(struct iee -+ might_sleep(); - +- - wdev->ibss_fixed = params->channel_fixed; - wdev->ibss_dfs_possible = params->userspace_handles_dfs; -+ wdev->chandef = params->chandef; @@ -6971,11 +4989,7 @@ index a1af6c2..dc1e265 100644 - wdev->wext.ibss.chandef = params->chandef; - #endif -@@ -200,6 +206,7 @@ static void __cfg80211_clear_ibss(struct -+ sdata = get_bss_sdata(sdata); -+- check_sdata_in_driver(sdata); -++ if (!check_sdata_in_driver(sdata)) -++ return -EIO; - +- - wdev->current_bss = NULL; - wdev->ssid_len = 0; -+ memset(&wdev->chandef, 0, sizeof(wdev->chandef)); @@ -6987,11 +5001,7 @@ index a1af6c2..dc1e265 100644 -@@ -2278,11 +2278,6 @@ DECLARE_EVENT_CLASS(cfg80211_rx_evt, - TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT, NETDEV_PR_ARG, MAC_PR_ARG(addr)) - ); -+ trace_drv_set_key(local, cmd, sdata, sta, key); -+ ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key); -+@@ -298,7 +302,8 @@ static inline void drv_update_tkip_key(s -+ ista = &sta->sta; - +- --DEFINE_EVENT(cfg80211_rx_evt, cfg80211_ibss_joined, -- TP_PROTO(struct net_device *netdev, const u8 *addr), -- TP_ARGS(netdev, addr) @@ -7003,11 +5013,7 @@ index a1af6c2..dc1e265 100644 -@@ -2293,6 +2288,24 @@ DEFINE_EVENT(cfg80211_rx_evt, cfg80211_r - TP_ARGS(netdev, addr) - ); -+ sdata = get_bss_sdata(sdata); -+- check_sdata_in_driver(sdata); -++ if (!check_sdata_in_driver(sdata)) -++ return; - +- -+TRACE_EVENT(cfg80211_ibss_joined, -+ TP_PROTO(struct net_device *netdev, const u8 *bssid, -+ struct ieee80211_channel *channel), @@ -7025,216 +5031,7 @@ index a1af6c2..dc1e265 100644 -+ TP_printk(NETDEV_PR_FMT ", bssid: " MAC_PR_FMT ", " CHAN_PR_FMT, -+ NETDEV_PR_ARG, MAC_PR_ARG(bssid), CHAN_PR_ARG) -+); -+ trace_drv_update_tkip_key(local, sdata, conf, ista, iv32); -+ if (local->ops->update_tkip_key) -+@@ -315,7 +320,8 @@ static inline int drv_hw_scan(struct iee -+ -+ might_sleep(); -+ -+- check_sdata_in_driver(sdata); -++ if (!check_sdata_in_driver(sdata)) -++ return -EIO; -+ -+ trace_drv_hw_scan(local, sdata); -+ ret = local->ops->hw_scan(&local->hw, &sdata->vif, req); -+@@ -328,7 +334,8 @@ static inline void drv_cancel_hw_scan(st -+ { -+ might_sleep(); -+ -+- check_sdata_in_driver(sdata); -++ if (!check_sdata_in_driver(sdata)) -++ return; -+ -+ trace_drv_cancel_hw_scan(local, sdata); -+ local->ops->cancel_hw_scan(&local->hw, &sdata->vif); -+@@ -345,7 +352,8 @@ drv_sched_scan_start(struct ieee80211_lo -+ -+ might_sleep(); -+ -+- check_sdata_in_driver(sdata); -++ if (!check_sdata_in_driver(sdata)) -++ return -EIO; -+ -+ trace_drv_sched_scan_start(local, sdata); -+ ret = local->ops->sched_scan_start(&local->hw, &sdata->vif, -+@@ -361,7 +369,8 @@ static inline int drv_sched_scan_stop(st -+ -+ might_sleep(); -+ -+- check_sdata_in_driver(sdata); -++ if (!check_sdata_in_driver(sdata)) -++ return -EIO; -+ -+ trace_drv_sched_scan_stop(local, sdata); -+ ret = local->ops->sched_scan_stop(&local->hw, &sdata->vif); -+@@ -462,7 +471,8 @@ static inline void drv_sta_notify(struct -+ struct ieee80211_sta *sta) -+ { -+ sdata = get_bss_sdata(sdata); -+- check_sdata_in_driver(sdata); -++ if (!check_sdata_in_driver(sdata)) -++ return; -+ -+ trace_drv_sta_notify(local, sdata, cmd, sta); -+ if (local->ops->sta_notify) -+@@ -479,7 +489,8 @@ static inline int drv_sta_add(struct iee -+ might_sleep(); -+ -+ sdata = get_bss_sdata(sdata); -+- check_sdata_in_driver(sdata); -++ if (!check_sdata_in_driver(sdata)) -++ return -EIO; -+ -+ trace_drv_sta_add(local, sdata, sta); -+ if (local->ops->sta_add) -+@@ -497,7 +508,8 @@ static inline void drv_sta_remove(struct -+ might_sleep(); -+ -+ sdata = get_bss_sdata(sdata); -+- check_sdata_in_driver(sdata); -++ if (!check_sdata_in_driver(sdata)) -++ return; -+ -+ trace_drv_sta_remove(local, sdata, sta); -+ if (local->ops->sta_remove) -+@@ -515,7 +527,8 @@ static inline void drv_sta_add_debugfs(s -+ might_sleep(); -+ -+ sdata = get_bss_sdata(sdata); -+- check_sdata_in_driver(sdata); -++ if (!check_sdata_in_driver(sdata)) -++ return; -+ -+ if (local->ops->sta_add_debugfs) -+ local->ops->sta_add_debugfs(&local->hw, &sdata->vif, -+@@ -545,7 +558,8 @@ static inline void drv_sta_pre_rcu_remov -+ might_sleep(); -+ -+ sdata = get_bss_sdata(sdata); -+- check_sdata_in_driver(sdata); -++ if (!check_sdata_in_driver(sdata)) -++ return; -+ -+ trace_drv_sta_pre_rcu_remove(local, sdata, &sta->sta); -+ if (local->ops->sta_pre_rcu_remove) -+@@ -566,7 +580,8 @@ int drv_sta_state(struct ieee80211_local -+ might_sleep(); -+ -+ sdata = get_bss_sdata(sdata); -+- check_sdata_in_driver(sdata); -++ if (!check_sdata_in_driver(sdata)) -++ return -EIO; -+ -+ trace_drv_sta_state(local, sdata, &sta->sta, old_state, new_state); -+ if (local->ops->sta_state) { -+@@ -590,7 +605,8 @@ static inline void drv_sta_rc_update(str -+ struct ieee80211_sta *sta, u32 changed) -+ { -+ sdata = get_bss_sdata(sdata); -+- check_sdata_in_driver(sdata); -++ if (!check_sdata_in_driver(sdata)) -++ return; -+ -+ WARN_ON(changed & IEEE80211_RC_SUPP_RATES_CHANGED && -+ (sdata->vif.type != NL80211_IFTYPE_ADHOC && -+@@ -612,7 +628,8 @@ static inline int drv_conf_tx(struct iee -+ -+ might_sleep(); -+ -+- check_sdata_in_driver(sdata); -++ if (!check_sdata_in_driver(sdata)) -++ return -EIO; -+ -+ trace_drv_conf_tx(local, sdata, ac, params); -+ if (local->ops->conf_tx) -+@@ -629,7 +646,8 @@ static inline u64 drv_get_tsf(struct iee -+ -+ might_sleep(); -+ -+- check_sdata_in_driver(sdata); -++ if (!check_sdata_in_driver(sdata)) -++ return ret; -+ -+ trace_drv_get_tsf(local, sdata); -+ if (local->ops->get_tsf) -+@@ -644,7 +662,8 @@ static inline void drv_set_tsf(struct ie -+ { -+ might_sleep(); -+ -+- check_sdata_in_driver(sdata); -++ if (!check_sdata_in_driver(sdata)) -++ return; -+ -+ trace_drv_set_tsf(local, sdata, tsf); -+ if (local->ops->set_tsf) -+@@ -657,7 +676,8 @@ static inline void drv_reset_tsf(struct -+ { -+ might_sleep(); -+ -+- check_sdata_in_driver(sdata); -++ if (!check_sdata_in_driver(sdata)) -++ return; -+ -+ trace_drv_reset_tsf(local, sdata); -+ if (local->ops->reset_tsf) -+@@ -689,7 +709,8 @@ static inline int drv_ampdu_action(struc -+ might_sleep(); -+ -+ sdata = get_bss_sdata(sdata); -+- check_sdata_in_driver(sdata); -++ if (!check_sdata_in_driver(sdata)) -++ return -EIO; -+ -+ trace_drv_ampdu_action(local, sdata, action, sta, tid, ssn, buf_size); -+ -+@@ -733,8 +754,8 @@ static inline void drv_flush(struct ieee -+ -+ might_sleep(); -+ -+- if (sdata) -+- check_sdata_in_driver(sdata); -++ if (sdata && !check_sdata_in_driver(sdata)) -++ return; -+ -+ trace_drv_flush(local, queues, drop); -+ if (local->ops->flush) -+@@ -854,7 +875,8 @@ static inline int drv_set_bitrate_mask(s -+ -+ might_sleep(); -+ -+- check_sdata_in_driver(sdata); -++ if (!check_sdata_in_driver(sdata)) -++ return -EIO; -+ -+ trace_drv_set_bitrate_mask(local, sdata, mask); -+ if (local->ops->set_bitrate_mask) -+@@ -869,7 +891,8 @@ static inline void drv_set_rekey_data(st -+ struct ieee80211_sub_if_data *sdata, -+ struct cfg80211_gtk_rekey_data *data) -+ { -+- check_sdata_in_driver(sdata); -++ if (!check_sdata_in_driver(sdata)) -++ return; -+ -+ trace_drv_set_rekey_data(local, sdata, data); -+ if (local->ops->set_rekey_data) -+@@ -937,7 +960,8 @@ static inline void drv_mgd_prepare_tx(st -+ { -+ might_sleep(); -+ -+- check_sdata_in_driver(sdata); -++ if (!check_sdata_in_driver(sdata)) -++ return; -+ WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION); -+ -+ trace_drv_mgd_prepare_tx(local, sdata); -+@@ -964,6 +988,9 @@ static inline int drv_add_chanctx(struct -+ static inline void drv_remove_chanctx(struct ieee80211_local *local, -+ struct ieee80211_chanctx *ctx) -+ { -++ if (WARN_ON(!ctx->driver_present)) -++ return; - + +-+ - TRACE_EVENT(cfg80211_probe_status, - TP_PROTO(struct net_device *netdev, const u8 *addr, u64 cookie, - bool acked), @@ -7268,11 +5065,7 @@ index a1af6c2..dc1e265 100644 -- enum cfg80211_chan_mode *chanmode) -+ enum cfg80211_chan_mode *chanmode, -+ u8 *radar_detect) -+ trace_drv_remove_chanctx(local, ctx); -+ if (local->ops->remove_chanctx) -+ local->ops->remove_chanctx(&local->hw, &ctx->conf); -+@@ -989,7 +1016,8 @@ static inline int drv_assign_vif_chanctx - { +- { - *chan = NULL; - *chanmode = CHAN_MODE_UNDEFINED; -@@ -660,6 +661,11 @@ cfg80211_get_chan_state(struct wireless_ @@ -7325,85 +5118,8 @@ index a1af6c2..dc1e265 100644 - wdev->mesh_id_len = setup->mesh_id_len; -- wdev->channel = setup->chandef.chan; -+ wdev->chandef = setup->chandef; -+ int ret = 0; -+ -+- check_sdata_in_driver(sdata); -++ if (!check_sdata_in_driver(sdata)) -++ return -EIO; -+ -+ trace_drv_assign_vif_chanctx(local, sdata, ctx); -+ if (local->ops->assign_vif_chanctx) { -+@@ -1007,7 +1035,8 @@ static inline void drv_unassign_vif_chan -+ struct ieee80211_sub_if_data *sdata, -+ struct ieee80211_chanctx *ctx) -+ { -+- check_sdata_in_driver(sdata); -++ if (!check_sdata_in_driver(sdata)) -++ return; -+ -+ trace_drv_unassign_vif_chanctx(local, sdata, ctx); -+ if (local->ops->unassign_vif_chanctx) { -+@@ -1024,7 +1053,8 @@ static inline int drv_start_ap(struct ie -+ { -+ int ret = 0; -+ -+- check_sdata_in_driver(sdata); -++ if (!check_sdata_in_driver(sdata)) -++ return -EIO; -+ -+ trace_drv_start_ap(local, sdata, &sdata->vif.bss_conf); -+ if (local->ops->start_ap) -+@@ -1036,7 +1066,8 @@ static inline int drv_start_ap(struct ie -+ static inline void drv_stop_ap(struct ieee80211_local *local, -+ struct ieee80211_sub_if_data *sdata) -+ { -+- check_sdata_in_driver(sdata); -++ if (!check_sdata_in_driver(sdata)) -++ return; -+ -+ trace_drv_stop_ap(local, sdata); -+ if (local->ops->stop_ap) -+@@ -1059,7 +1090,8 @@ drv_set_default_unicast_key(struct ieee8 -+ struct ieee80211_sub_if_data *sdata, -+ int key_idx) -+ { -+- check_sdata_in_driver(sdata); -++ if (!check_sdata_in_driver(sdata)) -++ return; -+ -+ WARN_ON_ONCE(key_idx < -1 || key_idx > 3); -+ -+@@ -1101,7 +1133,8 @@ static inline int drv_join_ibss(struct i -+ int ret = 0; -+ -+ might_sleep(); -+- check_sdata_in_driver(sdata); -++ if (!check_sdata_in_driver(sdata)) -++ return -EIO; -+ -+ trace_drv_join_ibss(local, sdata, &sdata->vif.bss_conf); -+ if (local->ops->join_ibss) -+@@ -1114,7 +1147,8 @@ static inline void drv_leave_ibss(struct -+ struct ieee80211_sub_if_data *sdata) -+ { -+ might_sleep(); -+- check_sdata_in_driver(sdata); -++ if (!check_sdata_in_driver(sdata)) -++ return; -+ -+ trace_drv_leave_ibss(local, sdata); -+ if (local->ops->leave_ibss) -+--- a/net/mac80211/ibss.c -++++ b/net/mac80211/ibss.c -+@@ -143,7 +143,7 @@ ieee80211_ibss_build_presp(struct ieee80 -+ *pos++ = csa_settings->block_tx ? 1 : 0; -+ *pos++ = ieee80211_frequency_to_channel( -+ csa_settings->chandef.chan->center_freq); -+- sdata->csa_counter_offset_beacon = (pos - presp->head); -++ sdata->csa_counter_offset_beacon[0] = (pos - presp->head); -+ *pos++ = csa_settings->count; - } - +- } +- - return err; -@@ -244,7 +244,7 @@ int cfg80211_set_mesh_channel(struct cfg - err = rdev_libertas_set_mesh_channel(rdev, wdev->netdev, @@ -7411,141 +5127,15 @@ index a1af6c2..dc1e265 100644 - if (!err) -- wdev->channel = chandef->chan; -+ wdev->chandef = *chandef; -+--- a/net/mac80211/ieee80211_i.h -++++ b/net/mac80211/ieee80211_i.h -+@@ -754,9 +754,10 @@ struct ieee80211_sub_if_data { -+ struct mac80211_qos_map __rcu *qos_map; -+ -+ struct work_struct csa_finalize_work; -+- int csa_counter_offset_beacon; -+- int csa_counter_offset_presp; -++ u16 csa_counter_offset_beacon[IEEE80211_MAX_CSA_COUNTERS_NUM]; -++ u16 csa_counter_offset_presp[IEEE80211_MAX_CSA_COUNTERS_NUM]; -+ bool csa_radar_required; -++ bool csa_block_tx; /* write-protected by sdata_lock and local->mtx */ -+ struct cfg80211_chan_def csa_chandef; -+ -+ struct list_head assigned_chanctx_list; /* protected by chanctx_mtx */ -+@@ -766,6 +767,7 @@ struct ieee80211_sub_if_data { -+ struct ieee80211_chanctx *reserved_chanctx; -+ struct cfg80211_chan_def reserved_chandef; -+ bool reserved_radar_required; -++ u8 csa_current_counter; -+ -+ /* used to reconfigure hardware SM PS */ -+ struct work_struct recalc_smps; -+@@ -1462,6 +1464,7 @@ __ieee80211_request_sched_scan_start(str -+ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, -+ struct cfg80211_sched_scan_request *req); -+ int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata); -++void ieee80211_sched_scan_end(struct ieee80211_local *local); -+ void ieee80211_sched_scan_stopped_work(struct work_struct *work); -+ -+ /* off-channel helpers */ -+@@ -1476,6 +1479,7 @@ void ieee80211_sw_roc_work(struct work_s -+ void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc); -+ -+ /* channel switch handling */ -++bool ieee80211_csa_needs_block_tx(struct ieee80211_local *local); -+ void ieee80211_csa_finalize_work(struct work_struct *work); -+ int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, -+ struct cfg80211_csa_settings *params); -+@@ -1837,6 +1841,15 @@ int ieee80211_check_combinations(struct -+ u8 radar_detect); -+ int ieee80211_max_num_channels(struct ieee80211_local *local); -+ -++/* TDLS */ -++int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, -++ const u8 *peer, u8 action_code, u8 dialog_token, -++ u16 status_code, u32 peer_capability, -++ const u8 *extra_ies, size_t extra_ies_len); -++int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, -++ const u8 *peer, enum nl80211_tdls_operation oper); -++ -++ -+ #ifdef CPTCFG_MAC80211_NOINLINE -+ #define debug_noinline noinline -+ #else -+--- a/net/mac80211/iface.c -++++ b/net/mac80211/iface.c -+@@ -838,8 +838,15 @@ static void ieee80211_do_stop(struct iee -+ -+ cancel_work_sync(&sdata->recalc_smps); -+ sdata_lock(sdata); -++ mutex_lock(&local->mtx); -+ sdata->vif.csa_active = false; -++ if (!ieee80211_csa_needs_block_tx(local)) -++ ieee80211_wake_queues_by_reason(&local->hw, -++ IEEE80211_MAX_QUEUE_MAP, -++ IEEE80211_QUEUE_STOP_REASON_CSA); -++ mutex_unlock(&local->mtx); -+ sdata_unlock(sdata); -++ -+ cancel_work_sync(&sdata->csa_finalize_work); -+ -+ cancel_delayed_work_sync(&sdata->dfs_cac_timer_work); -+--- a/net/mac80211/key.c -++++ b/net/mac80211/key.c -+@@ -325,7 +325,8 @@ ieee80211_key_alloc(u32 cipher, int idx, -+ struct ieee80211_key *key; -+ int i, j, err; -+ -+- BUG_ON(idx < 0 || idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS); -++ if (WARN_ON(idx < 0 || idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)) -++ return ERR_PTR(-EINVAL); -+ -+ key = kzalloc(sizeof(struct ieee80211_key) + key_len, GFP_KERNEL); -+ if (!key) -+@@ -481,8 +482,8 @@ int ieee80211_key_link(struct ieee80211_ -+ int idx, ret; -+ bool pairwise; -+ -+- BUG_ON(!sdata); -+- BUG_ON(!key); -++ if (WARN_ON(!sdata || !key)) -++ return -EINVAL; -+ -+ pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE; -+ idx = key->conf.keyidx; -+--- a/net/mac80211/main.c -++++ b/net/mac80211/main.c -+@@ -956,6 +956,8 @@ int ieee80211_register_hw(struct ieee802 -+ if (local->hw.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) -+ local->hw.wiphy->flags |= WIPHY_FLAG_TDLS_EXTERNAL_SETUP; -+ -++ local->hw.wiphy->max_num_csa_counters = IEEE80211_MAX_CSA_COUNTERS_NUM; -++ -+ result = wiphy_register(local->hw.wiphy); -+ if (result < 0) -+ goto fail_wiphy_register; -+--- a/net/mac80211/mesh.c -++++ b/net/mac80211/mesh.c -+@@ -679,7 +679,7 @@ ieee80211_mesh_build_beacon(struct ieee8 -+ *pos++ = 0x0; -+ *pos++ = ieee80211_frequency_to_channel( -+ csa->settings.chandef.chan->center_freq); -+- sdata->csa_counter_offset_beacon = hdr_len + 6; -++ sdata->csa_counter_offset_beacon[0] = hdr_len + 6; -+ *pos++ = csa->settings.count; -+ *pos++ = WLAN_EID_CHAN_SWITCH_PARAM; -+ *pos++ = 6; -+--- a/net/mac80211/mesh_pathtbl.c -++++ b/net/mac80211/mesh_pathtbl.c -+@@ -287,8 +287,10 @@ static void mesh_path_move_to_queue(stru -+ struct sk_buff_head failq; -+ unsigned long flags; -+ -+- BUG_ON(gate_mpath == from_mpath); -+- BUG_ON(!gate_mpath->next_hop); -++ if (WARN_ON(gate_mpath == from_mpath)) -++ return; -++ if (WARN_ON(!gate_mpath->next_hop)) -++ return; -+ -+ __skb_queue_head_init(&failq); - +- - return err; -- } ++@@ -442,7 +444,7 @@ int ath_startrecv(struct ath_softc *sc) ++ sc->rx.buf_hold = NULL; ++ sc->rx.rxlink = NULL; ++ list_for_each_entry_safe(bf, tbf, &sc->rx.rxbuf, list) { ++- ath_rx_buf_link(sc, bf); +++ ath_rx_buf_link(sc, bf, false); + } -@@ -276,7 +276,7 @@ static int __cfg80211_leave_mesh(struct - err = rdev_leave_mesh(rdev, dev); - if (!err) { @@ -7554,66 +5144,45 @@ index a1af6c2..dc1e265 100644 -+ memset(&wdev->chandef, 0, sizeof(wdev->chandef)); - rdev_set_qos_map(rdev, dev, NULL); - } -+--- a/net/mac80211/mesh_sync.c -++++ b/net/mac80211/mesh_sync.c -+@@ -171,7 +171,7 @@ static void mesh_sync_offset_adjust_tbtt -+ u8 cap; - +- ---- a/net/wireless/mlme.c -+++ b/net/wireless/mlme.c -@@ -772,7 +772,7 @@ void cfg80211_cac_event(struct net_devic - if (WARN_ON(!wdev->cac_started)) - return; -+ WARN_ON(ifmsh->mesh_sp_id != IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET); -+- BUG_ON(!rcu_read_lock_held()); -++ WARN_ON(!rcu_read_lock_held()); -+ cap = beacon->meshconf->meshconf_cap; -- if (WARN_ON(!wdev->channel)) -+ if (WARN_ON(!wdev->chandef.chan)) - return; -+ spin_lock_bh(&ifmsh->sync_offset_lock); -+--- a/net/mac80211/mlme.c -++++ b/net/mac80211/mlme.c -+@@ -975,16 +975,23 @@ static void ieee80211_chswitch_work(stru -+ /* XXX: shouldn't really modify cfg80211-owned data! */ -+ ifmgd->associated->channel = sdata->csa_chandef.chan; ++ /* We could have deleted elements so the list may be empty now */ ++@@ -1118,12 +1120,12 @@ requeue_drop_frag: ++ requeue: ++ list_add_tail(&bf->list, &sc->rx.rxbuf); - switch (event) { ---- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c -+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c -@@ -5065,6 +5065,10 @@ static u16 ar9003_hw_get_max_edge_power( - break; -- } ++- if (edma) { ++- ath_rx_edma_buf_link(sc, qtype); ++- } else { ++- ath_rx_buf_relink(sc, bf); +++ if (!edma) { +++ ath_rx_buf_relink(sc, bf, flush); ++ if (!flush) ++ ath9k_hw_rxena(ah); +++ } else if (!flush) { +++ ath_rx_edma_buf_link(sc, qtype); + } - } -++ ieee80211_bss_info_change_notify(sdata, changed); - + +-+ -+ if (is2GHz && !twiceMaxEdgePower) -+ twiceMaxEdgePower = 60; -++ mutex_lock(&local->mtx); -++ sdata->vif.csa_active = false; -+ /* XXX: wait for a beacon first? */ -+- ieee80211_wake_queues_by_reason(&local->hw, -++ if (!ieee80211_csa_needs_block_tx(local)) -++ ieee80211_wake_queues_by_reason(&local->hw, -+ IEEE80211_MAX_QUEUE_MAP, -+ IEEE80211_QUEUE_STOP_REASON_CSA); -++ mutex_unlock(&local->mtx); -+ -+- ieee80211_bss_info_change_notify(sdata, changed); -+- -+- out: -+- sdata->vif.csa_active = false; -+ ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED; -++ -++ ieee80211_sta_reset_beacon_monitor(sdata); -++ ieee80211_sta_reset_conn_monitor(sdata); - + +-+ - return twiceMaxEdgePower; -++out: -+ sdata_unlock(sdata); - } - +- } +- ---- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c -+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c -@@ -23,10 +23,11 @@ @@ -7629,104 +5198,40 @@ index a1af6c2..dc1e265 100644 -+ int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MAXIQCAL]; - int iqc_coeff[2]; - }; -+@@ -1100,12 +1107,16 @@ ieee80211_sta_process_chanswitch(struct -+ mutex_unlock(&local->chanctx_mtx); -+ -+ sdata->csa_chandef = csa_ie.chandef; -++ -++ mutex_lock(&local->mtx); -+ sdata->vif.csa_active = true; -++ sdata->csa_block_tx = csa_ie.mode; -+ -+- if (csa_ie.mode) -++ if (sdata->csa_block_tx) -+ ieee80211_stop_queues_by_reason(&local->hw, -+- IEEE80211_MAX_QUEUE_MAP, -+- IEEE80211_QUEUE_STOP_REASON_CSA); -++ IEEE80211_MAX_QUEUE_MAP, -++ IEEE80211_QUEUE_STOP_REASON_CSA); -++ mutex_unlock(&local->mtx); -+ -+ if (local->ops->channel_switch) { -+ /* use driver's channel switch callback */ -+@@ -1817,6 +1828,12 @@ static void ieee80211_set_disassoc(struc -+ ifmgd->flags = 0; -+ mutex_lock(&local->mtx); -+ ieee80211_vif_release_channel(sdata); -++ -++ sdata->vif.csa_active = false; -++ if (!ieee80211_csa_needs_block_tx(local)) -++ ieee80211_wake_queues_by_reason(&local->hw, -++ IEEE80211_MAX_QUEUE_MAP, -++ IEEE80211_QUEUE_STOP_REASON_CSA); -+ mutex_unlock(&local->mtx); - +- -@@ -800,7 +801,7 @@ static bool ar9003_hw_calc_iq_corr(struc - if (q_q_coff > 63) - q_q_coff = 63; -+ sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM; -+@@ -2045,6 +2062,7 @@ EXPORT_SYMBOL(ieee80211_ap_probereq_get) - +- -- iqc_coeff[0] = (q_q_coff * 128) + q_i_coff; -+ iqc_coeff[0] = (q_q_coff * 128) + (0x7f & q_i_coff); -+ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata) -+ { -++ struct ieee80211_local *local = sdata->local; -+ struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; -+ u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; - +- - ath_dbg(common, CALIBRATE, "tx chain %d: iq corr coeff=%x\n", - chain_idx, iqc_coeff[0]); -@@ -831,7 +832,7 @@ static bool ar9003_hw_calc_iq_corr(struc - if (q_q_coff > 63) - q_q_coff = 63; -+@@ -2058,10 +2076,14 @@ static void __ieee80211_disconnect(struc -+ WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, -+ true, frame_buf); -+ ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED; -++ -++ mutex_lock(&local->mtx); -+ sdata->vif.csa_active = false; -+- ieee80211_wake_queues_by_reason(&sdata->local->hw, -++ if (!ieee80211_csa_needs_block_tx(local)) -++ ieee80211_wake_queues_by_reason(&local->hw, -+ IEEE80211_MAX_QUEUE_MAP, -+ IEEE80211_QUEUE_STOP_REASON_CSA); -++ mutex_unlock(&local->mtx); -+ -+ cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, -+ IEEE80211_DEAUTH_FRAME_LEN); -+@@ -3546,6 +3568,9 @@ static void ieee80211_sta_bcn_mon_timer( -+ if (local->quiescing) -+ return; - +- -- iqc_coeff[1] = (q_q_coff * 128) + q_i_coff; -+ iqc_coeff[1] = (q_q_coff * 128) + (0x7f & q_i_coff); -++ if (sdata->vif.csa_active) -++ return; -++ -+ sdata->u.mgd.connection_loss = false; -+ ieee80211_queue_work(&sdata->local->hw, -+ &sdata->u.mgd.beacon_connection_loss_work); -+@@ -3561,6 +3586,9 @@ static void ieee80211_sta_conn_mon_timer -+ if (local->quiescing) -+ return; - +- - ath_dbg(common, CALIBRATE, "rx chain %d: iq corr coeff=%x\n", - chain_idx, iqc_coeff[1]); -@@ -839,7 +840,8 @@ static bool ar9003_hw_calc_iq_corr(struc - return true; -++ if (sdata->vif.csa_active) -++ return; -++ -+ ieee80211_queue_work(&local->hw, &ifmgd->monitor_work); - } +- } --static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement, -+static void ar9003_hw_detect_outlier(int mp_coeff[][MAXIQCAL], -+ int nmeasurement, - int max_delta) -- { ++ if (!budget--) ++--- a/net/mac80211/sta_info.c +++++ b/net/mac80211/sta_info.c ++@@ -227,6 +227,7 @@ struct sta_info *sta_info_get_by_idx(str ++ */ ++ void sta_info_free(struct ieee80211_local *local, struct sta_info *sta) + { - int mp_max = -64, max_idx = 0; -@@ -848,20 +850,20 @@ static void ar9003_hw_detect_outlier(int - @@ -7744,11 +5249,7 @@ index a1af6c2..dc1e265 100644 - min_idx = i; - } - } -+--- a/net/mac80211/rc80211_minstrel_ht.c -++++ b/net/mac80211/rc80211_minstrel_ht.c -+@@ -22,7 +22,7 @@ -+ #define MCS_NBITS (AVG_PKT_SIZE << 3) - +- - /* find average (exclude max abs value) */ - for (i = 0; i < nmeasurement; i++) { -- if ((abs(mp_coeff[i]) < abs(mp_max)) || @@ -7772,26 +5273,16 @@ index a1af6c2..dc1e265 100644 -@@ -882,15 +884,16 @@ static void ar9003_hw_detect_outlier(int - else - outlier_idx = min_idx; -- +++ struct ieee80211_sta_rates *rates; ++ int i; + -- mp_coeff[outlier_idx] = mp_avg; -+ mp_coeff[outlier_idx][0] = mp_avg; -- } -+ /* Number of symbols for a packet with (bps) bits per symbol */ -+-#define MCS_NSYMS(bps) ((MCS_NBITS + (bps) - 1) / (bps)) -++#define MCS_NSYMS(bps) DIV_ROUND_UP(MCS_NBITS, (bps)) -+ -+ /* Transmission time (nanoseconds) for a packet containing (syms) symbols */ -+ #define MCS_SYMBOL_TIME(sgi, syms) \ -+@@ -226,8 +226,9 @@ minstrel_ht_calc_tp(struct minstrel_ht_s -+ nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len); -+ -+ nsecs += minstrel_mcs_groups[group].duration[rate]; -+- tp = 1000000 * ((prob * 1000) / nsecs); -+ -++ /* prob is scaled - see MINSTREL_FRAC above */ -++ tp = 1000000 * ((prob * 1000) / nsecs); -+ mr->cur_tp = MINSTREL_TRUNC(tp); - } ++ if (sta->rate_ctrl) ++@@ -238,6 +239,10 @@ void sta_info_free(struct ieee80211_loca ++ kfree(sta->tx_lat); + } +- } --static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, -- struct coeff *coeff, @@ -7799,15 +5290,7 @@ index a1af6c2..dc1e265 100644 -+static void ar9003_hw_tx_iq_cal_outlier_detection(struct ath_hw *ah, -+ struct coeff *coeff, -+ bool is_reusable) -+--- a/net/mac80211/scan.c -++++ b/net/mac80211/scan.c -+@@ -1076,12 +1076,8 @@ void ieee80211_sched_scan_results(struct -+ } -+ EXPORT_SYMBOL(ieee80211_sched_scan_results); -+ -+-void ieee80211_sched_scan_stopped_work(struct work_struct *work) -++void ieee80211_sched_scan_end(struct ieee80211_local *local) - { +- { - int i, im, nmeasurement; -+ int magnitude, phase; - u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS]; @@ -7822,10 +5305,7 @@ index a1af6c2..dc1e265 100644 -- /* Detect magnitude outlier */ -- ar9003_hw_detect_outlier(coeff->mag_coeff[i], -- nmeasurement, MAX_MAG_DELTA); -+- struct ieee80211_local *local = -+- container_of(work, struct ieee80211_local, -+- sched_scan_stopped_work); - - +-- -- /* Detect phase outlier */ -- ar9003_hw_detect_outlier(coeff->phs_coeff[i], -- nmeasurement, MAX_PHS_DELTA); @@ -7839,14 +5319,18 @@ index a1af6c2..dc1e265 100644 -+ ar9003_hw_detect_outlier(coeff->mag_coeff[i], -+ nmeasurement, -+ MAX_MAG_DELTA); --+ +++ rates = rcu_dereference_protected(sta->sta.rates, true); +++ if (rates) +++ kfree(rates); + + -+ /* Detect phase outlier */ -+ ar9003_hw_detect_outlier(coeff->phs_coeff[i], -+ nmeasurement, -+ MAX_PHS_DELTA); -+ } - } -- ++ sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr); + - for (im = 0; im < nmeasurement; im++) { -+ magnitude = coeff->mag_coeff[i][im][0]; -+ phase = coeff->phs_coeff[i][im][0]; @@ -7855,23 +5339,24 @@ index a1af6c2..dc1e265 100644 -- ((coeff->phs_coeff[i][im] & 0x7f) << 7); -+ coeff->iqc_coeff[0] = -+ (phase & 0x7f) | ((magnitude & 0x7f) << 7); -+ mutex_lock(&local->mtx); - +- - if ((im % 2) == 0) - REG_RMW_FIELD(ah, tx_corr_coeff[im][i], -@@ -991,7 +1003,63 @@ static bool ar9003_hw_tx_iq_cal_run(stru - return true; -+ if (!rcu_access_pointer(local->sched_scan_sdata)) { -+@@ -1099,6 +1095,15 @@ void ieee80211_sched_scan_stopped_work(s -+ cfg80211_sched_scan_stopped(local->hw.wiphy); - } +- } ++ kfree(sta); ++--- a/net/mac80211/status.c +++++ b/net/mac80211/status.c ++@@ -541,6 +541,23 @@ static void ieee80211_tx_latency_end_msr ++ */ ++ #define STA_LOST_PKT_THRESHOLD 50 --static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah, bool is_reusable) -+static void __ar955x_tx_iq_cal_sort(struct ath_hw *ah, -+ struct coeff *coeff, -+ int i, int nmeasurement) -++void ieee80211_sched_scan_stopped_work(struct work_struct *work) - +{ +-+{ -+ struct ath_common *common = ath9k_hw_common(ah); -+ int im, ix, iy, temp; -+ @@ -7902,367 +5387,41 @@ index a1af6c2..dc1e265 100644 -+ i, im, -+ coeff->mag_coeff[i][im][0], -+ coeff->phs_coeff[i][im][0]); -++ struct ieee80211_local *local = -++ container_of(work, struct ieee80211_local, -++ sched_scan_stopped_work); -++ -++ ieee80211_sched_scan_end(local); -++} -++ -+ void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw) -+ { -+ struct ieee80211_local *local = hw_to_local(hw); -+--- /dev/null -++++ b/net/mac80211/tdls.c -+@@ -0,0 +1,325 @@ -++/* -++ * mac80211 TDLS handling code -++ * -++ * Copyright 2006-2010 Johannes Berg -++ * Copyright 2014, Intel Corporation -++ * -++ * This file is GPLv2 as found in COPYING. -++ */ -++ -++#include -++#include "ieee80211_i.h" -++ -++static void ieee80211_tdls_add_ext_capab(struct sk_buff *skb) -++{ -++ u8 *pos = (void *)skb_put(skb, 7); -++ -++ *pos++ = WLAN_EID_EXT_CAPABILITY; -++ *pos++ = 5; /* len */ -++ *pos++ = 0x0; -++ *pos++ = 0x0; -++ *pos++ = 0x0; -++ *pos++ = 0x0; -++ *pos++ = WLAN_EXT_CAPA5_TDLS_ENABLED; -++} -++ -++static u16 ieee80211_get_tdls_sta_capab(struct ieee80211_sub_if_data *sdata) -++{ -++ struct ieee80211_local *local = sdata->local; -++ u16 capab; -++ -++ capab = 0; -++ if (ieee80211_get_sdata_band(sdata) != IEEE80211_BAND_2GHZ) -++ return capab; -++ -++ if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE)) -++ capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME; -++ if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE)) -++ capab |= WLAN_CAPABILITY_SHORT_PREAMBLE; -++ -++ return capab; -++} -++ -++static void ieee80211_tdls_add_link_ie(struct sk_buff *skb, const u8 *src_addr, -++ const u8 *peer, const u8 *bssid) -++{ -++ struct ieee80211_tdls_lnkie *lnkid; -++ -++ lnkid = (void *)skb_put(skb, sizeof(struct ieee80211_tdls_lnkie)); -++ -++ lnkid->ie_type = WLAN_EID_LINK_ID; -++ lnkid->ie_len = sizeof(struct ieee80211_tdls_lnkie) - 2; -++ -++ memcpy(lnkid->bssid, bssid, ETH_ALEN); -++ memcpy(lnkid->init_sta, src_addr, ETH_ALEN); -++ memcpy(lnkid->resp_sta, peer, ETH_ALEN); -++} -++ -++static int -++ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev, -++ const u8 *peer, u8 action_code, u8 dialog_token, -++ u16 status_code, struct sk_buff *skb) -++{ -++ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -++ enum ieee80211_band band = ieee80211_get_sdata_band(sdata); -++ struct ieee80211_tdls_data *tf; -++ -++ tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u)); -++ -++ memcpy(tf->da, peer, ETH_ALEN); -++ memcpy(tf->sa, sdata->vif.addr, ETH_ALEN); -++ tf->ether_type = cpu_to_be16(ETH_P_TDLS); -++ tf->payload_type = WLAN_TDLS_SNAP_RFTYPE; -++ -++ switch (action_code) { -++ case WLAN_TDLS_SETUP_REQUEST: -++ tf->category = WLAN_CATEGORY_TDLS; -++ tf->action_code = WLAN_TDLS_SETUP_REQUEST; -++ -++ skb_put(skb, sizeof(tf->u.setup_req)); -++ tf->u.setup_req.dialog_token = dialog_token; -++ tf->u.setup_req.capability = -++ cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); -++ -++ ieee80211_add_srates_ie(sdata, skb, false, band); -++ ieee80211_add_ext_srates_ie(sdata, skb, false, band); -++ ieee80211_tdls_add_ext_capab(skb); -++ break; -++ case WLAN_TDLS_SETUP_RESPONSE: -++ tf->category = WLAN_CATEGORY_TDLS; -++ tf->action_code = WLAN_TDLS_SETUP_RESPONSE; -++ -++ skb_put(skb, sizeof(tf->u.setup_resp)); -++ tf->u.setup_resp.status_code = cpu_to_le16(status_code); -++ tf->u.setup_resp.dialog_token = dialog_token; -++ tf->u.setup_resp.capability = -++ cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); -++ -++ ieee80211_add_srates_ie(sdata, skb, false, band); -++ ieee80211_add_ext_srates_ie(sdata, skb, false, band); -++ ieee80211_tdls_add_ext_capab(skb); -++ break; -++ case WLAN_TDLS_SETUP_CONFIRM: -++ tf->category = WLAN_CATEGORY_TDLS; -++ tf->action_code = WLAN_TDLS_SETUP_CONFIRM; -++ -++ skb_put(skb, sizeof(tf->u.setup_cfm)); -++ tf->u.setup_cfm.status_code = cpu_to_le16(status_code); -++ tf->u.setup_cfm.dialog_token = dialog_token; -++ break; -++ case WLAN_TDLS_TEARDOWN: -++ tf->category = WLAN_CATEGORY_TDLS; -++ tf->action_code = WLAN_TDLS_TEARDOWN; -++ -++ skb_put(skb, sizeof(tf->u.teardown)); -++ tf->u.teardown.reason_code = cpu_to_le16(status_code); -++ break; -++ case WLAN_TDLS_DISCOVERY_REQUEST: -++ tf->category = WLAN_CATEGORY_TDLS; -++ tf->action_code = WLAN_TDLS_DISCOVERY_REQUEST; -++ -++ skb_put(skb, sizeof(tf->u.discover_req)); -++ tf->u.discover_req.dialog_token = dialog_token; -++ break; -++ default: -++ return -EINVAL; -++ } -++ -++ return 0; -++} -++ -++static int -++ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev, -++ const u8 *peer, u8 action_code, u8 dialog_token, -++ u16 status_code, struct sk_buff *skb) -++{ -++ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -++ enum ieee80211_band band = ieee80211_get_sdata_band(sdata); -++ struct ieee80211_mgmt *mgmt; -++ -++ mgmt = (void *)skb_put(skb, 24); -++ memset(mgmt, 0, 24); -++ memcpy(mgmt->da, peer, ETH_ALEN); -++ memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); -++ memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN); -++ -++ mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | -++ IEEE80211_STYPE_ACTION); -++ -++ switch (action_code) { -++ case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: -++ skb_put(skb, 1 + sizeof(mgmt->u.action.u.tdls_discover_resp)); -++ mgmt->u.action.category = WLAN_CATEGORY_PUBLIC; -++ mgmt->u.action.u.tdls_discover_resp.action_code = -++ WLAN_PUB_ACTION_TDLS_DISCOVER_RES; -++ mgmt->u.action.u.tdls_discover_resp.dialog_token = -++ dialog_token; -++ mgmt->u.action.u.tdls_discover_resp.capability = -++ cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); -++ -++ ieee80211_add_srates_ie(sdata, skb, false, band); -++ ieee80211_add_ext_srates_ie(sdata, skb, false, band); -++ ieee80211_tdls_add_ext_capab(skb); -++ break; -++ default: -++ return -EINVAL; - + } -++ -++ return 0; - +} - + +-+ } +-+} +-+ -+static bool ar955x_tx_iq_cal_median(struct ath_hw *ah, -+ struct coeff *coeff, -+ int iqcal_idx, -+ int nmeasurement) -++int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, -++ const u8 *peer, u8 action_code, u8 dialog_token, -++ u16 status_code, u32 peer_capability, -++ const u8 *extra_ies, size_t extra_ies_len) +++static void ieee80211_lost_packet(struct sta_info *sta, struct sk_buff *skb) +{ -+ int i; -++ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -++ struct ieee80211_local *local = sdata->local; -++ struct sk_buff *skb = NULL; -++ bool send_direct; -++ int ret; -++ -++ if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)) -++ return -ENOTSUPP; -++ -++ /* make sure we are in managed mode, and associated */ -++ if (sdata->vif.type != NL80211_IFTYPE_STATION || -++ !sdata->u.mgd.associated) -++ return -EINVAL; -++ -++ tdls_dbg(sdata, "TDLS mgmt action %d peer %pM\n", -++ action_code, peer); -++ -++ skb = dev_alloc_skb(local->hw.extra_tx_headroom + -++ max(sizeof(struct ieee80211_mgmt), -++ sizeof(struct ieee80211_tdls_data)) + -++ 50 + /* supported rates */ -++ 7 + /* ext capab */ -++ extra_ies_len + -++ sizeof(struct ieee80211_tdls_lnkie)); -++ if (!skb) -++ return -ENOMEM; -++ -++ skb_reserve(skb, local->hw.extra_tx_headroom); -++ -++ switch (action_code) { -++ case WLAN_TDLS_SETUP_REQUEST: -++ case WLAN_TDLS_SETUP_RESPONSE: -++ case WLAN_TDLS_SETUP_CONFIRM: -++ case WLAN_TDLS_TEARDOWN: -++ case WLAN_TDLS_DISCOVERY_REQUEST: -++ ret = ieee80211_prep_tdls_encap_data(wiphy, dev, peer, -++ action_code, dialog_token, -++ status_code, skb); -++ send_direct = false; -++ break; -++ case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: -++ ret = ieee80211_prep_tdls_direct(wiphy, dev, peer, action_code, -++ dialog_token, status_code, -++ skb); -++ send_direct = true; -++ break; -++ default: -++ ret = -ENOTSUPP; -++ break; -++ } -++ -++ if (ret < 0) -++ goto fail; -++ -++ if (extra_ies_len) -++ memcpy(skb_put(skb, extra_ies_len), extra_ies, extra_ies_len); -++ -++ /* the TDLS link IE is always added last */ -++ switch (action_code) { -++ case WLAN_TDLS_SETUP_REQUEST: -++ case WLAN_TDLS_SETUP_CONFIRM: -++ case WLAN_TDLS_TEARDOWN: -++ case WLAN_TDLS_DISCOVERY_REQUEST: -++ /* we are the initiator */ -++ ieee80211_tdls_add_link_ie(skb, sdata->vif.addr, peer, -++ sdata->u.mgd.bssid); -++ break; -++ case WLAN_TDLS_SETUP_RESPONSE: -++ case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: -++ /* we are the responder */ -++ ieee80211_tdls_add_link_ie(skb, peer, sdata->vif.addr, -++ sdata->u.mgd.bssid); -++ break; -++ default: -++ ret = -ENOTSUPP; -++ goto fail; -++ } +++ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + -+ if ((iqcal_idx + 1) != MAXIQCAL) -+ return false; -++ if (send_direct) { -++ ieee80211_tx_skb(sdata, skb); -++ return 0; -++ } +++ /* This packet was aggregated but doesn't carry status info */ +++ if ((info->flags & IEEE80211_TX_CTL_AMPDU) && +++ !(info->flags & IEEE80211_TX_STAT_AMPDU)) +++ return; + -+ for (i = 0; i < AR9300_MAX_CHAINS; i++) { -+ __ar955x_tx_iq_cal_sort(ah, coeff, i, nmeasurement); -++ /* -++ * According to 802.11z: Setup req/resp are sent in AC_BK, otherwise -++ * we should default to AC_VI. -++ */ -++ switch (action_code) { -++ case WLAN_TDLS_SETUP_REQUEST: -++ case WLAN_TDLS_SETUP_RESPONSE: -++ skb_set_queue_mapping(skb, IEEE80211_AC_BK); -++ skb->priority = 2; -++ break; -++ default: -++ skb_set_queue_mapping(skb, IEEE80211_AC_VI); -++ skb->priority = 5; -++ break; - + } +-+ } +++ if (++sta->lost_packets < STA_LOST_PKT_THRESHOLD) +++ return; + -+ return true; -++ /* disable bottom halves when entering the Tx path */ -++ local_bh_disable(); -++ ret = ieee80211_subif_start_xmit(skb, dev); -++ local_bh_enable(); -++ -++ return ret; -++ -++fail: -++ dev_kfree_skb(skb); -++ return ret; +++ cfg80211_cqm_pktloss_notify(sta->sdata->dev, sta->sta.addr, +++ sta->lost_packets, GFP_ATOMIC); +++ sta->lost_packets = 0; +} + -+static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah, -+ int iqcal_idx, -+ bool is_reusable) -++int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, -++ const u8 *peer, enum nl80211_tdls_operation oper) -++{ -++ struct sta_info *sta; -++ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -++ -++ if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)) -++ return -ENOTSUPP; -++ -++ if (sdata->vif.type != NL80211_IFTYPE_STATION) -++ return -EINVAL; -++ -++ tdls_dbg(sdata, "TDLS oper %d peer %pM\n", oper, peer); -++ -++ switch (oper) { -++ case NL80211_TDLS_ENABLE_LINK: -++ rcu_read_lock(); -++ sta = sta_info_get(sdata, peer); -++ if (!sta) { -++ rcu_read_unlock(); -++ return -ENOLINK; -++ } -++ -++ set_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH); -++ rcu_read_unlock(); -++ break; -++ case NL80211_TDLS_DISABLE_LINK: -++ return sta_info_destroy_addr(sdata, peer); -++ case NL80211_TDLS_TEARDOWN: -++ case NL80211_TDLS_SETUP: -++ case NL80211_TDLS_DISCOVERY_REQ: -++ /* We don't support in-driver setup/teardown/discovery */ -++ return -ENOTSUPP; -++ default: -++ return -ENOTSUPP; -++ } -++ -++ return 0; -++} -+--- a/net/mac80211/tx.c -++++ b/net/mac80211/tx.c -+@@ -2330,7 +2330,8 @@ void ieee80211_tx_pending(unsigned long -+ /* functions for drivers to get certain frames */ -+ -+ static void __ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata, -+- struct ps_data *ps, struct sk_buff *skb) -++ struct ps_data *ps, struct sk_buff *skb, -++ bool is_template) - { +- { - struct ath_common *common = ath9k_hw_common(ah); - const u32 txiqcal_status[AR9300_MAX_CHAINS] = { -@@ -1004,10 +1072,11 @@ static void ar9003_hw_tx_iq_cal_post_pro @@ -8281,25 +5440,23 @@ index a1af6c2..dc1e265 100644 - if (!(ah->txchainmask & (1 << i))) -@@ -1065,17 +1134,23 @@ static void ar9003_hw_tx_iq_cal_post_pro - goto tx_iqcal_fail; -- } -+ u8 *pos, *tim; -+ int aid0 = 0; -+@@ -2343,11 +2344,12 @@ static void __ieee80211_beacon_add_tim(s -+ * checking byte-for-byte */ -+ have_bits = !bitmap_empty((unsigned long *)ps->tim, -+ IEEE80211_MAX_AID+1); -+- -+- if (ps->dtim_count == 0) -+- ps->dtim_count = sdata->vif.bss_conf.dtim_period - 1; -+- else -+- ps->dtim_count--; -++ if (!is_template) { -++ if (ps->dtim_count == 0) -++ ps->dtim_count = sdata->vif.bss_conf.dtim_period - 1; -++ else -++ ps->dtim_count--; -++ } - ++ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) ++ { ++ struct sk_buff *skb2; ++@@ -680,12 +697,8 @@ void ieee80211_tx_status(struct ieee8021 ++ if (info->flags & IEEE80211_TX_STAT_ACK) { ++ if (sta->lost_packets) ++ sta->lost_packets = 0; ++- } else if (++sta->lost_packets >= STA_LOST_PKT_THRESHOLD) { ++- cfg80211_cqm_pktloss_notify(sta->sdata->dev, ++- sta->sta.addr, ++- sta->lost_packets, ++- GFP_ATOMIC); ++- sta->lost_packets = 0; +++ } else { +++ ieee80211_lost_packet(sta, skb); + } +- -- coeff.mag_coeff[i][im] = coeff.iqc_coeff[0] & 0x7f; -- coeff.phs_coeff[i][im] = -+ coeff.phs_coeff[i][im][iqcal_idx] = @@ -8315,325 +5472,33 @@ index a1af6c2..dc1e265 100644 -+ coeff.mag_coeff[i][im][iqcal_idx] -= 128; -+ if (coeff.phs_coeff[i][im][iqcal_idx] > 63) -+ coeff.phs_coeff[i][im][iqcal_idx] -= 128; -+ tim = pos = (u8 *) skb_put(skb, 6); -+ *pos++ = WLAN_EID_TIM; -+@@ -2393,7 +2395,8 @@ static void __ieee80211_beacon_add_tim(s -+ } -+ -+ static int ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata, -+- struct ps_data *ps, struct sk_buff *skb) -++ struct ps_data *ps, struct sk_buff *skb, -++ bool is_template) -+ { -+ struct ieee80211_local *local = sdata->local; -+ -+@@ -2405,24 +2408,24 @@ static int ieee80211_beacon_add_tim(stru -+ * of the tim bitmap in mac80211 and the driver. -+ */ -+ if (local->tim_in_locked_section) { -+- __ieee80211_beacon_add_tim(sdata, ps, skb); -++ __ieee80211_beacon_add_tim(sdata, ps, skb, is_template); -+ } else { -+ spin_lock_bh(&local->tim_lock); -+- __ieee80211_beacon_add_tim(sdata, ps, skb); -++ __ieee80211_beacon_add_tim(sdata, ps, skb, is_template); -+ spin_unlock_bh(&local->tim_lock); -+ } -+ -+ return 0; -+ } -+ -+-static void ieee80211_update_csa(struct ieee80211_sub_if_data *sdata, -+- struct beacon_data *beacon) -++static void ieee80211_set_csa(struct ieee80211_sub_if_data *sdata, -++ struct beacon_data *beacon) -+ { -+ struct probe_resp *resp; -+- int counter_offset_beacon = sdata->csa_counter_offset_beacon; -+- int counter_offset_presp = sdata->csa_counter_offset_presp; -+ u8 *beacon_data; -+ size_t beacon_data_len; -++ int i; -++ u8 count = sdata->csa_current_counter; -+ -+ switch (sdata->vif.type) { -+ case NL80211_IFTYPE_AP: -+@@ -2440,40 +2443,57 @@ static void ieee80211_update_csa(struct -+ default: -+ return; -+ } -+- if (WARN_ON(counter_offset_beacon >= beacon_data_len)) -+- return; -+ -+- /* Warn if the driver did not check for/react to csa -+- * completeness. A beacon with CSA counter set to 0 should -+- * never occur, because a counter of 1 means switch just -+- * before the next beacon. -+- */ -+- if (WARN_ON(beacon_data[counter_offset_beacon] == 1)) -+- return; -++ for (i = 0; i < IEEE80211_MAX_CSA_COUNTERS_NUM; ++i) { -++ u16 counter_offset_beacon = -++ sdata->csa_counter_offset_beacon[i]; -++ u16 counter_offset_presp = sdata->csa_counter_offset_presp[i]; -++ -++ if (counter_offset_beacon) { -++ if (WARN_ON(counter_offset_beacon >= beacon_data_len)) -++ return; -+ -+- beacon_data[counter_offset_beacon]--; -++ beacon_data[counter_offset_beacon] = count; -++ } -+ -+- if (sdata->vif.type == NL80211_IFTYPE_AP && counter_offset_presp) { -+- rcu_read_lock(); -+- resp = rcu_dereference(sdata->u.ap.probe_resp); -++ if (sdata->vif.type == NL80211_IFTYPE_AP && -++ counter_offset_presp) { -++ rcu_read_lock(); -++ resp = rcu_dereference(sdata->u.ap.probe_resp); -+ -+- /* if nl80211 accepted the offset, this should not happen. */ -+- if (WARN_ON(!resp)) { -++ /* If nl80211 accepted the offset, this should -++ * not happen. -++ */ -++ if (WARN_ON(!resp)) { -++ rcu_read_unlock(); -++ return; -++ } -++ resp->data[counter_offset_presp] = count; -+ rcu_read_unlock(); -+- return; } -+- resp->data[counter_offset_presp]--; -+- rcu_read_unlock(); - } +- } -- ar9003_hw_tx_iqcal_load_avg_2_passes(ah, &coeff, is_reusable); -+ } -+ -++u8 ieee80211_csa_update_counter(struct ieee80211_vif *vif) -++{ -++ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); -++ -++ sdata->csa_current_counter--; -++ -++ /* the counter should never reach 0 */ -++ WARN_ON(!sdata->csa_current_counter); - + +-+ -+ if (AR_SREV_9550(ah)) -+ outlier_detect = ar955x_tx_iq_cal_median(ah, &coeff, -+ iqcal_idx, nmeasurement); -+ if (outlier_detect) -+ ar9003_hw_tx_iq_cal_outlier_detection(ah, &coeff, is_reusable); -++ return sdata->csa_current_counter; -++} -++EXPORT_SYMBOL(ieee80211_csa_update_counter); -++ -+ bool ieee80211_csa_is_complete(struct ieee80211_vif *vif) -+ { -+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); -+ struct beacon_data *beacon = NULL; -+ u8 *beacon_data; -+ size_t beacon_data_len; -+- int counter_beacon = sdata->csa_counter_offset_beacon; -++ int counter_beacon = sdata->csa_counter_offset_beacon[0]; -+ int ret = false; - +- - return; -+ if (!ieee80211_sdata_running(sdata)) -+@@ -2523,9 +2543,11 @@ bool ieee80211_csa_is_complete(struct ie -+ } -+ EXPORT_SYMBOL(ieee80211_csa_is_complete); -+ -+-struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, -+- struct ieee80211_vif *vif, -+- u16 *tim_offset, u16 *tim_length) -++static struct sk_buff * -++__ieee80211_beacon_get(struct ieee80211_hw *hw, -++ struct ieee80211_vif *vif, -++ struct ieee80211_mutable_offsets *offs, -++ bool is_template) -+ { -+ struct ieee80211_local *local = hw_to_local(hw); -+ struct sk_buff *skb = NULL; -+@@ -2534,6 +2556,7 @@ struct sk_buff *ieee80211_beacon_get_tim -+ enum ieee80211_band band; -+ struct ieee80211_tx_rate_control txrc; -+ struct ieee80211_chanctx_conf *chanctx_conf; -++ int csa_off_base = 0; -+ -+ rcu_read_lock(); -+ -+@@ -2543,18 +2566,20 @@ struct sk_buff *ieee80211_beacon_get_tim -+ if (!ieee80211_sdata_running(sdata) || !chanctx_conf) -+ goto out; -+ -+- if (tim_offset) -+- *tim_offset = 0; -+- if (tim_length) -+- *tim_length = 0; -++ if (offs) -++ memset(offs, 0, sizeof(*offs)); -+ -+ if (sdata->vif.type == NL80211_IFTYPE_AP) { -+ struct ieee80211_if_ap *ap = &sdata->u.ap; -+ struct beacon_data *beacon = rcu_dereference(ap->beacon); -+ -+ if (beacon) { -+- if (sdata->vif.csa_active) -+- ieee80211_update_csa(sdata, beacon); -++ if (sdata->vif.csa_active) { -++ if (!is_template) -++ ieee80211_csa_update_counter(vif); -++ -++ ieee80211_set_csa(sdata, beacon); -++ } -+ -+ /* -+ * headroom, head length, -+@@ -2571,12 +2596,16 @@ struct sk_buff *ieee80211_beacon_get_tim -+ memcpy(skb_put(skb, beacon->head_len), beacon->head, -+ beacon->head_len); -+ -+- ieee80211_beacon_add_tim(sdata, &ap->ps, skb); -++ ieee80211_beacon_add_tim(sdata, &ap->ps, skb, -++ is_template); -++ -++ if (offs) { -++ offs->tim_offset = beacon->head_len; -++ offs->tim_length = skb->len - beacon->head_len; -+ -+- if (tim_offset) -+- *tim_offset = beacon->head_len; -+- if (tim_length) -+- *tim_length = skb->len - beacon->head_len; -++ /* for AP the csa offsets are from tail */ -++ csa_off_base = skb->len; -++ } -+ -+ if (beacon->tail) -+ memcpy(skb_put(skb, beacon->tail_len), -+@@ -2591,9 +2620,12 @@ struct sk_buff *ieee80211_beacon_get_tim -+ if (!presp) -+ goto out; -+ -+- if (sdata->vif.csa_active) -+- ieee80211_update_csa(sdata, presp); -++ if (sdata->vif.csa_active) { -++ if (!is_template) -++ ieee80211_csa_update_counter(vif); -+ -++ ieee80211_set_csa(sdata, presp); -++ } -+ -+ skb = dev_alloc_skb(local->tx_headroom + presp->head_len + -+ local->hw.extra_beacon_tailroom); -+@@ -2613,8 +2645,17 @@ struct sk_buff *ieee80211_beacon_get_tim -+ if (!bcn) -+ goto out; -+ -+- if (sdata->vif.csa_active) -+- ieee80211_update_csa(sdata, bcn); -++ if (sdata->vif.csa_active) { -++ if (!is_template) -++ /* TODO: For mesh csa_counter is in TU, so -++ * decrementing it by one isn't correct, but -++ * for now we leave it consistent with overall -++ * mac80211's behavior. -++ */ -++ ieee80211_csa_update_counter(vif); -++ -++ ieee80211_set_csa(sdata, bcn); -++ } - +- -@@ -1409,7 +1484,7 @@ skip_tx_iqcal: -+ if (ifmsh->sync_ops) -+ ifmsh->sync_ops->adjust_tbtt(sdata, bcn); -+@@ -2628,13 +2669,33 @@ struct sk_buff *ieee80211_beacon_get_tim -+ goto out; -+ skb_reserve(skb, local->tx_headroom); -+ memcpy(skb_put(skb, bcn->head_len), bcn->head, bcn->head_len); -+- ieee80211_beacon_add_tim(sdata, &ifmsh->ps, skb); -++ ieee80211_beacon_add_tim(sdata, &ifmsh->ps, skb, is_template); -++ -++ if (offs) { -++ offs->tim_offset = bcn->head_len; -++ offs->tim_length = skb->len - bcn->head_len; -++ } -++ -+ memcpy(skb_put(skb, bcn->tail_len), bcn->tail, bcn->tail_len); -+ } else { -+ WARN_ON(1); -+ goto out; - } - +- } +- - if (txiqcal_done) -- ar9003_hw_tx_iq_cal_post_proc(ah, is_reusable); -+ ar9003_hw_tx_iq_cal_post_proc(ah, 0, is_reusable); - else if (caldata && test_bit(TXIQCAL_DONE, &caldata->cal_flags)) - ar9003_hw_tx_iq_cal_reload(ah); -++ /* CSA offsets */ -++ if (offs) { -++ int i; -++ -++ for (i = 0; i < IEEE80211_MAX_CSA_COUNTERS_NUM; i++) { -++ u16 csa_off = sdata->csa_counter_offset_beacon[i]; -++ -++ if (!csa_off) -++ continue; -++ -++ offs->csa_counter_offs[i] = csa_off_base + csa_off; -++ } -++ } -++ -+ band = chanctx_conf->def.chan->band; -+ -+ info = IEEE80211_SKB_CB(skb); -+@@ -2665,6 +2726,32 @@ struct sk_buff *ieee80211_beacon_get_tim -+ out: -+ rcu_read_unlock(); -+ return skb; -++ -++} -++ -++struct sk_buff * -++ieee80211_beacon_get_template(struct ieee80211_hw *hw, -++ struct ieee80211_vif *vif, -++ struct ieee80211_mutable_offsets *offs) -++{ -++ return __ieee80211_beacon_get(hw, vif, offs, true); -++} -++EXPORT_SYMBOL(ieee80211_beacon_get_template); -++ -++struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, -++ struct ieee80211_vif *vif, -++ u16 *tim_offset, u16 *tim_length) -++{ -++ struct ieee80211_mutable_offsets offs = {}; -++ struct sk_buff *bcn = __ieee80211_beacon_get(hw, vif, &offs, false); -++ -++ if (tim_offset) -++ *tim_offset = offs.tim_offset; -++ -++ if (tim_length) -++ *tim_length = offs.tim_length; -++ -++ return bcn; -+ } -+ EXPORT_SYMBOL(ieee80211_beacon_get_tim); - +- -@@ -1455,14 +1530,38 @@ skip_tx_iqcal: - return true; -+--- a/net/mac80211/util.c -++++ b/net/mac80211/util.c -+@@ -1457,6 +1457,44 @@ void ieee80211_stop_device(struct ieee80 -+ drv_stop(local); - } - +- } +- -+static bool do_ar9003_agc_cal(struct ath_hw *ah) -++static void ieee80211_handle_reconfig_failure(struct ieee80211_local *local) - +{ +-+{ -+ struct ath_common *common = ath9k_hw_common(ah); -+ bool status; -+ @@ -8651,48 +5516,13 @@ index a1af6c2..dc1e265 100644 -+ AH_WAIT_TIMEOUT / 1000); -+ return false; -+ } -++ struct ieee80211_sub_if_data *sdata; -++ struct ieee80211_chanctx *ctx; -++ -++ /* -++ * We get here if during resume the device can't be restarted properly. -++ * We might also get here if this happens during HW reset, which is a -++ * slightly different situation and we need to drop all connections in -++ * the latter case. -++ * -++ * Ask cfg80211 to turn off all interfaces, this will result in more -++ * warnings but at least we'll then get into a clean stopped state. -++ */ -++ -++ local->resuming = false; -++ local->suspended = false; -++ local->started = false; -++ -++ /* scheduled scan clearly can't be running any more, but tell -++ * cfg80211 and clear local state -++ */ -++ ieee80211_sched_scan_end(local); - + +-+ -+ return true; -++ list_for_each_entry(sdata, &local->interfaces, list) -++ sdata->flags &= ~IEEE80211_SDATA_IN_DRIVER; -++ -++ /* Mark channel contexts as not being in the driver any more to avoid -++ * removing them from the driver during the shutdown process... -++ */ -++ mutex_lock(&local->chanctx_mtx); -++ list_for_each_entry(ctx, &local->chanctx_list, list) -++ ctx->driver_present = false; -++ mutex_unlock(&local->chanctx_mtx); -++ -++ cfg80211_shutdown_all_interfaces(local->hw.wiphy); - +} - + +-+} +-+ - static bool ar9003_hw_init_cal_soc(struct ath_hw *ah, - struct ath9k_channel *chan) -+ static void ieee80211_assign_chanctx(struct ieee80211_local *local, -+ struct ieee80211_sub_if_data *sdata) - { +- { - struct ath_common *common = ath9k_hw_common(ah); - struct ath9k_hw_cal_data *caldata = ah->caldata; - bool txiqcal_done = false; @@ -8705,8 +5535,7 @@ index a1af6c2..dc1e265 100644 - ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask); -@@ -1485,7 +1584,12 @@ static bool ar9003_hw_init_cal_soc(struc - * AGC calibration. Specifically, AR9550 in SoC chips. -+@@ -1520,9 +1558,11 @@ int ieee80211_reconfig(struct ieee80211_ - */ +- */ - if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) { -- txiqcal_done = true; -+ if (REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_0, @@ -8766,74 +5595,25 @@ index a1af6c2..dc1e265 100644 -+ } -+ } -+ } -+ res = drv_start(local); -+ if (res) { -+- WARN(local->suspended, "Hardware became unavailable " -+- "upon resume. This could be a software issue " -+- "prior to suspend or a hardware issue.\n"); -++ if (local->suspended) -++ WARN(1, "Hardware became unavailable upon resume. This could be a software issue prior to suspend or a hardware issue.\n"); -++ else -++ WARN(1, "Hardware became unavailable during restart.\n"); -++ ieee80211_handle_reconfig_failure(local); -+ return res; - } - +- } +- -- if (txiqcal_done) -- ar9003_hw_tx_iq_cal_post_proc(ah, is_reusable); -- - /* Revert chainmask to runtime parameters */ - ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); -+--- a/net/wireless/ap.c -++++ b/net/wireless/ap.c -+@@ -6,8 +6,8 @@ -+ #include "rdev-ops.h" - +- ---- a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h -+++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h -@@ -15,6 +15,8 @@ - #ifndef RTL8187_H - #define RTL8187_H - +- -+#include -+ - #include "rtl818x.h" - #include "leds.h" -+-static int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, -+- struct net_device *dev, bool notify) -++int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, -++ struct net_device *dev, bool notify) -+ { -+ struct wireless_dev *wdev = dev->ieee80211_ptr; -+ int err; -+--- a/net/wireless/chan.c -++++ b/net/wireless/chan.c -+@@ -370,8 +370,8 @@ int cfg80211_chandef_dfs_required(struct -+ case NL80211_IFTYPE_AP_VLAN: -+ case NL80211_IFTYPE_WDS: -+ case NL80211_IFTYPE_P2P_DEVICE: -+- case NL80211_IFTYPE_UNSPECIFIED: -+ break; -++ case NL80211_IFTYPE_UNSPECIFIED: -+ case NUM_NL80211_IFTYPES: -+ WARN_ON(1); -+ } -+@@ -796,8 +796,7 @@ bool cfg80211_reg_can_beacon(struct wiph -+ !cfg80211_go_permissive_chan(rdev, chandef->chan)) -+ prohibited_flags |= IEEE80211_CHAN_NO_IR; -+ -+- if (cfg80211_chandef_dfs_required(wiphy, chandef, -+- NL80211_IFTYPE_UNSPECIFIED) > 0 && -++ if (cfg80211_chandef_dfs_required(wiphy, chandef, iftype) > 0 && -+ cfg80211_chandef_dfs_available(wiphy, chandef)) { -+ /* We can skip IEEE80211_CHAN_NO_IR if chandef dfs available */ -+ prohibited_flags = IEEE80211_CHAN_DISABLED; -+--- a/net/wireless/core.c -++++ b/net/wireless/core.c -+@@ -210,15 +210,12 @@ void cfg80211_stop_p2p_device(struct cfg -+ } -+ } - +- -@@ -139,7 +141,10 @@ struct rtl8187_priv { - u8 aifsn[4]; - u8 rfkill_mask; @@ -8860,36 +5640,13 @@ index a1af6c2..dc1e265 100644 -+++ b/net/mac80211/wme.c -@@ -154,6 +154,11 @@ u16 ieee80211_select_queue(struct ieee80 - return IEEE80211_AC_BE; -+-static int cfg80211_rfkill_set_block(void *data, bool blocked) -++void cfg80211_shutdown_all_interfaces(struct wiphy *wiphy) -+ { -+- struct cfg80211_registered_device *rdev = data; -++ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); -+ struct wireless_dev *wdev; -+ -+- if (!blocked) -+- return 0; -+- -+- rtnl_lock(); -++ ASSERT_RTNL(); -+ -+ list_for_each_entry(wdev, &rdev->wdev_list, list) { -+ if (wdev->netdev) { -+@@ -234,7 +231,18 @@ static int cfg80211_rfkill_set_block(voi -+ break; -+ } - } -++} -++EXPORT_SYMBOL_GPL(cfg80211_shutdown_all_interfaces); - +- } +- -+ if (skb->protocol == sdata->control_port_protocol) { -+ skb->priority = 7; -+ return ieee80211_downgrade_queue(sdata, skb); -+ } -++static int cfg80211_rfkill_set_block(void *data, bool blocked) -++{ -++ struct cfg80211_registered_device *rdev = data; - + +-+ - /* use the data classifier to determine what 802.1d tag the - * data frame has */ - rcu_read_lock(); @@ -8904,71 +5661,30 @@ index a1af6c2..dc1e265 100644 -- - ac = tid->ac; - txq = ac->txq; -++ if (!blocked) -++ return 0; -++ -++ rtnl_lock(); -++ cfg80211_shutdown_all_interfaces(&rdev->wiphy); -+ rtnl_unlock(); - +- - ath_txq_lock(sc, txq); -+ return 0; -+@@ -401,6 +409,8 @@ struct wiphy *wiphy_new(const struct cfg -+ rdev->wiphy.rts_threshold = (u32) -1; -+ rdev->wiphy.coverage_class = 0; - +- -+ if (!tid->sched) { -+ ath_txq_unlock(sc, txq); -+ continue; -+ } -++ rdev->wiphy.max_num_csa_counters = 1; - + +-+ - buffered = ath_tid_has_buffered(tid); -+ return &rdev->wiphy; -+ } -+ EXPORT_SYMBOL(wiphy_new); -+@@ -697,7 +707,7 @@ void wiphy_unregister(struct wiphy *wiph -+ rtnl_lock(); -+ rdev->wiphy.registered = false; - +- - tid->sched = false; -@@ -1696,7 +1698,7 @@ int ath_cabq_update(struct ath_softc *sc -+- BUG_ON(!list_empty(&rdev->wdev_list)); -++ WARN_ON(!list_empty(&rdev->wdev_list)); - +- - ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi); -+ /* -+ * First remove the hardware from everywhere, this makes -+@@ -799,23 +809,23 @@ void cfg80211_update_iface_num(struct cf -+ rdev->num_running_monitor_ifaces += num; -+ } - +- -- qi.tqi_readyTime = (cur_conf->beacon_interval * -+ qi.tqi_readyTime = (TU_TO_USEC(cur_conf->beacon_interval) * - ATH_CABQ_READY_TIME) / 100; - ath_txq_update(sc, qnum, &qi); -+-void cfg80211_leave(struct cfg80211_registered_device *rdev, -+- struct wireless_dev *wdev) -++void __cfg80211_leave(struct cfg80211_registered_device *rdev, -++ struct wireless_dev *wdev) -+ { -+ struct net_device *dev = wdev->netdev; - +- -@@ -2061,7 +2063,7 @@ static struct ath_buf *ath_tx_setup_buff -+ ASSERT_RTNL(); -++ ASSERT_WDEV_LOCK(wdev); - +- - ATH_TXBUF_RESET(bf); -+ switch (wdev->iftype) { -+ case NL80211_IFTYPE_ADHOC: -+- cfg80211_leave_ibss(rdev, dev, true); -++ __cfg80211_leave_ibss(rdev, dev, true); -+ break; -+ case NL80211_IFTYPE_P2P_CLIENT: -+ case NL80211_IFTYPE_STATION: -+ if (rdev->sched_scan_req && dev == rdev->sched_scan_req->dev) -+ __cfg80211_stop_sched_scan(rdev, false); - +- -- if (tid) { -+ if (tid && ieee80211_is_data_present(hdr->frame_control)) { - fragno = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; @@ -8976,28 +5692,7 @@ index a1af6c2..dc1e265 100644 - hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT); -@@ -2184,14 +2186,15 @@ int ath_tx_start(struct ieee80211_hw *hw - txq->stopped = true; -+- wdev_lock(wdev); -+ #ifdef CPTCFG_CFG80211_WEXT -+ kfree(wdev->wext.ie); -+ wdev->wext.ie = NULL; -+@@ -824,20 +834,49 @@ void cfg80211_leave(struct cfg80211_regi -+ #endif -+ cfg80211_disconnect(rdev, dev, -+ WLAN_REASON_DEAUTH_LEAVING, true); -+- wdev_unlock(wdev); -+ break; -+ case NL80211_IFTYPE_MESH_POINT: -+- cfg80211_leave_mesh(rdev, dev); -++ __cfg80211_leave_mesh(rdev, dev); -+ break; -+ case NL80211_IFTYPE_AP: -+ case NL80211_IFTYPE_P2P_GO: -+- cfg80211_stop_ap(rdev, dev, true); -++ __cfg80211_stop_ap(rdev, dev, true); -+ break; -+ default: -+ break; - } +- } - -+ if (txctl->an && ieee80211_is_data_present(hdr->frame_control)) -+ tid = ath_get_skb_tid(sc, txctl->an, skb); @@ -9046,8 +5741,8 @@ index a1af6c2..dc1e265 100644 -+++ b/net/mac80211/sta_info.c -@@ -91,7 +91,7 @@ static int sta_info_hash_del(struct ieee - return -ENOENT; - } - +- } +- --static void cleanup_single_sta(struct sta_info *sta) -+static void __cleanup_single_sta(struct sta_info *sta) - { @@ -9075,25 +5770,13 @@ index a1af6c2..dc1e265 100644 - ieee80211_purge_tx_queue(&local->hw, &tid_tx->pending); - kfree(tid_tx); - } -++void cfg80211_leave(struct cfg80211_registered_device *rdev, -++ struct wireless_dev *wdev) -++{ -++ wdev_lock(wdev); -++ __cfg80211_leave(rdev, wdev); -++ wdev_unlock(wdev); - +} +-+} - -+static void cleanup_single_sta(struct sta_info *sta) -++ -++void cfg80211_stop_iface(struct wiphy *wiphy, struct wireless_dev *wdev, -++ gfp_t gfp) - +{ +-+{ -+ struct ieee80211_sub_if_data *sdata = sta->sdata; -+ struct ieee80211_local *local = sdata->local; -++ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); -++ struct cfg80211_event *ev; -++ unsigned long flags; - + +-+ -+ __cleanup_single_sta(sta); - sta_info_free(local, sta); - } @@ -9121,64 +5804,12 @@ index a1af6c2..dc1e265 100644 - -+ /* simplify things and don't accept BA sessions yet */ -+ set_sta_flag(sta, WLAN_STA_BLOCK_BA); -++ trace_cfg80211_stop_iface(wiphy, wdev); -++ -++ ev = kzalloc(sizeof(*ev), gfp); -++ if (!ev) -++ return; - + +-+ - /* make the station visible */ - sta_info_hash_add(local, sta); -++ ev->type = EVENT_STOPPED; -++ -++ spin_lock_irqsave(&wdev->event_lock, flags); -++ list_add_tail(&ev->list, &wdev->event_list); -++ spin_unlock_irqrestore(&wdev->event_lock, flags); -++ queue_work(cfg80211_wq, &rdev->event_work); -++} -++EXPORT_SYMBOL(cfg80211_stop_iface); -++ -+ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, -+ unsigned long state, void *ptr) -+ { -+--- a/net/wireless/core.h -++++ b/net/wireless/core.h -+@@ -185,6 +185,7 @@ enum cfg80211_event_type { -+ EVENT_ROAMED, -+ EVENT_DISCONNECTED, -+ EVENT_IBSS_JOINED, -++ EVENT_STOPPED, -+ }; - +- - list_add_rcu(&sta->list, &local->sta_list); -+ struct cfg80211_event { -+@@ -281,6 +282,8 @@ int cfg80211_join_mesh(struct cfg80211_r -+ struct net_device *dev, -+ struct mesh_setup *setup, -+ const struct mesh_config *conf); -++int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, -++ struct net_device *dev); -+ int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, -+ struct net_device *dev); -+ int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev, -+@@ -288,6 +291,8 @@ int cfg80211_set_mesh_channel(struct cfg -+ struct cfg80211_chan_def *chandef); -+ -+ /* AP */ -++int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, -++ struct net_device *dev, bool notify); -+ int cfg80211_stop_ap(struct cfg80211_registered_device *rdev, -+ struct net_device *dev, bool notify); -+ -+@@ -441,6 +446,8 @@ int cfg80211_validate_beacon_int(struct -+ void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, -+ enum nl80211_iftype iftype, int num); -+ -++void __cfg80211_leave(struct cfg80211_registered_device *rdev, -++ struct wireless_dev *wdev); -+ void cfg80211_leave(struct cfg80211_registered_device *rdev, -+ struct wireless_dev *wdev); - +- -+ /* notify driver */ -+ err = sta_info_insert_drv_state(local, sdata, sta); -+ if (err) @@ -9187,26 +5818,13 @@ index a1af6c2..dc1e265 100644 - set_sta_flag(sta, WLAN_STA_INSERTED); -+ /* accept BA sessions now */ -+ clear_sta_flag(sta, WLAN_STA_BLOCK_BA); -+--- a/net/wireless/ibss.c -++++ b/net/wireless/ibss.c -+@@ -420,8 +420,8 @@ int cfg80211_ibss_wext_siwessid(struct n -+ if (len > 0 && ssid[len - 1] == '\0') -+ len--; - +- - ieee80211_recalc_min_chandef(sdata); - ieee80211_sta_debugfs_add(sta); -@@ -522,6 +537,12 @@ static int sta_info_insert_finish(struct - mesh_accept_plinks_update(sdata); -++ memcpy(wdev->ssid, ssid, len); -+ wdev->wext.ibss.ssid = wdev->ssid; -+- memcpy(wdev->wext.ibss.ssid, ssid, len); -+ wdev->wext.ibss.ssid_len = len; - -+ wdev_lock(wdev); -+--- a/net/wireless/mesh.c -++++ b/net/wireless/mesh.c -+@@ -238,8 +238,8 @@ int cfg80211_set_mesh_channel(struct cfg - return 0; +- +- return 0; -+ out_remove: -+ sta_info_hash_del(local, sta); -+ list_del_rcu(&sta->list); @@ -9217,17 +5835,13 @@ index a1af6c2..dc1e265 100644 - mutex_unlock(&local->sta_mtx); - rcu_read_lock(); -@@ -1071,10 +1092,14 @@ struct ieee80211_sta *ieee80211_find_sta - } +- } - EXPORT_SYMBOL(ieee80211_find_sta); - +- --static void clear_sta_ps_flags(void *_sta) -+/* powersave support code */ -+void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) -+-static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, -+- struct net_device *dev) -++int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, -++ struct net_device *dev) - { +- { -- struct sta_info *sta = _sta; - struct ieee80211_sub_if_data *sdata = sta->sdata; -+ struct ieee80211_local *local = sdata->local; @@ -9235,63 +5849,12 @@ index a1af6c2..dc1e265 100644 -+ int filtered = 0, buffered = 0, ac; -+ unsigned long flags; - struct ps_data *ps; -+ struct wireless_dev *wdev = dev->ieee80211_ptr; -+ int err; -+--- a/net/wireless/nl80211.c -++++ b/net/wireless/nl80211.c -+@@ -371,8 +371,8 @@ static const struct nla_policy nl80211_p -+ [NL80211_ATTR_CH_SWITCH_COUNT] = { .type = NLA_U32 }, -+ [NL80211_ATTR_CH_SWITCH_BLOCK_TX] = { .type = NLA_FLAG }, -+ [NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED }, -+- [NL80211_ATTR_CSA_C_OFF_BEACON] = { .type = NLA_U16 }, -+- [NL80211_ATTR_CSA_C_OFF_PRESP] = { .type = NLA_U16 }, -++ [NL80211_ATTR_CSA_C_OFF_BEACON] = { .type = NLA_BINARY }, -++ [NL80211_ATTR_CSA_C_OFF_PRESP] = { .type = NLA_BINARY }, -+ [NL80211_ATTR_STA_SUPPORTED_CHANNELS] = { .type = NLA_BINARY }, -+ [NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES] = { .type = NLA_BINARY }, -+ [NL80211_ATTR_HANDLE_DFS] = { .type = NLA_FLAG }, -+@@ -386,6 +386,7 @@ static const struct nla_policy nl80211_p -+ [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 }, -+ [NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 }, -+ [NL80211_ATTR_IFACE_SOCKET_OWNER] = { .type = NLA_FLAG }, -++ [NL80211_ATTR_CSA_C_OFFSETS_TX] = { .type = NLA_BINARY }, -+ }; - +- - if (sdata->vif.type == NL80211_IFTYPE_AP || -@@ -1085,20 +1110,6 @@ static void clear_sta_ps_flags(void *_st - else - return; -+ /* policy for the key attributes */ -+@@ -970,8 +971,10 @@ static int nl80211_put_iface_combination -+ c->max_interfaces)) -+ goto nla_put_failure; -+ if (large && -+- nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS, -+- c->radar_detect_widths)) -++ (nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS, -++ c->radar_detect_widths) || -++ nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_REGIONS, -++ c->radar_detect_regions))) -+ goto nla_put_failure; -+ -+ nla_nest_end(msg, nl_combi); -+@@ -1667,6 +1670,13 @@ static int nl80211_send_wiphy(struct cfg -+ } -+ nla_nest_end(msg, nested); -+ } -++ state->split_start++; -++ break; -++ case 12: -++ if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH && -++ nla_put_u8(msg, NL80211_ATTR_MAX_CSA_COUNTERS, -++ rdev->wiphy.max_num_csa_counters)) -++ goto nla_put_failure; -+ -+ /* done */ -+ state->split_start = 0; -+@@ -5825,7 +5835,7 @@ static int nl80211_start_radar_detection -+ return -EBUSY; - +- -- clear_sta_flag(sta, WLAN_STA_PS_DRIVER); -- if (test_and_clear_sta_flag(sta, WLAN_STA_PS_STA)) -- atomic_dec(&ps->num_sta_ps); @@ -9307,27 +5870,12 @@ index a1af6c2..dc1e265 100644 -- unsigned long flags; -- - clear_sta_flag(sta, WLAN_STA_SP); -+ err = cfg80211_chandef_dfs_required(wdev->wiphy, &chandef, -+- NL80211_IFTYPE_UNSPECIFIED); -++ wdev->iftype); -+ if (err < 0) -+ return err; - +- - BUILD_BUG_ON(BITS_TO_LONGS(IEEE80211_NUM_TIDS) > 1); -@@ -1109,6 +1120,8 @@ void ieee80211_sta_ps_deliver_wakeup(str -+@@ -5866,6 +5876,7 @@ static int nl80211_channel_switch(struct -+ u8 radar_detect_width = 0; -+ int err; -+ bool need_new_beacon = false; -++ int len, i; - +- - skb_queue_head_init(&pending); -+ if (!rdev->ops->channel_switch || -+ !(rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)) -+@@ -5924,26 +5935,55 @@ static int nl80211_channel_switch(struct -+ if (!csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]) -+ return -EINVAL; - +- -+ /* sync with ieee80211_tx_h_unicast_ps_buf */ -+ spin_lock(&sta->ps_lock); - /* Send all buffered frames to the station */ @@ -9336,13 +5884,7 @@ index a1af6c2..dc1e265 100644 -@@ -1127,7 +1140,12 @@ void ieee80211_sta_ps_deliver_wakeup(str - buffered += tmp - count; - } -+- params.counter_offset_beacon = -+- nla_get_u16(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]); -+- if (params.counter_offset_beacon >= params.beacon_csa.tail_len) -++ len = nla_len(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]); -++ if (!len || (len % sizeof(u16))) -+ return -EINVAL; - +- -- ieee80211_add_pending_skbs_fn(local, &pending, clear_sta_ps_flags, sta); -+ ieee80211_add_pending_skbs(local, &pending); -+ clear_sta_flag(sta, WLAN_STA_PS_DRIVER); @@ -9366,15 +5908,7 @@ index a1af6c2..dc1e265 100644 -@@ -356,10 +357,8 @@ struct sta_info { - /* use the accessors defined below */ - unsigned long _flags; -+- /* sanity check - counters should be the same */ -+- if (params.beacon_csa.tail[params.counter_offset_beacon] != -+- params.count) -++ params.n_counter_offsets_beacon = len / sizeof(u16); -++ if (rdev->wiphy.max_num_csa_counters && -++ (params.n_counter_offsets_beacon > -++ rdev->wiphy.max_num_csa_counters)) -+ return -EINVAL; - +- -- /* -- * STA powersave frame queues, no more than the internal -- * locking required. @@ -9389,29 +5923,7 @@ index a1af6c2..dc1e265 100644 -@@ -435,9 +435,8 @@ void ieee80211_add_pending_skb(struct ie - spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); - } -++ params.counter_offsets_beacon = -++ nla_data(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]); -++ -++ /* sanity checks - counters should fit and be the same */ -++ for (i = 0; i < params.n_counter_offsets_beacon; i++) { -++ u16 offset = params.counter_offsets_beacon[i]; -++ -++ if (offset >= params.beacon_csa.tail_len) -++ return -EINVAL; -++ -++ if (params.beacon_csa.tail[offset] != params.count) -++ return -EINVAL; -++ } -++ -+ if (csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]) { -+- params.counter_offset_presp = -+- nla_get_u16(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]); -+- if (params.counter_offset_presp >= -+- params.beacon_csa.probe_resp_len) -++ len = nla_len(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]); -++ if (!len || (len % sizeof(u16))) -+ return -EINVAL; - +- --void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local, -- struct sk_buff_head *skbs, -- void (*fn)(void *data), void *data) @@ -9422,30 +5934,8 @@ index a1af6c2..dc1e265 100644 - struct sk_buff *skb; -@@ -461,9 +460,6 @@ void ieee80211_add_pending_skbs_fn(struc - __skb_queue_tail(&local->pending[queue], skb); -+- if (params.beacon_csa.probe_resp[params.counter_offset_presp] != -+- params.count) -++ params.n_counter_offsets_presp = len / sizeof(u16); -++ if (rdev->wiphy.max_num_csa_counters && -++ (params.n_counter_offsets_beacon > -++ rdev->wiphy.max_num_csa_counters)) -+ return -EINVAL; -++ -++ params.counter_offsets_presp = -++ nla_data(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]); -++ -++ /* sanity checks - counters should fit and be the same */ -++ for (i = 0; i < params.n_counter_offsets_presp; i++) { -++ u16 offset = params.counter_offsets_presp[i]; -++ -++ if (offset >= params.beacon_csa.probe_resp_len) -++ return -EINVAL; -++ -++ if (params.beacon_csa.probe_resp[offset] != -++ params.count) -++ return -EINVAL; -++ } - } - +- } +- -- if (fn) -- fn(data); -- @@ -9503,11 +5993,7 @@ index a1af6c2..dc1e265 100644 -+ if (common->disable_ani) - goto exit; -- } -+ skip_beacons: -+@@ -7793,6 +7833,27 @@ static int nl80211_tx_mgmt(struct sk_buf -+ if (!chandef.chan && params.offchan) -+ return -EINVAL; - +- -- len += scnprintf(buf + len, size - len, "%15s: %s\n", -- "ANI", "ENABLED"); -- len += scnprintf(buf + len, size - len, "%15s: %u\n", @@ -9598,47 +6084,16 @@ index a1af6c2..dc1e265 100644 -+ */ -+ rs->rs_datalen = 0; -+ rs->rs_more = true; -++ params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]); -++ params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]); -++ -++ if (info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]) { -++ int len = nla_len(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]); -++ int i; -++ -++ if (len % sizeof(u16)) -++ return -EINVAL; -++ -++ params.n_csa_offsets = len / sizeof(u16); -++ params.csa_offsets = -++ nla_data(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]); -++ -++ /* check that all the offsets fit the frame */ -++ for (i = 0; i < params.n_csa_offsets; i++) { -++ if (params.csa_offsets[i] >= params.len) -++ return -EINVAL; - + } -++ } -++ -+ if (!params.dont_wait_for_ack) { -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); -+ if (!msg) -+@@ -7807,8 +7868,6 @@ static int nl80211_tx_mgmt(struct sk_buf -+ } - } - +-+ } +- } +- - list_del(&bf->list); -@@ -985,32 +992,32 @@ static int ath9k_rx_skb_preprocess(struc - struct ath_common *common = ath9k_hw_common(ah); - struct ieee80211_hdr *hdr; - bool discard_current = sc->rx.discard_next; -- int ret = 0; -+- params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]); -+- params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]); -+ params.chan = chandef.chan; -+ err = cfg80211_mlme_mgmt_tx(rdev, wdev, ¶ms, &cookie); -+ if (err) -+@@ -8507,6 +8566,8 @@ static int nl80211_set_wowlan(struct sk_ - +- - /* - * Discard corrupt descriptors which are marked in - * ath_get_next_rx_buf(). @@ -9647,10 +6102,7 @@ index a1af6c2..dc1e265 100644 - if (discard_current) -- return -EINVAL; -+ goto corrupt; -+ nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN], -+ rem) { -++ u8 *mask_pat; - + +-+ -+ sc->rx.discard_next = false; - - /* @@ -9661,38 +6113,7 @@ index a1af6c2..dc1e265 100644 -- return -EINVAL; -+ goto corrupt; - } -+ nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat), -+ nla_len(pat), NULL); -+ err = -EINVAL; -+@@ -8530,19 +8591,18 @@ static int nl80211_set_wowlan(struct sk_ -+ goto error; -+ new_triggers.patterns[i].pkt_offset = pkt_offset; -+ -+- new_triggers.patterns[i].mask = -+- kmalloc(mask_len + pat_len, GFP_KERNEL); -+- if (!new_triggers.patterns[i].mask) { -++ mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL); -++ if (!mask_pat) { -+ err = -ENOMEM; -+ goto error; -+ } -+- new_triggers.patterns[i].pattern = -+- new_triggers.patterns[i].mask + mask_len; -+- memcpy(new_triggers.patterns[i].mask, -+- nla_data(pat_tb[NL80211_PKTPAT_MASK]), -++ new_triggers.patterns[i].mask = mask_pat; -++ memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]), -+ mask_len); -++ mask_pat += mask_len; -++ new_triggers.patterns[i].pattern = mask_pat; -+ new_triggers.patterns[i].pattern_len = pat_len; -+- memcpy(new_triggers.patterns[i].pattern, -++ memcpy(mask_pat, -+ nla_data(pat_tb[NL80211_PKTPAT_PATTERN]), -+ pat_len); -+ i++; -+@@ -8735,6 +8795,8 @@ static int nl80211_parse_coalesce_rule(s - +- -- /* -- * rs_status follows rs_datalen so if rs_datalen is too large -- * we can take a hint that hardware corrupted it, so ignore @@ -9707,42 +6128,8 @@ index a1af6c2..dc1e265 100644 - RX_STAT_INC(rx_len_err); -- return -EINVAL; -+ goto corrupt; -+ nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN], -+ rem) { -++ u8 *mask_pat; -++ -+ nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat), -+ nla_len(pat), NULL); -+ if (!pat_tb[NL80211_PKTPAT_MASK] || -+@@ -8756,17 +8818,19 @@ static int nl80211_parse_coalesce_rule(s -+ return -EINVAL; -+ new_rule->patterns[i].pkt_offset = pkt_offset; -+ -+- new_rule->patterns[i].mask = -+- kmalloc(mask_len + pat_len, GFP_KERNEL); -+- if (!new_rule->patterns[i].mask) -++ mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL); -++ if (!mask_pat) -+ return -ENOMEM; -+- new_rule->patterns[i].pattern = -+- new_rule->patterns[i].mask + mask_len; -+- memcpy(new_rule->patterns[i].mask, -+- nla_data(pat_tb[NL80211_PKTPAT_MASK]), mask_len); -++ -++ new_rule->patterns[i].mask = mask_pat; -++ memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]), -++ mask_len); -++ -++ mask_pat += mask_len; -++ new_rule->patterns[i].pattern = mask_pat; -+ new_rule->patterns[i].pattern_len = pat_len; -+- memcpy(new_rule->patterns[i].pattern, -+- nla_data(pat_tb[NL80211_PKTPAT_PATTERN]), pat_len); -++ memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_PATTERN]), -++ pat_len); -+ i++; - } - +- } +- - /* Only use status info from the last fragment */ -@@ -1024,10 +1031,8 @@ static int ath9k_rx_skb_preprocess(struc - * This is different from the other corrupt descriptor @@ -9765,31 +6152,7 @@ index a1af6c2..dc1e265 100644 -- goto exit; -+ return -EINVAL; - } -+--- a/net/wireless/sme.c -++++ b/net/wireless/sme.c -+@@ -149,7 +149,8 @@ static int cfg80211_conn_do_work(struct -+ case CFG80211_CONN_SCAN_AGAIN: -+ return cfg80211_conn_scan(wdev); -+ case CFG80211_CONN_AUTHENTICATE_NEXT: -+- BUG_ON(!rdev->ops->auth); -++ if (WARN_ON(!rdev->ops->auth)) -++ return -EOPNOTSUPP; -+ wdev->conn->state = CFG80211_CONN_AUTHENTICATING; -+ return cfg80211_mlme_auth(rdev, wdev->netdev, -+ params->channel, params->auth_type, -+@@ -161,7 +162,8 @@ static int cfg80211_conn_do_work(struct -+ case CFG80211_CONN_AUTH_FAILED: -+ return -ENOTCONN; -+ case CFG80211_CONN_ASSOCIATE_NEXT: -+- BUG_ON(!rdev->ops->assoc); -++ if (WARN_ON(!rdev->ops->assoc)) -++ return -EOPNOTSUPP; -+ wdev->conn->state = CFG80211_CONN_ASSOCIATING; -+ if (wdev->conn->prev_bssid_valid) -+ req.prev_bssid = wdev->conn->prev_bssid; -+@@ -877,7 +879,7 @@ void __cfg80211_disconnected(struct net_ -+ } - +- - /* - * everything but the rate is checked here, the rate check is done - * separately to avoid doing two lookups for a rate for each frame. @@ -9800,56 +6163,7 @@ index a1af6c2..dc1e265 100644 -- } -+ if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error)) -+ return -EINVAL; -+ void cfg80211_disconnected(struct net_device *dev, u16 reason, -+- u8 *ie, size_t ie_len, gfp_t gfp) -++ const u8 *ie, size_t ie_len, gfp_t gfp) -+ { -+ struct wireless_dev *wdev = dev->ieee80211_ptr; -+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); -+--- a/net/wireless/trace.h -++++ b/net/wireless/trace.h -+@@ -1876,29 +1876,33 @@ TRACE_EVENT(rdev_channel_switch, -+ WIPHY_ENTRY -+ NETDEV_ENTRY -+ CHAN_DEF_ENTRY -+- __field(u16, counter_offset_beacon) -+- __field(u16, counter_offset_presp) -+ __field(bool, radar_required) -+ __field(bool, block_tx) -+ __field(u8, count) -++ __dynamic_array(u16, bcn_ofs, params->n_counter_offsets_beacon) -++ __dynamic_array(u16, pres_ofs, params->n_counter_offsets_presp) -+ ), -+ TP_fast_assign( -+ WIPHY_ASSIGN; -+ NETDEV_ASSIGN; -+ CHAN_DEF_ASSIGN(¶ms->chandef); -+- __entry->counter_offset_beacon = params->counter_offset_beacon; -+- __entry->counter_offset_presp = params->counter_offset_presp; -+ __entry->radar_required = params->radar_required; -+ __entry->block_tx = params->block_tx; -+ __entry->count = params->count; -++ memcpy(__get_dynamic_array(bcn_ofs), -++ params->counter_offsets_beacon, -++ params->n_counter_offsets_beacon * sizeof(u16)); -++ -++ /* probe response offsets are optional */ -++ if (params->n_counter_offsets_presp) -++ memcpy(__get_dynamic_array(pres_ofs), -++ params->counter_offsets_presp, -++ params->n_counter_offsets_presp * sizeof(u16)); -+ ), -+ TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT -+- ", block_tx: %d, count: %u, radar_required: %d" -+- ", counter offsets (beacon/presp): %u/%u", -++ ", block_tx: %d, count: %u, radar_required: %d", -+ WIPHY_PR_ARG, NETDEV_PR_ARG, CHAN_DEF_PR_ARG, -+- __entry->block_tx, __entry->count, __entry->radar_required, -+- __entry->counter_offset_beacon, -+- __entry->counter_offset_presp) -++ __entry->block_tx, __entry->count, __entry->radar_required) -+ ); - +- - if (ath_is_mybeacon(common, hdr)) { - RX_STAT_INC(rx_beacons); -@@ -1064,15 +1066,11 @@ static int ath9k_rx_skb_preprocess(struc @@ -9862,127 +6176,30 @@ index a1af6c2..dc1e265 100644 -- } -+ if (WARN_ON(!ah->curchan)) -+ return -EINVAL; -+ TRACE_EVENT(rdev_set_qos_map, -+@@ -2636,6 +2640,21 @@ TRACE_EVENT(cfg80211_ft_event, -+ WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(target_ap)) -+ ); - +- -- if (ath9k_process_rate(common, hw, rx_stats, rx_status)) { -- ret =-EINVAL; -- goto exit; -- } -+ if (ath9k_process_rate(common, hw, rx_stats, rx_status)) -+ return -EINVAL; -++TRACE_EVENT(cfg80211_stop_iface, -++ TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev), -++ TP_ARGS(wiphy, wdev), -++ TP_STRUCT__entry( -++ WIPHY_ENTRY -++ WDEV_ENTRY -++ ), -++ TP_fast_assign( -++ WIPHY_ASSIGN; -++ WDEV_ASSIGN; -++ ), -++ TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT, -++ WIPHY_PR_ARG, WDEV_PR_ARG) -++); -++ -+ #endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */ - +- - ath9k_process_rssi(common, hw, rx_stats, rx_status); -+ #undef TRACE_INCLUDE_PATH -+--- a/net/wireless/util.c -++++ b/net/wireless/util.c -+@@ -476,7 +476,8 @@ int ieee80211_data_to_8023(struct sk_buf -+ EXPORT_SYMBOL(ieee80211_data_to_8023); - +- -@@ -1087,9 +1085,11 @@ static int ath9k_rx_skb_preprocess(struc - sc->rx.num_pkts++; - #endif -+ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, -+- enum nl80211_iftype iftype, u8 *bssid, bool qos) -++ enum nl80211_iftype iftype, -++ const u8 *bssid, bool qos) -+ { -+ struct ieee80211_hdr hdr; -+ u16 hdrlen, ethertype; -+@@ -839,6 +840,9 @@ void cfg80211_process_wdev_events(struct -+ __cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid, -+ ev->ij.channel); -+ break; -++ case EVENT_STOPPED: -++ __cfg80211_leave(wiphy_to_rdev(wdev->wiphy), wdev); -++ break; -+ } -+ wdev_unlock(wdev); - +- --exit: -- sc->rx.discard_next = false; -- return ret; -+ return 0; -+@@ -1271,10 +1275,20 @@ int cfg80211_iter_combinations(struct wi -+ void *data), -+ void *data) -+ { -++ const struct ieee80211_regdomain *regdom; -++ enum nl80211_dfs_regions region = 0; -+ int i, j, iftype; -+ int num_interfaces = 0; -+ u32 used_iftypes = 0; -+ -++ if (radar_detect) { -++ rcu_read_lock(); -++ regdom = rcu_dereference(cfg80211_regdomain); -++ if (regdom) -++ region = regdom->dfs_region; -++ rcu_read_unlock(); -++ } - + +-+ -+corrupt: -+ sc->rx.discard_next = rx_stats->rs_more; -+ return -EINVAL; -+ for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { -+ num_interfaces += iftype_num[iftype]; -+ if (iftype_num[iftype] > 0 && -+@@ -1315,6 +1329,10 @@ int cfg80211_iter_combinations(struct wi -+ if (radar_detect != (c->radar_detect_widths & radar_detect)) -+ goto cont; -+ -++ if (radar_detect && c->radar_detect_regions && -++ !(c->radar_detect_regions & BIT(region))) -++ goto cont; -++ -+ /* Finally check that all iftypes that we're currently -+ * using are actually part of this combination. If they -+ * aren't then we can't use this combination and have -+--- a/drivers/net/wireless/ath/ath9k/recv.c -++++ b/drivers/net/wireless/ath/ath9k/recv.c -+@@ -34,7 +34,8 @@ static inline bool ath9k_check_auto_slee -+ * buffer (or rx fifo). This can incorrectly acknowledge packets -+ * to a sender if last desc is self-linked. -+ */ -+-static void ath_rx_buf_link(struct ath_softc *sc, struct ath_rxbuf *bf) -++static void ath_rx_buf_link(struct ath_softc *sc, struct ath_rxbuf *bf, -++ bool flush) -+ { -+ struct ath_hw *ah = sc->sc_ah; -+ struct ath_common *common = ath9k_hw_common(ah); -+@@ -59,18 +60,19 @@ static void ath_rx_buf_link(struct ath_s -+ common->rx_bufsize, -+ 0); -+ -+- if (sc->rx.rxlink == NULL) -+- ath9k_hw_putrxbuf(ah, bf->bf_daddr); -+- else -++ if (sc->rx.rxlink) -+ *sc->rx.rxlink = bf->bf_daddr; -++ else if (!flush) -++ ath9k_hw_putrxbuf(ah, bf->bf_daddr); -+ -+ sc->rx.rxlink = &ds->ds_link; - } - +- } +- - static void ath9k_rx_skb_postprocess(struct ath_common *common, ---- a/drivers/net/wireless/ath/ath9k/ani.c -+++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -10018,14 +6235,7 @@ index a1af6c2..dc1e265 100644 -+ -+ if (!AR_SREV_9300_20_OR_LATER(ah)) -+ return; -+-static void ath_rx_buf_relink(struct ath_softc *sc, struct ath_rxbuf *bf) -++static void ath_rx_buf_relink(struct ath_softc *sc, struct ath_rxbuf *bf, -++ bool flush) -+ { -+ if (sc->rx.buf_hold) -+- ath_rx_buf_link(sc, sc->rx.buf_hold); -++ ath_rx_buf_link(sc, sc->rx.buf_hold, flush); - +- - if (aniState->ofdmNoiseImmunityLevel >= ATH9K_ANI_OFDM_DEF_LEVEL) { - ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH; -@@ -308,17 +318,6 @@ void ath9k_ani_reset(struct ath_hw *ah, @@ -10065,16 +6275,7 @@ index a1af6c2..dc1e265 100644 -+ ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_OLD; -+ ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_OLD; -+ } -+ sc->rx.buf_hold = bf; -+ } -+@@ -442,7 +444,7 @@ int ath_startrecv(struct ath_softc *sc) -+ sc->rx.buf_hold = NULL; -+ sc->rx.rxlink = NULL; -+ list_for_each_entry_safe(bf, tbf, &sc->rx.rxbuf, list) { -+- ath_rx_buf_link(sc, bf); -++ ath_rx_buf_link(sc, bf, false); -+ } - +- - ani->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL; - ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL; ---- a/drivers/net/wireless/ath/ath9k/ani.h @@ -10216,7 +6417,7 @@ index a1af6c2..dc1e265 100644 -+ if (IS_CHAN_HT40(ah->curchan)) -+ REG_RMW_FIELD(ah, AR_PHY_EXT_CCA, -+ AR_PHY_EXT_TIMING5_CYCPWR_THR1, value); -- + - if (level != aniState->spurImmunityLevel) { - ath_dbg(common, ANI, -@@ -1124,7 +1059,7 @@ static bool ar5008_hw_ani_control_new(st @@ -10228,33 +6429,15 @@ index a1af6c2..dc1e265 100644 - aniState->iniDef.cycpwrThr1Ext); - if (level > aniState->spurImmunityLevel) - ah->stats.ast_ani_spurup++; -+ /* We could have deleted elements so the list may be empty now */ -+@@ -1118,12 +1120,12 @@ requeue_drop_frag: -+ requeue: -+ list_add_tail(&bf->list, &sc->rx.rxbuf); -+ -+- if (edma) { -+- ath_rx_edma_buf_link(sc, qtype); -+- } else { -+- ath_rx_buf_relink(sc, bf); -++ if (!edma) { -++ ath_rx_buf_relink(sc, bf, flush); -+ if (!flush) -+ ath9k_hw_rxena(ah); -++ } else if (!flush) { -++ ath_rx_edma_buf_link(sc, qtype); -+ } -+ -+ if (!budget--) diff --git a/package/mac80211/patches/310-ap_scan.patch b/package/mac80211/patches/310-ap_scan.patch -index 389a003..a12e7e5 100644 +index 389a003..9334e4d 100644 --- a/package/mac80211/patches/310-ap_scan.patch +++ b/package/mac80211/patches/310-ap_scan.patch @@ -1,6 +1,6 @@ --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -2148,7 +2148,7 @@ static int ieee80211_scan(struct wiphy * -+@@ -2197,7 +2197,7 @@ static int ieee80211_scan(struct wiphy * ++@@ -2210,7 +2210,7 @@ static int ieee80211_scan(struct wiphy * * the frames sent while scanning on other channel will be * lost) */ @@ -10285,14 +6468,14 @@ index 07c54cc..808e729 100644 ATH_CARDS= ATH_DEBUG= diff --git a/package/mac80211/patches/405-regd_no_assoc_hints.patch b/package/mac80211/patches/405-regd_no_assoc_hints.patch -index 6ad4fda..ef60f9e 100644 +index 6ad4fda..2152433 100644 --- a/package/mac80211/patches/405-regd_no_assoc_hints.patch +++ b/package/mac80211/patches/405-regd_no_assoc_hints.patch @@ -1,6 +1,6 @@ --- a/net/wireless/reg.c +++ b/net/wireless/reg.c -@@ -1878,6 +1878,8 @@ void regulatory_hint_country_ie(struct w -+@@ -2079,6 +2079,8 @@ void regulatory_hint_country_ie(struct w ++@@ -2080,6 +2080,8 @@ void regulatory_hint_country_ie(struct w enum environment_cap env = ENVIRON_ANY; struct regulatory_request *request = NULL, *lr; @@ -10301,7 +6484,7 @@ index 6ad4fda..ef60f9e 100644 if (country_ie_len & 0x01) return; -@@ -2072,6 +2074,7 @@ static void restore_regulatory_settings( -+@@ -2275,6 +2277,7 @@ static void restore_regulatory_settings( ++@@ -2276,6 +2278,7 @@ static void restore_regulatory_settings( void regulatory_hint_disconnect(void) { @@ -10352,6 +6535,28 @@ index 3487ab2..1f06994 100644 BIT(NL80211_IFTYPE_MESH_POINT) | #endif BIT(NL80211_IFTYPE_AP) }, +diff --git a/package/mac80211/patches/431-add_platform_eeprom_support_to_ath5k.patch b/package/mac80211/patches/431-add_platform_eeprom_support_to_ath5k.patch +index a223b38..5cb4b51 100644 +--- a/package/mac80211/patches/431-add_platform_eeprom_support_to_ath5k.patch ++++ b/package/mac80211/patches/431-add_platform_eeprom_support_to_ath5k.patch +@@ -22,14 +22,14 @@ + u32 status, timeout; + + + struct ath5k_platform_data *pdata = NULL; +-+ +++ + + if (ah->pdev) + + pdata = ah->pdev->dev.platform_data; + + + + if (pdata && pdata->eeprom_data && pdata->eeprom_data[61] == AR5K_EEPROM_MAGIC_VALUE) { +-+ if (offset >= ATH5K_PLAT_EEP_MAX_WORDS) +++ if (offset >= ATH5K_PLAT_EEP_MAX_WORDS) + + return false; +-+ +++ + + *data = pdata->eeprom_data[offset]; + + return true; + + } diff --git a/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch b/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch index 664cf45..65821fe 100644 --- a/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch @@ -10502,7 +6707,7 @@ index 8f3cc03..c0e173f 100644 { struct ieee80211_channel *curchan = chandef->chan; diff --git a/package/mac80211/patches/520-mac80211_cur_txpower.patch b/package/mac80211/patches/520-mac80211_cur_txpower.patch -index 6df95bc..b79a3c4 100644 +index 6df95bc..68320a0 100644 --- a/package/mac80211/patches/520-mac80211_cur_txpower.patch +++ b/package/mac80211/patches/520-mac80211_cur_txpower.patch @@ -1,6 +1,6 @@ @@ -10518,7 +6723,7 @@ index 6df95bc..b79a3c4 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -2329,7 +2329,9 @@ static int ieee80211_get_tx_power(struct -+@@ -2378,7 +2378,9 @@ static int ieee80211_get_tx_power(struct ++@@ -2391,7 +2391,9 @@ static int ieee80211_get_tx_power(struct struct ieee80211_local *local = wiphy_priv(wiphy); struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); @@ -10532,7 +6737,7 @@ index 6df95bc..b79a3c4 100644 if (local->hw.conf.power_level != power) { changed |= IEEE80211_CONF_CHANGE_POWER; diff --git a/package/mac80211/patches/521-ath9k_cur_txpower.patch b/package/mac80211/patches/521-ath9k_cur_txpower.patch -index 0d6c360..3564323 100644 +index 0d6c360..83ff465 100644 --- a/package/mac80211/patches/521-ath9k_cur_txpower.patch +++ b/package/mac80211/patches/521-ath9k_cur_txpower.patch @@ -1,6 +1,6 @@ @@ -10548,19 +6753,19 @@ index 0d6c360..3564323 100644 out: spin_unlock_bh(&sc->sc_pcu_lock); -@@ -1371,6 +1375,7 @@ static int ath9k_config(struct ieee80211 -+@@ -1404,6 +1408,7 @@ static int ath9k_config(struct ieee80211 ++@@ -1405,6 +1409,7 @@ static int ath9k_config(struct ieee80211 sc->config.txpowlimit = 2 * conf->power_level; ath9k_cmn_update_txpow(ah, sc->curtxpow, sc->config.txpowlimit, &sc->curtxpow); diff --git a/package/mac80211/patches/522-mac80211_configure_antenna_gain.patch b/package/mac80211/patches/522-mac80211_configure_antenna_gain.patch -index 308ee6e..6ad04ac 100644 +index 308ee6e..284d134 100644 --- a/package/mac80211/patches/522-mac80211_configure_antenna_gain.patch +++ b/package/mac80211/patches/522-mac80211_configure_antenna_gain.patch @@ -1,6 +1,6 @@ --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h -@@ -2156,6 +2156,7 @@ struct cfg80211_qos_map { -+@@ -2188,6 +2188,7 @@ struct cfg80211_qos_map { ++@@ -2207,6 +2207,7 @@ struct cfg80211_qos_map { * (as advertised by the nl80211 feature flag.) * @get_tx_power: store the current TX power into the dbm variable; * return 0 if successful @@ -10569,7 +6774,7 @@ index 308ee6e..6ad04ac 100644 * @set_wds_peer: set the WDS peer for a WDS interface * -@@ -2380,6 +2381,7 @@ struct cfg80211_ops { -+@@ -2422,6 +2423,7 @@ struct cfg80211_ops { ++@@ -2441,6 +2442,7 @@ struct cfg80211_ops { enum nl80211_tx_power_setting type, int mbm); int (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev, int *dbm); @@ -10622,7 +6827,7 @@ index 308ee6e..6ad04ac 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -2339,6 +2339,19 @@ static int ieee80211_get_tx_power(struct -+@@ -2388,6 +2388,19 @@ static int ieee80211_get_tx_power(struct ++@@ -2401,6 +2401,19 @@ static int ieee80211_get_tx_power(struct return 0; } @@ -10631,7 +6836,7 @@ index 308ee6e..6ad04ac 100644 const u8 *addr) { -@@ -3924,6 +3937,7 @@ struct cfg80211_ops mac80211_config_ops -+@@ -3820,6 +3833,7 @@ const struct cfg80211_ops mac80211_confi ++@@ -3832,6 +3845,7 @@ const struct cfg80211_ops mac80211_confi .set_wiphy_params = ieee80211_set_wiphy_params, .set_tx_power = ieee80211_set_tx_power, .get_tx_power = ieee80211_get_tx_power, @@ -10733,7 +6938,7 @@ index 308ee6e..6ad04ac 100644 + if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] && diff --git a/package/mac80211/patches/523-ath9k_use_configured_antenna_gain.patch b/package/mac80211/patches/523-ath9k_use_configured_antenna_gain.patch -index 30aa9ee..aaefa2f 100644 +index 30aa9ee..0b28ab8 100644 --- a/package/mac80211/patches/523-ath9k_use_configured_antenna_gain.patch +++ b/package/mac80211/patches/523-ath9k_use_configured_antenna_gain.patch @@ -1,6 +1,6 @@ @@ -10749,20 +6954,28 @@ index 30aa9ee..aaefa2f 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c -@@ -1371,7 +1371,10 @@ static int ath9k_config(struct ieee80211 -+@@ -1404,7 +1404,10 @@ static int ath9k_config(struct ieee80211 ++@@ -1405,7 +1405,10 @@ static int ath9k_config(struct ieee80211 } if (changed & IEEE80211_CONF_CHANGE_POWER) { diff --git a/package/mac80211/patches/530-ath9k_extra_leds.patch b/package/mac80211/patches/530-ath9k_extra_leds.patch -index 59f78d9..4cf0700 100644 +index 59f78d9..b5f2f8b 100644 --- a/package/mac80211/patches/530-ath9k_extra_leds.patch +++ b/package/mac80211/patches/530-ath9k_extra_leds.patch +@@ -1,6 +1,6 @@ + --- a/drivers/net/wireless/ath/ath9k/ath9k.h + +++ b/drivers/net/wireless/ath/ath9k/ath9k.h +-@@ -563,6 +563,9 @@ static inline int ath9k_dump_btcoex(stru ++@@ -564,6 +564,9 @@ static inline int ath9k_dump_btcoex(stru + void ath_init_leds(struct ath_softc *sc); + void ath_deinit_leds(struct ath_softc *sc); + void ath_fill_led_pin(struct ath_softc *sc); @@ -10,7 +10,7 @@ #else static inline void ath_init_leds(struct ath_softc *sc) { -@@ -710,6 +713,13 @@ enum sc_op_flags { -+@@ -701,6 +704,13 @@ void ath_ant_comb_scan(struct ath_softc ++@@ -702,6 +705,13 @@ void ath_ant_comb_scan(struct ath_softc #define PS_BEACON_SYNC BIT(4) #define PS_WAIT_FOR_ANI BIT(5) @@ -10772,7 +6985,7 @@ index 59f78d9..4cf0700 100644 struct device *dev; -@@ -751,9 +761,8 @@ struct ath_softc { - struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; -+@@ -743,9 +753,8 @@ struct ath_softc { ++@@ -744,9 +754,8 @@ struct ath_softc { + struct ath_beacon beacon; #ifdef CPTCFG_MAC80211_LEDS @@ -10822,7 +7035,7 @@ index 6c9832c..718a3d0 100644 + int num_leds; + const struct gpio_led *leds; diff --git a/package/mac80211/patches/542-ath9k_debugfs_diag.patch b/package/mac80211/patches/542-ath9k_debugfs_diag.patch -index e1b6ff1..764e5e2 100644 +index e1b6ff1..2a56352 100644 --- a/package/mac80211/patches/542-ath9k_debugfs_diag.patch +++ b/package/mac80211/patches/542-ath9k_debugfs_diag.patch @@ -1,6 +1,6 @@ @@ -10847,7 +7060,7 @@ index e1b6ff1..764e5e2 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c -@@ -602,6 +602,11 @@ irqreturn_t ath_isr(int irq, void *dev) -+@@ -605,6 +605,11 @@ irqreturn_t ath_isr(int irq, void *dev) ++@@ -606,6 +606,11 @@ irqreturn_t ath_isr(int irq, void *dev) ath9k_debug_sync_cause(sc, sync_cause); status &= ah->imask; /* discard unasked-for bits */ @@ -14470,20 +10683,18 @@ index f9186d8..ee473dc 100644 rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY); diff --git a/package/mac80211/patches/620-rt2x00-rt3352-rf-id.patch b/package/mac80211/patches/620-rt2x00-rt3352-rf-id.patch -index 5e67344..86a990c 100644 +index 5e67344..05bcd58 100644 --- a/package/mac80211/patches/620-rt2x00-rt3352-rf-id.patch +++ b/package/mac80211/patches/620-rt2x00-rt3352-rf-id.patch -@@ -1,15 +1,11 @@ +@@ -1,6 +1,6 @@ --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c -@@ -7186,10 +7186,11 @@ static int rt2800_init_eeprom(struct rt2 -- * RT53xx: defined in "EEPROM_CHIP_ID" field -- */ -- if (rt2x00_rt(rt2x00dev, RT3290) || --- rt2x00_rt(rt2x00dev, RT3352) || -+@@ -7812,6 +7812,8 @@ static int rt2800_init_eeprom(struct rt2 - rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) ++@@ -7808,10 +7808,11 @@ static int rt2800_init_eeprom(struct rt2 + * RT53xx: defined in "EEPROM_CHIP_ID" field + */ + if (rt2x00_rt(rt2x00dev, RT3290) || +@@ -10,6 +10,6 @@ rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf); + else if (rt2x00_rt(rt2x00dev, RT3352)) + rf = RF3322; @@ -14505,7 +10716,7 @@ index 484c075..ae7e927 100644 static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = { diff --git a/package/mac80211/patches/800-b43-gpio-mask-module-option.patch b/package/mac80211/patches/800-b43-gpio-mask-module-option.patch -index fc874ad..e4d2f44 100644 +index fc874ad..7c56369 100644 --- a/package/mac80211/patches/800-b43-gpio-mask-module-option.patch +++ b/package/mac80211/patches/800-b43-gpio-mask-module-option.patch @@ -22,7 +22,7 @@ @@ -14513,12 +10724,12 @@ index fc874ad..e4d2f44 100644 module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444); MODULE_PARM_DESC(bad_frames_preempt, -@@ -2747,10 +2752,10 @@ static int b43_gpio_init(struct b43_wlde -+@@ -2739,10 +2744,10 @@ static int b43_gpio_init(struct b43_wlde ++@@ -2749,10 +2754,10 @@ static int b43_gpio_init(struct b43_wlde u32 mask, set; b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0); diff --git a/package/mac80211/patches/810-b43_no_pio.patch b/package/mac80211/patches/810-b43_no_pio.patch -index 5cd1b8b..bc9fda2 100644 +index 5cd1b8b..2023bf6 100644 --- a/package/mac80211/patches/810-b43_no_pio.patch +++ b/package/mac80211/patches/810-b43_no_pio.patch @@ -11,7 +11,7 @@ @@ -14526,7 +10737,7 @@ index 5cd1b8b..bc9fda2 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c -@@ -1915,10 +1915,12 @@ static void b43_do_interrupt_thread(stru -+@@ -1899,10 +1899,12 @@ static void b43_do_interrupt_thread(stru ++@@ -1909,10 +1909,12 @@ static void b43_do_interrupt_thread(stru dma_reason[0], dma_reason[1], dma_reason[2], dma_reason[3], dma_reason[4], dma_reason[5]); @@ -14546,14 +10757,14 @@ index 5cd1b8b..bc9fda2 100644 select SSB_BLOCKIO default y diff --git a/package/mac80211/patches/820-b43-add-antenna-control.patch b/package/mac80211/patches/820-b43-add-antenna-control.patch -index dea9830..b55c669 100644 +index dea9830..5a23967 100644 --- a/package/mac80211/patches/820-b43-add-antenna-control.patch +++ b/package/mac80211/patches/820-b43-add-antenna-control.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c -@@ -1562,7 +1562,7 @@ static void b43_write_beacon_template(st -+@@ -1546,7 +1546,7 @@ static void b43_write_beacon_template(st ++@@ -1556,7 +1556,7 @@ static void b43_write_beacon_template(st len, ram_offset, shm_size_offset, rate); /* Write the PHY TX control parameters. */ @@ -14562,7 +10773,7 @@ index dea9830..b55c669 100644 ctl = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL); /* We can't send beacons with short preamble. Would get PHY errors. */ -@@ -3105,8 +3105,8 @@ static int b43_chip_init(struct b43_wlde -+@@ -3103,8 +3103,8 @@ static int b43_chip_init(struct b43_wlde ++@@ -3113,8 +3113,8 @@ static int b43_chip_init(struct b43_wlde /* Select the antennae */ if (phy->ops->set_rx_antenna) @@ -14571,7 +10782,7 @@ index dea9830..b55c669 100644 if (phy->type == B43_PHYTYPE_B) { value16 = b43_read16(dev, 0x005E); -@@ -3850,7 +3850,6 @@ static int b43_op_config(struct ieee8021 -+@@ -3796,7 +3796,6 @@ static int b43_op_config(struct ieee8021 ++@@ -3806,7 +3806,6 @@ static int b43_op_config(struct ieee8021 struct b43_wldev *dev; struct b43_phy *phy; struct ieee80211_conf *conf = &hw->conf; @@ -14580,7 +10791,7 @@ index dea9830..b55c669 100644 bool reload_bss = false; -@@ -3904,11 +3903,9 @@ static int b43_op_config(struct ieee8021 -+@@ -3850,11 +3849,9 @@ static int b43_op_config(struct ieee8021 ++@@ -3860,11 +3859,9 @@ static int b43_op_config(struct ieee8021 } /* Antennas for RX and management frame TX. */ @@ -14589,7 +10800,7 @@ index dea9830..b55c669 100644 if (wl->radio_enabled != phy->radio_on) { if (wl->radio_enabled) { -@@ -5041,6 +5038,47 @@ static int b43_op_get_survey(struct ieee -+@@ -4978,6 +4975,47 @@ static int b43_op_get_survey(struct ieee ++@@ -4988,6 +4985,47 @@ static int b43_op_get_survey(struct ieee return 0; } @@ -14598,7 +10809,7 @@ index dea9830..b55c669 100644 .tx = b43_op_tx, .conf_tx = b43_op_conf_tx, -@@ -5062,6 +5100,8 @@ static const struct ieee80211_ops b43_hw -+@@ -4999,6 +5037,8 @@ static const struct ieee80211_ops b43_hw ++@@ -5009,6 +5047,8 @@ static const struct ieee80211_ops b43_hw .sw_scan_complete = b43_op_sw_scan_complete_notifier, .get_survey = b43_op_get_survey, .rfkill_poll = b43_rfkill_poll, @@ -14607,7 +10818,7 @@ index dea9830..b55c669 100644 /* Hard-reset the chip. Do not call this directly. -@@ -5308,6 +5348,8 @@ static int b43_one_core_attach(struct b4 -+@@ -5239,6 +5279,8 @@ static int b43_one_core_attach(struct b4 ++@@ -5295,6 +5335,8 @@ static int b43_one_core_attach(struct b4 if (!wldev) goto out; @@ -14616,12 +10827,12 @@ index dea9830..b55c669 100644 wldev->dev = dev; wldev->wl = wl; -@@ -5398,6 +5440,9 @@ static struct b43_wl *b43_wireless_init( -+@@ -5329,6 +5371,9 @@ static struct b43_wl *b43_wireless_init( ++@@ -5385,6 +5427,9 @@ static struct b43_wl *b43_wireless_init( hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; diff --git a/package/mac80211/patches/830-b43-workaround-pcie-bcm4716.patch b/package/mac80211/patches/830-b43-workaround-pcie-bcm4716.patch -index e76758c..86b61fc 100644 +index e76758c..49b2468 100644 --- a/package/mac80211/patches/830-b43-workaround-pcie-bcm4716.patch +++ b/package/mac80211/patches/830-b43-workaround-pcie-bcm4716.patch @@ -19,7 +19,7 @@ Signed-off-by: Hauke Mehrtens @@ -14651,7 +10862,7 @@ index e76758c..86b61fc 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c -@@ -4437,7 +4437,7 @@ static int b43_phy_versioning(struct b43 -+@@ -4370,7 +4370,7 @@ static int b43_phy_versioning(struct b43 ++@@ -4380,7 +4380,7 @@ static int b43_phy_versioning(struct b43 u16 radio24[3]; for (tmp = 0; tmp < 3; tmp++) { @@ -14660,7 +10871,7 @@ index e76758c..86b61fc 100644 } -@@ -4456,10 +4456,10 @@ static int b43_phy_versioning(struct b43 -+@@ -4389,10 +4389,10 @@ static int b43_phy_versioning(struct b43 ++@@ -4399,10 +4399,10 @@ static int b43_phy_versioning(struct b43 else tmp = 0x5205017F; } else { @@ -14713,14 +10924,14 @@ index e76758c..86b61fc 100644 B43_WARN_ON(reg == 1); diff --git a/package/mac80211/patches/845-b43-only-use-gpio-0-1-for-led.patch b/package/mac80211/patches/845-b43-only-use-gpio-0-1-for-led.patch -index 50347cd..8555ccf 100644 +index 50347cd..efc3451 100644 --- a/package/mac80211/patches/845-b43-only-use-gpio-0-1-for-led.patch +++ b/package/mac80211/patches/845-b43-only-use-gpio-0-1-for-led.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c -@@ -2764,6 +2764,14 @@ static int b43_gpio_init(struct b43_wlde -+@@ -2756,6 +2756,14 @@ static int b43_gpio_init(struct b43_wlde ++@@ -2766,6 +2766,14 @@ static int b43_gpio_init(struct b43_wlde } else if (dev->dev->chip_id == 0x5354) { /* Don't allow overtaking buttons GPIOs */ set &= 0x2; /* 0x2 is LED GPIO on BCM5354 */