| From 199fe414aee9db03658cc76e589ae2906d05e729 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 2dbcf5d5512ef..b7a9fe3d5fcb7 100644 |
| --- a/net/mac80211/mlme.c |
| +++ b/net/mac80211/mlme.c |
| @@ -1188,9 +1188,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 47e30a58566c2..d2a7459a5da43 100644 |
| --- a/net/wireless/nl80211.c |
| +++ b/net/wireless/nl80211.c |
| @@ -15727,6 +15727,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 |
| |