Commit fc36ffda authored by Johannes Berg's avatar Johannes Berg Committed by Luca Coelho

iwlwifi: mvm: support FTM initiator

Add support for FTM initiator, i.e. peer measurements with FTM
if the firmware supports FTM.

Additionally, add two defines we depend on in
include/linux/ieee80211.h.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarAvraham Stern <avraham.stern@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
parent b73f9a4a
......@@ -7,6 +7,7 @@
*
* Copyright(c) 2015 - 2017 Intel Deutschland GmbH
* Copyright (C) 2018 Intel Corporation
* Copyright (C) 2019 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
......@@ -28,6 +29,7 @@
*
* Copyright(c) 2015 - 2017 Intel Deutschland GmbH
* Copyright (C) 2018 Intel Corporation
* Copyright (C) 2019 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
......@@ -403,7 +405,10 @@ enum iwl_tof_response_mode {
* @IWL_TOF_INITIATOR_FLAGS_TX_CHAIN_SEL_A: use antenna A fo TX ACKs during FTM
* @IWL_TOF_INITIATOR_FLAGS_TX_CHAIN_SEL_B: use antenna B fo TX ACKs during FTM
* @IWL_TOF_INITIATOR_FLAGS_TX_CHAIN_SEL_C: use antenna C fo TX ACKs during FTM
* @IWL_TOF_INITIATOR_FLAGS_MINDELTA_NO_PREF: no preference for minDeltaFTM
* @IWL_TOF_INITIATOR_FLAGS_SPECIFIC_CALIB: use the specific calib value from
* the range request command
* @IWL_TOF_INITIATOR_FLAGS_COMMON_CALIB: use the common calib value from the
* ragne request command
*/
enum iwl_tof_initiator_flags {
IWL_TOF_INITIATOR_FLAGS_FAST_ALGO_DISABLED = BIT(0),
......@@ -413,7 +418,8 @@ enum iwl_tof_initiator_flags {
IWL_TOF_INITIATOR_FLAGS_TX_CHAIN_SEL_A = BIT(4),
IWL_TOF_INITIATOR_FLAGS_TX_CHAIN_SEL_B = BIT(5),
IWL_TOF_INITIATOR_FLAGS_TX_CHAIN_SEL_C = BIT(6),
IWL_TOF_INITIATOR_FLAGS_MINDELTA_NO_PREF = BIT(7),
IWL_TOF_INITIATOR_FLAGS_SPECIFIC_CALIB = BIT(15),
IWL_TOF_INITIATOR_FLAGS_COMMON_CALIB = BIT(16),
}; /* LOCATION_RANGE_REQ_CMD_API_S_VER_5 */
#define IWL_MVM_TOF_MAX_APS 5
......
......@@ -4,7 +4,8 @@ iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o
iwlmvm-y += utils.o rx.o rxmq.o tx.o binding.o quota.o sta.o sf.o
iwlmvm-y += scan.o time-event.o rs.o rs-fw.o
iwlmvm-y += power.o coex.o
iwlmvm-y += tt.o offloading.o tdls.o ftm-responder.o
iwlmvm-y += tt.o offloading.o tdls.o
iwlmvm-y += ftm-responder.o ftm-initiator.o
iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o debugfs-vif.o
iwlmvm-$(CONFIG_IWLWIFI_LEDS) += led.o
iwlmvm-$(CONFIG_PM) += d3.o
......
......@@ -63,6 +63,7 @@
#define __MVM_CONSTANTS_H
#include <linux/ieee80211.h>
#include "fw-api.h"
#define IWL_MVM_UAPSD_NOAGG_BSSIDS_NUM 20
......@@ -145,5 +146,7 @@
#define IWL_MVM_RS_TPC_SR_NO_INCREASE 85 /* percent */
#define IWL_MVM_RS_TPC_TX_POWER_STEP 3
#define IWL_MVM_ENABLE_EBS 1
#define IWL_MVM_FTM_INITIATOR_ALGO IWL_TOF_ALGO_TYPE_MAX_LIKE
#define IWL_MVM_FTM_INITIATOR_DYNACK true
#endif /* __MVM_CONSTANTS_H */
This diff is collapsed.
......@@ -184,6 +184,29 @@ static const struct iwl_fw_bcast_filter iwl_mvm_default_bcast_filters[] = {
};
#endif
static const struct cfg80211_pmsr_capabilities iwl_mvm_pmsr_capa = {
.max_peers = IWL_MVM_TOF_MAX_APS,
.report_ap_tsf = 1,
.randomize_mac_addr = 1,
.ftm = {
.supported = 1,
.asap = 1,
.non_asap = 1,
.request_lci = 1,
.request_civicloc = 1,
.max_bursts_exponent = -1, /* all supported */
.max_ftms_per_burst = 0, /* no limits */
.bandwidths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
BIT(NL80211_CHAN_WIDTH_20) |
BIT(NL80211_CHAN_WIDTH_40) |
BIT(NL80211_CHAN_WIDTH_80),
.preambles = BIT(NL80211_PREAMBLE_LEGACY) |
BIT(NL80211_PREAMBLE_HT) |
BIT(NL80211_PREAMBLE_VHT),
},
};
void iwl_mvm_ref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type)
{
if (!iwl_mvm_is_d0i3_supported(mvm))
......@@ -549,9 +572,11 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
}
if (fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_FTM_CALIBRATED))
IWL_UCODE_TLV_CAPA_FTM_CALIBRATED)) {
wiphy_ext_feature_set(hw->wiphy,
NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER);
hw->wiphy->pmsr_capa = &iwl_mvm_pmsr_capa;
}
ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS);
hw->wiphy->features |=
......@@ -1186,6 +1211,8 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
iwl_mvm_cleanup_roc_te(mvm);
ieee80211_remain_on_channel_expired(mvm->hw);
iwl_mvm_ftm_restart(mvm);
/*
* cleanup all interfaces, even inactive ones, as some might have
* gone down during the HW restart
......@@ -4895,6 +4922,31 @@ iwl_mvm_mac_get_ftm_responder_stats(struct ieee80211_hw *hw,
return 0;
}
static int iwl_mvm_start_pmsr(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct cfg80211_pmsr_request *request)
{
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
int ret;
mutex_lock(&mvm->mutex);
ret = iwl_mvm_ftm_start(mvm, vif, request);
mutex_unlock(&mvm->mutex);
return ret;
}
static void iwl_mvm_abort_pmsr(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct cfg80211_pmsr_request *request)
{
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
mutex_lock(&mvm->mutex);
iwl_mvm_ftm_abort(mvm, request);
mutex_unlock(&mvm->mutex);
}
static bool iwl_mvm_can_hw_csum(struct sk_buff *skb)
{
u8 protocol = ip_hdr(skb)->protocol;
......@@ -4998,6 +5050,8 @@ const struct ieee80211_ops iwl_mvm_hw_ops = {
.get_survey = iwl_mvm_mac_get_survey,
.sta_statistics = iwl_mvm_mac_sta_statistics,
.get_ftm_responder_stats = iwl_mvm_mac_get_ftm_responder_stats,
.start_pmsr = iwl_mvm_start_pmsr,
.abort_pmsr = iwl_mvm_abort_pmsr,
.can_aggregate_in_amsdu = iwl_mvm_mac_can_aggregate,
#ifdef CONFIG_IWLWIFI_DEBUGFS
......
......@@ -1151,6 +1151,12 @@ struct iwl_mvm {
struct ieee80211_cipher_scheme cs[IWL_UCODE_MAX_CS];
struct cfg80211_ftm_responder_stats ftm_resp_stats;
struct {
struct cfg80211_pmsr_request *req;
struct wireless_dev *req_wdev;
struct list_head loc_list;
int responses[IWL_MVM_TOF_MAX_APS];
} ftm_initiator;
struct ieee80211_vif *nan_vif;
#define IWL_MAX_BAID 32
......@@ -2069,6 +2075,16 @@ void iwl_mvm_ftm_restart_responder(struct iwl_mvm *mvm,
void iwl_mvm_ftm_responder_stats(struct iwl_mvm *mvm,
struct iwl_rx_cmd_buffer *rxb);
/* FTM initiator */
void iwl_mvm_ftm_restart(struct iwl_mvm *mvm);
void iwl_mvm_ftm_range_resp(struct iwl_mvm *mvm,
struct iwl_rx_cmd_buffer *rxb);
void iwl_mvm_ftm_lc_notif(struct iwl_mvm *mvm,
struct iwl_rx_cmd_buffer *rxb);
int iwl_mvm_ftm_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
struct cfg80211_pmsr_request *request);
void iwl_mvm_ftm_abort(struct iwl_mvm *mvm, struct cfg80211_pmsr_request *req);
/* TDLS */
/*
......
......@@ -302,6 +302,12 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
RX_HANDLER_SYNC),
RX_HANDLER_GRP(LOCATION_GROUP, TOF_RESPONDER_STATS,
iwl_mvm_ftm_responder_stats, RX_HANDLER_ASYNC_LOCKED),
RX_HANDLER_GRP(LOCATION_GROUP, TOF_RANGE_RESPONSE_NOTIF,
iwl_mvm_ftm_range_resp, RX_HANDLER_ASYNC_LOCKED),
RX_HANDLER_GRP(LOCATION_GROUP, TOF_LC_NOTIF,
iwl_mvm_ftm_lc_notif, RX_HANDLER_ASYNC_LOCKED),
RX_HANDLER_GRP(DEBUG_GROUP, MFU_ASSERT_DUMP_NTF,
iwl_mvm_mfu_assert_dump_notif, RX_HANDLER_SYNC),
RX_HANDLER_GRP(PROT_OFFLOAD_GROUP, STORED_BEACON_NTF,
......@@ -693,6 +699,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
INIT_LIST_HEAD(&mvm->aux_roc_te_list);
INIT_LIST_HEAD(&mvm->async_handlers_list);
spin_lock_init(&mvm->time_event_lock);
INIT_LIST_HEAD(&mvm->ftm_initiator.loc_list);
INIT_WORK(&mvm->async_handlers_wk, iwl_mvm_async_handlers_wk);
INIT_WORK(&mvm->roc_done_wk, iwl_mvm_roc_done_wk);
......
......@@ -2118,6 +2118,8 @@ ieee80211_he_oper_size(const u8 *he_oper_ie)
#define IEEE80211_SPCT_MSR_RPRT_TYPE_BASIC 0
#define IEEE80211_SPCT_MSR_RPRT_TYPE_CCA 1
#define IEEE80211_SPCT_MSR_RPRT_TYPE_RPI 2
#define IEEE80211_SPCT_MSR_RPRT_TYPE_LCI 8
#define IEEE80211_SPCT_MSR_RPRT_TYPE_CIVIC 11
/* 802.11g ERP information element */
#define WLAN_ERP_NON_ERP_PRESENT (1<<0)
......
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