developer | bbd45e1 | 2023-05-19 08:22:06 +0800 | [diff] [blame] | 1 | From 5f06d232336902dee12f67fad58ac6b637ef89ec Mon Sep 17 00:00:00 2001 |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 2 | From: Lian Chen <lian.chen@mediatek.com> |
| 3 | Date: Mon, 7 Nov 2022 14:47:44 +0800 |
developer | bbd45e1 | 2023-05-19 08:22:06 +0800 | [diff] [blame] | 4 | Subject: [PATCH 3004/3012] wifi: mt76: mt7915: wed: HW ATF support for mt7986 |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 5 | |
| 6 | Signed-off-by: Lian Chen <lian.chen@mediatek.com> |
| 7 | --- |
| 8 | mt76_connac_mcu.h | 2 + |
| 9 | mt7915/debugfs.c | 405 +++++++++++++++++++++++++++++++++++++++++++ |
| 10 | mt7915/init.c | 39 +++++ |
developer | 1346ce5 | 2022-12-15 21:36:14 +0800 | [diff] [blame] | 11 | mt7915/main.c | 15 ++ |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 12 | mt7915/mcu.c | 165 ++++++++++++++++++ |
| 13 | mt7915/mt7915.h | 68 ++++++++ |
| 14 | mt7915/mtk_debugfs.c | 133 +++++++++++++- |
developer | 1346ce5 | 2022-12-15 21:36:14 +0800 | [diff] [blame] | 15 | 7 files changed, 826 insertions(+), 1 deletion(-) |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 16 | |
| 17 | diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h |
developer | bbd45e1 | 2023-05-19 08:22:06 +0800 | [diff] [blame] | 18 | index 1fdbc1c..fd5aecb 100644 |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 19 | --- a/mt76_connac_mcu.h |
| 20 | +++ b/mt76_connac_mcu.h |
developer | 4f0d84b | 2023-03-03 14:21:44 +0800 | [diff] [blame] | 21 | @@ -1161,6 +1161,7 @@ enum { |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 22 | MCU_EXT_CMD_THERMAL_CTRL = 0x2c, |
| 23 | MCU_EXT_CMD_WTBL_UPDATE = 0x32, |
| 24 | MCU_EXT_CMD_SET_DRR_CTRL = 0x36, |
| 25 | + MCU_EXT_CMD_SET_FEATURE_CTRL = 0x38, |
| 26 | MCU_EXT_CMD_SET_RDD_CTRL = 0x3a, |
| 27 | MCU_EXT_CMD_ATE_CTRL = 0x3d, |
| 28 | MCU_EXT_CMD_PROTECT_CTRL = 0x3e, |
developer | 4f0d84b | 2023-03-03 14:21:44 +0800 | [diff] [blame] | 29 | @@ -1170,6 +1171,7 @@ enum { |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 30 | MCU_EXT_CMD_MUAR_UPDATE = 0x48, |
| 31 | MCU_EXT_CMD_BCN_OFFLOAD = 0x49, |
| 32 | MCU_EXT_CMD_RX_AIRTIME_CTRL = 0x4a, |
| 33 | + MCU_EXT_CMD_AT_PROC_MODULE = 0x4b, |
| 34 | MCU_EXT_CMD_SET_RX_PATH = 0x4e, |
| 35 | MCU_EXT_CMD_EFUSE_FREE_BLOCK = 0x4f, |
| 36 | MCU_EXT_CMD_TX_POWER_FEATURE_CTRL = 0x58, |
| 37 | diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c |
developer | bbd45e1 | 2023-05-19 08:22:06 +0800 | [diff] [blame] | 38 | index a122457..e44ac9a 100644 |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 39 | --- a/mt7915/debugfs.c |
| 40 | +++ b/mt7915/debugfs.c |
| 41 | @@ -12,6 +12,10 @@ |
| 42 | #define FW_BIN_LOG_MAGIC_V2 0x44d9c99a |
| 43 | #endif |
| 44 | |
| 45 | +#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] |
| 46 | +#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" |
| 47 | + |
| 48 | + |
| 49 | /** global debugfs **/ |
| 50 | |
| 51 | struct hw_queue_map { |
developer | 356ecec | 2022-11-14 10:25:04 +0800 | [diff] [blame] | 52 | @@ -211,6 +215,406 @@ static const struct file_operations mt7915_sys_recovery_ops = { |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 53 | .llseek = default_llseek, |
| 54 | }; |
| 55 | |
| 56 | +static ssize_t mt7915_vow_get(struct file *file, char __user *user_buf, |
| 57 | + size_t count, loff_t *ppos) |
| 58 | +{ |
| 59 | + char *buff; |
| 60 | + int desc = 0; |
| 61 | + ssize_t ret; |
| 62 | + static const size_t bufsz = 1000; |
| 63 | + |
| 64 | + buff = kmalloc(bufsz, GFP_KERNEL); |
| 65 | + if (!buff) |
| 66 | + return -ENOMEM; |
| 67 | + |
| 68 | + desc += scnprintf(buff + desc, bufsz - desc, |
| 69 | + "======== Control =============\n" |
| 70 | + "vow_atf_en=<0/1> 0:disable, 1:enable\n" |
| 71 | + "vow_watf_en=<0/1> 0:disable, 1:enable\n" |
| 72 | + "vow_watf_quantum=<level>-<quantum> unit 256us\n" |
| 73 | + "======== Station table =============\n" |
| 74 | + "vow_sta_dwrr_quantum_id=<wlanidx>-<WMM AC>-<Qid>\n" |
| 75 | + "vow_dwrr_max_wait_time=<time> 256us\n" |
| 76 | + "======== Debug =============\n" |
| 77 | + "vow_show_en=<0/1> 0:dieable, 1:enable\n" |
| 78 | + "vow_show_sta=<STA num>\n" |
| 79 | + "show_vow_info\n" |
| 80 | + "show_vow_sta_conf=<STA num> 0:all\n"); |
| 81 | + ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc); |
| 82 | + kfree(buff); |
| 83 | + return ret; |
| 84 | +} |
| 85 | + |
| 86 | +static int mt7915_set_vow_sta_dwrr_quantum_id(struct mt7915_dev *dev, |
| 87 | + u32 wcid_id, |
| 88 | + u32 ac, u32 val) |
| 89 | +{ |
| 90 | + struct mt7915_sta *msta; |
| 91 | + struct mt76_wcid *wcid; |
| 92 | + int ret; |
| 93 | + |
| 94 | + wcid = rcu_dereference(dev->mt76.wcid[wcid_id]); |
| 95 | + if ((!wcid) || (!wcid->sta)) { |
| 96 | + dev_err(dev->mt76.dev, "%s: error station.\n", __func__); |
| 97 | + return 0; |
| 98 | + } |
| 99 | + |
| 100 | + msta = container_of(wcid, struct mt7915_sta, wcid); |
| 101 | + |
| 102 | + msta->vow_sta_cfg.dwrr_quantum[ac] = val; |
| 103 | + |
| 104 | + ret = mt7915_mcu_set_vow_drr_ctrl(dev, msta, VOW_DRR_STA_AC0_QUA_ID + ac); |
| 105 | + dev_info(dev->mt76.dev, "%s: set sta %d, ac %d, quantum id %u.\n", |
| 106 | + __func__, wcid_id, ac, val); |
| 107 | + |
| 108 | + return ret; |
| 109 | +} |
| 110 | + |
| 111 | +static int mt7915_set_vow_atf_en(struct mt7915_dev *dev, u32 val) |
| 112 | +{ |
| 113 | + int ret; |
| 114 | + |
| 115 | + dev->vow_cfg.vow_atf_en = !!val; |
| 116 | + dev->vow_cfg.sta_max_wait_time = val ? 0x40 : 0x1; |
| 117 | + ret = mt7915_mcu_set_vow_feature_ctrl(dev); |
| 118 | + dev_info(dev->mt76.dev, "%s: set vow_atf_en %u.\n", |
| 119 | + __func__, val); |
| 120 | + |
| 121 | + ret = mt7915_mcu_set_vow_drr_ctrl(dev, NULL, |
| 122 | + VOW_DRR_AIRTIME_DEFICIT_BOUND); |
| 123 | + dev_info(dev->mt76.dev, "%s: set vow_dwrr_max_wait_time %u.\n", |
| 124 | + __func__, dev->vow_cfg.sta_max_wait_time); |
| 125 | + |
| 126 | + return ret; |
| 127 | +} |
| 128 | + |
| 129 | +static int mt7915_set_vow_dwrr_max_wait_time(struct mt7915_dev *dev, |
| 130 | + u32 val) |
| 131 | +{ |
| 132 | + int ret; |
| 133 | + |
| 134 | + dev->vow_cfg.sta_max_wait_time = val; |
| 135 | + ret = mt7915_mcu_set_vow_drr_ctrl(dev, NULL, |
| 136 | + VOW_DRR_AIRTIME_DEFICIT_BOUND); |
| 137 | + dev_info(dev->mt76.dev, "%s: set vow_dwrr_max_wait_time %u.\n", |
| 138 | + __func__, val); |
| 139 | + |
| 140 | + return ret; |
| 141 | +} |
| 142 | + |
| 143 | +static int mt7915_set_vow_watf_en(struct mt7915_dev *dev, u32 val) |
| 144 | +{ |
| 145 | + int ret; |
| 146 | + |
| 147 | + dev->vow_cfg.vow_watf_en = !!val; |
| 148 | + ret = mt7915_mcu_set_vow_feature_ctrl(dev); |
| 149 | + dev_info(dev->mt76.dev, "%s: set vow_watf_en %u.\n", __func__, val); |
| 150 | + |
| 151 | + return ret; |
| 152 | +} |
| 153 | + |
| 154 | +static int mt7915_set_vow_watf_quantum(struct mt7915_dev *dev, |
| 155 | + u32 id, u32 val) |
| 156 | +{ |
| 157 | + int ret; |
| 158 | + |
| 159 | + dev->vow_cfg.vow_sta_dwrr_quantum[id] = val; |
| 160 | + ret = mt7915_mcu_set_vow_drr_ctrl(dev, NULL, |
| 161 | + VOW_DRR_AIRTIME_QUANTUM_L0 + id); |
| 162 | + dev_info(dev->mt76.dev, "%s: set quantum id %u, val %d.\n", |
| 163 | + __func__, id, val); |
| 164 | + |
| 165 | + return ret; |
| 166 | +} |
| 167 | + |
| 168 | +extern int mt7915_vow_pleinfo_read(struct mt7915_dev *dev); |
| 169 | +static void mt7915_show_station_tx_airtime(struct work_struct *work){ |
| 170 | + struct mt7915_dev *dev = container_of(work, struct mt7915_dev, |
| 171 | + vow_work.work); |
| 172 | + static u32 vow_last_tx_time[MT7916_WTBL_SIZE]; |
| 173 | + struct ieee80211_sta *ieee80211_sta; |
| 174 | + struct mt7915_sta *msta; |
| 175 | + struct mt76_wcid *wcid; |
| 176 | + int idx = 0; |
| 177 | + int i = 0; |
| 178 | + u32 addr; |
| 179 | + int tx_airtime_sum = 0; |
| 180 | + int tx_add_airtime = 0; |
| 181 | + |
| 182 | + if (!dev->vow_cfg.vow_show_en) |
| 183 | + return; |
| 184 | + |
| 185 | + rcu_read_lock(); |
| 186 | + for (idx = 1; (idx < dev->vow_cfg.vow_show_sta) && |
| 187 | + (idx < MT7915_WTBL_STA); idx++) { |
| 188 | + if (idx >= ARRAY_SIZE(dev->mt76.wcid)) |
| 189 | + return; |
| 190 | + |
| 191 | + wcid = rcu_dereference(dev->mt76.wcid[idx]); |
| 192 | + if (!wcid || !wcid->sta) |
| 193 | + continue; |
| 194 | + |
| 195 | + msta = container_of(wcid, struct mt7915_sta, wcid); |
| 196 | + addr = mt7915_mac_wtbl_lmac_addr(dev, idx, 20); |
| 197 | + tx_airtime_sum = 0; |
| 198 | + |
| 199 | + for (i = 0; i < IEEE80211_NUM_ACS; i++) { |
| 200 | + tx_airtime_sum += mt76_rr(dev, addr); |
| 201 | + addr += 8; |
| 202 | + } |
| 203 | + tx_add_airtime = tx_airtime_sum - vow_last_tx_time[idx]; |
| 204 | + vow_last_tx_time[idx] = tx_airtime_sum; |
| 205 | + |
| 206 | + ieee80211_sta = container_of((void *)msta, struct ieee80211_sta, |
| 207 | + drv_priv); |
| 208 | + |
| 209 | + dev_info(dev->mt76.dev, "sta%u:" MACSTR " tx -> %u)\n", |
| 210 | + idx, MAC2STR(ieee80211_sta->addr), tx_add_airtime); |
| 211 | + } |
| 212 | + mt7915_vow_pleinfo_read(dev); |
| 213 | + ieee80211_queue_delayed_work(mt76_hw(dev), &dev->vow_work, 1 * HZ); |
| 214 | + rcu_read_unlock(); |
| 215 | + return; |
| 216 | +} |
| 217 | + |
| 218 | + |
| 219 | +static int mt7915_set_vow_show_en(struct mt7915_dev *dev, u32 val) |
| 220 | +{ |
| 221 | + if (!!dev->vow_cfg.vow_show_en == !!val) |
| 222 | + return 0; |
| 223 | + dev->vow_cfg.vow_show_en = val; |
| 224 | + mt7915_mcu_set_vow_feature_ctrl(dev); |
| 225 | + if (dev->vow_cfg.vow_show_en) { |
| 226 | + INIT_DELAYED_WORK(&dev->vow_work, mt7915_show_station_tx_airtime); |
| 227 | + ieee80211_queue_delayed_work(mt76_hw(dev), &dev->vow_work, 1 * HZ); |
| 228 | + } |
| 229 | + else { |
| 230 | + cancel_delayed_work_sync(&dev->vow_work); |
| 231 | + } |
| 232 | + return 0; |
| 233 | +} |
| 234 | + |
| 235 | +static int mt7915_set_vow_show_sta(struct mt7915_dev *dev, u32 val) |
| 236 | +{ |
| 237 | + dev->vow_cfg.vow_show_sta = val; |
| 238 | + dev_info(dev->mt76.dev, "%s: show station up to %d.\n", |
| 239 | + __func__, dev->vow_cfg.vow_show_sta); |
| 240 | + return 0; |
| 241 | +} |
| 242 | +static int mt7915_set_show_vow_info(struct mt7915_dev *dev) |
| 243 | +{ |
| 244 | + dev_info(dev->mt76.dev, "====== VOW Control Information ======\n"); |
| 245 | + dev_info(dev->mt76.dev, "ATF Enbale: %d\n", |
| 246 | + dev->vow_cfg.vow_atf_en); |
| 247 | + dev_info(dev->mt76.dev, "WATF Enable: %d\n", |
| 248 | + dev->vow_cfg.vow_watf_en); |
| 249 | + dev_info(dev->mt76.dev, "refill_period: %d\n", |
| 250 | + dev->vow_cfg.refill_period); |
| 251 | + dev_info(dev->mt76.dev, "===== VOW Max Deficit Information =====\n"); |
| 252 | + dev_info(dev->mt76.dev, "VOW Max Deficit(unit 256us): %d\n", |
| 253 | + dev->vow_cfg.sta_max_wait_time); |
| 254 | + dev_info(dev->mt76.dev, "===== VOW Quantum Information =====\n"); |
| 255 | + dev_info(dev->mt76.dev, "Quantum ID 0 value(unit 256us): %d\n", |
| 256 | + dev->vow_cfg.vow_sta_dwrr_quantum[0]); |
| 257 | + dev_info(dev->mt76.dev, "Quantum ID 1 value(unit 256us): %d\n", |
| 258 | + dev->vow_cfg.vow_sta_dwrr_quantum[1]); |
| 259 | + dev_info(dev->mt76.dev, "Quantum ID 2 value(unit 256us): %d\n", |
| 260 | + dev->vow_cfg.vow_sta_dwrr_quantum[2]); |
| 261 | + dev_info(dev->mt76.dev, "Quantum ID 3 value(unit 256us): %d\n", |
| 262 | + dev->vow_cfg.vow_sta_dwrr_quantum[3]); |
| 263 | + return 0; |
| 264 | +} |
| 265 | + |
| 266 | +static int mt7915_show_vow_sta_conf(struct mt7915_dev *dev, u32 val) |
| 267 | +{ |
| 268 | + struct ieee80211_sta *ieee80211_sta; |
| 269 | + struct mt7915_sta *msta; |
| 270 | + struct mt76_wcid *wcid; |
| 271 | + u32 i; |
| 272 | + u8 q; |
| 273 | + |
| 274 | + if (val > 0 && val < MT7915_WTBL_STA) { |
| 275 | + wcid = rcu_dereference(dev->mt76.wcid[val]); |
| 276 | + if (!wcid || !wcid->sta) |
| 277 | + return 0; |
| 278 | + msta = container_of(wcid, struct mt7915_sta, wcid); |
| 279 | + ieee80211_sta = container_of((void *)msta, struct ieee80211_sta, |
| 280 | + drv_priv); |
| 281 | + dev_info(dev->mt76.dev, "%s: ****** sta%d: "MACSTR"******\n", |
| 282 | + __func__, val, MAC2STR(ieee80211_sta->addr)); |
| 283 | + q = msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VO]; |
| 284 | + dev_info(dev->mt76.dev, "Ac0 --> %uus(%u)\n", |
| 285 | + (dev->vow_cfg.vow_sta_dwrr_quantum[q] << 8), q); |
| 286 | + q = msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VI]; |
| 287 | + dev_info(dev->mt76.dev, "Ac1 --> %uus(%u)\n", |
| 288 | + (dev->vow_cfg.vow_sta_dwrr_quantum[q] << 8), q); |
| 289 | + q = msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BE]; |
| 290 | + dev_info(dev->mt76.dev, "Ac2 --> %uus(%u)\n", |
| 291 | + (dev->vow_cfg.vow_sta_dwrr_quantum[q] << 8), q); |
| 292 | + q = msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BK]; |
| 293 | + dev_info(dev->mt76.dev, "Ac3 --> %uus(%u)\n", |
| 294 | + (dev->vow_cfg.vow_sta_dwrr_quantum[q] << 8), q); |
| 295 | + } |
| 296 | + else{ |
| 297 | + for (i = 1; i < MT7915_WTBL_STA; i++) { |
| 298 | + wcid = rcu_dereference(dev->mt76.wcid[i]); |
| 299 | + if (!wcid || !wcid->sta) |
| 300 | + continue; |
| 301 | + msta = container_of(wcid, struct mt7915_sta, wcid); |
| 302 | + ieee80211_sta = container_of((void *)msta, struct ieee80211_sta, |
| 303 | + drv_priv); |
| 304 | + dev_info(dev->mt76.dev, "%s: ****** sta%d: "MACSTR"******\n", |
| 305 | + __func__, i, MAC2STR(ieee80211_sta->addr)); |
| 306 | + q = msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VO]; |
| 307 | + dev_info(dev->mt76.dev, "Ac0 --> %uus(%u)\n", |
| 308 | + (dev->vow_cfg.vow_sta_dwrr_quantum[q] << 8), q); |
| 309 | + q = msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VI]; |
| 310 | + dev_info(dev->mt76.dev, "Ac1 --> %uus(%u)\n", |
| 311 | + (dev->vow_cfg.vow_sta_dwrr_quantum[q] << 8), q); |
| 312 | + q = msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BE]; |
| 313 | + dev_info(dev->mt76.dev, "Ac2 --> %uus(%u)\n", |
| 314 | + (dev->vow_cfg.vow_sta_dwrr_quantum[q] << 8), q); |
| 315 | + q = msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BK]; |
| 316 | + dev_info(dev->mt76.dev, "Ac3 --> %uus(%u)\n", |
| 317 | + (dev->vow_cfg.vow_sta_dwrr_quantum[q] << 8), q); |
| 318 | + } |
| 319 | + } |
| 320 | + return 0; |
| 321 | +} |
| 322 | + |
| 323 | +static ssize_t |
| 324 | +mt7915_vow_set(struct file *file, const char __user *user_buf, |
| 325 | + size_t count, loff_t *ppos) |
| 326 | +{ |
| 327 | + struct mt7915_phy *phy = file->private_data; |
| 328 | + struct mt7915_dev *dev = phy->dev; |
| 329 | + u32 rv, param1, param2, param3; |
| 330 | + char buf[128]; |
| 331 | + int ret = 0; |
| 332 | + |
| 333 | + if (count >= sizeof(buf)) |
| 334 | + return -EINVAL; |
| 335 | + |
| 336 | + if (copy_from_user(buf, user_buf, count)) |
| 337 | + return -EFAULT; |
| 338 | + |
| 339 | + if (count && buf[count - 1] == '\n') |
| 340 | + buf[count - 1] = '\0'; |
| 341 | + else |
| 342 | + buf[count] = '\0'; |
| 343 | + |
| 344 | + if (!strncmp(buf, "vow_sta_dwrr_quantum_id", |
| 345 | + strlen("vow_sta_dwrr_quantum_id"))) |
| 346 | + { |
| 347 | + rv = sscanf(buf, "vow_sta_dwrr_quantum_id=%d-%d-%d", |
| 348 | + ¶m1, ¶m2, ¶m3); |
| 349 | + if ((rv > 2) && (param2 < IEEE80211_NUM_ACS) && |
| 350 | + (param3 < VOW_WATF_LEVEL_NUM)) { |
| 351 | + ret = mt7915_set_vow_sta_dwrr_quantum_id(dev, param1, |
| 352 | + param2, param3); |
| 353 | + } |
| 354 | + else { |
| 355 | + goto out; |
| 356 | + } |
| 357 | + } |
| 358 | + else if (!strncmp(buf, "vow_atf_en", strlen("vow_atf_en"))) |
| 359 | + { |
| 360 | + rv = sscanf(buf, "vow_atf_en=%d", ¶m1); |
| 361 | + if (rv > 0) { |
| 362 | + ret = mt7915_set_vow_atf_en(dev, param1); |
| 363 | + } |
| 364 | + else { |
| 365 | + goto out; |
| 366 | + } |
| 367 | + } |
| 368 | + else if (!strncmp(buf, "vow_dwrr_max_wait_time", |
| 369 | + strlen("vow_dwrr_max_wait_time"))) |
| 370 | + { |
| 371 | + rv = sscanf(buf, "vow_dwrr_max_wait_time=%d", ¶m1); |
| 372 | + if (rv > 0) { |
| 373 | + ret = mt7915_set_vow_dwrr_max_wait_time(dev, param1); |
| 374 | + } |
| 375 | + else { |
| 376 | + goto out; |
| 377 | + } |
| 378 | + } |
| 379 | + else if (!strncmp(buf, "vow_watf_en", strlen("vow_watf_en"))) |
| 380 | + { |
| 381 | + rv = sscanf(buf, "vow_watf_en=%d", ¶m1); |
| 382 | + if (rv > 0) { |
| 383 | + ret = mt7915_set_vow_watf_en(dev, param1); |
| 384 | + } |
| 385 | + else { |
| 386 | + goto out; |
| 387 | + } |
| 388 | + } |
| 389 | + else if (!strncmp(buf, "vow_watf_quantum", |
| 390 | + strlen("vow_watf_quantum"))) |
| 391 | + { |
| 392 | + rv = sscanf(buf, "vow_watf_quantum=%d-%d", |
| 393 | + ¶m1, ¶m2); |
| 394 | + if ((dev->vow_cfg.vow_watf_en) && (rv > 1) && |
| 395 | + (param1 < VOW_WATF_LEVEL_NUM)) { |
| 396 | + ret = mt7915_set_vow_watf_quantum(dev, param1, param2); |
| 397 | + } |
| 398 | + else { |
| 399 | + goto out; |
| 400 | + } |
| 401 | + } |
| 402 | + else if (!strncmp(buf, "vow_show_en", strlen("vow_show_en"))) |
| 403 | + { |
| 404 | + rv = sscanf(buf, "vow_show_en=%d", ¶m1); |
| 405 | + if (rv > 0) { |
| 406 | + ret = mt7915_set_vow_show_en(dev, param1); |
| 407 | + } |
| 408 | + else { |
| 409 | + goto out; |
| 410 | + } |
| 411 | + } |
| 412 | + else if (!strncmp(buf, "vow_show_sta", strlen("vow_show_sta"))) |
| 413 | + { |
| 414 | + rv = sscanf(buf, "vow_show_sta=%d", ¶m1); |
| 415 | + if ((rv > 0)&& (param1 < MT7915_WTBL_STA)) { |
| 416 | + ret = mt7915_set_vow_show_sta(dev, param1); |
| 417 | + } |
| 418 | + else { |
| 419 | + goto out; |
| 420 | + } |
| 421 | + } |
| 422 | + else if (!strncmp(buf, "show_vow_info", strlen("show_vow_info"))) |
| 423 | + { |
| 424 | + if (rv == 0) { |
| 425 | + ret = mt7915_set_show_vow_info(dev); |
| 426 | + } |
| 427 | + else { |
| 428 | + dev_err(dev->mt76.dev, "show_vow_info\n"); |
| 429 | + goto out; |
| 430 | + } |
| 431 | + } |
| 432 | + else if (!strncmp(buf, "show_vow_sta_conf", strlen("show_vow_sta_conf"))) |
| 433 | + { |
| 434 | + rv = sscanf(buf, "show_vow_sta_conf=%d", ¶m1); |
| 435 | + if ((rv > 0) && (param1 < MT7915_WTBL_STA)) { |
| 436 | + ret = mt7915_show_vow_sta_conf(dev, param1); |
| 437 | + } |
| 438 | + else { |
| 439 | + goto out; |
| 440 | + } |
| 441 | + } |
| 442 | + |
| 443 | + if (ret) |
| 444 | + return ret; |
| 445 | +out: |
| 446 | + return count; |
| 447 | +} |
| 448 | + |
| 449 | +static const struct file_operations mt7915_vow_ops = { |
| 450 | + .write = mt7915_vow_set, |
| 451 | + .read = mt7915_vow_get, |
| 452 | + .open = simple_open, |
| 453 | + .llseek = default_llseek, |
| 454 | +}; |
| 455 | + |
| 456 | static int |
| 457 | mt7915_radar_trigger(void *data, u64 val) |
| 458 | { |
developer | c923344 | 2023-04-04 06:06:17 +0800 | [diff] [blame] | 459 | @@ -1342,6 +1746,7 @@ int mt7915_init_debugfs(struct mt7915_phy *phy) |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 460 | debugfs_create_devm_seqfile(dev->mt76.dev, "twt_stats", dir, |
| 461 | mt7915_twt_stats); |
| 462 | debugfs_create_file("rf_regval", 0600, dir, dev, &fops_rf_regval); |
| 463 | + debugfs_create_file("vow", 0600, dir, phy, &mt7915_vow_ops); |
| 464 | |
developer | eb6a018 | 2022-12-12 18:53:32 +0800 | [diff] [blame] | 465 | if (!dev->dbdc_support || phy->mt76->band_idx) { |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 466 | debugfs_create_u32("dfs_hw_pattern", 0400, dir, |
| 467 | diff --git a/mt7915/init.c b/mt7915/init.c |
developer | bbd45e1 | 2023-05-19 08:22:06 +0800 | [diff] [blame] | 468 | index 8eacf34..8684d7a 100644 |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 469 | --- a/mt7915/init.c |
| 470 | +++ b/mt7915/init.c |
developer | bbd45e1 | 2023-05-19 08:22:06 +0800 | [diff] [blame] | 471 | @@ -575,10 +575,46 @@ mt7915_init_led_mux(struct mt7915_dev *dev) |
developer | eb6a018 | 2022-12-12 18:53:32 +0800 | [diff] [blame] | 472 | } |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 473 | } |
| 474 | |
| 475 | +void mt7915_vow_init(struct mt7915_dev *dev) |
| 476 | +{ |
| 477 | + struct mt7915_vow_cfg *vow_cfg = &dev->vow_cfg; |
| 478 | + bool ret; |
| 479 | + int i; |
| 480 | + |
| 481 | + if (!(is_mt7915(&dev->mt76))) |
| 482 | + vow_cfg->vow_feature |= VOW_FEATURE_BWCG; |
| 483 | + |
| 484 | + vow_cfg->vow_atf_en = 0x1; |
| 485 | + vow_cfg->sta_max_wait_time = 0x40; |
| 486 | + vow_cfg->refill_period = 0x5; |
| 487 | + |
| 488 | + vow_cfg->vow_sta_dwrr_quantum[0] = 0x06; |
| 489 | + vow_cfg->vow_sta_dwrr_quantum[1] = 0x0c; |
| 490 | + vow_cfg->vow_sta_dwrr_quantum[2] = 0x10; |
| 491 | + vow_cfg->vow_sta_dwrr_quantum[3] = 0x14; |
| 492 | + vow_cfg->vow_sta_dwrr_quantum[4] = 0x18; |
| 493 | + vow_cfg->vow_sta_dwrr_quantum[5] = 0x1c; |
| 494 | + vow_cfg->vow_sta_dwrr_quantum[6] = 0x20; |
| 495 | + vow_cfg->vow_sta_dwrr_quantum[7] = 0x24; |
| 496 | + |
| 497 | + ret = mt7915_mcu_set_vow_drr_ctrl(dev, NULL, |
| 498 | + VOW_DRR_AIRTIME_DEFICIT_BOUND); |
| 499 | + ret = mt7915_mcu_set_vow_drr_ctrl(dev, NULL, |
| 500 | + VOW_DRR_AIRTIME_QUANTUM_ALL); |
| 501 | + |
| 502 | + for(i = 0; i < 4; i++) |
| 503 | + ret = mt7915_mcu_set_vow_drr_ctrl(dev, NULL, |
| 504 | + VOW_DRR_AIRTIME_QUANTUM_L0 + i); |
| 505 | + |
| 506 | + ret = mt7915_mcu_set_vow_feature_ctrl(dev); |
| 507 | + return; |
| 508 | +} |
| 509 | + |
| 510 | void mt7915_mac_init(struct mt7915_dev *dev) |
| 511 | { |
| 512 | int i; |
| 513 | u32 rx_len = is_mt7915(&dev->mt76) ? 0x400 : 0x680; |
| 514 | + struct wiphy *wiphy = dev->phy.mt76->hw->wiphy; |
| 515 | |
| 516 | /* config pse qid6 wfdma port selection */ |
| 517 | if (!is_mt7915(&dev->mt76) && dev->hif2) |
developer | bbd45e1 | 2023-05-19 08:22:06 +0800 | [diff] [blame] | 518 | @@ -600,6 +636,9 @@ void mt7915_mac_init(struct mt7915_dev *dev) |
developer | eb6a018 | 2022-12-12 18:53:32 +0800 | [diff] [blame] | 519 | mt7915_mac_init_band(dev, i); |
| 520 | |
| 521 | mt7915_init_led_mux(dev); |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 522 | + |
developer | eb6a018 | 2022-12-12 18:53:32 +0800 | [diff] [blame] | 523 | + if (mt7915_is_atf_default_on(wiphy, dev)) |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 524 | + mt7915_vow_init(dev); |
| 525 | } |
| 526 | |
| 527 | int mt7915_txbf_init(struct mt7915_dev *dev) |
| 528 | diff --git a/mt7915/main.c b/mt7915/main.c |
developer | bbd45e1 | 2023-05-19 08:22:06 +0800 | [diff] [blame] | 529 | index 275c6a0..2ba36da 100644 |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 530 | --- a/mt7915/main.c |
| 531 | +++ b/mt7915/main.c |
developer | 2324aa2 | 2023-04-12 11:30:15 +0800 | [diff] [blame] | 532 | @@ -217,6 +217,7 @@ int mt7915_init_vif(struct mt7915_phy *phy, struct ieee80211_vif *vif, bool bf_e |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 533 | { |
| 534 | struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; |
developer | 1346ce5 | 2022-12-15 21:36:14 +0800 | [diff] [blame] | 535 | struct mt7915_dev *dev = phy->dev; |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 536 | + struct wiphy *wiphy = dev->phy.mt76->hw->wiphy; |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 537 | struct mt76_txq *mtxq; |
| 538 | bool ext_phy = phy != &dev->phy; |
developer | 1346ce5 | 2022-12-15 21:36:14 +0800 | [diff] [blame] | 539 | int idx, ret = 0; |
developer | bbd45e1 | 2023-05-19 08:22:06 +0800 | [diff] [blame] | 540 | @@ -277,6 +278,9 @@ int mt7915_init_vif(struct mt7915_phy *phy, struct ieee80211_vif *vif, bool bf_e |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 541 | mt7915_mcu_add_sta(dev, vif, NULL, true); |
| 542 | rcu_assign_pointer(dev->mt76.wcid[idx], &mvif->sta.wcid); |
| 543 | |
developer | 1346ce5 | 2022-12-15 21:36:14 +0800 | [diff] [blame] | 544 | + if (mt7915_is_atf_default_on(wiphy, dev)) |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 545 | + mt7915_mcu_set_vow_band(dev, mvif); |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 546 | + |
developer | 1346ce5 | 2022-12-15 21:36:14 +0800 | [diff] [blame] | 547 | return ret; |
| 548 | } |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 549 | |
developer | bbd45e1 | 2023-05-19 08:22:06 +0800 | [diff] [blame] | 550 | @@ -699,6 +703,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 551 | struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv; |
| 552 | struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; |
| 553 | bool ext_phy = mvif->phy != &dev->phy; |
| 554 | + struct wiphy *wiphy = dev->phy.mt76->hw->wiphy; |
| 555 | #ifdef CONFIG_MTK_VENDOR |
developer | fd8e115 | 2023-02-14 11:29:23 +0800 | [diff] [blame] | 556 | struct mt7915_phy *phy = ext_phy ? mt7915_ext_phy(dev) : &dev->phy; |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 557 | #endif |
developer | bbd45e1 | 2023-05-19 08:22:06 +0800 | [diff] [blame] | 558 | @@ -749,6 +754,16 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, |
developer | fd8e115 | 2023-02-14 11:29:23 +0800 | [diff] [blame] | 559 | if (phy->muru_onoff & MUMIMO_DL_CERT) |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 560 | mt7915_mcu_set_mimo(phy, 0); |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 561 | #endif |
developer | eb6a018 | 2022-12-12 18:53:32 +0800 | [diff] [blame] | 562 | + if (mt7915_is_atf_default_on(wiphy, dev)) { |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 563 | + msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VO] = 2; |
| 564 | + msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VI] = 2; |
| 565 | + msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BE] = 1; |
| 566 | + msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BK] = 0; |
| 567 | + mt7915_mcu_set_vow_drr_ctrl(dev, msta, VOW_DRR_STA_BSS_GROUP); |
| 568 | + mt7915_mcu_set_vow_drr_ctrl(dev, msta, VOW_DRR_STA_PAUSE_SETTING); |
| 569 | + mt7915_mcu_set_vow_drr_ctrl(dev, msta, VOW_DRR_STA_ALL); |
| 570 | + } |
| 571 | + |
| 572 | return 0; |
| 573 | } |
| 574 | |
| 575 | diff --git a/mt7915/mcu.c b/mt7915/mcu.c |
developer | bbd45e1 | 2023-05-19 08:22:06 +0800 | [diff] [blame] | 576 | index e9bc4b1..3b0ba5c 100644 |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 577 | --- a/mt7915/mcu.c |
| 578 | +++ b/mt7915/mcu.c |
developer | bbd45e1 | 2023-05-19 08:22:06 +0800 | [diff] [blame] | 579 | @@ -3507,6 +3507,171 @@ int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band) |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 580 | &req, sizeof(req), false); |
| 581 | } |
| 582 | |
| 583 | +int mt7915_mcu_set_vow_drr_ctrl(struct mt7915_dev *dev, |
| 584 | + struct mt7915_sta *msta, |
| 585 | + u32 subcmd) |
| 586 | +{ |
| 587 | + u32 setting = 0; |
| 588 | + u32 i; |
| 589 | + |
| 590 | + struct { |
| 591 | + __le32 action; |
| 592 | + u8 wlan_idx_lo; |
| 593 | + u8 status; |
| 594 | + u8 wlan_idx_hi; |
| 595 | + u8 rsv0[5]; |
| 596 | + union { |
| 597 | + __le32 com_value; |
| 598 | + struct { |
| 599 | + u8 air_time_quantum[VOW_MAX_STA_DWRR_NUM]; |
| 600 | + }air_time_quantum_all; |
| 601 | + }air_time_ctrl; |
| 602 | + } __packed req = { |
| 603 | + .action = cpu_to_le32(subcmd), |
| 604 | + .wlan_idx_lo = msta ? to_wcid_lo(msta->wcid.idx) : to_wcid_lo(0x0), |
| 605 | + .wlan_idx_hi = msta ? to_wcid_hi(msta->wcid.idx) : to_wcid_hi(0x0), |
| 606 | + }; |
| 607 | + |
| 608 | + switch (subcmd) { |
| 609 | + case VOW_DRR_STA_ALL:{ |
| 610 | + setting |= 0x00; |
| 611 | + setting |= msta->vif->mt76.idx; |
| 612 | + setting |= msta->vow_sta_cfg.ac_change_rule << 4; |
| 613 | + setting |= (msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VO] << 8); |
| 614 | + setting |= (msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VI] << 12); |
| 615 | + setting |= (msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BE] << 16); |
| 616 | + setting |= (msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BK] << 20); |
| 617 | + if (dev->vow_cfg.vow_feature & VOW_FEATURE_BWCG) |
| 618 | + setting |= ((UMAC_BWC_GROUP_MIN) << 24); |
| 619 | + req.air_time_ctrl.com_value = cpu_to_le32(setting); |
| 620 | + break; |
| 621 | + } |
| 622 | + |
| 623 | + case VOW_DRR_STA_BSS_GROUP: |
| 624 | + req.air_time_ctrl.com_value = cpu_to_le32(0x0); |
| 625 | + break; |
| 626 | + |
| 627 | + case VOW_DRR_STA_PAUSE_SETTING: |
| 628 | + req.air_time_ctrl.com_value = cpu_to_le32(msta->vow_sta_cfg.paused); |
| 629 | + break; |
| 630 | + |
| 631 | + case VOW_DRR_STA_AC0_QUA_ID: |
| 632 | + req.air_time_ctrl.com_value = |
| 633 | + cpu_to_le32(msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VO]); |
| 634 | + break; |
| 635 | + |
| 636 | + case VOW_DRR_STA_AC1_QUA_ID: |
| 637 | + req.air_time_ctrl.com_value = |
| 638 | + cpu_to_le32(msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_VI]); |
| 639 | + break; |
| 640 | + |
| 641 | + case VOW_DRR_STA_AC2_QUA_ID: |
| 642 | + req.air_time_ctrl.com_value = |
| 643 | + cpu_to_le32(msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BE]); |
| 644 | + break; |
| 645 | + |
| 646 | + case VOW_DRR_STA_AC3_QUA_ID: |
| 647 | + req.air_time_ctrl.com_value = |
| 648 | + cpu_to_le32(msta->vow_sta_cfg.dwrr_quantum[IEEE80211_AC_BK]); |
| 649 | + break; |
| 650 | + |
| 651 | + case VOW_DRR_AIRTIME_DEFICIT_BOUND: |
| 652 | + req.air_time_ctrl.com_value = |
| 653 | + cpu_to_le32(dev->vow_cfg.sta_max_wait_time); |
| 654 | + break; |
| 655 | + |
| 656 | + case VOW_DRR_AIRTIME_QUANTUM_L0: |
| 657 | + case VOW_DRR_AIRTIME_QUANTUM_L1: |
| 658 | + case VOW_DRR_AIRTIME_QUANTUM_L2: |
| 659 | + case VOW_DRR_AIRTIME_QUANTUM_L3: |
| 660 | + case VOW_DRR_AIRTIME_QUANTUM_L4: |
| 661 | + case VOW_DRR_AIRTIME_QUANTUM_L5: |
| 662 | + case VOW_DRR_AIRTIME_QUANTUM_L6: |
| 663 | + case VOW_DRR_AIRTIME_QUANTUM_L7: |
| 664 | + req.air_time_ctrl.com_value = |
| 665 | + cpu_to_le32(dev->vow_cfg.vow_sta_dwrr_quantum[subcmd - |
| 666 | + VOW_DRR_AIRTIME_QUANTUM_L0]); |
| 667 | + break; |
| 668 | + |
| 669 | + case VOW_DRR_AIRTIME_QUANTUM_ALL: { |
| 670 | + for (i = 0; i < VOW_MAX_STA_DWRR_NUM; i++) { |
| 671 | + req.air_time_ctrl.air_time_quantum_all.air_time_quantum[i] = |
| 672 | + dev->vow_cfg.vow_sta_dwrr_quantum[i]; |
| 673 | + } |
| 674 | + break; |
| 675 | + } |
| 676 | + |
| 677 | + default: |
| 678 | + break; |
| 679 | + } |
| 680 | + |
| 681 | + return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SET_DRR_CTRL), |
| 682 | + &req, sizeof(req), false); |
| 683 | +} |
| 684 | + |
| 685 | +int mt7915_mcu_set_vow_feature_ctrl(struct mt7915_dev *dev) |
| 686 | +{ |
| 687 | + u16 value = 0; |
| 688 | + u32 sch_value = 0; |
| 689 | + |
| 690 | + struct vow_feature_ctrl { |
| 691 | + __le16 bss_flag; |
| 692 | + __le16 vow_ctrl_flag; |
| 693 | + __le16 bss_value[9]; |
| 694 | + __le16 vow_ctrl_val; |
| 695 | + __le16 time_token_value[2]; |
| 696 | + __le16 length_token_value[2]; |
| 697 | + __le32 tx_ctrl; |
| 698 | + __le32 sch_ctrl; |
| 699 | + } __packed req = { |
| 700 | + .bss_flag = cpu_to_le16(0xffff), |
| 701 | + .vow_ctrl_flag = cpu_to_le16(0xf231), |
| 702 | + .bss_value[0] = cpu_to_le16(0xffff), |
| 703 | + .bss_value[2] = cpu_to_le16(0xffff), |
| 704 | + .bss_value[8] = cpu_to_le16(0xffff), |
| 705 | + .time_token_value[0] = cpu_to_le16(0xffff), |
| 706 | + }; |
| 707 | + |
| 708 | + value |= dev->vow_cfg.refill_period; |
| 709 | + value |= 1 << 4; |
| 710 | + value |= 1 << 5; |
| 711 | + value |= dev->vow_cfg.vow_watf_en << 9; |
| 712 | + value |= 1 << 12; |
| 713 | + value |= dev->vow_cfg.vow_atf_en << 13; |
| 714 | + value |= 1 << 14; |
| 715 | + req.vow_ctrl_val = value; |
| 716 | + if (dev->vow_cfg.vow_atf_en) |
| 717 | + req.tx_ctrl = cpu_to_le32(0x6bf69e1f); |
| 718 | + sch_value |= 1 << 6; |
| 719 | + sch_value |= (((dev->vow_cfg.vow_show_en == 0) ? 0 : |
| 720 | + (dev->vow_cfg.vow_show_en - 1 )) << 4); |
| 721 | + req.sch_ctrl = sch_value; |
| 722 | + |
| 723 | + return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SET_FEATURE_CTRL), |
| 724 | + &req, sizeof(req), false); |
| 725 | +} |
| 726 | + |
| 727 | +int mt7915_mcu_set_vow_band(struct mt7915_dev *dev, struct mt7915_vif *mvif) |
| 728 | +{ |
| 729 | + struct module_ctrl { |
| 730 | + __le16 action; |
| 731 | + __le16 sub_action; |
| 732 | + __le32 rsv1[5]; |
| 733 | + u8 rsv2[72]; |
| 734 | + u8 group_idx; |
| 735 | + u8 band_idx; |
| 736 | + u8 rsv3[2]; |
| 737 | + } __packed req = { |
| 738 | + .action = cpu_to_le16(0x1), |
| 739 | + .sub_action = cpu_to_le16(0x4), |
| 740 | + .group_idx = mvif->mt76.band_idx * 4 + mvif->mt76.omac_idx % 4, |
| 741 | + .band_idx = mvif->mt76.band_idx, |
| 742 | + }; |
| 743 | + |
| 744 | + return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(AT_PROC_MODULE), |
| 745 | + &req, sizeof(req), false); |
| 746 | +} |
| 747 | + |
| 748 | int mt7915_mcu_set_txbf(struct mt7915_dev *dev, u8 action) |
| 749 | { |
developer | 1346ce5 | 2022-12-15 21:36:14 +0800 | [diff] [blame] | 750 | #define MT_BF_PROCESSING 4 |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 751 | diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h |
developer | bbd45e1 | 2023-05-19 08:22:06 +0800 | [diff] [blame] | 752 | index d0ae42f..fddca24 100644 |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 753 | --- a/mt7915/mt7915.h |
| 754 | +++ b/mt7915/mt7915.h |
developer | bbd45e1 | 2023-05-19 08:22:06 +0800 | [diff] [blame] | 755 | @@ -134,6 +134,58 @@ struct mt7915_twt_flow { |
developer | 356ecec | 2022-11-14 10:25:04 +0800 | [diff] [blame] | 756 | |
| 757 | DECLARE_EWMA(avg_signal, 10, 8) |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 758 | |
| 759 | +#define VOW_MAX_STA_DWRR_NUM 8 |
| 760 | +#define VOW_WATF_LEVEL_NUM 4 |
| 761 | +#define VOW_FEATURE_BWCG BIT(3) |
| 762 | +#define UMAC_BWC_GROUP_MIN 40 |
| 763 | + |
| 764 | + |
| 765 | +enum ext_cmd_vow_drr_ctrl { |
| 766 | + /* Type 1 */ |
| 767 | + VOW_DRR_STA_ALL = 0x00, |
| 768 | + VOW_DRR_STA_BSS_GROUP = 0x01, |
| 769 | + VOW_DRR_STA_AC0_QUA_ID = 0x03, |
| 770 | + VOW_DRR_STA_AC1_QUA_ID = 0x04, |
| 771 | + VOW_DRR_STA_AC2_QUA_ID = 0x05, |
| 772 | + VOW_DRR_STA_AC3_QUA_ID = 0x06, |
| 773 | + |
| 774 | + /* Type 2 */ |
| 775 | + VOW_DRR_AIRTIME_DEFICIT_BOUND = 0x10, |
| 776 | + |
| 777 | + /* Type 3 */ |
| 778 | + VOW_DRR_AIRTIME_QUANTUM_L0 = 0x20, |
| 779 | + VOW_DRR_AIRTIME_QUANTUM_L1 = 0x21, |
| 780 | + VOW_DRR_AIRTIME_QUANTUM_L2 = 0x22, |
| 781 | + VOW_DRR_AIRTIME_QUANTUM_L3 = 0x23, |
| 782 | + VOW_DRR_AIRTIME_QUANTUM_L4 = 0x24, |
| 783 | + VOW_DRR_AIRTIME_QUANTUM_L5 = 0x25, |
| 784 | + VOW_DRR_AIRTIME_QUANTUM_L6 = 0x26, |
| 785 | + VOW_DRR_AIRTIME_QUANTUM_L7 = 0x27, |
| 786 | + VOW_DRR_AIRTIME_QUANTUM_ALL = 0x28, |
| 787 | + VOW_DRR_STA_PAUSE_SETTING = 0x30, |
| 788 | +}; |
| 789 | + |
| 790 | +struct mt7915_vow_sta_cfg{ |
| 791 | + u8 dwrr_quantum[IEEE80211_NUM_ACS]; |
| 792 | + u8 ac_change_rule; |
| 793 | + bool paused; |
| 794 | +}; |
| 795 | + |
| 796 | +struct mt7915_vow_cfg{ |
| 797 | + /*ATF setting */ |
| 798 | + u32 vow_feature; |
| 799 | + bool vow_atf_en; |
| 800 | + u8 refill_period; |
| 801 | + u8 sta_max_wait_time; |
| 802 | + u8 vow_sta_dwrr_quantum[VOW_MAX_STA_DWRR_NUM]; |
| 803 | + u8 vow_show_en; |
| 804 | + u32 vow_show_sta; |
| 805 | + |
| 806 | + /*WATF setting */ |
| 807 | + bool vow_watf_en; |
| 808 | +}; |
| 809 | + |
| 810 | + |
| 811 | struct mt7915_sta { |
| 812 | struct mt76_wcid wcid; /* must be first */ |
| 813 | |
developer | bbd45e1 | 2023-05-19 08:22:06 +0800 | [diff] [blame] | 814 | @@ -156,6 +208,7 @@ struct mt7915_sta { |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 815 | u8 flowid_mask; |
| 816 | struct mt7915_twt_flow flow[MT7915_MAX_STA_TWT_AGRT]; |
| 817 | } twt; |
| 818 | + struct mt7915_vow_sta_cfg vow_sta_cfg; |
| 819 | }; |
| 820 | |
developer | bbd45e1 | 2023-05-19 08:22:06 +0800 | [diff] [blame] | 821 | struct mt7915_vif { |
| 822 | @@ -459,6 +512,8 @@ struct mt7915_dev { |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 823 | } dbg; |
| 824 | const struct mt7915_dbg_reg_desc *dbg_reg; |
| 825 | #endif |
| 826 | + struct delayed_work vow_work; |
| 827 | + struct mt7915_vow_cfg vow_cfg; |
| 828 | }; |
| 829 | |
| 830 | enum { |
developer | bbd45e1 | 2023-05-19 08:22:06 +0800 | [diff] [blame] | 831 | @@ -491,6 +546,15 @@ enum mt7915_rdd_cmd { |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 832 | RDD_IRQ_OFF, |
| 833 | }; |
| 834 | |
| 835 | +static inline bool |
developer | eb6a018 | 2022-12-12 18:53:32 +0800 | [diff] [blame] | 836 | +mt7915_is_atf_default_on(struct wiphy *wiphy, struct mt7915_dev *dev) |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 837 | +{ |
| 838 | + return ((!wiphy_ext_feature_isset(wiphy, |
| 839 | + NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) || |
| 840 | + mtk_wed_device_active(&dev->mt76.mmio.wed)); |
| 841 | +} |
| 842 | + |
| 843 | + |
| 844 | static inline struct mt7915_phy * |
| 845 | mt7915_hw_phy(struct ieee80211_hw *hw) |
| 846 | { |
developer | bbd45e1 | 2023-05-19 08:22:06 +0800 | [diff] [blame] | 847 | @@ -620,6 +684,10 @@ int mt7915_mcu_set_mac(struct mt7915_dev *dev, int band, bool enable, |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 848 | int mt7915_mcu_set_test_param(struct mt7915_dev *dev, u8 param, bool test_mode, |
| 849 | u8 en); |
| 850 | int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band); |
| 851 | +int mt7915_mcu_set_vow_drr_ctrl(struct mt7915_dev *dev, struct mt7915_sta *msta, |
| 852 | + u32 subcmd); |
| 853 | +int mt7915_mcu_set_vow_feature_ctrl(struct mt7915_dev *dev); |
| 854 | +int mt7915_mcu_set_vow_band(struct mt7915_dev *dev, struct mt7915_vif *mvif); |
| 855 | int mt7915_mcu_set_sku_en(struct mt7915_phy *phy, bool enable); |
| 856 | int mt7915_mcu_set_txpower_sku(struct mt7915_phy *phy); |
developer | fe7be7f | 2022-12-13 21:40:24 +0800 | [diff] [blame] | 857 | int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len, |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 858 | diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c |
developer | bbd45e1 | 2023-05-19 08:22:06 +0800 | [diff] [blame] | 859 | index 4629f6b..361b50c 100644 |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 860 | --- a/mt7915/mtk_debugfs.c |
| 861 | +++ b/mt7915/mtk_debugfs.c |
developer | d75d363 | 2023-01-05 14:31:01 +0800 | [diff] [blame] | 862 | @@ -1368,7 +1368,6 @@ static EMPTY_QUEUE_INFO_T ple_txcmd_queue_empty_info[] = { |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 863 | }; |
| 864 | |
| 865 | |
| 866 | - |
| 867 | static char* sta_ctrl_reg[] = {"ENABLE", "DISABLE", "PAUSE"}; |
| 868 | static u32 chip_show_sta_acq_info(struct seq_file *s, struct mt7915_dev *dev, u32 *ple_stat, |
| 869 | u32 *sta_pause, u32 *dis_sta_map, |
developer | d75d363 | 2023-01-05 14:31:01 +0800 | [diff] [blame] | 870 | @@ -1522,6 +1521,138 @@ static void chip_get_sta_pause(struct mt7915_dev *dev, u32 *sta_pause) |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 871 | } |
| 872 | } |
| 873 | |
| 874 | +u32 vow_chip_show_sta_acq_info(struct mt7915_dev *dev, u32 *ple_stat, |
| 875 | + u32 *sta_pause, u32 *dis_sta_map, |
| 876 | + u32 dumptxd) |
| 877 | +{ |
| 878 | + int i, j; |
| 879 | + u32 total_nonempty_cnt = 0; |
| 880 | + u32 ac_num = 9, all_ac_num; |
| 881 | + static char* sta_ctrl_reg[] = {"ENABLE", "DISABLE", "PAUSE"}; |
| 882 | + if (!is_mt7915(&dev->mt76)) |
| 883 | + ac_num = 17; |
| 884 | + |
| 885 | + all_ac_num = ac_num * 4; |
| 886 | + |
| 887 | + for (j = 0; j < all_ac_num; j++) { /* show AC Q info */ |
| 888 | + for (i = 0; i < 32; i++) { |
| 889 | + if (((ple_stat[j + 1] & (0x1 << i)) >> i) == 0) { |
| 890 | + u32 hfid, tfid, pktcnt, ac_n = j / ac_num, ctrl = 0; |
| 891 | + u32 sta_num = i + (j % ac_num) * 32, fl_que_ctrl[3] = {0}; |
| 892 | + u32 wmmidx = 0; |
| 893 | + struct mt7915_sta *msta; |
| 894 | + struct mt76_wcid *wcid; |
| 895 | + struct ieee80211_sta *sta = NULL; |
| 896 | + |
| 897 | + wcid = rcu_dereference(dev->mt76.wcid[sta_num]); |
| 898 | + sta = wcid_to_sta(wcid); |
| 899 | + if (!sta) { |
| 900 | + printk("ERROR!! no found STA wcid=%d\n", sta_num); |
| 901 | + continue; |
| 902 | + } |
| 903 | + msta = container_of(wcid, struct mt7915_sta, wcid); |
| 904 | + wmmidx = msta->vif->mt76.wmm_idx; |
| 905 | + |
| 906 | + dev_info(dev->mt76.dev, "\tSTA%d AC%d: ", sta_num, ac_n); |
| 907 | + |
| 908 | + fl_que_ctrl[0] |= MT_DBG_PLE_FL_QUE_CTRL0_EXECUTE_MASK; |
| 909 | + fl_que_ctrl[0] |= (ENUM_UMAC_LMAC_PORT_2 << |
| 910 | + MT_PLE_FL_QUE_CTRL0_Q_BUF_PID_SHFT); |
| 911 | + fl_que_ctrl[0] |= (ac_n << MT_PLE_FL_QUE_CTRL0_Q_BUF_QID_SHFT); |
| 912 | + fl_que_ctrl[0] |= sta_num; |
| 913 | + mt76_wr(dev, MT_DBG_PLE_FL_QUE_CTRL0, fl_que_ctrl[0]); |
| 914 | + fl_que_ctrl[1] = mt76_rr(dev, MT_DBG_PLE_FL_QUE_CTRL2); |
| 915 | + fl_que_ctrl[2] = mt76_rr(dev, MT_DBG_PLE_FL_QUE_CTRL3); |
| 916 | + hfid = FIELD_GET(MT_DBG_PLE_FL_QUE_CTRL2_Q_HEAD_FID_MASK, |
| 917 | + fl_que_ctrl[1]); |
| 918 | + tfid = FIELD_GET(MT_DBG_PLE_FL_QUE_CTRL2_Q_TAIL_FID_MASK, |
| 919 | + fl_que_ctrl[1]); |
| 920 | + pktcnt = FIELD_GET(MT_DBG_PLE_FL_QUE_CTRL3_Q_PKT_NUM_MASK, |
| 921 | + fl_que_ctrl[2]); |
| 922 | + dev_info(dev->mt76.dev, "tail/head fid = 0x%03x/0x%03x, pkt cnt = 0x%03x", |
| 923 | + tfid, hfid, pktcnt); |
| 924 | + |
| 925 | + if (((sta_pause[j % 6] & 0x1 << i) >> i) == 1) |
| 926 | + ctrl = 2; |
| 927 | + |
| 928 | + if (((dis_sta_map[j % 6] & 0x1 << i) >> i) == 1) |
| 929 | + ctrl = 1; |
| 930 | + |
| 931 | + dev_info(dev->mt76.dev, " ctrl = %s", sta_ctrl_reg[ctrl]); |
| 932 | + dev_info(dev->mt76.dev, " (wmmidx=%d)\n", wmmidx); |
| 933 | + |
| 934 | + total_nonempty_cnt++; |
| 935 | + } |
| 936 | + } |
| 937 | + } |
| 938 | + |
| 939 | + return total_nonempty_cnt; |
| 940 | +} |
| 941 | + |
| 942 | +int mt7915_vow_pleinfo_read(struct mt7915_dev *dev) |
| 943 | +{ |
| 944 | + u32 ple_stat[70] = {0}, pg_flow_ctrl[8] = {0}; |
| 945 | + u32 ple_txcmd_stat; |
| 946 | + u32 sta_pause[CR_NUM_OF_AC] = {0}, dis_sta_map[CR_NUM_OF_AC] = {0}; |
| 947 | + int i; |
| 948 | + |
| 949 | + chip_get_ple_acq_stat(dev, ple_stat); |
| 950 | + ple_txcmd_stat = mt76_rr(dev, MT_DBG_PLE_TXCMD_Q_EMPTY); |
| 951 | + pg_flow_ctrl[0] = mt76_rr(dev, MT_DBG_PLE_FREEPG_CNT); |
| 952 | + pg_flow_ctrl[1] = mt76_rr(dev, MT_DBG_PLE_FREEPG_HEAD_TAIL); |
| 953 | + pg_flow_ctrl[2] = mt76_rr(dev, MT_DBG_PLE_PG_HIF_GROUP); |
| 954 | + pg_flow_ctrl[3] = mt76_rr(dev, MT_DBG_PLE_HIF_PG_INFO); |
| 955 | + pg_flow_ctrl[4] = mt76_rr(dev, MT_DBG_PLE_PG_CPU_GROUP); |
| 956 | + pg_flow_ctrl[5] = mt76_rr(dev, MT_DBG_PLE_CPU_PG_INFO); |
| 957 | + pg_flow_ctrl[6] = mt76_rr(dev, MT_DBG_PLE_PG_HIF_TXCMD_GROUP); |
| 958 | + pg_flow_ctrl[7] = mt76_rr(dev, MT_DBG_PLE_HIF_TXCMD_PG_INFO); |
| 959 | + chip_get_dis_sta_map(dev, dis_sta_map); |
| 960 | + chip_get_sta_pause(dev, sta_pause); |
| 961 | + |
| 962 | + dev_info(dev->mt76.dev, "PLE Configuration Info:\n"); |
| 963 | + |
| 964 | + for (i = 0; i < 32; i++) { |
| 965 | + if (((ple_stat[0] & (0x1 << i)) >> i) == 0) { |
| 966 | + u32 hfid, tfid, pktcnt, fl_que_ctrl[3] = {0}; |
| 967 | + |
| 968 | + if (ple_queue_empty_info[i].QueueName != NULL) { |
| 969 | + fl_que_ctrl[0] |= MT_DBG_PLE_FL_QUE_CTRL0_EXECUTE_MASK; |
| 970 | + fl_que_ctrl[0] |= (ple_queue_empty_info[i].Portid << |
| 971 | + MT_PLE_FL_QUE_CTRL0_Q_BUF_PID_SHFT); |
| 972 | + fl_que_ctrl[0] |= (ple_queue_empty_info[i].Queueid << |
| 973 | + MT_PLE_FL_QUE_CTRL0_Q_BUF_QID_SHFT); |
| 974 | + } else |
| 975 | + continue; |
| 976 | + |
| 977 | + if (ple_queue_empty_info[i].Queueid >= |
| 978 | + ENUM_UMAC_LMAC_PLE_TX_Q_ALTX_0 && |
| 979 | + ple_queue_empty_info[i].Queueid <= |
| 980 | + ENUM_UMAC_LMAC_PLE_TX_Q_PSMP_0) |
| 981 | + /* band0 set TGID 0, bit31 = 0 */ |
| 982 | + mt76_wr(dev, MT_DBG_PLE_FL_QUE_CTRL1, 0x0); |
| 983 | + else if (ple_queue_empty_info[i].Queueid >= |
| 984 | + ENUM_UMAC_LMAC_PLE_TX_Q_ALTX_1 && |
| 985 | + ple_queue_empty_info[i].Queueid <= |
| 986 | + ENUM_UMAC_LMAC_PLE_TX_Q_PSMP_1) |
| 987 | + /* band1 set TGID 1, bit31 = 1 */ |
| 988 | + mt76_wr(dev, MT_DBG_PLE_FL_QUE_CTRL1, 0x80000000); |
| 989 | + |
| 990 | + mt76_wr(dev, MT_DBG_PLE_FL_QUE_CTRL0, fl_que_ctrl[0]); |
| 991 | + fl_que_ctrl[1] = mt76_rr(dev, MT_DBG_PLE_FL_QUE_CTRL2); |
| 992 | + fl_que_ctrl[2] = mt76_rr(dev, MT_DBG_PLE_FL_QUE_CTRL3); |
| 993 | + hfid = FIELD_GET(MT_DBG_PLE_FL_QUE_CTRL2_Q_HEAD_FID_MASK, |
| 994 | + fl_que_ctrl[1]); |
| 995 | + tfid = FIELD_GET(MT_DBG_PLE_FL_QUE_CTRL2_Q_TAIL_FID_MASK, |
| 996 | + fl_que_ctrl[1]); |
| 997 | + pktcnt = FIELD_GET(MT_DBG_PLE_FL_QUE_CTRL3_Q_PKT_NUM_MASK, |
| 998 | + fl_que_ctrl[2]); |
| 999 | + } |
| 1000 | + } |
| 1001 | + |
| 1002 | + vow_chip_show_sta_acq_info(dev, ple_stat, sta_pause, dis_sta_map, 0); |
| 1003 | + |
| 1004 | + return 0; |
| 1005 | +} |
| 1006 | static int mt7915_pleinfo_read(struct seq_file *s, void *data) |
| 1007 | { |
| 1008 | struct mt7915_dev *dev = dev_get_drvdata(s->private); |
| 1009 | -- |
developer | 2324aa2 | 2023-04-12 11:30:15 +0800 | [diff] [blame] | 1010 | 2.18.0 |
developer | c978ea1 | 2022-11-09 15:58:31 +0800 | [diff] [blame] | 1011 | |