[][MAC80211][wed][add trinfo when wed on]
[Description]
Add mt76 trinfo when wed on
[Release-log]
Change-Id: I8f87c181cc03ae3e2831943b93919036665c3c11
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/7010927
diff --git a/autobuild_mac80211_release/package/kernel/mt76/patches/3009-mt76-mt7915-wed-HW-ATF-support-for-mt7986.patch b/autobuild_mac80211_release/package/kernel/mt76/patches/3009-mt76-mt7915-wed-HW-ATF-support-for-mt7986.patch
new file mode 100644
index 0000000..6aa717b
--- /dev/null
+++ b/autobuild_mac80211_release/package/kernel/mt76/patches/3009-mt76-mt7915-wed-HW-ATF-support-for-mt7986.patch
@@ -0,0 +1,1014 @@
+From 74150a20593cebc6ae65e785ae3a784c0a21e23a Mon Sep 17 00:00:00 2001
+From: Lian Chen <lian.chen@mediatek.com>
+Date: Mon, 7 Nov 2022 14:47:44 +0800
+Subject: [PATCH 3009/3013] mt76: mt7915: wed: HW ATF support for mt7986
+
+Signed-off-by: Lian Chen <lian.chen@mediatek.com>
+---
+ mt76_connac_mcu.h | 2 +
+ mt7915/debugfs.c | 405 +++++++++++++++++++++++++++++++++++++++++++
+ mt7915/init.c | 39 +++++
+ mt7915/main.c | 15 ++
+ mt7915/mcu.c | 165 ++++++++++++++++++
+ mt7915/mt7915.h | 68 ++++++++
+ mt7915/mtk_debugfs.c | 133 +++++++++++++-
+ 7 files changed, 826 insertions(+), 1 deletion(-)
+ mode change 100644 => 100755 mt7915/init.c
+
+diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
+index 21ea55d..86ce55d 100644
+--- a/mt76_connac_mcu.h
++++ b/mt76_connac_mcu.h
+@@ -1159,6 +1159,7 @@ enum {
+ MCU_EXT_CMD_THERMAL_CTRL = 0x2c,
+ MCU_EXT_CMD_WTBL_UPDATE = 0x32,
+ MCU_EXT_CMD_SET_DRR_CTRL = 0x36,
++ MCU_EXT_CMD_SET_FEATURE_CTRL = 0x38,
+ MCU_EXT_CMD_SET_RDD_CTRL = 0x3a,
+ MCU_EXT_CMD_ATE_CTRL = 0x3d,
+ MCU_EXT_CMD_PROTECT_CTRL = 0x3e,
+@@ -1168,6 +1169,7 @@ enum {
+ MCU_EXT_CMD_MUAR_UPDATE = 0x48,
+ MCU_EXT_CMD_BCN_OFFLOAD = 0x49,
+ MCU_EXT_CMD_RX_AIRTIME_CTRL = 0x4a,
++ MCU_EXT_CMD_AT_PROC_MODULE = 0x4b,
+ MCU_EXT_CMD_SET_RX_PATH = 0x4e,
+ MCU_EXT_CMD_EFUSE_FREE_BLOCK = 0x4f,
+ MCU_EXT_CMD_TX_POWER_FEATURE_CTRL = 0x58,
+diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c
+index 3ef2148..b178036 100644
+--- a/mt7915/debugfs.c
++++ b/mt7915/debugfs.c
+@@ -12,6 +12,10 @@
+ #define FW_BIN_LOG_MAGIC_V2 0x44d9c99a
+ #endif
+
++#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
++#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
++
++
+ /** global debugfs **/
+
+ struct hw_queue_map {
+@@ -211,6 +215,406 @@ static const struct file_operations mt7915_sys_recovery_ops = {
+ .llseek = default_llseek,
+ };
+
++static ssize_t mt7915_vow_get(struct file *file, char __user *user_buf,
++ size_t count, loff_t *ppos)
++{
++ char *buff;
++ int desc = 0;
++ ssize_t ret;
++ static const size_t bufsz = 1000;
++
++ buff = kmalloc(bufsz, GFP_KERNEL);
++ if (!buff)
++ return -ENOMEM;
++
++ desc += scnprintf(buff + desc, bufsz - desc,
++ "======== Control =============\n"
++ "vow_atf_en=<0/1> 0:disable, 1:enable\n"
++ "vow_watf_en=<0/1> 0:disable, 1:enable\n"
++ "vow_watf_quantum=<level>-<quantum> unit 256us\n"
++ "======== Station table =============\n"
++ "vow_sta_dwrr_quantum_id=<wlanidx>-<WMM AC>-<Qid>\n"
++ "vow_dwrr_max_wait_time=<time> 256us\n"
++ "======== Debug =============\n"
++ "vow_show_en=<0/1> 0:dieable, 1:enable\n"
++ "vow_show_sta=<STA num>\n"
++ "show_vow_info\n"
++ "show_vow_sta_conf=<STA num> 0:all\n");
++ ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
++ kfree(buff);
++ return ret;
++}
++
++static int mt7915_set_vow_sta_dwrr_quantum_id(struct mt7915_dev *dev,
++ u32 wcid_id,
++ u32 ac, u32 val)
++{
++ struct mt7915_sta *msta;
++ struct mt76_wcid *wcid;
++ int ret;
++
++ wcid = rcu_dereference(dev->mt76.wcid[wcid_id]);
++ if ((!wcid) || (!wcid->sta)) {
++ dev_err(dev->mt76.dev, "%s: error station.\n", __func__);
++ return 0;
++ }
++
++ msta = container_of(wcid, struct mt7915_sta, wcid);
++
++ msta->vow_sta_cfg.dwrr_quantum[ac] = val;
++
++ ret = mt7915_mcu_set_vow_drr_ctrl(dev, msta, VOW_DRR_STA_AC0_QUA_ID + ac);
++ dev_info(dev->mt76.dev, "%s: set sta %d, ac %d, quantum id %u.\n",
++ __func__, wcid_id, ac, val);
++
++ return ret;
++}
++
++static int mt7915_set_vow_atf_en(struct mt7915_dev *dev, u32 val)
++{
++ int ret;
++
++ dev->vow_cfg.vow_atf_en = !!val;
++ dev->vow_cfg.sta_max_wait_time = val ? 0x40 : 0x1;
++ ret = mt7915_mcu_set_vow_feature_ctrl(dev);
++ dev_info(dev->mt76.dev, "%s: set vow_atf_en %u.\n",
++ __func__, val);
++
++ ret = mt7915_mcu_set_vow_drr_ctrl(dev, NULL,
++ VOW_DRR_AIRTIME_DEFICIT_BOUND);
++ dev_info(dev->mt76.dev, "%s: set vow_dwrr_max_wait_time %u.\n",
++ __func__, dev->vow_cfg.sta_max_wait_time);
++
++ return ret;
++}
++
++static int mt7915_set_vow_dwrr_max_wait_time(struct mt7915_dev *dev,
++ u32 val)
++{
++ int ret;
++
++ dev->vow_cfg.sta_max_wait_time = val;
++ ret = mt7915_mcu_set_vow_drr_ctrl(dev, NULL,
++ VOW_DRR_AIRTIME_DEFICIT_BOUND);
++ dev_info(dev->mt76.dev, "%s: set vow_dwrr_max_wait_time %u.\n",
++ __func__, val);
++
++ return ret;
++}
++
++static int mt7915_set_vow_watf_en(struct mt7915_dev *dev, u32 val)
++{
++ int ret;
++
++ dev->vow_cfg.vow_watf_en = !!val;
++ ret = mt7915_mcu_set_vow_feature_ctrl(dev);
++ dev_info(dev->mt76.dev, "%s: set vow_watf_en %u.\n", __func__, val);
++
++ return ret;
++}
++
++static int mt7915_set_vow_watf_quantum(struct mt7915_dev *dev,
++ u32 id, u32 val)
++{
++ int ret;
++
++ dev->vow_cfg.vow_sta_dwrr_quantum[id] = val;
++ ret = mt7915_mcu_set_vow_drr_ctrl(dev, NULL,
++ VOW_DRR_AIRTIME_QUANTUM_L0 + id);
++ dev_info(dev->mt76.dev, "%s: set quantum id %u, val %d.\n",
++ __func__, id, val);
++
++ return ret;
++}
++
++extern int mt7915_vow_pleinfo_read(struct mt7915_dev *dev);
++static void mt7915_show_station_tx_airtime(struct work_struct *work){
++ struct mt7915_dev *dev = container_of(work, struct mt7915_dev,
++ vow_work.work);
++ static u32 vow_last_tx_time[MT7916_WTBL_SIZE];
++ struct ieee80211_sta *ieee80211_sta;
++ struct mt7915_sta *msta;
++ struct mt76_wcid *wcid;
++ int idx = 0;
++ int i = 0;
++ u32 addr;
++ int tx_airtime_sum = 0;
++ int tx_add_airtime = 0;
++
++ if (!dev->vow_cfg.vow_show_en)
++ return;
++
++ rcu_read_lock();
++ for (idx = 1; (idx < dev->vow_cfg.vow_show_sta) &&
++ (idx < MT7915_WTBL_STA); idx++) {
++ if (idx >= ARRAY_SIZE(dev->mt76.wcid))
++ return;
++
++ wcid = rcu_dereference(dev->mt76.wcid[idx]);
++ if (!wcid || !wcid->sta)
++ continue;
++
++ msta = container_of(wcid, struct mt7915_sta, wcid);
++ addr = mt7915_mac_wtbl_lmac_addr(dev, idx, 20);
++ tx_airtime_sum = 0;
++
++ for (i = 0; i < IEEE80211_NUM_ACS; i++) {
++ tx_airtime_sum += mt76_rr(dev, addr);
++ addr += 8;
++ }
++ tx_add_airtime = tx_airtime_sum - vow_last_tx_time[idx];
++ vow_last_tx_time[idx] = tx_airtime_sum;
++
++ ieee80211_sta = container_of((void *)msta, struct ieee80211_sta,
++ drv_priv);
++
++ dev_info(dev->mt76.dev, "sta%u:" MACSTR " tx -> %u)\n",
++ idx, MAC2STR(ieee80211_sta->addr), tx_add_airtime);
++ }
++ mt7915_vow_pleinfo_read(dev);
++ ieee80211_queue_delayed_work(mt76_hw(dev), &dev->vow_work, 1 * HZ);
++ rcu_read_unlock();
++ return;
++}
++
++
++static int mt7915_set_vow_show_en(struct mt7915_dev *dev, u32 val)
++{
++ if (!!dev->vow_cfg.vow_show_en == !!val)
++ return 0;
++ dev->vow_cfg.vow_show_en = val;
++ mt7915_mcu_set_vow_feature_ctrl(dev);
++ if (dev->vow_cfg.vow_show_en) {
++ INIT_DELAYED_WORK(&dev->vow_work, mt7915_show_station_tx_airtime);
++ ieee80211_queue_delayed_work(mt76_hw(dev), &dev->vow_work, 1 * HZ);
++ }
++ else {
++ cancel_delayed_work_sync(&dev->vow_work);
++ }
++ return 0;
++}
++
++static int mt7915_set_vow_show_sta(struct mt7915_dev *dev, u32 val)
++{
++ dev->vow_cfg.vow_show_sta = val;
++ dev_info(dev->mt76.dev, "%s: show station up to %d.\n",
++ __func__, dev->vow_cfg.vow_show_sta);
++ return 0;
++}
++static int mt7915_set_show_vow_info(struct mt7915_dev *dev)
++{
++ dev_info(dev->mt76.dev, "====== VOW Control Information ======\n");
++ dev_info(dev->mt76.dev, "ATF Enbale: %d\n",
++ dev->vow_cfg.vow_atf_en);
++ dev_info(dev->mt76.dev, "WATF Enable: %d\n",
++ dev->vow_cfg.vow_watf_en);
++ dev_info(dev->mt76.dev, "refill_period: %d\n",
++ dev->vow_cfg.refill_period);
++ dev_info(dev->mt76.dev, "===== VOW Max Deficit Information =====\n");
++ dev_info(dev->mt76.dev, "VOW Max Deficit(unit 256us): %d\n",
++ dev->vow_cfg.sta_max_wait_time);
++ dev_info(dev->mt76.dev, "===== VOW Quantum Information =====\n");
++ dev_info(dev->mt76.dev, "Quantum ID 0 value(unit 256us): %d\n",
++ dev->vow_cfg.vow_sta_dwrr_quantum[0]);
++ dev_info(dev->mt76.dev, "Quantum ID 1 value(unit 256us): %d\n",
++ dev->vow_cfg.vow_sta_dwrr_quantum[1]);
++ dev_info(dev->mt76.dev, "Quantum ID 2 value(unit 256us): %d\n",
++ dev->vow_cfg.vow_sta_dwrr_quantum[2]);
++ dev_info(dev->mt76.dev, "Quantum ID 3 value(unit 256us): %d\n",
++ dev->vow_cfg.vow_sta_dwrr_quantum[3]);
++ return 0;
++}
++
++static int mt7915_show_vow_sta_conf(struct mt7915_dev *dev, u32 val)
++{
++ struct ieee80211_sta *ieee80211_sta;
++ struct mt7915_sta *msta;
++ struct mt76_wcid *wcid;
++ u32 i;
++ u8 q;
++
++ if (val > 0 && val < MT7915_WTBL_STA) {
++ wcid = rcu_dereference(dev->mt76.wcid[val]);
++ if (!wcid || !wcid->sta)
++ return 0;
++ msta = container_of(wcid, struct mt7915_sta, wcid);
++ ieee80211_sta = container_of((void *)msta, struct ieee80211_sta,
++ drv_priv);
++ dev_info(dev->mt76.dev, "%s: ****** sta%d: "MACSTR"******\n",
++ __func__, val, MAC2STR(ieee80211_sta->addr));
++ q = msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VO];
++ dev_info(dev->mt76.dev, "Ac0 --> %uus(%u)\n",
++ (dev->vow_cfg.vow_sta_dwrr_quantum[q] << 8), q);
++ q = msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VI];
++ dev_info(dev->mt76.dev, "Ac1 --> %uus(%u)\n",
++ (dev->vow_cfg.vow_sta_dwrr_quantum[q] << 8), q);
++ q = msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BE];
++ dev_info(dev->mt76.dev, "Ac2 --> %uus(%u)\n",
++ (dev->vow_cfg.vow_sta_dwrr_quantum[q] << 8), q);
++ q = msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BK];
++ dev_info(dev->mt76.dev, "Ac3 --> %uus(%u)\n",
++ (dev->vow_cfg.vow_sta_dwrr_quantum[q] << 8), q);
++ }
++ else{
++ for (i = 1; i < MT7915_WTBL_STA; i++) {
++ wcid = rcu_dereference(dev->mt76.wcid[i]);
++ if (!wcid || !wcid->sta)
++ continue;
++ msta = container_of(wcid, struct mt7915_sta, wcid);
++ ieee80211_sta = container_of((void *)msta, struct ieee80211_sta,
++ drv_priv);
++ dev_info(dev->mt76.dev, "%s: ****** sta%d: "MACSTR"******\n",
++ __func__, i, MAC2STR(ieee80211_sta->addr));
++ q = msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VO];
++ dev_info(dev->mt76.dev, "Ac0 --> %uus(%u)\n",
++ (dev->vow_cfg.vow_sta_dwrr_quantum[q] << 8), q);
++ q = msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VI];
++ dev_info(dev->mt76.dev, "Ac1 --> %uus(%u)\n",
++ (dev->vow_cfg.vow_sta_dwrr_quantum[q] << 8), q);
++ q = msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BE];
++ dev_info(dev->mt76.dev, "Ac2 --> %uus(%u)\n",
++ (dev->vow_cfg.vow_sta_dwrr_quantum[q] << 8), q);
++ q = msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BK];
++ dev_info(dev->mt76.dev, "Ac3 --> %uus(%u)\n",
++ (dev->vow_cfg.vow_sta_dwrr_quantum[q] << 8), q);
++ }
++ }
++ return 0;
++}
++
++static ssize_t
++mt7915_vow_set(struct file *file, const char __user *user_buf,
++ size_t count, loff_t *ppos)
++{
++ struct mt7915_phy *phy = file->private_data;
++ struct mt7915_dev *dev = phy->dev;
++ u32 rv, param1, param2, param3;
++ char buf[128];
++ int ret = 0;
++
++ if (count >= sizeof(buf))
++ return -EINVAL;
++
++ if (copy_from_user(buf, user_buf, count))
++ return -EFAULT;
++
++ if (count && buf[count - 1] == '\n')
++ buf[count - 1] = '\0';
++ else
++ buf[count] = '\0';
++
++ if (!strncmp(buf, "vow_sta_dwrr_quantum_id",
++ strlen("vow_sta_dwrr_quantum_id")))
++ {
++ rv = sscanf(buf, "vow_sta_dwrr_quantum_id=%d-%d-%d",
++ ¶m1, ¶m2, ¶m3);
++ if ((rv > 2) && (param2 < IEEE80211_NUM_ACS) &&
++ (param3 < VOW_WATF_LEVEL_NUM)) {
++ ret = mt7915_set_vow_sta_dwrr_quantum_id(dev, param1,
++ param2, param3);
++ }
++ else {
++ goto out;
++ }
++ }
++ else if (!strncmp(buf, "vow_atf_en", strlen("vow_atf_en")))
++ {
++ rv = sscanf(buf, "vow_atf_en=%d", ¶m1);
++ if (rv > 0) {
++ ret = mt7915_set_vow_atf_en(dev, param1);
++ }
++ else {
++ goto out;
++ }
++ }
++ else if (!strncmp(buf, "vow_dwrr_max_wait_time",
++ strlen("vow_dwrr_max_wait_time")))
++ {
++ rv = sscanf(buf, "vow_dwrr_max_wait_time=%d", ¶m1);
++ if (rv > 0) {
++ ret = mt7915_set_vow_dwrr_max_wait_time(dev, param1);
++ }
++ else {
++ goto out;
++ }
++ }
++ else if (!strncmp(buf, "vow_watf_en", strlen("vow_watf_en")))
++ {
++ rv = sscanf(buf, "vow_watf_en=%d", ¶m1);
++ if (rv > 0) {
++ ret = mt7915_set_vow_watf_en(dev, param1);
++ }
++ else {
++ goto out;
++ }
++ }
++ else if (!strncmp(buf, "vow_watf_quantum",
++ strlen("vow_watf_quantum")))
++ {
++ rv = sscanf(buf, "vow_watf_quantum=%d-%d",
++ ¶m1, ¶m2);
++ if ((dev->vow_cfg.vow_watf_en) && (rv > 1) &&
++ (param1 < VOW_WATF_LEVEL_NUM)) {
++ ret = mt7915_set_vow_watf_quantum(dev, param1, param2);
++ }
++ else {
++ goto out;
++ }
++ }
++ else if (!strncmp(buf, "vow_show_en", strlen("vow_show_en")))
++ {
++ rv = sscanf(buf, "vow_show_en=%d", ¶m1);
++ if (rv > 0) {
++ ret = mt7915_set_vow_show_en(dev, param1);
++ }
++ else {
++ goto out;
++ }
++ }
++ else if (!strncmp(buf, "vow_show_sta", strlen("vow_show_sta")))
++ {
++ rv = sscanf(buf, "vow_show_sta=%d", ¶m1);
++ if ((rv > 0)&& (param1 < MT7915_WTBL_STA)) {
++ ret = mt7915_set_vow_show_sta(dev, param1);
++ }
++ else {
++ goto out;
++ }
++ }
++ else if (!strncmp(buf, "show_vow_info", strlen("show_vow_info")))
++ {
++ if (rv == 0) {
++ ret = mt7915_set_show_vow_info(dev);
++ }
++ else {
++ dev_err(dev->mt76.dev, "show_vow_info\n");
++ goto out;
++ }
++ }
++ else if (!strncmp(buf, "show_vow_sta_conf", strlen("show_vow_sta_conf")))
++ {
++ rv = sscanf(buf, "show_vow_sta_conf=%d", ¶m1);
++ if ((rv > 0) && (param1 < MT7915_WTBL_STA)) {
++ ret = mt7915_show_vow_sta_conf(dev, param1);
++ }
++ else {
++ goto out;
++ }
++ }
++
++ if (ret)
++ return ret;
++out:
++ return count;
++}
++
++static const struct file_operations mt7915_vow_ops = {
++ .write = mt7915_vow_set,
++ .read = mt7915_vow_get,
++ .open = simple_open,
++ .llseek = default_llseek,
++};
++
+ static int
+ mt7915_radar_trigger(void *data, u64 val)
+ {
+@@ -1339,6 +1743,7 @@ int mt7915_init_debugfs(struct mt7915_phy *phy)
+ debugfs_create_devm_seqfile(dev->mt76.dev, "twt_stats", dir,
+ mt7915_twt_stats);
+ debugfs_create_file("rf_regval", 0600, dir, dev, &fops_rf_regval);
++ debugfs_create_file("vow", 0600, dir, phy, &mt7915_vow_ops);
+
+ if (!dev->dbdc_support || phy->mt76->band_idx) {
+ debugfs_create_u32("dfs_hw_pattern", 0400, dir,
+diff --git a/mt7915/init.c b/mt7915/init.c
+old mode 100644
+new mode 100755
+index e044f50..ef752e1
+--- a/mt7915/init.c
++++ b/mt7915/init.c
+@@ -563,10 +563,46 @@ mt7915_init_led_mux(struct mt7915_dev *dev)
+ }
+ }
+
++void mt7915_vow_init(struct mt7915_dev *dev)
++{
++ struct mt7915_vow_cfg *vow_cfg = &dev->vow_cfg;
++ bool ret;
++ int i;
++
++ if (!(is_mt7915(&dev->mt76)))
++ vow_cfg->vow_feature |= VOW_FEATURE_BWCG;
++
++ vow_cfg->vow_atf_en = 0x1;
++ vow_cfg->sta_max_wait_time = 0x40;
++ vow_cfg->refill_period = 0x5;
++
++ vow_cfg->vow_sta_dwrr_quantum[0] = 0x06;
++ vow_cfg->vow_sta_dwrr_quantum[1] = 0x0c;
++ vow_cfg->vow_sta_dwrr_quantum[2] = 0x10;
++ vow_cfg->vow_sta_dwrr_quantum[3] = 0x14;
++ vow_cfg->vow_sta_dwrr_quantum[4] = 0x18;
++ vow_cfg->vow_sta_dwrr_quantum[5] = 0x1c;
++ vow_cfg->vow_sta_dwrr_quantum[6] = 0x20;
++ vow_cfg->vow_sta_dwrr_quantum[7] = 0x24;
++
++ ret = mt7915_mcu_set_vow_drr_ctrl(dev, NULL,
++ VOW_DRR_AIRTIME_DEFICIT_BOUND);
++ ret = mt7915_mcu_set_vow_drr_ctrl(dev, NULL,
++ VOW_DRR_AIRTIME_QUANTUM_ALL);
++
++ for(i = 0; i < 4; i++)
++ ret = mt7915_mcu_set_vow_drr_ctrl(dev, NULL,
++ VOW_DRR_AIRTIME_QUANTUM_L0 + i);
++
++ ret = mt7915_mcu_set_vow_feature_ctrl(dev);
++ return;
++}
++
+ void mt7915_mac_init(struct mt7915_dev *dev)
+ {
+ int i;
+ u32 rx_len = is_mt7915(&dev->mt76) ? 0x400 : 0x680;
++ struct wiphy *wiphy = dev->phy.mt76->hw->wiphy;
+
+ /* config pse qid6 wfdma port selection */
+ if (!is_mt7915(&dev->mt76) && dev->hif2)
+@@ -588,6 +624,9 @@ void mt7915_mac_init(struct mt7915_dev *dev)
+ mt7915_mac_init_band(dev, i);
+
+ mt7915_init_led_mux(dev);
++
++ if (mt7915_is_atf_default_on(wiphy, dev))
++ mt7915_vow_init(dev);
+ }
+
+ int mt7915_txbf_init(struct mt7915_dev *dev)
+diff --git a/mt7915/main.c b/mt7915/main.c
+index 7dd3973..c87f04b 100644
+--- a/mt7915/main.c
++++ b/mt7915/main.c
+@@ -209,6 +209,7 @@ int mt7915_init_vif(struct mt7915_phy *phy, struct ieee80211_vif *vif, bool bf_e
+ {
+ struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
+ struct mt7915_dev *dev = phy->dev;
++ struct wiphy *wiphy = dev->phy.mt76->hw->wiphy;
+ struct mt76_txq *mtxq;
+ bool ext_phy = phy != &dev->phy;
+ int idx, ret = 0;
+@@ -270,6 +271,9 @@ int mt7915_init_vif(struct mt7915_phy *phy, struct ieee80211_vif *vif, bool bf_e
+ mt7915_mcu_add_sta(dev, vif, NULL, true);
+ rcu_assign_pointer(dev->mt76.wcid[idx], &mvif->sta.wcid);
+
++ if (mt7915_is_atf_default_on(wiphy, dev))
++ mt7915_mcu_set_vow_band(dev, mvif);
++
+ return ret;
+ }
+
+@@ -691,6 +695,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+ struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
+ struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
+ bool ext_phy = mvif->phy != &dev->phy;
++ struct wiphy *wiphy = dev->phy.mt76->hw->wiphy;
+ #ifdef CONFIG_MTK_VENDOR
+ struct mt7915_phy *phy;
+ #endif
+@@ -742,6 +747,16 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+ mt7915_mcu_set_mimo(phy, 0);
+ }
+ #endif
++ if (mt7915_is_atf_default_on(wiphy, dev)) {
++ msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VO] = 2;
++ msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VI] = 2;
++ msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BE] = 1;
++ msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BK] = 0;
++ mt7915_mcu_set_vow_drr_ctrl(dev, msta, VOW_DRR_STA_BSS_GROUP);
++ mt7915_mcu_set_vow_drr_ctrl(dev, msta, VOW_DRR_STA_PAUSE_SETTING);
++ mt7915_mcu_set_vow_drr_ctrl(dev, msta, VOW_DRR_STA_ALL);
++ }
++
+ return 0;
+ }
+
+diff --git a/mt7915/mcu.c b/mt7915/mcu.c
+index 116a5cc..15f20ad 100644
+--- a/mt7915/mcu.c
++++ b/mt7915/mcu.c
+@@ -3529,6 +3529,171 @@ int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band)
+ &req, sizeof(req), false);
+ }
+
++int mt7915_mcu_set_vow_drr_ctrl(struct mt7915_dev *dev,
++ struct mt7915_sta *msta,
++ u32 subcmd)
++{
++ u32 setting = 0;
++ u32 i;
++
++ struct {
++ __le32 action;
++ u8 wlan_idx_lo;
++ u8 status;
++ u8 wlan_idx_hi;
++ u8 rsv0[5];
++ union {
++ __le32 com_value;
++ struct {
++ u8 air_time_quantum[VOW_MAX_STA_DWRR_NUM];
++ }air_time_quantum_all;
++ }air_time_ctrl;
++ } __packed req = {
++ .action = cpu_to_le32(subcmd),
++ .wlan_idx_lo = msta ? to_wcid_lo(msta->wcid.idx) : to_wcid_lo(0x0),
++ .wlan_idx_hi = msta ? to_wcid_hi(msta->wcid.idx) : to_wcid_hi(0x0),
++ };
++
++ switch (subcmd) {
++ case VOW_DRR_STA_ALL:{
++ setting |= 0x00;
++ setting |= msta->vif->mt76.idx;
++ setting |= msta->vow_sta_cfg.ac_change_rule << 4;
++ setting |= (msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VO] << 8);
++ setting |= (msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VI] << 12);
++ setting |= (msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BE] << 16);
++ setting |= (msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BK] << 20);
++ if (dev->vow_cfg.vow_feature & VOW_FEATURE_BWCG)
++ setting |= ((UMAC_BWC_GROUP_MIN) << 24);
++ req.air_time_ctrl.com_value = cpu_to_le32(setting);
++ break;
++ }
++
++ case VOW_DRR_STA_BSS_GROUP:
++ req.air_time_ctrl.com_value = cpu_to_le32(0x0);
++ break;
++
++ case VOW_DRR_STA_PAUSE_SETTING:
++ req.air_time_ctrl.com_value = cpu_to_le32(msta->vow_sta_cfg.paused);
++ break;
++
++ case VOW_DRR_STA_AC0_QUA_ID:
++ req.air_time_ctrl.com_value =
++ cpu_to_le32(msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VO]);
++ break;
++
++ case VOW_DRR_STA_AC1_QUA_ID:
++ req.air_time_ctrl.com_value =
++ cpu_to_le32(msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VI]);
++ break;
++
++ case VOW_DRR_STA_AC2_QUA_ID:
++ req.air_time_ctrl.com_value =
++ cpu_to_le32(msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BE]);
++ break;
++
++ case VOW_DRR_STA_AC3_QUA_ID:
++ req.air_time_ctrl.com_value =
++ cpu_to_le32(msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BK]);
++ break;
++
++ case VOW_DRR_AIRTIME_DEFICIT_BOUND:
++ req.air_time_ctrl.com_value =
++ cpu_to_le32(dev->vow_cfg.sta_max_wait_time);
++ break;
++
++ case VOW_DRR_AIRTIME_QUANTUM_L0:
++ case VOW_DRR_AIRTIME_QUANTUM_L1:
++ case VOW_DRR_AIRTIME_QUANTUM_L2:
++ case VOW_DRR_AIRTIME_QUANTUM_L3:
++ case VOW_DRR_AIRTIME_QUANTUM_L4:
++ case VOW_DRR_AIRTIME_QUANTUM_L5:
++ case VOW_DRR_AIRTIME_QUANTUM_L6:
++ case VOW_DRR_AIRTIME_QUANTUM_L7:
++ req.air_time_ctrl.com_value =
++ cpu_to_le32(dev->vow_cfg.vow_sta_dwrr_quantum[subcmd -
++ VOW_DRR_AIRTIME_QUANTUM_L0]);
++ break;
++
++ case VOW_DRR_AIRTIME_QUANTUM_ALL: {
++ for (i = 0; i < VOW_MAX_STA_DWRR_NUM; i++) {
++ req.air_time_ctrl.air_time_quantum_all.air_time_quantum[i] =
++ dev->vow_cfg.vow_sta_dwrr_quantum[i];
++ }
++ break;
++ }
++
++ default:
++ break;
++ }
++
++ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SET_DRR_CTRL),
++ &req, sizeof(req), false);
++}
++
++int mt7915_mcu_set_vow_feature_ctrl(struct mt7915_dev *dev)
++{
++ u16 value = 0;
++ u32 sch_value = 0;
++
++ struct vow_feature_ctrl {
++ __le16 bss_flag;
++ __le16 vow_ctrl_flag;
++ __le16 bss_value[9];
++ __le16 vow_ctrl_val;
++ __le16 time_token_value[2];
++ __le16 length_token_value[2];
++ __le32 tx_ctrl;
++ __le32 sch_ctrl;
++ } __packed req = {
++ .bss_flag = cpu_to_le16(0xffff),
++ .vow_ctrl_flag = cpu_to_le16(0xf231),
++ .bss_value[0] = cpu_to_le16(0xffff),
++ .bss_value[2] = cpu_to_le16(0xffff),
++ .bss_value[8] = cpu_to_le16(0xffff),
++ .time_token_value[0] = cpu_to_le16(0xffff),
++ };
++
++ value |= dev->vow_cfg.refill_period;
++ value |= 1 << 4;
++ value |= 1 << 5;
++ value |= dev->vow_cfg.vow_watf_en << 9;
++ value |= 1 << 12;
++ value |= dev->vow_cfg.vow_atf_en << 13;
++ value |= 1 << 14;
++ req.vow_ctrl_val = value;
++ if (dev->vow_cfg.vow_atf_en)
++ req.tx_ctrl = cpu_to_le32(0x6bf69e1f);
++ sch_value |= 1 << 6;
++ sch_value |= (((dev->vow_cfg.vow_show_en == 0) ? 0 :
++ (dev->vow_cfg.vow_show_en - 1 )) << 4);
++ req.sch_ctrl = sch_value;
++
++ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SET_FEATURE_CTRL),
++ &req, sizeof(req), false);
++}
++
++int mt7915_mcu_set_vow_band(struct mt7915_dev *dev, struct mt7915_vif *mvif)
++{
++ struct module_ctrl {
++ __le16 action;
++ __le16 sub_action;
++ __le32 rsv1[5];
++ u8 rsv2[72];
++ u8 group_idx;
++ u8 band_idx;
++ u8 rsv3[2];
++ } __packed req = {
++ .action = cpu_to_le16(0x1),
++ .sub_action = cpu_to_le16(0x4),
++ .group_idx = mvif->mt76.band_idx * 4 + mvif->mt76.omac_idx % 4,
++ .band_idx = mvif->mt76.band_idx,
++ };
++
++ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(AT_PROC_MODULE),
++ &req, sizeof(req), false);
++}
++
+ int mt7915_mcu_set_txbf(struct mt7915_dev *dev, u8 action)
+ {
+ #define MT_BF_PROCESSING 4
+diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
+index 2335f78..c3a0b32 100644
+--- a/mt7915/mt7915.h
++++ b/mt7915/mt7915.h
+@@ -127,6 +127,58 @@ struct mt7915_twt_flow {
+
+ DECLARE_EWMA(avg_signal, 10, 8)
+
++#define VOW_MAX_STA_DWRR_NUM 8
++#define VOW_WATF_LEVEL_NUM 4
++#define VOW_FEATURE_BWCG BIT(3)
++#define UMAC_BWC_GROUP_MIN 40
++
++
++enum ext_cmd_vow_drr_ctrl {
++ /* Type 1 */
++ VOW_DRR_STA_ALL = 0x00,
++ VOW_DRR_STA_BSS_GROUP = 0x01,
++ VOW_DRR_STA_AC0_QUA_ID = 0x03,
++ VOW_DRR_STA_AC1_QUA_ID = 0x04,
++ VOW_DRR_STA_AC2_QUA_ID = 0x05,
++ VOW_DRR_STA_AC3_QUA_ID = 0x06,
++
++ /* Type 2 */
++ VOW_DRR_AIRTIME_DEFICIT_BOUND = 0x10,
++
++ /* Type 3 */
++ VOW_DRR_AIRTIME_QUANTUM_L0 = 0x20,
++ VOW_DRR_AIRTIME_QUANTUM_L1 = 0x21,
++ VOW_DRR_AIRTIME_QUANTUM_L2 = 0x22,
++ VOW_DRR_AIRTIME_QUANTUM_L3 = 0x23,
++ VOW_DRR_AIRTIME_QUANTUM_L4 = 0x24,
++ VOW_DRR_AIRTIME_QUANTUM_L5 = 0x25,
++ VOW_DRR_AIRTIME_QUANTUM_L6 = 0x26,
++ VOW_DRR_AIRTIME_QUANTUM_L7 = 0x27,
++ VOW_DRR_AIRTIME_QUANTUM_ALL = 0x28,
++ VOW_DRR_STA_PAUSE_SETTING = 0x30,
++};
++
++struct mt7915_vow_sta_cfg{
++ u8 dwrr_quantum[IEEE80211_NUM_ACS];
++ u8 ac_change_rule;
++ bool paused;
++};
++
++struct mt7915_vow_cfg{
++ /*ATF setting */
++ u32 vow_feature;
++ bool vow_atf_en;
++ u8 refill_period;
++ u8 sta_max_wait_time;
++ u8 vow_sta_dwrr_quantum[VOW_MAX_STA_DWRR_NUM];
++ u8 vow_show_en;
++ u32 vow_show_sta;
++
++ /*WATF setting */
++ bool vow_watf_en;
++};
++
++
+ struct mt7915_sta {
+ struct mt76_wcid wcid; /* must be first */
+
+@@ -148,6 +200,7 @@ struct mt7915_sta {
+ u8 flowid_mask;
+ struct mt7915_twt_flow flow[MT7915_MAX_STA_TWT_AGRT];
+ } twt;
++ struct mt7915_vow_sta_cfg vow_sta_cfg;
+ };
+
+ struct mt7915_vif_cap {
+@@ -461,6 +514,8 @@ struct mt7915_dev {
+ } dbg;
+ const struct mt7915_dbg_reg_desc *dbg_reg;
+ #endif
++ struct delayed_work vow_work;
++ struct mt7915_vow_cfg vow_cfg;
+ };
+
+ enum {
+@@ -493,6 +548,15 @@ enum mt7915_rdd_cmd {
+ RDD_IRQ_OFF,
+ };
+
++static inline bool
++mt7915_is_atf_default_on(struct wiphy *wiphy, struct mt7915_dev *dev)
++{
++ return ((!wiphy_ext_feature_isset(wiphy,
++ NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) ||
++ mtk_wed_device_active(&dev->mt76.mmio.wed));
++}
++
++
+ static inline struct mt7915_phy *
+ mt7915_hw_phy(struct ieee80211_hw *hw)
+ {
+@@ -621,6 +685,10 @@ int mt7915_mcu_set_mac(struct mt7915_dev *dev, int band, bool enable,
+ int mt7915_mcu_set_test_param(struct mt7915_dev *dev, u8 param, bool test_mode,
+ u8 en);
+ int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band);
++int mt7915_mcu_set_vow_drr_ctrl(struct mt7915_dev *dev, struct mt7915_sta *msta,
++ u32 subcmd);
++int mt7915_mcu_set_vow_feature_ctrl(struct mt7915_dev *dev);
++int mt7915_mcu_set_vow_band(struct mt7915_dev *dev, struct mt7915_vif *mvif);
+ int mt7915_mcu_set_sku_en(struct mt7915_phy *phy, bool enable);
+ int mt7915_mcu_set_txpower_sku(struct mt7915_phy *phy);
+ int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len,
+diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
+index f223871..d6ff7a5 100644
+--- a/mt7915/mtk_debugfs.c
++++ b/mt7915/mtk_debugfs.c
+@@ -1368,7 +1368,6 @@ static EMPTY_QUEUE_INFO_T ple_txcmd_queue_empty_info[] = {
+ };
+
+
+-
+ static char* sta_ctrl_reg[] = {"ENABLE", "DISABLE", "PAUSE"};
+ static u32 chip_show_sta_acq_info(struct seq_file *s, struct mt7915_dev *dev, u32 *ple_stat,
+ u32 *sta_pause, u32 *dis_sta_map,
+@@ -1522,6 +1521,138 @@ static void chip_get_sta_pause(struct mt7915_dev *dev, u32 *sta_pause)
+ }
+ }
+
++u32 vow_chip_show_sta_acq_info(struct mt7915_dev *dev, u32 *ple_stat,
++ u32 *sta_pause, u32 *dis_sta_map,
++ u32 dumptxd)
++{
++ int i, j;
++ u32 total_nonempty_cnt = 0;
++ u32 ac_num = 9, all_ac_num;
++ static char* sta_ctrl_reg[] = {"ENABLE", "DISABLE", "PAUSE"};
++ if (!is_mt7915(&dev->mt76))
++ ac_num = 17;
++
++ all_ac_num = ac_num * 4;
++
++ for (j = 0; j < all_ac_num; j++) { /* show AC Q info */
++ for (i = 0; i < 32; i++) {
++ if (((ple_stat[j + 1] & (0x1 << i)) >> i) == 0) {
++ u32 hfid, tfid, pktcnt, ac_n = j / ac_num, ctrl = 0;
++ u32 sta_num = i + (j % ac_num) * 32, fl_que_ctrl[3] = {0};
++ u32 wmmidx = 0;
++ struct mt7915_sta *msta;
++ struct mt76_wcid *wcid;
++ struct ieee80211_sta *sta = NULL;
++
++ wcid = rcu_dereference(dev->mt76.wcid[sta_num]);
++ sta = wcid_to_sta(wcid);
++ if (!sta) {
++ printk("ERROR!! no found STA wcid=%d\n", sta_num);
++ continue;
++ }
++ msta = container_of(wcid, struct mt7915_sta, wcid);
++ wmmidx = msta->vif->mt76.wmm_idx;
++
++ dev_info(dev->mt76.dev, "\tSTA%d AC%d: ", sta_num, ac_n);
++
++ fl_que_ctrl[0] |= MT_DBG_PLE_FL_QUE_CTRL0_EXECUTE_MASK;
++ fl_que_ctrl[0] |= (ENUM_UMAC_LMAC_PORT_2 <<
++ MT_PLE_FL_QUE_CTRL0_Q_BUF_PID_SHFT);
++ fl_que_ctrl[0] |= (ac_n << MT_PLE_FL_QUE_CTRL0_Q_BUF_QID_SHFT);
++ fl_que_ctrl[0] |= sta_num;
++ mt76_wr(dev, MT_DBG_PLE_FL_QUE_CTRL0, fl_que_ctrl[0]);
++ fl_que_ctrl[1] = mt76_rr(dev, MT_DBG_PLE_FL_QUE_CTRL2);
++ fl_que_ctrl[2] = mt76_rr(dev, MT_DBG_PLE_FL_QUE_CTRL3);
++ hfid = FIELD_GET(MT_DBG_PLE_FL_QUE_CTRL2_Q_HEAD_FID_MASK,
++ fl_que_ctrl[1]);
++ tfid = FIELD_GET(MT_DBG_PLE_FL_QUE_CTRL2_Q_TAIL_FID_MASK,
++ fl_que_ctrl[1]);
++ pktcnt = FIELD_GET(MT_DBG_PLE_FL_QUE_CTRL3_Q_PKT_NUM_MASK,
++ fl_que_ctrl[2]);
++ dev_info(dev->mt76.dev, "tail/head fid = 0x%03x/0x%03x, pkt cnt = 0x%03x",
++ tfid, hfid, pktcnt);
++
++ if (((sta_pause[j % 6] & 0x1 << i) >> i) == 1)
++ ctrl = 2;
++
++ if (((dis_sta_map[j % 6] & 0x1 << i) >> i) == 1)
++ ctrl = 1;
++
++ dev_info(dev->mt76.dev, " ctrl = %s", sta_ctrl_reg[ctrl]);
++ dev_info(dev->mt76.dev, " (wmmidx=%d)\n", wmmidx);
++
++ total_nonempty_cnt++;
++ }
++ }
++ }
++
++ return total_nonempty_cnt;
++}
++
++int mt7915_vow_pleinfo_read(struct mt7915_dev *dev)
++{
++ u32 ple_stat[70] = {0}, pg_flow_ctrl[8] = {0};
++ u32 ple_txcmd_stat;
++ u32 sta_pause[CR_NUM_OF_AC] = {0}, dis_sta_map[CR_NUM_OF_AC] = {0};
++ int i;
++
++ chip_get_ple_acq_stat(dev, ple_stat);
++ ple_txcmd_stat = mt76_rr(dev, MT_DBG_PLE_TXCMD_Q_EMPTY);
++ pg_flow_ctrl[0] = mt76_rr(dev, MT_DBG_PLE_FREEPG_CNT);
++ pg_flow_ctrl[1] = mt76_rr(dev, MT_DBG_PLE_FREEPG_HEAD_TAIL);
++ pg_flow_ctrl[2] = mt76_rr(dev, MT_DBG_PLE_PG_HIF_GROUP);
++ pg_flow_ctrl[3] = mt76_rr(dev, MT_DBG_PLE_HIF_PG_INFO);
++ pg_flow_ctrl[4] = mt76_rr(dev, MT_DBG_PLE_PG_CPU_GROUP);
++ pg_flow_ctrl[5] = mt76_rr(dev, MT_DBG_PLE_CPU_PG_INFO);
++ pg_flow_ctrl[6] = mt76_rr(dev, MT_DBG_PLE_PG_HIF_TXCMD_GROUP);
++ pg_flow_ctrl[7] = mt76_rr(dev, MT_DBG_PLE_HIF_TXCMD_PG_INFO);
++ chip_get_dis_sta_map(dev, dis_sta_map);
++ chip_get_sta_pause(dev, sta_pause);
++
++ dev_info(dev->mt76.dev, "PLE Configuration Info:\n");
++
++ for (i = 0; i < 32; i++) {
++ if (((ple_stat[0] & (0x1 << i)) >> i) == 0) {
++ u32 hfid, tfid, pktcnt, fl_que_ctrl[3] = {0};
++
++ if (ple_queue_empty_info[i].QueueName != NULL) {
++ fl_que_ctrl[0] |= MT_DBG_PLE_FL_QUE_CTRL0_EXECUTE_MASK;
++ fl_que_ctrl[0] |= (ple_queue_empty_info[i].Portid <<
++ MT_PLE_FL_QUE_CTRL0_Q_BUF_PID_SHFT);
++ fl_que_ctrl[0] |= (ple_queue_empty_info[i].Queueid <<
++ MT_PLE_FL_QUE_CTRL0_Q_BUF_QID_SHFT);
++ } else
++ continue;
++
++ if (ple_queue_empty_info[i].Queueid >=
++ ENUM_UMAC_LMAC_PLE_TX_Q_ALTX_0 &&
++ ple_queue_empty_info[i].Queueid <=
++ ENUM_UMAC_LMAC_PLE_TX_Q_PSMP_0)
++ /* band0 set TGID 0, bit31 = 0 */
++ mt76_wr(dev, MT_DBG_PLE_FL_QUE_CTRL1, 0x0);
++ else if (ple_queue_empty_info[i].Queueid >=
++ ENUM_UMAC_LMAC_PLE_TX_Q_ALTX_1 &&
++ ple_queue_empty_info[i].Queueid <=
++ ENUM_UMAC_LMAC_PLE_TX_Q_PSMP_1)
++ /* band1 set TGID 1, bit31 = 1 */
++ mt76_wr(dev, MT_DBG_PLE_FL_QUE_CTRL1, 0x80000000);
++
++ mt76_wr(dev, MT_DBG_PLE_FL_QUE_CTRL0, fl_que_ctrl[0]);
++ fl_que_ctrl[1] = mt76_rr(dev, MT_DBG_PLE_FL_QUE_CTRL2);
++ fl_que_ctrl[2] = mt76_rr(dev, MT_DBG_PLE_FL_QUE_CTRL3);
++ hfid = FIELD_GET(MT_DBG_PLE_FL_QUE_CTRL2_Q_HEAD_FID_MASK,
++ fl_que_ctrl[1]);
++ tfid = FIELD_GET(MT_DBG_PLE_FL_QUE_CTRL2_Q_TAIL_FID_MASK,
++ fl_que_ctrl[1]);
++ pktcnt = FIELD_GET(MT_DBG_PLE_FL_QUE_CTRL3_Q_PKT_NUM_MASK,
++ fl_que_ctrl[2]);
++ }
++ }
++
++ vow_chip_show_sta_acq_info(dev, ple_stat, sta_pause, dis_sta_map, 0);
++
++ return 0;
++}
+ static int mt7915_pleinfo_read(struct seq_file *s, void *data)
+ {
+ struct mt7915_dev *dev = dev_get_drvdata(s->private);
+--
+2.18.0
+