mt76_connac_mcu.c (74231B)
1// SPDX-License-Identifier: ISC 2/* Copyright (C) 2020 MediaTek Inc. */ 3 4#include "mt76_connac_mcu.h" 5 6int 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} 19EXPORT_SYMBOL_GPL(mt76_connac_mcu_start_firmware); 20 21int 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} 33EXPORT_SYMBOL_GPL(mt76_connac_mcu_patch_sem_ctrl); 34 35int 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} 47EXPORT_SYMBOL_GPL(mt76_connac_mcu_start_patch); 48 49#define MCU_PATCH_ADDRESS 0x200000 50 51int 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} 73EXPORT_SYMBOL_GPL(mt76_connac_mcu_init_download); 74 75int 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} 166EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_channel_domain); 167 168int 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} 183EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_mac_enable); 184 185int 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} 205EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_vif_ps); 206 207int 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} 225EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_rts_thresh); 226 227void 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} 241EXPORT_SYMBOL_GPL(mt76_connac_mcu_beacon_loss_iter); 242 243struct tlv * 244mt76_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} 266EXPORT_SYMBOL_GPL(mt76_connac_mcu_add_nested_tlv); 267 268struct 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} 289EXPORT_SYMBOL_GPL(__mt76_connac_mcu_alloc_sta_req); 290 291struct wtbl_req_hdr * 292mt76_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} 317EXPORT_SYMBOL_GPL(mt76_connac_mcu_alloc_wtbl_req); 318 319void 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} 359EXPORT_SYMBOL_GPL(mt76_connac_mcu_bss_omac_tlv); 360 361void 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} 419EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_basic_tlv); 420 421void 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} 451EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_uapsd); 452 453void 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} 481EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_hdr_trans_tlv); 482 483int 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} 508EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_update_hdr_trans); 509 510int 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} 527EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_update_hdr_trans); 528 529void 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} 581EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_generic_tlv); 582 583static void 584mt76_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) 610static void 611mt76_connac_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta) 612{ 613 struct ieee80211_sta_he_cap *he_cap = &sta->deflink.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->deflink.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 743static u8 744mt76_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->deflink.ht_cap; 754 vht_cap = &sta->deflink.vht_cap; 755 he_cap = &sta->deflink.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 789void 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->deflink.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->deflink.ht_cap.cap); 810 } 811 812 /* starec vht */ 813 if (sta->deflink.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->deflink.vht_cap.cap); 821 vht->vht_rx_mcs_map = sta->deflink.vht_cap.vht_mcs.rx_mcs_map; 822 vht->vht_tx_mcs_map = sta->deflink.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->deflink.ht_cap.ht_supported || sta->deflink.he_cap.has_he) 832 mt76_connac_mcu_sta_amsdu_tlv(skb, sta, vif); 833 834 /* starec he */ 835 if (sta->deflink.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->deflink.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->deflink.ht_cap.ampdu_factor) | 855 FIELD_PREP(IEEE80211_HT_AMPDU_PARM_DENSITY, 856 sta->deflink.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->deflink.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->deflink.ht_cap.ht_supported) 871 memcpy(ra_info->rx_mcs_bitmask, 872 sta->deflink.ht_cap.mcs.rx_mask, 873 HT_MCS_MASK_NUM); 874 875 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_STATE, sizeof(*state)); 876 state = (struct sta_rec_state *)tlv; 877 state->state = sta_state; 878 879 if (sta->deflink.vht_cap.vht_supported) { 880 state->vht_opmode = sta->deflink.bandwidth; 881 state->vht_opmode |= (sta->deflink.rx_nss - 1) << 882 IEEE80211_OPMODE_NOTIF_RX_NSS_SHIFT; 883 } 884} 885EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_tlv); 886 887void mt76_connac_mcu_wtbl_smps_tlv(struct sk_buff *skb, 888 struct ieee80211_sta *sta, 889 void *sta_wtbl, void *wtbl_tlv) 890{ 891 struct wtbl_smps *smps; 892 struct tlv *tlv; 893 894 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_SMPS, sizeof(*smps), 895 wtbl_tlv, sta_wtbl); 896 smps = (struct wtbl_smps *)tlv; 897 smps->smps = (sta->smps_mode == IEEE80211_SMPS_DYNAMIC); 898} 899EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_smps_tlv); 900 901void mt76_connac_mcu_wtbl_ht_tlv(struct mt76_dev *dev, struct sk_buff *skb, 902 struct ieee80211_sta *sta, void *sta_wtbl, 903 void *wtbl_tlv, bool ht_ldpc, bool vht_ldpc) 904{ 905 struct wtbl_ht *ht = NULL; 906 struct tlv *tlv; 907 u32 flags = 0; 908 909 if (sta->deflink.ht_cap.ht_supported || sta->deflink.he_6ghz_capa.capa) { 910 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_HT, sizeof(*ht), 911 wtbl_tlv, sta_wtbl); 912 ht = (struct wtbl_ht *)tlv; 913 ht->ldpc = ht_ldpc && 914 !!(sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING); 915 916 if (sta->deflink.ht_cap.ht_supported) { 917 ht->af = sta->deflink.ht_cap.ampdu_factor; 918 ht->mm = sta->deflink.ht_cap.ampdu_density; 919 } else { 920 ht->af = le16_get_bits(sta->deflink.he_6ghz_capa.capa, 921 IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP); 922 ht->mm = le16_get_bits(sta->deflink.he_6ghz_capa.capa, 923 IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START); 924 } 925 926 ht->ht = true; 927 } 928 929 if (sta->deflink.vht_cap.vht_supported || sta->deflink.he_6ghz_capa.capa) { 930 struct wtbl_vht *vht; 931 u8 af; 932 933 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_VHT, 934 sizeof(*vht), wtbl_tlv, 935 sta_wtbl); 936 vht = (struct wtbl_vht *)tlv; 937 vht->ldpc = vht_ldpc && 938 !!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC); 939 vht->vht = true; 940 941 af = FIELD_GET(IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK, 942 sta->deflink.vht_cap.cap); 943 if (ht) 944 ht->af = max(ht->af, af); 945 } 946 947 mt76_connac_mcu_wtbl_smps_tlv(skb, sta, sta_wtbl, wtbl_tlv); 948 949 if (is_connac_v1(dev) && sta->deflink.ht_cap.ht_supported) { 950 /* sgi */ 951 u32 msk = MT_WTBL_W5_SHORT_GI_20 | MT_WTBL_W5_SHORT_GI_40 | 952 MT_WTBL_W5_SHORT_GI_80 | MT_WTBL_W5_SHORT_GI_160; 953 struct wtbl_raw *raw; 954 955 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_RAW_DATA, 956 sizeof(*raw), wtbl_tlv, 957 sta_wtbl); 958 959 if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) 960 flags |= MT_WTBL_W5_SHORT_GI_20; 961 if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) 962 flags |= MT_WTBL_W5_SHORT_GI_40; 963 964 if (sta->deflink.vht_cap.vht_supported) { 965 if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80) 966 flags |= MT_WTBL_W5_SHORT_GI_80; 967 if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_160) 968 flags |= MT_WTBL_W5_SHORT_GI_160; 969 } 970 raw = (struct wtbl_raw *)tlv; 971 raw->val = cpu_to_le32(flags); 972 raw->msk = cpu_to_le32(~msk); 973 raw->wtbl_idx = 1; 974 raw->dw = 5; 975 } 976} 977EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_ht_tlv); 978 979int mt76_connac_mcu_sta_cmd(struct mt76_phy *phy, 980 struct mt76_sta_cmd_info *info) 981{ 982 struct mt76_vif *mvif = (struct mt76_vif *)info->vif->drv_priv; 983 struct mt76_dev *dev = phy->dev; 984 struct wtbl_req_hdr *wtbl_hdr; 985 struct tlv *sta_wtbl; 986 struct sk_buff *skb; 987 988 skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, info->wcid); 989 if (IS_ERR(skb)) 990 return PTR_ERR(skb); 991 992 if (info->sta || !info->offload_fw) 993 mt76_connac_mcu_sta_basic_tlv(skb, info->vif, info->sta, 994 info->enable, info->newly); 995 if (info->sta && info->enable) 996 mt76_connac_mcu_sta_tlv(phy, skb, info->sta, 997 info->vif, info->rcpi, 998 info->state); 999 1000 sta_wtbl = mt76_connac_mcu_add_tlv(skb, STA_REC_WTBL, 1001 sizeof(struct tlv)); 1002 1003 wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(dev, info->wcid, 1004 WTBL_RESET_AND_SET, 1005 sta_wtbl, &skb); 1006 if (IS_ERR(wtbl_hdr)) 1007 return PTR_ERR(wtbl_hdr); 1008 1009 if (info->enable) { 1010 mt76_connac_mcu_wtbl_generic_tlv(dev, skb, info->vif, 1011 info->sta, sta_wtbl, 1012 wtbl_hdr); 1013 mt76_connac_mcu_wtbl_hdr_trans_tlv(skb, info->vif, info->wcid, 1014 sta_wtbl, wtbl_hdr); 1015 if (info->sta) 1016 mt76_connac_mcu_wtbl_ht_tlv(dev, skb, info->sta, 1017 sta_wtbl, wtbl_hdr, 1018 true, true); 1019 } 1020 1021 return mt76_mcu_skb_send_msg(dev, skb, info->cmd, true); 1022} 1023EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_cmd); 1024 1025void mt76_connac_mcu_wtbl_ba_tlv(struct mt76_dev *dev, struct sk_buff *skb, 1026 struct ieee80211_ampdu_params *params, 1027 bool enable, bool tx, void *sta_wtbl, 1028 void *wtbl_tlv) 1029{ 1030 struct wtbl_ba *ba; 1031 struct tlv *tlv; 1032 1033 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_BA, sizeof(*ba), 1034 wtbl_tlv, sta_wtbl); 1035 1036 ba = (struct wtbl_ba *)tlv; 1037 ba->tid = params->tid; 1038 1039 if (tx) { 1040 ba->ba_type = MT_BA_TYPE_ORIGINATOR; 1041 ba->sn = enable ? cpu_to_le16(params->ssn) : 0; 1042 ba->ba_winsize = enable ? cpu_to_le16(params->buf_size) : 0; 1043 ba->ba_en = enable; 1044 } else { 1045 memcpy(ba->peer_addr, params->sta->addr, ETH_ALEN); 1046 ba->ba_type = MT_BA_TYPE_RECIPIENT; 1047 ba->rst_ba_tid = params->tid; 1048 ba->rst_ba_sel = RST_BA_MAC_TID_MATCH; 1049 ba->rst_ba_sb = 1; 1050 } 1051 1052 if (!is_connac_v1(dev)) { 1053 ba->ba_winsize = enable ? cpu_to_le16(params->buf_size) : 0; 1054 return; 1055 } 1056 1057 if (enable && tx) { 1058 static const u8 ba_range[] = { 4, 8, 12, 24, 36, 48, 54, 64 }; 1059 int i; 1060 1061 for (i = 7; i > 0; i--) { 1062 if (params->buf_size >= ba_range[i]) 1063 break; 1064 } 1065 ba->ba_winsize_idx = i; 1066 } 1067} 1068EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_ba_tlv); 1069 1070int mt76_connac_mcu_uni_add_dev(struct mt76_phy *phy, 1071 struct ieee80211_vif *vif, 1072 struct mt76_wcid *wcid, 1073 bool enable) 1074{ 1075 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 1076 struct mt76_dev *dev = phy->dev; 1077 struct { 1078 struct { 1079 u8 omac_idx; 1080 u8 band_idx; 1081 __le16 pad; 1082 } __packed hdr; 1083 struct req_tlv { 1084 __le16 tag; 1085 __le16 len; 1086 u8 active; 1087 u8 pad; 1088 u8 omac_addr[ETH_ALEN]; 1089 } __packed tlv; 1090 } dev_req = { 1091 .hdr = { 1092 .omac_idx = mvif->omac_idx, 1093 .band_idx = mvif->band_idx, 1094 }, 1095 .tlv = { 1096 .tag = cpu_to_le16(DEV_INFO_ACTIVE), 1097 .len = cpu_to_le16(sizeof(struct req_tlv)), 1098 .active = enable, 1099 }, 1100 }; 1101 struct { 1102 struct { 1103 u8 bss_idx; 1104 u8 pad[3]; 1105 } __packed hdr; 1106 struct mt76_connac_bss_basic_tlv basic; 1107 } basic_req = { 1108 .hdr = { 1109 .bss_idx = mvif->idx, 1110 }, 1111 .basic = { 1112 .tag = cpu_to_le16(UNI_BSS_INFO_BASIC), 1113 .len = cpu_to_le16(sizeof(struct mt76_connac_bss_basic_tlv)), 1114 .omac_idx = mvif->omac_idx, 1115 .band_idx = mvif->band_idx, 1116 .wmm_idx = mvif->wmm_idx, 1117 .active = enable, 1118 .bmc_tx_wlan_idx = cpu_to_le16(wcid->idx), 1119 .sta_idx = cpu_to_le16(wcid->idx), 1120 .conn_state = 1, 1121 }, 1122 }; 1123 int err, idx, cmd, len; 1124 void *data; 1125 1126 switch (vif->type) { 1127 case NL80211_IFTYPE_MESH_POINT: 1128 case NL80211_IFTYPE_MONITOR: 1129 case NL80211_IFTYPE_AP: 1130 basic_req.basic.conn_type = cpu_to_le32(CONNECTION_INFRA_AP); 1131 break; 1132 case NL80211_IFTYPE_STATION: 1133 basic_req.basic.conn_type = cpu_to_le32(CONNECTION_INFRA_STA); 1134 break; 1135 case NL80211_IFTYPE_ADHOC: 1136 basic_req.basic.conn_type = cpu_to_le32(CONNECTION_IBSS_ADHOC); 1137 break; 1138 default: 1139 WARN_ON(1); 1140 break; 1141 } 1142 1143 idx = mvif->omac_idx > EXT_BSSID_START ? HW_BSSID_0 : mvif->omac_idx; 1144 basic_req.basic.hw_bss_idx = idx; 1145 1146 memcpy(dev_req.tlv.omac_addr, vif->addr, ETH_ALEN); 1147 1148 cmd = enable ? MCU_UNI_CMD(DEV_INFO_UPDATE) : MCU_UNI_CMD(BSS_INFO_UPDATE); 1149 data = enable ? (void *)&dev_req : (void *)&basic_req; 1150 len = enable ? sizeof(dev_req) : sizeof(basic_req); 1151 1152 err = mt76_mcu_send_msg(dev, cmd, data, len, true); 1153 if (err < 0) 1154 return err; 1155 1156 cmd = enable ? MCU_UNI_CMD(BSS_INFO_UPDATE) : MCU_UNI_CMD(DEV_INFO_UPDATE); 1157 data = enable ? (void *)&basic_req : (void *)&dev_req; 1158 len = enable ? sizeof(basic_req) : sizeof(dev_req); 1159 1160 return mt76_mcu_send_msg(dev, cmd, data, len, true); 1161} 1162EXPORT_SYMBOL_GPL(mt76_connac_mcu_uni_add_dev); 1163 1164void mt76_connac_mcu_sta_ba_tlv(struct sk_buff *skb, 1165 struct ieee80211_ampdu_params *params, 1166 bool enable, bool tx) 1167{ 1168 struct sta_rec_ba *ba; 1169 struct tlv *tlv; 1170 1171 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_BA, sizeof(*ba)); 1172 1173 ba = (struct sta_rec_ba *)tlv; 1174 ba->ba_type = tx ? MT_BA_TYPE_ORIGINATOR : MT_BA_TYPE_RECIPIENT; 1175 ba->winsize = cpu_to_le16(params->buf_size); 1176 ba->ssn = cpu_to_le16(params->ssn); 1177 ba->ba_en = enable << params->tid; 1178 ba->amsdu = params->amsdu; 1179 ba->tid = params->tid; 1180} 1181EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_ba_tlv); 1182 1183int mt76_connac_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif, 1184 struct ieee80211_ampdu_params *params, 1185 int cmd, bool enable, bool tx) 1186{ 1187 struct mt76_wcid *wcid = (struct mt76_wcid *)params->sta->drv_priv; 1188 struct wtbl_req_hdr *wtbl_hdr; 1189 struct tlv *sta_wtbl; 1190 struct sk_buff *skb; 1191 int ret; 1192 1193 skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid); 1194 if (IS_ERR(skb)) 1195 return PTR_ERR(skb); 1196 1197 sta_wtbl = mt76_connac_mcu_add_tlv(skb, STA_REC_WTBL, 1198 sizeof(struct tlv)); 1199 1200 wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(dev, wcid, WTBL_SET, 1201 sta_wtbl, &skb); 1202 if (IS_ERR(wtbl_hdr)) 1203 return PTR_ERR(wtbl_hdr); 1204 1205 mt76_connac_mcu_wtbl_ba_tlv(dev, skb, params, enable, tx, sta_wtbl, 1206 wtbl_hdr); 1207 1208 ret = mt76_mcu_skb_send_msg(dev, skb, cmd, true); 1209 if (ret) 1210 return ret; 1211 1212 skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid); 1213 if (IS_ERR(skb)) 1214 return PTR_ERR(skb); 1215 1216 mt76_connac_mcu_sta_ba_tlv(skb, params, enable, tx); 1217 1218 return mt76_mcu_skb_send_msg(dev, skb, cmd, true); 1219} 1220EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_ba); 1221 1222u8 mt76_connac_get_phy_mode(struct mt76_phy *phy, struct ieee80211_vif *vif, 1223 enum nl80211_band band, struct ieee80211_sta *sta) 1224{ 1225 struct mt76_dev *dev = phy->dev; 1226 const struct ieee80211_sta_he_cap *he_cap; 1227 struct ieee80211_sta_vht_cap *vht_cap; 1228 struct ieee80211_sta_ht_cap *ht_cap; 1229 u8 mode = 0; 1230 1231 if (is_connac_v1(dev)) 1232 return 0x38; 1233 1234 if (sta) { 1235 ht_cap = &sta->deflink.ht_cap; 1236 vht_cap = &sta->deflink.vht_cap; 1237 he_cap = &sta->deflink.he_cap; 1238 } else { 1239 struct ieee80211_supported_band *sband; 1240 1241 sband = phy->hw->wiphy->bands[band]; 1242 ht_cap = &sband->ht_cap; 1243 vht_cap = &sband->vht_cap; 1244 he_cap = ieee80211_get_he_iftype_cap(sband, vif->type); 1245 } 1246 1247 if (band == NL80211_BAND_2GHZ) { 1248 mode |= PHY_MODE_B | PHY_MODE_G; 1249 1250 if (ht_cap->ht_supported) 1251 mode |= PHY_MODE_GN; 1252 1253 if (he_cap && he_cap->has_he) 1254 mode |= PHY_MODE_AX_24G; 1255 } else if (band == NL80211_BAND_5GHZ) { 1256 mode |= PHY_MODE_A; 1257 1258 if (ht_cap->ht_supported) 1259 mode |= PHY_MODE_AN; 1260 1261 if (vht_cap->vht_supported) 1262 mode |= PHY_MODE_AC; 1263 1264 if (he_cap && he_cap->has_he) 1265 mode |= PHY_MODE_AX_5G; 1266 } else if (band == NL80211_BAND_6GHZ) { 1267 mode |= PHY_MODE_A | PHY_MODE_AN | 1268 PHY_MODE_AC | PHY_MODE_AX_5G; 1269 } 1270 1271 return mode; 1272} 1273EXPORT_SYMBOL_GPL(mt76_connac_get_phy_mode); 1274 1275const struct ieee80211_sta_he_cap * 1276mt76_connac_get_he_phy_cap(struct mt76_phy *phy, struct ieee80211_vif *vif) 1277{ 1278 enum nl80211_band band = phy->chandef.chan->band; 1279 struct ieee80211_supported_band *sband; 1280 1281 sband = phy->hw->wiphy->bands[band]; 1282 1283 return ieee80211_get_he_iftype_cap(sband, vif->type); 1284} 1285EXPORT_SYMBOL_GPL(mt76_connac_get_he_phy_cap); 1286 1287#define DEFAULT_HE_PE_DURATION 4 1288#define DEFAULT_HE_DURATION_RTS_THRES 1023 1289static void 1290mt76_connac_mcu_uni_bss_he_tlv(struct mt76_phy *phy, struct ieee80211_vif *vif, 1291 struct tlv *tlv) 1292{ 1293 const struct ieee80211_sta_he_cap *cap; 1294 struct bss_info_uni_he *he; 1295 1296 cap = mt76_connac_get_he_phy_cap(phy, vif); 1297 1298 he = (struct bss_info_uni_he *)tlv; 1299 he->he_pe_duration = vif->bss_conf.htc_trig_based_pkt_ext; 1300 if (!he->he_pe_duration) 1301 he->he_pe_duration = DEFAULT_HE_PE_DURATION; 1302 1303 he->he_rts_thres = cpu_to_le16(vif->bss_conf.frame_time_rts_th); 1304 if (!he->he_rts_thres) 1305 he->he_rts_thres = cpu_to_le16(DEFAULT_HE_DURATION_RTS_THRES); 1306 1307 he->max_nss_mcs[CMD_HE_MCS_BW80] = cap->he_mcs_nss_supp.tx_mcs_80; 1308 he->max_nss_mcs[CMD_HE_MCS_BW160] = cap->he_mcs_nss_supp.tx_mcs_160; 1309 he->max_nss_mcs[CMD_HE_MCS_BW8080] = cap->he_mcs_nss_supp.tx_mcs_80p80; 1310} 1311 1312int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy, 1313 struct ieee80211_vif *vif, 1314 struct mt76_wcid *wcid, 1315 bool enable) 1316{ 1317 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 1318 struct cfg80211_chan_def *chandef = &phy->chandef; 1319 int freq1 = chandef->center_freq1, freq2 = chandef->center_freq2; 1320 enum nl80211_band band = chandef->chan->band; 1321 struct mt76_dev *mdev = phy->dev; 1322 struct { 1323 struct { 1324 u8 bss_idx; 1325 u8 pad[3]; 1326 } __packed hdr; 1327 struct mt76_connac_bss_basic_tlv basic; 1328 struct mt76_connac_bss_qos_tlv qos; 1329 } basic_req = { 1330 .hdr = { 1331 .bss_idx = mvif->idx, 1332 }, 1333 .basic = { 1334 .tag = cpu_to_le16(UNI_BSS_INFO_BASIC), 1335 .len = cpu_to_le16(sizeof(struct mt76_connac_bss_basic_tlv)), 1336 .bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int), 1337 .dtim_period = vif->bss_conf.dtim_period, 1338 .omac_idx = mvif->omac_idx, 1339 .band_idx = mvif->band_idx, 1340 .wmm_idx = mvif->wmm_idx, 1341 .active = true, /* keep bss deactivated */ 1342 .phymode = mt76_connac_get_phy_mode(phy, vif, band, NULL), 1343 }, 1344 .qos = { 1345 .tag = cpu_to_le16(UNI_BSS_INFO_QBSS), 1346 .len = cpu_to_le16(sizeof(struct mt76_connac_bss_qos_tlv)), 1347 .qos = vif->bss_conf.qos, 1348 }, 1349 }; 1350 struct { 1351 struct { 1352 u8 bss_idx; 1353 u8 pad[3]; 1354 } __packed hdr; 1355 struct rlm_tlv { 1356 __le16 tag; 1357 __le16 len; 1358 u8 control_channel; 1359 u8 center_chan; 1360 u8 center_chan2; 1361 u8 bw; 1362 u8 tx_streams; 1363 u8 rx_streams; 1364 u8 short_st; 1365 u8 ht_op_info; 1366 u8 sco; 1367 u8 band; 1368 u8 pad[2]; 1369 } __packed rlm; 1370 } __packed rlm_req = { 1371 .hdr = { 1372 .bss_idx = mvif->idx, 1373 }, 1374 .rlm = { 1375 .tag = cpu_to_le16(UNI_BSS_INFO_RLM), 1376 .len = cpu_to_le16(sizeof(struct rlm_tlv)), 1377 .control_channel = chandef->chan->hw_value, 1378 .center_chan = ieee80211_frequency_to_channel(freq1), 1379 .center_chan2 = ieee80211_frequency_to_channel(freq2), 1380 .tx_streams = hweight8(phy->antenna_mask), 1381 .ht_op_info = 4, /* set HT 40M allowed */ 1382 .rx_streams = phy->chainmask, 1383 .short_st = true, 1384 .band = band, 1385 }, 1386 }; 1387 int err, conn_type; 1388 u8 idx, basic_phy; 1389 1390 idx = mvif->omac_idx > EXT_BSSID_START ? HW_BSSID_0 : mvif->omac_idx; 1391 basic_req.basic.hw_bss_idx = idx; 1392 if (band == NL80211_BAND_6GHZ) 1393 basic_req.basic.phymode_ext = PHY_MODE_AX_6G; 1394 1395 basic_phy = mt76_connac_get_phy_mode_v2(phy, vif, band, NULL); 1396 basic_req.basic.nonht_basic_phy = cpu_to_le16(basic_phy); 1397 1398 switch (vif->type) { 1399 case NL80211_IFTYPE_MESH_POINT: 1400 case NL80211_IFTYPE_AP: 1401 if (vif->p2p) 1402 conn_type = CONNECTION_P2P_GO; 1403 else 1404 conn_type = CONNECTION_INFRA_AP; 1405 basic_req.basic.conn_type = cpu_to_le32(conn_type); 1406 break; 1407 case NL80211_IFTYPE_STATION: 1408 if (vif->p2p) 1409 conn_type = CONNECTION_P2P_GC; 1410 else 1411 conn_type = CONNECTION_INFRA_STA; 1412 basic_req.basic.conn_type = cpu_to_le32(conn_type); 1413 break; 1414 case NL80211_IFTYPE_ADHOC: 1415 basic_req.basic.conn_type = cpu_to_le32(CONNECTION_IBSS_ADHOC); 1416 break; 1417 default: 1418 WARN_ON(1); 1419 break; 1420 } 1421 1422 memcpy(basic_req.basic.bssid, vif->bss_conf.bssid, ETH_ALEN); 1423 basic_req.basic.bmc_tx_wlan_idx = cpu_to_le16(wcid->idx); 1424 basic_req.basic.sta_idx = cpu_to_le16(wcid->idx); 1425 basic_req.basic.conn_state = !enable; 1426 1427 err = mt76_mcu_send_msg(mdev, MCU_UNI_CMD(BSS_INFO_UPDATE), &basic_req, 1428 sizeof(basic_req), true); 1429 if (err < 0) 1430 return err; 1431 1432 if (vif->bss_conf.he_support) { 1433 struct { 1434 struct { 1435 u8 bss_idx; 1436 u8 pad[3]; 1437 } __packed hdr; 1438 struct bss_info_uni_he he; 1439 struct bss_info_uni_bss_color bss_color; 1440 } he_req = { 1441 .hdr = { 1442 .bss_idx = mvif->idx, 1443 }, 1444 .he = { 1445 .tag = cpu_to_le16(UNI_BSS_INFO_HE_BASIC), 1446 .len = cpu_to_le16(sizeof(struct bss_info_uni_he)), 1447 }, 1448 .bss_color = { 1449 .tag = cpu_to_le16(UNI_BSS_INFO_BSS_COLOR), 1450 .len = cpu_to_le16(sizeof(struct bss_info_uni_bss_color)), 1451 .enable = 0, 1452 .bss_color = 0, 1453 }, 1454 }; 1455 1456 if (enable) { 1457 he_req.bss_color.enable = 1458 vif->bss_conf.he_bss_color.enabled; 1459 he_req.bss_color.bss_color = 1460 vif->bss_conf.he_bss_color.color; 1461 } 1462 1463 mt76_connac_mcu_uni_bss_he_tlv(phy, vif, 1464 (struct tlv *)&he_req.he); 1465 err = mt76_mcu_send_msg(mdev, MCU_UNI_CMD(BSS_INFO_UPDATE), 1466 &he_req, sizeof(he_req), true); 1467 if (err < 0) 1468 return err; 1469 } 1470 1471 switch (chandef->width) { 1472 case NL80211_CHAN_WIDTH_40: 1473 rlm_req.rlm.bw = CMD_CBW_40MHZ; 1474 break; 1475 case NL80211_CHAN_WIDTH_80: 1476 rlm_req.rlm.bw = CMD_CBW_80MHZ; 1477 break; 1478 case NL80211_CHAN_WIDTH_80P80: 1479 rlm_req.rlm.bw = CMD_CBW_8080MHZ; 1480 break; 1481 case NL80211_CHAN_WIDTH_160: 1482 rlm_req.rlm.bw = CMD_CBW_160MHZ; 1483 break; 1484 case NL80211_CHAN_WIDTH_5: 1485 rlm_req.rlm.bw = CMD_CBW_5MHZ; 1486 break; 1487 case NL80211_CHAN_WIDTH_10: 1488 rlm_req.rlm.bw = CMD_CBW_10MHZ; 1489 break; 1490 case NL80211_CHAN_WIDTH_20_NOHT: 1491 case NL80211_CHAN_WIDTH_20: 1492 default: 1493 rlm_req.rlm.bw = CMD_CBW_20MHZ; 1494 rlm_req.rlm.ht_op_info = 0; 1495 break; 1496 } 1497 1498 if (rlm_req.rlm.control_channel < rlm_req.rlm.center_chan) 1499 rlm_req.rlm.sco = 1; /* SCA */ 1500 else if (rlm_req.rlm.control_channel > rlm_req.rlm.center_chan) 1501 rlm_req.rlm.sco = 3; /* SCB */ 1502 1503 return mt76_mcu_send_msg(mdev, MCU_UNI_CMD(BSS_INFO_UPDATE), &rlm_req, 1504 sizeof(rlm_req), true); 1505} 1506EXPORT_SYMBOL_GPL(mt76_connac_mcu_uni_add_bss); 1507 1508#define MT76_CONNAC_SCAN_CHANNEL_TIME 60 1509int mt76_connac_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif, 1510 struct ieee80211_scan_request *scan_req) 1511{ 1512 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 1513 struct cfg80211_scan_request *sreq = &scan_req->req; 1514 int n_ssids = 0, err, i, duration; 1515 int ext_channels_num = max_t(int, sreq->n_channels - 32, 0); 1516 struct ieee80211_channel **scan_list = sreq->channels; 1517 struct mt76_dev *mdev = phy->dev; 1518 struct mt76_connac_mcu_scan_channel *chan; 1519 struct mt76_connac_hw_scan_req *req; 1520 struct sk_buff *skb; 1521 1522 skb = mt76_mcu_msg_alloc(mdev, NULL, sizeof(*req)); 1523 if (!skb) 1524 return -ENOMEM; 1525 1526 set_bit(MT76_HW_SCANNING, &phy->state); 1527 mvif->scan_seq_num = (mvif->scan_seq_num + 1) & 0x7f; 1528 1529 req = (struct mt76_connac_hw_scan_req *)skb_put(skb, sizeof(*req)); 1530 1531 req->seq_num = mvif->scan_seq_num | mvif->band_idx << 7; 1532 req->bss_idx = mvif->idx; 1533 req->scan_type = sreq->n_ssids ? 1 : 0; 1534 req->probe_req_num = sreq->n_ssids ? 2 : 0; 1535 req->version = 1; 1536 1537 for (i = 0; i < sreq->n_ssids; i++) { 1538 if (!sreq->ssids[i].ssid_len) 1539 continue; 1540 1541 req->ssids[i].ssid_len = cpu_to_le32(sreq->ssids[i].ssid_len); 1542 memcpy(req->ssids[i].ssid, sreq->ssids[i].ssid, 1543 sreq->ssids[i].ssid_len); 1544 n_ssids++; 1545 } 1546 req->ssid_type = n_ssids ? BIT(2) : BIT(0); 1547 req->ssid_type_ext = n_ssids ? BIT(0) : 0; 1548 req->ssids_num = n_ssids; 1549 1550 duration = is_mt7921(phy->dev) ? 0 : MT76_CONNAC_SCAN_CHANNEL_TIME; 1551 /* increase channel time for passive scan */ 1552 if (!sreq->n_ssids) 1553 duration *= 2; 1554 req->timeout_value = cpu_to_le16(sreq->n_channels * duration); 1555 req->channel_min_dwell_time = cpu_to_le16(duration); 1556 req->channel_dwell_time = cpu_to_le16(duration); 1557 1558 req->channels_num = min_t(u8, sreq->n_channels, 32); 1559 req->ext_channels_num = min_t(u8, ext_channels_num, 32); 1560 for (i = 0; i < req->channels_num + req->ext_channels_num; i++) { 1561 if (i >= 32) 1562 chan = &req->ext_channels[i - 32]; 1563 else 1564 chan = &req->channels[i]; 1565 1566 switch (scan_list[i]->band) { 1567 case NL80211_BAND_2GHZ: 1568 chan->band = 1; 1569 break; 1570 case NL80211_BAND_6GHZ: 1571 chan->band = 3; 1572 break; 1573 default: 1574 chan->band = 2; 1575 break; 1576 } 1577 chan->channel_num = scan_list[i]->hw_value; 1578 } 1579 req->channel_type = sreq->n_channels ? 4 : 0; 1580 1581 if (sreq->ie_len > 0) { 1582 memcpy(req->ies, sreq->ie, sreq->ie_len); 1583 req->ies_len = cpu_to_le16(sreq->ie_len); 1584 } 1585 1586 if (is_mt7921(phy->dev)) 1587 req->scan_func |= SCAN_FUNC_SPLIT_SCAN; 1588 1589 memcpy(req->bssid, sreq->bssid, ETH_ALEN); 1590 if (sreq->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) { 1591 get_random_mask_addr(req->random_mac, sreq->mac_addr, 1592 sreq->mac_addr_mask); 1593 req->scan_func |= SCAN_FUNC_RANDOM_MAC; 1594 } 1595 1596 err = mt76_mcu_skb_send_msg(mdev, skb, MCU_CE_CMD(START_HW_SCAN), 1597 false); 1598 if (err < 0) 1599 clear_bit(MT76_HW_SCANNING, &phy->state); 1600 1601 return err; 1602} 1603EXPORT_SYMBOL_GPL(mt76_connac_mcu_hw_scan); 1604 1605int mt76_connac_mcu_cancel_hw_scan(struct mt76_phy *phy, 1606 struct ieee80211_vif *vif) 1607{ 1608 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 1609 struct { 1610 u8 seq_num; 1611 u8 is_ext_channel; 1612 u8 rsv[2]; 1613 } __packed req = { 1614 .seq_num = mvif->scan_seq_num, 1615 }; 1616 1617 if (test_and_clear_bit(MT76_HW_SCANNING, &phy->state)) { 1618 struct cfg80211_scan_info info = { 1619 .aborted = true, 1620 }; 1621 1622 ieee80211_scan_completed(phy->hw, &info); 1623 } 1624 1625 return mt76_mcu_send_msg(phy->dev, MCU_CE_CMD(CANCEL_HW_SCAN), 1626 &req, sizeof(req), false); 1627} 1628EXPORT_SYMBOL_GPL(mt76_connac_mcu_cancel_hw_scan); 1629 1630int mt76_connac_mcu_sched_scan_req(struct mt76_phy *phy, 1631 struct ieee80211_vif *vif, 1632 struct cfg80211_sched_scan_request *sreq) 1633{ 1634 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 1635 struct ieee80211_channel **scan_list = sreq->channels; 1636 struct mt76_connac_mcu_scan_channel *chan; 1637 struct mt76_connac_sched_scan_req *req; 1638 struct mt76_dev *mdev = phy->dev; 1639 struct cfg80211_match_set *match; 1640 struct cfg80211_ssid *ssid; 1641 struct sk_buff *skb; 1642 int i; 1643 1644 skb = mt76_mcu_msg_alloc(mdev, NULL, sizeof(*req) + sreq->ie_len); 1645 if (!skb) 1646 return -ENOMEM; 1647 1648 mvif->scan_seq_num = (mvif->scan_seq_num + 1) & 0x7f; 1649 1650 req = (struct mt76_connac_sched_scan_req *)skb_put(skb, sizeof(*req)); 1651 req->version = 1; 1652 req->seq_num = mvif->scan_seq_num | mvif->band_idx << 7; 1653 1654 if (sreq->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) { 1655 u8 *addr = is_mt7663(phy->dev) ? req->mt7663.random_mac 1656 : req->mt7921.random_mac; 1657 1658 req->scan_func = 1; 1659 get_random_mask_addr(addr, sreq->mac_addr, 1660 sreq->mac_addr_mask); 1661 } 1662 if (is_mt7921(phy->dev)) { 1663 req->mt7921.bss_idx = mvif->idx; 1664 req->mt7921.delay = cpu_to_le32(sreq->delay); 1665 } 1666 1667 req->ssids_num = sreq->n_ssids; 1668 for (i = 0; i < req->ssids_num; i++) { 1669 ssid = &sreq->ssids[i]; 1670 memcpy(req->ssids[i].ssid, ssid->ssid, ssid->ssid_len); 1671 req->ssids[i].ssid_len = cpu_to_le32(ssid->ssid_len); 1672 } 1673 1674 req->match_num = sreq->n_match_sets; 1675 for (i = 0; i < req->match_num; i++) { 1676 match = &sreq->match_sets[i]; 1677 memcpy(req->match[i].ssid, match->ssid.ssid, 1678 match->ssid.ssid_len); 1679 req->match[i].rssi_th = cpu_to_le32(match->rssi_thold); 1680 req->match[i].ssid_len = match->ssid.ssid_len; 1681 } 1682 1683 req->channel_type = sreq->n_channels ? 4 : 0; 1684 req->channels_num = min_t(u8, sreq->n_channels, 64); 1685 for (i = 0; i < req->channels_num; i++) { 1686 chan = &req->channels[i]; 1687 1688 switch (scan_list[i]->band) { 1689 case NL80211_BAND_2GHZ: 1690 chan->band = 1; 1691 break; 1692 case NL80211_BAND_6GHZ: 1693 chan->band = 3; 1694 break; 1695 default: 1696 chan->band = 2; 1697 break; 1698 } 1699 chan->channel_num = scan_list[i]->hw_value; 1700 } 1701 1702 req->intervals_num = sreq->n_scan_plans; 1703 for (i = 0; i < req->intervals_num; i++) 1704 req->intervals[i] = cpu_to_le16(sreq->scan_plans[i].interval); 1705 1706 if (sreq->ie_len > 0) { 1707 req->ie_len = cpu_to_le16(sreq->ie_len); 1708 memcpy(skb_put(skb, sreq->ie_len), sreq->ie, sreq->ie_len); 1709 } 1710 1711 return mt76_mcu_skb_send_msg(mdev, skb, MCU_CE_CMD(SCHED_SCAN_REQ), 1712 false); 1713} 1714EXPORT_SYMBOL_GPL(mt76_connac_mcu_sched_scan_req); 1715 1716int mt76_connac_mcu_sched_scan_enable(struct mt76_phy *phy, 1717 struct ieee80211_vif *vif, 1718 bool enable) 1719{ 1720 struct { 1721 u8 active; /* 0: enabled 1: disabled */ 1722 u8 rsv[3]; 1723 } __packed req = { 1724 .active = !enable, 1725 }; 1726 1727 if (enable) 1728 set_bit(MT76_HW_SCHED_SCANNING, &phy->state); 1729 else 1730 clear_bit(MT76_HW_SCHED_SCANNING, &phy->state); 1731 1732 return mt76_mcu_send_msg(phy->dev, MCU_CE_CMD(SCHED_SCAN_ENABLE), 1733 &req, sizeof(req), false); 1734} 1735EXPORT_SYMBOL_GPL(mt76_connac_mcu_sched_scan_enable); 1736 1737int mt76_connac_mcu_chip_config(struct mt76_dev *dev) 1738{ 1739 struct mt76_connac_config req = { 1740 .resp_type = 0, 1741 }; 1742 1743 memcpy(req.data, "assert", 7); 1744 1745 return mt76_mcu_send_msg(dev, MCU_CE_CMD(CHIP_CONFIG), 1746 &req, sizeof(req), false); 1747} 1748EXPORT_SYMBOL_GPL(mt76_connac_mcu_chip_config); 1749 1750int mt76_connac_mcu_set_deep_sleep(struct mt76_dev *dev, bool enable) 1751{ 1752 struct mt76_connac_config req = { 1753 .resp_type = 0, 1754 }; 1755 1756 snprintf(req.data, sizeof(req.data), "KeepFullPwr %d", !enable); 1757 1758 return mt76_mcu_send_msg(dev, MCU_CE_CMD(CHIP_CONFIG), 1759 &req, sizeof(req), false); 1760} 1761EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_deep_sleep); 1762 1763int mt76_connac_sta_state_dp(struct mt76_dev *dev, 1764 enum ieee80211_sta_state old_state, 1765 enum ieee80211_sta_state new_state) 1766{ 1767 if ((old_state == IEEE80211_STA_ASSOC && 1768 new_state == IEEE80211_STA_AUTHORIZED) || 1769 (old_state == IEEE80211_STA_NONE && 1770 new_state == IEEE80211_STA_NOTEXIST)) 1771 mt76_connac_mcu_set_deep_sleep(dev, true); 1772 1773 if ((old_state == IEEE80211_STA_NOTEXIST && 1774 new_state == IEEE80211_STA_NONE) || 1775 (old_state == IEEE80211_STA_AUTHORIZED && 1776 new_state == IEEE80211_STA_ASSOC)) 1777 mt76_connac_mcu_set_deep_sleep(dev, false); 1778 1779 return 0; 1780} 1781EXPORT_SYMBOL_GPL(mt76_connac_sta_state_dp); 1782 1783void mt76_connac_mcu_coredump_event(struct mt76_dev *dev, struct sk_buff *skb, 1784 struct mt76_connac_coredump *coredump) 1785{ 1786 spin_lock_bh(&dev->lock); 1787 __skb_queue_tail(&coredump->msg_list, skb); 1788 spin_unlock_bh(&dev->lock); 1789 1790 coredump->last_activity = jiffies; 1791 1792 queue_delayed_work(dev->wq, &coredump->work, 1793 MT76_CONNAC_COREDUMP_TIMEOUT); 1794} 1795EXPORT_SYMBOL_GPL(mt76_connac_mcu_coredump_event); 1796 1797static void mt76_connac_mcu_parse_tx_resource(struct mt76_dev *dev, 1798 struct sk_buff *skb) 1799{ 1800 struct mt76_sdio *sdio = &dev->sdio; 1801 struct mt76_connac_tx_resource { 1802 __le32 version; 1803 __le32 pse_data_quota; 1804 __le32 pse_mcu_quota; 1805 __le32 ple_data_quota; 1806 __le32 ple_mcu_quota; 1807 __le16 pse_page_size; 1808 __le16 ple_page_size; 1809 u8 pp_padding; 1810 u8 pad[3]; 1811 } __packed * tx_res; 1812 1813 tx_res = (struct mt76_connac_tx_resource *)skb->data; 1814 sdio->sched.pse_data_quota = le32_to_cpu(tx_res->pse_data_quota); 1815 sdio->sched.pse_mcu_quota = le32_to_cpu(tx_res->pse_mcu_quota); 1816 sdio->sched.ple_data_quota = le32_to_cpu(tx_res->ple_data_quota); 1817 sdio->sched.pse_page_size = le16_to_cpu(tx_res->pse_page_size); 1818 sdio->sched.deficit = tx_res->pp_padding; 1819} 1820 1821static void mt76_connac_mcu_parse_phy_cap(struct mt76_dev *dev, 1822 struct sk_buff *skb) 1823{ 1824 struct mt76_connac_phy_cap { 1825 u8 ht; 1826 u8 vht; 1827 u8 _5g; 1828 u8 max_bw; 1829 u8 nss; 1830 u8 dbdc; 1831 u8 tx_ldpc; 1832 u8 rx_ldpc; 1833 u8 tx_stbc; 1834 u8 rx_stbc; 1835 u8 hw_path; 1836 u8 he; 1837 } __packed * cap; 1838 1839 enum { 1840 WF0_24G, 1841 WF0_5G 1842 }; 1843 1844 cap = (struct mt76_connac_phy_cap *)skb->data; 1845 1846 dev->phy.antenna_mask = BIT(cap->nss) - 1; 1847 dev->phy.chainmask = dev->phy.antenna_mask; 1848 dev->phy.cap.has_2ghz = cap->hw_path & BIT(WF0_24G); 1849 dev->phy.cap.has_5ghz = cap->hw_path & BIT(WF0_5G); 1850} 1851 1852int mt76_connac_mcu_get_nic_capability(struct mt76_phy *phy) 1853{ 1854 struct mt76_connac_cap_hdr { 1855 __le16 n_element; 1856 u8 rsv[2]; 1857 } __packed * hdr; 1858 struct sk_buff *skb; 1859 int ret, i; 1860 1861 ret = mt76_mcu_send_and_get_msg(phy->dev, MCU_CE_CMD(GET_NIC_CAPAB), 1862 NULL, 0, true, &skb); 1863 if (ret) 1864 return ret; 1865 1866 hdr = (struct mt76_connac_cap_hdr *)skb->data; 1867 if (skb->len < sizeof(*hdr)) { 1868 ret = -EINVAL; 1869 goto out; 1870 } 1871 1872 skb_pull(skb, sizeof(*hdr)); 1873 1874 for (i = 0; i < le16_to_cpu(hdr->n_element); i++) { 1875 struct tlv_hdr { 1876 __le32 type; 1877 __le32 len; 1878 } __packed * tlv = (struct tlv_hdr *)skb->data; 1879 int len; 1880 1881 if (skb->len < sizeof(*tlv)) 1882 break; 1883 1884 skb_pull(skb, sizeof(*tlv)); 1885 1886 len = le32_to_cpu(tlv->len); 1887 if (skb->len < len) 1888 break; 1889 1890 switch (le32_to_cpu(tlv->type)) { 1891 case MT_NIC_CAP_6G: 1892 phy->cap.has_6ghz = skb->data[0]; 1893 break; 1894 case MT_NIC_CAP_MAC_ADDR: 1895 memcpy(phy->macaddr, (void *)skb->data, ETH_ALEN); 1896 break; 1897 case MT_NIC_CAP_PHY: 1898 mt76_connac_mcu_parse_phy_cap(phy->dev, skb); 1899 break; 1900 case MT_NIC_CAP_TX_RESOURCE: 1901 if (mt76_is_sdio(phy->dev)) 1902 mt76_connac_mcu_parse_tx_resource(phy->dev, 1903 skb); 1904 break; 1905 default: 1906 break; 1907 } 1908 skb_pull(skb, len); 1909 } 1910out: 1911 dev_kfree_skb(skb); 1912 1913 return ret; 1914} 1915EXPORT_SYMBOL_GPL(mt76_connac_mcu_get_nic_capability); 1916 1917static void 1918mt76_connac_mcu_build_sku(struct mt76_dev *dev, s8 *sku, 1919 struct mt76_power_limits *limits, 1920 enum nl80211_band band) 1921{ 1922 int max_power = is_mt7921(dev) ? 127 : 63; 1923 int i, offset = sizeof(limits->cck); 1924 1925 memset(sku, max_power, MT_SKU_POWER_LIMIT); 1926 1927 if (band == NL80211_BAND_2GHZ) { 1928 /* cck */ 1929 memcpy(sku, limits->cck, sizeof(limits->cck)); 1930 } 1931 1932 /* ofdm */ 1933 memcpy(&sku[offset], limits->ofdm, sizeof(limits->ofdm)); 1934 offset += sizeof(limits->ofdm); 1935 1936 /* ht */ 1937 for (i = 0; i < 2; i++) { 1938 memcpy(&sku[offset], limits->mcs[i], 8); 1939 offset += 8; 1940 } 1941 sku[offset++] = limits->mcs[0][0]; 1942 1943 /* vht */ 1944 for (i = 0; i < ARRAY_SIZE(limits->mcs); i++) { 1945 memcpy(&sku[offset], limits->mcs[i], 1946 ARRAY_SIZE(limits->mcs[i])); 1947 offset += 12; 1948 } 1949 1950 if (!is_mt7921(dev)) 1951 return; 1952 1953 /* he */ 1954 for (i = 0; i < ARRAY_SIZE(limits->ru); i++) { 1955 memcpy(&sku[offset], limits->ru[i], ARRAY_SIZE(limits->ru[i])); 1956 offset += ARRAY_SIZE(limits->ru[i]); 1957 } 1958} 1959 1960static s8 mt76_connac_get_ch_power(struct mt76_phy *phy, 1961 struct ieee80211_channel *chan, 1962 s8 target_power) 1963{ 1964 struct mt76_dev *dev = phy->dev; 1965 struct ieee80211_supported_band *sband; 1966 int i; 1967 1968 switch (chan->band) { 1969 case NL80211_BAND_2GHZ: 1970 sband = &phy->sband_2g.sband; 1971 break; 1972 case NL80211_BAND_5GHZ: 1973 sband = &phy->sband_5g.sband; 1974 break; 1975 case NL80211_BAND_6GHZ: 1976 sband = &phy->sband_6g.sband; 1977 break; 1978 default: 1979 return target_power; 1980 } 1981 1982 for (i = 0; i < sband->n_channels; i++) { 1983 struct ieee80211_channel *ch = &sband->channels[i]; 1984 1985 if (ch->hw_value == chan->hw_value) { 1986 if (!(ch->flags & IEEE80211_CHAN_DISABLED)) { 1987 int power = 2 * ch->max_reg_power; 1988 1989 if (is_mt7663(dev) && (power > 63 || power < -64)) 1990 power = 63; 1991 target_power = min_t(s8, power, target_power); 1992 } 1993 break; 1994 } 1995 } 1996 1997 return target_power; 1998} 1999 2000static int 2001mt76_connac_mcu_rate_txpower_band(struct mt76_phy *phy, 2002 enum nl80211_band band) 2003{ 2004 struct mt76_dev *dev = phy->dev; 2005 int sku_len, batch_len = is_mt7921(dev) ? 8 : 16; 2006 static const u8 chan_list_2ghz[] = { 2007 1, 2, 3, 4, 5, 6, 7, 2008 8, 9, 10, 11, 12, 13, 14 2009 }; 2010 static const u8 chan_list_5ghz[] = { 2011 36, 38, 40, 42, 44, 46, 48, 2012 50, 52, 54, 56, 58, 60, 62, 2013 64, 100, 102, 104, 106, 108, 110, 2014 112, 114, 116, 118, 120, 122, 124, 2015 126, 128, 132, 134, 136, 138, 140, 2016 142, 144, 149, 151, 153, 155, 157, 2017 159, 161, 165 2018 }; 2019 static const u8 chan_list_6ghz[] = { 2020 1, 3, 5, 7, 9, 11, 13, 2021 15, 17, 19, 21, 23, 25, 27, 2022 29, 33, 35, 37, 39, 41, 43, 2023 45, 47, 49, 51, 53, 55, 57, 2024 59, 61, 65, 67, 69, 71, 73, 2025 75, 77, 79, 81, 83, 85, 87, 2026 89, 91, 93, 97, 99, 101, 103, 2027 105, 107, 109, 111, 113, 115, 117, 2028 119, 121, 123, 125, 129, 131, 133, 2029 135, 137, 139, 141, 143, 145, 147, 2030 149, 151, 153, 155, 157, 161, 163, 2031 165, 167, 169, 171, 173, 175, 177, 2032 179, 181, 183, 185, 187, 189, 193, 2033 195, 197, 199, 201, 203, 205, 207, 2034 209, 211, 213, 215, 217, 219, 221, 2035 225, 227, 229, 233 2036 }; 2037 int i, n_chan, batch_size, idx = 0, tx_power, last_ch; 2038 struct mt76_connac_sku_tlv sku_tlbv; 2039 struct mt76_power_limits limits; 2040 const u8 *ch_list; 2041 2042 sku_len = is_mt7921(dev) ? sizeof(sku_tlbv) : sizeof(sku_tlbv) - 92; 2043 tx_power = 2 * phy->hw->conf.power_level; 2044 if (!tx_power) 2045 tx_power = 127; 2046 2047 if (band == NL80211_BAND_2GHZ) { 2048 n_chan = ARRAY_SIZE(chan_list_2ghz); 2049 ch_list = chan_list_2ghz; 2050 } else if (band == NL80211_BAND_6GHZ) { 2051 n_chan = ARRAY_SIZE(chan_list_6ghz); 2052 ch_list = chan_list_6ghz; 2053 } else { 2054 n_chan = ARRAY_SIZE(chan_list_5ghz); 2055 ch_list = chan_list_5ghz; 2056 } 2057 batch_size = DIV_ROUND_UP(n_chan, batch_len); 2058 2059 if (phy->cap.has_6ghz) 2060 last_ch = chan_list_6ghz[ARRAY_SIZE(chan_list_6ghz) - 1]; 2061 else if (phy->cap.has_5ghz) 2062 last_ch = chan_list_5ghz[ARRAY_SIZE(chan_list_5ghz) - 1]; 2063 else 2064 last_ch = chan_list_2ghz[ARRAY_SIZE(chan_list_2ghz) - 1]; 2065 2066 for (i = 0; i < batch_size; i++) { 2067 struct mt76_connac_tx_power_limit_tlv tx_power_tlv = {}; 2068 int j, err, msg_len, num_ch; 2069 struct sk_buff *skb; 2070 2071 num_ch = i == batch_size - 1 ? n_chan % batch_len : batch_len; 2072 msg_len = sizeof(tx_power_tlv) + num_ch * sizeof(sku_tlbv); 2073 skb = mt76_mcu_msg_alloc(dev, NULL, msg_len); 2074 if (!skb) 2075 return -ENOMEM; 2076 2077 skb_reserve(skb, sizeof(tx_power_tlv)); 2078 2079 BUILD_BUG_ON(sizeof(dev->alpha2) > sizeof(tx_power_tlv.alpha2)); 2080 memcpy(tx_power_tlv.alpha2, dev->alpha2, sizeof(dev->alpha2)); 2081 tx_power_tlv.n_chan = num_ch; 2082 2083 switch (band) { 2084 case NL80211_BAND_2GHZ: 2085 tx_power_tlv.band = 1; 2086 break; 2087 case NL80211_BAND_6GHZ: 2088 tx_power_tlv.band = 3; 2089 break; 2090 default: 2091 tx_power_tlv.band = 2; 2092 break; 2093 } 2094 2095 for (j = 0; j < num_ch; j++, idx++) { 2096 struct ieee80211_channel chan = { 2097 .hw_value = ch_list[idx], 2098 .band = band, 2099 }; 2100 s8 reg_power, sar_power; 2101 2102 reg_power = mt76_connac_get_ch_power(phy, &chan, 2103 tx_power); 2104 sar_power = mt76_get_sar_power(phy, &chan, reg_power); 2105 2106 mt76_get_rate_power_limits(phy, &chan, &limits, 2107 sar_power); 2108 2109 tx_power_tlv.last_msg = ch_list[idx] == last_ch; 2110 sku_tlbv.channel = ch_list[idx]; 2111 2112 mt76_connac_mcu_build_sku(dev, sku_tlbv.pwr_limit, 2113 &limits, band); 2114 skb_put_data(skb, &sku_tlbv, sku_len); 2115 } 2116 __skb_push(skb, sizeof(tx_power_tlv)); 2117 memcpy(skb->data, &tx_power_tlv, sizeof(tx_power_tlv)); 2118 2119 err = mt76_mcu_skb_send_msg(dev, skb, 2120 MCU_CE_CMD(SET_RATE_TX_POWER), 2121 false); 2122 if (err < 0) 2123 return err; 2124 } 2125 2126 return 0; 2127} 2128 2129int mt76_connac_mcu_set_rate_txpower(struct mt76_phy *phy) 2130{ 2131 int err; 2132 2133 if (phy->cap.has_2ghz) { 2134 err = mt76_connac_mcu_rate_txpower_band(phy, 2135 NL80211_BAND_2GHZ); 2136 if (err < 0) 2137 return err; 2138 } 2139 if (phy->cap.has_5ghz) { 2140 err = mt76_connac_mcu_rate_txpower_band(phy, 2141 NL80211_BAND_5GHZ); 2142 if (err < 0) 2143 return err; 2144 } 2145 if (phy->cap.has_6ghz) { 2146 err = mt76_connac_mcu_rate_txpower_band(phy, 2147 NL80211_BAND_6GHZ); 2148 if (err < 0) 2149 return err; 2150 } 2151 2152 return 0; 2153} 2154EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_rate_txpower); 2155 2156int mt76_connac_mcu_update_arp_filter(struct mt76_dev *dev, 2157 struct mt76_vif *vif, 2158 struct ieee80211_bss_conf *info) 2159{ 2160 struct sk_buff *skb; 2161 int i, len = min_t(int, info->arp_addr_cnt, 2162 IEEE80211_BSS_ARP_ADDR_LIST_LEN); 2163 struct { 2164 struct { 2165 u8 bss_idx; 2166 u8 pad[3]; 2167 } __packed hdr; 2168 struct mt76_connac_arpns_tlv arp; 2169 } req_hdr = { 2170 .hdr = { 2171 .bss_idx = vif->idx, 2172 }, 2173 .arp = { 2174 .tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_ARP), 2175 .len = cpu_to_le16(sizeof(struct mt76_connac_arpns_tlv)), 2176 .ips_num = len, 2177 .mode = 2, /* update */ 2178 .option = 1, 2179 }, 2180 }; 2181 2182 skb = mt76_mcu_msg_alloc(dev, NULL, 2183 sizeof(req_hdr) + len * sizeof(__be32)); 2184 if (!skb) 2185 return -ENOMEM; 2186 2187 skb_put_data(skb, &req_hdr, sizeof(req_hdr)); 2188 for (i = 0; i < len; i++) 2189 skb_put_data(skb, &info->arp_addr_list[i], sizeof(__be32)); 2190 2191 return mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD(OFFLOAD), true); 2192} 2193EXPORT_SYMBOL_GPL(mt76_connac_mcu_update_arp_filter); 2194 2195int mt76_connac_mcu_set_p2p_oppps(struct ieee80211_hw *hw, 2196 struct ieee80211_vif *vif) 2197{ 2198 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 2199 int ct_window = vif->bss_conf.p2p_noa_attr.oppps_ctwindow; 2200 struct mt76_phy *phy = hw->priv; 2201 struct { 2202 __le32 ct_win; 2203 u8 bss_idx; 2204 u8 rsv[3]; 2205 } __packed req = { 2206 .ct_win = cpu_to_le32(ct_window), 2207 .bss_idx = mvif->idx, 2208 }; 2209 2210 return mt76_mcu_send_msg(phy->dev, MCU_CE_CMD(SET_P2P_OPPPS), 2211 &req, sizeof(req), false); 2212} 2213EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_p2p_oppps); 2214 2215#ifdef CONFIG_PM 2216 2217const struct wiphy_wowlan_support mt76_connac_wowlan_support = { 2218 .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT | 2219 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | WIPHY_WOWLAN_NET_DETECT, 2220 .n_patterns = 1, 2221 .pattern_min_len = 1, 2222 .pattern_max_len = MT76_CONNAC_WOW_PATTEN_MAX_LEN, 2223 .max_nd_match_sets = 10, 2224}; 2225EXPORT_SYMBOL_GPL(mt76_connac_wowlan_support); 2226 2227static void 2228mt76_connac_mcu_key_iter(struct ieee80211_hw *hw, 2229 struct ieee80211_vif *vif, 2230 struct ieee80211_sta *sta, 2231 struct ieee80211_key_conf *key, 2232 void *data) 2233{ 2234 struct mt76_connac_gtk_rekey_tlv *gtk_tlv = data; 2235 u32 cipher; 2236 2237 if (key->cipher != WLAN_CIPHER_SUITE_AES_CMAC && 2238 key->cipher != WLAN_CIPHER_SUITE_CCMP && 2239 key->cipher != WLAN_CIPHER_SUITE_TKIP) 2240 return; 2241 2242 if (key->cipher == WLAN_CIPHER_SUITE_TKIP) 2243 cipher = BIT(3); 2244 else 2245 cipher = BIT(4); 2246 2247 /* we are assuming here to have a single pairwise key */ 2248 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { 2249 if (key->cipher == WLAN_CIPHER_SUITE_TKIP) 2250 gtk_tlv->proto = cpu_to_le32(NL80211_WPA_VERSION_1); 2251 else 2252 gtk_tlv->proto = cpu_to_le32(NL80211_WPA_VERSION_2); 2253 2254 gtk_tlv->pairwise_cipher = cpu_to_le32(cipher); 2255 gtk_tlv->keyid = key->keyidx; 2256 } else { 2257 gtk_tlv->group_cipher = cpu_to_le32(cipher); 2258 } 2259} 2260 2261int mt76_connac_mcu_update_gtk_rekey(struct ieee80211_hw *hw, 2262 struct ieee80211_vif *vif, 2263 struct cfg80211_gtk_rekey_data *key) 2264{ 2265 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 2266 struct mt76_connac_gtk_rekey_tlv *gtk_tlv; 2267 struct mt76_phy *phy = hw->priv; 2268 struct sk_buff *skb; 2269 struct { 2270 u8 bss_idx; 2271 u8 pad[3]; 2272 } __packed hdr = { 2273 .bss_idx = mvif->idx, 2274 }; 2275 2276 skb = mt76_mcu_msg_alloc(phy->dev, NULL, 2277 sizeof(hdr) + sizeof(*gtk_tlv)); 2278 if (!skb) 2279 return -ENOMEM; 2280 2281 skb_put_data(skb, &hdr, sizeof(hdr)); 2282 gtk_tlv = (struct mt76_connac_gtk_rekey_tlv *)skb_put(skb, 2283 sizeof(*gtk_tlv)); 2284 gtk_tlv->tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_GTK_REKEY); 2285 gtk_tlv->len = cpu_to_le16(sizeof(*gtk_tlv)); 2286 gtk_tlv->rekey_mode = 2; 2287 gtk_tlv->option = 1; 2288 2289 rcu_read_lock(); 2290 ieee80211_iter_keys_rcu(hw, vif, mt76_connac_mcu_key_iter, gtk_tlv); 2291 rcu_read_unlock(); 2292 2293 memcpy(gtk_tlv->kek, key->kek, NL80211_KEK_LEN); 2294 memcpy(gtk_tlv->kck, key->kck, NL80211_KCK_LEN); 2295 memcpy(gtk_tlv->replay_ctr, key->replay_ctr, NL80211_REPLAY_CTR_LEN); 2296 2297 return mt76_mcu_skb_send_msg(phy->dev, skb, 2298 MCU_UNI_CMD(OFFLOAD), true); 2299} 2300EXPORT_SYMBOL_GPL(mt76_connac_mcu_update_gtk_rekey); 2301 2302static int 2303mt76_connac_mcu_set_arp_filter(struct mt76_dev *dev, struct ieee80211_vif *vif, 2304 bool suspend) 2305{ 2306 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 2307 struct { 2308 struct { 2309 u8 bss_idx; 2310 u8 pad[3]; 2311 } __packed hdr; 2312 struct mt76_connac_arpns_tlv arpns; 2313 } req = { 2314 .hdr = { 2315 .bss_idx = mvif->idx, 2316 }, 2317 .arpns = { 2318 .tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_ARP), 2319 .len = cpu_to_le16(sizeof(struct mt76_connac_arpns_tlv)), 2320 .mode = suspend, 2321 }, 2322 }; 2323 2324 return mt76_mcu_send_msg(dev, MCU_UNI_CMD(OFFLOAD), &req, 2325 sizeof(req), true); 2326} 2327 2328static int 2329mt76_connac_mcu_set_gtk_rekey(struct mt76_dev *dev, struct ieee80211_vif *vif, 2330 bool suspend) 2331{ 2332 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 2333 struct { 2334 struct { 2335 u8 bss_idx; 2336 u8 pad[3]; 2337 } __packed hdr; 2338 struct mt76_connac_gtk_rekey_tlv gtk_tlv; 2339 } __packed req = { 2340 .hdr = { 2341 .bss_idx = mvif->idx, 2342 }, 2343 .gtk_tlv = { 2344 .tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_GTK_REKEY), 2345 .len = cpu_to_le16(sizeof(struct mt76_connac_gtk_rekey_tlv)), 2346 .rekey_mode = !suspend, 2347 }, 2348 }; 2349 2350 return mt76_mcu_send_msg(dev, MCU_UNI_CMD(OFFLOAD), &req, 2351 sizeof(req), true); 2352} 2353 2354static int 2355mt76_connac_mcu_set_suspend_mode(struct mt76_dev *dev, 2356 struct ieee80211_vif *vif, 2357 bool enable, u8 mdtim, 2358 bool wow_suspend) 2359{ 2360 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 2361 struct { 2362 struct { 2363 u8 bss_idx; 2364 u8 pad[3]; 2365 } __packed hdr; 2366 struct mt76_connac_suspend_tlv suspend_tlv; 2367 } req = { 2368 .hdr = { 2369 .bss_idx = mvif->idx, 2370 }, 2371 .suspend_tlv = { 2372 .tag = cpu_to_le16(UNI_SUSPEND_MODE_SETTING), 2373 .len = cpu_to_le16(sizeof(struct mt76_connac_suspend_tlv)), 2374 .enable = enable, 2375 .mdtim = mdtim, 2376 .wow_suspend = wow_suspend, 2377 }, 2378 }; 2379 2380 return mt76_mcu_send_msg(dev, MCU_UNI_CMD(SUSPEND), &req, 2381 sizeof(req), true); 2382} 2383 2384static int 2385mt76_connac_mcu_set_wow_pattern(struct mt76_dev *dev, 2386 struct ieee80211_vif *vif, 2387 u8 index, bool enable, 2388 struct cfg80211_pkt_pattern *pattern) 2389{ 2390 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 2391 struct mt76_connac_wow_pattern_tlv *ptlv; 2392 struct sk_buff *skb; 2393 struct req_hdr { 2394 u8 bss_idx; 2395 u8 pad[3]; 2396 } __packed hdr = { 2397 .bss_idx = mvif->idx, 2398 }; 2399 2400 skb = mt76_mcu_msg_alloc(dev, NULL, sizeof(hdr) + sizeof(*ptlv)); 2401 if (!skb) 2402 return -ENOMEM; 2403 2404 skb_put_data(skb, &hdr, sizeof(hdr)); 2405 ptlv = (struct mt76_connac_wow_pattern_tlv *)skb_put(skb, sizeof(*ptlv)); 2406 ptlv->tag = cpu_to_le16(UNI_SUSPEND_WOW_PATTERN); 2407 ptlv->len = cpu_to_le16(sizeof(*ptlv)); 2408 ptlv->data_len = pattern->pattern_len; 2409 ptlv->enable = enable; 2410 ptlv->index = index; 2411 2412 memcpy(ptlv->pattern, pattern->pattern, pattern->pattern_len); 2413 memcpy(ptlv->mask, pattern->mask, DIV_ROUND_UP(pattern->pattern_len, 8)); 2414 2415 return mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD(SUSPEND), true); 2416} 2417 2418static int 2419mt76_connac_mcu_set_wow_ctrl(struct mt76_phy *phy, struct ieee80211_vif *vif, 2420 bool suspend, struct cfg80211_wowlan *wowlan) 2421{ 2422 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 2423 struct mt76_dev *dev = phy->dev; 2424 struct { 2425 struct { 2426 u8 bss_idx; 2427 u8 pad[3]; 2428 } __packed hdr; 2429 struct mt76_connac_wow_ctrl_tlv wow_ctrl_tlv; 2430 struct mt76_connac_wow_gpio_param_tlv gpio_tlv; 2431 } req = { 2432 .hdr = { 2433 .bss_idx = mvif->idx, 2434 }, 2435 .wow_ctrl_tlv = { 2436 .tag = cpu_to_le16(UNI_SUSPEND_WOW_CTRL), 2437 .len = cpu_to_le16(sizeof(struct mt76_connac_wow_ctrl_tlv)), 2438 .cmd = suspend ? 1 : 2, 2439 }, 2440 .gpio_tlv = { 2441 .tag = cpu_to_le16(UNI_SUSPEND_WOW_GPIO_PARAM), 2442 .len = cpu_to_le16(sizeof(struct mt76_connac_wow_gpio_param_tlv)), 2443 .gpio_pin = 0xff, /* follow fw about GPIO pin */ 2444 }, 2445 }; 2446 2447 if (wowlan->magic_pkt) 2448 req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_MAGIC; 2449 if (wowlan->disconnect) 2450 req.wow_ctrl_tlv.trigger |= (UNI_WOW_DETECT_TYPE_DISCONNECT | 2451 UNI_WOW_DETECT_TYPE_BCN_LOST); 2452 if (wowlan->nd_config) { 2453 mt76_connac_mcu_sched_scan_req(phy, vif, wowlan->nd_config); 2454 req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_SCH_SCAN_HIT; 2455 mt76_connac_mcu_sched_scan_enable(phy, vif, suspend); 2456 } 2457 if (wowlan->n_patterns) 2458 req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_BITMAP; 2459 2460 if (mt76_is_mmio(dev)) 2461 req.wow_ctrl_tlv.wakeup_hif = WOW_PCIE; 2462 else if (mt76_is_usb(dev)) 2463 req.wow_ctrl_tlv.wakeup_hif = WOW_USB; 2464 else if (mt76_is_sdio(dev)) 2465 req.wow_ctrl_tlv.wakeup_hif = WOW_GPIO; 2466 2467 return mt76_mcu_send_msg(dev, MCU_UNI_CMD(SUSPEND), &req, 2468 sizeof(req), true); 2469} 2470 2471int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend) 2472{ 2473 struct { 2474 struct { 2475 u8 hif_type; /* 0x0: HIF_SDIO 2476 * 0x1: HIF_USB 2477 * 0x2: HIF_PCIE 2478 */ 2479 u8 pad[3]; 2480 } __packed hdr; 2481 struct hif_suspend_tlv { 2482 __le16 tag; 2483 __le16 len; 2484 u8 suspend; 2485 } __packed hif_suspend; 2486 } req = { 2487 .hif_suspend = { 2488 .tag = cpu_to_le16(0), /* 0: UNI_HIF_CTRL_BASIC */ 2489 .len = cpu_to_le16(sizeof(struct hif_suspend_tlv)), 2490 .suspend = suspend, 2491 }, 2492 }; 2493 2494 if (mt76_is_mmio(dev)) 2495 req.hdr.hif_type = 2; 2496 else if (mt76_is_usb(dev)) 2497 req.hdr.hif_type = 1; 2498 else if (mt76_is_sdio(dev)) 2499 req.hdr.hif_type = 0; 2500 2501 return mt76_mcu_send_msg(dev, MCU_UNI_CMD(HIF_CTRL), &req, 2502 sizeof(req), true); 2503} 2504EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_hif_suspend); 2505 2506void mt76_connac_mcu_set_suspend_iter(void *priv, u8 *mac, 2507 struct ieee80211_vif *vif) 2508{ 2509 struct mt76_phy *phy = priv; 2510 bool suspend = !test_bit(MT76_STATE_RUNNING, &phy->state); 2511 struct ieee80211_hw *hw = phy->hw; 2512 struct cfg80211_wowlan *wowlan = hw->wiphy->wowlan_config; 2513 int i; 2514 2515 mt76_connac_mcu_set_gtk_rekey(phy->dev, vif, suspend); 2516 mt76_connac_mcu_set_arp_filter(phy->dev, vif, suspend); 2517 2518 mt76_connac_mcu_set_suspend_mode(phy->dev, vif, suspend, 1, true); 2519 2520 for (i = 0; i < wowlan->n_patterns; i++) 2521 mt76_connac_mcu_set_wow_pattern(phy->dev, vif, i, suspend, 2522 &wowlan->patterns[i]); 2523 mt76_connac_mcu_set_wow_ctrl(phy, vif, suspend, wowlan); 2524} 2525EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_suspend_iter); 2526#endif /* CONFIG_PM */ 2527 2528u32 mt76_connac_mcu_reg_rr(struct mt76_dev *dev, u32 offset) 2529{ 2530 struct { 2531 __le32 addr; 2532 __le32 val; 2533 } __packed req = { 2534 .addr = cpu_to_le32(offset), 2535 }; 2536 2537 return mt76_mcu_send_msg(dev, MCU_CE_QUERY(REG_READ), &req, 2538 sizeof(req), true); 2539} 2540EXPORT_SYMBOL_GPL(mt76_connac_mcu_reg_rr); 2541 2542void mt76_connac_mcu_reg_wr(struct mt76_dev *dev, u32 offset, u32 val) 2543{ 2544 struct { 2545 __le32 addr; 2546 __le32 val; 2547 } __packed req = { 2548 .addr = cpu_to_le32(offset), 2549 .val = cpu_to_le32(val), 2550 }; 2551 2552 mt76_mcu_send_msg(dev, MCU_CE_CMD(REG_WRITE), &req, 2553 sizeof(req), false); 2554} 2555EXPORT_SYMBOL_GPL(mt76_connac_mcu_reg_wr); 2556 2557static int 2558mt76_connac_mcu_sta_key_tlv(struct mt76_connac_sta_key_conf *sta_key_conf, 2559 struct sk_buff *skb, 2560 struct ieee80211_key_conf *key, 2561 enum set_key_cmd cmd) 2562{ 2563 struct sta_rec_sec *sec; 2564 u32 len = sizeof(*sec); 2565 struct tlv *tlv; 2566 2567 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_KEY_V2, sizeof(*sec)); 2568 sec = (struct sta_rec_sec *)tlv; 2569 sec->add = cmd; 2570 2571 if (cmd == SET_KEY) { 2572 struct sec_key *sec_key; 2573 u8 cipher; 2574 2575 cipher = mt76_connac_mcu_get_cipher(key->cipher); 2576 if (cipher == MCU_CIPHER_NONE) 2577 return -EOPNOTSUPP; 2578 2579 sec_key = &sec->key[0]; 2580 sec_key->cipher_len = sizeof(*sec_key); 2581 2582 if (cipher == MCU_CIPHER_BIP_CMAC_128) { 2583 sec_key->cipher_id = MCU_CIPHER_AES_CCMP; 2584 sec_key->key_id = sta_key_conf->keyidx; 2585 sec_key->key_len = 16; 2586 memcpy(sec_key->key, sta_key_conf->key, 16); 2587 2588 sec_key = &sec->key[1]; 2589 sec_key->cipher_id = MCU_CIPHER_BIP_CMAC_128; 2590 sec_key->cipher_len = sizeof(*sec_key); 2591 sec_key->key_len = 16; 2592 memcpy(sec_key->key, key->key, 16); 2593 sec->n_cipher = 2; 2594 } else { 2595 sec_key->cipher_id = cipher; 2596 sec_key->key_id = key->keyidx; 2597 sec_key->key_len = key->keylen; 2598 memcpy(sec_key->key, key->key, key->keylen); 2599 2600 if (cipher == MCU_CIPHER_TKIP) { 2601 /* Rx/Tx MIC keys are swapped */ 2602 memcpy(sec_key->key + 16, key->key + 24, 8); 2603 memcpy(sec_key->key + 24, key->key + 16, 8); 2604 } 2605 2606 /* store key_conf for BIP batch update */ 2607 if (cipher == MCU_CIPHER_AES_CCMP) { 2608 memcpy(sta_key_conf->key, key->key, key->keylen); 2609 sta_key_conf->keyidx = key->keyidx; 2610 } 2611 2612 len -= sizeof(*sec_key); 2613 sec->n_cipher = 1; 2614 } 2615 } else { 2616 len -= sizeof(sec->key); 2617 sec->n_cipher = 0; 2618 } 2619 sec->len = cpu_to_le16(len); 2620 2621 return 0; 2622} 2623 2624int mt76_connac_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif, 2625 struct mt76_connac_sta_key_conf *sta_key_conf, 2626 struct ieee80211_key_conf *key, int mcu_cmd, 2627 struct mt76_wcid *wcid, enum set_key_cmd cmd) 2628{ 2629 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 2630 struct sk_buff *skb; 2631 int ret; 2632 2633 skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid); 2634 if (IS_ERR(skb)) 2635 return PTR_ERR(skb); 2636 2637 ret = mt76_connac_mcu_sta_key_tlv(sta_key_conf, skb, key, cmd); 2638 if (ret) 2639 return ret; 2640 2641 return mt76_mcu_skb_send_msg(dev, skb, mcu_cmd, true); 2642} 2643EXPORT_SYMBOL_GPL(mt76_connac_mcu_add_key); 2644 2645/* SIFS 20us + 512 byte beacon tranmitted by 1Mbps (3906us) */ 2646#define BCN_TX_ESTIMATE_TIME (4096 + 20) 2647void mt76_connac_mcu_bss_ext_tlv(struct sk_buff *skb, struct mt76_vif *mvif) 2648{ 2649 struct bss_info_ext_bss *ext; 2650 int ext_bss_idx, tsf_offset; 2651 struct tlv *tlv; 2652 2653 ext_bss_idx = mvif->omac_idx - EXT_BSSID_START; 2654 if (ext_bss_idx < 0) 2655 return; 2656 2657 tlv = mt76_connac_mcu_add_tlv(skb, BSS_INFO_EXT_BSS, sizeof(*ext)); 2658 2659 ext = (struct bss_info_ext_bss *)tlv; 2660 tsf_offset = ext_bss_idx * BCN_TX_ESTIMATE_TIME; 2661 ext->mbss_tsf_offset = cpu_to_le32(tsf_offset); 2662} 2663EXPORT_SYMBOL_GPL(mt76_connac_mcu_bss_ext_tlv); 2664 2665int mt76_connac_mcu_bss_basic_tlv(struct sk_buff *skb, 2666 struct ieee80211_vif *vif, 2667 struct ieee80211_sta *sta, 2668 struct mt76_phy *phy, u16 wlan_idx, 2669 bool enable) 2670{ 2671 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 2672 u32 type = vif->p2p ? NETWORK_P2P : NETWORK_INFRA; 2673 struct bss_info_basic *bss; 2674 struct tlv *tlv; 2675 2676 tlv = mt76_connac_mcu_add_tlv(skb, BSS_INFO_BASIC, sizeof(*bss)); 2677 bss = (struct bss_info_basic *)tlv; 2678 2679 switch (vif->type) { 2680 case NL80211_IFTYPE_MESH_POINT: 2681 case NL80211_IFTYPE_MONITOR: 2682 break; 2683 case NL80211_IFTYPE_AP: 2684 if (ieee80211_hw_check(phy->hw, SUPPORTS_MULTI_BSSID)) { 2685 u8 bssid_id = vif->bss_conf.bssid_indicator; 2686 struct wiphy *wiphy = phy->hw->wiphy; 2687 2688 if (bssid_id > ilog2(wiphy->mbssid_max_interfaces)) 2689 return -EINVAL; 2690 2691 bss->non_tx_bssid = vif->bss_conf.bssid_index; 2692 bss->max_bssid = bssid_id; 2693 } 2694 break; 2695 case NL80211_IFTYPE_STATION: 2696 if (enable) { 2697 rcu_read_lock(); 2698 if (!sta) 2699 sta = ieee80211_find_sta(vif, 2700 vif->bss_conf.bssid); 2701 /* TODO: enable BSS_INFO_UAPSD & BSS_INFO_PM */ 2702 if (sta) { 2703 struct mt76_wcid *wcid; 2704 2705 wcid = (struct mt76_wcid *)sta->drv_priv; 2706 wlan_idx = wcid->idx; 2707 } 2708 rcu_read_unlock(); 2709 } 2710 break; 2711 case NL80211_IFTYPE_ADHOC: 2712 type = NETWORK_IBSS; 2713 break; 2714 default: 2715 WARN_ON(1); 2716 break; 2717 } 2718 2719 bss->network_type = cpu_to_le32(type); 2720 bss->bmc_wcid_lo = to_wcid_lo(wlan_idx); 2721 bss->bmc_wcid_hi = to_wcid_hi(wlan_idx); 2722 bss->wmm_idx = mvif->wmm_idx; 2723 bss->active = enable; 2724 bss->cipher = mvif->cipher; 2725 2726 if (vif->type != NL80211_IFTYPE_MONITOR) { 2727 struct cfg80211_chan_def *chandef = &phy->chandef; 2728 2729 memcpy(bss->bssid, vif->bss_conf.bssid, ETH_ALEN); 2730 bss->bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int); 2731 bss->dtim_period = vif->bss_conf.dtim_period; 2732 bss->phy_mode = mt76_connac_get_phy_mode(phy, vif, 2733 chandef->chan->band, NULL); 2734 } else { 2735 memcpy(bss->bssid, phy->macaddr, ETH_ALEN); 2736 } 2737 2738 return 0; 2739} 2740EXPORT_SYMBOL_GPL(mt76_connac_mcu_bss_basic_tlv); 2741 2742#define ENTER_PM_STATE 1 2743#define EXIT_PM_STATE 2 2744int mt76_connac_mcu_set_pm(struct mt76_dev *dev, int band, int enter) 2745{ 2746 struct { 2747 u8 pm_number; 2748 u8 pm_state; 2749 u8 bssid[ETH_ALEN]; 2750 u8 dtim_period; 2751 u8 wlan_idx_lo; 2752 __le16 bcn_interval; 2753 __le32 aid; 2754 __le32 rx_filter; 2755 u8 band_idx; 2756 u8 wlan_idx_hi; 2757 u8 rsv[2]; 2758 __le32 feature; 2759 u8 omac_idx; 2760 u8 wmm_idx; 2761 u8 bcn_loss_cnt; 2762 u8 bcn_sp_duration; 2763 } __packed req = { 2764 .pm_number = 5, 2765 .pm_state = enter ? ENTER_PM_STATE : EXIT_PM_STATE, 2766 .band_idx = band, 2767 }; 2768 2769 return mt76_mcu_send_msg(dev, MCU_EXT_CMD(PM_STATE_CTRL), &req, 2770 sizeof(req), true); 2771} 2772EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_pm); 2773 2774int mt76_connac_mcu_restart(struct mt76_dev *dev) 2775{ 2776 struct { 2777 u8 power_mode; 2778 u8 rsv[3]; 2779 } req = { 2780 .power_mode = 1, 2781 }; 2782 2783 return mt76_mcu_send_msg(dev, MCU_CMD(NIC_POWER_CTRL), &req, 2784 sizeof(req), false); 2785} 2786EXPORT_SYMBOL_GPL(mt76_connac_mcu_restart); 2787 2788int mt76_connac_mcu_rdd_cmd(struct mt76_dev *dev, int cmd, u8 index, 2789 u8 rx_sel, u8 val) 2790{ 2791 struct { 2792 u8 ctrl; 2793 u8 rdd_idx; 2794 u8 rdd_rx_sel; 2795 u8 val; 2796 u8 rsv[4]; 2797 } __packed req = { 2798 .ctrl = cmd, 2799 .rdd_idx = index, 2800 .rdd_rx_sel = rx_sel, 2801 .val = val, 2802 }; 2803 2804 return mt76_mcu_send_msg(dev, MCU_EXT_CMD(SET_RDD_CTRL), &req, 2805 sizeof(req), true); 2806} 2807EXPORT_SYMBOL_GPL(mt76_connac_mcu_rdd_cmd); 2808 2809MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); 2810MODULE_LICENSE("Dual BSD/GPL");