diff mbox series

mt76: mt7915: update station's airtime and gi from event

Message ID 20211125091330.27770-1-MeiChia.Chiu@mediatek.com (mailing list archive)
State RFC
Delegated to: Felix Fietkau
Headers show
Series mt76: mt7915: update station's airtime and gi from event | expand

Commit Message

MeiChia Chiu Nov. 25, 2021, 9:13 a.m. UTC
From: MeiChia Chiu <meichia.chiu@mediatek.com>

To avoid race condition in firmware,
if firmware support airtime and gi event,
driver update station's airtime and gi from event.

Reviewed-by: Evelyn Tsai <evelyn.tsai@mediatek.com>
Reviewed-by: Ryder Lee <ryder.lee@mediatek.com>
Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: MeiChia Chiu <meichia.chiu@mediatek.com>

---
 .../net/wireless/mediatek/mt76/mt7915/init.c   |   2 +
 .../net/wireless/mediatek/mt76/mt7915/mac.c    |  35 ++++++++----
 .../net/wireless/mediatek/mt76/mt7915/mcu.c    | 138 ++++++++++++++++++++++++++++++++++++++++++++++++
 .../net/wireless/mediatek/mt76/mt7915/mcu.h    |  28 ++++++++++
 .../net/wireless/mediatek/mt76/mt7915/mt7915.h |  11 ++++
 5 files changed, 204 insertions(+), 10 deletions(-)

Comments

Ryder Lee Nov. 25, 2021, 6:56 p.m. UTC | #1
On Thu, 2021-11-25 at 17:13 +0800, MeiChia Chiu wrote:
> From: MeiChia Chiu <meichia.chiu@mediatek.com>

Should be [RFC].

> To avoid race condition in firmware,
> if firmware support airtime and gi event,
> driver update station's airtime and gi from event.
> 
> Reviewed-by: Evelyn Tsai <evelyn.tsai@mediatek.com>
> Reviewed-by: Ryder Lee <ryder.lee@mediatek.com>
> Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
> Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
> Signed-off-by: MeiChia Chiu <meichia.chiu@mediatek.com>
> 
> ---
>  .../net/wireless/mediatek/mt76/mt7915/init.c   |   2 +
>  .../net/wireless/mediatek/mt76/mt7915/mac.c    |  35 ++++++++----
>  .../net/wireless/mediatek/mt76/mt7915/mcu.c    | 138
> ++++++++++++++++++++++++++++++++++++++++++++++++
>  .../net/wireless/mediatek/mt76/mt7915/mcu.h    |  28 ++++++++++
>  .../net/wireless/mediatek/mt76/mt7915/mt7915.h |  11 ++++
>  5 files changed, 204 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
> b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
> index 4b56358d..a5f6d25d 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
> @@ -960,6 +960,8 @@ int mt7915_register_device(struct mt7915_dev
> *dev)
>  	if (ret)
>  		return ret;
>  
> +	dev->fw_ver = mt76_rr(dev, MT_SWDEF(0x7c));
> +
>  	return mt7915_init_debugfs(&dev->phy);
>  }
>  
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
> b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
> index 1041d88f..b2e20251 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
> @@ -1433,7 +1433,8 @@ mt7915_mac_tx_free(struct mt7915_dev *dev,
> struct sk_buff *skb)
>  		mt7915_txwi_free(dev, txwi, sta, &free_list);
>  	}
>  
> -	mt7915_mac_sta_poll(dev);
> +	if (!mt7915_firmware_offload(dev))
> +		mt7915_mac_sta_poll(dev);

@ Sujuan, can you double check if MCU_EXT_EVENT_TXRX_AIR_TIME works for
all firmware versions? Maybe we can use this single event directly if
everyone agrees with this change. 

I'd suggest adding some persuasive testing datas into the commit
message to help reviewers make adjudgement.

Ryder
Felix Fietkau Nov. 25, 2021, 7 p.m. UTC | #2
On 2021-11-25 19:56, Ryder Lee wrote:
> On Thu, 2021-11-25 at 17:13 +0800, MeiChia Chiu wrote:
>> From: MeiChia Chiu <meichia.chiu@mediatek.com>
> 
> Should be [RFC].
> 
>> To avoid race condition in firmware,
>> if firmware support airtime and gi event,
>> driver update station's airtime and gi from event.
>> 
>> Reviewed-by: Evelyn Tsai <evelyn.tsai@mediatek.com>
>> Reviewed-by: Ryder Lee <ryder.lee@mediatek.com>
>> Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
>> Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
>> Signed-off-by: MeiChia Chiu <meichia.chiu@mediatek.com>
>> 
>> ---
>>  .../net/wireless/mediatek/mt76/mt7915/init.c   |   2 +
>>  .../net/wireless/mediatek/mt76/mt7915/mac.c    |  35 ++++++++----
>>  .../net/wireless/mediatek/mt76/mt7915/mcu.c    | 138
>> ++++++++++++++++++++++++++++++++++++++++++++++++
>>  .../net/wireless/mediatek/mt76/mt7915/mcu.h    |  28 ++++++++++
>>  .../net/wireless/mediatek/mt76/mt7915/mt7915.h |  11 ++++
>>  5 files changed, 204 insertions(+), 10 deletions(-)
>> 
>> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
>> b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
>> index 4b56358d..a5f6d25d 100644
>> --- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
>> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
>> @@ -960,6 +960,8 @@ int mt7915_register_device(struct mt7915_dev
>> *dev)
>>  	if (ret)
>>  		return ret;
>>  
>> +	dev->fw_ver = mt76_rr(dev, MT_SWDEF(0x7c));
>> +
>>  	return mt7915_init_debugfs(&dev->phy);
>>  }
>>  
>> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
>> b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
>> index 1041d88f..b2e20251 100644
>> --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
>> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
>> @@ -1433,7 +1433,8 @@ mt7915_mac_tx_free(struct mt7915_dev *dev,
>> struct sk_buff *skb)
>>  		mt7915_txwi_free(dev, txwi, sta, &free_list);
>>  	}
>>  
>> -	mt7915_mac_sta_poll(dev);
>> +	if (!mt7915_firmware_offload(dev))
>> +		mt7915_mac_sta_poll(dev);
> 
> @ Sujuan, can you double check if MCU_EXT_EVENT_TXRX_AIR_TIME works for
> all firmware versions? Maybe we can use this single event directly if
> everyone agrees with this change.
> 
> I'd suggest adding some persuasive testing datas into the commit
> message to help reviewers make adjudgement.
How often is this event sent? I think the effectiveness of airtime 
fairness after this change needs to be carefully verified.

- Felix
kernel test robot Nov. 26, 2021, 7:04 a.m. UTC | #3
Hi MeiChia,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on kvalo-wireless-drivers-next/master]
[also build test WARNING on kvalo-wireless-drivers/master v5.16-rc2 next-20211125]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/MeiChia-Chiu/mt76-mt7915-update-station-s-airtime-and-gi-from-event/20211125-171608
base:   https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git master
config: riscv-allyesconfig (https://download.01.org/0day-ci/archive/20211126/202111261430.O1AAGfiL-lkp@intel.com/config)
compiler: riscv64-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/446d4941b6395463c374c2281241769ca0abaad9
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review MeiChia-Chiu/mt76-mt7915-update-station-s-airtime-and-gi-from-event/20211125-171608
        git checkout 446d4941b6395463c374c2281241769ca0abaad9
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=riscv SHELL=/bin/bash drivers/net/wireless/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   In file included from drivers/net/wireless/mediatek/mt76/mt7915/main.c:9:
>> drivers/net/wireless/mediatek/mt76/mt7915/mcu.h:234:1: warning: no semicolon at end of struct or union
     234 | };
         | ^
--
   In file included from drivers/net/wireless/mediatek/mt76/mt7915/mcu.c:7:
>> drivers/net/wireless/mediatek/mt76/mt7915/mcu.h:234:1: warning: no semicolon at end of struct or union
     234 | };
         | ^
   drivers/net/wireless/mediatek/mt76/mt7915/mcu.c:2516:5: warning: no previous prototype for 'mt7915_mcu_set_fixed_rate' [-Wmissing-prototypes]
    2516 | int mt7915_mcu_set_fixed_rate(struct mt7915_dev *dev,
         |     ^~~~~~~~~~~~~~~~~~~~~~~~~


vim +234 drivers/net/wireless/mediatek/mt76/mt7915/mcu.h

   217	
   218	struct mt7915_mcu_sta_stat {
   219		u8 event_id;
   220		u8 more_event;
   221		__le16 sta_num;
   222		union {
   223			struct {
   224				__le16 wlan_id;
   225				__le32 tx_time[4];
   226				__le32 rx_time[4];
   227			} airtime[0];
   228			struct {
   229				__le16 wlan_id;
   230				u8 gimode;
   231				u8 rsv;
   232			} gi[0];
   233		}
 > 234	};
   235	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff mbox series

Patch

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
index 4b56358d..a5f6d25d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
@@ -960,6 +960,8 @@  int mt7915_register_device(struct mt7915_dev *dev)
 	if (ret)
 		return ret;
 
+	dev->fw_ver = mt76_rr(dev, MT_SWDEF(0x7c));
+
 	return mt7915_init_debugfs(&dev->phy);
 }
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
index 1041d88f..b2e20251 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -1433,7 +1433,8 @@  mt7915_mac_tx_free(struct mt7915_dev *dev, struct sk_buff *skb)
 		mt7915_txwi_free(dev, txwi, sta, &free_list);
 	}
 
-	mt7915_mac_sta_poll(dev);
+	if (!mt7915_firmware_offload(dev))
+		mt7915_mac_sta_poll(dev);
 
 	if (wake)
 		mt76_set_tx_blocked(&dev->mt76, false);
@@ -2195,27 +2196,41 @@  void mt7915_mac_sta_rc_work(struct work_struct *work)
 void mt7915_mac_work(struct work_struct *work)
 {
 	struct mt7915_phy *phy;
+	struct mt7915_dev *dev;
 	struct mt76_phy *mphy;
 
 	mphy = (struct mt76_phy *)container_of(work, struct mt76_phy,
 					       mac_work.work);
 	phy = mphy->priv;
+	dev = phy->dev;
 
-	mutex_lock(&mphy->dev->mutex);
+	if (++phy->stats_work_count == 10) {
+		phy->stats_work_count = 0;
+		mutex_lock(&mphy->dev->mutex);
 
-	mt76_update_survey(mphy);
-	if (++mphy->mac_work_count == 5) {
-		mphy->mac_work_count = 0;
+		mt76_update_survey(mphy);
+		if (++mphy->mac_work_count == 5) {
+			mphy->mac_work_count = 0;
 
-		mt7915_mac_update_stats(phy);
-	}
+			mt7915_mac_update_stats(phy);
+		}
 
-	mutex_unlock(&mphy->dev->mutex);
+		mutex_unlock(&mphy->dev->mutex);
 
-	mt76_tx_status_check(mphy->dev, false);
+		mt76_tx_status_check(mphy->dev, false);
+	}
+
+	if (mt7915_firmware_offload(dev)) {
+		mutex_lock(&mphy->dev->mutex);
+		mt7915_mcu_get_all_sta_stats(phy->dev,
+					     MCU_EXT_EVENT_TXRX_AIR_TIME);
+		mt7915_mcu_get_all_sta_stats(phy->dev,
+					     MCU_EXT_EVENT_PHY_GI_MODE);
+		mutex_unlock(&mphy->dev->mutex);
+	}
 
 	ieee80211_queue_delayed_work(mphy->hw, &mphy->mac_work,
-				     MT7915_WATCHDOG_TIME);
+				     MT7915_WATCHDOG_TIME/10);
 }
 
 static void mt7915_dfs_stop_radar_detector(struct mt7915_phy *phy)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
index bfc10117..141ef797 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
@@ -510,6 +510,126 @@  mt7915_mcu_rx_log_message(struct mt7915_dev *dev, struct sk_buff *skb)
 		   (int)(skb->len - sizeof(*rxd)), data);
 }
 
+static void
+mt7915_mcu_get_sta_airtime(struct mt7915_dev *dev, struct sk_buff *skb)
+{
+	struct mt7915_mcu_sta_stat *at = (struct mt7915_mcu_sta_stat *)skb->data;
+	int idx;
+
+	for (idx = 0; idx < le16_to_cpu(at->sta_num); idx++) {
+		static const u8 ac_to_tid[] = {
+			[IEEE80211_AC_BE] = 0,
+			[IEEE80211_AC_BK] = 1,
+			[IEEE80211_AC_VI] = 4,
+			[IEEE80211_AC_VO] = 6
+		};
+		struct ieee80211_sta *sta;
+		struct mt7915_sta *msta;
+		struct mt76_wcid *wcid;
+		int i;
+		bool clear = false;
+		u16 w_idx;
+		u32 tx_time[IEEE80211_NUM_ACS], rx_time[IEEE80211_NUM_ACS];
+
+		w_idx = le16_to_cpu(at->airtime[idx].wlan_id);
+		wcid = rcu_dereference(dev->mt76.wcid[w_idx]);
+		sta = wcid_to_sta(wcid);
+		if (!sta)
+			continue;
+
+		msta = container_of(wcid, struct mt7915_sta, wcid);
+
+		for (i = 0; i < IEEE80211_NUM_ACS; i++) {
+			u32 tx_last = msta->airtime_ac[i];
+			u32 rx_last = msta->airtime_ac[i + 4];
+
+			msta->airtime_ac[i] =
+				le32_to_cpu(at->airtime[idx].tx_time[i]);
+			msta->airtime_ac[i + 4] =
+				le32_to_cpu(at->airtime[idx].rx_time[i]);
+
+			tx_time[i] = msta->airtime_ac[i] - tx_last;
+			rx_time[i] = msta->airtime_ac[i + 4] - rx_last;
+
+			if ((tx_last | rx_last) & BIT(30))
+				clear = true;
+		}
+
+		if (clear)
+			memset(msta->airtime_ac, 0, sizeof(msta->airtime_ac));
+
+		for (i = 0; i < IEEE80211_NUM_ACS; i++) {
+			u8 q = mt7915_lmac_mapping(dev, i);
+			u32 tx_cur = tx_time[q];
+			u32 rx_cur = rx_time[q];
+			u8 tid = ac_to_tid[i];
+
+			if (!tx_cur && !rx_cur)
+				continue;
+
+			ieee80211_sta_register_airtime(sta, tid, tx_cur,
+				rx_cur);
+		}
+	}
+}
+
+static void
+mt7915_mcu_get_sta_gi(struct mt7915_dev *dev, struct sk_buff *skb)
+{
+	struct mt7915_mcu_sta_stat *mgi = (struct mt7915_mcu_sta_stat *)skb->data;
+	int idx;
+
+	for (idx = 0; idx < le16_to_cpu(mgi->sta_num); idx++) {
+		struct ieee80211_sta *sta;
+		struct mt7915_sta *msta;
+		struct mt76_wcid *wcid;
+		struct rate_info *rate;
+		u8 val;
+		u16 w_idx;
+
+		w_idx = le16_to_cpu(mgi->gi[idx].wlan_id);
+		wcid = rcu_dereference(dev->mt76.wcid[w_idx]);
+		sta = wcid_to_sta(wcid);
+
+		if (!sta)
+			continue;
+
+		msta = container_of(wcid, struct mt7915_sta, wcid);
+		rate = &msta->wcid.rate;
+		val = mgi->gi[idx].gimode;
+
+		if (rate->flags & RATE_INFO_FLAGS_HE_MCS)
+			rate->he_gi = val;
+		else if (rate->flags &
+			(RATE_INFO_FLAGS_VHT_MCS | RATE_INFO_FLAGS_MCS)) {
+			if (val)
+				rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
+			else
+				rate->flags &= ~RATE_INFO_FLAGS_SHORT_GI;
+		}
+	}
+}
+
+static void
+mt7915_mcu_rx_sta_stats(struct mt7915_dev *dev, struct sk_buff *skb)
+{
+	u8 type;
+
+	skb_pull(skb, sizeof(struct mt7915_mcu_rxd));
+	type = *(skb->data);
+
+	switch (type) {
+	case MCU_EXT_EVENT_TXRX_AIR_TIME:
+		mt7915_mcu_get_sta_airtime(dev, skb);
+		break;
+	case MCU_EXT_EVENT_PHY_GI_MODE:
+		mt7915_mcu_get_sta_gi(dev, skb);
+		break;
+	default:
+		break;
+	}
+}
+
 static void
 mt7915_mcu_cca_finish(void *priv, u8 *mac, struct ieee80211_vif *vif)
 {
@@ -542,6 +662,9 @@  mt7915_mcu_rx_ext_event(struct mt7915_dev *dev, struct sk_buff *skb)
 				IEEE80211_IFACE_ITER_RESUME_ALL,
 				mt7915_mcu_cca_finish, dev);
 		break;
+	case MCU_EXT_EVENT_GET_ALL_STA_STATS:
+		mt7915_mcu_rx_sta_stats(dev, skb);
+		break;
 	default:
 		break;
 	}
@@ -571,6 +694,7 @@  void mt7915_mcu_rx_event(struct mt7915_dev *dev, struct sk_buff *skb)
 	    rxd->ext_eid == MCU_EXT_EVENT_ASSERT_DUMP ||
 	    rxd->ext_eid == MCU_EXT_EVENT_PS_SYNC ||
 	    rxd->ext_eid == MCU_EXT_EVENT_BCC_NOTIFY ||
+	    rxd->ext_eid == MCU_EXT_EVENT_GET_ALL_STA_STATS ||
 	    !rxd->seq)
 		mt7915_mcu_rx_unsolicited_event(dev, skb);
 	else
@@ -2993,6 +3117,20 @@  int mt7915_mcu_fw_dbg_ctrl(struct mt7915_dev *dev, u32 module, u8 level)
 				 sizeof(data), false);
 }
 
+int mt7915_mcu_get_all_sta_stats(struct mt7915_dev *dev, u8 event)
+{
+
+	struct {
+		u8 event_type;
+		u8 res[3];
+	} req = {
+		.event_type = event
+	};
+
+	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(GET_ALL_STA_STATS),
+		&req, sizeof(req), false);
+}
+
 static int mt7915_mcu_set_mwds(struct mt7915_dev *dev, bool enabled)
 {
 	struct {
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
index 4636b7dc..a1149224 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
@@ -44,6 +44,7 @@  enum {
 	MCU_EXT_EVENT_RDD_REPORT = 0x3a,
 	MCU_EXT_EVENT_CSA_NOTIFY = 0x4f,
 	MCU_EXT_EVENT_BCC_NOTIFY = 0x75,
+	MCU_EXT_EVENT_GET_ALL_STA_STATS = 0xb5,
 };
 
 enum {
@@ -53,6 +54,14 @@  enum {
 	MCU_ATE_CLEAN_TXQUEUE = 0x1c,
 };
 
+enum {
+	MCU_EXT_EVENT_ALL_TX_RX_RATE = 0x1,
+	MCU_EXT_EVENT_TX_STAT_PER_WCID = 0x2,
+	MCU_EXT_EVENT_RX_STAT = 0x03,
+	MCU_EXT_EVENT_TXRX_AIR_TIME = 0x05,
+	MCU_EXT_EVENT_PHY_GI_MODE = 0x07,
+};
+
 struct mt7915_mcu_rxd {
 	__le32 rxd[6];
 
@@ -206,6 +215,24 @@  struct mt7915_mcu_tx {
 	struct edca edca[IEEE80211_NUM_ACS];
 } __packed;
 
+struct mt7915_mcu_sta_stat {
+	u8 event_id;
+	u8 more_event;
+	__le16 sta_num;
+	union {
+		struct {
+			__le16 wlan_id;
+			__le32 tx_time[4];
+			__le32 rx_time[4];
+		} airtime[0];
+		struct {
+			__le16 wlan_id;
+			u8 gimode;
+			u8 rsv;
+		} gi[0];
+	}
+};
+
 #define WMM_AIFS_SET		BIT(0)
 #define WMM_CW_MIN_SET		BIT(1)
 #define WMM_CW_MAX_SET		BIT(2)
@@ -292,6 +319,7 @@  enum {
 	MCU_EXT_CMD_GROUP_PRE_CAL_INFO = 0xab,
 	MCU_EXT_CMD_DPD_PRE_CAL_INFO = 0xac,
 	MCU_EXT_CMD_PHY_STAT_INFO = 0xad,
+	MCU_EXT_CMD_GET_ALL_STA_STATS = 0xb5,
 };
 
 enum {
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
index c6c846d1..dea83e82 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
@@ -47,6 +47,8 @@ 
 #define MT7915_MAX_TWT_AGRT		16
 #define MT7915_MAX_STA_TWT_AGRT		8
 
+#define MT7915_FIRMWARE_V1		0
+
 struct mt7915_vif;
 struct mt7915_sta;
 struct mt7915_dfs_pulse;
@@ -228,6 +230,8 @@  struct mt7915_phy {
 	struct mib_stats mib;
 	struct mt76_channel_state state_ts;
 
+	u8 stats_work_count;
+
 #ifdef CONFIG_NL80211_TESTMODE
 	struct {
 		u32 *reg_backup;
@@ -276,6 +280,7 @@  struct mt7915_dev {
 	bool ibf;
 	u8 fw_debug_wm;
 	u8 fw_debug_wa;
+	u8 fw_ver;
 
 	void *cal;
 
@@ -457,6 +462,7 @@  int mt7915_mcu_rdd_cmd(struct mt7915_dev *dev, enum mt7915_rdd_cmd cmd,
 int mt7915_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3);
 int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl);
 int mt7915_mcu_fw_dbg_ctrl(struct mt7915_dev *dev, u32 module, u8 level);
+int mt7915_mcu_get_all_sta_stats(struct mt7915_dev *dev, u8 event);
 void mt7915_mcu_rx_event(struct mt7915_dev *dev, struct sk_buff *skb);
 void mt7915_mcu_exit(struct mt7915_dev *dev);
 
@@ -486,6 +492,11 @@  static inline void mt7915_irq_disable(struct mt7915_dev *dev, u32 mask)
 		mt76_set_irq_mask(&dev->mt76, MT_INT_MASK_CSR, mask, 0);
 }
 
+static inline bool mt7915_firmware_offload(struct mt7915_dev *dev)
+{
+	return dev->fw_ver == MT7915_FIRMWARE_V1;
+}
+
 u32 mt7915_mac_wtbl_lmac_addr(struct mt7915_dev *dev, u16 wcid, u8 dw);
 bool mt7915_mac_wtbl_update(struct mt7915_dev *dev, int idx, u32 mask);
 void mt7915_mac_reset_counters(struct mt7915_phy *phy);