diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 8412a30..3ae9d69 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -326,6 +326,7 @@ enum ieee80211_sta_flags { IEEE80211_STA_BEACON_POLL = BIT(0), IEEE80211_STA_CONNECTION_POLL = BIT(1), IEEE80211_STA_CONTROL_PORT = BIT(2), + IEEE80211_STA_DISABLE_BW_TRACK = BIT(3), IEEE80211_STA_DISABLE_HT = BIT(4), IEEE80211_STA_CSA_RECEIVED = BIT(5), IEEE80211_STA_MFP_ENABLED = BIT(6), diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index ae31968..fa19828 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -368,6 +368,15 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata, enum ieee80211_sta_rx_bandwidth new_sta_bw; int ret; + /* + * We've previously detected the AP as having broken BW tracking, + * so don't try to track changes any more. This isn't good, but + * with broken APs there isn't much we can do. One example of an + * AP like that is the D-Link DIR-825 with firmware 2.06NA. + */ + if (ifmgd->flags & IEEE80211_STA_DISABLE_BW_TRACK) + return 0; + /* if HT was/is disabled, don't track any bandwidth changes */ if (ifmgd->flags & IEEE80211_STA_DISABLE_HT || !ht_oper) return 0; @@ -406,16 +415,25 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata, if (cfg80211_chandef_identical(&chandef, &sdata->vif.bss_conf.chandef)) return 0; + if ((flags & (IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT)) != + (ifmgd->flags & (IEEE80211_STA_DISABLE_HT | + IEEE80211_STA_DISABLE_VHT))) { + sdata_info(sdata, + "AP %pM seems to have broken HT/VHT support, disable bandwidth tracking\n", + ifmgd->bssid); + ifmgd->flags |= IEEE80211_STA_DISABLE_BW_TRACK; + return 0; + } + flags &= ~(IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT); + sdata_info(sdata, "AP %pM changed bandwidth, new config is %d MHz, width %d (%d/%d MHz)\n", ifmgd->bssid, chandef.chan->center_freq, chandef.width, chandef.center_freq1, chandef.center_freq2); - if (flags != (ifmgd->flags & (IEEE80211_STA_DISABLE_HT | - IEEE80211_STA_DISABLE_VHT | - IEEE80211_STA_DISABLE_40MHZ | - IEEE80211_STA_DISABLE_80P80MHZ | - IEEE80211_STA_DISABLE_160MHZ)) || + if (flags != (ifmgd->flags & (IEEE80211_STA_DISABLE_40MHZ | + IEEE80211_STA_DISABLE_80P80MHZ | + IEEE80211_STA_DISABLE_160MHZ)) || !cfg80211_chandef_valid(&chandef)) { sdata_info(sdata, "AP %pM changed bandwidth in a way we can't support - disconnect\n",