Commit 54d96912 authored by Shaul Triebitz's avatar Shaul Triebitz Committed by Johannes Berg

wifi: iwlwifi: mvm: use ROC for P2P device activities

This is the first step towards removing the P2P Device MAC.
Use ROC (which uses the AUX MAC) for P2P Device
discoveribility and action frames.
Signed-off-by: default avatarShaul Triebitz <shaul.triebitz@intel.com>
Signed-off-by: default avatarMiri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://msgid.link/20240605140556.8c90e457abbd.I8e340759ecb299e05b1809f3d8060429c6cbbd01@changeidSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 5f1fee96
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* Copyright (C) 2012-2014, 2018-2020, 2022-2023 Intel Corporation
* Copyright (C) 2012-2014, 2018-2020, 2022-2024 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
......@@ -340,11 +340,13 @@ struct iwl_hs20_roc_res {
* @ROC_ACTIVITY_HOTSPOT: ROC for hs20 activity
* @ROC_ACTIVITY_P2P_DISC: ROC for p2p discoverability activity
* @ROC_ACTIVITY_P2P_TXRX: ROC for p2p action frames activity
* @ROC_ACTIVITY_P2P_NEG: ROC for p2p negotiation (used also for TX)
*/
enum iwl_roc_activity {
ROC_ACTIVITY_HOTSPOT,
ROC_ACTIVITY_P2P_DISC,
ROC_ACTIVITY_P2P_TXRX,
ROC_ACTIVITY_P2P_NEG,
ROC_NUM_ACTIVITIES
}; /* ROC_ACTIVITY_API_E_VER_1 */
......
......@@ -296,6 +296,7 @@ int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
INIT_LIST_HEAD(&mvmvif->time_event_data.list);
mvmvif->time_event_data.id = TE_MAX;
mvmvif->roc_activity = ROC_NUM_ACTIVITIES;
mvmvif->deflink.bcast_sta.sta_id = IWL_MVM_INVALID_STA;
mvmvif->deflink.mcast_sta.sta_id = IWL_MVM_INVALID_STA;
......
......@@ -821,7 +821,7 @@ void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
}
if (offchannel &&
!test_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status) &&
!test_bit(IWL_MVM_STATUS_ROC_P2P_RUNNING, &mvm->status) &&
!test_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status))
goto drop;
......@@ -1102,6 +1102,8 @@ static void iwl_mvm_cleanup_iterator(void *data, u8 *mac,
iwl_mvm_te_clear_data(mvm, &mvmvif->time_event_data);
spin_unlock_bh(&mvm->time_event_lock);
mvmvif->roc_activity = ROC_NUM_ACTIVITIES;
mvmvif->bf_enabled = false;
mvmvif->ba_enabled = false;
mvmvif->ap_sta = NULL;
......@@ -4771,6 +4773,37 @@ static int iwl_mvm_roc_station(struct iwl_mvm *mvm,
return ret;
}
static int iwl_mvm_roc_p2p(struct iwl_mvm *mvm,
struct ieee80211_channel *channel,
struct ieee80211_vif *vif,
int duration,
enum ieee80211_roc_type type)
{
enum iwl_roc_activity activity;
int ret;
lockdep_assert_held(&mvm->mutex);
switch (type) {
case IEEE80211_ROC_TYPE_NORMAL:
activity = ROC_ACTIVITY_P2P_DISC;
break;
case IEEE80211_ROC_TYPE_MGMT_TX:
activity = ROC_ACTIVITY_P2P_NEG;
break;
default:
WARN_ONCE(1, "Got an invalid P2P ROC type\n");
return -EINVAL;
}
ret = iwl_mvm_mld_add_aux_sta(mvm,
iwl_mvm_get_lmac_id(mvm, channel->band));
if (ret)
return ret;
return iwl_mvm_roc_add_cmd(mvm, channel, vif, duration, activity);
}
static int iwl_mvm_p2p_find_phy_ctxt(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct ieee80211_channel *channel)
......@@ -4863,6 +4896,10 @@ int iwl_mvm_roc_common(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
return -EINVAL;
}
if (iwl_mvm_has_p2p_over_aux(mvm)) {
ret = iwl_mvm_roc_p2p(mvm, channel, vif, duration, type);
return ret;
}
ret = iwl_mvm_p2p_find_phy_ctxt(mvm, vif, channel);
if (ret)
......
......@@ -453,6 +453,8 @@ struct iwl_mvm_esr_exit {
* @prevent_esr_done_wk: work that should be done when esr prevention ends.
* @mlo_int_scan_wk: work for the internal MLO scan.
* @unblock_esr_tpt_wk: work for unblocking EMLSR when tpt is high enough.
* @roc_activity: currently running ROC activity for this vif (or
* ROC_NUM_ACTIVITIES if no activity is running).
*/
struct iwl_mvm_vif {
struct iwl_mvm *mvm;
......@@ -530,6 +532,7 @@ struct iwl_mvm_vif {
struct iwl_mvm_time_event_data time_event_data;
struct iwl_mvm_time_event_data hs_time_event_data;
enum iwl_roc_activity roc_activity;
/* TCP Checksum Offload */
netdev_features_t features;
......@@ -1345,7 +1348,8 @@ DEFINE_GUARD(mvm, struct iwl_mvm *, mutex_lock(&_T->mutex), mutex_unlock(&_T->mu
* enum iwl_mvm_status - MVM status bits
* @IWL_MVM_STATUS_HW_RFKILL: HW RF-kill is asserted
* @IWL_MVM_STATUS_HW_CTKILL: CT-kill is active
* @IWL_MVM_STATUS_ROC_RUNNING: remain-on-channel is running
* @IWL_MVM_STATUS_ROC_P2P_RUNNING: remain-on-channel on P2P is running (when
* P2P is not over AUX)
* @IWL_MVM_STATUS_HW_RESTART_REQUESTED: HW restart was requested
* @IWL_MVM_STATUS_IN_HW_RESTART: HW restart is active
* @IWL_MVM_STATUS_ROC_AUX_RUNNING: AUX remain-on-channel is running
......@@ -1359,7 +1363,7 @@ DEFINE_GUARD(mvm, struct iwl_mvm *, mutex_lock(&_T->mutex), mutex_unlock(&_T->mu
enum iwl_mvm_status {
IWL_MVM_STATUS_HW_RFKILL,
IWL_MVM_STATUS_HW_CTKILL,
IWL_MVM_STATUS_ROC_RUNNING,
IWL_MVM_STATUS_ROC_P2P_RUNNING,
IWL_MVM_STATUS_HW_RESTART_REQUESTED,
IWL_MVM_STATUS_IN_HW_RESTART,
IWL_MVM_STATUS_ROC_AUX_RUNNING,
......@@ -2773,6 +2777,13 @@ static inline void iwl_mvm_mei_set_sw_rfkill_state(struct iwl_mvm *mvm)
sw_rfkill);
}
static inline bool iwl_mvm_has_p2p_over_aux(struct iwl_mvm *mvm)
{
u32 cmd_id = WIDE_ID(MAC_CONF_GROUP, ROC_CMD);
return iwl_fw_lookup_cmd_ver(mvm->fw, cmd_id, 0) >= 4;
}
static inline bool iwl_mvm_mei_filter_scan(struct iwl_mvm *mvm,
struct sk_buff *skb)
{
......@@ -2938,7 +2949,7 @@ void iwl_mvm_roc_duration_and_delay(struct ieee80211_vif *vif,
int iwl_mvm_roc_add_cmd(struct iwl_mvm *mvm,
struct ieee80211_channel *channel,
struct ieee80211_vif *vif,
int duration, u32 activity);
int duration, enum iwl_roc_activity activity);
/* EMLSR */
bool iwl_mvm_vif_has_esr_cap(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
......
......@@ -471,7 +471,7 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
iwl_mvm_time_sync_msmt_confirm_event, RX_HANDLER_SYNC,
struct iwl_time_msmt_cfm_notify),
RX_HANDLER_GRP(MAC_CONF_GROUP, ROC_NOTIF,
iwl_mvm_rx_roc_notif, RX_HANDLER_SYNC,
iwl_mvm_rx_roc_notif, RX_HANDLER_ASYNC_LOCKED,
struct iwl_roc_notif),
RX_HANDLER_GRP(SCAN_GROUP, CHANNEL_SURVEY_NOTIF,
iwl_mvm_rx_channel_survey_notif, RX_HANDLER_ASYNC_LOCKED,
......
......@@ -802,8 +802,28 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb)
if (info.control.vif) {
struct iwl_mvm_vif *mvmvif =
iwl_mvm_vif_from_mac80211(info.control.vif);
bool p2p_aux = iwl_mvm_has_p2p_over_aux(mvm);
if (info.control.vif->type == NL80211_IFTYPE_P2P_DEVICE ||
if ((info.control.vif->type == NL80211_IFTYPE_P2P_DEVICE &&
p2p_aux) ||
(info.control.vif->type == NL80211_IFTYPE_STATION &&
offchannel)) {
/*
* IWL_MVM_OFFCHANNEL_QUEUE is used for ROC packets
* that can be used in 2 different types of vifs, P2P
* Device and STATION.
* P2P Device uses the offchannel queue.
* STATION (HS2.0) uses the auxiliary context of the FW,
* and hence needs to be sent on the aux queue.
* If P2P_DEV_OVER_AUX is supported (p2p_aux = true)
* also P2P Device uses the aux queue.
*/
sta_id = mvm->aux_sta.sta_id;
queue = mvm->aux_queue;
if (WARN_ON(queue == IWL_MVM_INVALID_QUEUE))
return -1;
} else if (info.control.vif->type ==
NL80211_IFTYPE_P2P_DEVICE ||
info.control.vif->type == NL80211_IFTYPE_AP ||
info.control.vif->type == NL80211_IFTYPE_ADHOC) {
u32 link_id = u32_get_bits(info.control.flags,
......@@ -831,18 +851,6 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb)
} else if (info.control.vif->type == NL80211_IFTYPE_MONITOR) {
queue = mvm->snif_queue;
sta_id = mvm->snif_sta.sta_id;
} else if (info.control.vif->type == NL80211_IFTYPE_STATION &&
offchannel) {
/*
* IWL_MVM_OFFCHANNEL_QUEUE is used for ROC packets
* that can be used in 2 different types of vifs, P2P &
* STATION.
* P2P uses the offchannel queue.
* STATION (HS2.0) uses the auxiliary context of the FW,
* and hence needs to be sent on the aux queue.
*/
sta_id = mvm->aux_sta.sta_id;
queue = mvm->aux_queue;
}
}
......
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