1 // SPDX-License-Identifier: ISC 2 /* Copyright (C) 2020 Felix Fietkau <nbd@nbd.name> */ 3 #include "mt76.h" 4 5 const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS] = { 6 [MT76_TM_ATTR_RESET] = { .type = NLA_FLAG }, 7 [MT76_TM_ATTR_STATE] = { .type = NLA_U8 }, 8 [MT76_TM_ATTR_TX_COUNT] = { .type = NLA_U32 }, 9 [MT76_TM_ATTR_TX_RATE_MODE] = { .type = NLA_U8 }, 10 [MT76_TM_ATTR_TX_RATE_NSS] = { .type = NLA_U8 }, 11 [MT76_TM_ATTR_TX_RATE_IDX] = { .type = NLA_U8 }, 12 [MT76_TM_ATTR_TX_RATE_SGI] = { .type = NLA_U8 }, 13 [MT76_TM_ATTR_TX_RATE_LDPC] = { .type = NLA_U8 }, 14 [MT76_TM_ATTR_TX_RATE_STBC] = { .type = NLA_U8 }, 15 [MT76_TM_ATTR_TX_LTF] = { .type = NLA_U8 }, 16 [MT76_TM_ATTR_TX_ANTENNA] = { .type = NLA_U8 }, 17 [MT76_TM_ATTR_TX_SPE_IDX] = { .type = NLA_U8 }, 18 [MT76_TM_ATTR_TX_POWER_CONTROL] = { .type = NLA_U8 }, 19 [MT76_TM_ATTR_TX_POWER] = { .type = NLA_NESTED }, 20 [MT76_TM_ATTR_TX_DUTY_CYCLE] = { .type = NLA_U8 }, 21 [MT76_TM_ATTR_TX_IPG] = { .type = NLA_U32 }, 22 [MT76_TM_ATTR_TX_TIME] = { .type = NLA_U32 }, 23 [MT76_TM_ATTR_FREQ_OFFSET] = { .type = NLA_U32 }, 24 [MT76_TM_ATTR_DRV_DATA] = { .type = NLA_NESTED }, 25 }; 26 EXPORT_SYMBOL_GPL(mt76_tm_policy); 27 28 void mt76_testmode_tx_pending(struct mt76_phy *phy) 29 { 30 struct mt76_testmode_data *td = &phy->test; 31 struct mt76_dev *dev = phy->dev; 32 struct mt76_wcid *wcid = &dev->global_wcid; 33 struct sk_buff *skb = td->tx_skb; 34 struct mt76_queue *q; 35 u16 tx_queued_limit; 36 int qid; 37 38 if (!skb || !td->tx_pending) 39 return; 40 41 qid = skb_get_queue_mapping(skb); 42 q = phy->q_tx[qid]; 43 44 tx_queued_limit = td->tx_queued_limit ? td->tx_queued_limit : 1000; 45 46 spin_lock_bh(&q->lock); 47 48 while (td->tx_pending > 0 && 49 td->tx_queued - td->tx_done < tx_queued_limit && 50 q->queued < q->ndesc / 2) { 51 int ret; 52 53 ret = dev->queue_ops->tx_queue_skb(dev, q, skb_get(skb), wcid, 54 NULL); 55 if (ret < 0) 56 break; 57 58 td->tx_pending--; 59 td->tx_queued++; 60 } 61 62 dev->queue_ops->kick(dev, q); 63 64 spin_unlock_bh(&q->lock); 65 } 66 67 static u32 68 mt76_testmode_max_mpdu_len(struct mt76_phy *phy, u8 tx_rate_mode) 69 { 70 switch (tx_rate_mode) { 71 case MT76_TM_TX_MODE_HT: 72 return IEEE80211_MAX_MPDU_LEN_HT_7935; 73 case MT76_TM_TX_MODE_VHT: 74 case MT76_TM_TX_MODE_HE_SU: 75 case MT76_TM_TX_MODE_HE_EXT_SU: 76 case MT76_TM_TX_MODE_HE_TB: 77 case MT76_TM_TX_MODE_HE_MU: 78 if (phy->sband_5g.sband.vht_cap.cap & 79 IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991) 80 return IEEE80211_MAX_MPDU_LEN_VHT_7991; 81 return IEEE80211_MAX_MPDU_LEN_VHT_11454; 82 case MT76_TM_TX_MODE_CCK: 83 case MT76_TM_TX_MODE_OFDM: 84 default: 85 return IEEE80211_MAX_FRAME_LEN; 86 } 87 } 88 89 static void 90 mt76_testmode_free_skb(struct mt76_phy *phy) 91 { 92 struct mt76_testmode_data *td = &phy->test; 93 94 dev_kfree_skb(td->tx_skb); 95 td->tx_skb = NULL; 96 } 97 98 int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len) 99 { 100 #define MT_TXP_MAX_LEN 4095 101 u16 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA | 102 IEEE80211_FCTL_FROMDS; 103 struct mt76_testmode_data *td = &phy->test; 104 bool ext_phy = phy != &phy->dev->phy; 105 struct sk_buff **frag_tail, *head; 106 struct ieee80211_tx_info *info; 107 struct ieee80211_hdr *hdr; 108 u32 max_len, head_len; 109 int nfrags, i; 110 111 max_len = mt76_testmode_max_mpdu_len(phy, td->tx_rate_mode); 112 if (len > max_len) 113 len = max_len; 114 else if (len < sizeof(struct ieee80211_hdr)) 115 len = sizeof(struct ieee80211_hdr); 116 117 nfrags = len / MT_TXP_MAX_LEN; 118 head_len = nfrags ? MT_TXP_MAX_LEN : len; 119 120 if (len > IEEE80211_MAX_FRAME_LEN) 121 fc |= IEEE80211_STYPE_QOS_DATA; 122 123 head = alloc_skb(head_len, GFP_KERNEL); 124 if (!head) 125 return -ENOMEM; 126 127 hdr = __skb_put_zero(head, head_len); 128 hdr->frame_control = cpu_to_le16(fc); 129 memcpy(hdr->addr1, phy->macaddr, sizeof(phy->macaddr)); 130 memcpy(hdr->addr2, phy->macaddr, sizeof(phy->macaddr)); 131 memcpy(hdr->addr3, phy->macaddr, sizeof(phy->macaddr)); 132 skb_set_queue_mapping(head, IEEE80211_AC_BE); 133 134 info = IEEE80211_SKB_CB(head); 135 info->flags = IEEE80211_TX_CTL_INJECTED | 136 IEEE80211_TX_CTL_NO_ACK | 137 IEEE80211_TX_CTL_NO_PS_BUFFER; 138 139 if (ext_phy) 140 info->hw_queue |= MT_TX_HW_QUEUE_EXT_PHY; 141 142 frag_tail = &skb_shinfo(head)->frag_list; 143 144 for (i = 0; i < nfrags; i++) { 145 struct sk_buff *frag; 146 u16 frag_len; 147 148 if (i == nfrags - 1) 149 frag_len = len % MT_TXP_MAX_LEN; 150 else 151 frag_len = MT_TXP_MAX_LEN; 152 153 frag = alloc_skb(frag_len, GFP_KERNEL); 154 if (!frag) { 155 mt76_testmode_free_skb(phy); 156 dev_kfree_skb(head); 157 return -ENOMEM; 158 } 159 160 __skb_put_zero(frag, frag_len); 161 head->len += frag->len; 162 head->data_len += frag->len; 163 164 *frag_tail = frag; 165 frag_tail = &(*frag_tail)->next; 166 } 167 168 mt76_testmode_free_skb(phy); 169 td->tx_skb = head; 170 171 return 0; 172 } 173 EXPORT_SYMBOL(mt76_testmode_alloc_skb); 174 175 static int 176 mt76_testmode_tx_init(struct mt76_phy *phy) 177 { 178 struct mt76_testmode_data *td = &phy->test; 179 struct ieee80211_tx_info *info; 180 struct ieee80211_tx_rate *rate; 181 u8 max_nss = hweight8(phy->antenna_mask); 182 int ret; 183 184 ret = mt76_testmode_alloc_skb(phy, td->tx_mpdu_len); 185 if (ret) 186 return ret; 187 188 if (td->tx_rate_mode > MT76_TM_TX_MODE_VHT) 189 goto out; 190 191 if (td->tx_antenna_mask) 192 max_nss = min_t(u8, max_nss, hweight8(td->tx_antenna_mask)); 193 194 info = IEEE80211_SKB_CB(td->tx_skb); 195 rate = &info->control.rates[0]; 196 rate->count = 1; 197 rate->idx = td->tx_rate_idx; 198 199 switch (td->tx_rate_mode) { 200 case MT76_TM_TX_MODE_CCK: 201 if (phy->chandef.chan->band != NL80211_BAND_2GHZ) 202 return -EINVAL; 203 204 if (rate->idx > 4) 205 return -EINVAL; 206 break; 207 case MT76_TM_TX_MODE_OFDM: 208 if (phy->chandef.chan->band != NL80211_BAND_2GHZ) 209 break; 210 211 if (rate->idx > 8) 212 return -EINVAL; 213 214 rate->idx += 4; 215 break; 216 case MT76_TM_TX_MODE_HT: 217 if (rate->idx > 8 * max_nss && 218 !(rate->idx == 32 && 219 phy->chandef.width >= NL80211_CHAN_WIDTH_40)) 220 return -EINVAL; 221 222 rate->flags |= IEEE80211_TX_RC_MCS; 223 break; 224 case MT76_TM_TX_MODE_VHT: 225 if (rate->idx > 9) 226 return -EINVAL; 227 228 if (td->tx_rate_nss > max_nss) 229 return -EINVAL; 230 231 ieee80211_rate_set_vht(rate, td->tx_rate_idx, td->tx_rate_nss); 232 rate->flags |= IEEE80211_TX_RC_VHT_MCS; 233 break; 234 default: 235 break; 236 } 237 238 if (td->tx_rate_sgi) 239 rate->flags |= IEEE80211_TX_RC_SHORT_GI; 240 241 if (td->tx_rate_ldpc) 242 info->flags |= IEEE80211_TX_CTL_LDPC; 243 244 if (td->tx_rate_stbc) 245 info->flags |= IEEE80211_TX_CTL_STBC; 246 247 if (td->tx_rate_mode >= MT76_TM_TX_MODE_HT) { 248 switch (phy->chandef.width) { 249 case NL80211_CHAN_WIDTH_40: 250 rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; 251 break; 252 case NL80211_CHAN_WIDTH_80: 253 rate->flags |= IEEE80211_TX_RC_80_MHZ_WIDTH; 254 break; 255 case NL80211_CHAN_WIDTH_80P80: 256 case NL80211_CHAN_WIDTH_160: 257 rate->flags |= IEEE80211_TX_RC_160_MHZ_WIDTH; 258 break; 259 default: 260 break; 261 } 262 } 263 out: 264 return 0; 265 } 266 267 static void 268 mt76_testmode_tx_start(struct mt76_phy *phy) 269 { 270 struct mt76_testmode_data *td = &phy->test; 271 struct mt76_dev *dev = phy->dev; 272 273 td->tx_queued = 0; 274 td->tx_done = 0; 275 td->tx_pending = td->tx_count; 276 mt76_worker_schedule(&dev->tx_worker); 277 } 278 279 static void 280 mt76_testmode_tx_stop(struct mt76_phy *phy) 281 { 282 struct mt76_testmode_data *td = &phy->test; 283 struct mt76_dev *dev = phy->dev; 284 285 mt76_worker_disable(&dev->tx_worker); 286 287 td->tx_pending = 0; 288 289 mt76_worker_enable(&dev->tx_worker); 290 291 wait_event_timeout(dev->tx_wait, td->tx_done == td->tx_queued, 292 MT76_TM_TIMEOUT * HZ); 293 294 mt76_testmode_free_skb(phy); 295 } 296 297 static inline void 298 mt76_testmode_param_set(struct mt76_testmode_data *td, u16 idx) 299 { 300 td->param_set[idx / 32] |= BIT(idx % 32); 301 } 302 303 static inline bool 304 mt76_testmode_param_present(struct mt76_testmode_data *td, u16 idx) 305 { 306 return td->param_set[idx / 32] & BIT(idx % 32); 307 } 308 309 static void 310 mt76_testmode_init_defaults(struct mt76_phy *phy) 311 { 312 struct mt76_testmode_data *td = &phy->test; 313 314 if (td->tx_mpdu_len > 0) 315 return; 316 317 td->tx_mpdu_len = 1024; 318 td->tx_count = 1; 319 td->tx_rate_mode = MT76_TM_TX_MODE_OFDM; 320 td->tx_rate_nss = 1; 321 } 322 323 static int 324 __mt76_testmode_set_state(struct mt76_phy *phy, enum mt76_testmode_state state) 325 { 326 enum mt76_testmode_state prev_state = phy->test.state; 327 struct mt76_dev *dev = phy->dev; 328 int err; 329 330 if (prev_state == MT76_TM_STATE_TX_FRAMES) 331 mt76_testmode_tx_stop(phy); 332 333 if (state == MT76_TM_STATE_TX_FRAMES) { 334 err = mt76_testmode_tx_init(phy); 335 if (err) 336 return err; 337 } 338 339 err = dev->test_ops->set_state(phy, state); 340 if (err) { 341 if (state == MT76_TM_STATE_TX_FRAMES) 342 mt76_testmode_tx_stop(phy); 343 344 return err; 345 } 346 347 if (state == MT76_TM_STATE_TX_FRAMES) 348 mt76_testmode_tx_start(phy); 349 else if (state == MT76_TM_STATE_RX_FRAMES) { 350 memset(&phy->test.rx_stats, 0, sizeof(phy->test.rx_stats)); 351 } 352 353 phy->test.state = state; 354 355 return 0; 356 } 357 358 int mt76_testmode_set_state(struct mt76_phy *phy, enum mt76_testmode_state state) 359 { 360 struct mt76_testmode_data *td = &phy->test; 361 struct ieee80211_hw *hw = phy->hw; 362 363 if (state == td->state && state == MT76_TM_STATE_OFF) 364 return 0; 365 366 if (state > MT76_TM_STATE_OFF && 367 (!test_bit(MT76_STATE_RUNNING, &phy->state) || 368 !(hw->conf.flags & IEEE80211_CONF_MONITOR))) 369 return -ENOTCONN; 370 371 if (state != MT76_TM_STATE_IDLE && 372 td->state != MT76_TM_STATE_IDLE) { 373 int ret; 374 375 ret = __mt76_testmode_set_state(phy, MT76_TM_STATE_IDLE); 376 if (ret) 377 return ret; 378 } 379 380 return __mt76_testmode_set_state(phy, state); 381 382 } 383 EXPORT_SYMBOL(mt76_testmode_set_state); 384 385 static int 386 mt76_tm_get_u8(struct nlattr *attr, u8 *dest, u8 min, u8 max) 387 { 388 u8 val; 389 390 if (!attr) 391 return 0; 392 393 val = nla_get_u8(attr); 394 if (val < min || val > max) 395 return -EINVAL; 396 397 *dest = val; 398 return 0; 399 } 400 401 int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 402 void *data, int len) 403 { 404 struct mt76_phy *phy = hw->priv; 405 struct mt76_dev *dev = phy->dev; 406 struct mt76_testmode_data *td = &phy->test; 407 struct nlattr *tb[NUM_MT76_TM_ATTRS]; 408 bool ext_phy = phy != &dev->phy; 409 u32 state; 410 int err; 411 int i; 412 413 if (!dev->test_ops) 414 return -EOPNOTSUPP; 415 416 err = nla_parse_deprecated(tb, MT76_TM_ATTR_MAX, data, len, 417 mt76_tm_policy, NULL); 418 if (err) 419 return err; 420 421 err = -EINVAL; 422 423 mutex_lock(&dev->mutex); 424 425 if (tb[MT76_TM_ATTR_RESET]) { 426 mt76_testmode_set_state(phy, MT76_TM_STATE_OFF); 427 memset(td, 0, sizeof(*td)); 428 } 429 430 mt76_testmode_init_defaults(phy); 431 432 if (tb[MT76_TM_ATTR_TX_COUNT]) 433 td->tx_count = nla_get_u32(tb[MT76_TM_ATTR_TX_COUNT]); 434 435 if (tb[MT76_TM_ATTR_TX_RATE_IDX]) 436 td->tx_rate_idx = nla_get_u8(tb[MT76_TM_ATTR_TX_RATE_IDX]); 437 438 if (mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_RATE_MODE], &td->tx_rate_mode, 439 0, MT76_TM_TX_MODE_MAX) || 440 mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_RATE_NSS], &td->tx_rate_nss, 441 1, hweight8(phy->antenna_mask)) || 442 mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_RATE_SGI], &td->tx_rate_sgi, 0, 2) || 443 mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_RATE_LDPC], &td->tx_rate_ldpc, 0, 1) || 444 mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_RATE_STBC], &td->tx_rate_stbc, 0, 1) || 445 mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_LTF], &td->tx_ltf, 0, 2) || 446 mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_ANTENNA], &td->tx_antenna_mask, 447 1 << (ext_phy * 2), phy->antenna_mask << (ext_phy * 2)) || 448 mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_SPE_IDX], &td->tx_spe_idx, 0, 27) || 449 mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_DUTY_CYCLE], 450 &td->tx_duty_cycle, 0, 99) || 451 mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_POWER_CONTROL], 452 &td->tx_power_control, 0, 1)) 453 goto out; 454 455 if (tb[MT76_TM_ATTR_TX_LENGTH]) { 456 u32 val = nla_get_u32(tb[MT76_TM_ATTR_TX_LENGTH]); 457 458 if (val > mt76_testmode_max_mpdu_len(phy, td->tx_rate_mode) || 459 val < sizeof(struct ieee80211_hdr)) 460 goto out; 461 462 td->tx_mpdu_len = val; 463 } 464 465 if (tb[MT76_TM_ATTR_TX_IPG]) 466 td->tx_ipg = nla_get_u32(tb[MT76_TM_ATTR_TX_IPG]); 467 468 if (tb[MT76_TM_ATTR_TX_TIME]) 469 td->tx_time = nla_get_u32(tb[MT76_TM_ATTR_TX_TIME]); 470 471 if (tb[MT76_TM_ATTR_FREQ_OFFSET]) 472 td->freq_offset = nla_get_u32(tb[MT76_TM_ATTR_FREQ_OFFSET]); 473 474 if (tb[MT76_TM_ATTR_STATE]) { 475 state = nla_get_u32(tb[MT76_TM_ATTR_STATE]); 476 if (state > MT76_TM_STATE_MAX) 477 goto out; 478 } else { 479 state = td->state; 480 } 481 482 if (tb[MT76_TM_ATTR_TX_POWER]) { 483 struct nlattr *cur; 484 int idx = 0; 485 int rem; 486 487 nla_for_each_nested(cur, tb[MT76_TM_ATTR_TX_POWER], rem) { 488 if (nla_len(cur) != 1 || 489 idx >= ARRAY_SIZE(td->tx_power)) 490 goto out; 491 492 td->tx_power[idx++] = nla_get_u8(cur); 493 } 494 } 495 496 if (dev->test_ops->set_params) { 497 err = dev->test_ops->set_params(phy, tb, state); 498 if (err) 499 goto out; 500 } 501 502 for (i = MT76_TM_ATTR_STATE; i < ARRAY_SIZE(tb); i++) 503 if (tb[i]) 504 mt76_testmode_param_set(td, i); 505 506 err = 0; 507 if (tb[MT76_TM_ATTR_STATE]) 508 err = mt76_testmode_set_state(phy, state); 509 510 out: 511 mutex_unlock(&dev->mutex); 512 513 return err; 514 } 515 EXPORT_SYMBOL(mt76_testmode_cmd); 516 517 static int 518 mt76_testmode_dump_stats(struct mt76_phy *phy, struct sk_buff *msg) 519 { 520 struct mt76_testmode_data *td = &phy->test; 521 struct mt76_dev *dev = phy->dev; 522 u64 rx_packets = 0; 523 u64 rx_fcs_error = 0; 524 int i; 525 526 if (dev->test_ops->dump_stats) { 527 int ret; 528 529 ret = dev->test_ops->dump_stats(phy, msg); 530 if (ret) 531 return ret; 532 } 533 534 for (i = 0; i < ARRAY_SIZE(td->rx_stats.packets); i++) { 535 rx_packets += td->rx_stats.packets[i]; 536 rx_fcs_error += td->rx_stats.fcs_error[i]; 537 } 538 539 if (nla_put_u32(msg, MT76_TM_STATS_ATTR_TX_PENDING, td->tx_pending) || 540 nla_put_u32(msg, MT76_TM_STATS_ATTR_TX_QUEUED, td->tx_queued) || 541 nla_put_u32(msg, MT76_TM_STATS_ATTR_TX_DONE, td->tx_done) || 542 nla_put_u64_64bit(msg, MT76_TM_STATS_ATTR_RX_PACKETS, rx_packets, 543 MT76_TM_STATS_ATTR_PAD) || 544 nla_put_u64_64bit(msg, MT76_TM_STATS_ATTR_RX_FCS_ERROR, rx_fcs_error, 545 MT76_TM_STATS_ATTR_PAD)) 546 return -EMSGSIZE; 547 548 return 0; 549 } 550 551 int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg, 552 struct netlink_callback *cb, void *data, int len) 553 { 554 struct mt76_phy *phy = hw->priv; 555 struct mt76_dev *dev = phy->dev; 556 struct mt76_testmode_data *td = &phy->test; 557 struct nlattr *tb[NUM_MT76_TM_ATTRS] = {}; 558 int err = 0; 559 void *a; 560 int i; 561 562 if (!dev->test_ops) 563 return -EOPNOTSUPP; 564 565 if (cb->args[2]++ > 0) 566 return -ENOENT; 567 568 if (data) { 569 err = nla_parse_deprecated(tb, MT76_TM_ATTR_MAX, data, len, 570 mt76_tm_policy, NULL); 571 if (err) 572 return err; 573 } 574 575 mutex_lock(&dev->mutex); 576 577 if (tb[MT76_TM_ATTR_STATS]) { 578 err = -EINVAL; 579 580 a = nla_nest_start(msg, MT76_TM_ATTR_STATS); 581 if (a) { 582 err = mt76_testmode_dump_stats(phy, msg); 583 nla_nest_end(msg, a); 584 } 585 586 goto out; 587 } 588 589 mt76_testmode_init_defaults(phy); 590 591 err = -EMSGSIZE; 592 if (nla_put_u32(msg, MT76_TM_ATTR_STATE, td->state)) 593 goto out; 594 595 if (dev->test_mtd.name && 596 (nla_put_string(msg, MT76_TM_ATTR_MTD_PART, dev->test_mtd.name) || 597 nla_put_u32(msg, MT76_TM_ATTR_MTD_OFFSET, dev->test_mtd.offset))) 598 goto out; 599 600 if (nla_put_u32(msg, MT76_TM_ATTR_TX_COUNT, td->tx_count) || 601 nla_put_u32(msg, MT76_TM_ATTR_TX_LENGTH, td->tx_mpdu_len) || 602 nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_MODE, td->tx_rate_mode) || 603 nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_NSS, td->tx_rate_nss) || 604 nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_IDX, td->tx_rate_idx) || 605 nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_SGI, td->tx_rate_sgi) || 606 nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_LDPC, td->tx_rate_ldpc) || 607 nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_STBC, td->tx_rate_stbc) || 608 (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_LTF) && 609 nla_put_u8(msg, MT76_TM_ATTR_TX_LTF, td->tx_ltf)) || 610 (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_ANTENNA) && 611 nla_put_u8(msg, MT76_TM_ATTR_TX_ANTENNA, td->tx_antenna_mask)) || 612 (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_SPE_IDX) && 613 nla_put_u8(msg, MT76_TM_ATTR_TX_SPE_IDX, td->tx_spe_idx)) || 614 (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_DUTY_CYCLE) && 615 nla_put_u8(msg, MT76_TM_ATTR_TX_DUTY_CYCLE, td->tx_duty_cycle)) || 616 (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_IPG) && 617 nla_put_u32(msg, MT76_TM_ATTR_TX_IPG, td->tx_ipg)) || 618 (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_TIME) && 619 nla_put_u32(msg, MT76_TM_ATTR_TX_TIME, td->tx_time)) || 620 (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_POWER_CONTROL) && 621 nla_put_u8(msg, MT76_TM_ATTR_TX_POWER_CONTROL, td->tx_power_control)) || 622 (mt76_testmode_param_present(td, MT76_TM_ATTR_FREQ_OFFSET) && 623 nla_put_u8(msg, MT76_TM_ATTR_FREQ_OFFSET, td->freq_offset))) 624 goto out; 625 626 if (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_POWER)) { 627 a = nla_nest_start(msg, MT76_TM_ATTR_TX_POWER); 628 if (!a) 629 goto out; 630 631 for (i = 0; i < ARRAY_SIZE(td->tx_power); i++) 632 if (nla_put_u8(msg, i, td->tx_power[i])) 633 goto out; 634 635 nla_nest_end(msg, a); 636 } 637 638 err = 0; 639 640 out: 641 mutex_unlock(&dev->mutex); 642 643 return err; 644 } 645 EXPORT_SYMBOL(mt76_testmode_dump); 646