As session protection API is moving to be per link instead of per mac,
move the time events to be per link too.
Since there is only one concurrent time event per mac, it feels
unnecessary to have the time_event as a member of iwl_mvm_link_info.
(That way we will have to iterate over all links each time we want to
clear a time event, and also we will need mac80211 to tell us the link
id when mgd_tx_complete() is called.)
So leave this as a member of iwl_mvm_vif, but add the link id to the
time_event structure.
The link id in time_event will only be maintained and used for:
1. When SESSION_PROTECTION_CMD is supported (before it, we don't have MLO)
2. For time_events of types SESSION_PROTECT_CONF_ASSOC,
SESSION_PROTECT_CONF_P2P_DEVICE_DISCOV, and
SESSION_PROTECT_CONF_P2P_GO_NEGOTIATION
(not for aux roc/ Hot Spot time_events).
For P2P, non-MLO connections, and pre-MLD API, deflink id, meaning 0,
will be used
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20231017115047.21496bcacb18.I79d037325b4fae4c12a22d9477e53fc9c537ad46@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
}
void iwl_mvm_protect_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
- u32 duration_override)
+ u32 duration_override, unsigned int link_id)
{
u32 duration = IWL_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS;
u32 min_duration = IWL_MVM_TE_SESSION_PROTECTION_MIN_TIME_MS;
if (fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD))
iwl_mvm_schedule_session_protection(mvm, vif, 900,
- min_duration, false);
+ min_duration, false,
+ link_id);
else
iwl_mvm_protect_session(mvm, vif, duration,
min_duration, 500, false);
* time could be small without us having heard
* a beacon yet.
*/
- iwl_mvm_protect_assoc(mvm, vif, 0);
+ iwl_mvm_protect_assoc(mvm, vif, 0, 0);
}
iwl_mvm_sf_update(mvm, vif, false);
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
mutex_lock(&mvm->mutex);
- iwl_mvm_protect_assoc(mvm, vif, info->duration);
+ iwl_mvm_protect_assoc(mvm, vif, info->duration, info->link_id);
mutex_unlock(&mvm->mutex);
}
if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) &&
protect) {
+ /* We are in assoc so only one link is active-
+ * The association link
+ */
+ unsigned int link_id =
+ ffs(vif->active_links) - 1;
+
/* If we're not restarting and still haven't
* heard a beacon (dtim period unknown) then
* make sure we still have enough minimum time
* time could be small without us having heard
* a beacon yet.
*/
- iwl_mvm_protect_assoc(mvm, vif, 0);
+ iwl_mvm_protect_assoc(mvm, vif, 0, link_id);
}
iwl_mvm_sf_update(mvm, vif, false);
* if the te is in the time event list or not (when id == TE_MAX)
*/
u32 id;
+ u8 link_id;
};
/* Power management */
struct ieee80211_vif *vif);
/*Session Protection */
void iwl_mvm_protect_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
- u32 duration_override);
+ u32 duration_override, unsigned int link_id);
/* Quota management */
static inline size_t iwl_mvm_quota_cmd_size(struct iwl_mvm *mvm)
if (fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD))
iwl_mvm_schedule_session_protection(mvm, vif, duration,
- duration, true);
+ duration, true, link_id);
else
iwl_mvm_protect_session(mvm, vif, duration,
duration, 100, true);
te_data->uid = 0;
te_data->id = TE_MAX;
te_data->vif = NULL;
+ te_data->link_id = -1;
}
void iwl_mvm_roc_done_wk(struct work_struct *wk)
/* The time_event_data.id field is reused to save session
* protection's configuration.
*/
+
+ mvmvif->time_event_data.link_id = 0;
+
switch (type) {
case IEEE80211_ROC_TYPE_NORMAL:
mvmvif->time_event_data.id =
void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
u32 duration, u32 min_duration,
- bool wait_for_notif)
+ bool wait_for_notif,
+ unsigned int link_id)
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
lockdep_assert_held(&mvm->mutex);
spin_lock_bh(&mvm->time_event_lock);
- if (te_data->running &&
+ if (te_data->running && te_data->link_id == link_id &&
time_after(te_data->end_jiffies, TU_TO_EXP_TIME(min_duration))) {
IWL_DEBUG_TE(mvm, "We have enough time in the current TE: %u\n",
jiffies_to_msecs(te_data->end_jiffies - jiffies));
te_data->id = le32_to_cpu(cmd.conf_id);
te_data->duration = le32_to_cpu(cmd.duration_tu);
te_data->vif = vif;
+ te_data->link_id = link_id;
spin_unlock_bh(&mvm->time_event_lock);
IWL_DEBUG_TE(mvm, "Add new session protection, duration %d TU\n",
* @duration: the requested duration of the protection
* @min_duration: the minimum duration of the protection
* @wait_for_notif: if true, will block until the start of the protection
+ * @link_id: The link to schedule a session protection for
*/
void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
u32 duration, u32 min_duration,
- bool wait_for_notif);
+ bool wait_for_notif,
+ unsigned int link_id);
/**
* iwl_mvm_rx_session_protect_notif - handles %SESSION_PROTECTION_NOTIF