--- /dev/null
+From 9b199df4172237b8bdf86cc7ea417461b49a0514 Mon Sep 17 00:00:00 2001
+Date: Sat, 24 Apr 2021 16:01:17 +0200
+Subject: [PATCH] mt7915: add support for FTM responder role
+
+---
+ mt7915/init.c | 1 +
+ mt7915/main.c | 3 +++
+ mt7915/mcu.c | 32 ++++++++++++++++++++++++++++++++
+ mt7915/mcu.h | 1 +
+ mt7915/mt7915.h | 1 +
+ 5 files changed, 38 insertions(+)
+
+diff --git a/mt7915/init.c b/mt7915/init.c
+index 7b4f5c1..a0937f1 100644
+--- a/mt7915/init.c
++++ b/mt7915/init.c
+@@ -147,6 +147,7 @@ mt7915_init_wiphy(struct ieee80211_hw *hw)
+ wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
+
+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
++ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER);
+
+ ieee80211_hw_set(hw, HAS_RATE_CONTROL);
+ ieee80211_hw_set(hw, SUPPORTS_TX_ENCAP_OFFLOAD);
+diff --git a/mt7915/main.c b/mt7915/main.c
+index e5bd687..a0910c0 100644
+--- a/mt7915/main.c
++++ b/mt7915/main.c
+@@ -553,6 +553,9 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
+ mt7915_mcu_add_obss_spr(dev, vif, info->he_obss_pd.enable);
+ }
+
++ if (changed & BSS_CHANGED_FTM_RESPONDER)
++ mt7915_mcu_set_ftm_responder(phy, true);
++
+ if (changed & BSS_CHANGED_ERP_SLOT) {
+ int slottime = info->use_short_slot ? 9 : 20;
+
+diff --git a/mt7915/mcu.c b/mt7915/mcu.c
+index 6ca72dd..c22f580 100644
+--- a/mt7915/mcu.c
++++ b/mt7915/mcu.c
+@@ -3470,6 +3470,38 @@ int mt7915_mcu_apply_tx_dpd(struct mt7915_phy *phy)
+ return 0;
+ }
+
++int mt7915_mcu_set_ftm_responder(struct mt7915_phy *phy, bool enable)
++{
++ struct mt7915_dev *dev = phy->dev;
++ bool is_dbdc = phy != &dev->phy;
++
++ struct {
++ u8 ctrlType;
++ u8 ver; /* ? */
++ u8 throughold;
++ u8 iter;
++ u8 *payload;
++ u8 enable;
++ u8 role;
++ u8 catEnable;
++ u8 dbdc_idx;
++ u8 aucTypeSubtype[4];
++ } __packed req = {
++ .ctrlType = 0x00,
++ .ver = 2,
++ .throughold = 8,
++ .iter = 10,
++ .enable = enable,
++ .role = 1,
++ .catEnable = BIT(1),
++ .dbdc_idx = is_dbdc,
++ .aucTypeSubtype = {3, (IEEE80211_FTYPE_DATA >> 2) | (IEEE80211_STYPE_ACTION >> 2), 3, 3}
++ };
++
++ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_TMR_CTRL, &req,
++ sizeof(req), true);
++}
++
+ int mt7915_mcu_get_temperature(struct mt7915_dev *dev, int index)
+ {
+ struct {
+diff --git a/mt7915/mcu.h b/mt7915/mcu.h
+index 42582a6..7e43689 100644
+--- a/mt7915/mcu.h
++++ b/mt7915/mcu.h
+@@ -272,6 +272,7 @@ enum {
+ MCU_EXT_CMD_SET_RDD_CTRL = 0x3a,
+ MCU_EXT_CMD_ATE_CTRL = 0x3d,
+ MCU_EXT_CMD_PROTECT_CTRL = 0x3e,
++ MCU_EXT_CMD_TMR_CTRL = 0x44,
+ MCU_EXT_CMD_MAC_INIT_CTRL = 0x46,
+ MCU_EXT_CMD_RX_HDR_TRANS = 0x47,
+ MCU_EXT_CMD_MUAR_UPDATE = 0x48,
+diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
+index 4ea8972..0755156 100644
+--- a/mt7915/mt7915.h
++++ b/mt7915/mt7915.h
+@@ -332,6 +332,7 @@ int mt7915_mcu_set_fixed_rate(struct mt7915_dev *dev,
+ struct ieee80211_sta *sta, u32 rate);
+ int mt7915_mcu_set_eeprom(struct mt7915_dev *dev);
+ int mt7915_mcu_get_eeprom(struct mt7915_dev *dev, u32 offset);
++int mt7915_mcu_set_ftm_responder(struct mt7915_phy *phy, bool enable);
+ int mt7915_mcu_set_mac(struct mt7915_dev *dev, int band, bool enable,
+ bool hdr_trans);
+ int mt7915_mcu_set_test_param(struct mt7915_dev *dev, u8 param, bool test_mode,
+--
+2.31.1
+