1 // SPDX-License-Identifier: ISC 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 4 #include "mt76_connac_mcu.h" 5 6 int mt76_connac_mcu_start_firmware(struct mt76_dev *dev, u32 addr, u32 option) 7 { 8 struct { 9 __le32 option; 10 __le32 addr; 11 } req = { 12 .option = cpu_to_le32(option), 13 .addr = cpu_to_le32(addr), 14 }; 15 16 return mt76_mcu_send_msg(dev, MCU_CMD(FW_START_REQ), &req, 17 sizeof(req), true); 18 } 19 EXPORT_SYMBOL_GPL(mt76_connac_mcu_start_firmware); 20 21 int mt76_connac_mcu_patch_sem_ctrl(struct mt76_dev *dev, bool get) 22 { 23 u32 op = get ? PATCH_SEM_GET : PATCH_SEM_RELEASE; 24 struct { 25 __le32 op; 26 } req = { 27 .op = cpu_to_le32(op), 28 }; 29 30 return mt76_mcu_send_msg(dev, MCU_CMD(PATCH_SEM_CONTROL), 31 &req, sizeof(req), true); 32 } 33 EXPORT_SYMBOL_GPL(mt76_connac_mcu_patch_sem_ctrl); 34 35 int mt76_connac_mcu_start_patch(struct mt76_dev *dev) 36 { 37 struct { 38 u8 check_crc; 39 u8 reserved[3]; 40 } req = { 41 .check_crc = 0, 42 }; 43 44 return mt76_mcu_send_msg(dev, MCU_CMD(PATCH_FINISH_REQ), 45 &req, sizeof(req), true); 46 } 47 EXPORT_SYMBOL_GPL(mt76_connac_mcu_start_patch); 48 49 #define MCU_PATCH_ADDRESS 0x200000 50 51 int mt76_connac_mcu_init_download(struct mt76_dev *dev, u32 addr, u32 len, 52 u32 mode) 53 { 54 struct { 55 __le32 addr; 56 __le32 len; 57 __le32 mode; 58 } req = { 59 .addr = cpu_to_le32(addr), 60 .len = cpu_to_le32(len), 61 .mode = cpu_to_le32(mode), 62 }; 63 int cmd; 64 65 if ((!is_connac_v1(dev) && addr == MCU_PATCH_ADDRESS) || 66 (is_mt7921(dev) && addr == 0x900000)) 67 cmd = MCU_CMD(PATCH_START_REQ); 68 else 69 cmd = MCU_CMD(TARGET_ADDRESS_LEN_REQ); 70 71 return mt76_mcu_send_msg(dev, cmd, &req, sizeof(req), true); 72 } 73 EXPORT_SYMBOL_GPL(mt76_connac_mcu_init_download); 74 75 int mt76_connac_mcu_set_channel_domain(struct mt76_phy *phy) 76 { 77 int len, i, n_max_channels, n_2ch = 0, n_5ch = 0, n_6ch = 0; 78 struct mt76_connac_mcu_channel_domain { 79 u8 alpha2[4]; /* regulatory_request.alpha2 */ 80 u8 bw_2g; /* BW_20_40M 0 81 * BW_20M 1 82 * BW_20_40_80M 2 83 * BW_20_40_80_160M 3 84 * BW_20_40_80_8080M 4 85 */ 86 u8 bw_5g; 87 u8 bw_6g; 88 u8 pad; 89 u8 n_2ch; 90 u8 n_5ch; 91 u8 n_6ch; 92 u8 pad2; 93 } __packed hdr = { 94 .bw_2g = 0, 95 .bw_5g = 3, /* BW_20_40_80_160M */ 96 .bw_6g = 3, 97 }; 98 struct mt76_connac_mcu_chan { 99 __le16 hw_value; 100 __le16 pad; 101 __le32 flags; 102 } __packed channel; 103 struct mt76_dev *dev = phy->dev; 104 struct ieee80211_channel *chan; 105 struct sk_buff *skb; 106 107 n_max_channels = phy->sband_2g.sband.n_channels + 108 phy->sband_5g.sband.n_channels + 109 phy->sband_6g.sband.n_channels; 110 len = sizeof(hdr) + n_max_channels * sizeof(channel); 111 112 skb = mt76_mcu_msg_alloc(dev, NULL, len); 113 if (!skb) 114 return -ENOMEM; 115 116 skb_reserve(skb, sizeof(hdr)); 117 118 for (i = 0; i < phy->sband_2g.sband.n_channels; i++) { 119 chan = &phy->sband_2g.sband.channels[i]; 120 if (chan->flags & IEEE80211_CHAN_DISABLED) 121 continue; 122 123 channel.hw_value = cpu_to_le16(chan->hw_value); 124 channel.flags = cpu_to_le32(chan->flags); 125 channel.pad = 0; 126 127 skb_put_data(skb, &channel, sizeof(channel)); 128 n_2ch++; 129 } 130 for (i = 0; i < phy->sband_5g.sband.n_channels; i++) { 131 chan = &phy->sband_5g.sband.channels[i]; 132 if (chan->flags & IEEE80211_CHAN_DISABLED) 133 continue; 134 135 channel.hw_value = cpu_to_le16(chan->hw_value); 136 channel.flags = cpu_to_le32(chan->flags); 137 channel.pad = 0; 138 139 skb_put_data(skb, &channel, sizeof(channel)); 140 n_5ch++; 141 } 142 for (i = 0; i < phy->sband_6g.sband.n_channels; i++) { 143 chan = &phy->sband_6g.sband.channels[i]; 144 if (chan->flags & IEEE80211_CHAN_DISABLED) 145 continue; 146 147 channel.hw_value = cpu_to_le16(chan->hw_value); 148 channel.flags = cpu_to_le32(chan->flags); 149 channel.pad = 0; 150 151 skb_put_data(skb, &channel, sizeof(channel)); 152 n_6ch++; 153 } 154 155 BUILD_BUG_ON(sizeof(dev->alpha2) > sizeof(hdr.alpha2)); 156 memcpy(hdr.alpha2, dev->alpha2, sizeof(dev->alpha2)); 157 hdr.n_2ch = n_2ch; 158 hdr.n_5ch = n_5ch; 159 hdr.n_6ch = n_6ch; 160 161 memcpy(__skb_push(skb, sizeof(hdr)), &hdr, sizeof(hdr)); 162 163 return mt76_mcu_skb_send_msg(dev, skb, MCU_CE_CMD(SET_CHAN_DOMAIN), 164 false); 165 } 166 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_channel_domain); 167 168 int mt76_connac_mcu_set_mac_enable(struct mt76_dev *dev, int band, bool enable, 169 bool hdr_trans) 170 { 171 struct { 172 u8 enable; 173 u8 band; 174 u8 rsv[2]; 175 } __packed req_mac = { 176 .enable = enable, 177 .band = band, 178 }; 179 180 return mt76_mcu_send_msg(dev, MCU_EXT_CMD(MAC_INIT_CTRL), &req_mac, 181 sizeof(req_mac), true); 182 } 183 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_mac_enable); 184 185 int mt76_connac_mcu_set_vif_ps(struct mt76_dev *dev, struct ieee80211_vif *vif) 186 { 187 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 188 struct { 189 u8 bss_idx; 190 u8 ps_state; /* 0: device awake 191 * 1: static power save 192 * 2: dynamic power saving 193 */ 194 } req = { 195 .bss_idx = mvif->idx, 196 .ps_state = vif->bss_conf.ps ? 2 : 0, 197 }; 198 199 if (vif->type != NL80211_IFTYPE_STATION) 200 return -EOPNOTSUPP; 201 202 return mt76_mcu_send_msg(dev, MCU_CE_CMD(SET_PS_PROFILE), 203 &req, sizeof(req), false); 204 } 205 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_vif_ps); 206 207 int mt76_connac_mcu_set_rts_thresh(struct mt76_dev *dev, u32 val, u8 band) 208 { 209 struct { 210 u8 prot_idx; 211 u8 band; 212 u8 rsv[2]; 213 __le32 len_thresh; 214 __le32 pkt_thresh; 215 } __packed req = { 216 .prot_idx = 1, 217 .band = band, 218 .len_thresh = cpu_to_le32(val), 219 .pkt_thresh = cpu_to_le32(0x2), 220 }; 221 222 return mt76_mcu_send_msg(dev, MCU_EXT_CMD(PROTECT_CTRL), &req, 223 sizeof(req), true); 224 } 225 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_rts_thresh); 226 227 void mt76_connac_mcu_beacon_loss_iter(void *priv, u8 *mac, 228 struct ieee80211_vif *vif) 229 { 230 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 231 struct mt76_connac_beacon_loss_event *event = priv; 232 233 if (mvif->idx != event->bss_idx) 234 return; 235 236 if (!(vif->driver_flags & IEEE80211_VIF_BEACON_FILTER)) 237 return; 238 239 ieee80211_beacon_loss(vif); 240 } 241 EXPORT_SYMBOL_GPL(mt76_connac_mcu_beacon_loss_iter); 242 243 struct tlv * 244 mt76_connac_mcu_add_nested_tlv(struct sk_buff *skb, int tag, int len, 245 void *sta_ntlv, void *sta_wtbl) 246 { 247 struct sta_ntlv_hdr *ntlv_hdr = sta_ntlv; 248 struct tlv *sta_hdr = sta_wtbl; 249 struct tlv *ptlv, tlv = { 250 .tag = cpu_to_le16(tag), 251 .len = cpu_to_le16(len), 252 }; 253 u16 ntlv; 254 255 ptlv = skb_put(skb, len); 256 memcpy(ptlv, &tlv, sizeof(tlv)); 257 258 ntlv = le16_to_cpu(ntlv_hdr->tlv_num); 259 ntlv_hdr->tlv_num = cpu_to_le16(ntlv + 1); 260 261 if (sta_hdr) 262 le16_add_cpu(&sta_hdr->len, len); 263 264 return ptlv; 265 } 266 EXPORT_SYMBOL_GPL(mt76_connac_mcu_add_nested_tlv); 267 268 struct sk_buff * 269 __mt76_connac_mcu_alloc_sta_req(struct mt76_dev *dev, struct mt76_vif *mvif, 270 struct mt76_wcid *wcid, int len) 271 { 272 struct sta_req_hdr hdr = { 273 .bss_idx = mvif->idx, 274 .muar_idx = wcid ? mvif->omac_idx : 0, 275 .is_tlv_append = 1, 276 }; 277 struct sk_buff *skb; 278 279 mt76_connac_mcu_get_wlan_idx(dev, wcid, &hdr.wlan_idx_lo, 280 &hdr.wlan_idx_hi); 281 skb = mt76_mcu_msg_alloc(dev, NULL, len); 282 if (!skb) 283 return ERR_PTR(-ENOMEM); 284 285 skb_put_data(skb, &hdr, sizeof(hdr)); 286 287 return skb; 288 } 289 EXPORT_SYMBOL_GPL(__mt76_connac_mcu_alloc_sta_req); 290 291 struct wtbl_req_hdr * 292 mt76_connac_mcu_alloc_wtbl_req(struct mt76_dev *dev, struct mt76_wcid *wcid, 293 int cmd, void *sta_wtbl, struct sk_buff **skb) 294 { 295 struct tlv *sta_hdr = sta_wtbl; 296 struct wtbl_req_hdr hdr = { 297 .operation = cmd, 298 }; 299 struct sk_buff *nskb = *skb; 300 301 mt76_connac_mcu_get_wlan_idx(dev, wcid, &hdr.wlan_idx_lo, 302 &hdr.wlan_idx_hi); 303 if (!nskb) { 304 nskb = mt76_mcu_msg_alloc(dev, NULL, 305 MT76_CONNAC_WTBL_UPDATE_MAX_SIZE); 306 if (!nskb) 307 return ERR_PTR(-ENOMEM); 308 309 *skb = nskb; 310 } 311 312 if (sta_hdr) 313 le16_add_cpu(&sta_hdr->len, sizeof(hdr)); 314 315 return skb_put_data(nskb, &hdr, sizeof(hdr)); 316 } 317 EXPORT_SYMBOL_GPL(mt76_connac_mcu_alloc_wtbl_req); 318 319 void mt76_connac_mcu_bss_omac_tlv(struct sk_buff *skb, 320 struct ieee80211_vif *vif) 321 { 322 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 323 u8 omac_idx = mvif->omac_idx; 324 struct bss_info_omac *omac; 325 struct tlv *tlv; 326 u32 type = 0; 327 328 switch (vif->type) { 329 case NL80211_IFTYPE_MONITOR: 330 case NL80211_IFTYPE_MESH_POINT: 331 case NL80211_IFTYPE_AP: 332 if (vif->p2p) 333 type = CONNECTION_P2P_GO; 334 else 335 type = CONNECTION_INFRA_AP; 336 break; 337 case NL80211_IFTYPE_STATION: 338 if (vif->p2p) 339 type = CONNECTION_P2P_GC; 340 else 341 type = CONNECTION_INFRA_STA; 342 break; 343 case NL80211_IFTYPE_ADHOC: 344 type = CONNECTION_IBSS_ADHOC; 345 break; 346 default: 347 WARN_ON(1); 348 break; 349 } 350 351 tlv = mt76_connac_mcu_add_tlv(skb, BSS_INFO_OMAC, sizeof(*omac)); 352 353 omac = (struct bss_info_omac *)tlv; 354 omac->conn_type = cpu_to_le32(type); 355 omac->omac_idx = mvif->omac_idx; 356 omac->band_idx = mvif->band_idx; 357 omac->hw_bss_idx = omac_idx > EXT_BSSID_START ? HW_BSSID_0 : omac_idx; 358 } 359 EXPORT_SYMBOL_GPL(mt76_connac_mcu_bss_omac_tlv); 360 361 void mt76_connac_mcu_sta_basic_tlv(struct sk_buff *skb, 362 struct ieee80211_vif *vif, 363 struct ieee80211_sta *sta, 364 bool enable, bool newly) 365 { 366 struct sta_rec_basic *basic; 367 struct tlv *tlv; 368 int conn_type; 369 370 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_BASIC, sizeof(*basic)); 371 372 basic = (struct sta_rec_basic *)tlv; 373 basic->extra_info = cpu_to_le16(EXTRA_INFO_VER); 374 375 if (enable) { 376 if (newly) 377 basic->extra_info |= cpu_to_le16(EXTRA_INFO_NEW); 378 basic->conn_state = CONN_STATE_PORT_SECURE; 379 } else { 380 basic->conn_state = CONN_STATE_DISCONNECT; 381 } 382 383 if (!sta) { 384 basic->conn_type = cpu_to_le32(CONNECTION_INFRA_BC); 385 eth_broadcast_addr(basic->peer_addr); 386 return; 387 } 388 389 switch (vif->type) { 390 case NL80211_IFTYPE_MESH_POINT: 391 case NL80211_IFTYPE_AP: 392 if (vif->p2p) 393 conn_type = CONNECTION_P2P_GC; 394 else 395 conn_type = CONNECTION_INFRA_STA; 396 basic->conn_type = cpu_to_le32(conn_type); 397 basic->aid = cpu_to_le16(sta->aid); 398 break; 399 case NL80211_IFTYPE_STATION: 400 if (vif->p2p) 401 conn_type = CONNECTION_P2P_GO; 402 else 403 conn_type = CONNECTION_INFRA_AP; 404 basic->conn_type = cpu_to_le32(conn_type); 405 basic->aid = cpu_to_le16(vif->bss_conf.aid); 406 break; 407 case NL80211_IFTYPE_ADHOC: 408 basic->conn_type = cpu_to_le32(CONNECTION_IBSS_ADHOC); 409 basic->aid = cpu_to_le16(sta->aid); 410 break; 411 default: 412 WARN_ON(1); 413 break; 414 } 415 416 memcpy(basic->peer_addr, sta->addr, ETH_ALEN); 417 basic->qos = sta->wme; 418 } 419 EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_basic_tlv); 420 421 void mt76_connac_mcu_sta_uapsd(struct sk_buff *skb, struct ieee80211_vif *vif, 422 struct ieee80211_sta *sta) 423 { 424 struct sta_rec_uapsd *uapsd; 425 struct tlv *tlv; 426 427 if (vif->type != NL80211_IFTYPE_AP || !sta->wme) 428 return; 429 430 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_APPS, sizeof(*uapsd)); 431 uapsd = (struct sta_rec_uapsd *)tlv; 432 433 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) { 434 uapsd->dac_map |= BIT(3); 435 uapsd->tac_map |= BIT(3); 436 } 437 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI) { 438 uapsd->dac_map |= BIT(2); 439 uapsd->tac_map |= BIT(2); 440 } 441 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE) { 442 uapsd->dac_map |= BIT(1); 443 uapsd->tac_map |= BIT(1); 444 } 445 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK) { 446 uapsd->dac_map |= BIT(0); 447 uapsd->tac_map |= BIT(0); 448 } 449 uapsd->max_sp = sta->max_sp; 450 } 451 EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_uapsd); 452 453 void mt76_connac_mcu_wtbl_hdr_trans_tlv(struct sk_buff *skb, 454 struct ieee80211_vif *vif, 455 struct mt76_wcid *wcid, 456 void *sta_wtbl, void *wtbl_tlv) 457 { 458 struct wtbl_hdr_trans *htr; 459 struct tlv *tlv; 460 461 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_HDR_TRANS, 462 sizeof(*htr), 463 wtbl_tlv, sta_wtbl); 464 htr = (struct wtbl_hdr_trans *)tlv; 465 htr->no_rx_trans = true; 466 467 if (vif->type == NL80211_IFTYPE_STATION) 468 htr->to_ds = true; 469 else 470 htr->from_ds = true; 471 472 if (!wcid) 473 return; 474 475 htr->no_rx_trans = !test_bit(MT_WCID_FLAG_HDR_TRANS, &wcid->flags); 476 if (test_bit(MT_WCID_FLAG_4ADDR, &wcid->flags)) { 477 htr->to_ds = true; 478 htr->from_ds = true; 479 } 480 } 481 EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_hdr_trans_tlv); 482 483 int mt76_connac_mcu_sta_update_hdr_trans(struct mt76_dev *dev, 484 struct ieee80211_vif *vif, 485 struct mt76_wcid *wcid, int cmd) 486 { 487 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 488 struct wtbl_req_hdr *wtbl_hdr; 489 struct tlv *sta_wtbl; 490 struct sk_buff *skb; 491 492 skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid); 493 if (IS_ERR(skb)) 494 return PTR_ERR(skb); 495 496 sta_wtbl = mt76_connac_mcu_add_tlv(skb, STA_REC_WTBL, 497 sizeof(struct tlv)); 498 499 wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(dev, wcid, WTBL_SET, 500 sta_wtbl, &skb); 501 if (IS_ERR(wtbl_hdr)) 502 return PTR_ERR(wtbl_hdr); 503 504 mt76_connac_mcu_wtbl_hdr_trans_tlv(skb, vif, wcid, sta_wtbl, wtbl_hdr); 505 506 return mt76_mcu_skb_send_msg(dev, skb, cmd, true); 507 } 508 EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_update_hdr_trans); 509 510 int mt76_connac_mcu_wtbl_update_hdr_trans(struct mt76_dev *dev, 511 struct ieee80211_vif *vif, 512 struct ieee80211_sta *sta) 513 { 514 struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv; 515 struct wtbl_req_hdr *wtbl_hdr; 516 struct sk_buff *skb = NULL; 517 518 wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(dev, wcid, WTBL_SET, NULL, 519 &skb); 520 if (IS_ERR(wtbl_hdr)) 521 return PTR_ERR(wtbl_hdr); 522 523 mt76_connac_mcu_wtbl_hdr_trans_tlv(skb, vif, wcid, NULL, wtbl_hdr); 524 525 return mt76_mcu_skb_send_msg(dev, skb, MCU_EXT_CMD(WTBL_UPDATE), true); 526 } 527 EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_update_hdr_trans); 528 529 void mt76_connac_mcu_wtbl_generic_tlv(struct mt76_dev *dev, 530 struct sk_buff *skb, 531 struct ieee80211_vif *vif, 532 struct ieee80211_sta *sta, 533 void *sta_wtbl, void *wtbl_tlv) 534 { 535 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 536 struct wtbl_generic *generic; 537 struct wtbl_rx *rx; 538 struct wtbl_spe *spe; 539 struct tlv *tlv; 540 541 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_GENERIC, 542 sizeof(*generic), 543 wtbl_tlv, sta_wtbl); 544 545 generic = (struct wtbl_generic *)tlv; 546 547 if (sta) { 548 if (vif->type == NL80211_IFTYPE_STATION) 549 generic->partial_aid = cpu_to_le16(vif->bss_conf.aid); 550 else 551 generic->partial_aid = cpu_to_le16(sta->aid); 552 memcpy(generic->peer_addr, sta->addr, ETH_ALEN); 553 generic->muar_idx = mvif->omac_idx; 554 generic->qos = sta->wme; 555 } else { 556 if (!is_connac_v1(dev) && vif->type == NL80211_IFTYPE_STATION) 557 memcpy(generic->peer_addr, vif->bss_conf.bssid, 558 ETH_ALEN); 559 else 560 eth_broadcast_addr(generic->peer_addr); 561 562 generic->muar_idx = 0xe; 563 } 564 565 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_RX, sizeof(*rx), 566 wtbl_tlv, sta_wtbl); 567 568 rx = (struct wtbl_rx *)tlv; 569 rx->rca1 = sta ? vif->type != NL80211_IFTYPE_AP : 1; 570 rx->rca2 = 1; 571 rx->rv = 1; 572 573 if (!is_connac_v1(dev)) 574 return; 575 576 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_SPE, sizeof(*spe), 577 wtbl_tlv, sta_wtbl); 578 spe = (struct wtbl_spe *)tlv; 579 spe->spe_idx = 24; 580 } 581 EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_generic_tlv); 582 583 static void 584 mt76_connac_mcu_sta_amsdu_tlv(struct sk_buff *skb, struct ieee80211_sta *sta, 585 struct ieee80211_vif *vif) 586 { 587 struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv; 588 struct sta_rec_amsdu *amsdu; 589 struct tlv *tlv; 590 591 if (vif->type != NL80211_IFTYPE_AP && 592 vif->type != NL80211_IFTYPE_STATION) 593 return; 594 595 if (!sta->max_amsdu_len) 596 return; 597 598 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HW_AMSDU, sizeof(*amsdu)); 599 amsdu = (struct sta_rec_amsdu *)tlv; 600 amsdu->max_amsdu_num = 8; 601 amsdu->amsdu_en = true; 602 amsdu->max_mpdu_size = sta->max_amsdu_len >= 603 IEEE80211_MAX_MPDU_LEN_VHT_7991; 604 605 wcid->amsdu = true; 606 } 607 608 #define HE_PHY(p, c) u8_get_bits(c, IEEE80211_HE_PHY_##p) 609 #define HE_MAC(m, c) u8_get_bits(c, IEEE80211_HE_MAC_##m) 610 static void 611 mt76_connac_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta) 612 { 613 struct ieee80211_sta_he_cap *he_cap = &sta->he_cap; 614 struct ieee80211_he_cap_elem *elem = &he_cap->he_cap_elem; 615 struct sta_rec_he *he; 616 struct tlv *tlv; 617 u32 cap = 0; 618 619 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HE, sizeof(*he)); 620 621 he = (struct sta_rec_he *)tlv; 622 623 if (elem->mac_cap_info[0] & IEEE80211_HE_MAC_CAP0_HTC_HE) 624 cap |= STA_REC_HE_CAP_HTC; 625 626 if (elem->mac_cap_info[2] & IEEE80211_HE_MAC_CAP2_BSR) 627 cap |= STA_REC_HE_CAP_BSR; 628 629 if (elem->mac_cap_info[3] & IEEE80211_HE_MAC_CAP3_OMI_CONTROL) 630 cap |= STA_REC_HE_CAP_OM; 631 632 if (elem->mac_cap_info[4] & IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU) 633 cap |= STA_REC_HE_CAP_AMSDU_IN_AMPDU; 634 635 if (elem->mac_cap_info[4] & IEEE80211_HE_MAC_CAP4_BQR) 636 cap |= STA_REC_HE_CAP_BQR; 637 638 if (elem->phy_cap_info[0] & 639 (IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_2G | 640 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_5G)) 641 cap |= STA_REC_HE_CAP_BW20_RU242_SUPPORT; 642 643 if (elem->phy_cap_info[1] & 644 IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD) 645 cap |= STA_REC_HE_CAP_LDPC; 646 647 if (elem->phy_cap_info[1] & 648 IEEE80211_HE_PHY_CAP1_HE_LTF_AND_GI_FOR_HE_PPDUS_0_8US) 649 cap |= STA_REC_HE_CAP_SU_PPDU_1LTF_8US_GI; 650 651 if (elem->phy_cap_info[2] & 652 IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US) 653 cap |= STA_REC_HE_CAP_NDP_4LTF_3DOT2MS_GI; 654 655 if (elem->phy_cap_info[2] & 656 IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ) 657 cap |= STA_REC_HE_CAP_LE_EQ_80M_TX_STBC; 658 659 if (elem->phy_cap_info[2] & 660 IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ) 661 cap |= STA_REC_HE_CAP_LE_EQ_80M_RX_STBC; 662 663 if (elem->phy_cap_info[6] & 664 IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE) 665 cap |= STA_REC_HE_CAP_PARTIAL_BW_EXT_RANGE; 666 667 if (elem->phy_cap_info[7] & 668 IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI) 669 cap |= STA_REC_HE_CAP_SU_MU_PPDU_4LTF_8US_GI; 670 671 if (elem->phy_cap_info[7] & 672 IEEE80211_HE_PHY_CAP7_STBC_TX_ABOVE_80MHZ) 673 cap |= STA_REC_HE_CAP_GT_80M_TX_STBC; 674 675 if (elem->phy_cap_info[7] & 676 IEEE80211_HE_PHY_CAP7_STBC_RX_ABOVE_80MHZ) 677 cap |= STA_REC_HE_CAP_GT_80M_RX_STBC; 678 679 if (elem->phy_cap_info[8] & 680 IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI) 681 cap |= STA_REC_HE_CAP_ER_SU_PPDU_4LTF_8US_GI; 682 683 if (elem->phy_cap_info[8] & 684 IEEE80211_HE_PHY_CAP8_HE_ER_SU_1XLTF_AND_08_US_GI) 685 cap |= STA_REC_HE_CAP_ER_SU_PPDU_1LTF_8US_GI; 686 687 if (elem->phy_cap_info[9] & 688 IEEE80211_HE_PHY_CAP9_NON_TRIGGERED_CQI_FEEDBACK) 689 cap |= STA_REC_HE_CAP_TRIG_CQI_FK; 690 691 if (elem->phy_cap_info[9] & 692 IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU) 693 cap |= STA_REC_HE_CAP_TX_1024QAM_UNDER_RU242; 694 695 if (elem->phy_cap_info[9] & 696 IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU) 697 cap |= STA_REC_HE_CAP_RX_1024QAM_UNDER_RU242; 698 699 he->he_cap = cpu_to_le32(cap); 700 701 switch (sta->bandwidth) { 702 case IEEE80211_STA_RX_BW_160: 703 if (elem->phy_cap_info[0] & 704 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) 705 he->max_nss_mcs[CMD_HE_MCS_BW8080] = 706 he_cap->he_mcs_nss_supp.rx_mcs_80p80; 707 708 he->max_nss_mcs[CMD_HE_MCS_BW160] = 709 he_cap->he_mcs_nss_supp.rx_mcs_160; 710 fallthrough; 711 default: 712 he->max_nss_mcs[CMD_HE_MCS_BW80] = 713 he_cap->he_mcs_nss_supp.rx_mcs_80; 714 break; 715 } 716 717 he->t_frame_dur = 718 HE_MAC(CAP1_TF_MAC_PAD_DUR_MASK, elem->mac_cap_info[1]); 719 he->max_ampdu_exp = 720 HE_MAC(CAP3_MAX_AMPDU_LEN_EXP_MASK, elem->mac_cap_info[3]); 721 722 he->bw_set = 723 HE_PHY(CAP0_CHANNEL_WIDTH_SET_MASK, elem->phy_cap_info[0]); 724 he->device_class = 725 HE_PHY(CAP1_DEVICE_CLASS_A, elem->phy_cap_info[1]); 726 he->punc_pream_rx = 727 HE_PHY(CAP1_PREAMBLE_PUNC_RX_MASK, elem->phy_cap_info[1]); 728 729 he->dcm_tx_mode = 730 HE_PHY(CAP3_DCM_MAX_CONST_TX_MASK, elem->phy_cap_info[3]); 731 he->dcm_tx_max_nss = 732 HE_PHY(CAP3_DCM_MAX_TX_NSS_2, elem->phy_cap_info[3]); 733 he->dcm_rx_mode = 734 HE_PHY(CAP3_DCM_MAX_CONST_RX_MASK, elem->phy_cap_info[3]); 735 he->dcm_rx_max_nss = 736 HE_PHY(CAP3_DCM_MAX_RX_NSS_2, elem->phy_cap_info[3]); 737 he->dcm_rx_max_nss = 738 HE_PHY(CAP8_DCM_MAX_RU_MASK, elem->phy_cap_info[8]); 739 740 he->pkt_ext = 2; 741 } 742 743 static u8 744 mt76_connac_get_phy_mode_v2(struct mt76_phy *mphy, struct ieee80211_vif *vif, 745 enum nl80211_band band, struct ieee80211_sta *sta) 746 { 747 struct ieee80211_sta_ht_cap *ht_cap; 748 struct ieee80211_sta_vht_cap *vht_cap; 749 const struct ieee80211_sta_he_cap *he_cap; 750 u8 mode = 0; 751 752 if (sta) { 753 ht_cap = &sta->ht_cap; 754 vht_cap = &sta->vht_cap; 755 he_cap = &sta->he_cap; 756 } else { 757 struct ieee80211_supported_band *sband; 758 759 sband = mphy->hw->wiphy->bands[band]; 760 ht_cap = &sband->ht_cap; 761 vht_cap = &sband->vht_cap; 762 he_cap = ieee80211_get_he_iftype_cap(sband, vif->type); 763 } 764 765 if (band == NL80211_BAND_2GHZ) { 766 mode |= PHY_TYPE_BIT_HR_DSSS | PHY_TYPE_BIT_ERP; 767 768 if (ht_cap->ht_supported) 769 mode |= PHY_TYPE_BIT_HT; 770 771 if (he_cap && he_cap->has_he) 772 mode |= PHY_TYPE_BIT_HE; 773 } else if (band == NL80211_BAND_5GHZ || band == NL80211_BAND_6GHZ) { 774 mode |= PHY_TYPE_BIT_OFDM; 775 776 if (ht_cap->ht_supported) 777 mode |= PHY_TYPE_BIT_HT; 778 779 if (vht_cap->vht_supported) 780 mode |= PHY_TYPE_BIT_VHT; 781 782 if (he_cap && he_cap->has_he) 783 mode |= PHY_TYPE_BIT_HE; 784 } 785 786 return mode; 787 } 788 789 void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb, 790 struct ieee80211_sta *sta, 791 struct ieee80211_vif *vif, 792 u8 rcpi, u8 sta_state) 793 { 794 struct cfg80211_chan_def *chandef = &mphy->chandef; 795 enum nl80211_band band = chandef->chan->band; 796 struct mt76_dev *dev = mphy->dev; 797 struct sta_rec_ra_info *ra_info; 798 struct sta_rec_state *state; 799 struct sta_rec_phy *phy; 800 struct tlv *tlv; 801 u16 supp_rates; 802 803 /* starec ht */ 804 if (sta->ht_cap.ht_supported) { 805 struct sta_rec_ht *ht; 806 807 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HT, sizeof(*ht)); 808 ht = (struct sta_rec_ht *)tlv; 809 ht->ht_cap = cpu_to_le16(sta->ht_cap.cap); 810 } 811 812 /* starec vht */ 813 if (sta->vht_cap.vht_supported) { 814 struct sta_rec_vht *vht; 815 int len; 816 817 len = is_mt7921(dev) ? sizeof(*vht) : sizeof(*vht) - 4; 818 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_VHT, len); 819 vht = (struct sta_rec_vht *)tlv; 820 vht->vht_cap = cpu_to_le32(sta->vht_cap.cap); 821 vht->vht_rx_mcs_map = sta->vht_cap.vht_mcs.rx_mcs_map; 822 vht->vht_tx_mcs_map = sta->vht_cap.vht_mcs.tx_mcs_map; 823 } 824 825 /* starec uapsd */ 826 mt76_connac_mcu_sta_uapsd(skb, vif, sta); 827 828 if (!is_mt7921(dev)) 829 return; 830 831 if (sta->ht_cap.ht_supported || sta->he_cap.has_he) 832 mt76_connac_mcu_sta_amsdu_tlv(skb, sta, vif); 833 834 /* starec he */ 835 if (sta->he_cap.has_he) { 836 mt76_connac_mcu_sta_he_tlv(skb, sta); 837 if (band == NL80211_BAND_6GHZ && 838 sta_state == MT76_STA_INFO_STATE_ASSOC) { 839 struct sta_rec_he_6g_capa *he_6g_capa; 840 841 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HE_6G, 842 sizeof(*he_6g_capa)); 843 he_6g_capa = (struct sta_rec_he_6g_capa *)tlv; 844 he_6g_capa->capa = sta->he_6ghz_capa.capa; 845 } 846 } 847 848 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_PHY, sizeof(*phy)); 849 phy = (struct sta_rec_phy *)tlv; 850 phy->phy_type = mt76_connac_get_phy_mode_v2(mphy, vif, band, sta); 851 phy->basic_rate = cpu_to_le16((u16)vif->bss_conf.basic_rates); 852 phy->rcpi = rcpi; 853 phy->ampdu = FIELD_PREP(IEEE80211_HT_AMPDU_PARM_FACTOR, 854 sta->ht_cap.ampdu_factor) | 855 FIELD_PREP(IEEE80211_HT_AMPDU_PARM_DENSITY, 856 sta->ht_cap.ampdu_density); 857 858 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_RA, sizeof(*ra_info)); 859 ra_info = (struct sta_rec_ra_info *)tlv; 860 861 supp_rates = sta->supp_rates[band]; 862 if (band == NL80211_BAND_2GHZ) 863 supp_rates = FIELD_PREP(RA_LEGACY_OFDM, supp_rates >> 4) | 864 FIELD_PREP(RA_LEGACY_CCK, supp_rates & 0xf); 865 else 866 supp_rates = FIELD_PREP(RA_LEGACY_OFDM, supp_rates); 867 868 ra_info->legacy = cpu_to_le16(supp_rates); 869 870 if (sta->ht_cap.ht_supported) 871 memcpy(ra_info->rx_mcs_bitmask, sta->ht_cap.mcs.rx_mask, 872 HT_MCS_MASK_NUM); 873 874 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_STATE, sizeof(*state)); 875 state = (struct sta_rec_state *)tlv; 876 state->state = sta_state; 877 878 if (sta->vht_cap.vht_supported) { 879 state->vht_opmode = sta->bandwidth; 880 state->vht_opmode |= (sta->rx_nss - 1) << 881 IEEE80211_OPMODE_NOTIF_RX_NSS_SHIFT; 882 } 883 } 884 EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_tlv); 885 886 void mt76_connac_mcu_wtbl_smps_tlv(struct sk_buff *skb, 887 struct ieee80211_sta *sta, 888 void *sta_wtbl, void *wtbl_tlv) 889 { 890 struct wtbl_smps *smps; 891 struct tlv *tlv; 892 893 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_SMPS, sizeof(*smps), 894 wtbl_tlv, sta_wtbl); 895 smps = (struct wtbl_smps *)tlv; 896 smps->smps = (sta->smps_mode == IEEE80211_SMPS_DYNAMIC); 897 } 898 EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_smps_tlv); 899 900 void mt76_connac_mcu_wtbl_ht_tlv(struct mt76_dev *dev, struct sk_buff *skb, 901 struct ieee80211_sta *sta, void *sta_wtbl, 902 void *wtbl_tlv, bool ht_ldpc, bool vht_ldpc) 903 { 904 struct wtbl_ht *ht = NULL; 905 struct tlv *tlv; 906 u32 flags = 0; 907 908 if (sta->ht_cap.ht_supported || sta->he_6ghz_capa.capa) { 909 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_HT, sizeof(*ht), 910 wtbl_tlv, sta_wtbl); 911 ht = (struct wtbl_ht *)tlv; 912 ht->ldpc = ht_ldpc && 913 !!(sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING); 914 915 if (sta->ht_cap.ht_supported) { 916 ht->af = sta->ht_cap.ampdu_factor; 917 ht->mm = sta->ht_cap.ampdu_density; 918 } else { 919 ht->af = le16_get_bits(sta->he_6ghz_capa.capa, 920 IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP); 921 ht->mm = le16_get_bits(sta->he_6ghz_capa.capa, 922 IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START); 923 } 924 925 ht->ht = true; 926 } 927 928 if (sta->vht_cap.vht_supported || sta->he_6ghz_capa.capa) { 929 struct wtbl_vht *vht; 930 u8 af; 931 932 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_VHT, 933 sizeof(*vht), wtbl_tlv, 934 sta_wtbl); 935 vht = (struct wtbl_vht *)tlv; 936 vht->ldpc = vht_ldpc && 937 !!(sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC); 938 vht->vht = true; 939 940 af = FIELD_GET(IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK, 941 sta->vht_cap.cap); 942 if (ht) 943 ht->af = max(ht->af, af); 944 } 945 946 mt76_connac_mcu_wtbl_smps_tlv(skb, sta, sta_wtbl, wtbl_tlv); 947 948 if (is_connac_v1(dev) && sta->ht_cap.ht_supported) { 949 /* sgi */ 950 u32 msk = MT_WTBL_W5_SHORT_GI_20 | MT_WTBL_W5_SHORT_GI_40 | 951 MT_WTBL_W5_SHORT_GI_80 | MT_WTBL_W5_SHORT_GI_160; 952 struct wtbl_raw *raw; 953 954 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_RAW_DATA, 955 sizeof(*raw), wtbl_tlv, 956 sta_wtbl); 957 958 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) 959 flags |= MT_WTBL_W5_SHORT_GI_20; 960 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) 961 flags |= MT_WTBL_W5_SHORT_GI_40; 962 963 if (sta->vht_cap.vht_supported) { 964 if (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80) 965 flags |= MT_WTBL_W5_SHORT_GI_80; 966 if (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_160) 967 flags |= MT_WTBL_W5_SHORT_GI_160; 968 } 969 raw = (struct wtbl_raw *)tlv; 970 raw->val = cpu_to_le32(flags); 971 raw->msk = cpu_to_le32(~msk); 972 raw->wtbl_idx = 1; 973 raw->dw = 5; 974 } 975 } 976 EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_ht_tlv); 977 978 int mt76_connac_mcu_sta_cmd(struct mt76_phy *phy, 979 struct mt76_sta_cmd_info *info) 980 { 981 struct mt76_vif *mvif = (struct mt76_vif *)info->vif->drv_priv; 982 struct mt76_dev *dev = phy->dev; 983 struct wtbl_req_hdr *wtbl_hdr; 984 struct tlv *sta_wtbl; 985 struct sk_buff *skb; 986 987 skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, info->wcid); 988 if (IS_ERR(skb)) 989 return PTR_ERR(skb); 990 991 if (info->sta || !info->offload_fw) 992 mt76_connac_mcu_sta_basic_tlv(skb, info->vif, info->sta, 993 info->enable, info->newly); 994 if (info->sta && info->enable) 995 mt76_connac_mcu_sta_tlv(phy, skb, info->sta, 996 info->vif, info->rcpi, 997 info->state); 998 999 sta_wtbl = mt76_connac_mcu_add_tlv(skb, STA_REC_WTBL, 1000 sizeof(struct tlv)); 1001 1002 wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(dev, info->wcid, 1003 WTBL_RESET_AND_SET, 1004 sta_wtbl, &skb); 1005 if (IS_ERR(wtbl_hdr)) 1006 return PTR_ERR(wtbl_hdr); 1007 1008 if (info->enable) { 1009 mt76_connac_mcu_wtbl_generic_tlv(dev, skb, info->vif, 1010 info->sta, sta_wtbl, 1011 wtbl_hdr); 1012 mt76_connac_mcu_wtbl_hdr_trans_tlv(skb, info->vif, info->wcid, 1013 sta_wtbl, wtbl_hdr); 1014 if (info->sta) 1015 mt76_connac_mcu_wtbl_ht_tlv(dev, skb, info->sta, 1016 sta_wtbl, wtbl_hdr, 1017 true, true); 1018 } 1019 1020 return mt76_mcu_skb_send_msg(dev, skb, info->cmd, true); 1021 } 1022 EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_cmd); 1023 1024 void mt76_connac_mcu_wtbl_ba_tlv(struct mt76_dev *dev, struct sk_buff *skb, 1025 struct ieee80211_ampdu_params *params, 1026 bool enable, bool tx, void *sta_wtbl, 1027 void *wtbl_tlv) 1028 { 1029 struct wtbl_ba *ba; 1030 struct tlv *tlv; 1031 1032 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_BA, sizeof(*ba), 1033 wtbl_tlv, sta_wtbl); 1034 1035 ba = (struct wtbl_ba *)tlv; 1036 ba->tid = params->tid; 1037 1038 if (tx) { 1039 ba->ba_type = MT_BA_TYPE_ORIGINATOR; 1040 ba->sn = enable ? cpu_to_le16(params->ssn) : 0; 1041 ba->ba_winsize = enable ? cpu_to_le16(params->buf_size) : 0; 1042 ba->ba_en = enable; 1043 } else { 1044 memcpy(ba->peer_addr, params->sta->addr, ETH_ALEN); 1045 ba->ba_type = MT_BA_TYPE_RECIPIENT; 1046 ba->rst_ba_tid = params->tid; 1047 ba->rst_ba_sel = RST_BA_MAC_TID_MATCH; 1048 ba->rst_ba_sb = 1; 1049 } 1050 1051 if (!is_connac_v1(dev)) { 1052 ba->ba_winsize = enable ? cpu_to_le16(params->buf_size) : 0; 1053 return; 1054 } 1055 1056 if (enable && tx) { 1057 static const u8 ba_range[] = { 4, 8, 12, 24, 36, 48, 54, 64 }; 1058 int i; 1059 1060 for (i = 7; i > 0; i--) { 1061 if (params->buf_size >= ba_range[i]) 1062 break; 1063 } 1064 ba->ba_winsize_idx = i; 1065 } 1066 } 1067 EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_ba_tlv); 1068 1069 int mt76_connac_mcu_uni_add_dev(struct mt76_phy *phy, 1070 struct ieee80211_vif *vif, 1071 struct mt76_wcid *wcid, 1072 bool enable) 1073 { 1074 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 1075 struct mt76_dev *dev = phy->dev; 1076 struct { 1077 struct { 1078 u8 omac_idx; 1079 u8 band_idx; 1080 __le16 pad; 1081 } __packed hdr; 1082 struct req_tlv { 1083 __le16 tag; 1084 __le16 len; 1085 u8 active; 1086 u8 pad; 1087 u8 omac_addr[ETH_ALEN]; 1088 } __packed tlv; 1089 } dev_req = { 1090 .hdr = { 1091 .omac_idx = mvif->omac_idx, 1092 .band_idx = mvif->band_idx, 1093 }, 1094 .tlv = { 1095 .tag = cpu_to_le16(DEV_INFO_ACTIVE), 1096 .len = cpu_to_le16(sizeof(struct req_tlv)), 1097 .active = enable, 1098 }, 1099 }; 1100 struct { 1101 struct { 1102 u8 bss_idx; 1103 u8 pad[3]; 1104 } __packed hdr; 1105 struct mt76_connac_bss_basic_tlv basic; 1106 } basic_req = { 1107 .hdr = { 1108 .bss_idx = mvif->idx, 1109 }, 1110 .basic = { 1111 .tag = cpu_to_le16(UNI_BSS_INFO_BASIC), 1112 .len = cpu_to_le16(sizeof(struct mt76_connac_bss_basic_tlv)), 1113 .omac_idx = mvif->omac_idx, 1114 .band_idx = mvif->band_idx, 1115 .wmm_idx = mvif->wmm_idx, 1116 .active = enable, 1117 .bmc_tx_wlan_idx = cpu_to_le16(wcid->idx), 1118 .sta_idx = cpu_to_le16(wcid->idx), 1119 .conn_state = 1, 1120 }, 1121 }; 1122 int err, idx, cmd, len; 1123 void *data; 1124 1125 switch (vif->type) { 1126 case NL80211_IFTYPE_MESH_POINT: 1127 case NL80211_IFTYPE_MONITOR: 1128 case NL80211_IFTYPE_AP: 1129 basic_req.basic.conn_type = cpu_to_le32(CONNECTION_INFRA_AP); 1130 break; 1131 case NL80211_IFTYPE_STATION: 1132 basic_req.basic.conn_type = cpu_to_le32(CONNECTION_INFRA_STA); 1133 break; 1134 case NL80211_IFTYPE_ADHOC: 1135 basic_req.basic.conn_type = cpu_to_le32(CONNECTION_IBSS_ADHOC); 1136 break; 1137 default: 1138 WARN_ON(1); 1139 break; 1140 } 1141 1142 idx = mvif->omac_idx > EXT_BSSID_START ? HW_BSSID_0 : mvif->omac_idx; 1143 basic_req.basic.hw_bss_idx = idx; 1144 1145 memcpy(dev_req.tlv.omac_addr, vif->addr, ETH_ALEN); 1146 1147 cmd = enable ? MCU_UNI_CMD(DEV_INFO_UPDATE) : MCU_UNI_CMD(BSS_INFO_UPDATE); 1148 data = enable ? (void *)&dev_req : (void *)&basic_req; 1149 len = enable ? sizeof(dev_req) : sizeof(basic_req); 1150 1151 err = mt76_mcu_send_msg(dev, cmd, data, len, true); 1152 if (err < 0) 1153 return err; 1154 1155 cmd = enable ? MCU_UNI_CMD(BSS_INFO_UPDATE) : MCU_UNI_CMD(DEV_INFO_UPDATE); 1156 data = enable ? (void *)&basic_req : (void *)&dev_req; 1157 len = enable ? sizeof(basic_req) : sizeof(dev_req); 1158 1159 return mt76_mcu_send_msg(dev, cmd, data, len, true); 1160 } 1161 EXPORT_SYMBOL_GPL(mt76_connac_mcu_uni_add_dev); 1162 1163 void mt76_connac_mcu_sta_ba_tlv(struct sk_buff *skb, 1164 struct ieee80211_ampdu_params *params, 1165 bool enable, bool tx) 1166 { 1167 struct sta_rec_ba *ba; 1168 struct tlv *tlv; 1169 1170 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_BA, sizeof(*ba)); 1171 1172 ba = (struct sta_rec_ba *)tlv; 1173 ba->ba_type = tx ? MT_BA_TYPE_ORIGINATOR : MT_BA_TYPE_RECIPIENT; 1174 ba->winsize = cpu_to_le16(params->buf_size); 1175 ba->ssn = cpu_to_le16(params->ssn); 1176 ba->ba_en = enable << params->tid; 1177 ba->amsdu = params->amsdu; 1178 ba->tid = params->tid; 1179 } 1180 EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_ba_tlv); 1181 1182 int mt76_connac_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif, 1183 struct ieee80211_ampdu_params *params, 1184 int cmd, bool enable, bool tx) 1185 { 1186 struct mt76_wcid *wcid = (struct mt76_wcid *)params->sta->drv_priv; 1187 struct wtbl_req_hdr *wtbl_hdr; 1188 struct tlv *sta_wtbl; 1189 struct sk_buff *skb; 1190 int ret; 1191 1192 skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid); 1193 if (IS_ERR(skb)) 1194 return PTR_ERR(skb); 1195 1196 sta_wtbl = mt76_connac_mcu_add_tlv(skb, STA_REC_WTBL, 1197 sizeof(struct tlv)); 1198 1199 wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(dev, wcid, WTBL_SET, 1200 sta_wtbl, &skb); 1201 if (IS_ERR(wtbl_hdr)) 1202 return PTR_ERR(wtbl_hdr); 1203 1204 mt76_connac_mcu_wtbl_ba_tlv(dev, skb, params, enable, tx, sta_wtbl, 1205 wtbl_hdr); 1206 1207 ret = mt76_mcu_skb_send_msg(dev, skb, cmd, true); 1208 if (ret) 1209 return ret; 1210 1211 skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid); 1212 if (IS_ERR(skb)) 1213 return PTR_ERR(skb); 1214 1215 mt76_connac_mcu_sta_ba_tlv(skb, params, enable, tx); 1216 1217 return mt76_mcu_skb_send_msg(dev, skb, cmd, true); 1218 } 1219 EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_ba); 1220 1221 u8 mt76_connac_get_phy_mode(struct mt76_phy *phy, struct ieee80211_vif *vif, 1222 enum nl80211_band band, struct ieee80211_sta *sta) 1223 { 1224 struct mt76_dev *dev = phy->dev; 1225 const struct ieee80211_sta_he_cap *he_cap; 1226 struct ieee80211_sta_vht_cap *vht_cap; 1227 struct ieee80211_sta_ht_cap *ht_cap; 1228 u8 mode = 0; 1229 1230 if (is_connac_v1(dev)) 1231 return 0x38; 1232 1233 if (sta) { 1234 ht_cap = &sta->ht_cap; 1235 vht_cap = &sta->vht_cap; 1236 he_cap = &sta->he_cap; 1237 } else { 1238 struct ieee80211_supported_band *sband; 1239 1240 sband = phy->hw->wiphy->bands[band]; 1241 ht_cap = &sband->ht_cap; 1242 vht_cap = &sband->vht_cap; 1243 he_cap = ieee80211_get_he_iftype_cap(sband, vif->type); 1244 } 1245 1246 if (band == NL80211_BAND_2GHZ) { 1247 mode |= PHY_MODE_B | PHY_MODE_G; 1248 1249 if (ht_cap->ht_supported) 1250 mode |= PHY_MODE_GN; 1251 1252 if (he_cap && he_cap->has_he) 1253 mode |= PHY_MODE_AX_24G; 1254 } else if (band == NL80211_BAND_5GHZ) { 1255 mode |= PHY_MODE_A; 1256 1257 if (ht_cap->ht_supported) 1258 mode |= PHY_MODE_AN; 1259 1260 if (vht_cap->vht_supported) 1261 mode |= PHY_MODE_AC; 1262 1263 if (he_cap && he_cap->has_he) 1264 mode |= PHY_MODE_AX_5G; 1265 } else if (band == NL80211_BAND_6GHZ) { 1266 mode |= PHY_MODE_A | PHY_MODE_AN | 1267 PHY_MODE_AC | PHY_MODE_AX_5G; 1268 } 1269 1270 return mode; 1271 } 1272 EXPORT_SYMBOL_GPL(mt76_connac_get_phy_mode); 1273 1274 const struct ieee80211_sta_he_cap * 1275 mt76_connac_get_he_phy_cap(struct mt76_phy *phy, struct ieee80211_vif *vif) 1276 { 1277 enum nl80211_band band = phy->chandef.chan->band; 1278 struct ieee80211_supported_band *sband; 1279 1280 sband = phy->hw->wiphy->bands[band]; 1281 1282 return ieee80211_get_he_iftype_cap(sband, vif->type); 1283 } 1284 EXPORT_SYMBOL_GPL(mt76_connac_get_he_phy_cap); 1285 1286 #define DEFAULT_HE_PE_DURATION 4 1287 #define DEFAULT_HE_DURATION_RTS_THRES 1023 1288 static void 1289 mt76_connac_mcu_uni_bss_he_tlv(struct mt76_phy *phy, struct ieee80211_vif *vif, 1290 struct tlv *tlv) 1291 { 1292 const struct ieee80211_sta_he_cap *cap; 1293 struct bss_info_uni_he *he; 1294 1295 cap = mt76_connac_get_he_phy_cap(phy, vif); 1296 1297 he = (struct bss_info_uni_he *)tlv; 1298 he->he_pe_duration = vif->bss_conf.htc_trig_based_pkt_ext; 1299 if (!he->he_pe_duration) 1300 he->he_pe_duration = DEFAULT_HE_PE_DURATION; 1301 1302 he->he_rts_thres = cpu_to_le16(vif->bss_conf.frame_time_rts_th); 1303 if (!he->he_rts_thres) 1304 he->he_rts_thres = cpu_to_le16(DEFAULT_HE_DURATION_RTS_THRES); 1305 1306 he->max_nss_mcs[CMD_HE_MCS_BW80] = cap->he_mcs_nss_supp.tx_mcs_80; 1307 he->max_nss_mcs[CMD_HE_MCS_BW160] = cap->he_mcs_nss_supp.tx_mcs_160; 1308 he->max_nss_mcs[CMD_HE_MCS_BW8080] = cap->he_mcs_nss_supp.tx_mcs_80p80; 1309 } 1310 1311 int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy, 1312 struct ieee80211_vif *vif, 1313 struct mt76_wcid *wcid, 1314 bool enable) 1315 { 1316 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 1317 struct cfg80211_chan_def *chandef = &phy->chandef; 1318 int freq1 = chandef->center_freq1, freq2 = chandef->center_freq2; 1319 enum nl80211_band band = chandef->chan->band; 1320 struct mt76_dev *mdev = phy->dev; 1321 struct { 1322 struct { 1323 u8 bss_idx; 1324 u8 pad[3]; 1325 } __packed hdr; 1326 struct mt76_connac_bss_basic_tlv basic; 1327 struct mt76_connac_bss_qos_tlv qos; 1328 } basic_req = { 1329 .hdr = { 1330 .bss_idx = mvif->idx, 1331 }, 1332 .basic = { 1333 .tag = cpu_to_le16(UNI_BSS_INFO_BASIC), 1334 .len = cpu_to_le16(sizeof(struct mt76_connac_bss_basic_tlv)), 1335 .bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int), 1336 .dtim_period = vif->bss_conf.dtim_period, 1337 .omac_idx = mvif->omac_idx, 1338 .band_idx = mvif->band_idx, 1339 .wmm_idx = mvif->wmm_idx, 1340 .active = true, /* keep bss deactivated */ 1341 .phymode = mt76_connac_get_phy_mode(phy, vif, band, NULL), 1342 }, 1343 .qos = { 1344 .tag = cpu_to_le16(UNI_BSS_INFO_QBSS), 1345 .len = cpu_to_le16(sizeof(struct mt76_connac_bss_qos_tlv)), 1346 .qos = vif->bss_conf.qos, 1347 }, 1348 }; 1349 struct { 1350 struct { 1351 u8 bss_idx; 1352 u8 pad[3]; 1353 } __packed hdr; 1354 struct rlm_tlv { 1355 __le16 tag; 1356 __le16 len; 1357 u8 control_channel; 1358 u8 center_chan; 1359 u8 center_chan2; 1360 u8 bw; 1361 u8 tx_streams; 1362 u8 rx_streams; 1363 u8 short_st; 1364 u8 ht_op_info; 1365 u8 sco; 1366 u8 band; 1367 u8 pad[2]; 1368 } __packed rlm; 1369 } __packed rlm_req = { 1370 .hdr = { 1371 .bss_idx = mvif->idx, 1372 }, 1373 .rlm = { 1374 .tag = cpu_to_le16(UNI_BSS_INFO_RLM), 1375 .len = cpu_to_le16(sizeof(struct rlm_tlv)), 1376 .control_channel = chandef->chan->hw_value, 1377 .center_chan = ieee80211_frequency_to_channel(freq1), 1378 .center_chan2 = ieee80211_frequency_to_channel(freq2), 1379 .tx_streams = hweight8(phy->antenna_mask), 1380 .ht_op_info = 4, /* set HT 40M allowed */ 1381 .rx_streams = phy->chainmask, 1382 .short_st = true, 1383 .band = band, 1384 }, 1385 }; 1386 int err, conn_type; 1387 u8 idx, basic_phy; 1388 1389 idx = mvif->omac_idx > EXT_BSSID_START ? HW_BSSID_0 : mvif->omac_idx; 1390 basic_req.basic.hw_bss_idx = idx; 1391 if (band == NL80211_BAND_6GHZ) 1392 basic_req.basic.phymode_ext = PHY_MODE_AX_6G; 1393 1394 basic_phy = mt76_connac_get_phy_mode_v2(phy, vif, band, NULL); 1395 basic_req.basic.nonht_basic_phy = cpu_to_le16(basic_phy); 1396 1397 switch (vif->type) { 1398 case NL80211_IFTYPE_MESH_POINT: 1399 case NL80211_IFTYPE_AP: 1400 if (vif->p2p) 1401 conn_type = CONNECTION_P2P_GO; 1402 else 1403 conn_type = CONNECTION_INFRA_AP; 1404 basic_req.basic.conn_type = cpu_to_le32(conn_type); 1405 break; 1406 case NL80211_IFTYPE_STATION: 1407 if (vif->p2p) 1408 conn_type = CONNECTION_P2P_GC; 1409 else 1410 conn_type = CONNECTION_INFRA_STA; 1411 basic_req.basic.conn_type = cpu_to_le32(conn_type); 1412 break; 1413 case NL80211_IFTYPE_ADHOC: 1414 basic_req.basic.conn_type = cpu_to_le32(CONNECTION_IBSS_ADHOC); 1415 break; 1416 default: 1417 WARN_ON(1); 1418 break; 1419 } 1420 1421 memcpy(basic_req.basic.bssid, vif->bss_conf.bssid, ETH_ALEN); 1422 basic_req.basic.bmc_tx_wlan_idx = cpu_to_le16(wcid->idx); 1423 basic_req.basic.sta_idx = cpu_to_le16(wcid->idx); 1424 basic_req.basic.conn_state = !enable; 1425 1426 err = mt76_mcu_send_msg(mdev, MCU_UNI_CMD(BSS_INFO_UPDATE), &basic_req, 1427 sizeof(basic_req), true); 1428 if (err < 0) 1429 return err; 1430 1431 if (vif->bss_conf.he_support) { 1432 struct { 1433 struct { 1434 u8 bss_idx; 1435 u8 pad[3]; 1436 } __packed hdr; 1437 struct bss_info_uni_he he; 1438 struct bss_info_uni_bss_color bss_color; 1439 } he_req = { 1440 .hdr = { 1441 .bss_idx = mvif->idx, 1442 }, 1443 .he = { 1444 .tag = cpu_to_le16(UNI_BSS_INFO_HE_BASIC), 1445 .len = cpu_to_le16(sizeof(struct bss_info_uni_he)), 1446 }, 1447 .bss_color = { 1448 .tag = cpu_to_le16(UNI_BSS_INFO_BSS_COLOR), 1449 .len = cpu_to_le16(sizeof(struct bss_info_uni_bss_color)), 1450 .enable = 0, 1451 .bss_color = 0, 1452 }, 1453 }; 1454 1455 if (enable) { 1456 he_req.bss_color.enable = 1457 vif->bss_conf.he_bss_color.enabled; 1458 he_req.bss_color.bss_color = 1459 vif->bss_conf.he_bss_color.color; 1460 } 1461 1462 mt76_connac_mcu_uni_bss_he_tlv(phy, vif, 1463 (struct tlv *)&he_req.he); 1464 err = mt76_mcu_send_msg(mdev, MCU_UNI_CMD(BSS_INFO_UPDATE), 1465 &he_req, sizeof(he_req), true); 1466 if (err < 0) 1467 return err; 1468 } 1469 1470 switch (chandef->width) { 1471 case NL80211_CHAN_WIDTH_40: 1472 rlm_req.rlm.bw = CMD_CBW_40MHZ; 1473 break; 1474 case NL80211_CHAN_WIDTH_80: 1475 rlm_req.rlm.bw = CMD_CBW_80MHZ; 1476 break; 1477 case NL80211_CHAN_WIDTH_80P80: 1478 rlm_req.rlm.bw = CMD_CBW_8080MHZ; 1479 break; 1480 case NL80211_CHAN_WIDTH_160: 1481 rlm_req.rlm.bw = CMD_CBW_160MHZ; 1482 break; 1483 case NL80211_CHAN_WIDTH_5: 1484 rlm_req.rlm.bw = CMD_CBW_5MHZ; 1485 break; 1486 case NL80211_CHAN_WIDTH_10: 1487 rlm_req.rlm.bw = CMD_CBW_10MHZ; 1488 break; 1489 case NL80211_CHAN_WIDTH_20_NOHT: 1490 case NL80211_CHAN_WIDTH_20: 1491 default: 1492 rlm_req.rlm.bw = CMD_CBW_20MHZ; 1493 rlm_req.rlm.ht_op_info = 0; 1494 break; 1495 } 1496 1497 if (rlm_req.rlm.control_channel < rlm_req.rlm.center_chan) 1498 rlm_req.rlm.sco = 1; /* SCA */ 1499 else if (rlm_req.rlm.control_channel > rlm_req.rlm.center_chan) 1500 rlm_req.rlm.sco = 3; /* SCB */ 1501 1502 return mt76_mcu_send_msg(mdev, MCU_UNI_CMD(BSS_INFO_UPDATE), &rlm_req, 1503 sizeof(rlm_req), true); 1504 } 1505 EXPORT_SYMBOL_GPL(mt76_connac_mcu_uni_add_bss); 1506 1507 #define MT76_CONNAC_SCAN_CHANNEL_TIME 60 1508 int mt76_connac_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif, 1509 struct ieee80211_scan_request *scan_req) 1510 { 1511 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 1512 struct cfg80211_scan_request *sreq = &scan_req->req; 1513 int n_ssids = 0, err, i, duration; 1514 int ext_channels_num = max_t(int, sreq->n_channels - 32, 0); 1515 struct ieee80211_channel **scan_list = sreq->channels; 1516 struct mt76_dev *mdev = phy->dev; 1517 struct mt76_connac_mcu_scan_channel *chan; 1518 struct mt76_connac_hw_scan_req *req; 1519 struct sk_buff *skb; 1520 1521 skb = mt76_mcu_msg_alloc(mdev, NULL, sizeof(*req)); 1522 if (!skb) 1523 return -ENOMEM; 1524 1525 set_bit(MT76_HW_SCANNING, &phy->state); 1526 mvif->scan_seq_num = (mvif->scan_seq_num + 1) & 0x7f; 1527 1528 req = (struct mt76_connac_hw_scan_req *)skb_put(skb, sizeof(*req)); 1529 1530 req->seq_num = mvif->scan_seq_num | mvif->band_idx << 7; 1531 req->bss_idx = mvif->idx; 1532 req->scan_type = sreq->n_ssids ? 1 : 0; 1533 req->probe_req_num = sreq->n_ssids ? 2 : 0; 1534 req->version = 1; 1535 1536 for (i = 0; i < sreq->n_ssids; i++) { 1537 if (!sreq->ssids[i].ssid_len) 1538 continue; 1539 1540 req->ssids[i].ssid_len = cpu_to_le32(sreq->ssids[i].ssid_len); 1541 memcpy(req->ssids[i].ssid, sreq->ssids[i].ssid, 1542 sreq->ssids[i].ssid_len); 1543 n_ssids++; 1544 } 1545 req->ssid_type = n_ssids ? BIT(2) : BIT(0); 1546 req->ssid_type_ext = n_ssids ? BIT(0) : 0; 1547 req->ssids_num = n_ssids; 1548 1549 duration = is_mt7921(phy->dev) ? 0 : MT76_CONNAC_SCAN_CHANNEL_TIME; 1550 /* increase channel time for passive scan */ 1551 if (!sreq->n_ssids) 1552 duration *= 2; 1553 req->timeout_value = cpu_to_le16(sreq->n_channels * duration); 1554 req->channel_min_dwell_time = cpu_to_le16(duration); 1555 req->channel_dwell_time = cpu_to_le16(duration); 1556 1557 req->channels_num = min_t(u8, sreq->n_channels, 32); 1558 req->ext_channels_num = min_t(u8, ext_channels_num, 32); 1559 for (i = 0; i < req->channels_num + req->ext_channels_num; i++) { 1560 if (i >= 32) 1561 chan = &req->ext_channels[i - 32]; 1562 else 1563 chan = &req->channels[i]; 1564 1565 switch (scan_list[i]->band) { 1566 case NL80211_BAND_2GHZ: 1567 chan->band = 1; 1568 break; 1569 case NL80211_BAND_6GHZ: 1570 chan->band = 3; 1571 break; 1572 default: 1573 chan->band = 2; 1574 break; 1575 } 1576 chan->channel_num = scan_list[i]->hw_value; 1577 } 1578 req->channel_type = sreq->n_channels ? 4 : 0; 1579 1580 if (sreq->ie_len > 0) { 1581 memcpy(req->ies, sreq->ie, sreq->ie_len); 1582 req->ies_len = cpu_to_le16(sreq->ie_len); 1583 } 1584 1585 if (is_mt7921(phy->dev)) 1586 req->scan_func |= SCAN_FUNC_SPLIT_SCAN; 1587 1588 memcpy(req->bssid, sreq->bssid, ETH_ALEN); 1589 if (sreq->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) { 1590 get_random_mask_addr(req->random_mac, sreq->mac_addr, 1591 sreq->mac_addr_mask); 1592 req->scan_func |= SCAN_FUNC_RANDOM_MAC; 1593 } 1594 1595 err = mt76_mcu_skb_send_msg(mdev, skb, MCU_CE_CMD(START_HW_SCAN), 1596 false); 1597 if (err < 0) 1598 clear_bit(MT76_HW_SCANNING, &phy->state); 1599 1600 return err; 1601 } 1602 EXPORT_SYMBOL_GPL(mt76_connac_mcu_hw_scan); 1603 1604 int mt76_connac_mcu_cancel_hw_scan(struct mt76_phy *phy, 1605 struct ieee80211_vif *vif) 1606 { 1607 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 1608 struct { 1609 u8 seq_num; 1610 u8 is_ext_channel; 1611 u8 rsv[2]; 1612 } __packed req = { 1613 .seq_num = mvif->scan_seq_num, 1614 }; 1615 1616 if (test_and_clear_bit(MT76_HW_SCANNING, &phy->state)) { 1617 struct cfg80211_scan_info info = { 1618 .aborted = true, 1619 }; 1620 1621 ieee80211_scan_completed(phy->hw, &info); 1622 } 1623 1624 return mt76_mcu_send_msg(phy->dev, MCU_CE_CMD(CANCEL_HW_SCAN), 1625 &req, sizeof(req), false); 1626 } 1627 EXPORT_SYMBOL_GPL(mt76_connac_mcu_cancel_hw_scan); 1628 1629 int mt76_connac_mcu_sched_scan_req(struct mt76_phy *phy, 1630 struct ieee80211_vif *vif, 1631 struct cfg80211_sched_scan_request *sreq) 1632 { 1633 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 1634 struct ieee80211_channel **scan_list = sreq->channels; 1635 struct mt76_connac_mcu_scan_channel *chan; 1636 struct mt76_connac_sched_scan_req *req; 1637 struct mt76_dev *mdev = phy->dev; 1638 struct cfg80211_match_set *match; 1639 struct cfg80211_ssid *ssid; 1640 struct sk_buff *skb; 1641 int i; 1642 1643 skb = mt76_mcu_msg_alloc(mdev, NULL, sizeof(*req) + sreq->ie_len); 1644 if (!skb) 1645 return -ENOMEM; 1646 1647 mvif->scan_seq_num = (mvif->scan_seq_num + 1) & 0x7f; 1648 1649 req = (struct mt76_connac_sched_scan_req *)skb_put(skb, sizeof(*req)); 1650 req->version = 1; 1651 req->seq_num = mvif->scan_seq_num | mvif->band_idx << 7; 1652 1653 if (sreq->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) { 1654 u8 *addr = is_mt7663(phy->dev) ? req->mt7663.random_mac 1655 : req->mt7921.random_mac; 1656 1657 req->scan_func = 1; 1658 get_random_mask_addr(addr, sreq->mac_addr, 1659 sreq->mac_addr_mask); 1660 } 1661 if (is_mt7921(phy->dev)) { 1662 req->mt7921.bss_idx = mvif->idx; 1663 req->mt7921.delay = cpu_to_le32(sreq->delay); 1664 } 1665 1666 req->ssids_num = sreq->n_ssids; 1667 for (i = 0; i < req->ssids_num; i++) { 1668 ssid = &sreq->ssids[i]; 1669 memcpy(req->ssids[i].ssid, ssid->ssid, ssid->ssid_len); 1670 req->ssids[i].ssid_len = cpu_to_le32(ssid->ssid_len); 1671 } 1672 1673 req->match_num = sreq->n_match_sets; 1674 for (i = 0; i < req->match_num; i++) { 1675 match = &sreq->match_sets[i]; 1676 memcpy(req->match[i].ssid, match->ssid.ssid, 1677 match->ssid.ssid_len); 1678 req->match[i].rssi_th = cpu_to_le32(match->rssi_thold); 1679 req->match[i].ssid_len = match->ssid.ssid_len; 1680 } 1681 1682 req->channel_type = sreq->n_channels ? 4 : 0; 1683 req->channels_num = min_t(u8, sreq->n_channels, 64); 1684 for (i = 0; i < req->channels_num; i++) { 1685 chan = &req->channels[i]; 1686 1687 switch (scan_list[i]->band) { 1688 case NL80211_BAND_2GHZ: 1689 chan->band = 1; 1690 break; 1691 case NL80211_BAND_6GHZ: 1692 chan->band = 3; 1693 break; 1694 default: 1695 chan->band = 2; 1696 break; 1697 } 1698 chan->channel_num = scan_list[i]->hw_value; 1699 } 1700 1701 req->intervals_num = sreq->n_scan_plans; 1702 for (i = 0; i < req->intervals_num; i++) 1703 req->intervals[i] = cpu_to_le16(sreq->scan_plans[i].interval); 1704 1705 if (sreq->ie_len > 0) { 1706 req->ie_len = cpu_to_le16(sreq->ie_len); 1707 memcpy(skb_put(skb, sreq->ie_len), sreq->ie, sreq->ie_len); 1708 } 1709 1710 return mt76_mcu_skb_send_msg(mdev, skb, MCU_CE_CMD(SCHED_SCAN_REQ), 1711 false); 1712 } 1713 EXPORT_SYMBOL_GPL(mt76_connac_mcu_sched_scan_req); 1714 1715 int mt76_connac_mcu_sched_scan_enable(struct mt76_phy *phy, 1716 struct ieee80211_vif *vif, 1717 bool enable) 1718 { 1719 struct { 1720 u8 active; /* 0: enabled 1: disabled */ 1721 u8 rsv[3]; 1722 } __packed req = { 1723 .active = !enable, 1724 }; 1725 1726 if (enable) 1727 set_bit(MT76_HW_SCHED_SCANNING, &phy->state); 1728 else 1729 clear_bit(MT76_HW_SCHED_SCANNING, &phy->state); 1730 1731 return mt76_mcu_send_msg(phy->dev, MCU_CE_CMD(SCHED_SCAN_ENABLE), 1732 &req, sizeof(req), false); 1733 } 1734 EXPORT_SYMBOL_GPL(mt76_connac_mcu_sched_scan_enable); 1735 1736 int mt76_connac_mcu_chip_config(struct mt76_dev *dev) 1737 { 1738 struct mt76_connac_config req = { 1739 .resp_type = 0, 1740 }; 1741 1742 memcpy(req.data, "assert", 7); 1743 1744 return mt76_mcu_send_msg(dev, MCU_CE_CMD(CHIP_CONFIG), 1745 &req, sizeof(req), false); 1746 } 1747 EXPORT_SYMBOL_GPL(mt76_connac_mcu_chip_config); 1748 1749 int mt76_connac_mcu_set_deep_sleep(struct mt76_dev *dev, bool enable) 1750 { 1751 struct mt76_connac_config req = { 1752 .resp_type = 0, 1753 }; 1754 1755 snprintf(req.data, sizeof(req.data), "KeepFullPwr %d", !enable); 1756 1757 return mt76_mcu_send_msg(dev, MCU_CE_CMD(CHIP_CONFIG), 1758 &req, sizeof(req), false); 1759 } 1760 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_deep_sleep); 1761 1762 int mt76_connac_sta_state_dp(struct mt76_dev *dev, 1763 enum ieee80211_sta_state old_state, 1764 enum ieee80211_sta_state new_state) 1765 { 1766 if ((old_state == IEEE80211_STA_ASSOC && 1767 new_state == IEEE80211_STA_AUTHORIZED) || 1768 (old_state == IEEE80211_STA_NONE && 1769 new_state == IEEE80211_STA_NOTEXIST)) 1770 mt76_connac_mcu_set_deep_sleep(dev, true); 1771 1772 if ((old_state == IEEE80211_STA_NOTEXIST && 1773 new_state == IEEE80211_STA_NONE) || 1774 (old_state == IEEE80211_STA_AUTHORIZED && 1775 new_state == IEEE80211_STA_ASSOC)) 1776 mt76_connac_mcu_set_deep_sleep(dev, false); 1777 1778 return 0; 1779 } 1780 EXPORT_SYMBOL_GPL(mt76_connac_sta_state_dp); 1781 1782 void mt76_connac_mcu_coredump_event(struct mt76_dev *dev, struct sk_buff *skb, 1783 struct mt76_connac_coredump *coredump) 1784 { 1785 spin_lock_bh(&dev->lock); 1786 __skb_queue_tail(&coredump->msg_list, skb); 1787 spin_unlock_bh(&dev->lock); 1788 1789 coredump->last_activity = jiffies; 1790 1791 queue_delayed_work(dev->wq, &coredump->work, 1792 MT76_CONNAC_COREDUMP_TIMEOUT); 1793 } 1794 EXPORT_SYMBOL_GPL(mt76_connac_mcu_coredump_event); 1795 1796 static void mt76_connac_mcu_parse_tx_resource(struct mt76_dev *dev, 1797 struct sk_buff *skb) 1798 { 1799 struct mt76_sdio *sdio = &dev->sdio; 1800 struct mt76_connac_tx_resource { 1801 __le32 version; 1802 __le32 pse_data_quota; 1803 __le32 pse_mcu_quota; 1804 __le32 ple_data_quota; 1805 __le32 ple_mcu_quota; 1806 __le16 pse_page_size; 1807 __le16 ple_page_size; 1808 u8 pp_padding; 1809 u8 pad[3]; 1810 } __packed * tx_res; 1811 1812 tx_res = (struct mt76_connac_tx_resource *)skb->data; 1813 sdio->sched.pse_data_quota = le32_to_cpu(tx_res->pse_data_quota); 1814 sdio->sched.pse_mcu_quota = le32_to_cpu(tx_res->pse_mcu_quota); 1815 sdio->sched.ple_data_quota = le32_to_cpu(tx_res->ple_data_quota); 1816 sdio->sched.pse_page_size = le16_to_cpu(tx_res->pse_page_size); 1817 sdio->sched.deficit = tx_res->pp_padding; 1818 } 1819 1820 static void mt76_connac_mcu_parse_phy_cap(struct mt76_dev *dev, 1821 struct sk_buff *skb) 1822 { 1823 struct mt76_connac_phy_cap { 1824 u8 ht; 1825 u8 vht; 1826 u8 _5g; 1827 u8 max_bw; 1828 u8 nss; 1829 u8 dbdc; 1830 u8 tx_ldpc; 1831 u8 rx_ldpc; 1832 u8 tx_stbc; 1833 u8 rx_stbc; 1834 u8 hw_path; 1835 u8 he; 1836 } __packed * cap; 1837 1838 enum { 1839 WF0_24G, 1840 WF0_5G 1841 }; 1842 1843 cap = (struct mt76_connac_phy_cap *)skb->data; 1844 1845 dev->phy.antenna_mask = BIT(cap->nss) - 1; 1846 dev->phy.chainmask = dev->phy.antenna_mask; 1847 dev->phy.cap.has_2ghz = cap->hw_path & BIT(WF0_24G); 1848 dev->phy.cap.has_5ghz = cap->hw_path & BIT(WF0_5G); 1849 } 1850 1851 int mt76_connac_mcu_get_nic_capability(struct mt76_phy *phy) 1852 { 1853 struct mt76_connac_cap_hdr { 1854 __le16 n_element; 1855 u8 rsv[2]; 1856 } __packed * hdr; 1857 struct sk_buff *skb; 1858 int ret, i; 1859 1860 ret = mt76_mcu_send_and_get_msg(phy->dev, MCU_CE_CMD(GET_NIC_CAPAB), 1861 NULL, 0, true, &skb); 1862 if (ret) 1863 return ret; 1864 1865 hdr = (struct mt76_connac_cap_hdr *)skb->data; 1866 if (skb->len < sizeof(*hdr)) { 1867 ret = -EINVAL; 1868 goto out; 1869 } 1870 1871 skb_pull(skb, sizeof(*hdr)); 1872 1873 for (i = 0; i < le16_to_cpu(hdr->n_element); i++) { 1874 struct tlv_hdr { 1875 __le32 type; 1876 __le32 len; 1877 } __packed * tlv = (struct tlv_hdr *)skb->data; 1878 int len; 1879 1880 if (skb->len < sizeof(*tlv)) 1881 break; 1882 1883 skb_pull(skb, sizeof(*tlv)); 1884 1885 len = le32_to_cpu(tlv->len); 1886 if (skb->len < len) 1887 break; 1888 1889 switch (le32_to_cpu(tlv->type)) { 1890 case MT_NIC_CAP_6G: 1891 phy->cap.has_6ghz = skb->data[0]; 1892 break; 1893 case MT_NIC_CAP_MAC_ADDR: 1894 memcpy(phy->macaddr, (void *)skb->data, ETH_ALEN); 1895 break; 1896 case MT_NIC_CAP_PHY: 1897 mt76_connac_mcu_parse_phy_cap(phy->dev, skb); 1898 break; 1899 case MT_NIC_CAP_TX_RESOURCE: 1900 if (mt76_is_sdio(phy->dev)) 1901 mt76_connac_mcu_parse_tx_resource(phy->dev, 1902 skb); 1903 break; 1904 default: 1905 break; 1906 } 1907 skb_pull(skb, len); 1908 } 1909 out: 1910 dev_kfree_skb(skb); 1911 1912 return ret; 1913 } 1914 EXPORT_SYMBOL_GPL(mt76_connac_mcu_get_nic_capability); 1915 1916 static void 1917 mt76_connac_mcu_build_sku(struct mt76_dev *dev, s8 *sku, 1918 struct mt76_power_limits *limits, 1919 enum nl80211_band band) 1920 { 1921 int max_power = is_mt7921(dev) ? 127 : 63; 1922 int i, offset = sizeof(limits->cck); 1923 1924 memset(sku, max_power, MT_SKU_POWER_LIMIT); 1925 1926 if (band == NL80211_BAND_2GHZ) { 1927 /* cck */ 1928 memcpy(sku, limits->cck, sizeof(limits->cck)); 1929 } 1930 1931 /* ofdm */ 1932 memcpy(&sku[offset], limits->ofdm, sizeof(limits->ofdm)); 1933 offset += sizeof(limits->ofdm); 1934 1935 /* ht */ 1936 for (i = 0; i < 2; i++) { 1937 memcpy(&sku[offset], limits->mcs[i], 8); 1938 offset += 8; 1939 } 1940 sku[offset++] = limits->mcs[0][0]; 1941 1942 /* vht */ 1943 for (i = 0; i < ARRAY_SIZE(limits->mcs); i++) { 1944 memcpy(&sku[offset], limits->mcs[i], 1945 ARRAY_SIZE(limits->mcs[i])); 1946 offset += 12; 1947 } 1948 1949 if (!is_mt7921(dev)) 1950 return; 1951 1952 /* he */ 1953 for (i = 0; i < ARRAY_SIZE(limits->ru); i++) { 1954 memcpy(&sku[offset], limits->ru[i], ARRAY_SIZE(limits->ru[i])); 1955 offset += ARRAY_SIZE(limits->ru[i]); 1956 } 1957 } 1958 1959 static s8 mt76_connac_get_ch_power(struct mt76_phy *phy, 1960 struct ieee80211_channel *chan, 1961 s8 target_power) 1962 { 1963 struct mt76_dev *dev = phy->dev; 1964 struct ieee80211_supported_band *sband; 1965 int i; 1966 1967 switch (chan->band) { 1968 case NL80211_BAND_2GHZ: 1969 sband = &phy->sband_2g.sband; 1970 break; 1971 case NL80211_BAND_5GHZ: 1972 sband = &phy->sband_5g.sband; 1973 break; 1974 case NL80211_BAND_6GHZ: 1975 sband = &phy->sband_6g.sband; 1976 break; 1977 default: 1978 return target_power; 1979 } 1980 1981 for (i = 0; i < sband->n_channels; i++) { 1982 struct ieee80211_channel *ch = &sband->channels[i]; 1983 1984 if (ch->hw_value == chan->hw_value) { 1985 if (!(ch->flags & IEEE80211_CHAN_DISABLED)) { 1986 int power = 2 * ch->max_reg_power; 1987 1988 if (is_mt7663(dev) && (power > 63 || power < -64)) 1989 power = 63; 1990 target_power = min_t(s8, power, target_power); 1991 } 1992 break; 1993 } 1994 } 1995 1996 return target_power; 1997 } 1998 1999 static int 2000 mt76_connac_mcu_rate_txpower_band(struct mt76_phy *phy, 2001 enum nl80211_band band) 2002 { 2003 struct mt76_dev *dev = phy->dev; 2004 int sku_len, batch_len = is_mt7921(dev) ? 8 : 16; 2005 static const u8 chan_list_2ghz[] = { 2006 1, 2, 3, 4, 5, 6, 7, 2007 8, 9, 10, 11, 12, 13, 14 2008 }; 2009 static const u8 chan_list_5ghz[] = { 2010 36, 38, 40, 42, 44, 46, 48, 2011 50, 52, 54, 56, 58, 60, 62, 2012 64, 100, 102, 104, 106, 108, 110, 2013 112, 114, 116, 118, 120, 122, 124, 2014 126, 128, 132, 134, 136, 138, 140, 2015 142, 144, 149, 151, 153, 155, 157, 2016 159, 161, 165 2017 }; 2018 static const u8 chan_list_6ghz[] = { 2019 1, 3, 5, 7, 9, 11, 13, 2020 15, 17, 19, 21, 23, 25, 27, 2021 29, 33, 35, 37, 39, 41, 43, 2022 45, 47, 49, 51, 53, 55, 57, 2023 59, 61, 65, 67, 69, 71, 73, 2024 75, 77, 79, 81, 83, 85, 87, 2025 89, 91, 93, 97, 99, 101, 103, 2026 105, 107, 109, 111, 113, 115, 117, 2027 119, 121, 123, 125, 129, 131, 133, 2028 135, 137, 139, 141, 143, 145, 147, 2029 149, 151, 153, 155, 157, 161, 163, 2030 165, 167, 169, 171, 173, 175, 177, 2031 179, 181, 183, 185, 187, 189, 193, 2032 195, 197, 199, 201, 203, 205, 207, 2033 209, 211, 213, 215, 217, 219, 221, 2034 225, 227, 229, 233 2035 }; 2036 int i, n_chan, batch_size, idx = 0, tx_power, last_ch; 2037 struct mt76_connac_sku_tlv sku_tlbv; 2038 struct mt76_power_limits limits; 2039 const u8 *ch_list; 2040 2041 sku_len = is_mt7921(dev) ? sizeof(sku_tlbv) : sizeof(sku_tlbv) - 92; 2042 tx_power = 2 * phy->hw->conf.power_level; 2043 if (!tx_power) 2044 tx_power = 127; 2045 2046 if (band == NL80211_BAND_2GHZ) { 2047 n_chan = ARRAY_SIZE(chan_list_2ghz); 2048 ch_list = chan_list_2ghz; 2049 } else if (band == NL80211_BAND_6GHZ) { 2050 n_chan = ARRAY_SIZE(chan_list_6ghz); 2051 ch_list = chan_list_6ghz; 2052 } else { 2053 n_chan = ARRAY_SIZE(chan_list_5ghz); 2054 ch_list = chan_list_5ghz; 2055 } 2056 batch_size = DIV_ROUND_UP(n_chan, batch_len); 2057 2058 if (phy->cap.has_6ghz) 2059 last_ch = chan_list_6ghz[ARRAY_SIZE(chan_list_6ghz) - 1]; 2060 else if (phy->cap.has_5ghz) 2061 last_ch = chan_list_5ghz[ARRAY_SIZE(chan_list_5ghz) - 1]; 2062 else 2063 last_ch = chan_list_2ghz[ARRAY_SIZE(chan_list_2ghz) - 1]; 2064 2065 for (i = 0; i < batch_size; i++) { 2066 struct mt76_connac_tx_power_limit_tlv tx_power_tlv = {}; 2067 int j, err, msg_len, num_ch; 2068 struct sk_buff *skb; 2069 2070 num_ch = i == batch_size - 1 ? n_chan % batch_len : batch_len; 2071 msg_len = sizeof(tx_power_tlv) + num_ch * sizeof(sku_tlbv); 2072 skb = mt76_mcu_msg_alloc(dev, NULL, msg_len); 2073 if (!skb) 2074 return -ENOMEM; 2075 2076 skb_reserve(skb, sizeof(tx_power_tlv)); 2077 2078 BUILD_BUG_ON(sizeof(dev->alpha2) > sizeof(tx_power_tlv.alpha2)); 2079 memcpy(tx_power_tlv.alpha2, dev->alpha2, sizeof(dev->alpha2)); 2080 tx_power_tlv.n_chan = num_ch; 2081 2082 switch (band) { 2083 case NL80211_BAND_2GHZ: 2084 tx_power_tlv.band = 1; 2085 break; 2086 case NL80211_BAND_6GHZ: 2087 tx_power_tlv.band = 3; 2088 break; 2089 default: 2090 tx_power_tlv.band = 2; 2091 break; 2092 } 2093 2094 for (j = 0; j < num_ch; j++, idx++) { 2095 struct ieee80211_channel chan = { 2096 .hw_value = ch_list[idx], 2097 .band = band, 2098 }; 2099 s8 reg_power, sar_power; 2100 2101 reg_power = mt76_connac_get_ch_power(phy, &chan, 2102 tx_power); 2103 sar_power = mt76_get_sar_power(phy, &chan, reg_power); 2104 2105 mt76_get_rate_power_limits(phy, &chan, &limits, 2106 sar_power); 2107 2108 tx_power_tlv.last_msg = ch_list[idx] == last_ch; 2109 sku_tlbv.channel = ch_list[idx]; 2110 2111 mt76_connac_mcu_build_sku(dev, sku_tlbv.pwr_limit, 2112 &limits, band); 2113 skb_put_data(skb, &sku_tlbv, sku_len); 2114 } 2115 __skb_push(skb, sizeof(tx_power_tlv)); 2116 memcpy(skb->data, &tx_power_tlv, sizeof(tx_power_tlv)); 2117 2118 err = mt76_mcu_skb_send_msg(dev, skb, 2119 MCU_CE_CMD(SET_RATE_TX_POWER), 2120 false); 2121 if (err < 0) 2122 return err; 2123 } 2124 2125 return 0; 2126 } 2127 2128 int mt76_connac_mcu_set_rate_txpower(struct mt76_phy *phy) 2129 { 2130 int err; 2131 2132 if (phy->cap.has_2ghz) { 2133 err = mt76_connac_mcu_rate_txpower_band(phy, 2134 NL80211_BAND_2GHZ); 2135 if (err < 0) 2136 return err; 2137 } 2138 if (phy->cap.has_5ghz) { 2139 err = mt76_connac_mcu_rate_txpower_band(phy, 2140 NL80211_BAND_5GHZ); 2141 if (err < 0) 2142 return err; 2143 } 2144 if (phy->cap.has_6ghz) { 2145 err = mt76_connac_mcu_rate_txpower_band(phy, 2146 NL80211_BAND_6GHZ); 2147 if (err < 0) 2148 return err; 2149 } 2150 2151 return 0; 2152 } 2153 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_rate_txpower); 2154 2155 int mt76_connac_mcu_update_arp_filter(struct mt76_dev *dev, 2156 struct mt76_vif *vif, 2157 struct ieee80211_bss_conf *info) 2158 { 2159 struct sk_buff *skb; 2160 int i, len = min_t(int, info->arp_addr_cnt, 2161 IEEE80211_BSS_ARP_ADDR_LIST_LEN); 2162 struct { 2163 struct { 2164 u8 bss_idx; 2165 u8 pad[3]; 2166 } __packed hdr; 2167 struct mt76_connac_arpns_tlv arp; 2168 } req_hdr = { 2169 .hdr = { 2170 .bss_idx = vif->idx, 2171 }, 2172 .arp = { 2173 .tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_ARP), 2174 .len = cpu_to_le16(sizeof(struct mt76_connac_arpns_tlv)), 2175 .ips_num = len, 2176 .mode = 2, /* update */ 2177 .option = 1, 2178 }, 2179 }; 2180 2181 skb = mt76_mcu_msg_alloc(dev, NULL, 2182 sizeof(req_hdr) + len * sizeof(__be32)); 2183 if (!skb) 2184 return -ENOMEM; 2185 2186 skb_put_data(skb, &req_hdr, sizeof(req_hdr)); 2187 for (i = 0; i < len; i++) { 2188 u8 *addr = (u8 *)skb_put(skb, sizeof(__be32)); 2189 2190 memcpy(addr, &info->arp_addr_list[i], sizeof(__be32)); 2191 } 2192 2193 return mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD(OFFLOAD), true); 2194 } 2195 EXPORT_SYMBOL_GPL(mt76_connac_mcu_update_arp_filter); 2196 2197 int mt76_connac_mcu_set_p2p_oppps(struct ieee80211_hw *hw, 2198 struct ieee80211_vif *vif) 2199 { 2200 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 2201 int ct_window = vif->bss_conf.p2p_noa_attr.oppps_ctwindow; 2202 struct mt76_phy *phy = hw->priv; 2203 struct { 2204 __le32 ct_win; 2205 u8 bss_idx; 2206 u8 rsv[3]; 2207 } __packed req = { 2208 .ct_win = cpu_to_le32(ct_window), 2209 .bss_idx = mvif->idx, 2210 }; 2211 2212 return mt76_mcu_send_msg(phy->dev, MCU_CE_CMD(SET_P2P_OPPPS), 2213 &req, sizeof(req), false); 2214 } 2215 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_p2p_oppps); 2216 2217 #ifdef CONFIG_PM 2218 2219 const struct wiphy_wowlan_support mt76_connac_wowlan_support = { 2220 .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT | 2221 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | WIPHY_WOWLAN_NET_DETECT, 2222 .n_patterns = 1, 2223 .pattern_min_len = 1, 2224 .pattern_max_len = MT76_CONNAC_WOW_PATTEN_MAX_LEN, 2225 .max_nd_match_sets = 10, 2226 }; 2227 EXPORT_SYMBOL_GPL(mt76_connac_wowlan_support); 2228 2229 static void 2230 mt76_connac_mcu_key_iter(struct ieee80211_hw *hw, 2231 struct ieee80211_vif *vif, 2232 struct ieee80211_sta *sta, 2233 struct ieee80211_key_conf *key, 2234 void *data) 2235 { 2236 struct mt76_connac_gtk_rekey_tlv *gtk_tlv = data; 2237 u32 cipher; 2238 2239 if (key->cipher != WLAN_CIPHER_SUITE_AES_CMAC && 2240 key->cipher != WLAN_CIPHER_SUITE_CCMP && 2241 key->cipher != WLAN_CIPHER_SUITE_TKIP) 2242 return; 2243 2244 if (key->cipher == WLAN_CIPHER_SUITE_TKIP) 2245 cipher = BIT(3); 2246 else 2247 cipher = BIT(4); 2248 2249 /* we are assuming here to have a single pairwise key */ 2250 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { 2251 if (key->cipher == WLAN_CIPHER_SUITE_TKIP) 2252 gtk_tlv->proto = cpu_to_le32(NL80211_WPA_VERSION_1); 2253 else 2254 gtk_tlv->proto = cpu_to_le32(NL80211_WPA_VERSION_2); 2255 2256 gtk_tlv->pairwise_cipher = cpu_to_le32(cipher); 2257 gtk_tlv->keyid = key->keyidx; 2258 } else { 2259 gtk_tlv->group_cipher = cpu_to_le32(cipher); 2260 } 2261 } 2262 2263 int mt76_connac_mcu_update_gtk_rekey(struct ieee80211_hw *hw, 2264 struct ieee80211_vif *vif, 2265 struct cfg80211_gtk_rekey_data *key) 2266 { 2267 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 2268 struct mt76_connac_gtk_rekey_tlv *gtk_tlv; 2269 struct mt76_phy *phy = hw->priv; 2270 struct sk_buff *skb; 2271 struct { 2272 u8 bss_idx; 2273 u8 pad[3]; 2274 } __packed hdr = { 2275 .bss_idx = mvif->idx, 2276 }; 2277 2278 skb = mt76_mcu_msg_alloc(phy->dev, NULL, 2279 sizeof(hdr) + sizeof(*gtk_tlv)); 2280 if (!skb) 2281 return -ENOMEM; 2282 2283 skb_put_data(skb, &hdr, sizeof(hdr)); 2284 gtk_tlv = (struct mt76_connac_gtk_rekey_tlv *)skb_put(skb, 2285 sizeof(*gtk_tlv)); 2286 gtk_tlv->tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_GTK_REKEY); 2287 gtk_tlv->len = cpu_to_le16(sizeof(*gtk_tlv)); 2288 gtk_tlv->rekey_mode = 2; 2289 gtk_tlv->option = 1; 2290 2291 rcu_read_lock(); 2292 ieee80211_iter_keys_rcu(hw, vif, mt76_connac_mcu_key_iter, gtk_tlv); 2293 rcu_read_unlock(); 2294 2295 memcpy(gtk_tlv->kek, key->kek, NL80211_KEK_LEN); 2296 memcpy(gtk_tlv->kck, key->kck, NL80211_KCK_LEN); 2297 memcpy(gtk_tlv->replay_ctr, key->replay_ctr, NL80211_REPLAY_CTR_LEN); 2298 2299 return mt76_mcu_skb_send_msg(phy->dev, skb, 2300 MCU_UNI_CMD(OFFLOAD), true); 2301 } 2302 EXPORT_SYMBOL_GPL(mt76_connac_mcu_update_gtk_rekey); 2303 2304 static int 2305 mt76_connac_mcu_set_arp_filter(struct mt76_dev *dev, struct ieee80211_vif *vif, 2306 bool suspend) 2307 { 2308 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 2309 struct { 2310 struct { 2311 u8 bss_idx; 2312 u8 pad[3]; 2313 } __packed hdr; 2314 struct mt76_connac_arpns_tlv arpns; 2315 } req = { 2316 .hdr = { 2317 .bss_idx = mvif->idx, 2318 }, 2319 .arpns = { 2320 .tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_ARP), 2321 .len = cpu_to_le16(sizeof(struct mt76_connac_arpns_tlv)), 2322 .mode = suspend, 2323 }, 2324 }; 2325 2326 return mt76_mcu_send_msg(dev, MCU_UNI_CMD(OFFLOAD), &req, 2327 sizeof(req), true); 2328 } 2329 2330 static int 2331 mt76_connac_mcu_set_gtk_rekey(struct mt76_dev *dev, struct ieee80211_vif *vif, 2332 bool suspend) 2333 { 2334 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 2335 struct { 2336 struct { 2337 u8 bss_idx; 2338 u8 pad[3]; 2339 } __packed hdr; 2340 struct mt76_connac_gtk_rekey_tlv gtk_tlv; 2341 } __packed req = { 2342 .hdr = { 2343 .bss_idx = mvif->idx, 2344 }, 2345 .gtk_tlv = { 2346 .tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_GTK_REKEY), 2347 .len = cpu_to_le16(sizeof(struct mt76_connac_gtk_rekey_tlv)), 2348 .rekey_mode = !suspend, 2349 }, 2350 }; 2351 2352 return mt76_mcu_send_msg(dev, MCU_UNI_CMD(OFFLOAD), &req, 2353 sizeof(req), true); 2354 } 2355 2356 static int 2357 mt76_connac_mcu_set_suspend_mode(struct mt76_dev *dev, 2358 struct ieee80211_vif *vif, 2359 bool enable, u8 mdtim, 2360 bool wow_suspend) 2361 { 2362 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 2363 struct { 2364 struct { 2365 u8 bss_idx; 2366 u8 pad[3]; 2367 } __packed hdr; 2368 struct mt76_connac_suspend_tlv suspend_tlv; 2369 } req = { 2370 .hdr = { 2371 .bss_idx = mvif->idx, 2372 }, 2373 .suspend_tlv = { 2374 .tag = cpu_to_le16(UNI_SUSPEND_MODE_SETTING), 2375 .len = cpu_to_le16(sizeof(struct mt76_connac_suspend_tlv)), 2376 .enable = enable, 2377 .mdtim = mdtim, 2378 .wow_suspend = wow_suspend, 2379 }, 2380 }; 2381 2382 return mt76_mcu_send_msg(dev, MCU_UNI_CMD(SUSPEND), &req, 2383 sizeof(req), true); 2384 } 2385 2386 static int 2387 mt76_connac_mcu_set_wow_pattern(struct mt76_dev *dev, 2388 struct ieee80211_vif *vif, 2389 u8 index, bool enable, 2390 struct cfg80211_pkt_pattern *pattern) 2391 { 2392 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 2393 struct mt76_connac_wow_pattern_tlv *ptlv; 2394 struct sk_buff *skb; 2395 struct req_hdr { 2396 u8 bss_idx; 2397 u8 pad[3]; 2398 } __packed hdr = { 2399 .bss_idx = mvif->idx, 2400 }; 2401 2402 skb = mt76_mcu_msg_alloc(dev, NULL, sizeof(hdr) + sizeof(*ptlv)); 2403 if (!skb) 2404 return -ENOMEM; 2405 2406 skb_put_data(skb, &hdr, sizeof(hdr)); 2407 ptlv = (struct mt76_connac_wow_pattern_tlv *)skb_put(skb, sizeof(*ptlv)); 2408 ptlv->tag = cpu_to_le16(UNI_SUSPEND_WOW_PATTERN); 2409 ptlv->len = cpu_to_le16(sizeof(*ptlv)); 2410 ptlv->data_len = pattern->pattern_len; 2411 ptlv->enable = enable; 2412 ptlv->index = index; 2413 2414 memcpy(ptlv->pattern, pattern->pattern, pattern->pattern_len); 2415 memcpy(ptlv->mask, pattern->mask, DIV_ROUND_UP(pattern->pattern_len, 8)); 2416 2417 return mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD(SUSPEND), true); 2418 } 2419 2420 static int 2421 mt76_connac_mcu_set_wow_ctrl(struct mt76_phy *phy, struct ieee80211_vif *vif, 2422 bool suspend, struct cfg80211_wowlan *wowlan) 2423 { 2424 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 2425 struct mt76_dev *dev = phy->dev; 2426 struct { 2427 struct { 2428 u8 bss_idx; 2429 u8 pad[3]; 2430 } __packed hdr; 2431 struct mt76_connac_wow_ctrl_tlv wow_ctrl_tlv; 2432 struct mt76_connac_wow_gpio_param_tlv gpio_tlv; 2433 } req = { 2434 .hdr = { 2435 .bss_idx = mvif->idx, 2436 }, 2437 .wow_ctrl_tlv = { 2438 .tag = cpu_to_le16(UNI_SUSPEND_WOW_CTRL), 2439 .len = cpu_to_le16(sizeof(struct mt76_connac_wow_ctrl_tlv)), 2440 .cmd = suspend ? 1 : 2, 2441 }, 2442 .gpio_tlv = { 2443 .tag = cpu_to_le16(UNI_SUSPEND_WOW_GPIO_PARAM), 2444 .len = cpu_to_le16(sizeof(struct mt76_connac_wow_gpio_param_tlv)), 2445 .gpio_pin = 0xff, /* follow fw about GPIO pin */ 2446 }, 2447 }; 2448 2449 if (wowlan->magic_pkt) 2450 req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_MAGIC; 2451 if (wowlan->disconnect) 2452 req.wow_ctrl_tlv.trigger |= (UNI_WOW_DETECT_TYPE_DISCONNECT | 2453 UNI_WOW_DETECT_TYPE_BCN_LOST); 2454 if (wowlan->nd_config) { 2455 mt76_connac_mcu_sched_scan_req(phy, vif, wowlan->nd_config); 2456 req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_SCH_SCAN_HIT; 2457 mt76_connac_mcu_sched_scan_enable(phy, vif, suspend); 2458 } 2459 if (wowlan->n_patterns) 2460 req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_BITMAP; 2461 2462 if (mt76_is_mmio(dev)) 2463 req.wow_ctrl_tlv.wakeup_hif = WOW_PCIE; 2464 else if (mt76_is_usb(dev)) 2465 req.wow_ctrl_tlv.wakeup_hif = WOW_USB; 2466 else if (mt76_is_sdio(dev)) 2467 req.wow_ctrl_tlv.wakeup_hif = WOW_GPIO; 2468 2469 return mt76_mcu_send_msg(dev, MCU_UNI_CMD(SUSPEND), &req, 2470 sizeof(req), true); 2471 } 2472 2473 int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend) 2474 { 2475 struct { 2476 struct { 2477 u8 hif_type; /* 0x0: HIF_SDIO 2478 * 0x1: HIF_USB 2479 * 0x2: HIF_PCIE 2480 */ 2481 u8 pad[3]; 2482 } __packed hdr; 2483 struct hif_suspend_tlv { 2484 __le16 tag; 2485 __le16 len; 2486 u8 suspend; 2487 } __packed hif_suspend; 2488 } req = { 2489 .hif_suspend = { 2490 .tag = cpu_to_le16(0), /* 0: UNI_HIF_CTRL_BASIC */ 2491 .len = cpu_to_le16(sizeof(struct hif_suspend_tlv)), 2492 .suspend = suspend, 2493 }, 2494 }; 2495 2496 if (mt76_is_mmio(dev)) 2497 req.hdr.hif_type = 2; 2498 else if (mt76_is_usb(dev)) 2499 req.hdr.hif_type = 1; 2500 else if (mt76_is_sdio(dev)) 2501 req.hdr.hif_type = 0; 2502 2503 return mt76_mcu_send_msg(dev, MCU_UNI_CMD(HIF_CTRL), &req, 2504 sizeof(req), true); 2505 } 2506 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_hif_suspend); 2507 2508 void mt76_connac_mcu_set_suspend_iter(void *priv, u8 *mac, 2509 struct ieee80211_vif *vif) 2510 { 2511 struct mt76_phy *phy = priv; 2512 bool suspend = !test_bit(MT76_STATE_RUNNING, &phy->state); 2513 struct ieee80211_hw *hw = phy->hw; 2514 struct cfg80211_wowlan *wowlan = hw->wiphy->wowlan_config; 2515 int i; 2516 2517 mt76_connac_mcu_set_gtk_rekey(phy->dev, vif, suspend); 2518 mt76_connac_mcu_set_arp_filter(phy->dev, vif, suspend); 2519 2520 mt76_connac_mcu_set_suspend_mode(phy->dev, vif, suspend, 1, true); 2521 2522 for (i = 0; i < wowlan->n_patterns; i++) 2523 mt76_connac_mcu_set_wow_pattern(phy->dev, vif, i, suspend, 2524 &wowlan->patterns[i]); 2525 mt76_connac_mcu_set_wow_ctrl(phy, vif, suspend, wowlan); 2526 } 2527 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_suspend_iter); 2528 #endif /* CONFIG_PM */ 2529 2530 u32 mt76_connac_mcu_reg_rr(struct mt76_dev *dev, u32 offset) 2531 { 2532 struct { 2533 __le32 addr; 2534 __le32 val; 2535 } __packed req = { 2536 .addr = cpu_to_le32(offset), 2537 }; 2538 2539 return mt76_mcu_send_msg(dev, MCU_CE_QUERY(REG_READ), &req, 2540 sizeof(req), true); 2541 } 2542 EXPORT_SYMBOL_GPL(mt76_connac_mcu_reg_rr); 2543 2544 void mt76_connac_mcu_reg_wr(struct mt76_dev *dev, u32 offset, u32 val) 2545 { 2546 struct { 2547 __le32 addr; 2548 __le32 val; 2549 } __packed req = { 2550 .addr = cpu_to_le32(offset), 2551 .val = cpu_to_le32(val), 2552 }; 2553 2554 mt76_mcu_send_msg(dev, MCU_CE_CMD(REG_WRITE), &req, 2555 sizeof(req), false); 2556 } 2557 EXPORT_SYMBOL_GPL(mt76_connac_mcu_reg_wr); 2558 2559 static int 2560 mt76_connac_mcu_sta_key_tlv(struct mt76_connac_sta_key_conf *sta_key_conf, 2561 struct sk_buff *skb, 2562 struct ieee80211_key_conf *key, 2563 enum set_key_cmd cmd) 2564 { 2565 struct sta_rec_sec *sec; 2566 u32 len = sizeof(*sec); 2567 struct tlv *tlv; 2568 2569 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_KEY_V2, sizeof(*sec)); 2570 sec = (struct sta_rec_sec *)tlv; 2571 sec->add = cmd; 2572 2573 if (cmd == SET_KEY) { 2574 struct sec_key *sec_key; 2575 u8 cipher; 2576 2577 cipher = mt76_connac_mcu_get_cipher(key->cipher); 2578 if (cipher == MCU_CIPHER_NONE) 2579 return -EOPNOTSUPP; 2580 2581 sec_key = &sec->key[0]; 2582 sec_key->cipher_len = sizeof(*sec_key); 2583 2584 if (cipher == MCU_CIPHER_BIP_CMAC_128) { 2585 sec_key->cipher_id = MCU_CIPHER_AES_CCMP; 2586 sec_key->key_id = sta_key_conf->keyidx; 2587 sec_key->key_len = 16; 2588 memcpy(sec_key->key, sta_key_conf->key, 16); 2589 2590 sec_key = &sec->key[1]; 2591 sec_key->cipher_id = MCU_CIPHER_BIP_CMAC_128; 2592 sec_key->cipher_len = sizeof(*sec_key); 2593 sec_key->key_len = 16; 2594 memcpy(sec_key->key, key->key, 16); 2595 sec->n_cipher = 2; 2596 } else { 2597 sec_key->cipher_id = cipher; 2598 sec_key->key_id = key->keyidx; 2599 sec_key->key_len = key->keylen; 2600 memcpy(sec_key->key, key->key, key->keylen); 2601 2602 if (cipher == MCU_CIPHER_TKIP) { 2603 /* Rx/Tx MIC keys are swapped */ 2604 memcpy(sec_key->key + 16, key->key + 24, 8); 2605 memcpy(sec_key->key + 24, key->key + 16, 8); 2606 } 2607 2608 /* store key_conf for BIP batch update */ 2609 if (cipher == MCU_CIPHER_AES_CCMP) { 2610 memcpy(sta_key_conf->key, key->key, key->keylen); 2611 sta_key_conf->keyidx = key->keyidx; 2612 } 2613 2614 len -= sizeof(*sec_key); 2615 sec->n_cipher = 1; 2616 } 2617 } else { 2618 len -= sizeof(sec->key); 2619 sec->n_cipher = 0; 2620 } 2621 sec->len = cpu_to_le16(len); 2622 2623 return 0; 2624 } 2625 2626 int mt76_connac_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif, 2627 struct mt76_connac_sta_key_conf *sta_key_conf, 2628 struct ieee80211_key_conf *key, int mcu_cmd, 2629 struct mt76_wcid *wcid, enum set_key_cmd cmd) 2630 { 2631 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 2632 struct sk_buff *skb; 2633 int ret; 2634 2635 skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid); 2636 if (IS_ERR(skb)) 2637 return PTR_ERR(skb); 2638 2639 ret = mt76_connac_mcu_sta_key_tlv(sta_key_conf, skb, key, cmd); 2640 if (ret) 2641 return ret; 2642 2643 return mt76_mcu_skb_send_msg(dev, skb, mcu_cmd, true); 2644 } 2645 EXPORT_SYMBOL_GPL(mt76_connac_mcu_add_key); 2646 2647 /* SIFS 20us + 512 byte beacon tranmitted by 1Mbps (3906us) */ 2648 #define BCN_TX_ESTIMATE_TIME (4096 + 20) 2649 void mt76_connac_mcu_bss_ext_tlv(struct sk_buff *skb, struct mt76_vif *mvif) 2650 { 2651 struct bss_info_ext_bss *ext; 2652 int ext_bss_idx, tsf_offset; 2653 struct tlv *tlv; 2654 2655 ext_bss_idx = mvif->omac_idx - EXT_BSSID_START; 2656 if (ext_bss_idx < 0) 2657 return; 2658 2659 tlv = mt76_connac_mcu_add_tlv(skb, BSS_INFO_EXT_BSS, sizeof(*ext)); 2660 2661 ext = (struct bss_info_ext_bss *)tlv; 2662 tsf_offset = ext_bss_idx * BCN_TX_ESTIMATE_TIME; 2663 ext->mbss_tsf_offset = cpu_to_le32(tsf_offset); 2664 } 2665 EXPORT_SYMBOL_GPL(mt76_connac_mcu_bss_ext_tlv); 2666 2667 int mt76_connac_mcu_bss_basic_tlv(struct sk_buff *skb, 2668 struct ieee80211_vif *vif, 2669 struct ieee80211_sta *sta, 2670 struct mt76_phy *phy, u16 wlan_idx, 2671 bool enable) 2672 { 2673 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 2674 u32 type = vif->p2p ? NETWORK_P2P : NETWORK_INFRA; 2675 struct bss_info_basic *bss; 2676 struct tlv *tlv; 2677 2678 tlv = mt76_connac_mcu_add_tlv(skb, BSS_INFO_BASIC, sizeof(*bss)); 2679 bss = (struct bss_info_basic *)tlv; 2680 2681 switch (vif->type) { 2682 case NL80211_IFTYPE_MESH_POINT: 2683 case NL80211_IFTYPE_MONITOR: 2684 break; 2685 case NL80211_IFTYPE_AP: 2686 if (ieee80211_hw_check(phy->hw, SUPPORTS_MULTI_BSSID)) { 2687 u8 bssid_id = vif->bss_conf.bssid_indicator; 2688 struct wiphy *wiphy = phy->hw->wiphy; 2689 2690 if (bssid_id > ilog2(wiphy->mbssid_max_interfaces)) 2691 return -EINVAL; 2692 2693 bss->non_tx_bssid = vif->bss_conf.bssid_index; 2694 bss->max_bssid = bssid_id; 2695 } 2696 break; 2697 case NL80211_IFTYPE_STATION: 2698 if (enable) { 2699 rcu_read_lock(); 2700 if (!sta) 2701 sta = ieee80211_find_sta(vif, 2702 vif->bss_conf.bssid); 2703 /* TODO: enable BSS_INFO_UAPSD & BSS_INFO_PM */ 2704 if (sta) { 2705 struct mt76_wcid *wcid; 2706 2707 wcid = (struct mt76_wcid *)sta->drv_priv; 2708 wlan_idx = wcid->idx; 2709 } 2710 rcu_read_unlock(); 2711 } 2712 break; 2713 case NL80211_IFTYPE_ADHOC: 2714 type = NETWORK_IBSS; 2715 break; 2716 default: 2717 WARN_ON(1); 2718 break; 2719 } 2720 2721 bss->network_type = cpu_to_le32(type); 2722 bss->bmc_wcid_lo = to_wcid_lo(wlan_idx); 2723 bss->bmc_wcid_hi = to_wcid_hi(wlan_idx); 2724 bss->wmm_idx = mvif->wmm_idx; 2725 bss->active = enable; 2726 bss->cipher = mvif->cipher; 2727 2728 if (vif->type != NL80211_IFTYPE_MONITOR) { 2729 struct cfg80211_chan_def *chandef = &phy->chandef; 2730 2731 memcpy(bss->bssid, vif->bss_conf.bssid, ETH_ALEN); 2732 bss->bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int); 2733 bss->dtim_period = vif->bss_conf.dtim_period; 2734 bss->phy_mode = mt76_connac_get_phy_mode(phy, vif, 2735 chandef->chan->band, NULL); 2736 } else { 2737 memcpy(bss->bssid, phy->macaddr, ETH_ALEN); 2738 } 2739 2740 return 0; 2741 } 2742 EXPORT_SYMBOL_GPL(mt76_connac_mcu_bss_basic_tlv); 2743 2744 #define ENTER_PM_STATE 1 2745 #define EXIT_PM_STATE 2 2746 int mt76_connac_mcu_set_pm(struct mt76_dev *dev, int band, int enter) 2747 { 2748 struct { 2749 u8 pm_number; 2750 u8 pm_state; 2751 u8 bssid[ETH_ALEN]; 2752 u8 dtim_period; 2753 u8 wlan_idx_lo; 2754 __le16 bcn_interval; 2755 __le32 aid; 2756 __le32 rx_filter; 2757 u8 band_idx; 2758 u8 wlan_idx_hi; 2759 u8 rsv[2]; 2760 __le32 feature; 2761 u8 omac_idx; 2762 u8 wmm_idx; 2763 u8 bcn_loss_cnt; 2764 u8 bcn_sp_duration; 2765 } __packed req = { 2766 .pm_number = 5, 2767 .pm_state = enter ? ENTER_PM_STATE : EXIT_PM_STATE, 2768 .band_idx = band, 2769 }; 2770 2771 return mt76_mcu_send_msg(dev, MCU_EXT_CMD(PM_STATE_CTRL), &req, 2772 sizeof(req), true); 2773 } 2774 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_pm); 2775 2776 int mt76_connac_mcu_restart(struct mt76_dev *dev) 2777 { 2778 struct { 2779 u8 power_mode; 2780 u8 rsv[3]; 2781 } req = { 2782 .power_mode = 1, 2783 }; 2784 2785 return mt76_mcu_send_msg(dev, MCU_CMD(NIC_POWER_CTRL), &req, 2786 sizeof(req), false); 2787 } 2788 EXPORT_SYMBOL_GPL(mt76_connac_mcu_restart); 2789 2790 int mt76_connac_mcu_rdd_cmd(struct mt76_dev *dev, int cmd, u8 index, 2791 u8 rx_sel, u8 val) 2792 { 2793 struct { 2794 u8 ctrl; 2795 u8 rdd_idx; 2796 u8 rdd_rx_sel; 2797 u8 val; 2798 u8 rsv[4]; 2799 } __packed req = { 2800 .ctrl = cmd, 2801 .rdd_idx = index, 2802 .rdd_rx_sel = rx_sel, 2803 .val = val, 2804 }; 2805 2806 return mt76_mcu_send_msg(dev, MCU_EXT_CMD(SET_RDD_CTRL), &req, 2807 sizeof(req), true); 2808 } 2809 EXPORT_SYMBOL_GPL(mt76_connac_mcu_rdd_cmd); 2810 2811 MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); 2812 MODULE_LICENSE("Dual BSD/GPL"); 2813