| From 4d9fa6f7f7fb48afe1b0aab4b82d279d2ac45c09 Mon Sep 17 00:00:00 2001 |
| From: Sergey Matyukevich <sergey.matyukevich.os@quantenna.com> |
| Date: Tue, 26 Mar 2019 09:27:37 +0000 |
| Subject: mac80211/cfg80211: update bss channel on channel switch |
| |
| [ Upstream commit 5dc8cdce1d722c733f8c7af14c5fb595cfedbfa8 ] |
| |
| FullMAC STAs have no way to update bss channel after CSA channel switch |
| completion. As a result, user-space tools may provide inconsistent |
| channel info. For instance, consider the following two commands: |
| $ sudo iw dev wlan0 link |
| $ sudo iw dev wlan0 info |
| The latter command gets channel info from the hardware, so most probably |
| its output will be correct. However the former command gets channel info |
| from scan cache, so its output will contain outdated channel info. |
| In fact, current bss channel info will not be updated until the |
| next [re-]connect. |
| |
| Note that mac80211 STAs have a workaround for this, but it requires |
| access to internal cfg80211 data, see ieee80211_chswitch_work: |
| |
| /* XXX: shouldn't really modify cfg80211-owned data! */ |
| ifmgd->associated->channel = sdata->csa_chandef.chan; |
| |
| This patch suggests to convert mac80211 workaround into cfg80211 behavior |
| and to update current bss channel in cfg80211_ch_switch_notify. |
| |
| Signed-off-by: Sergey Matyukevich <sergey.matyukevich.os@quantenna.com> |
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| net/mac80211/mlme.c | 3 --- |
| net/wireless/nl80211.c | 5 +++++ |
| 2 files changed, 5 insertions(+), 3 deletions(-) |
| |
| diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c |
| index 6878215672871..715ab0e6579cb 100644 |
| --- a/net/mac80211/mlme.c |
| +++ b/net/mac80211/mlme.c |
| @@ -1167,9 +1167,6 @@ static void ieee80211_chswitch_work(struct work_struct *work) |
| goto out; |
| } |
| |
| - /* XXX: shouldn't really modify cfg80211-owned data! */ |
| - ifmgd->associated->channel = sdata->csa_chandef.chan; |
| - |
| ifmgd->csa_waiting_bcn = true; |
| |
| ieee80211_sta_reset_beacon_monitor(sdata); |
| diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c |
| index 156ce708b5330..0044bfb526abc 100644 |
| --- a/net/wireless/nl80211.c |
| +++ b/net/wireless/nl80211.c |
| @@ -15667,6 +15667,11 @@ void cfg80211_ch_switch_notify(struct net_device *dev, |
| |
| wdev->chandef = *chandef; |
| wdev->preset_chandef = *chandef; |
| + |
| + if (wdev->iftype == NL80211_IFTYPE_STATION && |
| + !WARN_ON(!wdev->current_bss)) |
| + wdev->current_bss->pub.channel = chandef->chan; |
| + |
| nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL, |
| NL80211_CMD_CH_SWITCH_NOTIFY, 0); |
| } |
| -- |
| 2.20.1 |
| |