@@ -867,7 +867,7 @@ ieee80211_determine_chan_mode(struct ieee80211_sub_if_data *sdata,
static int ieee80211_config_bw(struct ieee80211_link_data *link,
struct ieee802_11_elems *elems,
- u64 *changed)
+ bool update, u64 *changed)
{
struct ieee80211_channel *channel = link->conf->chanreq.oper.chan;
struct ieee80211_sub_if_data *sdata = link->sdata;
@@ -942,6 +942,11 @@ static int ieee80211_config_bw(struct ieee80211_link_data *link,
return -EINVAL;
}
+ if (!update) {
+ link->conf->chanreq = chanreq;
+ return 0;
+ }
+
/*
* We're tracking the current AP here, so don't do any further checks
* here. This keeps us from playing ping-pong with regulatory, without
@@ -4504,6 +4509,8 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
/*
* We previously checked these in the beacon/probe response, so
* they should be present here. This is just a safety net.
+ * Note that the ieee80211_config_bw() below would also check
+ * for this (and more), but this has better error reporting.
*/
if (!is_6ghz && link->u.mgd.conn.mode >= IEEE80211_CONN_MODE_HT &&
(!elems->wmm_param || !elems->ht_cap_elem || !elems->ht_operation)) {
@@ -4521,6 +4528,14 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
goto out;
}
+ /* check/update if AP changed anything in assoc response vs. scan */
+ if (ieee80211_config_bw(link, elems,
+ link_id == assoc_data->assoc_link_id,
+ changed)) {
+ ret = false;
+ goto out;
+ }
+
if (WARN_ON(!link->conf->chanreq.oper.chan)) {
ret = false;
goto out;
@@ -6597,7 +6612,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_link_data *link,
changed |= ieee80211_recalc_twt_req(sdata, sband, link, link_sta, elems);
- if (ieee80211_config_bw(link, elems, &changed)) {
+ if (ieee80211_config_bw(link, elems, true, &changed)) {
ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
WLAN_REASON_DEAUTH_LEAVING,
true, deauth_buf);