Commit cf85123a authored by Avraham Stern's avatar Avraham Stern Committed by Johannes Berg

wifi: iwlwifi: mvm: support enabling and disabling HW timestamping

Instead of enabling HW timestamping by default every time a station
is connected, disable it by default and enable it only upon request
for a specific station. HW timestamping can be enabled for only one
peer at a time.
Signed-off-by: default avatarAvraham Stern <avraham.stern@intel.com>
Signed-off-by: default avatarGregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230320122330.62b98fbf545b.I450c1017ada7900a71a63d879bb542a08e3166c8@changeidSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 3068248b
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "iwl-phy-db.h" #include "iwl-phy-db.h"
#include "iwl-modparams.h" #include "iwl-modparams.h"
#include "iwl-nvm-parse.h" #include "iwl-nvm-parse.h"
#include "time-sync.h"
#define MVM_UCODE_ALIVE_TIMEOUT (HZ) #define MVM_UCODE_ALIVE_TIMEOUT (HZ)
#define MVM_UCODE_CALIB_TIMEOUT (2 * HZ) #define MVM_UCODE_CALIB_TIMEOUT (2 * HZ)
...@@ -1666,8 +1667,12 @@ int iwl_mvm_up(struct iwl_mvm *mvm) ...@@ -1666,8 +1667,12 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
goto error; goto error;
} }
if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
iwl_mvm_send_recovery_cmd(mvm, ERROR_RECOVERY_UPDATE_DB); iwl_mvm_send_recovery_cmd(mvm, ERROR_RECOVERY_UPDATE_DB);
iwl_mvm_time_sync_config(mvm, mvm->time_sync.peer_addr,
IWL_TIME_SYNC_PROTOCOL_TM |
IWL_TIME_SYNC_PROTOCOL_FTM);
}
if (!mvm->ptp_data.ptp_clock) if (!mvm->ptp_data.ptp_clock)
iwl_mvm_ptp_init(mvm); iwl_mvm_ptp_init(mvm);
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "fw/error-dump.h" #include "fw/error-dump.h"
#include "iwl-prph.h" #include "iwl-prph.h"
#include "iwl-nvm-parse.h" #include "iwl-nvm-parse.h"
#include "time-sync.h"
static const struct ieee80211_iface_limit iwl_mvm_limits[] = { static const struct ieee80211_iface_limit iwl_mvm_limits[] = {
{ {
...@@ -416,6 +417,10 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) ...@@ -416,6 +417,10 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
wiphy_ext_feature_set(hw->wiphy, wiphy_ext_feature_set(hw->wiphy,
NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT); NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT);
if (fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_TIME_SYNC_BOTH_FTM_TM))
hw->wiphy->hw_timestamp_max_peers = 1;
ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS); ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS);
hw->wiphy->features |= hw->wiphy->features |=
NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR | NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR |
...@@ -5765,6 +5770,29 @@ static bool iwl_mvm_mac_can_aggregate(struct ieee80211_hw *hw, ...@@ -5765,6 +5770,29 @@ static bool iwl_mvm_mac_can_aggregate(struct ieee80211_hw *hw,
return iwl_mvm_can_hw_csum(skb) == iwl_mvm_can_hw_csum(head); return iwl_mvm_can_hw_csum(skb) == iwl_mvm_can_hw_csum(head);
} }
static int iwl_mvm_set_hw_timestamp(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct cfg80211_set_hw_timestamp *hwts)
{
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
u32 protocols = 0;
int ret;
/* HW timestamping is only supported for a specific station */
if (!hwts->macaddr)
return -EOPNOTSUPP;
if (hwts->enable)
protocols =
IWL_TIME_SYNC_PROTOCOL_TM | IWL_TIME_SYNC_PROTOCOL_FTM;
mutex_lock(&mvm->mutex);
ret = iwl_mvm_time_sync_config(mvm, hwts->macaddr, protocols);
mutex_unlock(&mvm->mutex);
return ret;
}
const struct ieee80211_ops iwl_mvm_hw_ops = { const struct ieee80211_ops iwl_mvm_hw_ops = {
.tx = iwl_mvm_mac_tx, .tx = iwl_mvm_mac_tx,
.wake_tx_queue = iwl_mvm_mac_wake_tx_queue, .wake_tx_queue = iwl_mvm_mac_wake_tx_queue,
...@@ -5853,4 +5881,5 @@ const struct ieee80211_ops iwl_mvm_hw_ops = { ...@@ -5853,4 +5881,5 @@ const struct ieee80211_ops iwl_mvm_hw_ops = {
#ifdef CONFIG_IWLWIFI_DEBUGFS #ifdef CONFIG_IWLWIFI_DEBUGFS
.sta_add_debugfs = iwl_mvm_sta_add_debugfs, .sta_add_debugfs = iwl_mvm_sta_add_debugfs,
#endif #endif
.set_hw_timestamp = iwl_mvm_set_hw_timestamp,
}; };
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
#include "mvm.h" #include "mvm.h"
#include "sta.h" #include "sta.h"
#include "rs.h" #include "rs.h"
#include "time-sync.h"
/* /*
* New version of ADD_STA_sta command added new fields at the end of the * New version of ADD_STA_sta command added new fields at the end of the
...@@ -1793,11 +1792,6 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm, ...@@ -1793,11 +1792,6 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
} }
} }
if (!sta->tdls)
iwl_mvm_time_sync_config(mvm, sta->addr,
IWL_TIME_SYNC_PROTOCOL_TM |
IWL_TIME_SYNC_PROTOCOL_FTM);
rcu_assign_pointer(mvm->fw_id_to_mac_id[sta_id], sta); rcu_assign_pointer(mvm->fw_id_to_mac_id[sta_id], sta);
return 0; return 0;
...@@ -1987,8 +1981,6 @@ static bool iwl_mvm_sta_del(struct iwl_mvm *mvm, struct ieee80211_vif *vif, ...@@ -1987,8 +1981,6 @@ static bool iwl_mvm_sta_del(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
spin_lock_bh(&mvm_sta->lock); spin_lock_bh(&mvm_sta->lock);
spin_unlock_bh(&mvm_sta->lock); spin_unlock_bh(&mvm_sta->lock);
iwl_mvm_time_sync_sta_rm(mvm, sta);
return false; return false;
} }
......
...@@ -125,7 +125,7 @@ void iwl_mvm_time_sync_msmt_confirm_event(struct iwl_mvm *mvm, ...@@ -125,7 +125,7 @@ void iwl_mvm_time_sync_msmt_confirm_event(struct iwl_mvm *mvm,
ieee80211_tx_status_ext(mvm->hw, &status); ieee80211_tx_status_ext(mvm->hw, &status);
} }
int iwl_mvm_time_sync_config(struct iwl_mvm *mvm, u8 *addr, u32 protocols) int iwl_mvm_time_sync_config(struct iwl_mvm *mvm, const u8 *addr, u32 protocols)
{ {
struct iwl_time_sync_cfg_cmd cmd = {}; struct iwl_time_sync_cfg_cmd cmd = {};
int err; int err;
...@@ -166,13 +166,8 @@ int iwl_mvm_time_sync_config(struct iwl_mvm *mvm, u8 *addr, u32 protocols) ...@@ -166,13 +166,8 @@ int iwl_mvm_time_sync_config(struct iwl_mvm *mvm, u8 *addr, u32 protocols)
IWL_DEBUG_INFO(mvm, "Time sync: set peer addr=%pM\n", addr); IWL_DEBUG_INFO(mvm, "Time sync: set peer addr=%pM\n", addr);
} }
return err; if (!mvm->time_sync.active)
} skb_queue_purge(&mvm->time_sync.frame_list);
void iwl_mvm_time_sync_sta_rm(struct iwl_mvm *mvm, struct ieee80211_sta *sta) return err;
{
/* Disable time sync with this station */
iwl_mvm_time_sync_config(mvm, sta->addr, 0);
skb_queue_purge(&mvm->time_sync.frame_list);
} }
...@@ -13,8 +13,8 @@ void iwl_mvm_time_sync_msmt_event(struct iwl_mvm *mvm, ...@@ -13,8 +13,8 @@ void iwl_mvm_time_sync_msmt_event(struct iwl_mvm *mvm,
struct iwl_rx_cmd_buffer *rxb); struct iwl_rx_cmd_buffer *rxb);
void iwl_mvm_time_sync_msmt_confirm_event(struct iwl_mvm *mvm, void iwl_mvm_time_sync_msmt_confirm_event(struct iwl_mvm *mvm,
struct iwl_rx_cmd_buffer *rxb); struct iwl_rx_cmd_buffer *rxb);
int iwl_mvm_time_sync_config(struct iwl_mvm *mvm, u8 *addr, u32 protocols); int iwl_mvm_time_sync_config(struct iwl_mvm *mvm, const u8 *addr,
void iwl_mvm_time_sync_sta_rm(struct iwl_mvm *mvm, struct ieee80211_sta *sta); u32 protocols);
static inline static inline
bool iwl_mvm_time_sync_frame(struct iwl_mvm *mvm, struct sk_buff *skb, u8 *addr) bool iwl_mvm_time_sync_frame(struct iwl_mvm *mvm, struct sk_buff *skb, u8 *addr)
......
@@
struct ieee80211_hw *hw;
expression val;
@@
-hw->wiphy->hw_timestamp_max_peers = val
+hw_timestamp_max_peers(hw)
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