mirror of https://gitee.com/openkylin/linux.git
mac80211: fix managed mode BSSID handling
Currently, we will ask the driver to configure right away when somebody changes the desired BSSID. That's totally strange because then we will configure the driver without even knowing whether the BSS exists. Change this to only configure the BSSID when associated, and configure a zero BSSID when not associated. As a side effect, this fixes an issue with the iwlwifi driver which doesn't implement sta_notify properly and uses the BSSID instead and gets very confused if the BSSID is cleared before we disassociate, which results in the warning Marcel posted [1] and iwlwifi bug 1995 [2]. [1] http://thread.gmane.org/gmane.linux.kernel.wireless.general/32598 [2] http://www.intellinuxwireless.org/bugzilla/show_bug.cgi?id=1995 Cc: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
bbcf3f0277
commit
9cef873798
|
@ -219,18 +219,26 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
|
|||
u32 changed)
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
static const u8 zero[ETH_ALEN] = { 0 };
|
||||
|
||||
if (!changed)
|
||||
return;
|
||||
|
||||
if (sdata->vif.type == NL80211_IFTYPE_STATION)
|
||||
sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid;
|
||||
else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
|
||||
if (sdata->vif.type == NL80211_IFTYPE_STATION) {
|
||||
/*
|
||||
* While not associated, claim a BSSID of all-zeroes
|
||||
* so that drivers don't do any weird things with the
|
||||
* BSSID at that time.
|
||||
*/
|
||||
if (sdata->vif.bss_conf.assoc)
|
||||
sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid;
|
||||
else
|
||||
sdata->vif.bss_conf.bssid = zero;
|
||||
} else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
|
||||
sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid;
|
||||
else if (sdata->vif.type == NL80211_IFTYPE_AP)
|
||||
sdata->vif.bss_conf.bssid = sdata->dev->dev_addr;
|
||||
else if (ieee80211_vif_is_mesh(&sdata->vif)) {
|
||||
static const u8 zero[ETH_ALEN] = { 0 };
|
||||
sdata->vif.bss_conf.bssid = zero;
|
||||
} else {
|
||||
WARN_ON(1);
|
||||
|
|
|
@ -977,6 +977,10 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
|
|||
* changed or not.
|
||||
*/
|
||||
bss_info_changed |= BSS_CHANGED_BASIC_RATES;
|
||||
|
||||
/* And the BSSID changed - we're associated now */
|
||||
bss_info_changed |= BSS_CHANGED_BSSID;
|
||||
|
||||
ieee80211_bss_info_change_notify(sdata, bss_info_changed);
|
||||
|
||||
/* will be same as sdata */
|
||||
|
@ -1176,6 +1180,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
|
|||
}
|
||||
|
||||
ieee80211_hw_config(local, config_changed);
|
||||
|
||||
/* And the BSSID changed -- not very interesting here */
|
||||
changed |= BSS_CHANGED_BSSID;
|
||||
ieee80211_bss_info_change_notify(sdata, changed);
|
||||
|
||||
rcu_read_lock();
|
||||
|
@ -2481,9 +2488,6 @@ int ieee80211_sta_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid)
|
|||
ifmgd->flags &= ~IEEE80211_STA_BSSID_SET;
|
||||
}
|
||||
|
||||
if (netif_running(sdata->dev))
|
||||
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
|
||||
|
||||
return ieee80211_sta_commit(sdata);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue