Skip to content

Commit bf5da87

Browse files
mattigotegrumbach
authored andcommitted
iwlwifi: mvm: add remove flow for AUX ROC time events
Add a flow that handles the requests to cancel the roc time event, that has been triggered via the aux framework. The roc for bss is different than the roc for p2p devices, and is done via the aux framework using the aux queue, thus requires a different flow to cancel the time event. Signed-off-by: Matti Gottlieb <[email protected]> Reviewed-by: Johannes Berg <[email protected]> Signed-off-by: Emmanuel Grumbach <[email protected]>
1 parent 2992a32 commit bf5da87

File tree

3 files changed

+89
-24
lines changed

3 files changed

+89
-24
lines changed

drivers/net/wireless/iwlwifi/mvm/mac80211.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2652,7 +2652,7 @@ static int iwl_mvm_cancel_roc(struct ieee80211_hw *hw)
26522652
IWL_DEBUG_MAC80211(mvm, "enter\n");
26532653

26542654
mutex_lock(&mvm->mutex);
2655-
iwl_mvm_stop_p2p_roc(mvm);
2655+
iwl_mvm_stop_roc(mvm);
26562656
mutex_unlock(&mvm->mutex);
26572657

26582658
IWL_DEBUG_MAC80211(mvm, "leave\n");

drivers/net/wireless/iwlwifi/mvm/time-event.c

Lines changed: 86 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -549,18 +549,11 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm,
549549
}
550550
}
551551

552-
/*
553-
* Explicit request to remove a time event. The removal of a time event needs to
554-
* be synchronized with the flow of a time event's end notification, which also
555-
* removes the time event from the op mode data structures.
556-
*/
557-
void iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
558-
struct iwl_mvm_vif *mvmvif,
559-
struct iwl_mvm_time_event_data *te_data)
552+
static bool __iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
553+
struct iwl_mvm_time_event_data *te_data,
554+
u32 *uid)
560555
{
561-
struct iwl_time_event_cmd time_cmd = {};
562-
u32 id, uid;
563-
int ret;
556+
u32 id;
564557

565558
/*
566559
* It is possible that by the time we got to this point the time
@@ -569,7 +562,7 @@ void iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
569562
spin_lock_bh(&mvm->time_event_lock);
570563

571564
/* Save time event uid before clearing its data */
572-
uid = te_data->uid;
565+
*uid = te_data->uid;
573566
id = te_data->id;
574567

575568
/*
@@ -584,10 +577,59 @@ void iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
584577
* send a removal command.
585578
*/
586579
if (id == TE_MAX) {
587-
IWL_DEBUG_TE(mvm, "TE 0x%x has already ended\n", uid);
588-
return;
580+
IWL_DEBUG_TE(mvm, "TE 0x%x has already ended\n", *uid);
581+
return false;
589582
}
590583

584+
return true;
585+
}
586+
587+
/*
588+
* Explicit request to remove a aux roc time event. The removal of a time
589+
* event needs to be synchronized with the flow of a time event's end
590+
* notification, which also removes the time event from the op mode
591+
* data structures.
592+
*/
593+
static void iwl_mvm_remove_aux_roc_te(struct iwl_mvm *mvm,
594+
struct iwl_mvm_vif *mvmvif,
595+
struct iwl_mvm_time_event_data *te_data)
596+
{
597+
struct iwl_hs20_roc_req aux_cmd = {};
598+
u32 uid;
599+
int ret;
600+
601+
if (!__iwl_mvm_remove_time_event(mvm, te_data, &uid))
602+
return;
603+
604+
aux_cmd.event_unique_id = cpu_to_le32(uid);
605+
aux_cmd.action = cpu_to_le32(FW_CTXT_ACTION_REMOVE);
606+
aux_cmd.id_and_color =
607+
cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color));
608+
IWL_DEBUG_TE(mvm, "Removing BSS AUX ROC TE 0x%x\n",
609+
le32_to_cpu(aux_cmd.event_unique_id));
610+
ret = iwl_mvm_send_cmd_pdu(mvm, HOT_SPOT_CMD, 0,
611+
sizeof(aux_cmd), &aux_cmd);
612+
613+
if (WARN_ON(ret))
614+
return;
615+
}
616+
617+
/*
618+
* Explicit request to remove a time event. The removal of a time event needs to
619+
* be synchronized with the flow of a time event's end notification, which also
620+
* removes the time event from the op mode data structures.
621+
*/
622+
void iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
623+
struct iwl_mvm_vif *mvmvif,
624+
struct iwl_mvm_time_event_data *te_data)
625+
{
626+
struct iwl_time_event_cmd time_cmd = {};
627+
u32 uid;
628+
int ret;
629+
630+
if (!__iwl_mvm_remove_time_event(mvm, te_data, &uid))
631+
return;
632+
591633
/* When we remove a TE, the UID is to be set in the id field */
592634
time_cmd.id = cpu_to_le32(uid);
593635
time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_REMOVE);
@@ -666,36 +708,59 @@ int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
666708
return iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd);
667709
}
668710

669-
void iwl_mvm_stop_p2p_roc(struct iwl_mvm *mvm)
711+
void iwl_mvm_stop_roc(struct iwl_mvm *mvm)
670712
{
671713
struct iwl_mvm_vif *mvmvif;
672714
struct iwl_mvm_time_event_data *te_data;
715+
bool is_p2p = false;
673716

674717
lockdep_assert_held(&mvm->mutex);
675718

719+
mvmvif = NULL;
720+
spin_lock_bh(&mvm->time_event_lock);
721+
676722
/*
677723
* Iterate over the list of time events and find the time event that is
678724
* associated with a P2P_DEVICE interface.
679725
* This assumes that a P2P_DEVICE interface can have only a single time
680726
* event at any given time and this time event coresponds to a ROC
681727
* request
682728
*/
683-
mvmvif = NULL;
684-
spin_lock_bh(&mvm->time_event_lock);
685729
list_for_each_entry(te_data, &mvm->time_event_list, list) {
686-
if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE) {
730+
if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE &&
731+
te_data->running) {
687732
mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif);
688-
break;
733+
is_p2p = true;
734+
goto remove_te;
735+
}
736+
}
737+
738+
/*
739+
* Iterate over the list of aux roc time events and find the time
740+
* event that is associated with a BSS interface.
741+
* This assumes that a BSS interface can have only a single time
742+
* event at any given time and this time event coresponds to a ROC
743+
* request
744+
*/
745+
list_for_each_entry(te_data, &mvm->aux_roc_te_list, list) {
746+
if (te_data->running) {
747+
mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif);
748+
goto remove_te;
689749
}
690750
}
751+
752+
remove_te:
691753
spin_unlock_bh(&mvm->time_event_lock);
692754

693755
if (!mvmvif) {
694-
IWL_WARN(mvm, "P2P_DEVICE no remain on channel event\n");
756+
IWL_WARN(mvm, "No remain on channel event\n");
695757
return;
696758
}
697759

698-
iwl_mvm_remove_time_event(mvm, mvmvif, te_data);
760+
if (is_p2p)
761+
iwl_mvm_remove_time_event(mvm, mvmvif, te_data);
762+
else
763+
iwl_mvm_remove_aux_roc_te(mvm, mvmvif, te_data);
699764

700765
iwl_mvm_roc_finished(mvm);
701766
}

drivers/net/wireless/iwlwifi/mvm/time-event.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,14 +182,14 @@ int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
182182
int duration, enum ieee80211_roc_type type);
183183

184184
/**
185-
* iwl_mvm_stop_p2p_roc - stop remain on channel for p2p device functionlity
185+
* iwl_mvm_stop_roc - stop remain on channel functionality
186186
* @mvm: the mvm component
187187
*
188188
* This function can be used to cancel an ongoing ROC session.
189189
* The function is async, it will instruct the FW to stop serving the ROC
190190
* session, but will not wait for the actual stopping of the session.
191191
*/
192-
void iwl_mvm_stop_p2p_roc(struct iwl_mvm *mvm);
192+
void iwl_mvm_stop_roc(struct iwl_mvm *mvm);
193193

194194
/**
195195
* iwl_mvm_remove_time_event - general function to clean up of time event

0 commit comments

Comments
 (0)