aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c23
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.c5
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.h4
3 files changed, 28 insertions, 4 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 3261730181fa..77166520bc01 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -803,6 +803,27 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
803 return; 803 return;
804 } 804 }
805 iwl_mvm_configure_mcast_filter(mvm, vif); 805 iwl_mvm_configure_mcast_filter(mvm, vif);
806
807 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART,
808 &mvm->status)) {
809 /*
810 * If we're restarting then the firmware will
811 * obviously have lost synchronisation with
812 * the AP. It will attempt to synchronise by
813 * itself, but we can make it more reliable by
814 * scheduling a session protection time event.
815 *
816 * The firmware needs to receive a beacon to
817 * catch up with synchronisation, use 110% of
818 * the beacon interval.
819 *
820 * Set a large maximum delay to allow for more
821 * than a single interface.
822 */
823 u32 dur = (11 * vif->bss_conf.beacon_int) / 10;
824 iwl_mvm_protect_session(mvm, vif, dur, dur,
825 5 * dur);
826 }
806 } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) { 827 } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) {
807 /* remove AP station now that the MAC is unassoc */ 828 /* remove AP station now that the MAC is unassoc */
808 ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id); 829 ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id);
@@ -1170,7 +1191,7 @@ static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
1170 1191
1171 mutex_lock(&mvm->mutex); 1192 mutex_lock(&mvm->mutex);
1172 /* Try really hard to protect the session and hear a beacon */ 1193 /* Try really hard to protect the session and hear a beacon */
1173 iwl_mvm_protect_session(mvm, vif, duration, min_duration); 1194 iwl_mvm_protect_session(mvm, vif, duration, min_duration, 500);
1174 mutex_unlock(&mvm->mutex); 1195 mutex_unlock(&mvm->mutex);
1175} 1196}
1176 1197
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c
index 76a3c177e100..33cf56fdfc41 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.c
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c
@@ -387,7 +387,8 @@ static int iwl_mvm_time_event_send_add(struct iwl_mvm *mvm,
387 387
388void iwl_mvm_protect_session(struct iwl_mvm *mvm, 388void iwl_mvm_protect_session(struct iwl_mvm *mvm,
389 struct ieee80211_vif *vif, 389 struct ieee80211_vif *vif,
390 u32 duration, u32 min_duration) 390 u32 duration, u32 min_duration,
391 u32 max_delay)
391{ 392{
392 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 393 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
393 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data; 394 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
@@ -426,7 +427,7 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm,
426 cpu_to_le32(iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG)); 427 cpu_to_le32(iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG));
427 428
428 time_cmd.max_frags = TE_V2_FRAG_NONE; 429 time_cmd.max_frags = TE_V2_FRAG_NONE;
429 time_cmd.max_delay = cpu_to_le32(500); 430 time_cmd.max_delay = cpu_to_le32(max_delay);
430 /* TODO: why do we need to interval = bi if it is not periodic? */ 431 /* TODO: why do we need to interval = bi if it is not periodic? */
431 time_cmd.interval = cpu_to_le32(1); 432 time_cmd.interval = cpu_to_le32(1);
432 time_cmd.duration = cpu_to_le32(duration); 433 time_cmd.duration = cpu_to_le32(duration);
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.h b/drivers/net/wireless/iwlwifi/mvm/time-event.h
index f86c51065ed3..d9c8d6cfa2db 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.h
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.h
@@ -123,6 +123,7 @@
123 * @duration: the duration of the session in TU. 123 * @duration: the duration of the session in TU.
124 * @min_duration: will start a new session if the current session will end 124 * @min_duration: will start a new session if the current session will end
125 * in less than min_duration. 125 * in less than min_duration.
126 * @max_delay: maximum delay before starting the time event (in TU)
126 * 127 *
127 * This function can be used to start a session protection which means that the 128 * This function can be used to start a session protection which means that the
128 * fw will stay on the channel for %duration_ms milliseconds. This function 129 * fw will stay on the channel for %duration_ms milliseconds. This function
@@ -133,7 +134,8 @@
133 */ 134 */
134void iwl_mvm_protect_session(struct iwl_mvm *mvm, 135void iwl_mvm_protect_session(struct iwl_mvm *mvm,
135 struct ieee80211_vif *vif, 136 struct ieee80211_vif *vif,
136 u32 duration, u32 min_duration); 137 u32 duration, u32 min_duration,
138 u32 max_delay);
137 139
138/** 140/**
139 * iwl_mvm_stop_session_protection - cancel the session protection. 141 * iwl_mvm_stop_session_protection - cancel the session protection.