Commit 81d62d5a authored by Johannes Berg's avatar Johannes Berg Committed by Emmanuel Grumbach

iwlwifi: mvm: continue (with error) CSA on GO time event failure

If, on a GO, the CSA time event fails to be scheduled, continue the
flow towards mac80211's state machine so it doesn't get stuck, but
report an error later on the post switch which will cause mac80211
to tear down the operation. This ensures nothing gets stuck due to
the scheduling failure.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent 208d271a
...@@ -3646,6 +3646,8 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw, ...@@ -3646,6 +3646,8 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
mutex_lock(&mvm->mutex); mutex_lock(&mvm->mutex);
mvmvif->csa_failed = false;
IWL_DEBUG_MAC80211(mvm, "pre CSA to freq %d\n", IWL_DEBUG_MAC80211(mvm, "pre CSA to freq %d\n",
chsw->chandef.center_freq1); chsw->chandef.center_freq1);
...@@ -3721,6 +3723,12 @@ static int iwl_mvm_post_channel_switch(struct ieee80211_hw *hw, ...@@ -3721,6 +3723,12 @@ static int iwl_mvm_post_channel_switch(struct ieee80211_hw *hw,
mutex_lock(&mvm->mutex); mutex_lock(&mvm->mutex);
if (mvmvif->csa_failed) {
mvmvif->csa_failed = false;
ret = -EIO;
goto out_unlock;
}
if (vif->type == NL80211_IFTYPE_STATION) { if (vif->type == NL80211_IFTYPE_STATION) {
struct iwl_mvm_sta *mvmsta; struct iwl_mvm_sta *mvmsta;
......
...@@ -354,6 +354,7 @@ struct iwl_mvm_vif_bf_data { ...@@ -354,6 +354,7 @@ struct iwl_mvm_vif_bf_data {
* @beacon_stats: beacon statistics, containing the # of received beacons, * @beacon_stats: beacon statistics, containing the # of received beacons,
* # of received beacons accumulated over FW restart, and the current * # of received beacons accumulated over FW restart, and the current
* average signal of beacons retrieved from the firmware * average signal of beacons retrieved from the firmware
* @csa_failed: CSA failed to schedule time event, report an error later
*/ */
struct iwl_mvm_vif { struct iwl_mvm_vif {
struct iwl_mvm *mvm; struct iwl_mvm *mvm;
...@@ -433,6 +434,7 @@ struct iwl_mvm_vif { ...@@ -433,6 +434,7 @@ struct iwl_mvm_vif {
/* Indicates that CSA countdown may be started */ /* Indicates that CSA countdown may be started */
bool csa_countdown; bool csa_countdown;
bool csa_failed;
}; };
static inline struct iwl_mvm_vif * static inline struct iwl_mvm_vif *
......
...@@ -196,19 +196,23 @@ iwl_mvm_te_handle_notify_csa(struct iwl_mvm *mvm, ...@@ -196,19 +196,23 @@ iwl_mvm_te_handle_notify_csa(struct iwl_mvm *mvm,
struct iwl_mvm_time_event_data *te_data, struct iwl_mvm_time_event_data *te_data,
struct iwl_time_event_notif *notif) struct iwl_time_event_notif *notif)
{ {
if (!le32_to_cpu(notif->status)) { struct ieee80211_vif *vif = te_data->vif;
if (te_data->vif->type == NL80211_IFTYPE_STATION) struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
ieee80211_connection_loss(te_data->vif);
if (!notif->status)
IWL_DEBUG_TE(mvm, "CSA time event failed to start\n"); IWL_DEBUG_TE(mvm, "CSA time event failed to start\n");
iwl_mvm_te_clear_data(mvm, te_data);
return;
}
switch (te_data->vif->type) { switch (te_data->vif->type) {
case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP:
if (!notif->status)
mvmvif->csa_failed = true;
iwl_mvm_csa_noa_start(mvm); iwl_mvm_csa_noa_start(mvm);
break; break;
case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_STATION:
if (!notif->status) {
ieee80211_connection_loss(te_data->vif);
break;
}
iwl_mvm_csa_client_absent(mvm, te_data->vif); iwl_mvm_csa_client_absent(mvm, te_data->vif);
ieee80211_chswitch_done(te_data->vif, true); ieee80211_chswitch_done(te_data->vif, true);
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment