-commit b9f268b5b01331c3c82179abca551429450e9417
-Author: Michal Kazior <michal.kazior@tieto.com>
-Date: Wed Jan 29 14:22:27 2014 +0100
+commit 230ab8c1880266c9cfceac962e2d48309dea79a7
+Author: Felix Fietkau <nbd@openwrt.org>
+Date: Mon May 19 21:48:56 2014 +0200
- cfg80211: consider existing DFS interfaces
+ ath9k: re-schedule rx processing after budget exceeded
- It was possible to break interface combinations in
- the following way:
+ Should improve rx stability under load
- combo 1: iftype = AP, num_ifaces = 2, num_chans = 2,
- combo 2: iftype = AP, num_ifaces = 1, num_chans = 1, radar = HT20
-
- With the above interface combinations it was
- possible to:
-
- step 1. start AP on DFS channel by matching combo 2
- step 2. start AP on non-DFS channel by matching combo 1
-
- This was possible beacuse (step 2) did not consider
- if other interfaces require radar detection.
-
- The patch changes how cfg80211 tracks channels -
- instead of channel itself now a complete chandef
- is stored.
-
- Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
- Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-
-commit bc9c62f5f511cc395c62dbf4cdd437f23db53b28
-Author: Antonio Quartulli <antonio@open-mesh.com>
-Date: Wed Jan 29 17:53:43 2014 +0100
-
- cfg80211: fix channel configuration in IBSS join
-
- When receiving an IBSS_JOINED event select the BSS object
- based on the {bssid, channel} couple rather than the bssid
- only.
- With the current approach if another cell having the same
- BSSID (but using a different channel) exists then cfg80211
- picks up the wrong BSS object.
- The result is a mismatching channel configuration between
- cfg80211 and the driver, that can lead to any sort of
- problem.
-
- 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.
- By passing the channel to cfg80211_get_bss() we can solve
- this ambiguity and retrieve/create the correct BSS object.
- All the users of cfg80211_ibss_joined() have been changed
- accordingly.
-
- 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
- cfg80211_ibss_joined() with a zero BSSID on ibss-leave).
-
- Cc: Kalle Valo <kvalo@qca.qualcomm.com>
- Cc: Arend van Spriel <arend@broadcom.com>
- Cc: Bing Zhao <bzhao@marvell.com>
- Cc: Jussi Kivilinna <jussi.kivilinna@iki.fi>
- Cc: libertas-dev@lists.infradead.org
- Acked-by: Kalle Valo <kvalo@qca.qualcomm.com>
- Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
- [minor code cleanup in ath6kl]
- Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-
-commit 7e0c41cb41f215aba2c39b1c237bb4d42ec49a85
-Author: Johannes Berg <johannes.berg@intel.com>
-Date: Fri Jan 24 14:41:44 2014 +0100
-
- mac80211: fix bufferable MMPDU RX handling
-
- 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.
-
- 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.
-
- Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-
-commit fc0df6d2343636e3f48a069330d5b972e3d8659d
-Author: Janusz Dziedzic <janusz.dziedzic@tieto.com>
-Date: Fri Jan 24 14:29:21 2014 +0100
-
- cfg80211: set preset_chandef after channel switch
-
- Set preset_chandef in channel switch notification.
- In other case we will have old preset_chandef.
-
- Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
- Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-
-commit cdec895e2344987ff171cece96e25d7407a3ebf6
-Author: Simon Wunderlich <simon@open-mesh.com>
-Date: Fri Jan 24 23:48:29 2014 +0100
-
- mac80211: send ibss probe responses with noack flag
-
- 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.
-
- Signed-off-by: Simon Wunderlich <simon@open-mesh.com>
- [fix typo & 'wildcard SSID' in commit log]
- Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-
-commit 0b865d1e6b9c05052adae9315df7cb195dc60c3b
-Author: Luciano Coelho <luciano.coelho@intel.com>
-Date: Tue Jan 28 17:09:08 2014 +0200
-
- mac80211: ibss: remove unnecessary call to release channel
-
- 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().
-
- Signed-off-by: Luciano Coelho <luciano.coelho@intel.com>
- Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-commit e1b6c17e971f0a51ff86c2dac2584c63cd999cd7
-Author: Michal Kazior <michal.kazior@tieto.com>
-Date: Wed Jan 29 07:56:21 2014 +0100
+commit 27647baeaee1b12bc3c57ccf1c7eba53bcd7fe53
+Author: Felix Fietkau <nbd@openwrt.org>
+Date: Mon May 19 21:20:49 2014 +0200
- mac80211: add missing CSA locking
+ ath9k: avoid passing buffers to the hardware during flush
- The patch adds a missing sdata lock and adds a few
- lockdeps for easier maintenance.
+ 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: Michal Kazior <michal.kazior@tieto.com>
- Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-commit ad17ba7d14d225b109b73c177cd446afb8050598
-Author: Michal Kazior <michal.kazior@tieto.com>
-Date: Wed Jan 29 07:56:20 2014 +0100
+commit 92e9dd662542683856e62a5e7e43fcf5b9da5c4a
+Author: Henning Rogge <hrogge@gmail.com>
+Date: Thu May 1 10:03:46 2014 +0200
- mac80211: fix sdata->radar_required locking
+ mac80211: Fix mac80211 station info rx bitrate for IBSS mode
- radar_required setting wasn't protected by
- local->mtx in some places. This should prevent
- from scanning/radar detection/roc colliding.
+ Filter out incoming multicast packages before applying their bitrate
+ to the rx bitrate station info field to prevent them from setting the
+ rx bitrate to the basic multicast rate.
- Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
- Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Henning Rogge <hrogge@gmail.com>
-commit 5fcd5f1808813a3d9e502fd756e01bee8a79c85d
-Author: Michal Kazior <michal.kazior@tieto.com>
-Date: Wed Jan 29 07:56:19 2014 +0100
+commit 4c8a3486cb577d40c1ef75f0a8dc9a04773eef83
+Author: Nickolay Ledovskikh <nledovskikh@gmail.com>
+Date: Fri Apr 25 22:53:34 2014 +0400
- mac80211: move csa_active setting in STA CSA
+ ath5k: Fix AR5K_PHY_TXPOWER_RATE_MAX register value setting.
- 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.
+ I was reading ath5k power setting code and
+ noticed typing error in ath5k_hw_txpower function.
+ Invalid value was written to AR5K_PHY_TXPOWER_RATE_MAX
+ register.
- Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
- Reviewed-by: Luciano Coelho <luciano.coelho@intel.com>
- Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Nikolay Ledovskikh <nledovskikh@gmail.com>
+ Acked-by: Nick Kossifidis <mickflemm@gmail.com>
+ Signed-off-by: John W. Linville <linville@tuxdriver.com>
-commit e486da4b7eed71821c6b4c1bb9ac62ffd3ab13e9
-Author: Michal Kazior <michal.kazior@tieto.com>
-Date: Wed Jan 29 07:56:18 2014 +0100
+commit 4d76248013dbb1948429555208900a585b0f351d
+Author: Janusz Dziedzic <janusz.dziedzic@tieto.com>
+Date: Tue Apr 8 13:38:43 2014 +0200
- mac80211: fix possible memory leak on AP CSA failure
+ ath9k: Enable DFS only when ATH9K_DFS_CERTIFIED
- If CSA for AP interface failed and the interface
- was not stopped afterwards another CSA request
- would leak sdata->u.ap.next_beacon.
+ Add DFS interface combination only when
+ CONFIG_ATH9K_DFS_CERTIFIED is set. In other case
+ user can run CAC/beaconing without proper handling
+ of pulse events (without radar detection activated).
- Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
- Reviewed-by: Luciano Coelho <luciano.coelho@intel.com>
- Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Reported-by: Cedric Voncken <cedric.voncken@acksys.fr>
+ Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
+ Signed-off-by: John W. Linville <linville@tuxdriver.com>
-commit 3a77ba08940682bf3d52cf14f980337324af9d4a
-Author: Johannes Berg <johannes.berg@intel.com>
-Date: Sat Feb 1 00:33:29 2014 +0100
+commit c83a4e5156a4b4dd22137d33a5625440982d6d37
+Author: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
+Date: Mon Apr 28 21:17:08 2014 +0530
- mac80211: fix fragmentation code, particularly for encryption
-
- The "new" fragmentation code (since my rewrite almost 5 years ago)
- erroneously sets skb->len rather than using skb_trim() to adjust
- the length of the first fragment after copying out all the others.
- This leaves the skb tail pointer pointing to after where the data
- originally ended, and thus causes the encryption MIC to be written
- at that point, rather than where it belongs: immediately after the
- data.
-
- 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
- verified at the receiver, the MIC is practically guaranteed to
- be wrong
- b) we leak up to 8 bytes of plaintext (!) of the packet out into
- the air
+ ath9k_hw: fix worse EVM for 11b rates
- 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.
+ Adjust FIR filter co-efficients to improve EVM for 11b rates.
- Fix this by using skb_trim() properly.
-
- Cc: stable@vger.kernel.org
- Fixes: 2de8e0d999b8 ("mac80211: rewrite fragmentation")
- Reported-by: Jouni Malinen <j@w1.fi>
- Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
+ Signed-off-by: John W. Linville <linville@tuxdriver.com>
-commit de5f242e0c10e841017e37eb8c38974a642dbca8
-Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
-Date: Tue Jan 28 06:21:59 2014 +0530
+commit 8aab2c7a2f4a957e344db429dfb1190ae59ce8b5
+Author: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
+Date: Mon Apr 28 21:17:07 2014 +0530
- ath9k: Fix build error on ARM
-
- Use mdelay instead of udelay to fix this error:
+ ath9k_hw: update ar9300 initvals
- ERROR: "__bad_udelay" [drivers/net/wireless/ath/ath9k/ath9k_hw.ko] undefined!
- make[1]: *** [__modpost] Error 1
- make: *** [modules] Error 2
+ * rfsat gainchange hysteresis of rf_gain stuck with large
+ interference present.
- Reported-by: Josh Boyer <jwboyer@fedoraproject.org>
- Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
+ Signed-off-by: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
+ Signed-off-by: John W. Linville <linville@tuxdriver.com>
-commit 8e3ea7a51dfc61810fcefd947f6edcf61125252a
-Author: Geert Uytterhoeven <geert@linux-m68k.org>
-Date: Sun Jan 26 11:53:21 2014 +0100
+commit 8c7ae357cc5b6bd037ad2d666e9f3789cf882925
+Author: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
+Date: Wed Apr 23 15:07:57 2014 +0530
- ath9k: Fix uninitialized variable in ath9k_has_tx_pending()
+ ath9k: fix race in setting ATH_OP_INVALID
- drivers/net/wireless/ath/ath9k/main.c: In function ‘ath9k_has_tx_pending’:
- drivers/net/wireless/ath/ath9k/main.c:1869: warning: ‘npend’ may be used uninitialized in this function
+ The commit "ath9k: move sc_flags to ath_common" moved setting
+ ATH_OP_INVALID flag below ieee80211_register_hw. This is causing
+ the flag never being cleared randomly as the drv_start is called
+ prior to setting flag. Fix this by setting the flag prior to
+ register_hw.
- Introduced by commit 10e2318103f5941aa70c318afe34bc41f1b98529 ("ath9k:
- optimize ath9k_flush").
-
- Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
+ Signed-off-by: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
+ Signed-off-by: John W. Linville <linville@tuxdriver.com>
-commit a4a634a6937ebdd827fa58e8fcdb8ca49a3769f6
-Author: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-Date: Mon Jan 27 11:07:42 2014 +0200
+commit c82552c5b0cb1735dbcbad78b1ffc6d3c212dc56
+Author: Tim Harvey <tharvey@gateworks.com>
+Date: Mon Apr 21 16:14:57 2014 -0700
- mac80211: release the channel in error path in start_ap
-
- When the driver cannot start the AP or when the assignement
- of the beacon goes wrong, we need to unassign the vif.
+ ath9k: add a recv budget
- Cc: stable@vger.kernel.org
- Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
- Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-
-commit dfb6889a75c601aedb7450b7e606668e77da6679
-Author: Johannes Berg <johannes.berg@intel.com>
-Date: Wed Jan 22 11:14:19 2014 +0200
-
- cfg80211: send scan results from work queue
+ Implement a recv budget so that in cases of high traffic we still allow other
+ taskets to get processed.
- Due to the previous commit, when a scan finishes, it is in theory
- possible to hit the following sequence:
- 1. interface starts being removed
- 2. scan is cancelled by driver and cfg80211 is notified
- 3. scan done work is scheduled
- 4. interface is removed completely, rdev->scan_req is freed,
- event sent to userspace but scan done work remains pending
- 5. new scan is requested on another virtual interface
- 6. scan done work runs, freeing the still-running scan
+ Without this, we can encounter a host of issues during high wireless traffic
+ reception depending on system load including rcu stall's detected (ARM),
+ soft lockups, failure to service critical tasks such as watchdog resets,
+ and triggering of the tx stuck tasklet.
- To fix this situation, hang on to the scan done message and block
- new scans while that is the case, and only send the message from
- the work function, regardless of whether the scan_req is already
- freed from interface removal. This makes step 5 above impossible
- and changes step 6 to be
- 5. scan done work runs, sending the scan done message
+ The same thing was proposed previously by Ben:
+ http://www.spinics.net/lists/linux-wireless/msg112891.html
- 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.
+ The only difference here is that I make sure only processed packets are counted
+ in the budget by checking at the end of the rx loop.
- Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Tim Harvey <tharvey@gateworks.com>
+ Acked-by: Felix Fietkau <nbd@openwrt.org>
+ Signed-off-by: John W. Linville <linville@tuxdriver.com>
-commit 45b7ab41fc08627d9a8428cb413d5d84662a9707
-Author: Johannes Berg <johannes.berg@intel.com>
-Date: Wed Jan 22 11:14:18 2014 +0200
+commit 3a758134e66ca74a9df792616b5288b2fa2cfd7f
+Author: Tim Harvey <tharvey@gateworks.com>
+Date: Mon Apr 21 16:14:56 2014 -0700
- cfg80211: fix scan done race
+ ath9k: fix possible hang on flush
- When an interface/wdev is removed, any ongoing scan should be
- cancelled by the driver. This will make it call cfg80211, which
- only queues a work struct. If interface/wdev removal is quick
- enough, this can leave the scan request pending and processed
- only after the interface is gone, causing a use-after-free.
+ If a flush is requested, make sure to clear the descriptor once we've
+ processed it.
- Fix this by making sure the scan request is not pending after
- the interface is destroyed. We can't flush or cancel the work
- item due to locking concerns, but when it'll run it shouldn't
- find anything to do. This leaves a potential issue, if a new
- scan gets requested before the work runs, it prematurely stops
- the running scan, potentially causing another crash. I'll fix
- that in the next patch.
+ This resolves a hang that will occur if all RX descriptors are full when a
+ flush is requested.
- This was particularly observed with P2P_DEVICE wdevs, likely
- because freeing them is quicker than freeing netdevs.
-
- Reported-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
- Fixes: 4a58e7c38443 ("cfg80211: don't "leak" uncompleted scans")
- Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Tim Harvey <tharvey@gateworks.com>
+ Acked-by: Felix Fietkau <nbd@openwrt.org>
+ Signed-off-by: John W. Linville <linville@tuxdriver.com>
-commit ae04fa489ab31b5a10d3cc8399f52761175d4321
-Author: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-Date: Thu Jan 23 14:28:16 2014 +0200
+commit eefb1d6adc4c60d219182b8917e4567484ce07fc
+Author: Felix Fietkau <nbd@openwrt.org>
+Date: Mon Apr 28 18:27:41 2014 +0200
- mac80211: avoid deadlock revealed by lockdep
-
- sdata->u.ap.request_smps_work can’t be flushed synchronously
- under wdev_lock(wdev) since ieee80211_request_smps_ap_work
- itself locks the same lock.
- While at it, reset the driver_smps_mode when the ap is
- stopped to its default: OFF.
-
- This solves:
-
- ======================================================
- [ 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: [<c105b8d0>] flush_work+0x0/0x90
-
- but task is already holding lock:
- (&wdev->mtx){+.+.+.}, at: [<f9b32626>] cfg80211_stop_ap+0x26/0x230 [cfg80211]
-
- which lock already depends on the new lock.
-
- the existing dependency chain (in reverse order) is:
+ ath9k: remove tid->paused flag
- -> #1 (&wdev->mtx){+.+.+.}:
- [<c10aefa9>] lock_acquire+0x79/0xe0
- [<c1607a1a>] mutex_lock_nested+0x4a/0x360
- [<fb06288b>] ieee80211_request_smps_ap_work+0x2b/0x50 [mac80211]
- [<c105cdd8>] process_one_work+0x198/0x450
- [<c105d469>] worker_thread+0xf9/0x320
- [<c10669ff>] kthread+0x9f/0xb0
- [<c1613397>] ret_from_kernel_thread+0x1b/0x28
+ There are some corner cases where the driver could get stuck with a full
+ tid queue that is paused, leading to a software tx queue hang.
- -> #0 ((&sdata->u.ap.request_smps_work)){+.+...}:
- [<c10ae9df>] __lock_acquire+0x183f/0x1910
- [<c10aefa9>] lock_acquire+0x79/0xe0
- [<c105b917>] flush_work+0x47/0x90
- [<c105d867>] __cancel_work_timer+0x67/0xe0
- [<c105d90f>] cancel_work_sync+0xf/0x20
- [<fb0765cc>] ieee80211_stop_ap+0x8c/0x340 [mac80211]
- [<f9b3268c>] cfg80211_stop_ap+0x8c/0x230 [cfg80211]
- [<f9b0d8f9>] cfg80211_leave+0x79/0x100 [cfg80211]
- [<f9b0da72>] cfg80211_netdev_notifier_call+0xf2/0x4f0 [cfg80211]
- [<c160f2c9>] notifier_call_chain+0x59/0x130
- [<c106c6de>] __raw_notifier_call_chain+0x1e/0x30
- [<c106c70f>] raw_notifier_call_chain+0x1f/0x30
- [<c14f8213>] call_netdevice_notifiers_info+0x33/0x70
- [<c14f8263>] call_netdevice_notifiers+0x13/0x20
- [<c14f82a4>] __dev_close_many+0x34/0xb0
- [<c14f83fe>] dev_close_many+0x6e/0xc0
- [<c14f9c77>] rollback_registered_many+0xa7/0x1f0
- [<c14f9dd4>] unregister_netdevice_many+0x14/0x60
- [<fb06f4d9>] ieee80211_remove_interfaces+0xe9/0x170 [mac80211]
- [<fb055116>] ieee80211_unregister_hw+0x56/0x110 [mac80211]
- [<fa3e9396>] iwl_op_mode_mvm_stop+0x26/0xe0 [iwlmvm]
- [<f9b9d8ca>] _iwl_op_mode_stop+0x3a/0x70 [iwlwifi]
- [<f9b9d96f>] iwl_opmode_deregister+0x6f/0x90 [iwlwifi]
- [<fa405179>] __exit_compat+0xd/0x19 [iwlmvm]
- [<c10b8bf9>] SyS_delete_module+0x179/0x2b0
- [<c1613421>] sysenter_do_call+0x12/0x32
+ Since the tx queueing rework, pausing per-tid queues on aggregation
+ session setup is no longer necessary. The driver will assign sequence
+ numbers to buffered frames when a new session is established, in order
+ to get the correct starting sequence number.
- Fixes: 687da132234f ("mac80211: implement SMPS for AP")
- Cc: <stable@vger.kernel.org> [3.13]
- Reported-by: Ilan Peer <ilan.peer@intel.com>
- Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
- Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-
-commit 178b205e96217164fd7c30113464250d0b6f5eca
-Author: Johannes Berg <johannes.berg@intel.com>
-Date: Thu Jan 23 16:32:29 2014 +0100
-
- cfg80211: re-enable 5/10 MHz support
-
- 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.
+ mac80211 prevents new frames from entering the queue during setup.
- Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-commit 110a1c79acda14edc83b7c8dc5af9c7ddd23eb61
-Author: Pontus Fuchs <pontus.fuchs@gmail.com>
-Date: Thu Jan 16 15:00:40 2014 +0100
+commit 98a713933d8495f4078f561c1e651b738dd5b531
+Author: Felix Fietkau <nbd@openwrt.org>
+Date: Sun Apr 27 14:49:03 2014 +0200
- nl80211: Reset split_start when netlink skb is exhausted
+ ath9k_hw: do not lower ANI setting below default on AR913x
- 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.
+ When the amount of noise fluctuates strongly, low immunity settings
+ can sometimes disrupt signal detection on AR913x chips. When that
+ happens, no OFDM/CCK errors are reported anymore, and ANI tunes the
+ radio to the lowest immunity settings.
+ Usually rx/tx fails as well in that case.
- 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.
+ To fix this, keep noise immunity settings at or above ANI default level,
+ which will keep radio parameters at or above INI values.
- Cc: stable@vger.kernel.org
- Fixes: 3713b4e364ef ("nl80211: allow splitting wiphy information in dumps")
- Signed-off-by: Pontus Fuchs <pontus.fuchs@gmail.com>
- [avoid the entire workaround when state->split is set]
- Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-commit b4c31b45ffc7ef110fa9ecc34d7878fe7c5b9da4
-Author: Eliad Peller <eliad@wizery.com>
-Date: Sun Jan 12 11:06:37 2014 +0200
+commit 7cbb4c021bfd1e656f5b9953a947ab3c64e4e3b0
+Author: Felix Fietkau <nbd@openwrt.org>
+Date: Thu Apr 10 10:49:01 2014 +0200
- mac80211: move roc cookie assignment earlier
-
- ieee80211_start_roc_work() might add a new roc
- to existing roc, and tell cfg80211 it has already
- started.
+ mac80211: exclude AP_VLAN interfaces from tx power calculation
- However, this might happen before the roc cookie
- was set, resulting in REMAIN_ON_CHANNEL (started)
- event with null cookie. Consequently, it can make
- wpa_supplicant go out of sync.
-
- Fix it by setting the roc cookie earlier.
+ Their power value is initialized to zero. This patch fixes an issue
+ where the configured power drops to the minimum value when AP_VLAN
+ interfaces are created/removed.
Cc: stable@vger.kernel.org
- Signed-off-by: Eliad Peller <eliad@wizery.com>
- Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-
-commit cfdc9157bfd7bcf88ab4dae08873a9907eba984c
-Author: Johannes Berg <johannes.berg@intel.com>
-Date: Fri Jan 24 14:06:29 2014 +0100
-
- nl80211: send event when AP operation is stopped
-
- 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.
-
- 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.
-
- Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-commit d5d567eda7704f190379ca852a8f9a4112e3eee3
-Author: Johannes Berg <johannes.berg@intel.com>
-Date: Thu Jan 23 16:20:29 2014 +0100
+commit 0ca13e26341733bf9577287fb04a3bef0d2f5cc9
+Author: Felix Fietkau <nbd@openwrt.org>
+Date: Wed Apr 9 00:07:01 2014 +0200
- mac80211: add length check in ieee80211_is_robust_mgmt_frame()
+ mac80211: suppress BSS info change notifications for AP_VLAN
- 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.
+ Fixes warnings on tx power changes
- Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-commit f8f6d212a047fc65c7d3442dfc038f65517236fc
-Author: Johannes Berg <johannes.berg@intel.com>
-Date: Fri Jan 24 10:53:53 2014 +0100
+commit ec998e5991781ecdaad0911dc64f1c8d3749c308
+Author: Felix Fietkau <nbd@openwrt.org>
+Date: Tue Apr 8 23:42:17 2014 +0200
- nl80211: fix scheduled scan RSSI matchset attribute confusion
-
- The scheduled scan matchsets were intended to be a list of filters,
- with the found BSS having to pass at least one of them to be passed
- to the host. When the RSSI attribute was added, however, this was
- broken and currently wpa_supplicant adds that attribute in its own
- matchset; however, it doesn't intend that to mean that anything
- that passes the RSSI filter should be passed to the host, instead
- it wants it to mean that everything needs to also have higher RSSI.
-
- This is semantically problematic because we have a list of filters
- like [ SSID1, SSID2, SSID3, RSSI ] with no real indication which
- one should be OR'ed and which one AND'ed.
-
- To fix this, move the RSSI filter attribute into each matchset. As
- we need to stay backward compatible, treat a matchset with only the
- RSSI attribute as a "default RSSI filter" for all other matchsets,
- but only if there are other matchsets (an RSSI-only matchset by
- itself is still desirable.)
-
- To make driver implementation easier, keep a global min_rssi_thold
- for the entire request as well. The only affected driver is ath6kl.
+ ath9k: fix a scheduling while atomic bug in CSA handling
- I found this when I looked into the code after Raja Mani submitted
- a patch fixing the n_match_sets calculation to disregard the RSSI,
- but that patch didn't address the semantic issue.
+ Commit "ath9k: prepare for multi-interface CSA support" added a call to
+ ieee80211_iterate_active_interfaces in atomic context (beacon tasklet),
+ which is crashing.
+ Use ieee80211_iterate_active_interfaces_atomic instead.
- Reported-by: Raja Mani <rmani@qti.qualcomm.com>
- Acked-by: Luciano Coelho <luciano.coelho@intel.com>
- Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-commit de553e8545e65a6dc4e45f43df7e1443d4291922
-Author: Johannes Berg <johannes.berg@intel.com>
-Date: Fri Jan 24 10:17:47 2014 +0100
+commit 93f310a38a1d81a4bc8fcd9bf29628bd721cf2ef
+Author: Felix Fietkau <nbd@openwrt.org>
+Date: Sun Apr 6 23:35:28 2014 +0200
- nl80211: check nla_parse() return values
+ ath9k_hw: reduce ANI firstep range for older chips
- If there's a policy, then nla_parse() return values must be
- checked, otherwise the policy is useless and there's nothing
- that ensures the attributes are actually what we expect them
- to be.
+ 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.
- Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-commit 652204a0733e9e1c54661d6f9d36e2e1e3b22bb1
-Author: Karl Beldan <karl.beldan@rivierawaves.com>
-Date: Thu Jan 23 20:06:34 2014 +0100
- mac80211: send {ADD,DEL}BA on AC_VO like other mgmt frames, as per spec
-
- ATM, {ADD,DEL}BA and BAR frames are sent on the AC matching the TID of
- the BA parameters. In the discussion [1] about this patch, Johannes
- recalled that it fixed some races with the DELBA and indeed this
- behavior was introduced in [2].
- While [2] is right for the BARs, the part queueing the {ADD,DEL}BAs on
- their BA params TID AC violates the spec and is more a workaround for
- some drivers. Helmut expressed some concerns wrt such drivers, in
- particular DELBAs in rt2x00.
-
- ATM, DELBAs are sent after a driver has called (hence "purposely")
- ieee80211_start_tx_ba_cb_irqsafe and Johannes and Emmanuel gave some
- details wrt intentions behind the split of the IEEE80211_AMPDU_TX_STOP_*
- given to the driver ampdu_action supposed to call this function, which
- could prove handy to people trying to do the right thing in faulty
- drivers (if their fw/hw don't get in their way).
-
- [1] http://mid.gmane.org/1390391564-18481-1-git-send-email-karl.beldan@gmail.com
- [2] Commit: cf6bb79ad828 ("mac80211: Use appropriate TID for sending BAR, ADDBA and DELBA frames")
-
- Signed-off-by: Karl Beldan <karl.beldan@rivierawaves.com>
- Cc: Helmut Schaa <helmut.schaa@googlemail.com>
- Cc: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
- Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---- 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",
- nw_type & ADHOC_CREATOR ? "creator" : "joiner");
-- cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
-+ cfg80211_ibss_joined(vif->ndev, bssid, chan, GFP_KERNEL);
- cfg80211_put_bss(ar->wiphy, bss);
- return;
- }
-@@ -861,13 +861,9 @@ void ath6kl_cfg80211_disconnect_event(st
- }
-
- if (vif->nw_type & ADHOC_NETWORK) {
-- if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) {
-+ if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC)
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
- "%s: ath6k not in ibss mode\n", __func__);
-- return;
-- }
-- memset(bssid, 0, ETH_ALEN);
-- cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
- return;
- }
-
-@@ -3256,6 +3252,15 @@ static int ath6kl_cfg80211_sscan_start(s
- struct ath6kl_vif *vif = netdev_priv(dev);
- u16 interval;
- int ret, rssi_thold;
-+ int n_match_sets = request->n_match_sets;
-+
-+ /*
-+ * If there's a matchset w/o an SSID, then assume it's just for
-+ * the RSSI (nothing else is currently supported) and ignore it.
-+ * The device only supports a global RSSI filter that we set below.
-+ */
-+ if (n_match_sets == 1 && !request->match_sets[0].ssid.ssid_len)
-+ n_match_sets = 0;
-
- if (ar->state != ATH6KL_STATE_ON)
- return -EIO;
-@@ -3268,11 +3273,11 @@ static int ath6kl_cfg80211_sscan_start(s
- ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
- request->n_ssids,
- request->match_sets,
-- request->n_match_sets);
-+ n_match_sets);
- if (ret < 0)
- return ret;
-
-- if (!request->n_match_sets) {
-+ if (!n_match_sets) {
- ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
- ALL_BSS_FILTER, 0);
- if (ret < 0)
-@@ -3286,12 +3291,12 @@ static int ath6kl_cfg80211_sscan_start(s
-
- if (test_bit(ATH6KL_FW_CAPABILITY_RSSI_SCAN_THOLD,
- ar->fw_capabilities)) {
-- if (request->rssi_thold <= NL80211_SCAN_RSSI_THOLD_OFF)
-+ if (request->min_rssi_thold <= NL80211_SCAN_RSSI_THOLD_OFF)
- rssi_thold = 0;
-- else if (request->rssi_thold < -127)
-+ else if (request->min_rssi_thold < -127)
- rssi_thold = -127;
- else
-- rssi_thold = request->rssi_thold;
-+ rssi_thold = request->min_rssi_thold;
+--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
++++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+@@ -1004,11 +1004,9 @@ static bool ar5008_hw_ani_control_new(st
+ case ATH9K_ANI_FIRSTEP_LEVEL:{
+ u32 level = param;
- ret = ath6kl_wmi_set_rssi_filter_cmd(ar->wmi, vif->fw_vif_idx,
- rssi_thold);
---- a/drivers/net/wireless/ath/ath9k/hw.c
-+++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -1316,7 +1316,7 @@ static bool ath9k_hw_set_reset(struct at
- if (AR_SREV_9300_20_OR_LATER(ah))
- udelay(50);
- else if (AR_SREV_9100(ah))
-- udelay(10000);
-+ mdelay(10);
- else
- udelay(100);
+- value = level * 2;
++ value = level;
+ REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
+ AR_PHY_FIND_SIG_FIRSTEP, value);
+- REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW,
+- AR_PHY_FIND_SIG_FIRSTEP_LOW, value);
-@@ -2051,9 +2051,8 @@ static bool ath9k_hw_set_power_awake(str
+ if (level != aniState->firstepLevel) {
+ ath_dbg(common, ANI,
+--- a/drivers/net/wireless/ath/ath9k/beacon.c
++++ b/drivers/net/wireless/ath/ath9k/beacon.c
+@@ -312,10 +312,9 @@ static void ath9k_csa_update_vif(void *d
- REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
- AR_RTC_FORCE_WAKE_EN);
--
- if (AR_SREV_9100(ah))
-- udelay(10000);
-+ mdelay(10);
- else
- udelay(50);
-
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -1866,7 +1866,7 @@ static void ath9k_set_coverage_class(str
-
- static bool ath9k_has_tx_pending(struct ath_softc *sc)
- {
-- int i, npend;
-+ int i, npend = 0;
-
- for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
- if (!ATH_TXQ_SETUP(sc, i))
---- a/drivers/net/wireless/iwlwifi/mvm/scan.c
-+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
-@@ -595,6 +595,9 @@ static void iwl_scan_offload_build_ssid(
- * config match list.
- */
- for (i = 0; i < req->n_match_sets && i < PROBE_OPTION_MAX; i++) {
-+ /* skip empty SSID matchsets */
-+ if (!req->match_sets[i].ssid.ssid_len)
-+ continue;
- scan->direct_scan[i].id = WLAN_EID_SSID;
- scan->direct_scan[i].len = req->match_sets[i].ssid.ssid_len;
- memcpy(scan->direct_scan[i].ssid, req->match_sets[i].ssid.ssid,
---- a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c
-+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c
-@@ -452,7 +452,7 @@ bool rtl88ee_rx_query_desc(struct ieee80
- /* During testing, hdr was NULL */
- return false;
- }
-- if ((ieee80211_is_robust_mgmt_frame(hdr)) &&
-+ if ((_ieee80211_is_robust_mgmt_frame(hdr)) &&
- (ieee80211_has_protected(hdr->frame_control)))
- rx_status->flag &= ~RX_FLAG_DECRYPTED;
- else
---- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
-+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
-@@ -393,7 +393,7 @@ bool rtl92ce_rx_query_desc(struct ieee80
- /* In testing, hdr was NULL here */
- return false;
- }
-- if ((ieee80211_is_robust_mgmt_frame(hdr)) &&
-+ if ((_ieee80211_is_robust_mgmt_frame(hdr)) &&
- (ieee80211_has_protected(hdr->frame_control)))
- rx_status->flag &= ~RX_FLAG_DECRYPTED;
- else
---- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
-+++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
-@@ -310,7 +310,7 @@ bool rtl92se_rx_query_desc(struct ieee80
- /* during testing, hdr was NULL here */
- return false;
- }
-- if ((ieee80211_is_robust_mgmt_frame(hdr)) &&
-+ if ((_ieee80211_is_robust_mgmt_frame(hdr)) &&
- (ieee80211_has_protected(hdr->frame_control)))
- rx_status->flag &= ~RX_FLAG_DECRYPTED;
- else
---- a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c
-+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c
-@@ -334,7 +334,7 @@ bool rtl8723ae_rx_query_desc(struct ieee
- /* during testing, hdr could be NULL here */
- return false;
- }
-- if ((ieee80211_is_robust_mgmt_frame(hdr)) &&
-+ if ((_ieee80211_is_robust_mgmt_frame(hdr)) &&
- (ieee80211_has_protected(hdr->frame_control)))
- rx_status->flag &= ~RX_FLAG_DECRYPTED;
- else
---- a/include/linux/ieee80211.h
-+++ b/include/linux/ieee80211.h
-@@ -597,6 +597,20 @@ static inline int ieee80211_is_qos_nullf
- }
-
- /**
-+ * ieee80211_is_bufferable_mmpdu - check if frame is bufferable MMPDU
-+ * @fc: frame control field in little-endian byteorder
-+ */
-+static inline bool ieee80211_is_bufferable_mmpdu(__le16 fc)
-+{
-+ /* IEEE 802.11-2012, definition of "bufferable management frame";
-+ * note that this ignores the IBSS special case. */
-+ return ieee80211_is_mgmt(fc) &&
-+ (ieee80211_is_action(fc) ||
-+ ieee80211_is_disassoc(fc) ||
-+ ieee80211_is_deauth(fc));
-+}
-+
-+/**
- * ieee80211_is_first_frag - check if IEEE80211_SCTL_FRAG is not set
- * @seq_ctrl: frame sequence control bytes in little-endian byteorder
- */
-@@ -2192,10 +2206,10 @@ static inline u8 *ieee80211_get_DA(struc
- }
-
- /**
-- * 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
- * @hdr: the frame (buffer must include at least the first octet of payload)
- */
--static inline bool ieee80211_is_robust_mgmt_frame(struct ieee80211_hdr *hdr)
-+static inline bool _ieee80211_is_robust_mgmt_frame(struct ieee80211_hdr *hdr)
+ void ath9k_csa_update(struct ath_softc *sc)
{
- 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
-+ */
-+static inline bool ieee80211_is_robust_mgmt_frame(struct sk_buff *skb)
-+{
-+ if (skb->len < 25)
-+ return false;
-+ return _ieee80211_is_robust_mgmt_frame((void *)skb->data);
-+}
-+
-+/**
- * ieee80211_is_public_action - check if frame is a public action frame
- * @hdr: the frame
- * @len: length of the frame
---- a/include/net/cfg80211.h
-+++ b/include/net/cfg80211.h
-@@ -1395,9 +1395,11 @@ struct cfg80211_scan_request {
- * struct cfg80211_match_set - sets of attributes to match
- *
- * @ssid: SSID to be matched
-+ * @rssi_thold: don't report scan results below this threshold (in s32 dBm)
- */
- struct cfg80211_match_set {
- struct cfg80211_ssid ssid;
-+ s32 rssi_thold;
- };
-
- /**
-@@ -1420,7 +1422,8 @@ struct cfg80211_match_set {
- * @dev: the interface
- * @scan_start: start time of the scheduled scan
- * @channels: channels to scan
-- * @rssi_thold: don't report scan results below this threshold (in s32 dBm)
-+ * @min_rssi_thold: for drivers only supporting a single threshold, this
-+ * contains the minimum over all matchsets
- */
- struct cfg80211_sched_scan_request {
- struct cfg80211_ssid *ssids;
-@@ -1433,7 +1436,7 @@ struct cfg80211_sched_scan_request {
- u32 flags;
- struct cfg80211_match_set *match_sets;
- int n_match_sets;
-- s32 rssi_thold;
-+ s32 min_rssi_thold;
-
- /* internal */
- struct wiphy *wiphy;
-@@ -3130,8 +3133,8 @@ struct cfg80211_cached_keys;
- * @identifier: (private) Identifier used in nl80211 to identify this
- * wireless device if it has no netdev
- * @current_bss: (private) Used by the internal configuration code
-- * @channel: (private) Used by the internal configuration code to track
-- * the user-set AP, monitor and WDS channel
-+ * @chandef: (private) Used by the internal configuration code to track
-+ * the user-set channel definition.
- * @preset_chandef: (private) Used by the internal configuration code to
- * track the channel to be used for AP later
- * @bssid: (private) Used by the internal configuration code
-@@ -3195,9 +3198,7 @@ struct wireless_dev {
-
- struct cfg80211_internal_bss *current_bss; /* associated / joined */
- struct cfg80211_chan_def preset_chandef;
--
-- /* for AP and mesh channel tracking */
-- struct ieee80211_channel *channel;
-+ struct cfg80211_chan_def chandef;
-
- bool ibss_fixed;
- bool ibss_dfs_possible;
-@@ -3879,6 +3880,7 @@ void cfg80211_michael_mic_failure(struct
- *
- * @dev: network device
- * @bssid: the BSSID of the IBSS joined
-+ * @channel: the channel of the IBSS joined
- * @gfp: allocation flags
- *
- * This function notifies cfg80211 that the device joined an IBSS or
-@@ -3888,7 +3890,8 @@ void cfg80211_michael_mic_failure(struct
- * with the locally generated beacon -- this guarantees that there is
- * always a scan result for this IBSS. cfg80211 will handle the rest.
- */
--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);
-
- /**
- * cfg80211_notify_new_candidate - notify cfg80211 of a new mesh peer candidate
---- a/include/uapi/linux/nl80211.h
-+++ b/include/uapi/linux/nl80211.h
-@@ -2442,9 +2442,15 @@ enum nl80211_reg_rule_attr {
- * enum nl80211_sched_scan_match_attr - scheduled scan match attributes
- * @__NL80211_SCHED_SCAN_MATCH_ATTR_INVALID: attribute number 0 is reserved
- * @NL80211_SCHED_SCAN_MATCH_ATTR_SSID: SSID to be used for matching,
-- * only report BSS with matching SSID.
-+ * only report BSS with matching SSID.
- * @NL80211_SCHED_SCAN_MATCH_ATTR_RSSI: RSSI threshold (in dBm) for reporting a
-- * BSS in scan results. Filtering is turned off if not specified.
-+ * BSS in scan results. Filtering is turned off if not specified. Note that
-+ * if this attribute is in a match set of its own, then it is treated as
-+ * the default value for all matchsets with an SSID, rather than being a
-+ * matchset of its own without an RSSI filter. This is due to problems with
-+ * how this API was implemented in the past. Also, due to the same problem,
-+ * the only way to create a matchset with only an RSSI filter (with this
-+ * attribute) is if there's only a single matchset with the RSSI attribute.
- * @NL80211_SCHED_SCAN_MATCH_ATTR_MAX: highest scheduled scan filter
- * attribute number currently defined
- * @__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST: internal use
---- a/net/mac80211/agg-tx.c
-+++ b/net/mac80211/agg-tx.c
-@@ -107,7 +107,7 @@ static void ieee80211_send_addba_request
- mgmt->u.action.u.addba_req.start_seq_num =
- cpu_to_le16(start_seq_num << 4);
-
-- ieee80211_tx_skb_tid(sdata, skb, tid);
-+ ieee80211_tx_skb(sdata, skb);
+- ieee80211_iterate_active_interfaces(sc->hw,
+- IEEE80211_IFACE_ITER_NORMAL,
+- ath9k_csa_update_vif,
+- sc);
++ ieee80211_iterate_active_interfaces_atomic(sc->hw,
++ IEEE80211_IFACE_ITER_NORMAL,
++ ath9k_csa_update_vif, sc);
}
- void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn)
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -970,9 +970,9 @@ static int ieee80211_start_ap(struct wip
- /* TODO: make hostapd tell us what it wants */
- sdata->smps_mode = IEEE80211_SMPS_OFF;
- sdata->needed_rx_chains = sdata->local->rx_chains;
-- sdata->radar_required = params->radar_required;
-
- mutex_lock(&local->mtx);
-+ sdata->radar_required = params->radar_required;
- err = ieee80211_vif_use_channel(sdata, ¶ms->chandef,
- IEEE80211_CHANCTX_SHARED);
- mutex_unlock(&local->mtx);
-@@ -1021,8 +1021,10 @@ static int ieee80211_start_ap(struct wip
- IEEE80211_P2P_OPPPS_ENABLE_BIT;
-
- err = ieee80211_assign_beacon(sdata, ¶ms->beacon);
-- if (err < 0)
-+ if (err < 0) {
-+ ieee80211_vif_release_channel(sdata);
- return err;
-+ }
- changed |= err;
-
- err = drv_start_ap(sdata->local, sdata);
-@@ -1032,6 +1034,7 @@ static int ieee80211_start_ap(struct wip
- if (old)
- kfree_rcu(old, rcu_head);
- RCU_INIT_POINTER(sdata->u.ap.beacon, NULL);
-+ ieee80211_vif_release_channel(sdata);
- return err;
+ void ath9k_beacon_tasklet(unsigned long data)
+--- a/net/mac80211/main.c
++++ b/net/mac80211/main.c
+@@ -152,6 +152,8 @@ static u32 ieee80211_hw_conf_chan(struct
+ list_for_each_entry_rcu(sdata, &local->interfaces, list) {
+ if (!rcu_access_pointer(sdata->vif.chanctx_conf))
+ continue;
++ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
++ continue;
+ power = min(power, sdata->vif.bss_conf.txpower);
}
+ rcu_read_unlock();
+@@ -203,7 +205,7 @@ void ieee80211_bss_info_change_notify(st
+ {
+ struct ieee80211_local *local = sdata->local;
-@@ -1053,6 +1056,7 @@ static int ieee80211_change_beacon(struc
- int err;
-
- sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-+ sdata_assert_lock(sdata);
-
- /* 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;
-
-+ sdata_assert_lock(sdata);
-+
- old_beacon = sdata_dereference(sdata->u.ap.beacon, sdata);
- if (!old_beacon)
- return -ENOENT;
-@@ -1090,8 +1096,6 @@ static int ieee80211_stop_ap(struct wiph
- kfree(sdata->u.ap.next_beacon);
- sdata->u.ap.next_beacon = NULL;
-
-- cancel_work_sync(&sdata->u.ap.request_smps_work);
--
- /* turn off carrier for this interface and dependent VLANs */
- list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
- netif_carrier_off(vlan->dev);
-@@ -1103,6 +1107,7 @@ static int ieee80211_stop_ap(struct wiph
- kfree_rcu(old_beacon, rcu_head);
- if (old_probe_resp)
- kfree_rcu(old_probe_resp, rcu_head);
-+ sdata->u.ap.driver_smps_mode = IEEE80211_SMPS_OFF;
-
- __sta_info_flush(sdata, true);
- ieee80211_free_keys(sdata, true);
-@@ -2638,6 +2643,24 @@ static int ieee80211_start_roc_work(stru
- INIT_DELAYED_WORK(&roc->work, ieee80211_sw_roc_work);
- INIT_LIST_HEAD(&roc->dependents);
-
-+ /*
-+ * cookie is either the roc cookie (for normal roc)
-+ * or the SKB (for mgmt TX)
-+ */
-+ if (!txskb) {
-+ /* local->mtx protects this */
-+ local->roc_cookie_counter++;
-+ roc->cookie = local->roc_cookie_counter;
-+ /* wow, you wrapped 64 bits ... more likely a bug */
-+ if (WARN_ON(roc->cookie == 0)) {
-+ roc->cookie = 1;
-+ local->roc_cookie_counter++;
-+ }
-+ *cookie = roc->cookie;
-+ } else {
-+ *cookie = (unsigned long)txskb;
-+ }
-+
- /* if there's one pending or we're scanning, queue this one */
- if (!list_empty(&local->roc_list) ||
- local->scanning || local->radar_detect_enabled)
-@@ -2772,24 +2795,6 @@ static int ieee80211_start_roc_work(stru
- if (!queued)
- list_add_tail(&roc->list, &local->roc_list);
-
-- /*
-- * cookie is either the roc cookie (for normal roc)
-- * or the SKB (for mgmt TX)
-- */
-- if (!txskb) {
-- /* local->mtx protects this */
-- local->roc_cookie_counter++;
-- roc->cookie = local->roc_cookie_counter;
-- /* wow, you wrapped 64 bits ... more likely a bug */
-- if (WARN_ON(roc->cookie == 0)) {
-- roc->cookie = 1;
-- local->roc_cookie_counter++;
-- }
-- *cookie = roc->cookie;
-- } else {
-- *cookie = (unsigned long)txskb;
-- }
--
- return 0;
- }
+- if (!changed)
++ if (!changed || sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+ return;
-@@ -3004,8 +3009,10 @@ void ieee80211_csa_finalize_work(struct
- if (!ieee80211_sdata_running(sdata))
- goto unlock;
+ drv_bss_info_changed(local, sdata, &sdata->vif.bss_conf, changed);
+--- a/drivers/net/wireless/ath/ath9k/ani.c
++++ b/drivers/net/wireless/ath/ath9k/ani.c
+@@ -155,6 +155,9 @@ static void ath9k_hw_set_ofdm_nil(struct
+ ATH9K_ANI_RSSI_THR_LOW,
+ ATH9K_ANI_RSSI_THR_HIGH);
+
++ if (AR_SREV_9100(ah) && immunityLevel < ATH9K_ANI_OFDM_DEF_LEVEL)
++ immunityLevel = ATH9K_ANI_OFDM_DEF_LEVEL;
++
+ if (!scan)
+ aniState->ofdmNoiseImmunityLevel = immunityLevel;
+
+@@ -235,6 +238,9 @@ static void ath9k_hw_set_cck_nil(struct
+ BEACON_RSSI(ah), ATH9K_ANI_RSSI_THR_LOW,
+ ATH9K_ANI_RSSI_THR_HIGH);
+
++ if (AR_SREV_9100(ah) && immunityLevel < ATH9K_ANI_CCK_DEF_LEVEL)
++ immunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
++
+ if (ah->opmode == NL80211_IFTYPE_STATION &&
+ BEACON_RSSI(ah) <= ATH9K_ANI_RSSI_THR_LOW &&
+ immunityLevel > ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI)
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -251,7 +251,6 @@ struct ath_atx_tid {
+
+ s8 bar_index;
+ bool sched;
+- bool paused;
+ bool active;
+ };
-- sdata->radar_required = sdata->csa_radar_required;
-+ 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))
-@@ -3022,13 +3029,13 @@ void ieee80211_csa_finalize_work(struct
- switch (sdata->vif.type) {
- case NL80211_IFTYPE_AP:
- err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon);
-+ kfree(sdata->u.ap.next_beacon);
-+ sdata->u.ap.next_beacon = NULL;
-+
- if (err < 0)
- goto unlock;
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -107,9 +107,6 @@ static void ath_tx_queue_tid(struct ath_
+ {
+ struct ath_atx_ac *ac = tid->ac;
- changed |= err;
-- kfree(sdata->u.ap.next_beacon);
-- sdata->u.ap.next_beacon = NULL;
+- if (tid->paused)
+- return;
-
- ieee80211_bss_info_change_notify(sdata, err);
- break;
- case NL80211_IFTYPE_ADHOC:
-@@ -3066,7 +3073,7 @@ int ieee80211_channel_switch(struct wiph
- struct ieee80211_if_mesh __maybe_unused *ifmsh;
- int err, num_chanctx;
-
-- lockdep_assert_held(&sdata->wdev.mtx);
-+ sdata_assert_lock(sdata);
-
- if (!list_empty(&local->roc_list) || local->scanning)
- return -EBUSY;
---- a/net/mac80211/ht.c
-+++ b/net/mac80211/ht.c
-@@ -375,7 +375,7 @@ void ieee80211_send_delba(struct ieee802
- mgmt->u.action.u.delba.params = cpu_to_le16(params);
- mgmt->u.action.u.delba.reason_code = cpu_to_le16(reason_code);
+ if (tid->sched)
+ return;
-- ieee80211_tx_skb_tid(sdata, skb, tid);
-+ ieee80211_tx_skb(sdata, skb);
- }
+@@ -1407,7 +1404,6 @@ int ath_tx_aggr_start(struct ath_softc *
+ ath_tx_tid_change_state(sc, txtid);
+
+ txtid->active = true;
+- txtid->paused = true;
+ *ssn = txtid->seq_start = txtid->seq_next;
+ txtid->bar_index = -1;
+
+@@ -1427,7 +1423,6 @@ void ath_tx_aggr_stop(struct ath_softc *
+
+ ath_txq_lock(sc, txq);
+ txtid->active = false;
+- txtid->paused = false;
+ ath_tx_flush_tid(sc, txtid);
+ ath_tx_tid_change_state(sc, txtid);
+ ath_txq_unlock_complete(sc, txq);
+@@ -1487,7 +1482,7 @@ void ath_tx_aggr_wakeup(struct ath_softc
+ ath_txq_lock(sc, txq);
+ ac->clear_ps_filter = true;
+
+- if (!tid->paused && ath_tid_has_buffered(tid)) {
++ if (ath_tid_has_buffered(tid)) {
+ ath_tx_queue_tid(txq, tid);
+ ath_txq_schedule(sc, txq);
+ }
+@@ -1510,7 +1505,6 @@ void ath_tx_aggr_resume(struct ath_softc
+ ath_txq_lock(sc, txq);
- 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);
+ tid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
+- tid->paused = false;
- 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);
- }
+ if (ath_tid_has_buffered(tid)) {
+ ath_tx_queue_tid(txq, tid);
+@@ -1544,8 +1538,6 @@ void ath9k_release_buffered_frames(struc
+ continue;
---- a/net/mac80211/iface.c
-+++ b/net/mac80211/iface.c
-@@ -770,12 +770,19 @@ static void ieee80211_do_stop(struct iee
+ tid = ATH_AN_2_TID(an, i);
+- if (tid->paused)
+- continue;
- ieee80211_roc_purge(local, sdata);
+ ath_txq_lock(sc, tid->ac->txq);
+ while (nframes > 0) {
+@@ -1844,9 +1836,6 @@ void ath_txq_schedule(struct ath_softc *
+ list_del(&tid->list);
+ tid->sched = false;
-- if (sdata->vif.type == NL80211_IFTYPE_STATION)
-+ switch (sdata->vif.type) {
-+ case NL80211_IFTYPE_STATION:
- ieee80211_mgd_stop(sdata);
--
-- if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
-+ break;
-+ case NL80211_IFTYPE_ADHOC:
- ieee80211_ibss_stop(sdata);
+- if (tid->paused)
+- continue;
-
-+ break;
-+ case NL80211_IFTYPE_AP:
-+ cancel_work_sync(&sdata->u.ap.request_smps_work);
-+ break;
-+ default:
-+ break;
-+ }
-
- /*
- * 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);
-
- cancel_work_sync(&sdata->recalc_smps);
-+ sdata_lock(sdata);
- sdata->vif.csa_active = false;
-+ sdata_unlock(sdata);
- cancel_work_sync(&sdata->csa_finalize_work);
-
- 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
+ if (ath_tx_sched_aggr(sc, txq, tid, &stop))
+ sent = true;
+
+@@ -2698,7 +2687,6 @@ void ath_tx_node_init(struct ath_softc *
+ tid->baw_size = WME_MAX_BA;
+ tid->baw_head = tid->baw_tail = 0;
+ tid->sched = false;
+- tid->paused = false;
+ tid->active = false;
+ __skb_queue_head_init(&tid->buf_q);
+ __skb_queue_head_init(&tid->retry_q);
+--- 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_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-
-- if (skb->len < 24 || is_multicast_ether_addr(hdr->addr1))
-+ if (is_multicast_ether_addr(hdr->addr1))
- return 0;
-
-- return ieee80211_is_robust_mgmt_frame(hdr);
-+ return ieee80211_is_robust_mgmt_frame(skb);
+ 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;
}
-
-@@ -610,10 +610,10 @@ static int ieee80211_is_multicast_robust
+-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 ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-
-- if (skb->len < 24 || !is_multicast_ether_addr(hdr->addr1))
-+ if (!is_multicast_ether_addr(hdr->addr1))
- return 0;
+ if (sc->rx.buf_hold)
+- ath_rx_buf_link(sc, sc->rx.buf_hold);
++ ath_rx_buf_link(sc, sc->rx.buf_hold, flush);
-- return ieee80211_is_robust_mgmt_frame(hdr);
-+ return ieee80211_is_robust_mgmt_frame(skb);
+ sc->rx.buf_hold = bf;
}
-
-
-@@ -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;
-
-- if (!ieee80211_is_robust_mgmt_frame((struct ieee80211_hdr *) hdr))
-+ if (!ieee80211_is_robust_mgmt_frame(skb))
- return -1; /* not a robust management frame */
-
- mmie = (struct ieee80211_mmie *)
-@@ -1311,18 +1311,15 @@ ieee80211_rx_h_sta_process(struct ieee80
- !ieee80211_has_morefrags(hdr->frame_control) &&
- !(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) &&
- (rx->sdata->vif.type == NL80211_IFTYPE_AP ||
-- rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) {
-+ rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) &&
-+ /* PM bit is only checked in frames where it isn't reserved,
-+ * in AP mode it's reserved in non-bufferable management frames
-+ * (cf. IEEE 802.11-2012 8.2.4.1.7 Power Management field)
-+ */
-+ (!ieee80211_is_mgmt(hdr->frame_control) ||
-+ ieee80211_is_bufferable_mmpdu(hdr->frame_control))) {
- if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
-- /*
-- * Ignore doze->wake transitions that are
-- * indicated by non-data frames, the standard
-- * is unclear here, but for example going to
-- * PS mode and then scanning would cause a
-- * doze->wake transition for the probe request,
-- * and that is clearly undesirable.
-- */
-- if (ieee80211_is_data(hdr->frame_control) &&
-- !ieee80211_has_pm(hdr->frame_control))
-+ if (!ieee80211_has_pm(hdr->frame_control))
- sta_ps_end(sta);
- } else {
- if (ieee80211_has_pm(hdr->frame_control))
-@@ -1845,8 +1842,7 @@ static int ieee80211_drop_unencrypted_mg
- * having configured keys.
- */
- if (unlikely(ieee80211_is_action(fc) && !rx->key &&
-- ieee80211_is_robust_mgmt_frame(
-- (struct ieee80211_hdr *) rx->skb->data)))
-+ ieee80211_is_robust_mgmt_frame(rx->skb)))
- return -EACCES;
- }
-
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -452,8 +452,7 @@ static int ieee80211_use_mfp(__le16 fc,
- if (sta == NULL || !test_sta_flag(sta, WLAN_STA_MFP))
- return 0;
-
-- if (!ieee80211_is_robust_mgmt_frame((struct ieee80211_hdr *)
-- skb->data))
-+ if (!ieee80211_is_robust_mgmt_frame(skb))
- return 0;
-
- return 1;
-@@ -525,9 +524,7 @@ ieee80211_tx_h_ps_buf(struct ieee80211_t
-
- /* only deauth, disassoc and action are bufferable MMPDUs */
- if (ieee80211_is_mgmt(hdr->frame_control) &&
-- !ieee80211_is_deauth(hdr->frame_control) &&
-- !ieee80211_is_disassoc(hdr->frame_control) &&
-- !ieee80211_is_action(hdr->frame_control)) {
-+ !ieee80211_is_bufferable_mmpdu(hdr->frame_control)) {
- if (tx->flags & IEEE80211_TX_UNICAST)
- info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER;
- return TX_CONTINUE;
-@@ -567,7 +564,7 @@ ieee80211_tx_h_select_key(struct ieee802
- tx->key = key;
- else if (ieee80211_is_mgmt(hdr->frame_control) &&
- is_multicast_ether_addr(hdr->addr1) &&
-- ieee80211_is_robust_mgmt_frame(hdr) &&
-+ ieee80211_is_robust_mgmt_frame(tx->skb) &&
- (key = rcu_dereference(tx->sdata->default_mgmt_key)))
- tx->key = key;
- else if (is_multicast_ether_addr(hdr->addr1) &&
-@@ -582,12 +579,12 @@ ieee80211_tx_h_select_key(struct ieee802
- tx->key = NULL;
- else if (tx->skb->protocol == tx->sdata->control_port_protocol)
- tx->key = NULL;
-- else if (ieee80211_is_robust_mgmt_frame(hdr) &&
-+ else if (ieee80211_is_robust_mgmt_frame(tx->skb) &&
- !(ieee80211_is_action(hdr->frame_control) &&
- tx->sta && test_sta_flag(tx->sta, WLAN_STA_MFP)))
- tx->key = NULL;
- else if (ieee80211_is_mgmt(hdr->frame_control) &&
-- !ieee80211_is_robust_mgmt_frame(hdr))
-+ !ieee80211_is_robust_mgmt_frame(tx->skb))
- tx->key = NULL;
- else {
- I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted);
-@@ -878,7 +875,7 @@ static int ieee80211_fragment(struct iee
- }
-
- /* adjust first fragment's length */
-- skb->len = hdrlen + per_fragm;
-+ skb_trim(skb, hdrlen + per_fragm);
- return 0;
+@@ -106,7 +108,7 @@ static void ath_opmode_init(struct ath_s
}
---- a/net/mac80211/wpa.c
-+++ b/net/mac80211/wpa.c
-@@ -499,7 +499,7 @@ ieee80211_crypto_ccmp_decrypt(struct iee
- hdrlen = ieee80211_hdrlen(hdr->frame_control);
-
- if (!ieee80211_is_data(hdr->frame_control) &&
-- !ieee80211_is_robust_mgmt_frame(hdr))
-+ !ieee80211_is_robust_mgmt_frame(skb))
- return RX_CONTINUE;
-
- data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN -
---- a/net/wireless/ap.c
-+++ b/net/wireless/ap.c
-@@ -27,9 +27,10 @@ static int __cfg80211_stop_ap(struct cfg
- err = rdev_stop_ap(rdev, dev);
- if (!err) {
- wdev->beacon_interval = 0;
-- wdev->channel = NULL;
-+ memset(&wdev->chandef, 0, sizeof(wdev->chandef));
- wdev->ssid_len = 0;
- rdev_set_qos_map(rdev, dev, NULL);
-+ nl80211_send_ap_stopped(wdev);
+ static bool ath_rx_edma_buf_link(struct ath_softc *sc,
+- enum ath9k_rx_qtype qtype)
++ enum ath9k_rx_qtype qtype, bool flush)
+ {
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath_rx_edma *rx_edma;
+@@ -127,7 +129,8 @@ static bool ath_rx_edma_buf_link(struct
+ ah->caps.rx_status_len, DMA_TO_DEVICE);
+
+ SKB_CB_ATHBUF(skb) = bf;
+- ath9k_hw_addrxbuf_edma(ah, bf->bf_buf_addr, qtype);
++ if (!flush)
++ ath9k_hw_addrxbuf_edma(ah, bf->bf_buf_addr, qtype);
+ __skb_queue_tail(&rx_edma->rx_fifo, skb);
+
+ return true;
+@@ -145,7 +148,7 @@ static void ath_rx_addbuffer_edma(struct
}
- return err;
---- a/net/wireless/core.c
-+++ b/net/wireless/core.c
-@@ -203,8 +203,11 @@ void cfg80211_stop_p2p_device(struct cfg
-
- rdev->opencount--;
+ list_for_each_entry_safe(bf, tbf, &sc->rx.rxbuf, list)
+- if (!ath_rx_edma_buf_link(sc, qtype))
++ if (!ath_rx_edma_buf_link(sc, qtype, false))
+ break;
-- WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev &&
-- !rdev->scan_req->notified);
-+ if (rdev->scan_req && rdev->scan_req->wdev == wdev) {
-+ if (WARN_ON(!rdev->scan_req->notified))
-+ rdev->scan_req->aborted = true;
-+ ___cfg80211_scan_done(rdev, false);
-+ }
}
-
- static int cfg80211_rfkill_set_block(void *data, bool blocked)
-@@ -447,9 +450,6 @@ int wiphy_register(struct wiphy *wiphy)
- int i;
- u16 ifmodes = wiphy->interface_modes;
-
-- /* support for 5/10 MHz is broken due to nl80211 API mess - disable */
-- wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_5_10_MHZ;
--
- /*
- * There are major locking problems in nl80211/mac80211 for CSA,
- * disable for all drivers until this has been reworked.
-@@ -875,8 +875,11 @@ static int cfg80211_netdev_notifier_call
- break;
- case NETDEV_DOWN:
- cfg80211_update_iface_num(rdev, wdev->iftype, -1);
-- WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev &&
-- !rdev->scan_req->notified);
-+ if (rdev->scan_req && rdev->scan_req->wdev == wdev) {
-+ if (WARN_ON(!rdev->scan_req->notified))
-+ rdev->scan_req->aborted = true;
-+ ___cfg80211_scan_done(rdev, false);
-+ }
-
- if (WARN_ON(rdev->sched_scan_req &&
- rdev->sched_scan_req->dev == wdev->netdev)) {
---- a/net/wireless/core.h
-+++ b/net/wireless/core.h
-@@ -62,6 +62,7 @@ struct cfg80211_registered_device {
- struct rb_root bss_tree;
- u32 bss_generation;
- struct cfg80211_scan_request *scan_req; /* protected by RTNL */
-+ struct sk_buff *scan_msg;
- struct cfg80211_sched_scan_request *sched_scan_req;
- unsigned long suspend_at;
- struct work_struct scan_done_wk;
-@@ -210,6 +211,7 @@ struct cfg80211_event {
- } dc;
- struct {
- u8 bssid[ETH_ALEN];
-+ struct ieee80211_channel *channel;
- } ij;
- };
- };
-@@ -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,
- struct net_device *dev, bool nowext);
--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);
- int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
- struct wireless_dev *wdev);
-
-@@ -361,7 +364,8 @@ int cfg80211_validate_key_settings(struc
- struct key_params *params, int key_idx,
- bool pairwise, const u8 *mac_addr);
- void __cfg80211_scan_done(struct work_struct *wk);
--void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev);
-+void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev,
-+ bool send_message);
- void __cfg80211_sched_scan_results(struct work_struct *wk);
- int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
- bool driver_initiated);
-@@ -441,7 +445,8 @@ static inline unsigned int elapsed_jiffi
- void
- cfg80211_get_chan_state(struct wireless_dev *wdev,
- struct ieee80211_channel **chan,
-- enum cfg80211_chan_mode *chanmode);
-+ enum cfg80211_chan_mode *chanmode,
-+ u8 *radar_detect);
-
- int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
- struct cfg80211_chan_def *chandef);
---- a/net/wireless/nl80211.c
-+++ b/net/wireless/nl80211.c
-@@ -1723,9 +1723,10 @@ static int nl80211_dump_wiphy(struct sk_
- * We can then retry with the larger buffer.
- */
- if ((ret == -ENOBUFS || ret == -EMSGSIZE) &&
-- !skb->len &&
-+ !skb->len && !state->split &&
- cb->min_dump_alloc < 4096) {
- cb->min_dump_alloc = 4096;
-+ state->split_start = 0;
- rtnl_unlock();
- return 1;
- }
-@@ -2047,10 +2048,12 @@ static int nl80211_set_wiphy(struct sk_b
- nla_for_each_nested(nl_txq_params,
- info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
- rem_txq_params) {
-- nla_parse(tb, NL80211_TXQ_ATTR_MAX,
-- nla_data(nl_txq_params),
-- nla_len(nl_txq_params),
-- txq_params_policy);
-+ result = nla_parse(tb, NL80211_TXQ_ATTR_MAX,
-+ nla_data(nl_txq_params),
-+ nla_len(nl_txq_params),
-+ txq_params_policy);
-+ if (result)
-+ goto bad_res;
- result = parse_txq_params(tb, &txq_params);
- if (result)
- goto bad_res;
-@@ -3289,7 +3292,7 @@ static int nl80211_start_ap(struct sk_bu
- if (!err) {
- wdev->preset_chandef = params.chandef;
- wdev->beacon_interval = params.beacon_interval;
-- wdev->channel = params.chandef.chan;
-+ wdev->chandef = params.chandef;
- wdev->ssid_len = params.ssid_len;
- memcpy(wdev->ssid, params.ssid, wdev->ssid_len);
+@@ -442,7 +445,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);
}
-@@ -5210,9 +5213,11 @@ static int nl80211_set_reg(struct sk_buf
- nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
- rem_reg_rules) {
-- nla_parse(tb, NL80211_REG_RULE_ATTR_MAX,
-- nla_data(nl_reg_rule), nla_len(nl_reg_rule),
-- reg_rule_policy);
-+ r = nla_parse(tb, NL80211_REG_RULE_ATTR_MAX,
-+ nla_data(nl_reg_rule), nla_len(nl_reg_rule),
-+ reg_rule_policy);
-+ if (r)
-+ goto bad_reg;
- r = parse_reg_rule(tb, &rd->reg_rules[rule_idx]);
- if (r)
- goto bad_reg;
-@@ -5277,7 +5282,7 @@ static int nl80211_trigger_scan(struct s
- if (!rdev->ops->scan)
- return -EOPNOTSUPP;
-
-- if (rdev->scan_req) {
-+ if (rdev->scan_req || rdev->scan_msg) {
- err = -EBUSY;
- goto unlock;
- }
-@@ -5475,6 +5480,7 @@ static int nl80211_start_sched_scan(stru
- enum ieee80211_band band;
- size_t ie_len;
- struct nlattr *tb[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1];
-+ s32 default_match_rssi = NL80211_SCAN_RSSI_THOLD_OFF;
-
- if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) ||
- !rdev->ops->sched_scan_start)
-@@ -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
-+ * the old implementation, matchsets containing only the RSSI attribute
-+ * (NL80211_SCHED_SCAN_MATCH_ATTR_RSSI) are considered as the 'default'
-+ * RSSI for all matchsets, rather than their own matchset for reporting
-+ * all APs with a strong RSSI. This is needed to be compatible with
-+ * older userspace that treated a matchset with only the RSSI as the
-+ * global RSSI for all other matchsets - if there are other matchsets.
-+ */
-+ if (info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
- nla_for_each_nested(attr,
- info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
-- tmp)
-- n_match_sets++;
-+ tmp) {
-+ struct nlattr *rssi;
-+
-+ err = nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
-+ nla_data(attr), nla_len(attr),
-+ nl80211_match_policy);
-+ if (err)
-+ return err;
-+ /* add other standalone attributes here */
-+ if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID]) {
-+ n_match_sets++;
-+ continue;
-+ }
-+ rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
-+ if (rssi)
-+ default_match_rssi = nla_get_s32(rssi);
-+ }
-+ }
-+
-+ /* 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;
-
- if (n_match_sets > wiphy->max_match_sets)
- return -EINVAL;
-@@ -5634,11 +5669,22 @@ static int nl80211_start_sched_scan(stru
- tmp) {
- struct nlattr *ssid, *rssi;
-
-- nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
-- nla_data(attr), nla_len(attr),
-- nl80211_match_policy);
-+ err = nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
-+ nla_data(attr), nla_len(attr),
-+ nl80211_match_policy);
-+ if (err)
-+ goto out_free;
- ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID];
- if (ssid) {
-+ if (WARN_ON(i >= n_match_sets)) {
-+ /* this indicates a programming error,
-+ * the loop above should have verified
-+ * things properly
-+ */
-+ err = -EINVAL;
-+ goto out_free;
-+ }
-+
- if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) {
- err = -EINVAL;
- goto out_free;
-@@ -5647,15 +5693,28 @@ static int nl80211_start_sched_scan(stru
- nla_data(ssid), nla_len(ssid));
- request->match_sets[i].ssid.ssid_len =
- nla_len(ssid);
-+ /* special attribute - old implemenation w/a */
-+ request->match_sets[i].rssi_thold =
-+ default_match_rssi;
-+ rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
-+ if (rssi)
-+ request->match_sets[i].rssi_thold =
-+ nla_get_s32(rssi);
- }
-- rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
-- if (rssi)
-- request->rssi_thold = nla_get_u32(rssi);
-- else
-- request->rssi_thold =
-- NL80211_SCAN_RSSI_THOLD_OFF;
- i++;
+ /* We could have deleted elements so the list may be empty now */
+@@ -636,7 +639,7 @@ static bool ath_edma_get_buffers(struct
+ if (ret == -EINVAL) {
+ /* corrupt descriptor, skip this one and the following one */
+ list_add_tail(&bf->list, &sc->rx.rxbuf);
+- ath_rx_edma_buf_link(sc, qtype);
++ ath_rx_edma_buf_link(sc, qtype, false);
+
+ skb = skb_peek(&rx_edma->rx_fifo);
+ if (skb) {
+@@ -645,7 +648,7 @@ static bool ath_edma_get_buffers(struct
+
+ __skb_unlink(skb, &rx_edma->rx_fifo);
+ list_add_tail(&bf->list, &sc->rx.rxbuf);
+- ath_rx_edma_buf_link(sc, qtype);
++ ath_rx_edma_buf_link(sc, qtype, false);
}
-+
-+ /* there was no other matchset, so the RSSI one is alone */
-+ if (i == 0)
-+ request->match_sets[0].rssi_thold = default_match_rssi;
-+
-+ request->min_rssi_thold = INT_MAX;
-+ for (i = 0; i < n_match_sets; i++)
-+ request->min_rssi_thold =
-+ min(request->match_sets[i].rssi_thold,
-+ request->min_rssi_thold);
-+ } else {
-+ request->min_rssi_thold = NL80211_SCAN_RSSI_THOLD_OFF;
- }
- if (info->attrs[NL80211_ATTR_IE]) {
-@@ -5751,7 +5810,7 @@ static int nl80211_start_radar_detection
+ bf = NULL;
+@@ -975,6 +978,7 @@ int ath_rx_tasklet(struct ath_softc *sc,
+ u64 tsf = 0;
+ unsigned long flags;
+ dma_addr_t new_buf_addr;
++ unsigned int budget = 512;
- err = rdev->ops->start_radar_detection(&rdev->wiphy, dev, &chandef);
- if (!err) {
-- wdev->channel = chandef.chan;
-+ wdev->chandef = chandef;
- wdev->cac_started = true;
- wdev->cac_start_time = jiffies;
- }
-@@ -7502,16 +7561,19 @@ static int nl80211_set_tx_bitrate_mask(s
- * directly to the enum ieee80211_band values used in cfg80211.
- */
- BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 8);
-- nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem)
-- {
-+ nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem) {
- enum ieee80211_band band = nla_type(tx_rates);
-+ int err;
+ if (edma)
+ dma_type = DMA_BIDIRECTIONAL;
+@@ -1113,15 +1117,17 @@ requeue_drop_frag:
+ }
+ requeue:
+ list_add_tail(&bf->list, &sc->rx.rxbuf);
+- if (flush)
+- continue;
+
+ if (edma) {
+- ath_rx_edma_buf_link(sc, qtype);
++ ath_rx_edma_buf_link(sc, qtype, flush);
+ } else {
+- ath_rx_buf_relink(sc, bf);
+- ath9k_hw_rxena(ah);
++ ath_rx_buf_relink(sc, bf, flush);
++ if (!flush)
++ ath9k_hw_rxena(ah);
+ }
+
- if (band < 0 || band >= IEEE80211_NUM_BANDS)
- return -EINVAL;
- sband = rdev->wiphy.bands[band];
- if (sband == NULL)
- return -EINVAL;
-- nla_parse(tb, NL80211_TXRATE_MAX, nla_data(tx_rates),
-- nla_len(tx_rates), nl80211_txattr_policy);
-+ err = nla_parse(tb, NL80211_TXRATE_MAX, nla_data(tx_rates),
-+ nla_len(tx_rates), nl80211_txattr_policy);
-+ if (err)
-+ return err;
- if (tb[NL80211_TXRATE_LEGACY]) {
- mask.control[band].legacy = rateset_to_mask(
- sband,
-@@ -10054,40 +10116,31 @@ void nl80211_send_scan_start(struct cfg8
- NL80211_MCGRP_SCAN, GFP_KERNEL);
- }
-
--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,
-+ struct wireless_dev *wdev, bool aborted)
- {
- struct sk_buff *msg;
++ if (!budget--)
++ break;
+ } while (1);
- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
- if (!msg)
-- return;
-+ return NULL;
-
- if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0,
-- NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
-+ aborted ? NL80211_CMD_SCAN_ABORTED :
-+ NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
- nlmsg_free(msg);
-- return;
-+ return NULL;
+ if (!(ah->imask & ATH9K_INT_RXEOL)) {
+@@ -1129,5 +1135,5 @@ requeue:
+ ath9k_hw_set_interrupts(ah);
}
-- genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
-- NL80211_MCGRP_SCAN, GFP_KERNEL);
-+ return msg;
- }
-
--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)
- {
-- struct sk_buff *msg;
--
-- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
- if (!msg)
- return;
-
-- if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0,
-- NL80211_CMD_SCAN_ABORTED) < 0) {
-- nlmsg_free(msg);
-- return;
-- }
--
- genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
- NL80211_MCGRP_SCAN, GFP_KERNEL);
- }
-@@ -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;
- nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL);
- }
- EXPORT_SYMBOL(cfg80211_ch_switch_notify);
-@@ -11673,6 +11727,35 @@ void cfg80211_crit_proto_stopped(struct
- }
- EXPORT_SYMBOL(cfg80211_crit_proto_stopped);
-
-+void nl80211_send_ap_stopped(struct wireless_dev *wdev)
-+{
-+ struct wiphy *wiphy = wdev->wiphy;
-+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
-+ struct sk_buff *msg;
-+ void *hdr;
-+
-+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
-+ if (!msg)
-+ return;
-+
-+ hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_STOP_AP);
-+ if (!hdr)
-+ goto out;
-+
-+ 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;
-+
-+ genlmsg_end(msg, hdr);
-+
-+ genlmsg_multicast_netns(&nl80211_fam, wiphy_net(wiphy), msg, 0,
-+ NL80211_MCGRP_MLME, GFP_KERNEL);
-+ return;
-+ out:
-+ nlmsg_free(msg);
-+}
-+
- /* initialisation/exit functions */
-
- int nl80211_init(void)
---- a/net/wireless/nl80211.h
-+++ b/net/wireless/nl80211.h
-@@ -8,10 +8,10 @@ void nl80211_exit(void);
- void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev);
- void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
- struct wireless_dev *wdev);
--void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
-- struct wireless_dev *wdev);
--void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
-- struct wireless_dev *wdev);
-+struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev,
-+ struct wireless_dev *wdev, bool aborted);
-+void nl80211_send_scan_result(struct cfg80211_registered_device *rdev,
-+ struct sk_buff *msg);
- void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
- struct net_device *netdev, u32 cmd);
- void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
-@@ -74,6 +74,8 @@ nl80211_radar_notify(struct cfg80211_reg
- enum nl80211_radar_event event,
- struct net_device *netdev, gfp_t gfp);
-
-+void nl80211_send_ap_stopped(struct wireless_dev *wdev);
-+
- void cfg80211_rdev_free_coalesce(struct cfg80211_registered_device *rdev);
-
- #endif /* __NET_WIRELESS_NL80211_H */
---- a/net/wireless/scan.c
-+++ b/net/wireless/scan.c
-@@ -161,18 +161,25 @@ static void __cfg80211_bss_expire(struct
- dev->bss_generation++;
+- return 0;
++ return !budget;
}
+--- a/drivers/net/wireless/ath/ath9k/ahb.c
++++ b/drivers/net/wireless/ath/ath9k/ahb.c
+@@ -86,7 +86,6 @@ static int ath_ahb_probe(struct platform
+ int irq;
+ int ret = 0;
+ struct ath_hw *ah;
+- struct ath_common *common;
+ char hw_name[64];
+
+ if (!dev_get_platdata(&pdev->dev)) {
+@@ -146,9 +145,6 @@ static int ath_ahb_probe(struct platform
+ wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n",
+ hw_name, (unsigned long)mem, irq);
+
+- common = ath9k_hw_common(sc->sc_ah);
+- /* Will be cleared in ath9k_start() */
+- set_bit(ATH_OP_INVALID, &common->op_flags);
+ return 0;
--void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev)
-+void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev,
-+ bool send_message)
- {
- struct cfg80211_scan_request *request;
- struct wireless_dev *wdev;
-+ struct sk_buff *msg;
- #ifdef CPTCFG_CFG80211_WEXT
- union iwreq_data wrqu;
- #endif
-
- ASSERT_RTNL();
-
-- request = rdev->scan_req;
-+ if (rdev->scan_msg) {
-+ nl80211_send_scan_result(rdev, rdev->scan_msg);
-+ rdev->scan_msg = NULL;
-+ return;
-+ }
-
-+ request = rdev->scan_req;
- if (!request)
- return;
-
-@@ -186,18 +193,16 @@ void ___cfg80211_scan_done(struct cfg802
- if (wdev->netdev)
- cfg80211_sme_scan_done(wdev->netdev);
-
-- if (request->aborted) {
-- nl80211_send_scan_aborted(rdev, wdev);
-- } else {
-- if (request->flags & NL80211_SCAN_FLAG_FLUSH) {
-- /* flush entries from previous scans */
-- spin_lock_bh(&rdev->bss_lock);
-- __cfg80211_bss_expire(rdev, request->scan_start);
-- spin_unlock_bh(&rdev->bss_lock);
-- }
-- nl80211_send_scan_done(rdev, wdev);
-+ if (!request->aborted &&
-+ request->flags & NL80211_SCAN_FLAG_FLUSH) {
-+ /* flush entries from previous scans */
-+ spin_lock_bh(&rdev->bss_lock);
-+ __cfg80211_bss_expire(rdev, request->scan_start);
-+ spin_unlock_bh(&rdev->bss_lock);
+ err_irq:
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -670,6 +670,7 @@ static const struct ieee80211_iface_comb
+ .num_different_channels = 1,
+ .beacon_int_infra_match = true,
+ },
++#ifdef CONFIG_ATH9K_DFS_CERTIFIED
+ {
+ .limits = if_dfs_limits,
+ .n_limits = ARRAY_SIZE(if_dfs_limits),
+@@ -679,6 +680,7 @@ static const struct ieee80211_iface_comb
+ .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
+ BIT(NL80211_CHAN_WIDTH_20),
}
++#endif
+ };
-+ 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
+ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
+@@ -781,6 +783,9 @@ int ath9k_init_device(u16 devid, struct
+ common = ath9k_hw_common(ah);
+ ath9k_set_hw_capab(sc, hw);
- rdev->scan_req = NULL;
- kfree(request);
++ /* Will be cleared in ath9k_start() */
++ set_bit(ATH_OP_INVALID, &common->op_flags);
+
-+ if (!send_message)
-+ rdev->scan_msg = msg;
-+ else
-+ nl80211_send_scan_result(rdev, msg);
- }
-
- void __cfg80211_scan_done(struct work_struct *wk)
-@@ -221,7 +231,7 @@ void __cfg80211_scan_done(struct work_st
- scan_done_wk);
-
- rtnl_lock();
-- ___cfg80211_scan_done(rdev);
-+ ___cfg80211_scan_done(rdev, true);
- rtnl_unlock();
- }
-
-@@ -1079,7 +1089,7 @@ int cfg80211_wext_siwscan(struct net_dev
- if (IS_ERR(rdev))
- return PTR_ERR(rdev);
-
-- if (rdev->scan_req) {
-+ if (rdev->scan_req || rdev->scan_msg) {
- err = -EBUSY;
- goto out;
- }
-@@ -1481,7 +1491,7 @@ int cfg80211_wext_giwscan(struct net_dev
- if (IS_ERR(rdev))
- return PTR_ERR(rdev);
-
-- if (rdev->scan_req)
-+ if (rdev->scan_req || rdev->scan_msg)
- return -EAGAIN;
-
- 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);
-
-- if (rdev->scan_req)
-+ if (rdev->scan_req || rdev->scan_msg)
- return -EBUSY;
-
- if (wdev->conn->params.channel)
---- a/net/mac80211/mlme.c
-+++ b/net/mac80211/mlme.c
-@@ -1001,7 +1001,6 @@ ieee80211_sta_process_chanswitch(struct
- }
-
- ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED;
-- sdata->vif.csa_active = true;
-
- mutex_lock(&local->chanctx_mtx);
- if (local->use_chanctx) {
-@@ -1039,6 +1038,7 @@ ieee80211_sta_process_chanswitch(struct
- mutex_unlock(&local->chanctx_mtx);
-
- sdata->csa_chandef = csa_ie.chandef;
-+ sdata->vif.csa_active = true;
-
- 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(
+ /* Initialize regulatory */
+ error = ath_regd_init(&common->regulatory, sc->hw->wiphy,
+ ath9k_reg_notifier);
+--- a/drivers/net/wireless/ath/ath9k/pci.c
++++ b/drivers/net/wireless/ath/ath9k/pci.c
+@@ -784,7 +784,6 @@ static int ath_pci_probe(struct pci_dev
{
- struct ieee80211_sub_if_data *sdata;
+ struct ath_softc *sc;
+ struct ieee80211_hw *hw;
+- struct ath_common *common;
+ u8 csz;
+ u32 val;
+ int ret = 0;
+@@ -877,10 +876,6 @@ static int ath_pci_probe(struct pci_dev
+ wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n",
+ hw_name, (unsigned long)sc->mem, pdev->irq);
+
+- /* Will be cleared in ath9k_start() */
+- common = ath9k_hw_common(sc->sc_ah);
+- set_bit(ATH_OP_INVALID, &common->op_flags);
+-
+ return 0;
-+ lockdep_assert_held(&local->mtx);
-+
- rcu_read_lock();
- list_for_each_entry_rcu(sdata, &local->interfaces, list) {
- if (sdata->radar_required) {
---- a/net/mac80211/ibss.c
-+++ b/net/mac80211/ibss.c
-@@ -294,7 +294,6 @@ static void __ieee80211_sta_join_ibss(st
+ err_init:
+--- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
++++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
+@@ -410,7 +410,7 @@ static const u32 ar9300_2p2_baseband_cor
+ {0x00009e30, 0x06336f77},
+ {0x00009e34, 0x6af6532f},
+ {0x00009e38, 0x0cc80c00},
+- {0x00009e40, 0x0d261820},
++ {0x00009e40, 0x0d261800},
+ {0x00009e4c, 0x00001004},
+ {0x00009e50, 0x00ff03f1},
+ {0x00009e54, 0x00000000},
+--- a/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h
++++ b/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h
+@@ -592,7 +592,7 @@ static const u32 ar9331_1p1_baseband_cor
+ {0x00009e30, 0x06336f77},
+ {0x00009e34, 0x6af6532f},
+ {0x00009e38, 0x0cc80c00},
+- {0x00009e40, 0x0d261820},
++ {0x00009e40, 0x0d261800},
+ {0x00009e4c, 0x00001004},
+ {0x00009e50, 0x00ff03f1},
+ {0x00009fc0, 0x803e4788},
+--- a/drivers/net/wireless/ath/ath9k/ar9330_1p2_initvals.h
++++ b/drivers/net/wireless/ath/ath9k/ar9330_1p2_initvals.h
+@@ -231,7 +231,7 @@ static const u32 ar9331_1p2_baseband_cor
+ {0x00009e30, 0x06336f77},
+ {0x00009e34, 0x6af6532f},
+ {0x00009e38, 0x0cc80c00},
+- {0x00009e40, 0x0d261820},
++ {0x00009e40, 0x0d261800},
+ {0x00009e4c, 0x00001004},
+ {0x00009e50, 0x00ff03f1},
+ {0x00009fc0, 0x803e4788},
+--- a/drivers/net/wireless/ath/ath9k/ar9340_initvals.h
++++ b/drivers/net/wireless/ath/ath9k/ar9340_initvals.h
+@@ -318,7 +318,7 @@ static const u32 ar9340_1p0_baseband_cor
+ {0x00009e30, 0x06336f77},
+ {0x00009e34, 0x6af6532f},
+ {0x00009e38, 0x0cc80c00},
+- {0x00009e40, 0x0d261820},
++ {0x00009e40, 0x0d261800},
+ {0x00009e4c, 0x00001004},
+ {0x00009e50, 0x00ff03f1},
+ {0x00009e54, 0x00000000},
+@@ -348,9 +348,9 @@ static const u32 ar9340_1p0_baseband_cor
+ {0x0000a370, 0x00000000},
+ {0x0000a390, 0x00000001},
+ {0x0000a394, 0x00000444},
+- {0x0000a398, 0x00000000},
+- {0x0000a39c, 0x210d0401},
+- {0x0000a3a0, 0xab9a7144},
++ {0x0000a398, 0x001f0e0f},
++ {0x0000a39c, 0x0075393f},
++ {0x0000a3a0, 0xb79f6427},
+ {0x0000a3a4, 0x00000000},
+ {0x0000a3a8, 0xaaaaaaaa},
+ {0x0000a3ac, 0x3c466478},
+--- a/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
++++ b/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
+@@ -90,7 +90,7 @@ static const u32 ar9580_1p0_baseband_cor
+ {0x00009e30, 0x06336f77},
+ {0x00009e34, 0x6af6532f},
+ {0x00009e38, 0x0cc80c00},
+- {0x00009e40, 0x0d261820},
++ {0x00009e40, 0x0d261800},
+ {0x00009e4c, 0x00001004},
+ {0x00009e50, 0x00ff03f1},
+ {0x00009e54, 0x00000000},
+--- a/drivers/net/wireless/ath/ath9k/ar953x_initvals.h
++++ b/drivers/net/wireless/ath/ath9k/ar953x_initvals.h
+@@ -257,9 +257,9 @@ static const u32 qca953x_1p0_baseband_co
+ {0x0000a370, 0x00000000},
+ {0x0000a390, 0x00000001},
+ {0x0000a394, 0x00000444},
+- {0x0000a398, 0x1f020503},
+- {0x0000a39c, 0x29180c03},
+- {0x0000a3a0, 0x9a8b6844},
++ {0x0000a398, 0x001f0e0f},
++ {0x0000a39c, 0x0075393f},
++ {0x0000a3a0, 0xb79f6427},
+ {0x0000a3a4, 0x000000ff},
+ {0x0000a3a8, 0x6a6a6a6a},
+ {0x0000a3ac, 0x6a6a6a6a},
+--- a/drivers/net/wireless/ath/ath5k/phy.c
++++ b/drivers/net/wireless/ath/ath5k/phy.c
+@@ -3709,8 +3709,8 @@ ath5k_hw_txpower(struct ath5k_hw *ah, st
+ AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_CHIRP),
+ AR5K_TPC);
+ } else {
+- ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX |
+- AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX);
++ ath5k_hw_reg_write(ah, AR5K_TUNE_MAX_TXPOWER,
++ AR5K_PHY_TXPOWER_RATE_MAX);
}
- mutex_lock(&local->mtx);
-- ieee80211_vif_release_channel(sdata);
- if (ieee80211_vif_use_channel(sdata, &chandef,
- ifibss->fixed_channel ?
- IEEE80211_CHANCTX_SHARED :
-@@ -303,6 +302,7 @@ static void __ieee80211_sta_join_ibss(st
- mutex_unlock(&local->mtx);
- return;
+ return 0;
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -1231,7 +1231,8 @@ ieee80211_rx_h_sta_process(struct ieee80
+ if (ether_addr_equal(bssid, rx->sdata->u.ibss.bssid) &&
+ test_sta_flag(sta, WLAN_STA_AUTHORIZED)) {
+ sta->last_rx = jiffies;
+- if (ieee80211_is_data(hdr->frame_control)) {
++ if (ieee80211_is_data(hdr->frame_control) &&
++ !is_multicast_ether_addr(hdr->addr1)) {
+ sta->last_rx_rate_idx = status->rate_idx;
+ sta->last_rx_rate_flag = status->flag;
+ sta->last_rx_rate_vht_flag = status->vht_flag;
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -442,6 +442,8 @@ void ath9k_tasklet(unsigned long data)
+ ath9k_ps_wakeup(sc);
+ spin_lock(&sc->sc_pcu_lock);
+
++ sc->intrstatus = 0;
++
+ if (status & ATH9K_INT_FATAL) {
+ type = RESET_TYPE_FATAL_INT;
+ ath9k_queue_reset(sc, type);
+@@ -510,10 +512,12 @@ void ath9k_tasklet(unsigned long data)
+ if (status & rxmask) {
+ /* Check for high priority Rx first */
+ if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
+- (status & ATH9K_INT_RXHP))
+- ath_rx_tasklet(sc, 0, true);
++ (status & ATH9K_INT_RXHP) &&
++ ath_rx_tasklet(sc, 0, true))
++ sc->intrstatus |= ATH9K_INT_RXHP;
+
+- ath_rx_tasklet(sc, 0, false);
++ if (ath_rx_tasklet(sc, 0, false))
++ sc->intrstatus |= ATH9K_INT_RXLP;
}
-+ sdata->radar_required = radar_required;
- mutex_unlock(&local->mtx);
-
- memcpy(ifibss->bssid, bssid, ETH_ALEN);
-@@ -318,7 +318,6 @@ static void __ieee80211_sta_join_ibss(st
- rcu_assign_pointer(ifibss->presp, presp);
- mgmt = (void *)presp->head;
-
-- sdata->radar_required = radar_required;
- sdata->vif.bss_conf.enable_beacon = true;
- sdata->vif.bss_conf.beacon_int = beacon_int;
- sdata->vif.bss_conf.basic_rates = basic_rates;
-@@ -386,7 +385,7 @@ static void __ieee80211_sta_join_ibss(st
- presp->head_len, 0, GFP_KERNEL);
- cfg80211_put_bss(local->hw.wiphy, bss);
- netif_carrier_on(sdata->dev);
-- cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL);
-+ cfg80211_ibss_joined(sdata->dev, ifibss->bssid, chan, GFP_KERNEL);
- }
-
- 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;
-
-+ sdata_assert_lock(sdata);
-+
- sta_flags = IEEE80211_STA_DISABLE_VHT;
- switch (ifibss->chandef.width) {
- case NL80211_CHAN_WIDTH_5:
-@@ -1471,6 +1472,11 @@ static void ieee80211_rx_mgmt_probe_req(
- 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;
-+
-+ /* avoid excessive retries for probe request to wildcard SSIDs */
-+ if (pos[1] == 0)
-+ IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_NO_ACK;
-+
- ieee80211_tx_skb(sdata, skb);
- }
-
---- a/net/mac80211/mesh.c
-+++ b/net/mac80211/mesh.c
-@@ -872,6 +872,8 @@ ieee80211_mesh_process_chnswitch(struct
- if (!ifmsh->mesh_id)
- return false;
-
-+ sdata_assert_lock(sdata);
-+
- sta_flags = IEEE80211_STA_DISABLE_VHT;
- switch (sdata->vif.bss_conf.chandef.width) {
- case NL80211_CHAN_WIDTH_20_NOHT:
---- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
-+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
-@@ -4658,6 +4658,7 @@ brcmf_notify_connect_status(struct brcmf
- struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
- struct net_device *ndev = ifp->ndev;
- struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
-+ struct ieee80211_channel *chan;
- s32 err = 0;
-
- if (ifp->vif->mode == WL_MODE_AP) {
-@@ -4665,9 +4666,10 @@ brcmf_notify_connect_status(struct brcmf
- } else if (brcmf_is_linkup(e)) {
- brcmf_dbg(CONN, "Linkup\n");
- if (brcmf_is_ibssmode(ifp->vif)) {
-+ chan = ieee80211_get_channel(cfg->wiphy, cfg->channel);
- memcpy(profile->bssid, e->addr, ETH_ALEN);
- wl_inform_ibss(cfg, ndev, e->addr);
-- cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
-+ cfg80211_ibss_joined(ndev, e->addr, chan, GFP_KERNEL);
- clear_bit(BRCMF_VIF_STATUS_CONNECTING,
- &ifp->vif->sme_state);
- set_bit(BRCMF_VIF_STATUS_CONNECTED,
---- a/drivers/net/wireless/libertas/cfg.c
-+++ b/drivers/net/wireless/libertas/cfg.c
-@@ -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;
-
-- cfg80211_ibss_joined(priv->dev, bssid, GFP_KERNEL);
-+ cfg80211_ibss_joined(priv->dev, bssid, params->chandef.chan,
-+ GFP_KERNEL);
-
- /* TODO: consider doing this at MACREG_INT_CODE_LINK_SENSED time */
- priv->connect_status = LBS_CONNECTED;
---- a/drivers/net/wireless/mwifiex/cfg80211.c
-+++ b/drivers/net/wireless/mwifiex/cfg80211.c
-@@ -1881,7 +1881,8 @@ mwifiex_cfg80211_join_ibss(struct wiphy
- params->privacy);
- done:
- if (!ret) {
-- cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, GFP_KERNEL);
-+ cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid,
-+ params->chandef.chan, GFP_KERNEL);
- dev_dbg(priv->adapter->dev,
- "info: joined/created adhoc network with bssid"
- " %pM successfully\n", priv->cfg_bssid);
---- a/drivers/net/wireless/rndis_wlan.c
-+++ b/drivers/net/wireless/rndis_wlan.c
-@@ -2835,7 +2835,9 @@ static void rndis_wlan_do_link_up_work(s
- bssid, req_ie, req_ie_len,
- resp_ie, resp_ie_len, GFP_KERNEL);
- } else if (priv->infra_mode == NDIS_80211_INFRA_ADHOC)
-- cfg80211_ibss_joined(usbdev->net, bssid, GFP_KERNEL);
-+ cfg80211_ibss_joined(usbdev->net, bssid,
-+ get_current_channel(usbdev, NULL),
-+ GFP_KERNEL);
-
- kfree(info);
-
---- a/net/wireless/ibss.c
-+++ b/net/wireless/ibss.c
-@@ -14,7 +14,8 @@
- #include "rdev-ops.h"
+ if (status & ATH9K_INT_TX) {
+@@ -541,6 +545,9 @@ void ath9k_tasklet(unsigned long data)
--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)
- {
- 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;
-
-- 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);
-
- if (WARN_ON(!bss))
-@@ -54,21 +54,26 @@ void __cfg80211_ibss_joined(struct net_d
- #endif
- }
-
--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)
- {
- struct wireless_dev *wdev = dev->ieee80211_ptr;
- struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
- struct cfg80211_event *ev;
- unsigned long flags;
-
-- trace_cfg80211_ibss_joined(dev, bssid);
-+ trace_cfg80211_ibss_joined(dev, bssid, channel);
-+
-+ if (WARN_ON(!channel))
-+ return;
-
- ev = kzalloc(sizeof(*ev), gfp);
- if (!ev)
- return;
-
- ev->type = EVENT_IBSS_JOINED;
-- memcpy(ev->cr.bssid, bssid, ETH_ALEN);
-+ memcpy(ev->ij.bssid, bssid, ETH_ALEN);
-+ ev->ij.channel = channel;
-
- 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
-
- wdev->ibss_fixed = params->channel_fixed;
- wdev->ibss_dfs_possible = params->userspace_handles_dfs;
-+ wdev->chandef = params->chandef;
- #ifdef CPTCFG_CFG80211_WEXT
- wdev->wext.ibss.chandef = params->chandef;
- #endif
-@@ -200,6 +206,7 @@ static void __cfg80211_clear_ibss(struct
-
- wdev->current_bss = NULL;
- wdev->ssid_len = 0;
-+ memset(&wdev->chandef, 0, sizeof(wdev->chandef));
- #ifdef CPTCFG_CFG80211_WEXT
- if (!nowext)
- wdev->wext.ibss.ssid_len = 0;
---- a/net/wireless/trace.h
-+++ b/net/wireless/trace.h
-@@ -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))
- );
-
--DEFINE_EVENT(cfg80211_rx_evt, cfg80211_ibss_joined,
-- TP_PROTO(struct net_device *netdev, const u8 *addr),
-- TP_ARGS(netdev, addr)
--);
--
- DEFINE_EVENT(cfg80211_rx_evt, cfg80211_rx_spurious_frame,
- TP_PROTO(struct net_device *netdev, const u8 *addr),
- TP_ARGS(netdev, addr)
-@@ -2293,6 +2288,24 @@ DEFINE_EVENT(cfg80211_rx_evt, cfg80211_r
- TP_ARGS(netdev, addr)
- );
-
-+TRACE_EVENT(cfg80211_ibss_joined,
-+ TP_PROTO(struct net_device *netdev, const u8 *bssid,
-+ struct ieee80211_channel *channel),
-+ TP_ARGS(netdev, bssid, channel),
-+ TP_STRUCT__entry(
-+ NETDEV_ENTRY
-+ MAC_ENTRY(bssid)
-+ CHAN_ENTRY
-+ ),
-+ TP_fast_assign(
-+ NETDEV_ASSIGN;
-+ MAC_ASSIGN(bssid, bssid);
-+ CHAN_ASSIGN(channel);
-+ ),
-+ TP_printk(NETDEV_PR_FMT ", bssid: " MAC_PR_FMT ", " CHAN_PR_FMT,
-+ NETDEV_PR_ARG, MAC_PR_ARG(bssid), CHAN_PR_ARG)
-+);
-+
- TRACE_EVENT(cfg80211_probe_status,
- TP_PROTO(struct net_device *netdev, const u8 *addr, u64 cookie,
- bool acked),
---- a/net/wireless/util.c
-+++ b/net/wireless/util.c
-@@ -820,7 +820,8 @@ void cfg80211_process_wdev_events(struct
- ev->dc.reason, true);
- break;
- case EVENT_IBSS_JOINED:
-- __cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid);
-+ __cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid,
-+ ev->ij.channel);
- break;
- }
- wdev_unlock(wdev);
-@@ -1356,7 +1357,7 @@ int cfg80211_can_use_iftype_chan(struct
- */
- mutex_lock_nested(&wdev_iter->mtx, 1);
- __acquire(wdev_iter->mtx);
-- cfg80211_get_chan_state(wdev_iter, &ch, &chmode);
-+ cfg80211_get_chan_state(wdev_iter, &ch, &chmode, &radar_detect);
- wdev_unlock(wdev_iter);
-
- switch (chmode) {
---- a/net/wireless/chan.c
-+++ b/net/wireless/chan.c
-@@ -642,7 +642,8 @@ int cfg80211_set_monitor_channel(struct
- void
- cfg80211_get_chan_state(struct wireless_dev *wdev,
- struct ieee80211_channel **chan,
-- enum cfg80211_chan_mode *chanmode)
-+ enum cfg80211_chan_mode *chanmode,
-+ u8 *radar_detect)
- {
- *chan = NULL;
- *chanmode = CHAN_MODE_UNDEFINED;
-@@ -660,6 +661,11 @@ cfg80211_get_chan_state(struct wireless_
- !wdev->ibss_dfs_possible)
- ? CHAN_MODE_SHARED
- : CHAN_MODE_EXCLUSIVE;
-+
-+ /* consider worst-case - IBSS can try to return to the
-+ * original user-specified channel as creator */
-+ if (wdev->ibss_dfs_possible)
-+ *radar_detect |= BIT(wdev->chandef.width);
- return;
- }
- break;
-@@ -674,17 +680,26 @@ cfg80211_get_chan_state(struct wireless_
- case NL80211_IFTYPE_AP:
- case NL80211_IFTYPE_P2P_GO:
- if (wdev->cac_started) {
-- *chan = wdev->channel;
-+ *chan = wdev->chandef.chan;
- *chanmode = CHAN_MODE_SHARED;
-+ *radar_detect |= BIT(wdev->chandef.width);
- } else if (wdev->beacon_interval) {
-- *chan = wdev->channel;
-+ *chan = wdev->chandef.chan;
- *chanmode = CHAN_MODE_SHARED;
-+
-+ if (cfg80211_chandef_dfs_required(wdev->wiphy,
-+ &wdev->chandef))
-+ *radar_detect |= BIT(wdev->chandef.width);
- }
- return;
- case NL80211_IFTYPE_MESH_POINT:
- if (wdev->mesh_id_len) {
-- *chan = wdev->channel;
-+ *chan = wdev->chandef.chan;
- *chanmode = CHAN_MODE_SHARED;
+ /* re-enable hardware interrupt */
+ ath9k_hw_enable_interrupts(ah);
++ if (sc->intrstatus)
++ tasklet_schedule(&sc->intr_tq);
+
-+ if (cfg80211_chandef_dfs_required(wdev->wiphy,
-+ &wdev->chandef))
-+ *radar_detect |= BIT(wdev->chandef.width);
- }
- return;
- case NL80211_IFTYPE_MONITOR:
---- a/net/wireless/mesh.c
-+++ b/net/wireless/mesh.c
-@@ -195,7 +195,7 @@ int __cfg80211_join_mesh(struct cfg80211
- if (!err) {
- memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len);
- wdev->mesh_id_len = setup->mesh_id_len;
-- wdev->channel = setup->chandef.chan;
-+ wdev->chandef = setup->chandef;
- }
-
- return err;
-@@ -244,7 +244,7 @@ int cfg80211_set_mesh_channel(struct cfg
- err = rdev_libertas_set_mesh_channel(rdev, wdev->netdev,
- chandef->chan);
- if (!err)
-- wdev->channel = chandef->chan;
-+ wdev->chandef = *chandef;
-
- return err;
- }
-@@ -276,7 +276,7 @@ static int __cfg80211_leave_mesh(struct
- err = rdev_leave_mesh(rdev, dev);
- if (!err) {
- wdev->mesh_id_len = 0;
-- wdev->channel = NULL;
-+ memset(&wdev->chandef, 0, sizeof(wdev->chandef));
- rdev_set_qos_map(rdev, dev, NULL);
- }
+ out:
+ spin_unlock(&sc->sc_pcu_lock);
+ ath9k_ps_restore(sc);
+@@ -607,7 +614,7 @@ irqreturn_t ath_isr(int irq, void *dev)
+ return IRQ_NONE;
---- 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;
-
-- if (WARN_ON(!wdev->channel))
-+ if (WARN_ON(!wdev->chandef.chan))
- return;
+ /* Cache the status */
+- sc->intrstatus = status;
++ sc->intrstatus |= status;
- switch (event) {
+ if (status & SCHED_INTR)
+ sched = true;