blob: 64bc9e5b6d03be399d438418ecabc7964faead63 [file] [log] [blame]
From 851129617f31e9c802b01eab480f9f8041cfde4f Mon Sep 17 00:00:00 2001
From: MeiChia Chiu <meichia.chiu@mediatek.com>
Date: Mon, 6 Jun 2022 20:15:51 +0800
Subject: [PATCH 1005/1008] mt76: certification patches
---
.../wireless/mediatek/mt76/mt76_connac_mcu.h | 1 +
.../net/wireless/mediatek/mt76/mt7915/init.c | 7 +-
.../net/wireless/mediatek/mt76/mt7915/mac.c | 23 +
.../net/wireless/mediatek/mt76/mt7915/main.c | 15 +-
.../net/wireless/mediatek/mt76/mt7915/mcu.c | 466 ++++++++++++++++++
.../net/wireless/mediatek/mt76/mt7915/mcu.h | 207 +++++++-
.../wireless/mediatek/mt76/mt7915/mt7915.h | 13 +
.../mediatek/mt76/mt7915/mtk_debugfs.c | 7 +-
.../wireless/mediatek/mt76/mt7915/vendor.c | 187 +++++++
.../wireless/mediatek/mt76/mt7915/vendor.h | 42 ++
10 files changed, 962 insertions(+), 6 deletions(-)
diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
index 865bbf3d..25aeedc2 100644
--- a/mt76_connac_mcu.h
+++ b/mt76_connac_mcu.h
@@ -1144,6 +1144,7 @@ enum {
MCU_EXT_CMD_PHY_STAT_INFO = 0xad,
/* for vendor csi and air monitor */
MCU_EXT_CMD_SMESH_CTRL = 0xae,
+ MCU_EXT_CMD_CERT_CFG = 0xb7,
MCU_EXT_CMD_CSI_CTRL = 0xc2,
};
diff --git a/mt7915/init.c b/mt7915/init.c
index 6e2a1c13..02d1b6d8 100644
--- a/mt7915/init.c
+++ b/mt7915/init.c
@@ -372,12 +372,17 @@ mt7915_init_wiphy(struct ieee80211_hw *hw)
if (!phy->dev->dbdc_support)
wiphy->txq_memory_limit = 32 << 20; /* 32 MiB */
- if (phy->mt76->cap.has_2ghz)
+ if (phy->mt76->cap.has_2ghz) {
+ phy->mt76->sband_2g.sband.ht_cap.ampdu_density =
+ IEEE80211_HT_MPDU_DENSITY_4;
phy->mt76->sband_2g.sband.ht_cap.cap |=
IEEE80211_HT_CAP_LDPC_CODING |
IEEE80211_HT_CAP_MAX_AMSDU;
+ }
if (phy->mt76->cap.has_5ghz) {
+ phy->mt76->sband_5g.sband.ht_cap.ampdu_density =
+ IEEE80211_HT_MPDU_DENSITY_4;
phy->mt76->sband_5g.sband.ht_cap.cap |=
IEEE80211_HT_CAP_LDPC_CODING |
IEEE80211_HT_CAP_MAX_AMSDU;
diff --git a/mt7915/mac.c b/mt7915/mac.c
index 8aa5350a..24052f47 100644
--- a/mt7915/mac.c
+++ b/mt7915/mac.c
@@ -7,6 +7,7 @@
#include "../dma.h"
#include "mac.h"
#include "mcu.h"
+#include "vendor.h"
#define to_rssi(field, rxv) ((FIELD_GET(field, rxv) - 220) / 2)
@@ -1736,6 +1737,21 @@ static void mt7915_mac_severe_check(struct mt7915_phy *phy)
phy->trb_ts = trb;
}
+#ifdef CONFIG_MTK_VENDOR
+void mt7915_capi_sta_rc_work(void *data, struct ieee80211_sta *sta)
+{
+ struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
+ struct mt7915_dev *dev = msta->vif->phy->dev;
+ u32 *changed = data;
+
+ spin_lock_bh(&dev->sta_poll_lock);
+ msta->changed |= *changed;
+ if (list_empty(&msta->rc_list))
+ list_add_tail(&msta->rc_list, &dev->sta_rc_list);
+ spin_unlock_bh(&dev->sta_poll_lock);
+}
+#endif
+
void mt7915_mac_sta_rc_work(struct work_struct *work)
{
struct mt7915_dev *dev = container_of(work, struct mt7915_dev, rc_work);
@@ -1758,6 +1774,13 @@ void mt7915_mac_sta_rc_work(struct work_struct *work)
sta = container_of((void *)msta, struct ieee80211_sta, drv_priv);
vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv);
+#ifdef CONFIG_MTK_VENDOR
+ if (changed & CAPI_RFEATURE_CHANGED) {
+ mt7915_mcu_set_rfeature_starec(&changed, dev, vif, sta);
+ spin_lock_bh(&dev->sta_poll_lock);
+ continue;
+ }
+#endif
if (changed & (IEEE80211_RC_SUPP_RATES_CHANGED |
IEEE80211_RC_NSS_CHANGED |
IEEE80211_RC_BW_CHANGED))
diff --git a/mt7915/main.c b/mt7915/main.c
index cd7314c9..d5fb947a 100644
--- a/mt7915/main.c
+++ b/mt7915/main.c
@@ -653,6 +653,9 @@ 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;
+#ifdef CONFIG_MTK_VENDOR
+ struct mt7915_phy *phy;
+#endif
int ret, idx;
idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7915_WTBL_STA);
@@ -678,7 +681,17 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
#ifdef CONFIG_MTK_VENDOR
mt7915_vendor_amnt_sta_remove(mvif->phy, sta);
#endif
- return mt7915_mcu_add_rate_ctrl(dev, vif, sta, false);
+ ret = mt7915_mcu_add_rate_ctrl(dev, vif, sta, false);
+ if (ret)
+ return ret;
+
+#ifdef CONFIG_MTK_VENDOR
+ if (dev->dbg.muru_onoff & MUMIMO_DL_CERT) {
+ phy = mvif->mt76.band_idx ? mt7915_ext_phy(dev) : &dev->phy;
+ mt7915_mcu_set_mimo(phy, 0);
+ }
+#endif
+ return 0;
}
void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
diff --git a/mt7915/mcu.c b/mt7915/mcu.c
index a6b5d213..53d4cd44 100644
--- a/mt7915/mcu.c
+++ b/mt7915/mcu.c
@@ -3579,6 +3579,472 @@ mt7915_mcu_report_csi(struct mt7915_dev *dev, struct sk_buff *skb)
return 0;
}
+void mt7915_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif)
+{
+ u8 mode, val;
+ struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
+ struct mt7915_dev *dev = mvif->phy->dev;
+
+ mode = FIELD_GET(RATE_CFG_MODE, *((u32 *)data));
+ val = FIELD_GET(RATE_CFG_VAL, *((u32 *)data));
+
+ switch (mode) {
+ case RATE_PARAM_FIXED_OFDMA:
+ if (val == 3) /* DL 20 and 80 */
+ dev->dbg.muru_onoff = OFDMA_DL; /* Enable OFDMA DL only */
+ else
+ dev->dbg.muru_onoff = val;
+ break;
+ case RATE_PARAM_FIXED_MIMO:
+ if (val == 0)
+ dev->dbg.muru_onoff = MUMIMO_DL_CERT | MUMIMO_DL;
+ break;
+ }
+}
+
+void mt7915_mcu_set_rfeature_starec(void *data, struct mt7915_dev *dev,
+ struct ieee80211_vif *vif, struct ieee80211_sta *sta)
+{
+ struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
+ struct mt7915_vif *mvif = msta->vif;
+ struct sta_rec_ra_fixed *ra;
+ struct sk_buff *skb;
+ struct tlv *tlv;
+ u8 mode, val;
+ int len = sizeof(struct sta_req_hdr) + sizeof(*ra);
+
+ mode = FIELD_GET(RATE_CFG_MODE, *((u32 *)data));
+ val = FIELD_GET(RATE_CFG_VAL, *((u32 *)data));
+
+ skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76, &msta->wcid, len);
+ if (IS_ERR(skb))
+ return;
+
+ tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_RA_UPDATE, sizeof(*ra));
+ ra = (struct sta_rec_ra_fixed *)tlv;
+
+ switch (mode) {
+ case RATE_PARAM_FIXED_GI:
+ ra->field = cpu_to_le32(RATE_PARAM_FIXED_GI);
+ ra->phy.sgi = val * 85;
+ break;
+ case RATE_PARAM_FIXED_HE_LTF:
+ ra->field = cpu_to_le32(RATE_PARAM_FIXED_HE_LTF);
+ ra->phy.he_ltf = val * 85;
+ break;
+ case RATE_PARAM_FIXED_MCS:
+ ra->field = cpu_to_le32(RATE_PARAM_FIXED_MCS);
+ ra->phy.mcs = val;
+ break;
+ }
+
+ mt76_mcu_skb_send_msg(&dev->mt76, skb,
+ MCU_EXT_CMD(STA_REC_UPDATE), true);
+}
+
+int mt7915_mcu_set_mu_prot_frame_th(struct mt7915_phy *phy, u32 val)
+{
+ struct mt7915_dev *dev = phy->dev;
+ struct {
+ __le32 cmd;
+ __le32 threshold;
+ } __packed req = {
+ .cmd = cpu_to_le32(MURU_SET_PROT_FRAME_THR),
+ .threshold = val,
+ };
+
+ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL), &req,
+ sizeof(req), false);
+}
+
+int mt7915_mcu_set_mu_edca(struct mt7915_phy *phy, u8 val)
+{
+ struct mt7915_dev *dev = phy->dev;
+ struct {
+ __le32 cmd;
+ u8 override;
+ } __packed req = {
+ .cmd = cpu_to_le32(MURU_SET_CERT_MU_EDCA_OVERRIDE),
+ .override = val,
+ };
+
+ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL), &req,
+ sizeof(req), false);
+}
+
+int mt7915_mcu_set_muru_cfg(struct mt7915_phy *phy, struct mt7915_muru *muru)
+{
+ struct mt7915_dev *dev = phy->dev;
+ struct {
+ __le32 cmd;
+ struct mt7915_muru muru;
+ } __packed req = {
+ .cmd = cpu_to_le32(MURU_SET_MANUAL_CFG),
+ };
+
+ memcpy(&req.muru, muru, sizeof(struct mt7915_muru));
+
+ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL), &req,
+ sizeof(req), false);
+}
+
+int mt7915_set_muru_cfg(struct mt7915_phy *phy, u8 action, u8 val)
+{
+ struct mt7915_muru muru;
+ struct mt7915_muru_dl *dl = &muru.dl;
+ struct mt7915_muru_ul *ul = &muru.ul;
+ struct mt7915_muru_comm *comm = &muru.comm;
+
+ memset(&muru, 0, sizeof(muru));
+
+ switch (action) {
+ case MURU_DL_USER_CNT:
+ dl->user_num = val;
+ comm->ppdu_format |= MURU_PPDU_HE_MU;
+ comm->sch_type |= MURU_OFDMA_SCH_TYPE_DL;
+ muru.cfg_comm = cpu_to_le32(MURU_COMM_SET);
+ muru.cfg_dl = cpu_to_le32(MURU_USER_CNT);
+ return mt7915_mcu_set_muru_cfg(phy, &muru);
+ case MURU_UL_USER_CNT:
+ ul->user_num = val;
+ comm->ppdu_format |= MURU_PPDU_HE_TRIG;
+ comm->sch_type |= MURU_OFDMA_SCH_TYPE_UL;
+ muru.cfg_comm = cpu_to_le32(MURU_COMM_SET);
+ muru.cfg_ul = cpu_to_le32(MURU_USER_CNT);
+ return mt7915_mcu_set_muru_cfg(phy, &muru);
+ default:
+ return 0;
+ }
+}
+
+void mt7915_mcu_set_ppdu_tx_type(struct mt7915_phy *phy, u8 ppdu_type)
+{
+ struct mt7915_dev *dev = phy->dev;
+ struct {
+ __le32 cmd;
+ u8 enable_su;
+ } __packed ppdu_type_req = {
+ .cmd = cpu_to_le32(MURU_SET_SUTX),
+ };
+
+ switch(ppdu_type) {
+ case CAPI_SU:
+ ppdu_type_req.enable_su = 1;
+ mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL),
+ &ppdu_type_req, sizeof(ppdu_type_req), false);
+ mt7915_set_muru_cfg(phy, MURU_DL_USER_CNT, 0);
+ break;
+ case CAPI_MU:
+ ppdu_type_req.enable_su = 0;
+ mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL),
+ &ppdu_type_req, sizeof(ppdu_type_req), false);
+ break;
+ default:
+ break;
+ }
+}
+
+void mt7915_mcu_set_nusers_ofdma(struct mt7915_phy *phy, u8 type, u8 ofdma_user_cnt)
+{
+ struct mt7915_dev *dev = phy->dev;
+ struct {
+ __le32 cmd;
+ u8 enable_su;
+ } __packed nusers_ofdma_req = {
+ .cmd = cpu_to_le32(MURU_SET_SUTX),
+ .enable_su = 0,
+ };
+
+ mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL),
+ &nusers_ofdma_req, sizeof(nusers_ofdma_req), false);
+
+ mt7915_mcu_set_mu_dl_ack_policy(phy, MU_DL_ACK_POLICY_SU_BAR);
+ mt7915_mcu_set_mu_prot_frame_th(phy, 9999);
+ switch(type) {
+ case MURU_UL_USER_CNT:
+ mt7915_set_muru_cfg(phy, MURU_UL_USER_CNT, ofdma_user_cnt);
+ break;
+ case MURU_DL_USER_CNT:
+ default:
+ mt7915_set_muru_cfg(phy, MURU_DL_USER_CNT, ofdma_user_cnt);
+ break;
+ }
+}
+
+void mt7915_mcu_set_mimo(struct mt7915_phy *phy, u8 direction)
+{
+#define MUMIMO_SET_FIXED_RATE 10
+#define MUMIMO_SET_FIXED_GRP_RATE 11
+#define MUMIMO_SET_FORCE_MU 12
+ struct mt7915_dev *dev = phy->dev;
+ struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
+ struct {
+ __le32 cmd;
+ __le16 sub_cmd;
+ __le16 disable_ra;
+ } __packed fixed_rate_req = {
+ .cmd = cpu_to_le32(MURU_SET_MUMIMO_CTRL),
+ .sub_cmd = cpu_to_le16(MUMIMO_SET_FIXED_RATE),
+ .disable_ra = cpu_to_le16(1),
+ };
+ struct {
+ __le32 cmd;
+ __le32 sub_cmd;
+ struct {
+ u8 user_cnt:2;
+ u8 rsv:2;
+ u8 ns0:1;
+ u8 ns1:1;
+ u8 ns2:1;
+ u8 ns3:1;
+
+ __le16 wlan_id_user0;
+ __le16 wlan_id_user1;
+ __le16 wlan_id_user2;
+ __le16 wlan_id_user3;
+
+ u8 dl_mcs_user0:4;
+ u8 dl_mcs_user1:4;
+ u8 dl_mcs_user2:4;
+ u8 dl_mcs_user3:4;
+
+ u8 ul_mcs_user0:4;
+ u8 ul_mcs_user1:4;
+ u8 ul_mcs_user2:4;
+ u8 ul_mcs_user3:4;
+
+ u8 ru_alloc;
+ u8 cap;
+ u8 gi;
+ u8 dl_ul;
+ } grp_rate_conf;
+ } fixed_grp_rate_req = {
+ .cmd = cpu_to_le32(MURU_SET_MUMIMO_CTRL),
+ .sub_cmd = cpu_to_le32(MUMIMO_SET_FIXED_GRP_RATE),
+ .grp_rate_conf = {
+ .user_cnt = 1,
+ .ru_alloc = 134,
+ .gi = 0,
+ .cap = 1,
+ .dl_ul = 0,
+ .wlan_id_user0 = cpu_to_le16(1),
+ .dl_mcs_user0 = 2,
+ .wlan_id_user1 = cpu_to_le16(2),
+ .dl_mcs_user1 = 2,
+ },
+ };
+ struct {
+ __le32 cmd;
+ __le16 sub_cmd;
+ bool force_mu;
+ } __packed force_mu_req = {
+ .cmd = cpu_to_le32(MURU_SET_MUMIMO_CTRL),
+ .sub_cmd = cpu_to_le16(MUMIMO_SET_FORCE_MU),
+ .force_mu = true,
+ };
+
+ switch (chandef->width) {
+ case NL80211_CHAN_WIDTH_20_NOHT:
+ case NL80211_CHAN_WIDTH_20:
+ fixed_grp_rate_req.grp_rate_conf.ru_alloc = 122;
+ break;
+ case NL80211_CHAN_WIDTH_80:
+ default:
+ break;
+ }
+
+ mt7915_mcu_set_mu_dl_ack_policy(phy, MU_DL_ACK_POLICY_SU_BAR);
+
+ mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL),
+ &fixed_rate_req, sizeof(fixed_rate_req), false);
+ mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL),
+ &fixed_grp_rate_req, sizeof(fixed_grp_rate_req), false);
+ mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL),
+ &force_mu_req, sizeof(force_mu_req), false);
+}
+
+void mt7915_mcu_set_dynalgo(struct mt7915_phy *phy, u8 enable)
+{
+ struct mt7915_dev *dev = phy->dev;
+ struct {
+ __le32 cmd;
+ u8 enable;
+ } __packed req = {
+ .cmd = cpu_to_le32(MURU_SET_20M_DYN_ALGO),
+ .enable = enable,
+ };
+
+ mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL),
+ &req, sizeof(req), false);
+}
+
+void mt7915_mcu_set_cert(struct mt7915_phy *phy, u8 type)
+{
+#define CFGINFO_CERT_CFG 4
+ struct mt7915_dev *dev = phy->dev;
+ struct {
+ struct basic_info{
+ u8 dbdc_idx;
+ u8 rsv[3];
+ __le32 tlv_num;
+ u8 tlv_buf[0];
+ } hdr;
+ struct cert_cfg{
+ __le16 tag;
+ __le16 length;
+ u8 cert_program;
+ u8 rsv[3];
+ } tlv;
+ } req = {
+ .hdr = {
+ .dbdc_idx = phy != &dev->phy,
+ .tlv_num = cpu_to_le32(1),
+ },
+ .tlv = {
+ .tag = cpu_to_le16(CFGINFO_CERT_CFG),
+ .length = cpu_to_le16(sizeof(struct cert_cfg)),
+ .cert_program = type, /* 1: CAPI Enable */
+ }
+ };
+
+ mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(CERT_CFG),
+ &req, sizeof(req), false);
+}
+
+void mt7915_mcu_set_bypass_smthint(struct mt7915_phy *phy, u8 val)
+{
+#define BF_CMD_CFG_PHY 36
+#define BF_PHY_SMTH_INTL_BYPASS 0
+ struct mt7915_dev *dev = phy->dev;
+ struct {
+ u8 cmd_category_id;
+ u8 action;
+ u8 band_idx;
+ u8 smthintbypass;
+ u8 rsv[12];
+ } req = {
+ .cmd_category_id = BF_CMD_CFG_PHY,
+ .action = BF_PHY_SMTH_INTL_BYPASS,
+ .band_idx = phy != &dev->phy,
+ .smthintbypass = val,
+ };
+
+ mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(TXBF_ACTION),
+ &req, sizeof(req), false);
+}
+
+int mt7915_mcu_set_bsrp_ctrl(struct mt7915_phy *phy, u16 interval,
+ u16 ru_alloc, u32 ppdu_dur, u8 trig_flow, u8 ext_cmd)
+{
+ struct mt7915_dev *dev = phy->dev;
+ struct {
+ __le32 cmd;
+ __le16 bsrp_interval;
+ __le16 bsrp_ru_alloc;
+ __le32 ppdu_duration;
+ u8 trigger_flow;
+ u8 ext_cmd_bsrp;
+ } __packed req = {
+ .cmd = cpu_to_le32(MURU_SET_BSRP_CTRL),
+ .bsrp_interval = cpu_to_le16(interval),
+ .bsrp_ru_alloc = cpu_to_le16(ru_alloc),
+ .ppdu_duration = cpu_to_le32(ppdu_dur),
+ .trigger_flow = trig_flow,
+ .ext_cmd_bsrp = ext_cmd,
+ };
+
+ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL), &req,
+ sizeof(req), false);
+}
+
+int mt7915_mcu_set_mu_dl_ack_policy(struct mt7915_phy *phy, u8 policy_num)
+{
+ struct mt7915_dev *dev = phy->dev;
+ struct {
+ __le32 cmd;
+ u8 ack_policy;
+ } __packed req = {
+ .cmd = cpu_to_le32(MURU_SET_MU_DL_ACK_POLICY),
+ .ack_policy = policy_num,
+ };
+
+ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL), &req,
+ sizeof(req), false);
+}
+
+int mt7915_mcu_set_txbf_sound_info(struct mt7915_phy *phy, u8 action,
+ u8 v1, u8 v2, u8 v3)
+{
+ struct mt7915_dev *dev = phy->dev;
+ struct {
+ u8 cmd_category_id;
+ u8 action;
+ u8 read_clear;
+ u8 vht_opt;
+ u8 he_opt;
+ u8 glo_opt;
+ __le16 wlan_idx;
+ u8 sound_interval;
+ u8 sound_stop;
+ u8 max_sound_sta;
+ u8 tx_time;
+ u8 mcs;
+ bool ldpc;
+ u8 inf;
+ u8 rsv;
+ } __packed req = {
+ .cmd_category_id = BF_CMD_TXSND_INFO,
+ .action = action,
+ };
+
+ switch (action) {
+ case BF_SND_CFG_OPT:
+ req.vht_opt = v1;
+ req.he_opt = v2;
+ req.glo_opt = v3;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(TXBF_ACTION), &req,
+ sizeof(req), false);
+}
+
+int mt7915_mcu_set_rfeature_trig_type(struct mt7915_phy *phy, u8 enable, u8 trig_type)
+{
+ struct mt7915_dev *dev = phy->dev;
+ int ret = 0;
+ struct {
+ __le32 cmd;
+ u8 trig_type;
+ } __packed req = {
+ .cmd = cpu_to_le32(MURU_SET_TRIG_TYPE),
+ .trig_type = trig_type,
+ };
+
+ if (enable) {
+ ret = mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL), &req,
+ sizeof(req), false);
+ if (ret)
+ return ret;
+ }
+
+ switch (trig_type) {
+ case CAPI_BASIC:
+ return mt7915_mcu_set_bsrp_ctrl(phy, 5, 67, 0, 0, enable);
+ case CAPI_BRP:
+ return mt7915_mcu_set_txbf_sound_info(phy, BF_SND_CFG_OPT,
+ 0x0, 0x0, 0x1b);
+ case CAPI_MU_BAR:
+ return mt7915_mcu_set_mu_dl_ack_policy(phy,
+ MU_DL_ACK_POLICY_MU_BAR);
+ case CAPI_BSRP:
+ return mt7915_mcu_set_bsrp_ctrl(phy, 5, 67, 4, 0, enable);
+ default:
+ return 0;
+ }
+}
#endif
#ifdef MTK_DEBUG
diff --git a/mt7915/mcu.h b/mt7915/mcu.h
index d3cc8283..aab1a6a3 100644
--- a/mt7915/mcu.h
+++ b/mt7915/mcu.h
@@ -396,10 +396,14 @@ enum {
RATE_PARAM_FIXED = 3,
RATE_PARAM_MMPS_UPDATE = 5,
RATE_PARAM_FIXED_HE_LTF = 7,
- RATE_PARAM_FIXED_MCS,
+ RATE_PARAM_FIXED_MCS = 8,
RATE_PARAM_FIXED_GI = 11,
RATE_PARAM_AUTO = 20,
RATE_PARAM_SPE_UPDATE = 22,
+#ifdef CONFIG_MTK_VENDOR
+ RATE_PARAM_FIXED_MIMO = 30,
+ RATE_PARAM_FIXED_OFDMA = 31,
+#endif
};
#define RATE_CFG_MCS GENMASK(3, 0)
@@ -411,6 +415,9 @@ enum {
#define RATE_CFG_PHY_TYPE GENMASK(27, 24)
#define RATE_CFG_HE_LTF GENMASK(31, 28)
+#define RATE_CFG_MODE GENMASK(15, 8)
+#define RATE_CFG_VAL GENMASK(7, 0)
+
enum {
THERMAL_PROTECT_PARAMETER_CTRL,
THERMAL_PROTECT_BASIC_INFO,
@@ -561,5 +568,203 @@ struct csi_data {
#define OFDMA_UL BIT(1)
#define MUMIMO_DL BIT(2)
#define MUMIMO_UL BIT(3)
+#define MUMIMO_DL_CERT BIT(4)
+
+#ifdef CONFIG_MTK_VENDOR
+struct mt7915_muru_comm {
+ u8 ppdu_format;
+ u8 sch_type;
+ u8 band;
+ u8 wmm_idx;
+ u8 spe_idx;
+ u8 proc_type;
+};
+
+struct mt7915_muru_dl {
+ u8 user_num;
+ u8 tx_mode;
+ u8 bw;
+ u8 gi;
+ u8 ltf;
+ /* sigB */
+ u8 mcs;
+ u8 dcm;
+ u8 cmprs;
+
+ u8 ru[8];
+ u8 c26[2];
+ u8 ack_policy;
+
+ struct {
+ __le16 wlan_idx;
+ u8 ru_alloc_seg;
+ u8 ru_idx;
+ u8 ldpc;
+ u8 nss;
+ u8 mcs;
+ u8 mu_group_idx;
+ u8 vht_groud_id;
+ u8 vht_up;
+ u8 he_start_stream;
+ u8 he_mu_spatial;
+ u8 ack_policy;
+ __le16 tx_power_alpha;
+ } usr[16];
+};
+
+struct mt7915_muru_ul {
+ u8 user_num;
+
+ /* UL TX */
+ u8 trig_type;
+ __le16 trig_cnt;
+ __le16 trig_intv;
+ u8 bw;
+ u8 gi_ltf;
+ __le16 ul_len;
+ u8 pad;
+ u8 trig_ta[ETH_ALEN];
+ u8 ru[8];
+ u8 c26[2];
+
+ struct {
+ __le16 wlan_idx;
+ u8 ru_alloc;
+ u8 ru_idx;
+ u8 ldpc;
+ u8 nss;
+ u8 mcs;
+ u8 target_rssi;
+ __le32 trig_pkt_size;
+ } usr[16];
+
+ /* HE TB RX Debug */
+ __le32 rx_hetb_nonsf_en_bitmap;
+ __le32 rx_hetb_cfg[2];
+
+ /* DL TX */
+ u8 ba_type;
+};
+
+struct mt7915_muru {
+ __le32 cfg_comm;
+ __le32 cfg_dl;
+ __le32 cfg_ul;
+
+ struct mt7915_muru_comm comm;
+ struct mt7915_muru_dl dl;
+ struct mt7915_muru_ul ul;
+};
+
+#define MURU_PPDU_HE_TRIG BIT(2)
+#define MURU_PPDU_HE_MU BIT(3)
+
+#define MURU_OFDMA_SCH_TYPE_DL BIT(0)
+#define MURU_OFDMA_SCH_TYPE_UL BIT(1)
+
+/* Common Config */
+#define MURU_COMM_PPDU_FMT BIT(0)
+#define MURU_COMM_SCH_TYPE BIT(1)
+#define MURU_COMM_SET (MURU_COMM_PPDU_FMT | MURU_COMM_SCH_TYPE)
+/* DL&UL User config*/
+#define MURU_USER_CNT BIT(4)
+
+enum {
+ CAPI_SU,
+ CAPI_MU,
+ CAPI_ER_SU,
+ CAPI_TB,
+ CAPI_LEGACY
+};
+
+enum {
+ CAPI_BASIC,
+ CAPI_BRP,
+ CAPI_MU_BAR,
+ CAPI_MU_RTS,
+ CAPI_BSRP,
+ CAPI_GCR_MU_BAR,
+ CAPI_BQRP,
+ CAPI_NDP_FRP
+};
+
+enum {
+ MURU_SET_BSRP_CTRL = 1,
+ MURU_SET_SUTX = 16,
+ MURU_SET_MUMIMO_CTRL = 17,
+ MURU_SET_MANUAL_CFG = 100,
+ MURU_SET_MU_DL_ACK_POLICY = 200,
+ MURU_SET_TRIG_TYPE = 201,
+ MURU_SET_20M_DYN_ALGO = 202,
+ MURU_SET_PROT_FRAME_THR = 204,
+ MURU_SET_CERT_MU_EDCA_OVERRIDE = 205,
+};
+
+enum {
+ MU_DL_ACK_POLICY_MU_BAR = 3,
+ MU_DL_ACK_POLICY_TF_FOR_ACK = 4,
+ MU_DL_ACK_POLICY_SU_BAR = 5,
+};
+
+enum {
+ BF_SOUNDING_OFF = 0,
+ BF_SOUNDING_ON,
+ BF_DATA_PACKET_APPLY,
+ BF_PFMU_MEM_ALLOCATE,
+ BF_PFMU_MEM_RELEASE,
+ BF_PFMU_TAG_READ,
+ BF_PFMU_TAG_WRITE,
+ BF_PROFILE_READ,
+ BF_PROFILE_WRITE,
+ BF_PN_READ,
+ BF_PN_WRITE,
+ BF_PFMU_MEM_ALLOC_MAP_READ,
+ BF_AID_SET,
+ BF_STA_REC_READ,
+ BF_PHASE_CALIBRATION,
+ BF_IBF_PHASE_COMP,
+ BF_LNA_GAIN_CONFIG,
+ BF_PROFILE_WRITE_20M_ALL,
+ BF_APCLIENT_CLUSTER,
+ BF_AWARE_CTRL,
+ BF_HW_ENABLE_STATUS_UPDATE,
+ BF_REPT_CLONED_STA_TO_NORMAL_STA,
+ BF_GET_QD,
+ BF_BFEE_HW_CTRL,
+ BF_PFMU_SW_TAG_WRITE,
+ BF_MOD_EN_CTRL,
+ BF_DYNSND_EN_INTR,
+ BF_DYNSND_CFG_DMCS_TH,
+ BF_DYNSND_EN_PFID_INTR,
+ BF_CONFIG,
+ BF_PFMU_DATA_WRITE,
+ BF_FBRPT_DBG_INFO_READ,
+ BF_CMD_TXSND_INFO,
+ BF_CMD_PLY_INFO,
+ BF_CMD_MU_METRIC,
+ BF_CMD_TXCMD,
+ BF_CMD_CFG_PHY,
+ BF_CMD_SND_CNT,
+ BF_CMD_MAX
+};
+
+enum {
+ BF_SND_READ_INFO = 0,
+ BF_SND_CFG_OPT,
+ BF_SND_CFG_INTV,
+ BF_SND_STA_STOP,
+ BF_SND_CFG_MAX_STA,
+ BF_SND_CFG_BFRP,
+ BF_SND_CFG_INF
+};
+
+enum {
+ MURU_UPDATE = 0,
+ MURU_DL_USER_CNT,
+ MURU_UL_USER_CNT,
+ MURU_DL_INIT,
+ MURU_UL_INIT,
+};
+#endif
#endif
diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
index 2af06d35..5aafaac0 100644
--- a/mt7915/mt7915.h
+++ b/mt7915/mt7915.h
@@ -663,6 +663,19 @@ void mt7915_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
#endif
#ifdef CONFIG_MTK_VENDOR
+void mt7915_capi_sta_rc_work(void *data, struct ieee80211_sta *sta);
+void mt7915_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif);
+void mt7915_mcu_set_rfeature_starec(void *data, struct mt7915_dev *dev,
+ struct ieee80211_vif *vif, struct ieee80211_sta *sta);
+int mt7915_mcu_set_rfeature_trig_type(struct mt7915_phy *phy, u8 enable, u8 trig_type);
+int mt7915_mcu_set_mu_dl_ack_policy(struct mt7915_phy *phy, u8 policy_num);
+void mt7915_mcu_set_ppdu_tx_type(struct mt7915_phy *phy, u8 ppdu_type);
+void mt7915_mcu_set_nusers_ofdma(struct mt7915_phy *phy, u8 type, u8 ofdma_user_cnt);
+void mt7915_mcu_set_mimo(struct mt7915_phy *phy, u8 direction);
+void mt7915_mcu_set_dynalgo(struct mt7915_phy *phy, u8 enable);
+int mt7915_mcu_set_mu_edca(struct mt7915_phy *phy, u8 val);
+void mt7915_mcu_set_cert(struct mt7915_phy *phy, u8 type);
+void mt7915_mcu_set_bypass_smthint(struct mt7915_phy *phy, u8 val);
void mt7915_vendor_register(struct mt7915_phy *phy);
int mt7915_mcu_set_csi(struct mt7915_phy *phy, u8 mode,
u8 cfg, u8 v1, u32 v2, u8 *mac_addr);
diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
index e239df95..222268fc 100644
--- a/mt7915/mtk_debugfs.c
+++ b/mt7915/mtk_debugfs.c
@@ -2486,7 +2486,8 @@ static int mt7915_muru_onoff_get(void *data, u64 *val)
*val = dev->dbg.muru_onoff;
- printk("mumimo ul:%d, mumimo dl:%d, ofdma ul:%d, ofdma dl:%d\n",
+ printk("cert mumimo dl:%d, mumimo ul:%d, mumimo dl:%d, ofdma ul:%d, ofdma dl:%d\n",
+ !!(dev->dbg.muru_onoff & MUMIMO_DL_CERT),
!!(dev->dbg.muru_onoff & MUMIMO_UL),
!!(dev->dbg.muru_onoff & MUMIMO_DL),
!!(dev->dbg.muru_onoff & OFDMA_UL),
@@ -2499,8 +2500,8 @@ static int mt7915_muru_onoff_set(void *data, u64 val)
{
struct mt7915_dev *dev = data;
- if (val > 15) {
- printk("Wrong value! The value is between 0 ~ 15.\n");
+ if (val > 31) {
+ printk("Wrong value! The value is between 0 ~ 31.\n");
goto exit;
}
diff --git a/mt7915/vendor.c b/mt7915/vendor.c
index b94d787e..7456c577 100644
--- a/mt7915/vendor.c
+++ b/mt7915/vendor.c
@@ -22,6 +22,29 @@ csi_ctrl_policy[NUM_MTK_VENDOR_ATTRS_CSI_CTRL] = {
[MTK_VENDOR_ATTR_CSI_CTRL_DATA] = { .type = NLA_NESTED },
};
+static const struct nla_policy
+wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = {
+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_MCS] = {.type = NLA_U8 },
+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_OFDMA] = {.type = NLA_U8 },
+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_PPDU_TX_TYPE] = {.type = NLA_U8 },
+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA] = {.type = NLA_U8 },
+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO] = {.type = NLA_U8 },
+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE] = {.type = NLA_U16 },
+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_MU_EDCA] = {.type = NLA_U8 },
+ [MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT] = {.type = NLA_U8 },
+};
+
+static const struct nla_policy
+rfeature_ctrl_policy[NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL] = {
+ [MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI] = {.type = NLA_U8 },
+ [MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_LTF] = { .type = NLA_U8 },
+ [MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_CFG] = { .type = NLA_NESTED },
+ [MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_EN] = { .type = NLA_U8 },
+ [MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE] = { .type = NLA_U8 },
+ [MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY] = { .type = NLA_U8 },
+ [MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TXBF] = { .type = NLA_U8 },
+};
+
struct csi_null_tone {
u8 start;
u8 end;
@@ -777,6 +800,148 @@ mt7915_vendor_amnt_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
return len + 1;
}
+static int mt7915_vendor_rfeature_ctrl(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data,
+ int data_len)
+{
+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+ struct mt7915_phy *phy = mt7915_hw_phy(hw);
+ struct mt7915_dev *dev = phy->dev;
+ struct nlattr *tb[NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL];
+ int err;
+ u32 val;
+
+ err = nla_parse(tb, MTK_VENDOR_ATTR_RFEATURE_CTRL_MAX, data, data_len,
+ rfeature_ctrl_policy, NULL);
+ if (err)
+ return err;
+
+ val = CAPI_RFEATURE_CHANGED;
+
+ if (tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI]) {
+ val |= FIELD_PREP(RATE_CFG_MODE, RATE_PARAM_FIXED_GI)|
+ FIELD_PREP(RATE_CFG_VAL, nla_get_u8(tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI]));
+ ieee80211_iterate_stations_atomic(hw, mt7915_capi_sta_rc_work, &val);
+ ieee80211_queue_work(hw, &dev->rc_work);
+ }
+ else if (tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_LTF]) {
+ val |= FIELD_PREP(RATE_CFG_MODE, RATE_PARAM_FIXED_HE_LTF)|
+ FIELD_PREP(RATE_CFG_VAL, nla_get_u8(tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_LTF]));
+ ieee80211_iterate_stations_atomic(hw, mt7915_capi_sta_rc_work, &val);
+ ieee80211_queue_work(hw, &dev->rc_work);
+ }
+ else if (tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_CFG]) {
+ u8 enable, trig_type;
+ int rem;
+ struct nlattr *cur;
+
+ nla_for_each_nested(cur, tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_CFG], rem) {
+ switch(nla_type(cur)) {
+ case MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_EN:
+ enable = nla_get_u8(cur);
+ break;
+ case MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE:
+ trig_type = nla_get_u8(cur);
+ break;
+ default:
+ return -EINVAL;
+ };
+ }
+
+ err = mt7915_mcu_set_rfeature_trig_type(phy, enable, trig_type);
+ if (err)
+ return err;
+ }
+ else if (tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY]) {
+ u8 ack_policy;
+
+ ack_policy = nla_get_u8(tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY]);
+#define HE_TB_PPDU_ACK 4
+ switch (ack_policy) {
+ case HE_TB_PPDU_ACK:
+ return mt7915_mcu_set_mu_dl_ack_policy(phy, ack_policy);
+ default:
+ return 0;
+ }
+ }
+ else if (tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TXBF]) {
+ u8 trig_txbf;
+
+ trig_txbf = nla_get_u8(tb[MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TXBF]);
+ /* CAPI only issues trig_txbf=disable */
+ }
+
+ return 0;
+}
+
+static int mt7915_vendor_wireless_ctrl(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data,
+ int data_len)
+{
+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+ struct mt7915_phy *phy = mt7915_hw_phy(hw);
+ struct mt7915_dev *dev = phy->dev;
+ struct nlattr *tb[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL];
+ int err;
+ u8 val8;
+ u16 val16;
+ u32 val32;
+
+ err = nla_parse(tb, MTK_VENDOR_ATTR_WIRELESS_CTRL_MAX, data, data_len,
+ wireless_ctrl_policy, NULL);
+ if (err)
+ return err;
+
+ val32 = CAPI_WIRELESS_CHANGED;
+
+ if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_MCS]) {
+ val32 &= ~CAPI_WIRELESS_CHANGED;
+ val32 |= CAPI_RFEATURE_CHANGED |
+ FIELD_PREP(RATE_CFG_MODE, RATE_PARAM_FIXED_MCS) |
+ FIELD_PREP(RATE_CFG_VAL, nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_MCS]));
+ ieee80211_iterate_stations_atomic(hw, mt7915_capi_sta_rc_work, &val32);
+ ieee80211_queue_work(hw, &dev->rc_work);
+ } else if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_OFDMA]) {
+ val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_OFDMA]);
+ val32 |= FIELD_PREP(RATE_CFG_MODE, RATE_PARAM_FIXED_OFDMA) |
+ FIELD_PREP(RATE_CFG_VAL, val8);
+ ieee80211_iterate_active_interfaces_atomic(hw, IEEE80211_IFACE_ITER_RESUME_ALL,
+ mt7915_set_wireless_vif, &val32);
+ if (val8 == 3) /* DL20and80 */
+ mt7915_mcu_set_dynalgo(phy, 1); /* Enable dynamic algo */
+ } else if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE]) {
+ val16 = nla_get_u16(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE]);
+ hw->max_tx_aggregation_subframes = val16;
+ hw->max_rx_aggregation_subframes = val16;
+ } else if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_MU_EDCA]) {
+ val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_MU_EDCA]);
+ mt7915_mcu_set_mu_edca(phy, val8);
+ } else if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_PPDU_TX_TYPE]) {
+ val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_PPDU_TX_TYPE]);
+ mt7915_mcu_set_ppdu_tx_type(phy, val8);
+ } else if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA]) {
+ val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA]);
+ if (FIELD_GET(OFDMA_UL, dev->dbg.muru_onoff) == 1)
+ mt7915_mcu_set_nusers_ofdma(phy, MURU_UL_USER_CNT, val8);
+ else
+ mt7915_mcu_set_nusers_ofdma(phy, MURU_DL_USER_CNT, val8);
+ } else if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO]) {
+ val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO]);
+ val32 |= FIELD_PREP(RATE_CFG_MODE, RATE_PARAM_FIXED_MIMO) |
+ FIELD_PREP(RATE_CFG_VAL, val8);
+ ieee80211_iterate_active_interfaces_atomic(hw, IEEE80211_IFACE_ITER_RESUME_ALL,
+ mt7915_set_wireless_vif, &val32);
+ } else if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT]) {
+ val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT]);
+ mt7915_mcu_set_cert(phy, val8); /* Cert Enable for OMI */
+ mt7915_mcu_set_bypass_smthint(phy, val8); /* Cert bypass smooth interpolation */
+ }
+
+ return 0;
+}
+
static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
{
.info = {
@@ -801,6 +966,28 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
.dumpit = mt7915_vendor_amnt_ctrl_dump,
.policy = amnt_ctrl_policy,
.maxattr = MTK_VENDOR_ATTR_AMNT_CTRL_MAX,
+ },
+ {
+ .info = {
+ .vendor_id = MTK_NL80211_VENDOR_ID,
+ .subcmd = MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL,
+ },
+ .flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
+ WIPHY_VENDOR_CMD_NEED_RUNNING,
+ .doit = mt7915_vendor_rfeature_ctrl,
+ .policy = rfeature_ctrl_policy,
+ .maxattr = MTK_VENDOR_ATTR_RFEATURE_CTRL_MAX,
+ },
+ {
+ .info = {
+ .vendor_id = MTK_NL80211_VENDOR_ID,
+ .subcmd = MTK_NL80211_VENDOR_SUBCMD_WIRELESS_CTRL,
+ },
+ .flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
+ WIPHY_VENDOR_CMD_NEED_RUNNING,
+ .doit = mt7915_vendor_wireless_ctrl,
+ .policy = wireless_ctrl_policy,
+ .maxattr = MTK_VENDOR_ATTR_WIRELESS_CTRL_MAX,
}
};
diff --git a/mt7915/vendor.h b/mt7915/vendor.h
index 976817f3..1b08321c 100644
--- a/mt7915/vendor.h
+++ b/mt7915/vendor.h
@@ -6,6 +6,48 @@
enum mtk_nl80211_vendor_subcmds {
MTK_NL80211_VENDOR_SUBCMD_AMNT_CTRL = 0xae,
MTK_NL80211_VENDOR_SUBCMD_CSI_CTRL = 0xc2,
+ MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL = 0xc3,
+ MTK_NL80211_VENDOR_SUBCMD_WIRELESS_CTRL = 0xc4,
+};
+
+enum mtk_capi_control_changed {
+ CAPI_RFEATURE_CHANGED = BIT(16),
+ CAPI_WIRELESS_CHANGED = BIT(17),
+};
+
+enum mtk_vendor_attr_wireless_ctrl {
+ MTK_VENDOR_ATTR_WIRELESS_CTRL_UNSPEC,
+
+ MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_MCS,
+ MTK_VENDOR_ATTR_WIRELESS_CTRL_OFDMA,
+ MTK_VENDOR_ATTR_WIRELESS_CTRL_PPDU_TX_TYPE,
+ MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA,
+ MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE,
+ MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO,
+ MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT = 9,
+
+ MTK_VENDOR_ATTR_WIRELESS_CTRL_MU_EDCA, /* reserve */
+ /* keep last */
+ NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL,
+ MTK_VENDOR_ATTR_WIRELESS_CTRL_MAX =
+ NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL - 1
+};
+
+enum mtk_vendor_attr_rfeature_ctrl {
+ MTK_VENDOR_ATTR_RFEATURE_CTRL_UNSPEC,
+
+ MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI,
+ MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_LTF,
+ MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_CFG,
+ MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_EN,
+ MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE,
+ MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY,
+ MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TXBF,
+
+ /* keep last */
+ NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL,
+ MTK_VENDOR_ATTR_RFEATURE_CTRL_MAX =
+ NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL - 1
};
enum mtk_vendor_attr_csi_ctrl {
--
2.25.1