developer | 617abbd | 2024-04-23 14:50:01 +0800 | [diff] [blame^] | 1 | From e9b712d9fa71f982a52ee20eb86929d8938ec7ca Mon Sep 17 00:00:00 2001 |
| 2 | From: Howard Hsu <howard-yh.hsu@mediatek.com> |
| 3 | Date: Mon, 4 Mar 2024 16:21:16 +0800 |
| 4 | Subject: [PATCH 110/116] mtk: wifi: mt76: mt7996: support band_idx option for |
| 5 | set_mu/get_mu vendor command |
| 6 | |
| 7 | The vendor command set_mu and get_mu should be executed with band_idx. |
| 8 | With band_idx, driver can access the corrsponding phy by band_idx. |
| 9 | |
| 10 | CR-Id: WCNCR00240772 |
| 11 | Change-Id: Id33d5efd3752e767fc11e852836d9939e4d6a088 |
| 12 | Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com> |
| 13 | --- |
| 14 | mt7996/mcu.c | 26 +++++++++++++++++++------- |
| 15 | mt7996/mcu.h | 1 + |
| 16 | mt7996/vendor.c | 40 +++++++++++++++++++++++++++++++++++----- |
| 17 | mt7996/vendor.h | 1 + |
| 18 | 4 files changed, 56 insertions(+), 12 deletions(-) |
| 19 | |
| 20 | diff --git a/mt7996/mcu.c b/mt7996/mcu.c |
| 21 | index dc719ecbe..cd49f7058 100644 |
| 22 | --- a/mt7996/mcu.c |
| 23 | +++ b/mt7996/mcu.c |
| 24 | @@ -5853,12 +5853,23 @@ int mt7996_mcu_set_vow_feature_ctrl(struct mt7996_phy *phy) |
| 25 | #ifdef CONFIG_MTK_VENDOR |
| 26 | void mt7996_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif) |
| 27 | { |
| 28 | - u8 mode, val; |
| 29 | + u8 mode, val, band_idx; |
| 30 | struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; |
| 31 | - struct mt7996_phy *phy = mvif->deflink.phy; |
| 32 | + struct mt7996_phy *phy; |
| 33 | + struct mt76_phy *mphy; |
| 34 | |
| 35 | mode = FIELD_GET(RATE_CFG_MODE, *((u32 *)data)); |
| 36 | val = FIELD_GET(RATE_CFG_VAL, *((u32 *)data)); |
| 37 | + band_idx = FIELD_GET(RATE_CFG_BAND_IDX, *((u32 *)data)); |
| 38 | + |
| 39 | + if (!mt7996_band_valid(mvif->dev, band_idx)) |
| 40 | + goto error; |
| 41 | + |
| 42 | + mphy = mvif->dev->mt76.phys[band_idx]; |
| 43 | + if (!mphy) |
| 44 | + goto error; |
| 45 | + |
| 46 | + phy = (struct mt7996_phy *)mphy->priv; |
| 47 | |
| 48 | switch (mode) { |
| 49 | case RATE_PARAM_FIXED_OFDMA: |
| 50 | @@ -5874,13 +5885,14 @@ void mt7996_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif) |
| 51 | phy->muru_onoff = MUMIMO_UL; |
| 52 | break; |
| 53 | case RATE_PARAM_AUTO_MU: |
| 54 | - if (val < 0 || val > 15) { |
| 55 | - printk("Wrong value! The value is between 0-15.\n"); |
| 56 | - break; |
| 57 | - } |
| 58 | - phy->muru_onoff = val; |
| 59 | + phy->muru_onoff = val & GENMASK(3, 0); |
| 60 | break; |
| 61 | } |
| 62 | + |
| 63 | + return; |
| 64 | +error: |
| 65 | + dev_err(mvif->dev->mt76.dev, "Invalid band_idx to config\n"); |
| 66 | + return; |
| 67 | } |
| 68 | |
| 69 | void mt7996_set_beacon_vif(void *data, u8 *mac, struct ieee80211_vif *vif) |
| 70 | diff --git a/mt7996/mcu.h b/mt7996/mcu.h |
| 71 | index ee36cf5ed..3d5a0c3c2 100644 |
| 72 | --- a/mt7996/mcu.h |
| 73 | +++ b/mt7996/mcu.h |
| 74 | @@ -888,6 +888,7 @@ enum { |
| 75 | #endif |
| 76 | }; |
| 77 | |
| 78 | +#define RATE_CFG_BAND_IDX GENMASK(17, 16) |
| 79 | #define RATE_CFG_MODE GENMASK(15, 8) |
| 80 | #define RATE_CFG_VAL GENMASK(7, 0) |
| 81 | |
| 82 | diff --git a/mt7996/vendor.c b/mt7996/vendor.c |
| 83 | index 31688c373..64ef5515c 100644 |
| 84 | --- a/mt7996/vendor.c |
| 85 | +++ b/mt7996/vendor.c |
| 86 | @@ -16,6 +16,7 @@ mu_ctrl_policy[NUM_MTK_VENDOR_ATTRS_MU_CTRL] = { |
| 87 | [MTK_VENDOR_ATTR_MU_CTRL_ONOFF] = {.type = NLA_U8 }, |
| 88 | [MTK_VENDOR_ATTR_MU_CTRL_DUMP] = {.type = NLA_U8 }, |
| 89 | [MTK_VENDOR_ATTR_MU_CTRL_STRUCT] = {.type = NLA_BINARY }, |
| 90 | + [MTK_VENDOR_ATTR_MU_CTRL_BAND_IDX] = {.type = NLA_U8 }, |
| 91 | }; |
| 92 | |
| 93 | static const struct nla_policy |
| 94 | @@ -135,7 +136,7 @@ static int mt7996_vendor_mu_ctrl(struct wiphy *wiphy, |
| 95 | struct mt7996_phy *phy = mt7996_hw_phy(hw); |
| 96 | struct mt7996_muru *muru; |
| 97 | int err; |
| 98 | - u8 val8; |
| 99 | + u8 val8, band_idx; |
| 100 | u32 val32 = 0; |
| 101 | |
| 102 | err = nla_parse(tb, MTK_VENDOR_ATTR_MU_CTRL_MAX, data, data_len, |
| 103 | @@ -143,10 +144,13 @@ static int mt7996_vendor_mu_ctrl(struct wiphy *wiphy, |
| 104 | if (err) |
| 105 | return err; |
| 106 | |
| 107 | - if (tb[MTK_VENDOR_ATTR_MU_CTRL_ONOFF]) { |
| 108 | + if (tb[MTK_VENDOR_ATTR_MU_CTRL_ONOFF] && |
| 109 | + tb[MTK_VENDOR_ATTR_MU_CTRL_BAND_IDX]) { |
| 110 | val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_MU_CTRL_ONOFF]); |
| 111 | + band_idx = nla_get_u8(tb[MTK_VENDOR_ATTR_MU_CTRL_BAND_IDX]); |
| 112 | val32 |= FIELD_PREP(RATE_CFG_MODE, RATE_PARAM_AUTO_MU) | |
| 113 | - FIELD_PREP(RATE_CFG_VAL, val8); |
| 114 | + FIELD_PREP(RATE_CFG_VAL, val8) | |
| 115 | + FIELD_PREP(RATE_CFG_BAND_IDX, band_idx); |
| 116 | ieee80211_iterate_active_interfaces_atomic(hw, IEEE80211_IFACE_ITER_RESUME_ALL, |
| 117 | mt7996_set_wireless_vif, &val32); |
| 118 | } else if (tb[MTK_VENDOR_ATTR_MU_CTRL_STRUCT]) { |
| 119 | @@ -168,18 +172,44 @@ mt7996_vendor_mu_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev, |
| 120 | unsigned long *storage) |
| 121 | { |
| 122 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); |
| 123 | - struct mt7996_phy *phy = mt7996_hw_phy(hw); |
| 124 | - int len = 0; |
| 125 | + struct mt7996_dev *dev = mt7996_hw_dev(hw); |
| 126 | + struct mt7996_phy *phy; |
| 127 | + struct mt76_phy *mphy; |
| 128 | + struct nlattr *tb[NUM_MTK_VENDOR_ATTRS_MU_CTRL]; |
| 129 | + int len = 0, err; |
| 130 | + u8 band_idx; |
| 131 | |
| 132 | if (*storage == 1) |
| 133 | return -ENOENT; |
| 134 | *storage = 1; |
| 135 | |
| 136 | + err = nla_parse(tb, MTK_VENDOR_ATTR_MU_CTRL_MAX, data, data_len, |
| 137 | + mu_ctrl_policy, NULL); |
| 138 | + if (err) |
| 139 | + return err; |
| 140 | + |
| 141 | + if (!tb[MTK_VENDOR_ATTR_MU_CTRL_BAND_IDX]) |
| 142 | + return -EINVAL; |
| 143 | + |
| 144 | + band_idx = nla_get_u8(tb[MTK_VENDOR_ATTR_MU_CTRL_BAND_IDX]); |
| 145 | + if (!mt7996_band_valid(dev, band_idx)) |
| 146 | + goto error; |
| 147 | + |
| 148 | + mphy = dev->mt76.phys[band_idx]; |
| 149 | + if (!mphy) |
| 150 | + goto error; |
| 151 | + |
| 152 | + phy = (struct mt7996_phy *)mphy->priv; |
| 153 | + |
| 154 | if (nla_put_u8(skb, MTK_VENDOR_ATTR_MU_CTRL_DUMP, phy->muru_onoff)) |
| 155 | return -ENOMEM; |
| 156 | len += 1; |
| 157 | |
| 158 | return len; |
| 159 | + |
| 160 | +error: |
| 161 | + dev_err(dev->mt76.dev, "Invalid band idx to dump\n"); |
| 162 | + return -EINVAL; |
| 163 | } |
| 164 | |
| 165 | void mt7996_set_wireless_rts_sigta(struct ieee80211_hw *hw, u8 value) { |
| 166 | diff --git a/mt7996/vendor.h b/mt7996/vendor.h |
| 167 | index 0d1ef3228..323467756 100644 |
| 168 | --- a/mt7996/vendor.h |
| 169 | +++ b/mt7996/vendor.h |
| 170 | @@ -68,6 +68,7 @@ enum mtk_vendor_attr_mu_ctrl { |
| 171 | MTK_VENDOR_ATTR_MU_CTRL_ONOFF, |
| 172 | MTK_VENDOR_ATTR_MU_CTRL_DUMP, |
| 173 | MTK_VENDOR_ATTR_MU_CTRL_STRUCT, |
| 174 | + MTK_VENDOR_ATTR_MU_CTRL_BAND_IDX, |
| 175 | |
| 176 | /* keep last */ |
| 177 | NUM_MTK_VENDOR_ATTRS_MU_CTRL, |
| 178 | -- |
| 179 | 2.39.2 |
| 180 | |