1 // SPDX-License-Identifier: ISC 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 4 #include "mt7915.h" 5 #include "mac.h" 6 #include "mcu.h" 7 #include "testmode.h" 8 9 enum { 10 TM_CHANGED_TXPOWER, 11 TM_CHANGED_FREQ_OFFSET, 12 13 /* must be last */ 14 NUM_TM_CHANGED 15 }; 16 17 static const u8 tm_change_map[] = { 18 [TM_CHANGED_TXPOWER] = MT76_TM_ATTR_TX_POWER, 19 [TM_CHANGED_FREQ_OFFSET] = MT76_TM_ATTR_FREQ_OFFSET, 20 }; 21 22 struct reg_band { 23 u32 band[2]; 24 }; 25 26 #define REG_BAND(_list, _reg) \ 27 { _list.band[0] = MT_##_reg(0); \ 28 _list.band[1] = MT_##_reg(1); } 29 #define REG_BAND_IDX(_list, _reg, _idx) \ 30 { _list.band[0] = MT_##_reg(0, _idx); \ 31 _list.band[1] = MT_##_reg(1, _idx); } 32 33 #define TM_REG_MAX_ID 17 34 static struct reg_band reg_backup_list[TM_REG_MAX_ID]; 35 36 37 static int 38 mt7915_tm_set_tx_power(struct mt7915_phy *phy) 39 { 40 struct mt7915_dev *dev = phy->dev; 41 struct mt76_phy *mphy = phy->mt76; 42 struct cfg80211_chan_def *chandef = &mphy->chandef; 43 int freq = chandef->center_freq1; 44 int ret; 45 struct { 46 u8 format_id; 47 u8 dbdc_idx; 48 s8 tx_power; 49 u8 ant_idx; /* Only 0 is valid */ 50 u8 center_chan; 51 u8 rsv[3]; 52 } __packed req = { 53 .format_id = 0xf, 54 .dbdc_idx = phy != &dev->phy, 55 .center_chan = ieee80211_frequency_to_channel(freq), 56 }; 57 u8 *tx_power = NULL; 58 59 if (phy->mt76->test.state != MT76_TM_STATE_OFF) 60 tx_power = phy->mt76->test.tx_power; 61 62 /* Tx power of the other antennas are the same as antenna 0 */ 63 if (tx_power && tx_power[0]) 64 req.tx_power = tx_power[0]; 65 66 ret = mt76_mcu_send_msg(&dev->mt76, 67 MCU_EXT_CMD(TX_POWER_FEATURE_CTRL), 68 &req, sizeof(req), false); 69 70 return ret; 71 } 72 73 static int 74 mt7915_tm_set_freq_offset(struct mt7915_phy *phy, bool en, u32 val) 75 { 76 struct mt7915_dev *dev = phy->dev; 77 struct mt7915_tm_cmd req = { 78 .testmode_en = en, 79 .param_idx = MCU_ATE_SET_FREQ_OFFSET, 80 .param.freq.band = phy != &dev->phy, 81 .param.freq.freq_offset = cpu_to_le32(val), 82 }; 83 84 return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(ATE_CTRL), &req, 85 sizeof(req), false); 86 } 87 88 static int 89 mt7915_tm_mode_ctrl(struct mt7915_dev *dev, bool enable) 90 { 91 struct { 92 u8 format_id; 93 bool enable; 94 u8 rsv[2]; 95 } __packed req = { 96 .format_id = 0x6, 97 .enable = enable, 98 }; 99 100 return mt76_mcu_send_msg(&dev->mt76, 101 MCU_EXT_CMD(TX_POWER_FEATURE_CTRL), 102 &req, sizeof(req), false); 103 } 104 105 static int 106 mt7915_tm_set_trx(struct mt7915_phy *phy, int type, bool en) 107 { 108 struct mt7915_dev *dev = phy->dev; 109 struct mt7915_tm_cmd req = { 110 .testmode_en = 1, 111 .param_idx = MCU_ATE_SET_TRX, 112 .param.trx.type = type, 113 .param.trx.enable = en, 114 .param.trx.band = phy != &dev->phy, 115 }; 116 117 return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(ATE_CTRL), &req, 118 sizeof(req), false); 119 } 120 121 static int 122 mt7915_tm_clean_hwq(struct mt7915_phy *phy, u8 wcid) 123 { 124 struct mt7915_dev *dev = phy->dev; 125 struct mt7915_tm_cmd req = { 126 .testmode_en = 1, 127 .param_idx = MCU_ATE_CLEAN_TXQUEUE, 128 .param.clean.wcid = wcid, 129 .param.clean.band = phy != &dev->phy, 130 }; 131 132 return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(ATE_CTRL), &req, 133 sizeof(req), false); 134 } 135 136 static int 137 mt7915_tm_set_slot_time(struct mt7915_phy *phy, u8 slot_time, u8 sifs) 138 { 139 struct mt7915_dev *dev = phy->dev; 140 struct mt7915_tm_cmd req = { 141 .testmode_en = !(phy->mt76->test.state == MT76_TM_STATE_OFF), 142 .param_idx = MCU_ATE_SET_SLOT_TIME, 143 .param.slot.slot_time = slot_time, 144 .param.slot.sifs = sifs, 145 .param.slot.rifs = 2, 146 .param.slot.eifs = cpu_to_le16(60), 147 .param.slot.band = phy != &dev->phy, 148 }; 149 150 return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(ATE_CTRL), &req, 151 sizeof(req), false); 152 } 153 154 static int 155 mt7915_tm_set_tam_arb(struct mt7915_phy *phy, bool enable, bool mu) 156 { 157 struct mt7915_dev *dev = phy->dev; 158 u32 op_mode; 159 160 if (!enable) 161 op_mode = TAM_ARB_OP_MODE_NORMAL; 162 else if (mu) 163 op_mode = TAM_ARB_OP_MODE_TEST; 164 else 165 op_mode = TAM_ARB_OP_MODE_FORCE_SU; 166 167 return mt7915_mcu_set_muru_ctrl(dev, MURU_SET_ARB_OP_MODE, op_mode); 168 } 169 170 static int 171 mt7915_tm_set_wmm_qid(struct mt7915_phy *phy, u8 qid, u8 aifs, u8 cw_min, 172 u16 cw_max, u16 txop) 173 { 174 struct mt7915_vif *mvif = (struct mt7915_vif *)phy->monitor_vif->drv_priv; 175 struct mt7915_mcu_tx req = { .total = 1 }; 176 struct edca *e = &req.edca[0]; 177 178 e->queue = qid + mvif->mt76.wmm_idx * MT76_CONNAC_MAX_WMM_SETS; 179 e->set = WMM_PARAM_SET; 180 181 e->aifs = aifs; 182 e->cw_min = cw_min; 183 e->cw_max = cpu_to_le16(cw_max); 184 e->txop = cpu_to_le16(txop); 185 186 return mt7915_mcu_update_edca(phy->dev, &req); 187 } 188 189 static int 190 mt7915_tm_set_ipg_params(struct mt7915_phy *phy, u32 ipg, u8 mode) 191 { 192 #define TM_DEFAULT_SIFS 10 193 #define TM_MAX_SIFS 127 194 #define TM_MAX_AIFSN 0xf 195 #define TM_MIN_AIFSN 0x1 196 #define BBP_PROC_TIME 1500 197 struct mt7915_dev *dev = phy->dev; 198 u8 sig_ext = (mode == MT76_TM_TX_MODE_CCK) ? 0 : 6; 199 u8 slot_time = 9, sifs = TM_DEFAULT_SIFS; 200 u8 aifsn = TM_MIN_AIFSN; 201 u32 i2t_time, tr2t_time, txv_time; 202 u16 cw = 0; 203 204 if (ipg < sig_ext + slot_time + sifs) 205 ipg = 0; 206 207 if (!ipg) 208 goto done; 209 210 ipg -= sig_ext; 211 212 if (ipg <= (TM_MAX_SIFS + slot_time)) { 213 sifs = ipg - slot_time; 214 } else { 215 u32 val = (ipg + slot_time) / slot_time; 216 217 while (val >>= 1) 218 cw++; 219 220 if (cw > 16) 221 cw = 16; 222 223 ipg -= ((1 << cw) - 1) * slot_time; 224 225 aifsn = ipg / slot_time; 226 if (aifsn > TM_MAX_AIFSN) 227 aifsn = TM_MAX_AIFSN; 228 229 ipg -= aifsn * slot_time; 230 231 if (ipg > TM_DEFAULT_SIFS) 232 sifs = min_t(u32, ipg, TM_MAX_SIFS); 233 } 234 done: 235 txv_time = mt76_get_field(dev, MT_TMAC_ATCR(phy->band_idx), 236 MT_TMAC_ATCR_TXV_TOUT); 237 txv_time *= 50; /* normal clock time */ 238 239 i2t_time = (slot_time * 1000 - txv_time - BBP_PROC_TIME) / 50; 240 tr2t_time = (sifs * 1000 - txv_time - BBP_PROC_TIME) / 50; 241 242 mt76_set(dev, MT_TMAC_TRCR0(phy->band_idx), 243 FIELD_PREP(MT_TMAC_TRCR0_TR2T_CHK, tr2t_time) | 244 FIELD_PREP(MT_TMAC_TRCR0_I2T_CHK, i2t_time)); 245 246 mt7915_tm_set_slot_time(phy, slot_time, sifs); 247 248 return mt7915_tm_set_wmm_qid(phy, 249 mt76_connac_lmac_mapping(IEEE80211_AC_BE), 250 aifsn, cw, cw, 0); 251 } 252 253 static int 254 mt7915_tm_set_tx_len(struct mt7915_phy *phy, u32 tx_time) 255 { 256 struct mt76_phy *mphy = phy->mt76; 257 struct mt76_testmode_data *td = &mphy->test; 258 struct ieee80211_supported_band *sband; 259 struct rate_info rate = {}; 260 u16 flags = 0, tx_len; 261 u32 bitrate; 262 int ret; 263 264 if (!tx_time) 265 return 0; 266 267 rate.mcs = td->tx_rate_idx; 268 rate.nss = td->tx_rate_nss; 269 270 switch (td->tx_rate_mode) { 271 case MT76_TM_TX_MODE_CCK: 272 case MT76_TM_TX_MODE_OFDM: 273 if (mphy->chandef.chan->band == NL80211_BAND_5GHZ) 274 sband = &mphy->sband_5g.sband; 275 else if (mphy->chandef.chan->band == NL80211_BAND_6GHZ) 276 sband = &mphy->sband_6g.sband; 277 else 278 sband = &mphy->sband_2g.sband; 279 280 rate.legacy = sband->bitrates[rate.mcs].bitrate; 281 break; 282 case MT76_TM_TX_MODE_HT: 283 rate.mcs += rate.nss * 8; 284 flags |= RATE_INFO_FLAGS_MCS; 285 286 if (td->tx_rate_sgi) 287 flags |= RATE_INFO_FLAGS_SHORT_GI; 288 break; 289 case MT76_TM_TX_MODE_VHT: 290 flags |= RATE_INFO_FLAGS_VHT_MCS; 291 292 if (td->tx_rate_sgi) 293 flags |= RATE_INFO_FLAGS_SHORT_GI; 294 break; 295 case MT76_TM_TX_MODE_HE_SU: 296 case MT76_TM_TX_MODE_HE_EXT_SU: 297 case MT76_TM_TX_MODE_HE_TB: 298 case MT76_TM_TX_MODE_HE_MU: 299 rate.he_gi = td->tx_rate_sgi; 300 flags |= RATE_INFO_FLAGS_HE_MCS; 301 break; 302 default: 303 break; 304 } 305 rate.flags = flags; 306 307 switch (mphy->chandef.width) { 308 case NL80211_CHAN_WIDTH_160: 309 case NL80211_CHAN_WIDTH_80P80: 310 rate.bw = RATE_INFO_BW_160; 311 break; 312 case NL80211_CHAN_WIDTH_80: 313 rate.bw = RATE_INFO_BW_80; 314 break; 315 case NL80211_CHAN_WIDTH_40: 316 rate.bw = RATE_INFO_BW_40; 317 break; 318 default: 319 rate.bw = RATE_INFO_BW_20; 320 break; 321 } 322 323 bitrate = cfg80211_calculate_bitrate(&rate); 324 tx_len = bitrate * tx_time / 10 / 8; 325 326 ret = mt76_testmode_alloc_skb(phy->mt76, tx_len); 327 if (ret) 328 return ret; 329 330 return 0; 331 } 332 333 static void 334 mt7915_tm_reg_backup_restore(struct mt7915_phy *phy) 335 { 336 int n_regs = ARRAY_SIZE(reg_backup_list); 337 struct mt7915_dev *dev = phy->dev; 338 u32 *b = phy->test.reg_backup; 339 int i; 340 341 REG_BAND_IDX(reg_backup_list[0], AGG_PCR0, 0); 342 REG_BAND_IDX(reg_backup_list[1], AGG_PCR0, 1); 343 REG_BAND_IDX(reg_backup_list[2], AGG_AWSCR0, 0); 344 REG_BAND_IDX(reg_backup_list[3], AGG_AWSCR0, 1); 345 REG_BAND_IDX(reg_backup_list[4], AGG_AWSCR0, 2); 346 REG_BAND_IDX(reg_backup_list[5], AGG_AWSCR0, 3); 347 REG_BAND(reg_backup_list[6], AGG_MRCR); 348 REG_BAND(reg_backup_list[7], TMAC_TFCR0); 349 REG_BAND(reg_backup_list[8], TMAC_TCR0); 350 REG_BAND(reg_backup_list[9], AGG_ATCR1); 351 REG_BAND(reg_backup_list[10], AGG_ATCR3); 352 REG_BAND(reg_backup_list[11], TMAC_TRCR0); 353 REG_BAND(reg_backup_list[12], TMAC_ICR0); 354 REG_BAND_IDX(reg_backup_list[13], ARB_DRNGR0, 0); 355 REG_BAND_IDX(reg_backup_list[14], ARB_DRNGR0, 1); 356 REG_BAND(reg_backup_list[15], WF_RFCR); 357 REG_BAND(reg_backup_list[16], WF_RFCR1); 358 359 if (phy->mt76->test.state == MT76_TM_STATE_OFF) { 360 for (i = 0; i < n_regs; i++) 361 mt76_wr(dev, reg_backup_list[i].band[phy->band_idx], b[i]); 362 return; 363 } 364 365 if (!b) { 366 b = devm_kzalloc(dev->mt76.dev, 4 * n_regs, GFP_KERNEL); 367 if (!b) 368 return; 369 370 phy->test.reg_backup = b; 371 for (i = 0; i < n_regs; i++) 372 b[i] = mt76_rr(dev, reg_backup_list[i].band[phy->band_idx]); 373 } 374 375 mt76_clear(dev, MT_AGG_PCR0(phy->band_idx, 0), MT_AGG_PCR0_MM_PROT | 376 MT_AGG_PCR0_GF_PROT | MT_AGG_PCR0_ERP_PROT | 377 MT_AGG_PCR0_VHT_PROT | MT_AGG_PCR0_BW20_PROT | 378 MT_AGG_PCR0_BW40_PROT | MT_AGG_PCR0_BW80_PROT); 379 mt76_set(dev, MT_AGG_PCR0(phy->band_idx, 0), MT_AGG_PCR0_PTA_WIN_DIS); 380 381 mt76_wr(dev, MT_AGG_PCR0(phy->band_idx, 1), MT_AGG_PCR1_RTS0_NUM_THRES | 382 MT_AGG_PCR1_RTS0_LEN_THRES); 383 384 mt76_clear(dev, MT_AGG_MRCR(phy->band_idx), MT_AGG_MRCR_BAR_CNT_LIMIT | 385 MT_AGG_MRCR_LAST_RTS_CTS_RN | MT_AGG_MRCR_RTS_FAIL_LIMIT | 386 MT_AGG_MRCR_TXCMD_RTS_FAIL_LIMIT); 387 388 mt76_rmw(dev, MT_AGG_MRCR(phy->band_idx), MT_AGG_MRCR_RTS_FAIL_LIMIT | 389 MT_AGG_MRCR_TXCMD_RTS_FAIL_LIMIT, 390 FIELD_PREP(MT_AGG_MRCR_RTS_FAIL_LIMIT, 1) | 391 FIELD_PREP(MT_AGG_MRCR_TXCMD_RTS_FAIL_LIMIT, 1)); 392 393 mt76_wr(dev, MT_TMAC_TFCR0(phy->band_idx), 0); 394 mt76_clear(dev, MT_TMAC_TCR0(phy->band_idx), MT_TMAC_TCR0_TBTT_STOP_CTRL); 395 396 /* config rx filter for testmode rx */ 397 mt76_wr(dev, MT_WF_RFCR(phy->band_idx), 0xcf70a); 398 mt76_wr(dev, MT_WF_RFCR1(phy->band_idx), 0); 399 } 400 401 static void 402 mt7915_tm_init(struct mt7915_phy *phy, bool en) 403 { 404 struct mt7915_dev *dev = phy->dev; 405 406 if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state)) 407 return; 408 409 mt7915_mcu_set_sku_en(phy, !en); 410 411 mt7915_tm_mode_ctrl(dev, en); 412 mt7915_tm_reg_backup_restore(phy); 413 mt7915_tm_set_trx(phy, TM_MAC_TXRX, !en); 414 415 mt7915_mcu_add_bss_info(phy, phy->monitor_vif, en); 416 mt7915_mcu_add_sta(dev, phy->monitor_vif, NULL, en); 417 418 if (!en) 419 mt7915_tm_set_tam_arb(phy, en, 0); 420 } 421 422 static void 423 mt7915_tm_update_channel(struct mt7915_phy *phy) 424 { 425 mutex_unlock(&phy->dev->mt76.mutex); 426 mt7915_set_channel(phy); 427 mutex_lock(&phy->dev->mt76.mutex); 428 429 mt7915_mcu_set_chan_info(phy, MCU_EXT_CMD(SET_RX_PATH)); 430 } 431 432 static void 433 mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en) 434 { 435 static const u8 spe_idx_map[] = {0, 0, 1, 0, 3, 2, 4, 0, 436 9, 8, 6, 10, 16, 12, 18, 0}; 437 struct mt76_testmode_data *td = &phy->mt76->test; 438 struct mt7915_dev *dev = phy->dev; 439 struct ieee80211_tx_info *info; 440 u8 duty_cycle = td->tx_duty_cycle; 441 u32 tx_time = td->tx_time; 442 u32 ipg = td->tx_ipg; 443 444 mt7915_tm_set_trx(phy, TM_MAC_RX_RXV, false); 445 mt7915_tm_clean_hwq(phy, dev->mt76.global_wcid.idx); 446 447 if (en) { 448 mt7915_tm_update_channel(phy); 449 450 if (td->tx_spe_idx) { 451 phy->test.spe_idx = td->tx_spe_idx; 452 } else { 453 u8 tx_ant = td->tx_antenna_mask; 454 455 if (phy != &dev->phy) 456 tx_ant >>= dev->chainshift; 457 phy->test.spe_idx = spe_idx_map[tx_ant]; 458 } 459 } 460 461 mt7915_tm_set_tam_arb(phy, en, 462 td->tx_rate_mode == MT76_TM_TX_MODE_HE_MU); 463 464 /* if all three params are set, duty_cycle will be ignored */ 465 if (duty_cycle && tx_time && !ipg) { 466 ipg = tx_time * 100 / duty_cycle - tx_time; 467 } else if (duty_cycle && !tx_time && ipg) { 468 if (duty_cycle < 100) 469 tx_time = duty_cycle * ipg / (100 - duty_cycle); 470 } 471 472 mt7915_tm_set_ipg_params(phy, ipg, td->tx_rate_mode); 473 mt7915_tm_set_tx_len(phy, tx_time); 474 475 if (ipg) 476 td->tx_queued_limit = MT76_TM_TIMEOUT * 1000000 / ipg / 2; 477 478 if (!en || !td->tx_skb) 479 return; 480 481 info = IEEE80211_SKB_CB(td->tx_skb); 482 info->control.vif = phy->monitor_vif; 483 484 mt7915_tm_set_trx(phy, TM_MAC_TX, en); 485 } 486 487 static void 488 mt7915_tm_set_rx_frames(struct mt7915_phy *phy, bool en) 489 { 490 mt7915_tm_set_trx(phy, TM_MAC_RX_RXV, false); 491 492 if (en) { 493 struct mt7915_dev *dev = phy->dev; 494 495 mt7915_tm_update_channel(phy); 496 497 /* read-clear */ 498 mt76_rr(dev, MT_MIB_SDR3(phy != &dev->phy)); 499 mt7915_tm_set_trx(phy, TM_MAC_RX_RXV, en); 500 } 501 } 502 503 static int 504 mt7915_tm_rf_switch_mode(struct mt7915_dev *dev, u32 oper) 505 { 506 struct mt7915_tm_rf_test req = { 507 .op.op_mode = cpu_to_le32(oper), 508 }; 509 510 return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(RF_TEST), &req, 511 sizeof(req), true); 512 } 513 514 static int 515 mt7915_tm_set_tx_cont(struct mt7915_phy *phy, bool en) 516 { 517 #define TX_CONT_START 0x05 518 #define TX_CONT_STOP 0x06 519 struct mt7915_dev *dev = phy->dev; 520 struct cfg80211_chan_def *chandef = &phy->mt76->chandef; 521 int freq1 = ieee80211_frequency_to_channel(chandef->center_freq1); 522 struct mt76_testmode_data *td = &phy->mt76->test; 523 u32 func_idx = en ? TX_CONT_START : TX_CONT_STOP; 524 u8 rate_idx = td->tx_rate_idx, mode; 525 u16 rateval; 526 struct mt7915_tm_rf_test req = { 527 .action = 1, 528 .icap_len = 120, 529 .op.rf.func_idx = cpu_to_le32(func_idx), 530 }; 531 struct tm_tx_cont *tx_cont = &req.op.rf.param.tx_cont; 532 533 tx_cont->control_ch = chandef->chan->hw_value; 534 tx_cont->center_ch = freq1; 535 tx_cont->tx_ant = td->tx_antenna_mask; 536 tx_cont->band = phy != &dev->phy; 537 538 switch (chandef->width) { 539 case NL80211_CHAN_WIDTH_40: 540 tx_cont->bw = CMD_CBW_40MHZ; 541 break; 542 case NL80211_CHAN_WIDTH_80: 543 tx_cont->bw = CMD_CBW_80MHZ; 544 break; 545 case NL80211_CHAN_WIDTH_80P80: 546 tx_cont->bw = CMD_CBW_8080MHZ; 547 break; 548 case NL80211_CHAN_WIDTH_160: 549 tx_cont->bw = CMD_CBW_160MHZ; 550 break; 551 case NL80211_CHAN_WIDTH_5: 552 tx_cont->bw = CMD_CBW_5MHZ; 553 break; 554 case NL80211_CHAN_WIDTH_10: 555 tx_cont->bw = CMD_CBW_10MHZ; 556 break; 557 case NL80211_CHAN_WIDTH_20: 558 tx_cont->bw = CMD_CBW_20MHZ; 559 break; 560 case NL80211_CHAN_WIDTH_20_NOHT: 561 tx_cont->bw = CMD_CBW_20MHZ; 562 break; 563 default: 564 return -EINVAL; 565 } 566 567 if (!en) { 568 req.op.rf.param.func_data = cpu_to_le32(phy != &dev->phy); 569 goto out; 570 } 571 572 if (td->tx_rate_mode <= MT76_TM_TX_MODE_OFDM) { 573 struct ieee80211_supported_band *sband; 574 u8 idx = rate_idx; 575 576 if (chandef->chan->band == NL80211_BAND_5GHZ) 577 sband = &phy->mt76->sband_5g.sband; 578 else if (chandef->chan->band == NL80211_BAND_6GHZ) 579 sband = &phy->mt76->sband_6g.sband; 580 else 581 sband = &phy->mt76->sband_2g.sband; 582 583 if (td->tx_rate_mode == MT76_TM_TX_MODE_OFDM) 584 idx += 4; 585 rate_idx = sband->bitrates[idx].hw_value & 0xff; 586 } 587 588 switch (td->tx_rate_mode) { 589 case MT76_TM_TX_MODE_CCK: 590 mode = MT_PHY_TYPE_CCK; 591 break; 592 case MT76_TM_TX_MODE_OFDM: 593 mode = MT_PHY_TYPE_OFDM; 594 break; 595 case MT76_TM_TX_MODE_HT: 596 mode = MT_PHY_TYPE_HT; 597 break; 598 case MT76_TM_TX_MODE_VHT: 599 mode = MT_PHY_TYPE_VHT; 600 break; 601 case MT76_TM_TX_MODE_HE_SU: 602 mode = MT_PHY_TYPE_HE_SU; 603 break; 604 case MT76_TM_TX_MODE_HE_EXT_SU: 605 mode = MT_PHY_TYPE_HE_EXT_SU; 606 break; 607 case MT76_TM_TX_MODE_HE_TB: 608 mode = MT_PHY_TYPE_HE_TB; 609 break; 610 case MT76_TM_TX_MODE_HE_MU: 611 mode = MT_PHY_TYPE_HE_MU; 612 break; 613 default: 614 return -EINVAL; 615 } 616 617 rateval = mode << 6 | rate_idx; 618 tx_cont->rateval = cpu_to_le16(rateval); 619 620 out: 621 if (!en) { 622 int ret; 623 624 ret = mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(RF_TEST), &req, 625 sizeof(req), true); 626 if (ret) 627 return ret; 628 629 return mt7915_tm_rf_switch_mode(dev, RF_OPER_NORMAL); 630 } 631 632 mt7915_tm_rf_switch_mode(dev, RF_OPER_RF_TEST); 633 mt7915_tm_update_channel(phy); 634 635 return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(RF_TEST), &req, 636 sizeof(req), true); 637 } 638 639 static void 640 mt7915_tm_update_params(struct mt7915_phy *phy, u32 changed) 641 { 642 struct mt76_testmode_data *td = &phy->mt76->test; 643 bool en = phy->mt76->test.state != MT76_TM_STATE_OFF; 644 645 if (changed & BIT(TM_CHANGED_FREQ_OFFSET)) 646 mt7915_tm_set_freq_offset(phy, en, en ? td->freq_offset : 0); 647 if (changed & BIT(TM_CHANGED_TXPOWER)) 648 mt7915_tm_set_tx_power(phy); 649 } 650 651 static int 652 mt7915_tm_set_state(struct mt76_phy *mphy, enum mt76_testmode_state state) 653 { 654 struct mt76_testmode_data *td = &mphy->test; 655 struct mt7915_phy *phy = mphy->priv; 656 enum mt76_testmode_state prev_state = td->state; 657 658 mphy->test.state = state; 659 660 if (prev_state == MT76_TM_STATE_TX_FRAMES || 661 state == MT76_TM_STATE_TX_FRAMES) 662 mt7915_tm_set_tx_frames(phy, state == MT76_TM_STATE_TX_FRAMES); 663 else if (prev_state == MT76_TM_STATE_RX_FRAMES || 664 state == MT76_TM_STATE_RX_FRAMES) 665 mt7915_tm_set_rx_frames(phy, state == MT76_TM_STATE_RX_FRAMES); 666 else if (prev_state == MT76_TM_STATE_TX_CONT || 667 state == MT76_TM_STATE_TX_CONT) 668 mt7915_tm_set_tx_cont(phy, state == MT76_TM_STATE_TX_CONT); 669 else if (prev_state == MT76_TM_STATE_OFF || 670 state == MT76_TM_STATE_OFF) 671 mt7915_tm_init(phy, !(state == MT76_TM_STATE_OFF)); 672 673 if ((state == MT76_TM_STATE_IDLE && 674 prev_state == MT76_TM_STATE_OFF) || 675 (state == MT76_TM_STATE_OFF && 676 prev_state == MT76_TM_STATE_IDLE)) { 677 u32 changed = 0; 678 int i; 679 680 for (i = 0; i < ARRAY_SIZE(tm_change_map); i++) { 681 u16 cur = tm_change_map[i]; 682 683 if (td->param_set[cur / 32] & BIT(cur % 32)) 684 changed |= BIT(i); 685 } 686 687 mt7915_tm_update_params(phy, changed); 688 } 689 690 return 0; 691 } 692 693 static int 694 mt7915_tm_set_params(struct mt76_phy *mphy, struct nlattr **tb, 695 enum mt76_testmode_state new_state) 696 { 697 struct mt76_testmode_data *td = &mphy->test; 698 struct mt7915_phy *phy = mphy->priv; 699 u32 changed = 0; 700 int i; 701 702 BUILD_BUG_ON(NUM_TM_CHANGED >= 32); 703 704 if (new_state == MT76_TM_STATE_OFF || 705 td->state == MT76_TM_STATE_OFF) 706 return 0; 707 708 if (td->tx_antenna_mask & ~mphy->chainmask) 709 return -EINVAL; 710 711 for (i = 0; i < ARRAY_SIZE(tm_change_map); i++) { 712 if (tb[tm_change_map[i]]) 713 changed |= BIT(i); 714 } 715 716 mt7915_tm_update_params(phy, changed); 717 718 return 0; 719 } 720 721 static int 722 mt7915_tm_dump_stats(struct mt76_phy *mphy, struct sk_buff *msg) 723 { 724 struct mt7915_phy *phy = mphy->priv; 725 struct mt7915_dev *dev = phy->dev; 726 enum mt76_rxq_id q; 727 void *rx, *rssi; 728 u16 fcs_err; 729 int i; 730 u32 cnt; 731 732 rx = nla_nest_start(msg, MT76_TM_STATS_ATTR_LAST_RX); 733 if (!rx) 734 return -ENOMEM; 735 736 if (nla_put_s32(msg, MT76_TM_RX_ATTR_FREQ_OFFSET, phy->test.last_freq_offset)) 737 return -ENOMEM; 738 739 rssi = nla_nest_start(msg, MT76_TM_RX_ATTR_RCPI); 740 if (!rssi) 741 return -ENOMEM; 742 743 for (i = 0; i < ARRAY_SIZE(phy->test.last_rcpi); i++) 744 if (nla_put_u8(msg, i, phy->test.last_rcpi[i])) 745 return -ENOMEM; 746 747 nla_nest_end(msg, rssi); 748 749 rssi = nla_nest_start(msg, MT76_TM_RX_ATTR_IB_RSSI); 750 if (!rssi) 751 return -ENOMEM; 752 753 for (i = 0; i < ARRAY_SIZE(phy->test.last_ib_rssi); i++) 754 if (nla_put_s8(msg, i, phy->test.last_ib_rssi[i])) 755 return -ENOMEM; 756 757 nla_nest_end(msg, rssi); 758 759 rssi = nla_nest_start(msg, MT76_TM_RX_ATTR_WB_RSSI); 760 if (!rssi) 761 return -ENOMEM; 762 763 for (i = 0; i < ARRAY_SIZE(phy->test.last_wb_rssi); i++) 764 if (nla_put_s8(msg, i, phy->test.last_wb_rssi[i])) 765 return -ENOMEM; 766 767 nla_nest_end(msg, rssi); 768 769 if (nla_put_u8(msg, MT76_TM_RX_ATTR_SNR, phy->test.last_snr)) 770 return -ENOMEM; 771 772 nla_nest_end(msg, rx); 773 774 cnt = mt76_rr(dev, MT_MIB_SDR3(phy->band_idx)); 775 fcs_err = is_mt7915(&dev->mt76) ? FIELD_GET(MT_MIB_SDR3_FCS_ERR_MASK, cnt) : 776 FIELD_GET(MT_MIB_SDR3_FCS_ERR_MASK_MT7916, cnt); 777 778 q = phy->band_idx ? MT_RXQ_BAND1 : MT_RXQ_MAIN; 779 mphy->test.rx_stats.packets[q] += fcs_err; 780 mphy->test.rx_stats.fcs_error[q] += fcs_err; 781 782 return 0; 783 } 784 785 const struct mt76_testmode_ops mt7915_testmode_ops = { 786 .set_state = mt7915_tm_set_state, 787 .set_params = mt7915_tm_set_params, 788 .dump_stats = mt7915_tm_dump_stats, 789 }; 790