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->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 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->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 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->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 } 885 EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_tlv); 886 887 void 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 } 899 EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_smps_tlv); 900 901 void 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 } 977 EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_ht_tlv); 978 979 int 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 } 1023 EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_cmd); 1024 1025 void 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 } 1068 EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_ba_tlv); 1069 1070 int 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 } 1162 EXPORT_SYMBOL_GPL(mt76_connac_mcu_uni_add_dev); 1163 1164 void 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 } 1181 EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_ba_tlv); 1182 1183 int 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 } 1220 EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_ba); 1221 1222 u8 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 } 1273 EXPORT_SYMBOL_GPL(mt76_connac_get_phy_mode); 1274 1275 const struct ieee80211_sta_he_cap * 1276 mt76_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 } 1285 EXPORT_SYMBOL_GPL(mt76_connac_get_he_phy_cap); 1286 1287 #define DEFAULT_HE_PE_DURATION 4 1288 #define DEFAULT_HE_DURATION_RTS_THRES 1023 1289 static void 1290 mt76_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 1312 int 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 } 1506 EXPORT_SYMBOL_GPL(mt76_connac_mcu_uni_add_bss); 1507 1508 #define MT76_CONNAC_SCAN_CHANNEL_TIME 60 1509 int 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 } 1603 EXPORT_SYMBOL_GPL(mt76_connac_mcu_hw_scan); 1604 1605 int 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 } 1628 EXPORT_SYMBOL_GPL(mt76_connac_mcu_cancel_hw_scan); 1629 1630 int 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 } 1714 EXPORT_SYMBOL_GPL(mt76_connac_mcu_sched_scan_req); 1715 1716 int 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 } 1735 EXPORT_SYMBOL_GPL(mt76_connac_mcu_sched_scan_enable); 1736 1737 int 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 } 1748 EXPORT_SYMBOL_GPL(mt76_connac_mcu_chip_config); 1749 1750 int 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 } 1761 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_deep_sleep); 1762 1763 int 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 } 1781 EXPORT_SYMBOL_GPL(mt76_connac_sta_state_dp); 1782 1783 void 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 } 1795 EXPORT_SYMBOL_GPL(mt76_connac_mcu_coredump_event); 1796 1797 static 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 1821 static 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 1852 int 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 } 1910 out: 1911 dev_kfree_skb(skb); 1912 1913 return ret; 1914 } 1915 EXPORT_SYMBOL_GPL(mt76_connac_mcu_get_nic_capability); 1916 1917 static void 1918 mt76_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 1960 static 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 2000 static int 2001 mt76_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 2129 int 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 } 2154 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_rate_txpower); 2155 2156 int 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 u8 *addr = (u8 *)skb_put(skb, sizeof(__be32)); 2190 2191 memcpy(addr, &info->arp_addr_list[i], sizeof(__be32)); 2192 } 2193 2194 return mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD(OFFLOAD), true); 2195 } 2196 EXPORT_SYMBOL_GPL(mt76_connac_mcu_update_arp_filter); 2197 2198 int mt76_connac_mcu_set_p2p_oppps(struct ieee80211_hw *hw, 2199 struct ieee80211_vif *vif) 2200 { 2201 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 2202 int ct_window = vif->bss_conf.p2p_noa_attr.oppps_ctwindow; 2203 struct mt76_phy *phy = hw->priv; 2204 struct { 2205 __le32 ct_win; 2206 u8 bss_idx; 2207 u8 rsv[3]; 2208 } __packed req = { 2209 .ct_win = cpu_to_le32(ct_window), 2210 .bss_idx = mvif->idx, 2211 }; 2212 2213 return mt76_mcu_send_msg(phy->dev, MCU_CE_CMD(SET_P2P_OPPPS), 2214 &req, sizeof(req), false); 2215 } 2216 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_p2p_oppps); 2217 2218 #ifdef CONFIG_PM 2219 2220 const struct wiphy_wowlan_support mt76_connac_wowlan_support = { 2221 .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT | 2222 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | WIPHY_WOWLAN_NET_DETECT, 2223 .n_patterns = 1, 2224 .pattern_min_len = 1, 2225 .pattern_max_len = MT76_CONNAC_WOW_PATTEN_MAX_LEN, 2226 .max_nd_match_sets = 10, 2227 }; 2228 EXPORT_SYMBOL_GPL(mt76_connac_wowlan_support); 2229 2230 static void 2231 mt76_connac_mcu_key_iter(struct ieee80211_hw *hw, 2232 struct ieee80211_vif *vif, 2233 struct ieee80211_sta *sta, 2234 struct ieee80211_key_conf *key, 2235 void *data) 2236 { 2237 struct mt76_connac_gtk_rekey_tlv *gtk_tlv = data; 2238 u32 cipher; 2239 2240 if (key->cipher != WLAN_CIPHER_SUITE_AES_CMAC && 2241 key->cipher != WLAN_CIPHER_SUITE_CCMP && 2242 key->cipher != WLAN_CIPHER_SUITE_TKIP) 2243 return; 2244 2245 if (key->cipher == WLAN_CIPHER_SUITE_TKIP) 2246 cipher = BIT(3); 2247 else 2248 cipher = BIT(4); 2249 2250 /* we are assuming here to have a single pairwise key */ 2251 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { 2252 if (key->cipher == WLAN_CIPHER_SUITE_TKIP) 2253 gtk_tlv->proto = cpu_to_le32(NL80211_WPA_VERSION_1); 2254 else 2255 gtk_tlv->proto = cpu_to_le32(NL80211_WPA_VERSION_2); 2256 2257 gtk_tlv->pairwise_cipher = cpu_to_le32(cipher); 2258 gtk_tlv->keyid = key->keyidx; 2259 } else { 2260 gtk_tlv->group_cipher = cpu_to_le32(cipher); 2261 } 2262 } 2263 2264 int mt76_connac_mcu_update_gtk_rekey(struct ieee80211_hw *hw, 2265 struct ieee80211_vif *vif, 2266 struct cfg80211_gtk_rekey_data *key) 2267 { 2268 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 2269 struct mt76_connac_gtk_rekey_tlv *gtk_tlv; 2270 struct mt76_phy *phy = hw->priv; 2271 struct sk_buff *skb; 2272 struct { 2273 u8 bss_idx; 2274 u8 pad[3]; 2275 } __packed hdr = { 2276 .bss_idx = mvif->idx, 2277 }; 2278 2279 skb = mt76_mcu_msg_alloc(phy->dev, NULL, 2280 sizeof(hdr) + sizeof(*gtk_tlv)); 2281 if (!skb) 2282 return -ENOMEM; 2283 2284 skb_put_data(skb, &hdr, sizeof(hdr)); 2285 gtk_tlv = (struct mt76_connac_gtk_rekey_tlv *)skb_put(skb, 2286 sizeof(*gtk_tlv)); 2287 gtk_tlv->tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_GTK_REKEY); 2288 gtk_tlv->len = cpu_to_le16(sizeof(*gtk_tlv)); 2289 gtk_tlv->rekey_mode = 2; 2290 gtk_tlv->option = 1; 2291 2292 rcu_read_lock(); 2293 ieee80211_iter_keys_rcu(hw, vif, mt76_connac_mcu_key_iter, gtk_tlv); 2294 rcu_read_unlock(); 2295 2296 memcpy(gtk_tlv->kek, key->kek, NL80211_KEK_LEN); 2297 memcpy(gtk_tlv->kck, key->kck, NL80211_KCK_LEN); 2298 memcpy(gtk_tlv->replay_ctr, key->replay_ctr, NL80211_REPLAY_CTR_LEN); 2299 2300 return mt76_mcu_skb_send_msg(phy->dev, skb, 2301 MCU_UNI_CMD(OFFLOAD), true); 2302 } 2303 EXPORT_SYMBOL_GPL(mt76_connac_mcu_update_gtk_rekey); 2304 2305 static int 2306 mt76_connac_mcu_set_arp_filter(struct mt76_dev *dev, struct ieee80211_vif *vif, 2307 bool suspend) 2308 { 2309 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 2310 struct { 2311 struct { 2312 u8 bss_idx; 2313 u8 pad[3]; 2314 } __packed hdr; 2315 struct mt76_connac_arpns_tlv arpns; 2316 } req = { 2317 .hdr = { 2318 .bss_idx = mvif->idx, 2319 }, 2320 .arpns = { 2321 .tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_ARP), 2322 .len = cpu_to_le16(sizeof(struct mt76_connac_arpns_tlv)), 2323 .mode = suspend, 2324 }, 2325 }; 2326 2327 return mt76_mcu_send_msg(dev, MCU_UNI_CMD(OFFLOAD), &req, 2328 sizeof(req), true); 2329 } 2330 2331 static int 2332 mt76_connac_mcu_set_gtk_rekey(struct mt76_dev *dev, struct ieee80211_vif *vif, 2333 bool suspend) 2334 { 2335 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 2336 struct { 2337 struct { 2338 u8 bss_idx; 2339 u8 pad[3]; 2340 } __packed hdr; 2341 struct mt76_connac_gtk_rekey_tlv gtk_tlv; 2342 } __packed req = { 2343 .hdr = { 2344 .bss_idx = mvif->idx, 2345 }, 2346 .gtk_tlv = { 2347 .tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_GTK_REKEY), 2348 .len = cpu_to_le16(sizeof(struct mt76_connac_gtk_rekey_tlv)), 2349 .rekey_mode = !suspend, 2350 }, 2351 }; 2352 2353 return mt76_mcu_send_msg(dev, MCU_UNI_CMD(OFFLOAD), &req, 2354 sizeof(req), true); 2355 } 2356 2357 static int 2358 mt76_connac_mcu_set_suspend_mode(struct mt76_dev *dev, 2359 struct ieee80211_vif *vif, 2360 bool enable, u8 mdtim, 2361 bool wow_suspend) 2362 { 2363 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 2364 struct { 2365 struct { 2366 u8 bss_idx; 2367 u8 pad[3]; 2368 } __packed hdr; 2369 struct mt76_connac_suspend_tlv suspend_tlv; 2370 } req = { 2371 .hdr = { 2372 .bss_idx = mvif->idx, 2373 }, 2374 .suspend_tlv = { 2375 .tag = cpu_to_le16(UNI_SUSPEND_MODE_SETTING), 2376 .len = cpu_to_le16(sizeof(struct mt76_connac_suspend_tlv)), 2377 .enable = enable, 2378 .mdtim = mdtim, 2379 .wow_suspend = wow_suspend, 2380 }, 2381 }; 2382 2383 return mt76_mcu_send_msg(dev, MCU_UNI_CMD(SUSPEND), &req, 2384 sizeof(req), true); 2385 } 2386 2387 static int 2388 mt76_connac_mcu_set_wow_pattern(struct mt76_dev *dev, 2389 struct ieee80211_vif *vif, 2390 u8 index, bool enable, 2391 struct cfg80211_pkt_pattern *pattern) 2392 { 2393 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 2394 struct mt76_connac_wow_pattern_tlv *ptlv; 2395 struct sk_buff *skb; 2396 struct req_hdr { 2397 u8 bss_idx; 2398 u8 pad[3]; 2399 } __packed hdr = { 2400 .bss_idx = mvif->idx, 2401 }; 2402 2403 skb = mt76_mcu_msg_alloc(dev, NULL, sizeof(hdr) + sizeof(*ptlv)); 2404 if (!skb) 2405 return -ENOMEM; 2406 2407 skb_put_data(skb, &hdr, sizeof(hdr)); 2408 ptlv = (struct mt76_connac_wow_pattern_tlv *)skb_put(skb, sizeof(*ptlv)); 2409 ptlv->tag = cpu_to_le16(UNI_SUSPEND_WOW_PATTERN); 2410 ptlv->len = cpu_to_le16(sizeof(*ptlv)); 2411 ptlv->data_len = pattern->pattern_len; 2412 ptlv->enable = enable; 2413 ptlv->index = index; 2414 2415 memcpy(ptlv->pattern, pattern->pattern, pattern->pattern_len); 2416 memcpy(ptlv->mask, pattern->mask, DIV_ROUND_UP(pattern->pattern_len, 8)); 2417 2418 return mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD(SUSPEND), true); 2419 } 2420 2421 static int 2422 mt76_connac_mcu_set_wow_ctrl(struct mt76_phy *phy, struct ieee80211_vif *vif, 2423 bool suspend, struct cfg80211_wowlan *wowlan) 2424 { 2425 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 2426 struct mt76_dev *dev = phy->dev; 2427 struct { 2428 struct { 2429 u8 bss_idx; 2430 u8 pad[3]; 2431 } __packed hdr; 2432 struct mt76_connac_wow_ctrl_tlv wow_ctrl_tlv; 2433 struct mt76_connac_wow_gpio_param_tlv gpio_tlv; 2434 } req = { 2435 .hdr = { 2436 .bss_idx = mvif->idx, 2437 }, 2438 .wow_ctrl_tlv = { 2439 .tag = cpu_to_le16(UNI_SUSPEND_WOW_CTRL), 2440 .len = cpu_to_le16(sizeof(struct mt76_connac_wow_ctrl_tlv)), 2441 .cmd = suspend ? 1 : 2, 2442 }, 2443 .gpio_tlv = { 2444 .tag = cpu_to_le16(UNI_SUSPEND_WOW_GPIO_PARAM), 2445 .len = cpu_to_le16(sizeof(struct mt76_connac_wow_gpio_param_tlv)), 2446 .gpio_pin = 0xff, /* follow fw about GPIO pin */ 2447 }, 2448 }; 2449 2450 if (wowlan->magic_pkt) 2451 req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_MAGIC; 2452 if (wowlan->disconnect) 2453 req.wow_ctrl_tlv.trigger |= (UNI_WOW_DETECT_TYPE_DISCONNECT | 2454 UNI_WOW_DETECT_TYPE_BCN_LOST); 2455 if (wowlan->nd_config) { 2456 mt76_connac_mcu_sched_scan_req(phy, vif, wowlan->nd_config); 2457 req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_SCH_SCAN_HIT; 2458 mt76_connac_mcu_sched_scan_enable(phy, vif, suspend); 2459 } 2460 if (wowlan->n_patterns) 2461 req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_BITMAP; 2462 2463 if (mt76_is_mmio(dev)) 2464 req.wow_ctrl_tlv.wakeup_hif = WOW_PCIE; 2465 else if (mt76_is_usb(dev)) 2466 req.wow_ctrl_tlv.wakeup_hif = WOW_USB; 2467 else if (mt76_is_sdio(dev)) 2468 req.wow_ctrl_tlv.wakeup_hif = WOW_GPIO; 2469 2470 return mt76_mcu_send_msg(dev, MCU_UNI_CMD(SUSPEND), &req, 2471 sizeof(req), true); 2472 } 2473 2474 int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend) 2475 { 2476 struct { 2477 struct { 2478 u8 hif_type; /* 0x0: HIF_SDIO 2479 * 0x1: HIF_USB 2480 * 0x2: HIF_PCIE 2481 */ 2482 u8 pad[3]; 2483 } __packed hdr; 2484 struct hif_suspend_tlv { 2485 __le16 tag; 2486 __le16 len; 2487 u8 suspend; 2488 } __packed hif_suspend; 2489 } req = { 2490 .hif_suspend = { 2491 .tag = cpu_to_le16(0), /* 0: UNI_HIF_CTRL_BASIC */ 2492 .len = cpu_to_le16(sizeof(struct hif_suspend_tlv)), 2493 .suspend = suspend, 2494 }, 2495 }; 2496 2497 if (mt76_is_mmio(dev)) 2498 req.hdr.hif_type = 2; 2499 else if (mt76_is_usb(dev)) 2500 req.hdr.hif_type = 1; 2501 else if (mt76_is_sdio(dev)) 2502 req.hdr.hif_type = 0; 2503 2504 return mt76_mcu_send_msg(dev, MCU_UNI_CMD(HIF_CTRL), &req, 2505 sizeof(req), true); 2506 } 2507 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_hif_suspend); 2508 2509 void mt76_connac_mcu_set_suspend_iter(void *priv, u8 *mac, 2510 struct ieee80211_vif *vif) 2511 { 2512 struct mt76_phy *phy = priv; 2513 bool suspend = !test_bit(MT76_STATE_RUNNING, &phy->state); 2514 struct ieee80211_hw *hw = phy->hw; 2515 struct cfg80211_wowlan *wowlan = hw->wiphy->wowlan_config; 2516 int i; 2517 2518 mt76_connac_mcu_set_gtk_rekey(phy->dev, vif, suspend); 2519 mt76_connac_mcu_set_arp_filter(phy->dev, vif, suspend); 2520 2521 mt76_connac_mcu_set_suspend_mode(phy->dev, vif, suspend, 1, true); 2522 2523 for (i = 0; i < wowlan->n_patterns; i++) 2524 mt76_connac_mcu_set_wow_pattern(phy->dev, vif, i, suspend, 2525 &wowlan->patterns[i]); 2526 mt76_connac_mcu_set_wow_ctrl(phy, vif, suspend, wowlan); 2527 } 2528 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_suspend_iter); 2529 #endif /* CONFIG_PM */ 2530 2531 u32 mt76_connac_mcu_reg_rr(struct mt76_dev *dev, u32 offset) 2532 { 2533 struct { 2534 __le32 addr; 2535 __le32 val; 2536 } __packed req = { 2537 .addr = cpu_to_le32(offset), 2538 }; 2539 2540 return mt76_mcu_send_msg(dev, MCU_CE_QUERY(REG_READ), &req, 2541 sizeof(req), true); 2542 } 2543 EXPORT_SYMBOL_GPL(mt76_connac_mcu_reg_rr); 2544 2545 void mt76_connac_mcu_reg_wr(struct mt76_dev *dev, u32 offset, u32 val) 2546 { 2547 struct { 2548 __le32 addr; 2549 __le32 val; 2550 } __packed req = { 2551 .addr = cpu_to_le32(offset), 2552 .val = cpu_to_le32(val), 2553 }; 2554 2555 mt76_mcu_send_msg(dev, MCU_CE_CMD(REG_WRITE), &req, 2556 sizeof(req), false); 2557 } 2558 EXPORT_SYMBOL_GPL(mt76_connac_mcu_reg_wr); 2559 2560 static int 2561 mt76_connac_mcu_sta_key_tlv(struct mt76_connac_sta_key_conf *sta_key_conf, 2562 struct sk_buff *skb, 2563 struct ieee80211_key_conf *key, 2564 enum set_key_cmd cmd) 2565 { 2566 struct sta_rec_sec *sec; 2567 u32 len = sizeof(*sec); 2568 struct tlv *tlv; 2569 2570 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_KEY_V2, sizeof(*sec)); 2571 sec = (struct sta_rec_sec *)tlv; 2572 sec->add = cmd; 2573 2574 if (cmd == SET_KEY) { 2575 struct sec_key *sec_key; 2576 u8 cipher; 2577 2578 cipher = mt76_connac_mcu_get_cipher(key->cipher); 2579 if (cipher == MCU_CIPHER_NONE) 2580 return -EOPNOTSUPP; 2581 2582 sec_key = &sec->key[0]; 2583 sec_key->cipher_len = sizeof(*sec_key); 2584 2585 if (cipher == MCU_CIPHER_BIP_CMAC_128) { 2586 sec_key->cipher_id = MCU_CIPHER_AES_CCMP; 2587 sec_key->key_id = sta_key_conf->keyidx; 2588 sec_key->key_len = 16; 2589 memcpy(sec_key->key, sta_key_conf->key, 16); 2590 2591 sec_key = &sec->key[1]; 2592 sec_key->cipher_id = MCU_CIPHER_BIP_CMAC_128; 2593 sec_key->cipher_len = sizeof(*sec_key); 2594 sec_key->key_len = 16; 2595 memcpy(sec_key->key, key->key, 16); 2596 sec->n_cipher = 2; 2597 } else { 2598 sec_key->cipher_id = cipher; 2599 sec_key->key_id = key->keyidx; 2600 sec_key->key_len = key->keylen; 2601 memcpy(sec_key->key, key->key, key->keylen); 2602 2603 if (cipher == MCU_CIPHER_TKIP) { 2604 /* Rx/Tx MIC keys are swapped */ 2605 memcpy(sec_key->key + 16, key->key + 24, 8); 2606 memcpy(sec_key->key + 24, key->key + 16, 8); 2607 } 2608 2609 /* store key_conf for BIP batch update */ 2610 if (cipher == MCU_CIPHER_AES_CCMP) { 2611 memcpy(sta_key_conf->key, key->key, key->keylen); 2612 sta_key_conf->keyidx = key->keyidx; 2613 } 2614 2615 len -= sizeof(*sec_key); 2616 sec->n_cipher = 1; 2617 } 2618 } else { 2619 len -= sizeof(sec->key); 2620 sec->n_cipher = 0; 2621 } 2622 sec->len = cpu_to_le16(len); 2623 2624 return 0; 2625 } 2626 2627 int mt76_connac_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif, 2628 struct mt76_connac_sta_key_conf *sta_key_conf, 2629 struct ieee80211_key_conf *key, int mcu_cmd, 2630 struct mt76_wcid *wcid, enum set_key_cmd cmd) 2631 { 2632 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 2633 struct sk_buff *skb; 2634 int ret; 2635 2636 skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid); 2637 if (IS_ERR(skb)) 2638 return PTR_ERR(skb); 2639 2640 ret = mt76_connac_mcu_sta_key_tlv(sta_key_conf, skb, key, cmd); 2641 if (ret) 2642 return ret; 2643 2644 return mt76_mcu_skb_send_msg(dev, skb, mcu_cmd, true); 2645 } 2646 EXPORT_SYMBOL_GPL(mt76_connac_mcu_add_key); 2647 2648 /* SIFS 20us + 512 byte beacon tranmitted by 1Mbps (3906us) */ 2649 #define BCN_TX_ESTIMATE_TIME (4096 + 20) 2650 void mt76_connac_mcu_bss_ext_tlv(struct sk_buff *skb, struct mt76_vif *mvif) 2651 { 2652 struct bss_info_ext_bss *ext; 2653 int ext_bss_idx, tsf_offset; 2654 struct tlv *tlv; 2655 2656 ext_bss_idx = mvif->omac_idx - EXT_BSSID_START; 2657 if (ext_bss_idx < 0) 2658 return; 2659 2660 tlv = mt76_connac_mcu_add_tlv(skb, BSS_INFO_EXT_BSS, sizeof(*ext)); 2661 2662 ext = (struct bss_info_ext_bss *)tlv; 2663 tsf_offset = ext_bss_idx * BCN_TX_ESTIMATE_TIME; 2664 ext->mbss_tsf_offset = cpu_to_le32(tsf_offset); 2665 } 2666 EXPORT_SYMBOL_GPL(mt76_connac_mcu_bss_ext_tlv); 2667 2668 int mt76_connac_mcu_bss_basic_tlv(struct sk_buff *skb, 2669 struct ieee80211_vif *vif, 2670 struct ieee80211_sta *sta, 2671 struct mt76_phy *phy, u16 wlan_idx, 2672 bool enable) 2673 { 2674 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; 2675 u32 type = vif->p2p ? NETWORK_P2P : NETWORK_INFRA; 2676 struct bss_info_basic *bss; 2677 struct tlv *tlv; 2678 2679 tlv = mt76_connac_mcu_add_tlv(skb, BSS_INFO_BASIC, sizeof(*bss)); 2680 bss = (struct bss_info_basic *)tlv; 2681 2682 switch (vif->type) { 2683 case NL80211_IFTYPE_MESH_POINT: 2684 case NL80211_IFTYPE_MONITOR: 2685 break; 2686 case NL80211_IFTYPE_AP: 2687 if (ieee80211_hw_check(phy->hw, SUPPORTS_MULTI_BSSID)) { 2688 u8 bssid_id = vif->bss_conf.bssid_indicator; 2689 struct wiphy *wiphy = phy->hw->wiphy; 2690 2691 if (bssid_id > ilog2(wiphy->mbssid_max_interfaces)) 2692 return -EINVAL; 2693 2694 bss->non_tx_bssid = vif->bss_conf.bssid_index; 2695 bss->max_bssid = bssid_id; 2696 } 2697 break; 2698 case NL80211_IFTYPE_STATION: 2699 if (enable) { 2700 rcu_read_lock(); 2701 if (!sta) 2702 sta = ieee80211_find_sta(vif, 2703 vif->bss_conf.bssid); 2704 /* TODO: enable BSS_INFO_UAPSD & BSS_INFO_PM */ 2705 if (sta) { 2706 struct mt76_wcid *wcid; 2707 2708 wcid = (struct mt76_wcid *)sta->drv_priv; 2709 wlan_idx = wcid->idx; 2710 } 2711 rcu_read_unlock(); 2712 } 2713 break; 2714 case NL80211_IFTYPE_ADHOC: 2715 type = NETWORK_IBSS; 2716 break; 2717 default: 2718 WARN_ON(1); 2719 break; 2720 } 2721 2722 bss->network_type = cpu_to_le32(type); 2723 bss->bmc_wcid_lo = to_wcid_lo(wlan_idx); 2724 bss->bmc_wcid_hi = to_wcid_hi(wlan_idx); 2725 bss->wmm_idx = mvif->wmm_idx; 2726 bss->active = enable; 2727 bss->cipher = mvif->cipher; 2728 2729 if (vif->type != NL80211_IFTYPE_MONITOR) { 2730 struct cfg80211_chan_def *chandef = &phy->chandef; 2731 2732 memcpy(bss->bssid, vif->bss_conf.bssid, ETH_ALEN); 2733 bss->bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int); 2734 bss->dtim_period = vif->bss_conf.dtim_period; 2735 bss->phy_mode = mt76_connac_get_phy_mode(phy, vif, 2736 chandef->chan->band, NULL); 2737 } else { 2738 memcpy(bss->bssid, phy->macaddr, ETH_ALEN); 2739 } 2740 2741 return 0; 2742 } 2743 EXPORT_SYMBOL_GPL(mt76_connac_mcu_bss_basic_tlv); 2744 2745 #define ENTER_PM_STATE 1 2746 #define EXIT_PM_STATE 2 2747 int mt76_connac_mcu_set_pm(struct mt76_dev *dev, int band, int enter) 2748 { 2749 struct { 2750 u8 pm_number; 2751 u8 pm_state; 2752 u8 bssid[ETH_ALEN]; 2753 u8 dtim_period; 2754 u8 wlan_idx_lo; 2755 __le16 bcn_interval; 2756 __le32 aid; 2757 __le32 rx_filter; 2758 u8 band_idx; 2759 u8 wlan_idx_hi; 2760 u8 rsv[2]; 2761 __le32 feature; 2762 u8 omac_idx; 2763 u8 wmm_idx; 2764 u8 bcn_loss_cnt; 2765 u8 bcn_sp_duration; 2766 } __packed req = { 2767 .pm_number = 5, 2768 .pm_state = enter ? ENTER_PM_STATE : EXIT_PM_STATE, 2769 .band_idx = band, 2770 }; 2771 2772 return mt76_mcu_send_msg(dev, MCU_EXT_CMD(PM_STATE_CTRL), &req, 2773 sizeof(req), true); 2774 } 2775 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_pm); 2776 2777 int mt76_connac_mcu_restart(struct mt76_dev *dev) 2778 { 2779 struct { 2780 u8 power_mode; 2781 u8 rsv[3]; 2782 } req = { 2783 .power_mode = 1, 2784 }; 2785 2786 return mt76_mcu_send_msg(dev, MCU_CMD(NIC_POWER_CTRL), &req, 2787 sizeof(req), false); 2788 } 2789 EXPORT_SYMBOL_GPL(mt76_connac_mcu_restart); 2790 2791 int mt76_connac_mcu_rdd_cmd(struct mt76_dev *dev, int cmd, u8 index, 2792 u8 rx_sel, u8 val) 2793 { 2794 struct { 2795 u8 ctrl; 2796 u8 rdd_idx; 2797 u8 rdd_rx_sel; 2798 u8 val; 2799 u8 rsv[4]; 2800 } __packed req = { 2801 .ctrl = cmd, 2802 .rdd_idx = index, 2803 .rdd_rx_sel = rx_sel, 2804 .val = val, 2805 }; 2806 2807 return mt76_mcu_send_msg(dev, MCU_EXT_CMD(SET_RDD_CTRL), &req, 2808 sizeof(req), true); 2809 } 2810 EXPORT_SYMBOL_GPL(mt76_connac_mcu_rdd_cmd); 2811 2812 MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); 2813 MODULE_LICENSE("Dual BSD/GPL"); 2814